5 #define YY_INT_ALIGNED short int
7 /* A lexical scanner generated by flex */
10 #define YY_FLEX_MAJOR_VERSION 2
11 #define YY_FLEX_MINOR_VERSION 5
12 #define YY_FLEX_SUBMINOR_VERSION 31
13 #if YY_FLEX_SUBMINOR_VERSION > 0
17 /* First, we deal with platform-specific or compiler-specific issues. */
19 /* begin standard C headers. */
25 /* end standard C headers. */
27 /* flex integer type definitions */
32 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
34 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
36 typedef int8_t flex_int8_t
;
37 typedef uint8_t flex_uint8_t
;
38 typedef int16_t flex_int16_t
;
39 typedef uint16_t flex_uint16_t
;
40 typedef int32_t flex_int32_t
;
41 typedef uint32_t flex_uint32_t
;
43 typedef signed char flex_int8_t
;
44 typedef short int flex_int16_t
;
45 typedef int flex_int32_t
;
46 typedef unsigned char flex_uint8_t
;
47 typedef unsigned short int flex_uint16_t
;
48 typedef unsigned int flex_uint32_t
;
51 /* Limits of integral types. */
53 #define INT8_MIN (-128)
56 #define INT16_MIN (-32767-1)
59 #define INT32_MIN (-2147483647-1)
62 #define INT8_MAX (127)
65 #define INT16_MAX (32767)
68 #define INT32_MAX (2147483647)
71 #define UINT8_MAX (255U)
74 #define UINT16_MAX (65535U)
77 #define UINT32_MAX (4294967295U)
80 #endif /* ! FLEXINT_H */
84 /* The "const" storage-class-modifier is valid. */
87 #else /* ! __cplusplus */
94 #endif /* ! __cplusplus */
102 /* Returned upon end-of-file. */
105 /* Promotes a possibly negative, possibly signed char to an unsigned
106 * integer for use as an array index. If the signed char is negative,
107 * we want to instead treat it as an 8-bit unsigned char, hence the
110 #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
112 /* Enter a start condition. This macro really ought to take a parameter,
113 * but we do it the disgusting crufty way forced on us by the ()-less
114 * definition of BEGIN.
116 #define BEGIN (yy_start) = 1 + 2 *
118 /* Translate the current start state into a value that can be later handed
119 * to BEGIN to return to the state. The YYSTATE alias is for lex
122 #define YY_START (((yy_start) - 1) / 2)
123 #define YYSTATE YY_START
125 /* Action number for EOF rule of a given start state. */
126 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
128 /* Special action meaning "start processing a new file". */
129 #define YY_NEW_FILE rtfrestart(rtfin )
131 #define YY_END_OF_BUFFER_CHAR 0
133 /* Size of default input buffer. */
135 #define YY_BUF_SIZE 16384
138 #ifndef YY_TYPEDEF_YY_BUFFER_STATE
139 #define YY_TYPEDEF_YY_BUFFER_STATE
140 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
145 extern FILE *rtfin
, *rtfout
;
147 #define EOB_ACT_CONTINUE_SCAN 0
148 #define EOB_ACT_END_OF_FILE 1
149 #define EOB_ACT_LAST_MATCH 2
151 #define YY_LESS_LINENO(n)
153 /* Return all but the first "n" matched characters back to the input stream. */
157 /* Undo effects of setting up rtftext. */ \
158 int yyless_macro_arg = (n); \
159 YY_LESS_LINENO(yyless_macro_arg);\
160 *yy_cp = (yy_hold_char); \
161 YY_RESTORE_YY_MORE_OFFSET \
162 (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
163 YY_DO_BEFORE_ACTION; /* set up rtftext again */ \
167 #define unput(c) yyunput( c, (yytext_ptr) )
169 /* The following is because we cannot portably get our hands on size_t
170 * (without autoconf's help, which isn't available because we want
171 * flex-generated scanners to compile on their own).
174 #ifndef YY_TYPEDEF_YY_SIZE_T
175 #define YY_TYPEDEF_YY_SIZE_T
176 typedef unsigned int yy_size_t
;
179 #ifndef YY_STRUCT_YY_BUFFER_STATE
180 #define YY_STRUCT_YY_BUFFER_STATE
181 struct yy_buffer_state
185 char *yy_ch_buf
; /* input buffer */
186 char *yy_buf_pos
; /* current position in input buffer */
188 /* Size of input buffer in bytes, not including room for EOB
191 yy_size_t yy_buf_size
;
193 /* Number of characters read into yy_ch_buf, not including EOB
198 /* Whether we "own" the buffer - i.e., we know we created it,
199 * and can realloc() it to grow it, and should free() it to
202 int yy_is_our_buffer
;
204 /* Whether this is an "interactive" input source; if so, and
205 * if we're using stdio for input, then we want to use getc()
206 * instead of fread(), to make sure we stop fetching input after
209 int yy_is_interactive
;
211 /* Whether we're considered to be at the beginning of a line.
212 * If so, '^' rules will be active on the next match, otherwise
217 int yy_bs_lineno
; /**< The line count. */
218 int yy_bs_column
; /**< The column count. */
220 /* Whether to try to fill the input buffer when we reach the
225 int yy_buffer_status
;
227 #define YY_BUFFER_NEW 0
228 #define YY_BUFFER_NORMAL 1
229 /* When an EOF's been seen but there's still some text to process
230 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
231 * shouldn't try reading from the input source any more. We might
232 * still have a bunch of tokens to match, though, because of
233 * possible backing-up.
235 * When we actually see the EOF, we change the status to "new"
236 * (via rtfrestart()), so that the user can continue scanning by
237 * just pointing rtfin at a new input file.
239 #define YY_BUFFER_EOF_PENDING 2
242 #endif /* !YY_STRUCT_YY_BUFFER_STATE */
244 /* Stack of input buffers. */
245 static size_t yy_buffer_stack_top
= 0; /**< index of top of stack. */
246 static size_t yy_buffer_stack_max
= 0; /**< capacity of stack. */
247 static YY_BUFFER_STATE
* yy_buffer_stack
= 0; /**< Stack as an array. */
249 /* We provide macros for accessing buffer states in case in the
250 * future we want to put the buffer states in a more general
253 * Returns the top of the stack, or NULL.
255 #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
256 ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
259 /* Same as previous macro, but useful when we know that the buffer stack is not
260 * NULL or when we need an lvalue. For internal use only.
262 #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
264 /* yy_hold_char holds the character lost when rtftext is formed. */
265 static char yy_hold_char
;
266 static int yy_n_chars
; /* number of characters read into yy_ch_buf */
269 /* Points to current character in buffer. */
270 static char *yy_c_buf_p
= (char *) 0;
271 static int yy_init
= 1; /* whether we need to initialize */
272 static int yy_start
= 0; /* start state number */
274 /* Flag which is used to allow rtfwrap()'s to do buffer switches
275 * instead of setting up a fresh rtfin. A bit of a hack ...
277 static int yy_did_buffer_switch_on_eof
;
279 void rtfrestart (FILE *input_file
);
280 void rtf_switch_to_buffer (YY_BUFFER_STATE new_buffer
);
281 YY_BUFFER_STATE
rtf_create_buffer (FILE *file
,int size
);
282 void rtf_delete_buffer (YY_BUFFER_STATE b
);
283 void rtf_flush_buffer (YY_BUFFER_STATE b
);
284 void rtfpush_buffer_state (YY_BUFFER_STATE new_buffer
);
285 void rtfpop_buffer_state (void );
287 static void rtfensure_buffer_stack (void );
288 static void rtf_load_buffer_state (void );
289 static void rtf_init_buffer (YY_BUFFER_STATE b
,FILE *file
);
291 #define YY_FLUSH_BUFFER rtf_flush_buffer(YY_CURRENT_BUFFER )
293 YY_BUFFER_STATE
rtf_scan_buffer (char *base
,yy_size_t size
);
294 YY_BUFFER_STATE
rtf_scan_string (yyconst
char *yy_str
);
295 YY_BUFFER_STATE
rtf_scan_bytes (yyconst
char *bytes
,int len
);
297 void *rtfalloc (yy_size_t
);
298 void *rtfrealloc (void *,yy_size_t
);
299 void rtffree (void * );
301 #define yy_new_buffer rtf_create_buffer
303 #define yy_set_interactive(is_interactive) \
305 if ( ! YY_CURRENT_BUFFER ){ \
306 rtfensure_buffer_stack (); \
307 YY_CURRENT_BUFFER_LVALUE = \
308 rtf_create_buffer(rtfin,YY_BUF_SIZE ); \
310 YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
313 #define yy_set_bol(at_bol) \
315 if ( ! YY_CURRENT_BUFFER ){\
316 rtfensure_buffer_stack (); \
317 YY_CURRENT_BUFFER_LVALUE = \
318 rtf_create_buffer(rtfin,YY_BUF_SIZE ); \
320 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
323 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
325 /* Begin user sect3 */
327 typedef unsigned char YY_CHAR
;
329 FILE *rtfin
= (FILE *) 0, *rtfout
= (FILE *) 0;
331 typedef int yy_state_type
;
333 extern int rtflineno
;
337 extern char *rtftext
;
338 #define yytext_ptr rtftext
340 static yy_state_type
yy_get_previous_state (void );
341 static yy_state_type
yy_try_NUL_trans (yy_state_type current_state
);
342 static int yy_get_next_buffer (void );
343 static void yy_fatal_error (yyconst
char msg
[] );
345 /* Done after the current pattern has been matched and before the
346 * corresponding action - sets up rtftext.
348 #define YY_DO_BEFORE_ACTION \
349 (yytext_ptr) = yy_bp; \
350 rtfleng = (size_t) (yy_cp - yy_bp); \
351 (yy_hold_char) = *yy_cp; \
353 (yy_c_buf_p) = yy_cp;
355 #define YY_NUM_RULES 10
356 #define YY_END_OF_BUFFER 11
357 /* This struct is not used in this scanner,
358 but its presence is necessary. */
361 flex_int32_t yy_verify
;
364 static yyconst flex_int16_t yy_accept
[33] =
366 0, 0, 11, 8, 8, 9, 9, 1, 2, 8,
367 0, 0, 5, 3, 5, 0, 0, 5, 5, 5,
368 0, 6, 5, 7, 5, 5, 5, 4, 5, 5,
372 static yyconst flex_int32_t yy_ec
[256] =
374 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
375 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
376 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
377 1, 3, 1, 1, 4, 1, 1, 1, 5, 1,
378 1, 1, 1, 1, 1, 1, 1, 6, 6, 6,
379 6, 6, 6, 6, 6, 6, 6, 1, 1, 7,
380 1, 8, 9, 1, 10, 10, 10, 10, 10, 10,
381 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
382 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
383 1, 12, 1, 1, 1, 1, 10, 10, 10, 10,
385 10, 10, 11, 11, 11, 11, 11, 11, 11, 11,
386 11, 11, 11, 11, 11, 11, 13, 11, 11, 11,
387 11, 11, 14, 1, 15, 1, 1, 1, 1, 1,
388 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
389 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
390 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
391 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
392 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
393 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
394 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
396 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
397 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
398 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
399 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
400 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
404 static yyconst flex_int32_t yy_meta
[16] =
406 1, 1, 2, 1, 1, 2, 3, 4, 1, 2,
410 static yyconst flex_int16_t yy_base
[37] =
412 0, 14, 45, 0, 0, 39, 25, 59, 59, 0,
413 38, 0, 2, 59, 14, 0, 3, 59, 16, 21,
414 25, 59, 28, 59, 38, 23, 19, 59, 17, 12,
418 static yyconst flex_int16_t yy_def
[37] =
420 33, 33, 32, 34, 34, 32, 32, 32, 32, 34,
421 32, 32, 35, 32, 35, 36, 32, 32, 32, 32,
422 36, 32, 32, 32, 32, 32, 25, 32, 25, 25,
423 25, 0, 32, 32, 32, 32
426 static yyconst flex_int16_t yy_nxt
[75] =
428 32, 5, 13, 32, 18, 17, 6, 19, 22, 17,
429 19, 7, 22, 8, 9, 5, 18, 31, 18, 20,
430 6, 19, 30, 18, 29, 7, 23, 8, 9, 12,
431 18, 28, 24, 25, 13, 13, 14, 15, 14, 14,
432 26, 16, 11, 27, 32, 32, 28, 4, 4, 4,
433 4, 10, 10, 32, 10, 21, 21, 21, 3, 32,
434 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
438 static yyconst flex_int16_t yy_chk
[75] =
440 0, 1, 35, 0, 13, 12, 1, 13, 17, 12,
441 31, 1, 17, 1, 1, 2, 15, 30, 19, 15,
442 2, 19, 29, 20, 27, 2, 20, 2, 2, 7,
443 23, 26, 21, 23, 7, 7, 7, 7, 7, 7,
444 25, 11, 6, 25, 3, 0, 25, 33, 33, 33,
445 33, 34, 34, 0, 34, 36, 36, 36, 32, 32,
446 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
450 static yy_state_type yy_last_accepting_state
;
451 static char *yy_last_accepting_cpos
;
453 extern int rtf_flex_debug
;
454 int rtf_flex_debug
= 0;
456 /* The intent behind this definition is that it'll catch
457 * any uses of REJECT which flex missed.
459 #define REJECT reject_used_but_not_detected
460 #define yymore() yymore_used_but_not_detected
461 #define YY_MORE_ADJ 0
462 #define YY_RESTORE_YY_MORE_OFFSET
467 rtf.ll - A simple RTF Parser (Flex code)
469 Copyright (c) 2002 by Vladimir Shutoff <vovan@shutoff.ru> (original code)
470 Copyright (c) 2004 by Thiago S. Barcelos <barcelos@ime.usp.br> (Kopete port)
471 Kopete (c) 2002-2003 by the Kopete developers <kopete-devel@kde.org>
473 *************************************************************************
475 * This program is free software; you can redistribute it and/or modify *
476 * it under the terms of the GNU General Public License as published by *
477 * the Free Software Foundation; either version 2 of the License, or *
478 * (at your option) any later version. *
480 *************************************************************************
483 flex -olex.yy.c `test -f rtf.ll || echo './'`rtf.ll
484 sed '/^#/ s|lex.yy\.c|rtf.cc|' lex.yy.c >rtf.cc
495 #define UNICODE_CHAR 7
500 #define YY_NEVER_INTERACTIVE 1
501 #define YY_ALWAYS_INTERACTIVE 0
508 #ifndef YY_NO_UNISTD_H
509 /* Special case for "unistd.h", since it is non-ANSI. We include it way
510 * down here because we want the user's section 1 to have been scanned first.
511 * The user has a chance to override it with an option.
516 #ifndef YY_EXTRA_TYPE
517 #define YY_EXTRA_TYPE void *
520 /* Macros after this point can all be overridden by user definitions in
524 #ifndef YY_SKIP_YYWRAP
526 extern "C" int rtfwrap (void );
528 extern int rtfwrap (void );
533 static void yy_flex_strncpy (char *,yyconst
char *,int );
536 #ifdef YY_NEED_STRLEN
537 static int yy_flex_strlen (yyconst
char * );
543 static int yyinput (void );
545 static int input (void );
550 /* Amount of stuff to slurp up with each read. */
551 #ifndef YY_READ_BUF_SIZE
552 #define YY_READ_BUF_SIZE 8192
555 /* Copy whatever the last rule matched to the standard output. */
557 /* This used to be an fputs(), but since the string might contain NUL's,
558 * we now use fwrite().
560 #define ECHO (void) fwrite( rtftext, rtfleng, 1, rtfout )
563 /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
564 * is returned in "result".
567 #define YY_INPUT(buf,result,max_size) \
568 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
572 for ( n = 0; n < max_size && \
573 (c = getc( rtfin )) != EOF && c != '\n'; ++n ) \
576 buf[n++] = (char) c; \
577 if ( c == EOF && ferror( rtfin ) ) \
578 YY_FATAL_ERROR( "input in flex scanner failed" ); \
584 while ( (result = fread(buf, 1, max_size, rtfin))==0 && ferror(rtfin)) \
586 if( errno != EINTR) \
588 YY_FATAL_ERROR( "input in flex scanner failed" ); \
599 /* No semi-colon after return; correct usage is to write "yyterminate();" -
600 * we don't want an extra ';' after the "return" because that will cause
601 * some compilers to complain about unreachable statements.
604 #define yyterminate() return YY_NULL
607 /* Number of entries by which start-condition stack grows. */
608 #ifndef YY_START_STACK_INCR
609 #define YY_START_STACK_INCR 25
612 /* Report a fatal error. */
613 #ifndef YY_FATAL_ERROR
614 #define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
617 /* end tables serialization structures and prototypes */
619 /* Default declaration of generated scanner - a define so the user can
620 * easily add parameters.
623 #define YY_DECL_IS_OURS 1
625 extern int rtflex (void);
627 #define YY_DECL int rtflex (void)
628 #endif /* !YY_DECL */
630 /* Code executed at the beginning of each rule, after rtftext and rtfleng
633 #ifndef YY_USER_ACTION
634 #define YY_USER_ACTION
637 /* Code executed at the end of each rule. */
639 #define YY_BREAK break;
642 #define YY_RULE_SETUP \
645 /** The main scanner function which does all the work.
649 register yy_state_type yy_current_state
;
650 register char *yy_cp
, *yy_bp
;
667 (yy_start
) = 1; /* first start state */
675 if ( ! YY_CURRENT_BUFFER
) {
676 rtfensure_buffer_stack ();
677 YY_CURRENT_BUFFER_LVALUE
=
678 rtf_create_buffer(rtfin
,YY_BUF_SIZE
);
681 rtf_load_buffer_state( );
684 while ( 1 ) /* loops until end-of-file is reached */
686 yy_cp
= (yy_c_buf_p
);
688 /* Support of rtftext. */
689 *yy_cp
= (yy_hold_char
);
691 /* yy_bp points to the position in yy_ch_buf of the start of
696 yy_current_state
= (yy_start
);
700 register YY_CHAR yy_c
= yy_ec
[YY_SC_TO_UI(*yy_cp
)];
701 if ( yy_accept
[yy_current_state
] )
703 (yy_last_accepting_state
) = yy_current_state
;
704 (yy_last_accepting_cpos
) = yy_cp
;
706 while ( yy_chk
[yy_base
[yy_current_state
] + yy_c
] != yy_current_state
)
708 yy_current_state
= (int) yy_def
[yy_current_state
];
709 if ( yy_current_state
>= 33 )
710 yy_c
= yy_meta
[(unsigned int) yy_c
];
712 yy_current_state
= yy_nxt
[yy_base
[yy_current_state
] + (unsigned int) yy_c
];
715 while ( yy_base
[yy_current_state
] != 59 );
718 yy_act
= yy_accept
[yy_current_state
];
720 { /* have to back up */
721 yy_cp
= (yy_last_accepting_cpos
);
722 yy_current_state
= (yy_last_accepting_state
);
723 yy_act
= yy_accept
[yy_current_state
];
728 do_action
: /* This label is used only to access EOF actions. */
731 { /* beginning of action switch */
732 case 0: /* must back up */
733 /* undo the effects of YY_DO_BEFORE_ACTION */
734 *yy_cp
= (yy_hold_char
);
735 yy_cp
= (yy_last_accepting_cpos
);
736 yy_current_state
= (yy_last_accepting_state
);
757 { return UNICODE_CHAR
; }
770 /* rule 7 can match eol */
776 /* rule 8 can match eol */
792 case YY_STATE_EOF(INITIAL
):
795 case YY_END_OF_BUFFER
:
797 /* Amount of text matched not including the EOB char. */
798 int yy_amount_of_matched_text
= (int) (yy_cp
- (yytext_ptr
)) - 1;
800 /* Undo the effects of YY_DO_BEFORE_ACTION. */
801 *yy_cp
= (yy_hold_char
);
802 YY_RESTORE_YY_MORE_OFFSET
804 if ( YY_CURRENT_BUFFER_LVALUE
->yy_buffer_status
== YY_BUFFER_NEW
)
806 /* We're scanning a new file or input source. It's
807 * possible that this happened because the user
808 * just pointed rtfin at a new source and called
809 * rtflex(). If so, then we have to assure
810 * consistency between YY_CURRENT_BUFFER and our
811 * globals. Here is the right place to do so, because
812 * this is the first action (other than possibly a
813 * back-up) that will match for the new input source.
815 (yy_n_chars
) = YY_CURRENT_BUFFER_LVALUE
->yy_n_chars
;
816 YY_CURRENT_BUFFER_LVALUE
->yy_input_file
= rtfin
;
817 YY_CURRENT_BUFFER_LVALUE
->yy_buffer_status
= YY_BUFFER_NORMAL
;
820 /* Note that here we test for yy_c_buf_p "<=" to the position
821 * of the first EOB in the buffer, since yy_c_buf_p will
822 * already have been incremented past the NUL character
823 * (since all states make transitions on EOB to the
824 * end-of-buffer state). Contrast this with the test
827 if ( (yy_c_buf_p
) <= &YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
[(yy_n_chars
)] )
828 { /* This was really a NUL. */
829 yy_state_type yy_next_state
;
831 (yy_c_buf_p
) = (yytext_ptr
) + yy_amount_of_matched_text
;
833 yy_current_state
= yy_get_previous_state( );
835 /* Okay, we're now positioned to make the NUL
836 * transition. We couldn't have
837 * yy_get_previous_state() go ahead and do it
838 * for us because it doesn't know how to deal
839 * with the possibility of jamming (and we don't
840 * want to build jamming into it because then it
841 * will run more slowly).
844 yy_next_state
= yy_try_NUL_trans( yy_current_state
);
846 yy_bp
= (yytext_ptr
) + YY_MORE_ADJ
;
850 /* Consume the NUL. */
851 yy_cp
= ++(yy_c_buf_p
);
852 yy_current_state
= yy_next_state
;
858 yy_cp
= (yy_c_buf_p
);
863 else switch ( yy_get_next_buffer( ) )
865 case EOB_ACT_END_OF_FILE
:
867 (yy_did_buffer_switch_on_eof
) = 0;
871 /* Note: because we've taken care in
872 * yy_get_next_buffer() to have set up
873 * rtftext, we can now set up
874 * yy_c_buf_p so that if some total
875 * hoser (like flex itself) wants to
876 * call the scanner after we return the
877 * YY_NULL, it'll still work - another
878 * YY_NULL will get returned.
880 (yy_c_buf_p
) = (yytext_ptr
) + YY_MORE_ADJ
;
882 yy_act
= YY_STATE_EOF(YY_START
);
888 if ( ! (yy_did_buffer_switch_on_eof
) )
894 case EOB_ACT_CONTINUE_SCAN
:
896 (yytext_ptr
) + yy_amount_of_matched_text
;
898 yy_current_state
= yy_get_previous_state( );
900 yy_cp
= (yy_c_buf_p
);
901 yy_bp
= (yytext_ptr
) + YY_MORE_ADJ
;
904 case EOB_ACT_LAST_MATCH
:
906 &YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
[(yy_n_chars
)];
908 yy_current_state
= yy_get_previous_state( );
910 yy_cp
= (yy_c_buf_p
);
911 yy_bp
= (yytext_ptr
) + YY_MORE_ADJ
;
919 "fatal flex scanner internal error--no action found" );
920 } /* end of action switch */
921 } /* end of scanning one token */
922 } /* end of rtflex */
924 /* yy_get_next_buffer - try to read in a new buffer
926 * Returns a code representing an action:
927 * EOB_ACT_LAST_MATCH -
928 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
929 * EOB_ACT_END_OF_FILE - end of file
931 static int yy_get_next_buffer (void)
933 register char *dest
= YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
;
934 register char *source
= (yytext_ptr
);
935 register int number_to_move
, i
;
938 if ( (yy_c_buf_p
) > &YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
[(yy_n_chars
) + 1] )
940 "fatal flex scanner internal error--end of buffer missed" );
942 if ( YY_CURRENT_BUFFER_LVALUE
->yy_fill_buffer
== 0 )
943 { /* Don't try to fill the buffer, so this is an EOF. */
944 if ( (yy_c_buf_p
) - (yytext_ptr
) - YY_MORE_ADJ
== 1 )
946 /* We matched a single character, the EOB, so
947 * treat this as a final EOF.
949 return EOB_ACT_END_OF_FILE
;
954 /* We matched some text prior to the EOB, first
957 return EOB_ACT_LAST_MATCH
;
961 /* Try to read more data. */
963 /* First move last chars to start of buffer. */
964 number_to_move
= (int) ((yy_c_buf_p
) - (yytext_ptr
)) - 1;
966 for ( i
= 0; i
< number_to_move
; ++i
)
967 *(dest
++) = *(source
++);
969 if ( YY_CURRENT_BUFFER_LVALUE
->yy_buffer_status
== YY_BUFFER_EOF_PENDING
)
970 /* don't do the read, it's not guaranteed to return an EOF,
973 YY_CURRENT_BUFFER_LVALUE
->yy_n_chars
= (yy_n_chars
) = 0;
978 YY_CURRENT_BUFFER_LVALUE
->yy_buf_size
- number_to_move
- 1;
980 while ( num_to_read
<= 0 )
981 { /* Not enough room in the buffer - grow it. */
983 /* just a shorter name for the current buffer */
984 YY_BUFFER_STATE b
= YY_CURRENT_BUFFER
;
986 int yy_c_buf_p_offset
=
987 (int) ((yy_c_buf_p
) - b
->yy_ch_buf
);
989 if ( b
->yy_is_our_buffer
)
991 int new_size
= b
->yy_buf_size
* 2;
994 b
->yy_buf_size
+= b
->yy_buf_size
/ 8;
998 b
->yy_ch_buf
= (char *)
999 /* Include room in for 2 EOB chars. */
1000 rtfrealloc((void *) b
->yy_ch_buf
,b
->yy_buf_size
+ 2 );
1003 /* Can't grow it, we don't own it. */
1006 if ( ! b
->yy_ch_buf
)
1008 "fatal error - scanner input buffer overflow" );
1010 (yy_c_buf_p
) = &b
->yy_ch_buf
[yy_c_buf_p_offset
];
1012 num_to_read
= YY_CURRENT_BUFFER_LVALUE
->yy_buf_size
-
1017 if ( num_to_read
> YY_READ_BUF_SIZE
)
1018 num_to_read
= YY_READ_BUF_SIZE
;
1020 /* Read in more data. */
1021 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
[number_to_move
]),
1022 (yy_n_chars
), num_to_read
);
1024 YY_CURRENT_BUFFER_LVALUE
->yy_n_chars
= (yy_n_chars
);
1027 if ( (yy_n_chars
) == 0 )
1029 if ( number_to_move
== YY_MORE_ADJ
)
1031 ret_val
= EOB_ACT_END_OF_FILE
;
1037 ret_val
= EOB_ACT_LAST_MATCH
;
1038 YY_CURRENT_BUFFER_LVALUE
->yy_buffer_status
=
1039 YY_BUFFER_EOF_PENDING
;
1044 ret_val
= EOB_ACT_CONTINUE_SCAN
;
1046 (yy_n_chars
) += number_to_move
;
1047 YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
[(yy_n_chars
)] = YY_END_OF_BUFFER_CHAR
;
1048 YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
[(yy_n_chars
) + 1] = YY_END_OF_BUFFER_CHAR
;
1050 (yytext_ptr
) = &YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
[0];
1055 /* yy_get_previous_state - get the state just before the EOB char was reached */
1057 static yy_state_type
yy_get_previous_state (void)
1059 register yy_state_type yy_current_state
;
1060 register char *yy_cp
;
1062 yy_current_state
= (yy_start
);
1064 for ( yy_cp
= (yytext_ptr
) + YY_MORE_ADJ
; yy_cp
< (yy_c_buf_p
); ++yy_cp
)
1066 register YY_CHAR yy_c
= (*yy_cp
? yy_ec
[YY_SC_TO_UI(*yy_cp
)] : 1);
1067 if ( yy_accept
[yy_current_state
] )
1069 (yy_last_accepting_state
) = yy_current_state
;
1070 (yy_last_accepting_cpos
) = yy_cp
;
1072 while ( yy_chk
[yy_base
[yy_current_state
] + yy_c
] != yy_current_state
)
1074 yy_current_state
= (int) yy_def
[yy_current_state
];
1075 if ( yy_current_state
>= 33 )
1076 yy_c
= yy_meta
[(unsigned int) yy_c
];
1078 yy_current_state
= yy_nxt
[yy_base
[yy_current_state
] + (unsigned int) yy_c
];
1081 return yy_current_state
;
1084 /* yy_try_NUL_trans - try to make a transition on the NUL character
1087 * next_state = yy_try_NUL_trans( current_state );
1089 static yy_state_type
yy_try_NUL_trans (yy_state_type yy_current_state
)
1091 register int yy_is_jam
;
1092 register char *yy_cp
= (yy_c_buf_p
);
1094 register YY_CHAR yy_c
= 1;
1095 if ( yy_accept
[yy_current_state
] )
1097 (yy_last_accepting_state
) = yy_current_state
;
1098 (yy_last_accepting_cpos
) = yy_cp
;
1100 while ( yy_chk
[yy_base
[yy_current_state
] + yy_c
] != yy_current_state
)
1102 yy_current_state
= (int) yy_def
[yy_current_state
];
1103 if ( yy_current_state
>= 33 )
1104 yy_c
= yy_meta
[(unsigned int) yy_c
];
1106 yy_current_state
= yy_nxt
[yy_base
[yy_current_state
] + (unsigned int) yy_c
];
1107 yy_is_jam
= (yy_current_state
== 32);
1109 return yy_is_jam
? 0 : yy_current_state
;
1114 static int yyinput (void)
1116 static int input (void)
1122 *(yy_c_buf_p
) = (yy_hold_char
);
1124 if ( *(yy_c_buf_p
) == YY_END_OF_BUFFER_CHAR
)
1126 /* yy_c_buf_p now points to the character we want to return.
1127 * If this occurs *before* the EOB characters, then it's a
1128 * valid NUL; if not, then we've hit the end of the buffer.
1130 if ( (yy_c_buf_p
) < &YY_CURRENT_BUFFER_LVALUE
->yy_ch_buf
[(yy_n_chars
)] )
1131 /* This was really a NUL. */
1132 *(yy_c_buf_p
) = '\0';
1135 { /* need more input */
1136 int offset
= (yy_c_buf_p
) - (yytext_ptr
);
1139 switch ( yy_get_next_buffer( ) )
1141 case EOB_ACT_LAST_MATCH
:
1142 /* This happens because yy_g_n_b()
1143 * sees that we've accumulated a
1144 * token and flags that we need to
1145 * try matching the token before
1146 * proceeding. But for input(),
1147 * there's no matching to consider.
1148 * So convert the EOB_ACT_LAST_MATCH
1149 * to EOB_ACT_END_OF_FILE.
1152 /* Reset buffer status. */
1157 case EOB_ACT_END_OF_FILE
:
1162 if ( ! (yy_did_buffer_switch_on_eof
) )
1171 case EOB_ACT_CONTINUE_SCAN
:
1172 (yy_c_buf_p
) = (yytext_ptr
) + offset
;
1178 c
= *(unsigned char *) (yy_c_buf_p
); /* cast for 8-bit char's */
1179 *(yy_c_buf_p
) = '\0'; /* preserve rtftext */
1180 (yy_hold_char
) = *++(yy_c_buf_p
);
1184 #endif /* ifndef YY_NO_INPUT */
1186 /** Immediately switch to a different input stream.
1187 * @param input_file A readable stream.
1189 * @note This function does not reset the start condition to @c INITIAL .
1191 void rtfrestart (FILE * input_file
)
1194 if ( ! YY_CURRENT_BUFFER
){
1195 rtfensure_buffer_stack ();
1196 YY_CURRENT_BUFFER_LVALUE
=
1197 rtf_create_buffer(rtfin
,YY_BUF_SIZE
);
1200 rtf_init_buffer(YY_CURRENT_BUFFER
,input_file
);
1201 rtf_load_buffer_state( );
1204 /** Switch to a different input buffer.
1205 * @param new_buffer The new input buffer.
1208 void rtf_switch_to_buffer (YY_BUFFER_STATE new_buffer
)
1211 /* TODO. We should be able to replace this entire function body
1213 * rtfpop_buffer_state();
1214 * rtfpush_buffer_state(new_buffer);
1216 rtfensure_buffer_stack ();
1217 if ( YY_CURRENT_BUFFER
== new_buffer
)
1220 if ( YY_CURRENT_BUFFER
)
1222 /* Flush out information for old buffer. */
1223 *(yy_c_buf_p
) = (yy_hold_char
);
1224 YY_CURRENT_BUFFER_LVALUE
->yy_buf_pos
= (yy_c_buf_p
);
1225 YY_CURRENT_BUFFER_LVALUE
->yy_n_chars
= (yy_n_chars
);
1228 YY_CURRENT_BUFFER_LVALUE
= new_buffer
;
1229 rtf_load_buffer_state( );
1231 /* We don't actually know whether we did this switch during
1232 * EOF (rtfwrap()) processing, but the only time this flag
1233 * is looked at is after rtfwrap() is called, so it's safe
1234 * to go ahead and always set it.
1236 (yy_did_buffer_switch_on_eof
) = 1;
1239 static void rtf_load_buffer_state (void)
1241 (yy_n_chars
) = YY_CURRENT_BUFFER_LVALUE
->yy_n_chars
;
1242 (yytext_ptr
) = (yy_c_buf_p
) = YY_CURRENT_BUFFER_LVALUE
->yy_buf_pos
;
1243 rtfin
= YY_CURRENT_BUFFER_LVALUE
->yy_input_file
;
1244 (yy_hold_char
) = *(yy_c_buf_p
);
1247 /** Allocate and initialize an input buffer state.
1248 * @param file A readable stream.
1249 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
1251 * @return the allocated buffer state.
1253 YY_BUFFER_STATE
rtf_create_buffer (FILE * file
, int size
)
1257 b
= (YY_BUFFER_STATE
) rtfalloc(sizeof( struct yy_buffer_state
) );
1259 YY_FATAL_ERROR( "out of dynamic memory in rtf_create_buffer()" );
1261 b
->yy_buf_size
= size
;
1263 /* yy_ch_buf has to be 2 characters longer than the size given because
1264 * we need to put in 2 end-of-buffer characters.
1266 b
->yy_ch_buf
= (char *) rtfalloc(b
->yy_buf_size
+ 2 );
1267 if ( ! b
->yy_ch_buf
)
1268 YY_FATAL_ERROR( "out of dynamic memory in rtf_create_buffer()" );
1270 b
->yy_is_our_buffer
= 1;
1272 rtf_init_buffer(b
,file
);
1277 /** Destroy the buffer.
1278 * @param b a buffer created with rtf_create_buffer()
1281 void rtf_delete_buffer (YY_BUFFER_STATE b
)
1287 if ( b
== YY_CURRENT_BUFFER
) /* Not sure if we should pop here. */
1288 YY_CURRENT_BUFFER_LVALUE
= (YY_BUFFER_STATE
) 0;
1290 if ( b
->yy_is_our_buffer
)
1291 rtffree((void *) b
->yy_ch_buf
);
1293 rtffree((void *) b
);
1297 extern int isatty (int );
1298 #endif /* __cplusplus */
1300 /* Initializes or reinitializes a buffer.
1301 * This function is sometimes called more than once on the same buffer,
1302 * such as during a rtfrestart() or at EOF.
1304 static void rtf_init_buffer (YY_BUFFER_STATE b
, FILE * file
)
1309 rtf_flush_buffer(b
);
1311 b
->yy_input_file
= file
;
1312 b
->yy_fill_buffer
= 1;
1314 /* If b is the current buffer, then rtf_init_buffer was _probably_
1315 * called from rtfrestart() or through yy_get_next_buffer.
1316 * In that case, we don't want to reset the lineno or column.
1318 if (b
!= YY_CURRENT_BUFFER
){
1319 b
->yy_bs_lineno
= 1;
1320 b
->yy_bs_column
= 0;
1323 b
->yy_is_interactive
= file
? (isatty( fileno(file
) ) > 0) : 0;
1328 /** Discard all buffered characters. On the next scan, YY_INPUT will be called.
1329 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
1332 void rtf_flush_buffer (YY_BUFFER_STATE b
)
1339 /* We always need two end-of-buffer characters. The first causes
1340 * a transition to the end-of-buffer state. The second causes
1341 * a jam in that state.
1343 b
->yy_ch_buf
[0] = YY_END_OF_BUFFER_CHAR
;
1344 b
->yy_ch_buf
[1] = YY_END_OF_BUFFER_CHAR
;
1346 b
->yy_buf_pos
= &b
->yy_ch_buf
[0];
1349 b
->yy_buffer_status
= YY_BUFFER_NEW
;
1351 if ( b
== YY_CURRENT_BUFFER
)
1352 rtf_load_buffer_state( );
1355 /** Pushes the new state onto the stack. The new state becomes
1356 * the current state. This function will allocate the stack
1358 * @param new_buffer The new state.
1361 void rtfpush_buffer_state (YY_BUFFER_STATE new_buffer
)
1363 if (new_buffer
== NULL
)
1366 rtfensure_buffer_stack();
1368 /* This block is copied from rtf_switch_to_buffer. */
1369 if ( YY_CURRENT_BUFFER
)
1371 /* Flush out information for old buffer. */
1372 *(yy_c_buf_p
) = (yy_hold_char
);
1373 YY_CURRENT_BUFFER_LVALUE
->yy_buf_pos
= (yy_c_buf_p
);
1374 YY_CURRENT_BUFFER_LVALUE
->yy_n_chars
= (yy_n_chars
);
1377 /* Only push if top exists. Otherwise, replace top. */
1378 if (YY_CURRENT_BUFFER
)
1379 (yy_buffer_stack_top
)++;
1380 YY_CURRENT_BUFFER_LVALUE
= new_buffer
;
1382 /* copied from rtf_switch_to_buffer. */
1383 rtf_load_buffer_state( );
1384 (yy_did_buffer_switch_on_eof
) = 1;
1387 /** Removes and deletes the top of the stack, if present.
1388 * The next element becomes the new top.
1391 void rtfpop_buffer_state (void)
1393 if (!YY_CURRENT_BUFFER
)
1396 rtf_delete_buffer(YY_CURRENT_BUFFER
);
1397 YY_CURRENT_BUFFER_LVALUE
= NULL
;
1398 if ((yy_buffer_stack_top
) > 0)
1399 --(yy_buffer_stack_top
);
1401 if (YY_CURRENT_BUFFER
) {
1402 rtf_load_buffer_state( );
1403 (yy_did_buffer_switch_on_eof
) = 1;
1407 /* Allocates the stack if it does not exist.
1408 * Guarantees space for at least one push.
1410 static void rtfensure_buffer_stack (void)
1414 if (!(yy_buffer_stack
)) {
1416 /* First allocation is just for 2 elements, since we don't know if this
1417 * scanner will even need a stack. We use 2 instead of 1 to avoid an
1418 * immediate realloc on the next call.
1421 (yy_buffer_stack
) = (struct yy_buffer_state
**)rtfalloc
1422 (num_to_alloc
* sizeof(struct yy_buffer_state
*)
1425 memset((yy_buffer_stack
), 0, num_to_alloc
* sizeof(struct yy_buffer_state
*));
1427 (yy_buffer_stack_max
) = num_to_alloc
;
1428 (yy_buffer_stack_top
) = 0;
1432 if ((yy_buffer_stack_top
) >= ((yy_buffer_stack_max
)) - 1){
1434 /* Increase the buffer to prepare for a possible push. */
1435 int grow_size
= 8 /* arbitrary grow size */;
1437 num_to_alloc
= (yy_buffer_stack_max
) + grow_size
;
1438 (yy_buffer_stack
) = (struct yy_buffer_state
**)rtfrealloc
1440 num_to_alloc
* sizeof(struct yy_buffer_state
*)
1443 /* zero only the new slots.*/
1444 memset((yy_buffer_stack
) + (yy_buffer_stack_max
), 0, grow_size
* sizeof(struct yy_buffer_state
*));
1445 (yy_buffer_stack_max
) = num_to_alloc
;
1449 /** Setup the input buffer state to scan directly from a user-specified character buffer.
1450 * @param base the character buffer
1451 * @param size the size in bytes of the character buffer
1453 * @return the newly allocated buffer state object.
1455 YY_BUFFER_STATE
rtf_scan_buffer (char * base
, yy_size_t size
)
1460 base
[size
-2] != YY_END_OF_BUFFER_CHAR
||
1461 base
[size
-1] != YY_END_OF_BUFFER_CHAR
)
1462 /* They forgot to leave room for the EOB's. */
1465 b
= (YY_BUFFER_STATE
) rtfalloc(sizeof( struct yy_buffer_state
) );
1467 YY_FATAL_ERROR( "out of dynamic memory in rtf_scan_buffer()" );
1469 b
->yy_buf_size
= size
- 2; /* "- 2" to take care of EOB's */
1470 b
->yy_buf_pos
= b
->yy_ch_buf
= base
;
1471 b
->yy_is_our_buffer
= 0;
1472 b
->yy_input_file
= 0;
1473 b
->yy_n_chars
= b
->yy_buf_size
;
1474 b
->yy_is_interactive
= 0;
1476 b
->yy_fill_buffer
= 0;
1477 b
->yy_buffer_status
= YY_BUFFER_NEW
;
1479 rtf_switch_to_buffer(b
);
1484 /** Setup the input buffer state to scan a string. The next call to rtflex() will
1485 * scan from a @e copy of @a str.
1486 * @param str a NUL-terminated string to scan
1488 * @return the newly allocated buffer state object.
1489 * @note If you want to scan bytes that may contain NUL values, then use
1490 * rtf_scan_bytes() instead.
1492 YY_BUFFER_STATE
rtf_scan_string (yyconst
char * yy_str
)
1495 return rtf_scan_bytes(yy_str
,strlen(yy_str
) );
1498 /** Setup the input buffer state to scan the given bytes. The next call to rtflex() will
1499 * scan from a @e copy of @a bytes.
1500 * @param bytes the byte buffer to scan
1501 * @param len the number of bytes in the buffer pointed to by @a bytes.
1503 * @return the newly allocated buffer state object.
1505 YY_BUFFER_STATE
rtf_scan_bytes (yyconst
char * bytes
, int len
)
1512 /* Get memory for full buffer, including space for trailing EOB's. */
1514 buf
= (char *) rtfalloc(n
);
1516 YY_FATAL_ERROR( "out of dynamic memory in rtf_scan_bytes()" );
1518 for ( i
= 0; i
< len
; ++i
)
1521 buf
[len
] = buf
[len
+1] = YY_END_OF_BUFFER_CHAR
;
1523 b
= rtf_scan_buffer(buf
,n
);
1525 YY_FATAL_ERROR( "bad buffer in rtf_scan_bytes()" );
1527 /* It's okay to grow etc. this buffer, and we should throw it
1528 * away when we're done.
1530 b
->yy_is_our_buffer
= 1;
1535 #ifndef YY_EXIT_FAILURE
1536 #define YY_EXIT_FAILURE 2
1539 static void yy_fatal_error (yyconst
char* msg
)
1541 (void) fprintf( stderr
, "%s\n", msg
);
1542 exit( YY_EXIT_FAILURE
);
1545 /* Redefine yyless() so it works in section 3 code. */
1551 /* Undo effects of setting up rtftext. */ \
1552 int yyless_macro_arg = (n); \
1553 YY_LESS_LINENO(yyless_macro_arg);\
1554 rtftext[rtfleng] = (yy_hold_char); \
1555 (yy_c_buf_p) = rtftext + yyless_macro_arg; \
1556 (yy_hold_char) = *(yy_c_buf_p); \
1557 *(yy_c_buf_p) = '\0'; \
1558 rtfleng = yyless_macro_arg; \
1562 /* Accessor methods (get/set functions) to struct members. */
1564 /** Get the current line number.
1567 int rtfget_lineno (void)
1573 /** Get the input stream.
1576 FILE *rtfget_in (void)
1581 /** Get the output stream.
1584 FILE *rtfget_out (void)
1589 /** Get the length of the current token.
1592 int rtfget_leng (void)
1597 /** Get the current token.
1601 char *rtfget_text (void)
1606 /** Set the current line number.
1607 * @param line_number
1610 void rtfset_lineno (int line_number
)
1613 rtflineno
= line_number
;
1616 /** Set the input stream. This does not discard the current
1618 * @param in_str A readable stream.
1620 * @see rtf_switch_to_buffer
1622 void rtfset_in (FILE * in_str
)
1627 void rtfset_out (FILE * out_str
)
1632 int rtfget_debug (void)
1634 return rtf_flex_debug
;
1637 void rtfset_debug (int bdebug
)
1639 rtf_flex_debug
= bdebug
;
1642 /* rtflex_destroy is for both reentrant and non-reentrant scanners. */
1643 int rtflex_destroy (void)
1646 /* Pop the buffer stack, destroying each element. */
1647 while(YY_CURRENT_BUFFER
){
1648 rtf_delete_buffer(YY_CURRENT_BUFFER
);
1649 YY_CURRENT_BUFFER_LVALUE
= NULL
;
1650 rtfpop_buffer_state();
1653 /* Destroy the stack itself. */
1654 rtffree((yy_buffer_stack
) );
1655 (yy_buffer_stack
) = NULL
;
1661 * Internal utility routines.
1665 static void yy_flex_strncpy (char* s1
, yyconst
char * s2
, int n
)
1668 for ( i
= 0; i
< n
; ++i
)
1673 #ifdef YY_NEED_STRLEN
1674 static int yy_flex_strlen (yyconst
char * s
)
1677 for ( n
= 0; s
[n
]; ++n
)
1684 void *rtfalloc (yy_size_t size
)
1686 return (void *) malloc( size
);
1689 void *rtfrealloc (void * ptr
, yy_size_t size
)
1691 /* The cast to (char *) in the following accommodates both
1692 * implementations that use char* generic pointers, and those
1693 * that use void* generic pointers. It works with the latter
1694 * because both ANSI C and C++ allow castless assignment from
1695 * any pointer type to void*, and deal with argument conversions
1696 * as though doing an assignment.
1698 return (void *) realloc( (char *) ptr
, size
);
1701 void rtffree (void * ptr
)
1703 free( (char *) ptr
); /* see rtfrealloc() for (char *) cast */
1706 #define YYTABLES_NAME "yytables"
1709 #undef YY_FLUSH_BUFFER
1711 #undef yy_new_buffer
1712 #undef yy_set_interactive
1714 #undef YY_DO_BEFORE_ACTION
1716 #ifdef YY_DECL_IS_OURS
1717 #undef YY_DECL_IS_OURS
1724 #include "rtf2html.h"
1726 void ParStyle::clearFormatting()
1728 // For now, do nothing.
1729 // dir is not a formatting item.
1732 QString
RTF2HTML::quoteString(const QString
&_str
, quoteMode mode
)
1735 str
.replace('&', "&");
1736 str
.replace('<', "<");
1737 str
.replace('>', ">");
1738 str
.replace('\"', """);
1742 str
.replace(QRegExp("\n"), "<br>\n");
1745 str
.replace(QRegExp("\n"), "<br/>\n");
1754 while ((pos
= re
.indexIn(str
, pos
)) != -1) {
1755 len
= re
.matchedLength();
1760 for (int i
= 1; i
< len
; i
++)
1762 str
.replace(pos
, len
, s
);
1767 RTF2HTML::RTF2HTML()
1771 bExplicitParagraph
= false;
1774 OutTag
* RTF2HTML::getTopOutTag(TagEnum tagType
)
1776 vector
<OutTag
>::iterator it
, it_end
;
1777 for(it
= oTags
.begin(), it_end
= oTags
.end(); it
!= it_end
; ++it
)
1778 if (it
->tag
== tagType
)
1783 void RTF2HTML::FlushOutTags()
1785 vector
<OutTag
>::iterator iter
;
1786 for (iter
= oTags
.begin(); iter
!= oTags
.end(); iter
++)
1790 case TAG_FONT_COLOR
:
1792 // RTF colors are 1-based; colors[] is a 0-based array.
1793 if (t
.param
> colors
.size() || t
.param
== 0)
1795 QColor
&c
= colors
[t
.param
-1];
1796 PrintUnquoted("<span style=\"color:#%02X%02X%02X\">", c
.red(), c
.green(), c
.blue());
1800 PrintUnquoted("<span style=\"font-size:%upt\">", t
.param
);
1802 case TAG_FONT_FAMILY
:
1804 if (t
.param
> fonts
.size() || t
.param
== 0)
1806 FontDef
&f
= fonts
[t
.param
-1];
1807 string name
= (!f
.nonTaggedName
.empty()) ? f
.nonTaggedName
: f
.taggedName
;
1808 PrintUnquoted("<span style=\"font-family:%s\">", name
.c_str());
1812 if (t
.param
> colors
.size() || t
.param
== 0)
1814 QColor
&c
= colors
[t
.param
-1];
1815 PrintUnquoted("<span style=\"background-color:#%02X%02X%02X;\">", c
.red(), c
.green(), c
.blue());
1819 PrintUnquoted("<b>");
1822 PrintUnquoted("<i>");
1825 PrintUnquoted("<u>");
1834 // This function will close the already-opened tag 'tag'. It will take
1835 // care of closing the tags which 'tag' contains first (ie. it will unroll
1836 // the stack till the point where 'tag' is).
1837 void Level::resetTag(TagEnum tag
)
1839 // A stack which'll keep tags we had to close in order to reach 'tag'.
1840 // After we close 'tag', we will reopen them.
1843 while (p
->tags
.size() > m_nTagsStartPos
){ // Don't go further than the point where this level starts.
1845 TagEnum nTag
= p
->tags
.top();
1847 /* A tag will be located in oTags if it still wasn't printed out.
1848 A tag will get printed out only if necessary (e.g. <I></I> will
1850 Thus, for each tag we remove from the actual tag stack, we also
1851 try to remove a yet-to-be-printed tag, and only if there are no
1852 yet-to-be-printed tags left, we start closing the tags we pop.
1853 The tags have one space - needed for umlaute (�) and .toUtf8()
1855 if (p
->oTags
.empty()){
1857 case TAG_FONT_COLOR
:
1860 case TAG_FONT_FAMILY
:
1861 p
->PrintUnquoted(" </span>");
1864 p
->PrintUnquoted(" </b>");
1867 p
->PrintUnquoted(" </i>");
1870 p
->PrintUnquoted(" </u>");
1876 p
->oTags
.pop_back();
1880 if (nTag
== tag
) break; // if we reached the tag we were looking to close.
1881 s
.push(nTag
); // remember to reopen this tag
1884 if (tag
== TAG_ALL
) return;
1887 TagEnum nTag
= s
.top();
1889 case TAG_FONT_COLOR
:{
1890 unsigned nFontColor
= m_nFontColor
;
1892 setFontColor(nFontColor
);
1895 case TAG_FONT_SIZE
:{
1896 unsigned nFontSize
= m_nFontSize
;
1898 setFontSize(nFontSize
);
1902 unsigned nFontBgColor
= m_nFontBgColor
;
1904 setFontBgColor(nFontBgColor
);
1907 case TAG_FONT_FAMILY
:{
1908 unsigned nFont
= m_nFont
;
1914 bool nBold
= m_bBold
;
1920 bool nItalic
= m_bItalic
;
1925 case TAG_UNDERLINE
:{
1926 bool nUnderline
= m_bUnderline
;
1927 m_bUnderline
= false;
1928 setUnderline(nUnderline
);
1938 Level::Level(RTF2HTML
*_p
) :
1943 m_bTaggedFontNameOk(false),
1947 m_nTagsStartPos
= p
->tags
.size();
1951 Level::Level(const Level
&l
) :
1953 m_bFontTbl(l
.m_bFontTbl
),
1954 m_bColors(l
.m_bColors
),
1956 m_bTaggedFontNameOk(l
.m_bTaggedFontNameOk
),
1958 m_nEncoding(l
.m_nEncoding
)
1960 m_nTagsStartPos
= p
->tags
.size();
1969 m_bFontName
= false;
1972 m_bUnderline
= false;
1975 void RTF2HTML::PrintUnquoted(const char *str
, ...)
1980 vsnprintf(buff
, sizeof(buff
), str
, ap
);
1985 void RTF2HTML::PrintQuoted(const QString
&str
)
1987 sParagraph
+= quoteString(str
);
1990 void RTF2HTML::FlushParagraph()
1992 if (!bExplicitParagraph
|| sParagraph
.isEmpty())
1997 // Note: Lower-case 'ltr' and 'rtl' are important for Qt.
1998 s += (parStyle.dir == ParStyle::DirRTL ? "rtl" : "ltr");
2007 // Clear up the paragraph members
2009 bExplicitParagraph
= false;
2012 void Level::setFont(unsigned nFont
)
2018 if (nFont
> p
->fonts
.size() +1){
2019 // kDebug(14191) << "Invalid font index (" <<
2020 // nFont << ") while parsing font table." << endl;
2023 if (nFont
> p
->fonts
.size()){
2026 p
->fonts
.push_back(f
);
2032 if (nFont
> p
->fonts
.size())
2034 // kDebug(14191) << "Invalid font index (" <<
2035 // nFont << ")." << endl;
2038 if (m_nFont
== nFont
)
2041 if (m_nFont
) resetTag(TAG_FONT_FAMILY
);
2042 m_nEncoding
= p
->fonts
[nFont
-1].charset
;
2043 p
->oTags
.push_back(OutTag(TAG_FONT_FAMILY
, nFont
));
2044 p
->PutTag(TAG_FONT_FAMILY
);
2048 void Level::setFontName()
2050 // This function is only valid during font table parsing.
2052 if ((m_nFont
> 0) && (m_nFont
<= p
->fonts
.size()))
2053 // Be prepared to accept a font name.
2058 void Level::setEncoding(unsigned nEncoding
)
2061 if ((m_nFont
> 0) && (m_nFont
<= p
->fonts
.size()))
2062 p
->fonts
[m_nFont
-1].charset
= nEncoding
;
2065 m_nEncoding
= nEncoding
;
2068 void Level::setBold(bool bBold
)
2070 if (m_bBold
== bBold
) return;
2071 if (m_bBold
) resetTag(TAG_BOLD
);
2073 if (!m_bBold
) return;
2074 p
->oTags
.push_back(OutTag(TAG_BOLD
, 0));
2075 p
->PutTag(TAG_BOLD
);
2078 void Level::setItalic(bool bItalic
)
2080 if (m_bItalic
== bItalic
) return;
2081 if (m_bItalic
) resetTag(TAG_ITALIC
);
2082 m_bItalic
= bItalic
;
2083 if (!m_bItalic
) return;
2084 p
->oTags
.push_back(OutTag(TAG_ITALIC
, 0));
2085 p
->PutTag(TAG_ITALIC
);
2088 void Level::setUnderline(bool bUnderline
)
2090 if (m_bUnderline
== bUnderline
) return;
2091 if (m_bUnderline
) resetTag(TAG_UNDERLINE
);
2092 m_bUnderline
= bUnderline
;
2093 if (!m_bUnderline
) return;
2094 p
->oTags
.push_back(OutTag(TAG_UNDERLINE
, 0));
2095 p
->PutTag(TAG_UNDERLINE
);
2098 void Level::setFontColor(unsigned short nColor
)
2100 if (m_nFontColor
== nColor
) return;
2101 if (m_nFontColor
) resetTag(TAG_FONT_COLOR
);
2102 if (nColor
> p
->colors
.size()) return;
2103 m_nFontColor
= nColor
;
2104 p
->oTags
.push_back(OutTag(TAG_FONT_COLOR
, m_nFontColor
));
2105 p
->PutTag(TAG_FONT_COLOR
);
2108 void Level::setFontBgColor(unsigned short nColor
)
2110 if (m_nFontBgColor
== nColor
) return;
2111 if (m_nFontBgColor
!= 0) resetTag(TAG_BG_COLOR
);
2112 if (nColor
> p
->colors
.size()) return;
2113 m_nFontBgColor
= nColor
;
2114 p
->oTags
.push_back(OutTag(TAG_BG_COLOR
, m_nFontBgColor
));
2115 p
->PutTag(TAG_BG_COLOR
);
2118 void Level::setFontSizeHalfPoints(unsigned short nSize
)
2120 setFontSize(nSize
/ 2);
2123 void Level::setFontSize(unsigned short nSize
)
2125 if (m_nFontSize
== nSize
) return;
2126 if (m_nFontSize
) resetTag(TAG_FONT_SIZE
);
2127 p
->oTags
.push_back(OutTag(TAG_FONT_SIZE
, nSize
));
2128 p
->PutTag(TAG_FONT_SIZE
);
2129 m_nFontSize
= nSize
;
2132 void Level::startParagraph()
2134 // Whatever tags we have open now, close them.
2135 // We cannot carry let character formatting tags wrap paragraphs,
2136 // since a formatting tag can close at any time and we cannot
2137 // close the paragraph any time we want.
2140 // Flush the current paragraph HTML to the document HTML.
2141 p
->FlushParagraph();
2143 // Mark this new paragraph as an explicit one (from \par etc.).
2144 p
->bExplicitParagraph
= true;
2146 // Restore character formatting
2147 p
->oTags
.push_back(OutTag(TAG_FONT_SIZE
, m_nFontSize
));
2148 p
->PutTag(TAG_FONT_SIZE
);
2149 p
->oTags
.push_back(OutTag(TAG_FONT_COLOR
, m_nFontColor
));
2150 p
->PutTag(TAG_FONT_COLOR
);
2151 p
->oTags
.push_back(OutTag(TAG_FONT_FAMILY
, m_nFont
));
2152 p
->PutTag(TAG_FONT_FAMILY
);
2153 if (m_nFontBgColor
!= 0)
2155 p
->oTags
.push_back(OutTag(TAG_BG_COLOR
, m_nFontBgColor
));
2156 p
->PutTag(TAG_BG_COLOR
);
2160 p
->oTags
.push_back(OutTag(TAG_BOLD
, 0));
2161 p
->PutTag(TAG_BOLD
);
2165 p
->PutTag(TAG_ITALIC
);
2166 p
->oTags
.push_back(OutTag(TAG_ITALIC
, 0));
2170 p
->oTags
.push_back(OutTag(TAG_UNDERLINE
, 0));
2171 p
->PutTag(TAG_UNDERLINE
);
2175 bool Level::isParagraphOpen() const
2177 return p
->bExplicitParagraph
;
2180 void Level::clearParagraphFormatting()
2182 // implicitly start a paragraph
2183 if (!isParagraphOpen())
2185 // Since we don't implement any of the paragraph formatting tags (e.g. alignment),
2186 // we don't clean up anything here. Note that \pard does NOT clean character
2187 // formatting (such as font size, font weight, italics...).
2188 p
->parStyle
.clearFormatting();
2191 void Level::setParagraphDirLTR()
2193 // implicitly start a paragraph
2194 if (!isParagraphOpen())
2196 p
->parStyle
.dir
= ParStyle::DirLTR
;
2199 void Level::setParagraphDirRTL()
2201 // implicitly start a paragraph
2202 if (!isParagraphOpen())
2204 p
->parStyle
.dir
= ParStyle::DirRTL
;
2207 void Level::addLineBreak()
2209 p
->PrintUnquoted("<br/>");
2217 QColor
c(m_nRed
, m_nGreen
, m_nBlue
);
2218 p
->colors
.push_back(c
);
2225 void Level::setText(const char *str
)
2231 else if (m_bFontTbl
)
2233 if ((m_nFont
<= 0) || (m_nFont
> p
->fonts
.size()))
2236 FontDef
& def
= p
->fonts
[m_nFont
-1];
2238 const char *pp
= strchr(str
, ';');
2247 def
.nonTaggedName
.append(str
, size
);
2248 // We know we have the entire name
2250 m_bFontName
= false;
2252 else if (!m_bTaggedFontNameOk
)
2254 def
.taggedName
.append(str
, size
);
2256 m_bTaggedFontNameOk
= true;
2262 if ((unsigned char)(*str
) >= ' ') break;
2271 if (text
.length() == 0) return;
2272 // TODO: Make encoding work in Kopete
2274 const char *encoding = NULL;
2276 for (const ENCODING *c = ICQPlugin::core->encodings; c->language; c++){
2279 if ((unsigned)c->rtf_code == m_nEncoding){
2280 encoding = c->codec;
2285 if (encoding == NULL)
2286 encoding = p->encoding;
2288 QTextCodec *codec = ICQClient::_getCodec(encoding);
2290 //p->PrintQuoted(codec->toUnicode(text.c_str(), text.length()));
2291 p
->PrintQuoted(text
.c_str());
2295 const unsigned FONTTBL
= 0;
2296 const unsigned COLORTBL
= 1;
2297 const unsigned RED
= 2;
2298 const unsigned GREEN
= 3;
2299 const unsigned BLUE
= 4;
2300 const unsigned CF
= 5;
2301 const unsigned FS
= 6;
2302 const unsigned HIGHLIGHT
= 7;
2303 const unsigned PARD
= 8;
2304 const unsigned PAR
= 9;
2305 const unsigned I
= 10;
2306 const unsigned B
= 11;
2307 const unsigned UL
= 12;
2308 const unsigned F
= 13;
2309 const unsigned FCHARSET
= 14;
2310 const unsigned FNAME
= 15;
2311 const unsigned ULNONE
= 16;
2312 const unsigned LTRPAR
= 17;
2313 const unsigned RTLPAR
= 18;
2314 const unsigned LINE
= 19;
2316 static char cmds
[] =
2339 int rtfwrap() { return 1; }
2341 static char h2d(char c
)
2343 if ((c
>= '0') && (c
<= '9'))
2345 if ((c
>= 'A') && (c
<= 'F'))
2346 return (c
- 'A') + 10;
2347 if ((c
>= 'a') && (c
<= 'f'))
2348 return (c
- 'a') + 10;
2352 QString
RTF2HTML::Parse(const char *rtf
, const char *_encoding
)
2354 encoding
= _encoding
;
2355 YY_BUFFER_STATE yy_current_buffer
= rtf_scan_string(rtf
);
2363 levels
.push(cur_level
);
2367 if (!levels
.empty()){
2370 cur_level
= levels
.top();
2377 const char ICQIMAGE
[] = "icqimage";
2378 const char *smiles
[] = { ":-)" , ":-O" , ":-|" , ":-/" , // 0-3
2379 ":-(" , ":-*" , ":-/" , ":'(" , // 4-7
2380 ";-)" , ":-@" , ":-$" , ":-X" , // 8-B
2381 ":-P" , "8-)" , "O:)" , ":-D" }; // C-F
2382 const char *p
= rtftext
+ 3;
2383 if ((strlen(p
) > strlen(ICQIMAGE
)) && !memcmp(p
, ICQIMAGE
, strlen(ICQIMAGE
))){
2385 for (p
+= strlen(ICQIMAGE
); *p
; p
++){
2386 if ((*p
>= '0') && (*p
<= '9')){
2391 if ((*p
>= 'A') && (*p
<= 'F')){
2393 n
+= (*p
- 'A') + 10;
2396 if ((*p
>= 'a') && (*p
<= 'f')){
2398 n
+= (*p
- 'a') + 10;
2404 PrintUnquoted(" %s ", smiles
[n
] );
2406 // kDebug(14191) << "Unknown image " << rtftext;
2413 cur_level
.setText(rtftext
+1);
2416 cur_level
.setText(rtftext
);
2420 sParagraph
+= QChar((unsigned short)(atol(rtftext
+ 2)));
2425 s
[0] = (h2d(rtftext
[2]) << 4) + h2d(rtftext
[3]);
2427 cur_level
.setText(s
);
2433 const char *cmd
= rtftext
+ 1;
2435 unsigned cmd_size
= 0;
2438 for (p
= cmd
; *p
; p
++, cmd_size
++)
2439 if (((*p
>= '0') && (*p
<= '9')) || (*p
== ' ')) break;
2440 if (*p
&& (*p
!= ' ')) cmd_value
= atol(p
);
2441 for (p
= cmds
; *p
; p
+= strlen(p
) + 1, n_cmd
++){
2442 if (strlen(p
) > cmd_size
) continue;
2443 if (!memcmp(p
, cmd
, cmd_size
)) break;
2447 case FONTTBL
: // fonttbl
2448 cur_level
.setFontTbl();
2451 cur_level
.setColors();
2454 cur_level
.setRed(cmd_value
);
2457 cur_level
.setGreen(cmd_value
);
2460 cur_level
.setBlue(cmd_value
);
2463 cur_level
.setFontColor(cmd_value
);
2466 cur_level
.setFontSizeHalfPoints(cmd_value
);
2469 cur_level
.setFontBgColor(cmd_value
);
2472 cur_level
.clearParagraphFormatting();
2475 cur_level
.startParagraph();
2478 cur_level
.setItalic(cmd_value
!= 0);
2481 cur_level
.setBold(cmd_value
!= 0);
2484 cur_level
.setUnderline(cmd_value
!= 0);
2487 cur_level
.setUnderline(false);
2490 // RTF fonts are 0-based; our font index is 1-based.
2491 cur_level
.setFont(cmd_value
+1);
2494 cur_level
.setEncoding(cmd_value
);
2497 cur_level
.setFontName();
2500 cur_level
.setParagraphDirLTR();
2503 cur_level
.setParagraphDirRTL();
2506 cur_level
.addLineBreak();
2512 rtf_delete_buffer(yy_current_buffer
);
2513 yy_current_buffer
= NULL
;
2519 bool ICQClient::parseRTF(const char *rtf, const char *encoding, QString &res)
2521 char _RTF[] = "{\\rtf";
2522 if ((strlen(rtf) > strlen(_RTF)) && !memcmp(rtf, _RTF, strlen(_RTF))){
2524 res = p.Parse(rtf, encoding);
2527 QTextCodec *codec = ICQClient::_getCodec(encoding);
2528 res = codec->toUnicode(rtf, strlen(rtf));