]> git.ipfire.org Git - thirdparty/glibc.git/blame - iconv/skeleton.c
Update.
[thirdparty/glibc.git] / iconv / skeleton.c
CommitLineData
09376451 1/* Skeleton for a conversion module.
63e04088 2 Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
8619129f
UD
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21/* This file can be included to provide definitions of several things
22 many modules have in common. It can be customized using the following
23 macros:
24
25 DEFINE_INIT define the default initializer. This requires the
26 following symbol to be defined.
27
28 CHARSET_NAME string with official name of the coded character
29 set (in all-caps)
30
31 DEFINE_FINI define the default destructor function.
32
33 MIN_NEEDED_FROM minimal number of bytes needed for the from-charset.
34 MIN_NEEDED_TO likewise for the to-charset.
35
36 MAX_NEEDED_FROM maximal number of bytes needed for the from-charset.
37 This macro is optional, it defaults to MIN_NEEDED_FROM.
38 MAX_NEEDED_TO likewise for the to-charset.
39
40 DEFINE_DIRECTION_OBJECTS
41 two objects will be defined to be used when the
42 `gconv' function must only distinguish two
43 directions. This is implied by DEFINE_INIT.
44 If this macro is not defined the following
45 macro must be available.
46
47 FROM_DIRECTION this macro is supposed to return a value != 0
48 if we convert from the current character set,
49 otherwise it return 0.
50
51 EMIT_SHIFT_TO_INIT this symbol is optional. If it is defined it
52 defines some code which writes out a sequence
53 of characters which bring the current state into
54 the initial state.
55
56 FROM_LOOP name of the function implementing the conversion
57 from the current characters.
58 TO_LOOP likewise for the other direction
59
60 RESET_STATE in case of an error we must reset the state for
61 the rerun so this macro must be defined for
62 stateful encodings. It takes an argument which
63 is nonzero when saving.
64
65 RESET_INPUT_BUFFER If the input character sets allow this the macro
66 can be defined to reset the input buffer pointers
67 to cover only those characters up to the error.
68
69 FUNCTION_NAME if not set the conversion function is named `gconv'.
28f1c862
UD
70
71 PREPARE_LOOP optional code preparing the conversion loop. Can
72 contain variable definitions.
918b9d72 73 END_LOOP also optional, may be used to store information
28f1c862
UD
74
75 EXTRA_LOOP_ARGS optional macro specifying extra arguments passed
76 to loop function.
8619129f
UD
77 */
78
79#include <assert.h>
80#include <gconv.h>
81#include <string.h>
82#define __need_size_t
83#define __need_NULL
84#include <stddef.h>
c66dbe00
UD
85
86#ifndef STATIC_GCONV
87# include <dlfcn.h>
c66dbe00 88#endif
8619129f 89
a808d541
UD
90#ifndef DL_CALL_FCT
91# define DL_CALL_FCT(fct, args) fct args
92#endif
93
8619129f
UD
94/* The direction objects. */
95#if DEFINE_DIRECTION_OBJECTS || DEFINE_INIT
96static int from_object;
97static int to_object;
98
99# ifndef FROM_DIRECTION
d64b6ad0 100# define FROM_DIRECTION (step->__data == &from_object)
8619129f
UD
101# endif
102#else
103# ifndef FROM_DIRECTION
104# error "FROM_DIRECTION must be provided if direction objects are not used"
105# endif
106#endif
107
108
109/* How many bytes are needed at most for the from-charset. */
110#ifndef MAX_NEEDED_FROM
111# define MAX_NEEDED_FROM MIN_NEEDED_FROM
112#endif
113
114/* Same for the to-charset. */
115#ifndef MAX_NEEDED_TO
116# define MAX_NEEDED_TO MIN_NEEDED_TO
117#endif
118
119
77e1d15a
UD
120/* Define macros which can access unaligned buffers. These macros are
121 supposed to be used only in code outside the inner loops. For the inner
122 loops we have other definitions which allow optimized access. */
123#ifdef _STRING_ARCH_unaligned
124/* We can handle unaligned memory access. */
c1db8b0d
UD
125# define get16u(addr) *((uint16_t *) (addr))
126# define get32u(addr) *((uint32_t *) (addr))
77e1d15a
UD
127
128/* We need no special support for writing values either. */
c1db8b0d
UD
129# define put16u(addr, val) *((uint16_t *) (addr)) = (val)
130# define put32u(addr, val) *((uint32_t *) (addr)) = (val)
77e1d15a
UD
131#else
132/* Distinguish between big endian and little endian. */
133# if __BYTE_ORDER == __LITTLE_ENDIAN
c1db8b0d 134# define get16u(addr) \
77e1d15a
UD
135 (((__const unsigned char *) (addr))[1] << 8 \
136 | ((__const unsigned char *) (addr))[0])
c1db8b0d 137# define get32u(addr) \
77e1d15a
UD
138 (((((__const unsigned char *) (addr))[3] << 8 \
139 | ((__const unsigned char *) (addr))[2]) << 8 \
140 | ((__const unsigned char *) (addr))[1]) << 8 \
141 | ((__const unsigned char *) (addr))[0])
142
c1db8b0d 143# define put16u(addr, val) \
77e1d15a 144 ({ uint16_t __val = (val); \
cb2c5501
UD
145 ((unsigned char *) (addr))[0] = __val; \
146 ((unsigned char *) (addr))[1] = __val >> 8; \
77e1d15a 147 (void) 0; })
c1db8b0d 148# define put32u(addr, val) \
cb2c5501
UD
149 ({ uint32_t __val = (val); \
150 ((unsigned char *) (addr))[0] = __val; \
77e1d15a 151 __val >>= 8; \
cb2c5501 152 ((unsigned char *) (addr))[1] = __val; \
77e1d15a 153 __val >>= 8; \
cb2c5501 154 ((unsigned char *) (addr))[2] = __val; \
77e1d15a 155 __val >>= 8; \
cb2c5501 156 ((unsigned char *) (addr))[3] = __val; \
77e1d15a
UD
157 (void) 0; })
158# else
c1db8b0d 159# define get16u(addr) \
77e1d15a
UD
160 (((__const unsigned char *) (addr))[0] << 8 \
161 | ((__const unsigned char *) (addr))[1])
c1db8b0d 162# define get32u(addr) \
77e1d15a
UD
163 (((((__const unsigned char *) (addr))[0] << 8 \
164 | ((__const unsigned char *) (addr))[1]) << 8 \
165 | ((__const unsigned char *) (addr))[2]) << 8 \
166 | ((__const unsigned char *) (addr))[3])
167
c1db8b0d 168# define put16u(addr, val) \
77e1d15a 169 ({ uint16_t __val = (val); \
cb2c5501 170 ((unsigned char *) (addr))[1] = __val; \
a1303dc8 171 ((unsigned char *) (addr))[0] = __val >> 8; \
77e1d15a 172 (void) 0; })
c1db8b0d 173# define put32u(addr, val) \
cb2c5501
UD
174 ({ uint32_t __val = (val); \
175 ((unsigned char *) (addr))[3] = __val; \
77e1d15a 176 __val >>= 8; \
cb2c5501 177 ((unsigned char *) (addr))[2] = __val; \
77e1d15a 178 __val >>= 8; \
cb2c5501 179 ((unsigned char *) (addr))[1] = __val; \
77e1d15a 180 __val >>= 8; \
cb2c5501 181 ((unsigned char *) (addr))[0] = __val; \
77e1d15a
UD
182 (void) 0; })
183# endif
184#endif
185
186
8619129f
UD
187/* For conversions from a fixed width character sets to another fixed width
188 character set we we can define RESET_INPUT_BUFFER is necessary. */
189#if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
190# if MIN_NEEDED_FROM == MAX_NEEDED_FROM && MIN_NEEDED_TO == MAX_NEEDED_TO
390955cb 191/* We have to use these `if's here since the compiler cannot know that
8619129f
UD
192 (outbuf - outerr) is always divisible by MIN_NEEDED_TO. */
193# define RESET_INPUT_BUFFER \
194 if (MIN_NEEDED_FROM % MIN_NEEDED_TO == 0) \
fd1b5c0f 195 *inptrp -= (outbuf - outerr) * (MIN_NEEDED_FROM / MIN_NEEDED_TO); \
8619129f 196 else if (MIN_NEEDED_TO % MIN_NEEDED_FROM == 0) \
fd1b5c0f 197 *inptrp -= (outbuf - outerr) / (MIN_NEEDED_TO / MIN_NEEDED_FROM); \
8619129f 198 else \
fd1b5c0f 199 *inptrp -= ((outbuf - outerr) / MIN_NEEDED_TO) * MIN_NEEDED_FROM
8619129f
UD
200# endif
201#endif
202
203
204/* The default init function. It simply matches the name and initializes
205 the step data to point to one of the objects above. */
206#if DEFINE_INIT
207# ifndef CHARSET_NAME
208# error "CHARSET_NAME not defined"
209# endif
210
211int
d64b6ad0 212gconv_init (struct __gconv_step *step)
8619129f
UD
213{
214 /* Determine which direction. */
d64b6ad0 215 if (strcmp (step->__from_name, CHARSET_NAME) == 0)
918b9d72 216 {
d64b6ad0 217 step->__data = &from_object;
390955cb 218
d64b6ad0
UD
219 step->__min_needed_from = MIN_NEEDED_FROM;
220 step->__max_needed_from = MAX_NEEDED_FROM;
221 step->__min_needed_to = MIN_NEEDED_TO;
222 step->__max_needed_to = MAX_NEEDED_TO;
918b9d72 223 }
365afefc 224 else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0)
918b9d72 225 {
d64b6ad0 226 step->__data = &to_object;
390955cb 227
d64b6ad0
UD
228 step->__min_needed_from = MIN_NEEDED_TO;
229 step->__max_needed_from = MAX_NEEDED_TO;
230 step->__min_needed_to = MIN_NEEDED_FROM;
231 step->__max_needed_to = MAX_NEEDED_FROM;
918b9d72 232 }
390955cb 233 else
d64b6ad0 234 return __GCONV_NOCONV;
8619129f 235
9ce5071a 236#ifdef RESET_STATE
d64b6ad0 237 step->__stateful = 1;
9ce5071a 238#else
d64b6ad0 239 step->__stateful = 0;
9ce5071a
UD
240#endif
241
d64b6ad0 242 return __GCONV_OK;
8619129f
UD
243}
244#endif
245
246
247/* The default destructor function does nothing in the moment and so
248 be define it at all. But we still provide the macro just in case
249 we need it some day. */
250#if DEFINE_FINI
251#endif
252
253
28f1c862
UD
254/* If no arguments have to passed to the loop function define the macro
255 as empty. */
256#ifndef EXTRA_LOOP_ARGS
257# define EXTRA_LOOP_ARGS
258#endif
259
260
8619129f
UD
261/* This is the actual conversion function. */
262#ifndef FUNCTION_NAME
263# define FUNCTION_NAME gconv
264#endif
265
fd1b5c0f
UD
266/* The macros are used to access the function to convert single characters. */
267#define SINGLE(fct) SINGLE2 (fct)
268#define SINGLE2(fct) fct##_single
269
270
8619129f 271int
d64b6ad0 272FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
fd1b5c0f
UD
273 const unsigned char **inptrp, const unsigned char *inend,
274 size_t *written, int do_flush, int consume_incomplete)
8619129f 275{
d64b6ad0
UD
276 struct __gconv_step *next_step = step + 1;
277 struct __gconv_step_data *next_data = data + 1;
85830c4c 278 __gconv_fct fct;
8619129f
UD
279 int status;
280
85830c4c
UD
281 fct = (data->__flags & __GCONV_IS_LAST) ? NULL : next_step->__fct;
282
8619129f
UD
283 /* If the function is called with no input this means we have to reset
284 to the initial state. The possibly partly converted input is
285 dropped. */
978ce92b 286 if (__builtin_expect (do_flush, 0))
8619129f 287 {
d64b6ad0 288 status = __GCONV_OK;
8619129f 289
390955cb
UD
290#ifdef EMIT_SHIFT_TO_INIT
291 /* Emit the escape sequence to reset the state. */
292 EMIT_SHIFT_TO_INIT;
8619129f 293#endif
390955cb
UD
294 /* Call the steps down the chain if there are any but only if we
295 successfully emitted the escape sequence. */
85830c4c 296 if (status == __GCONV_OK && ! (data->__flags & __GCONV_IS_LAST))
390955cb 297 status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL,
fd1b5c0f 298 written, 1, consume_incomplete));
8619129f
UD
299 }
300 else
301 {
8619129f 302 /* We preserve the initial values of the pointer variables. */
fd1b5c0f 303 const unsigned char *inptr = *inptrp;
d64b6ad0
UD
304 unsigned char *outbuf = data->__outbuf;
305 unsigned char *outend = data->__outbufend;
b117f744 306 unsigned char *outstart;
3aaad0b6
UD
307 /* This variable is used to count the number of characters we
308 actually converted. */
309 size_t converted = 0;
fdf64555
UD
310#if defined _STRING_ARCH_unaligned \
311 || MIN_NEEDED_FROM == 1 || MAX_NEEDED_FROM % MIN_NEEDED_FROM != 0 \
312 || MIN_NEEDED_TO == 1 || MAX_NEEDED_TO % MIN_NEEDED_TO != 0
77e1d15a
UD
313# define unaligned 0
314#else
3aaad0b6 315 int unaligned;
77e1d15a
UD
316# define GEN_unaligned(name) GEN_unaligned2 (name)
317# define GEN_unaligned2(name) name##_unaligned
318#endif
8619129f 319
28f1c862
UD
320#ifdef PREPARE_LOOP
321 PREPARE_LOOP
322#endif
323
fd1b5c0f
UD
324#if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1
325 /* If the function is used to implement the mb*towc*() or wc*tomb*()
326 functions we must test whether any bytes from the last call are
327 stored in the `state' object. */
328 if (((MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
329 || (MAX_NEEDED_TO > 1 && !FROM_DIRECTION))
330 && consume_incomplete && (data->__statep->__count & 7) != 0)
331 {
332 /* Yep, we have some bytes left over. Process them now. */
333
334# if MAX_NEEDED_FROM > 1
335 if (MAX_NEEDED_TO == 1 || FROM_DIRECTION)
336 status = SINGLE(FROM_LOOP) (inptrp, inend, &outbuf, outend,
85830c4c
UD
337 data->__statep, data->__flags,
338 step->__data, &converted
339 EXTRA_LOOP_ARGS);
fd1b5c0f
UD
340# endif
341# if MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1 && !ONE_DIRECTION
342 else
343# endif
344# if MAX_NEEDED_TO > 1 && !ONE_DIRECTION
345 status = SINGLE(TO_LOOP) (inptrp, inend, &outbuf, outend,
85830c4c
UD
346 data->__statep, data->__flags,
347 step->__data, &converted
348 EXTRA_LOOP_ARGS);
fd1b5c0f
UD
349# endif
350
365afefc 351 if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK)
fd1b5c0f
UD
352 return status;
353 }
354#endif
355
3aaad0b6
UD
356#if !defined _STRING_ARCH_unaligned \
357 && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \
358 && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0
359 /* The following assumes that encodings, which have a variable length
360 what might unalign a buffer even though it is a aligned in the
361 beginning, either don't have the minimal number of bytes as a divisor
362 of the maximum length or have a minimum length of 1. This is true
363 for all known and supported encodings. */
364 unaligned = ((FROM_DIRECTION
365 && ((uintptr_t) inptr % MIN_NEEDED_FROM != 0
85830c4c 366 || ((data->__flags & __GCONV_IS_LAST)
3aaad0b6
UD
367 && (uintptr_t) outbuf % MIN_NEEDED_TO != 0)))
368 || (!FROM_DIRECTION
85830c4c 369 && (((data->__flags & __GCONV_IS_LAST)
3aaad0b6
UD
370 && (uintptr_t) outbuf % MIN_NEEDED_FROM != 0)
371 || (uintptr_t) inptr % MIN_NEEDED_TO != 0)));
372#endif
373
8619129f
UD
374 do
375 {
376 /* Remember the start value for this round. */
fd1b5c0f 377 inptr = *inptrp;
8619129f 378 /* The outbuf buffer is empty. */
b117f744 379 outstart = outbuf;
8619129f 380
8619129f
UD
381#ifdef SAVE_RESET_STATE
382 SAVE_RESET_STATE (1);
383#endif
384
365afefc 385 if (__builtin_expect (!unaligned, 1))
77e1d15a
UD
386 {
387 if (FROM_DIRECTION)
388 /* Run the conversion loop. */
fd1b5c0f 389 status = FROM_LOOP (inptrp, inend, &outbuf, outend,
85830c4c
UD
390 data->__statep, data->__flags,
391 step->__data, &converted EXTRA_LOOP_ARGS);
77e1d15a
UD
392 else
393 /* Run the conversion loop. */
fd1b5c0f 394 status = TO_LOOP (inptrp, inend, &outbuf, outend,
85830c4c
UD
395 data->__statep, data->__flags,
396 step->__data, &converted EXTRA_LOOP_ARGS);
77e1d15a 397 }
c1db8b0d
UD
398#if !defined _STRING_ARCH_unaligned \
399 && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \
400 && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0
8619129f 401 else
77e1d15a
UD
402 {
403 if (FROM_DIRECTION)
404 /* Run the conversion loop. */
fd1b5c0f 405 status = GEN_unaligned (FROM_LOOP) (inptrp, inend, &outbuf,
77e1d15a 406 outend, data->__statep,
85830c4c 407 data->__flags,
77e1d15a
UD
408 step->__data, &converted
409 EXTRA_LOOP_ARGS);
410 else
411 /* Run the conversion loop. */
fd1b5c0f 412 status = GEN_unaligned (TO_LOOP) (inptrp, inend, &outbuf,
77e1d15a 413 outend, data->__statep,
85830c4c 414 data->__flags,
77e1d15a
UD
415 step->__data, &converted
416 EXTRA_LOOP_ARGS);
417 }
418#endif
8619129f 419
0aece08d
UD
420 /* We finished one use of the loops. */
421 ++data->__invocation_counter;
422
390955cb 423 /* If this is the last step leave the loop, there is nothing
8619129f 424 we can do. */
365afefc 425 if (__builtin_expect (data->__flags & __GCONV_IS_LAST, 0))
8619129f
UD
426 {
427 /* Store information about how many bytes are available. */
d64b6ad0 428 data->__outbuf = outbuf;
bf979eef 429
63e04088 430 /* Remember how many non-identical characters we converted. */
bf979eef
UD
431 *written += converted;
432
8619129f
UD
433 break;
434 }
435
436 /* Write out all output which was produced. */
365afefc 437 if (__builtin_expect (outbuf > outstart, 1))
8619129f 438 {
d64b6ad0 439 const unsigned char *outerr = data->__outbuf;
8619129f
UD
440 int result;
441
4bae5567 442 result = DL_CALL_FCT (fct, (next_step, next_data, &outerr,
fd1b5c0f
UD
443 outbuf, written, 0,
444 consume_incomplete));
8619129f 445
d64b6ad0 446 if (result != __GCONV_EMPTY_INPUT)
8619129f 447 {
978ce92b 448 if (__builtin_expect (outerr != outbuf, 0))
8619129f
UD
449 {
450#ifdef RESET_INPUT_BUFFER
451 RESET_INPUT_BUFFER;
452#else
453 /* We have a problem with the in on of the functions
454 below. Undo the conversion upto the error point. */
455 size_t nstatus;
456
457 /* Reload the pointers. */
fd1b5c0f 458 *inptrp = inptr;
b117f744 459 outbuf = outstart;
8619129f
UD
460
461 /* Reset the state. */
462# ifdef SAVE_RESET_STATE
463 SAVE_RESET_STATE (0);
464# endif
465
85830c4c 466 /* XXX Handle unaligned access here as well. */
8619129f
UD
467 if (FROM_DIRECTION)
468 /* Run the conversion loop. */
fd1b5c0f
UD
469 nstatus = FROM_LOOP ((const unsigned char **) inptrp,
470 (const unsigned char *) inend,
8619129f
UD
471 (unsigned char **) &outbuf,
472 (unsigned char *) outerr,
85830c4c
UD
473 data->__statep, data->__flags,
474 step->__data, &converted
475 EXTRA_LOOP_ARGS);
8619129f
UD
476 else
477 /* Run the conversion loop. */
fd1b5c0f
UD
478 nstatus = TO_LOOP ((const unsigned char **) inptrp,
479 (const unsigned char *) inend,
8619129f
UD
480 (unsigned char **) &outbuf,
481 (unsigned char *) outerr,
85830c4c
UD
482 data->__statep, data->__flags,
483 step->__data, &converted
484 EXTRA_LOOP_ARGS);
8619129f
UD
485
486 /* We must run out of output buffer space in this
487 rerun. */
5aa8ff62 488 assert (outbuf == outerr);
d64b6ad0 489 assert (nstatus == __GCONV_FULL_OUTPUT);
0aece08d
UD
490
491 /* If we haven't consumed a single byte decrement
492 the invocation counter. */
365afefc 493 if (__builtin_expect (outbuf == outstart, 0))
0aece08d 494 --data->__invocation_counter;
8619129f
UD
495#endif /* reset input buffer */
496 }
497
498 /* Change the status. */
499 status = result;
500 }
501 else
502 /* All the output is consumed, we can make another run
503 if everything was ok. */
d64b6ad0
UD
504 if (status == __GCONV_FULL_OUTPUT)
505 status = __GCONV_OK;
8619129f
UD
506 }
507 }
d64b6ad0 508 while (status == __GCONV_OK);
8619129f 509
918b9d72
UD
510#ifdef END_LOOP
511 END_LOOP
512#endif
fd1b5c0f
UD
513
514 /* If we are supposed to consume all character store now all of the
515 remaining characters in the `state' object. */
516#if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1
517 if (((MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
518 || (MAX_NEEDED_TO > 1 && !FROM_DIRECTION))
365afefc
UD
519 && __builtin_expect (consume_incomplete, 0)
520 && status == __GCONV_INCOMPLETE_INPUT)
fd1b5c0f
UD
521 {
522# ifdef STORE_REST
523 mbstate_t *state = data->__statep;
524
525 STORE_REST
526# else
527 size_t cnt;
528
529 /* Make sure the remaining bytes fit into the state objects
530 buffer. */
531 assert (inend - *inptrp < 4);
532
533 for (cnt = 0; *inptrp < inend; ++cnt)
534 data->__statep->__value.__wchb[cnt] = *(*inptrp)++;
535 data->__statep->__count &= ~7;
536 data->__statep->__count |= cnt;
537# endif
538 }
539#endif
8619129f
UD
540 }
541
542 return status;
543}
544
545#undef DEFINE_INIT
546#undef CHARSET_NAME
547#undef DEFINE_FINI
548#undef MIN_NEEDED_FROM
549#undef MIN_NEEDED_TO
550#undef MAX_NEEDED_FROM
551#undef MAX_NEEDED_TO
552#undef DEFINE_DIRECTION_OBJECTS
553#undef FROM_DIRECTION
554#undef EMIT_SHIFT_TO_INIT
555#undef FROM_LOOP
556#undef TO_LOOP
557#undef RESET_STATE
558#undef RESET_INPUT_BUFFER
559#undef FUNCTION_NAME
918b9d72
UD
560#undef PREPARE_LOOP
561#undef END_LOOP
fd1b5c0f
UD
562#undef ONE_DIRECTION
563#undef STORE_REST