1 /************************************************************************/
2 /* */
3 /* Reading of Rtf files. (Various utility functions.) */
4 /* */
5 /************************************************************************/
6
7 # include "docRtfConfig.h"
8
9 # include <stdlib.h>
10 # include <string.h>
11 # include <stdio.h>
12 # include <ctype.h>
13 # include <charnames.h>
14
15 # include <appDebugon.h>
16
17 # include <textOfficeCharset.h>
18
19 # include "docRtfReaderImpl.h"
20 # include "docRtfTags.h"
21 # include "docRtfFlags.h"
22
23 /************************************************************************/
24 /* */
25 /* Read a control word from the input stream. */
26 /* */
27 /************************************************************************/
28
docRtfReadControlWord(RtfReader * rrc,int * pC,char * controlWord,int * pGotArg,int * pArg)29 static int docRtfReadControlWord( RtfReader * rrc,
30 int * pC,
31 char * controlWord,
32 int * pGotArg,
33 int * pArg )
34 {
35 SimpleInputStream * sis= rrc->rrcSis;
36 int c;
37 int len= 0;
38 int sign= 1;
39
40 c= sioInGetByte( sis );
41 while( c == '\n' || c == '\r' )
42 {
43 if ( c == '\n' )
44 { rrc->rrCurrentLine++; }
45 c= sioInGetByte( sis );
46 }
47
48 if ( c != '\\' )
49 { CDEB(c); return -1; }
50
51 c= sioInGetByte( sis );
52 if ( ! isalpha( c ) )
53 {
54 switch( c )
55 {
56 case '\n':
57 rrc->rrCurrentLine++;
58 /*FALLTHROUGH*/
59 case '\r':
60 strcpy( controlWord, RTFtag_par );
61 *pGotArg= 0;
62 return 0;
63 case '\t':
64 strcpy( controlWord, "tab" );
65 *pGotArg= 0;
66 return 0;
67 case '_':
68 *pC= '-'; return 1;
69
70 case '-':
71 controlWord[len++]= c;
72 controlWord[len ]= '\0';
73 *pGotArg= 0;
74 return 0;
75
76 default:
77 *pC= c; return 1;
78 }
79 }
80 controlWord[len++]= c;
81
82 for (;;)
83 {
84 c= sioInGetByte( sis );
85 if ( ! isalpha( c ) )
86 { controlWord[len]= '\0'; break; }
87 if ( len >= TEDszRTFCONTROL )
88 { LLDEB(len,TEDszRTFCONTROL); return -1; }
89 controlWord[len++]= c;
90 }
91
92 if ( c == '-' )
93 { sign= -1; c= sioInGetByte( sis ); }
94
95 *pGotArg= ( isdigit( c ) != 0 );
96 if ( *pGotArg )
97 {
98 int arg= c- '0';
99
100 c= sioInGetByte( sis );
101
102 while( isdigit( c ) )
103 { arg= 10* arg+ c- '0'; c= sioInGetByte( sis ); }
104
105 *pArg= sign* arg;
106 }
107
108 if ( c != ' ' )
109 { sioInUngetLastRead( sis ); }
110
111 return 0;
112 }
113
114 /************************************************************************/
115 /* */
116 /* Find a Control word. */
117 /* */
118 /************************************************************************/
119
docRtfFindWord(const char * controlWord,const RtfControlWord * controlWords)120 const RtfControlWord * docRtfFindWord( const char * controlWord,
121 const RtfControlWord * controlWords )
122 {
123 if ( controlWords )
124 {
125 while( controlWords->rcwWord )
126 {
127 if ( ! strcmp( controlWords->rcwWord, controlWord ) )
128 { return controlWords; }
129
130 controlWords++;
131 }
132 }
133
134 return (RtfControlWord *)0;
135 }
136
docRtfApplyControlWord(const RtfControlWord * rcw,int gotArg,int arg,RtfReader * rrc)137 int docRtfApplyControlWord( const RtfControlWord * rcw,
138 int gotArg,
139 int arg,
140 RtfReader * rrc )
141 {
142 if ( ! gotArg )
143 { arg= -1; }
144
145 if ( rcw->rcwType == RTCtypeENUM )
146 {
147 if ( gotArg )
148 { SLLLDEB(rcw->rcwWord,arg,rcw->rcwType,gotArg); }
149
150 arg= rcw->rcwEnumValue;
151 }
152
153 if ( rcw->rcwType != RTCtypeENUM &&
154 rcw->rcwEnumValue != 0 &&
155 rcw->rcwID != PIPpropTYPE )
156 { SLLDEB(rcw->rcwWord,rcw->rcwType,rcw->rcwEnumValue); }
157
158 if ( (*rcw->rcwApply) ( rcw, arg, rrc ) )
159 { LSLDEB(rrc->rrCurrentLine,rcw->rcwWord,arg); return -1; }
160
161 return 0;
162 }
163
164 /************************************************************************/
165 /* */
166 /* Find out what to do. */
167 /* */
168 /* Return RTFfiCTRLGROUP: Found a control group. */
169 /* Return RTFfiWORD: Found a control word. */
170 /* Return RTFfiCHAR: Found a character. */
171 /* Return RTFfiCLOSE: Found an unescaped brace. */
172 /* Return -1: Error. */
173 /* */
174 /************************************************************************/
175
docRtfFindControl(RtfReader * rrc,int * pC,char * controlWord,int * pGotArg,int * pArg)176 int docRtfFindControl( RtfReader * rrc,
177 int * pC,
178 char * controlWord,
179 int * pGotArg,
180 int * pArg )
181 {
182 SimpleInputStream * sis= rrc->rrcSis;
183 RtfReadingState * rrs= rrc->rrcState;
184
185 int c;
186 int res;
187
188 if ( rrc->rrcCharacterAhead != EOF )
189 {
190 *pC= rrc->rrcCharacterAhead;
191 rrc->rrcCharacterAhead= EOF;
192 return RTFfiCHAR;
193 }
194
195 for (;;)
196 {
197 c= sioInGetByte( sis );
198
199 switch( c )
200 {
201 case EOF:
202 if ( rrs )
203 { rrs->rrsUnicodeBytesToSkip= 0; }
204
205 if ( ! ( rrc->rrReadFlags & RTFflagLENIENT ) )
206 {
207 const char * message= DOC_RTF_LENIENT_MESSAGE;
208 XSDEB(c,message); return -1;
209 }
210 else{ XDEB(c); *pC= '}'; return RTFfiCLOSE; }
211
212 case '\\':
213 sioInUngetLastRead( sis );
214 res= docRtfReadControlWord( rrc, &c,
215 controlWord, pGotArg, pArg );
216
217 if ( res < 0 )
218 { LDEB(res); return -1; }
219 if ( res > 0 )
220 {
221 switch( c )
222 {
223 case '\\': case '{': case '}':
224 *pC= c; return RTFfiCHAR;
225
226 case '~':
227 c= ISO1_nobreakspace;
228 *pC= c; return RTFfiCHAR;
229
230 case '_':
231 c= '-';
232 *pC= c; return RTFfiCHAR;
233
234 case '\'':
235 if ( res == 1 )
236 {
237 char b[3];
238 unsigned int uc;
239
240 b[0]= sioInGetByte( sis );
241 b[1]= sioInGetByte( sis );
242 b[2]= '\0';
243
244 sscanf( b, "%x", &uc ); c= uc;
245 }
246 goto defaultCase;
247
248 default:
249 if ( res == 2 )
250 { *pC= c; return RTFfiCHAR; }
251 else{ goto defaultCase; }
252 }
253 }
254 return RTFfiWORD;
255
256 case '{':
257 if ( rrs )
258 { rrs->rrsUnicodeBytesToSkip= 0; }
259
260 c= sioInGetByte( sis );
261 while( c == '\n' || c == '\r' )
262 {
263 if ( c == '\n' )
264 { rrc->rrCurrentLine++; }
265 c= sioInGetByte( sis );
266 }
267
268 if ( c == '\\' )
269 {
270 sioInUngetLastRead( sis );
271 res= docRtfReadControlWord( rrc, &c,
272 controlWord, pGotArg, pArg );
273 if ( res < 0 )
274 { LDEB(res); return -1; }
275 if ( res > 0 )
276 {
277 if ( c == '*' )
278 {
279 res= docRtfReadControlWord( rrc, &c,
280 controlWord, pGotArg, pArg );
281 if ( res )
282 { LDEB(res); return -1; }
283
284 return RTFfiSTARGROUP;
285 }
286
287 if ( c=='\'' )
288 {
289 char b[3];
290 unsigned int uc;
291
292 b[0]= sioInGetByte( sis );
293 b[1]= sioInGetByte( sis );
294 b[2]= '\0';
295
296 sscanf( b, "%x", &uc ); c= uc;
297 }
298
299 if ( rrs && rrs->rrsUnicodeBytesToSkip > 0 )
300 { rrs->rrsUnicodeBytesToSkip= 0; }
301
302 rrc->rrcCharacterAhead= c;
303
304 return RTFfiTEXTGROUP;
305 }
306
307 return RTFfiCTRLGROUP;
308 }
309
310 sioInUngetLastRead( sis );
311 return RTFfiTEXTGROUP;
312
313 case '\n':
314 rrc->rrCurrentLine++;
315 /*FALLTHROUGH*/
316 case '\r':
317 continue;
318
319 case '}':
320 rrs->rrsUnicodeBytesToSkip= 0;
321 *pC= c; return RTFfiCLOSE;
322
323 case '\t':
324 *pC= c; return RTFfiTAB;
325
326 default: defaultCase:
327
328 if ( rrs && rrs->rrsUnicodeBytesToSkip > 0 )
329 { rrs->rrsUnicodeBytesToSkip--; continue; }
330
331 *pC= c; return RTFfiCHAR;
332 }
333 }
334 }
335
336 /************************************************************************/
337 /* */
338 /* Add the collected text to the document. Subtract extra unicode */
339 /* */
340 /************************************************************************/
341
docRtfAddParticule(RtfReader * rrc,const char * collectedText,int len)342 static int docRtfAddParticule( RtfReader * rrc,
343 const char * collectedText,
344 int len )
345 {
346 RtfReadingState * rrs= rrc->rrcState;
347
348 if ( ! rrc->rrcAddParticule )
349 { XDEB(rrc->rrcAddParticule); return -1; }
350
351 while ( rrs->rrsUnicodeBytesToSkip > 0 && len > 0 )
352 {
353 rrs->rrsUnicodeBytesToSkip--; len--;
354 collectedText++;
355 }
356
357 if ( len > 0 && (*rrc->rrcAddParticule)( rrc, collectedText, len ) )
358 { LDEB(len); return -1; }
359
360 return 0;
361 }
362
363 /************************************************************************/
364 /* */
365 /* Consume free text upto a control word or a group. */
366 /* */
367 /************************************************************************/
368
docRtfReadText(int c,int * pC,char * controlWord,int * pGotArg,int * pArg,RtfReader * rrc)369 static int docRtfReadText( int c,
370 int * pC,
371
372 char * controlWord,
373 int * pGotArg,
374 int * pArg,
375
376 RtfReader * rrc )
377 {
378 RtfReadingState * rrs= rrc->rrcState;
379 SimpleInputStream * sis= rrc->rrcSis;
380 int res;
381
382 static char * collectedText;
383 static int collectedSize;
384
385 char * fresh;
386 int size;
387 int len;
388
389 len= 0;
390 if ( len >= collectedSize )
391 {
392 size= 100;
393
394 fresh= (char *)realloc( collectedText, size+ 2 );
395 if ( ! fresh )
396 { LXDEB(size,fresh); return -1; }
397
398 collectedText= fresh;
399 collectedSize= size;
400 }
401
402 collectedText[len++]= c;
403 collectedText[len ]= '\0';
404
405 for (;;)
406 {
407 c= sioInGetByte( sis );
408
409 switch( c )
410 {
411 case EOF:
412 LDEB(c); return -1;
413
414 case '}':
415 if ( docRtfAddParticule( rrc, collectedText, len ) )
416 { LDEB(len); return -1; }
417 rrs->rrsUnicodeBytesToSkip= 0;
418 return RTFfiCLOSE;
419
420 case '{':
421 sioInUngetLastRead( sis );
422 res= docRtfFindControl( rrc, &c, controlWord, pGotArg, pArg );
423 if ( res < 0 )
424 { LDEB(res); return res; }
425 if ( docRtfAddParticule( rrc, collectedText, len ) )
426 { LDEB(len); return -1; }
427 rrs->rrsUnicodeBytesToSkip= 0;
428 *pC= c; return res;
429
430 case '\n':
431 rrc->rrCurrentLine++;
432 /*FALLTHROUGH*/
433
434 case '\r' :
435 continue;
436
437 case '\\':
438 sioInUngetLastRead( sis );
439 res= docRtfFindControl( rrc, &c, controlWord, pGotArg, pArg );
440 if ( res < 0 )
441 { LDEB(res); return res; }
442
443 if ( res != RTFfiCHAR )
444 {
445 if ( docRtfAddParticule( rrc, collectedText, len ) )
446 { LDEB(len); return -1; }
447
448 return res;
449 }
450
451 /*FALLTHROUGH*/
452
453 default:
454 if ( len >= collectedSize )
455 {
456 size= ( 3* collectedSize+ 2 )/ 2;
457
458 if ( size < len )
459 { size= len+ 2; }
460
461 fresh= (char *)realloc( collectedText, size+ 2 );
462 if ( ! fresh )
463 { LXDEB(size,fresh); return -1; }
464
465 collectedText= fresh;
466 collectedSize= size;
467 }
468
469 collectedText[len++]= c;
470 collectedText[len ]= '\0';
471 break;
472
473 case '\t':
474 if ( docRtfAddParticule( rrc, collectedText, len ) )
475 { LDEB(len); return -1; }
476 strcpy( controlWord, "tab" ); *pGotArg= 0; *pArg= -1;
477 res= RTFfiWORD;
478 return res;
479 }
480 }
481 }
482
483 /************************************************************************/
484 /* */
485 /* Skip an unknown or superfluous group. */
486 /* */
487 /************************************************************************/
488
docRtfSkipGroup(const RtfControlWord * rcw,int ignored_arg,RtfReader * rrc)489 int docRtfSkipGroup( const RtfControlWord * rcw,
490 int ignored_arg,
491 RtfReader * rrc )
492 {
493 int rval= 0;
494 int complainUnknown= rrc->rrcComplainUnknown;
495
496 rrc->rrcComplainUnknown= 0;
497 rrc->rrcInIgnoredGroup++;
498
499 if ( docRtfReadGroup( rcw, 0, 0, rrc,
500 (RtfControlWord *)0, docRtfIgnoreText, (RtfCommitGroup)0 ) )
501 { SDEB(rcw->rcwWord); rval= -1; }
502
503 rrc->rrcInIgnoredGroup--;
504 rrc->rrcComplainUnknown= complainUnknown;
505
506 return rval;
507 }
508
509 /************************************************************************/
510 /* */
511 /* Read an RTF control group. typically the document. */
512 /* */
513 /************************************************************************/
514
docRtfReadGroupX(const RtfControlWord * rcw,const RtfControlWord * applyFirst,int gotArg,int arg,RtfReader * rrc,const RtfControlWord * groupWords,RtfAddTextParticule addParticule,RtfCommitGroup commitGroup)515 int docRtfReadGroupX( const RtfControlWord * rcw,
516 const RtfControlWord * applyFirst,
517 int gotArg,
518 int arg,
519 RtfReader * rrc,
520 const RtfControlWord * groupWords,
521 RtfAddTextParticule addParticule,
522 RtfCommitGroup commitGroup )
523 {
524 int rval;
525 RtfReadingState internRrs;
526
527 docRtfPushReadingState( rrc, &internRrs );
528
529 rval= docRtfConsumeGroup( applyFirst, gotArg, arg,
530 rrc, groupWords, addParticule );
531
532 if ( rval )
533 { LDEB(rval); }
534
535 if ( commitGroup && (*commitGroup)( rcw, rrc ) )
536 { LDEB(1); rval= -1; }
537
538 docRtfPopReadingState( rrc );
539
540 return rval;
541 }
542
docRtfReadGroup(const RtfControlWord * rcw,int gotArg,int arg,RtfReader * rrc,const RtfControlWord * groupWords,RtfAddTextParticule addParticule,RtfCommitGroup commitGroup)543 int docRtfReadGroup( const RtfControlWord * rcw,
544 int gotArg,
545 int arg,
546 RtfReader * rrc,
547 const RtfControlWord * groupWords,
548 RtfAddTextParticule addParticule,
549 RtfCommitGroup commitGroup )
550 {
551 int rval;
552 RtfReadingState internRrs;
553
554 docRtfPushReadingState( rrc, &internRrs );
555
556 rval= docRtfConsumeGroup( (const RtfControlWord *)0, gotArg, arg,
557 rrc, groupWords, addParticule );
558
559 if ( rval )
560 { LDEB(rval); }
561
562 if ( commitGroup && (*commitGroup)( rcw, rrc ) )
563 { LDEB(1); rval= -1; }
564
565 docRtfPopReadingState( rrc );
566
567 return rval;
568 }
569
570 /************************************************************************/
571 /* */
572 /* Consume detail tags. In practice that is the properties of a border */
573 /* */
574 /************************************************************************/
575
docRtfConsumeWord(RtfReader * rrc,const RtfControlWord * rcw,int * pC,char * controlWord,int * pGotArg,int * pArg)576 static int docRtfConsumeWord( RtfReader * rrc,
577 const RtfControlWord * rcw,
578 int * pC,
579 char * controlWord,
580 int * pGotArg,
581 int * pArg )
582 {
583 int resAhead= -2;
584
585 int c= *pC;
586 int gotArg= *pGotArg;
587 int arg= *pArg;
588
589 int gotArgAhead= 0;
590 int argAhead= -1;
591
592 int res;
593
594 if ( rcw->rcwPrepare )
595 {
596 if ( (*rcw->rcwPrepare) ( rcw, arg, rrc ) )
597 { SLDEB(rcw->rcwWord,arg); return -1; }
598 }
599
600 if ( rcw->rcwDetailWords )
601 {
602 for (;;)
603 {
604 const RtfControlWord * rcwAhead;
605
606 resAhead= docRtfFindControl( rrc, &c,
607 controlWord, &gotArgAhead, &argAhead );
608
609 if ( resAhead != RTFfiWORD )
610 { break; }
611
612 rcwAhead= docRtfFindWord( controlWord, rcw->rcwDetailWords );
613
614 if ( ! rcwAhead )
615 { break; }
616 if ( rcwAhead->rcwType == RTCtypeDEST )
617 { SLDEB(rcwAhead->rcwWord,rcwAhead->rcwType); break; }
618
619 if ( ! rrc->rrcInIgnoredGroup )
620 {
621 int resx= docRtfApplyControlWord(
622 rcwAhead, gotArgAhead, argAhead, rrc );
623
624 if ( resx < 0 )
625 { LSDEB(resx,controlWord); return -1; }
626 }
627 }
628 }
629
630 if ( rrc->rrcInIgnoredGroup )
631 {
632 if ( rcw->rcwType == RTCtypeDEST )
633 { SLDEB(rcw->rcwWord,rcw->rcwType); }
634
635 res= 0;
636 }
637 else{
638 res= docRtfApplyControlWord( rcw, gotArg, arg, rrc );
639 if ( res < 0 )
640 { SLDEB(rcw->rcwWord,res); return -1; }
641 }
642
643 if ( resAhead == -2 )
644 {
645 res= docRtfFindControl( rrc, &c, controlWord, &gotArg, &arg );
646 }
647 else{
648 res= resAhead; arg= argAhead; gotArg= gotArgAhead;
649 resAhead= -2;
650 }
651
652 *pC= c; *pGotArg= gotArg; *pArg= arg;
653 return res;
654 }
655
656 /************************************************************************/
657 /* */
658 /* Read an unknown group. */
659 /* */
660 /************************************************************************/
661
docRtfReadUnknownGroup(RtfReader * rrc)662 int docRtfReadUnknownGroup( RtfReader * rrc )
663 {
664 int complainUnknown= rrc->rrcComplainUnknown;
665
666 rrc->rrcComplainUnknown= 0;
667
668 if ( docRtfReadGroup( (const RtfControlWord *)0, 0, 0, rrc,
669 (RtfControlWord *)0, docRtfIgnoreText, (RtfCommitGroup)0 ) )
670 { LDEB(1); return -1; }
671
672 rrc->rrcComplainUnknown= complainUnknown;
673
674 return 0;
675 }
676
docRtfConsumeGroup(const RtfControlWord * applyFirst,int gotArg,int arg,RtfReader * rrc,const RtfControlWord * groupWords,RtfAddTextParticule addParticule)677 int docRtfConsumeGroup( const RtfControlWord * applyFirst,
678 int gotArg,
679 int arg,
680 RtfReader * rrc,
681 const RtfControlWord * groupWords,
682 RtfAddTextParticule addParticule )
683 {
684 int rval= 0;
685 int res;
686 const RtfControlWord * rcw;
687
688 char controlWord[TEDszRTFCONTROL+1];
689 int c;
690
691 RtfAddTextParticule savedAddParticule= rrc->rrcAddParticule;
692
693 if ( applyFirst )
694 {
695 res= docRtfConsumeWord( rrc, applyFirst,
696 &c, controlWord, &gotArg, &arg );
697 if ( res < 0 )
698 { LDEB(res); rval= -1; goto ready; }
699 }
700 else{
701 res= docRtfFindControl( rrc, &c, controlWord, &gotArg, &arg );
702 if ( res < 0 )
703 { LDEB(res); rval= -1; goto ready; }
704 }
705
706 if ( addParticule )
707 { rrc->rrcAddParticule= addParticule; }
708
709 for (;;)
710 {
711 const RtfControlWord * rcwApplyFirst;
712 int argApplyFirst;
713 int gotArgApplyFirst;
714
715 switch( res )
716 {
717 case RTFfiCLOSE:
718 goto ready;
719
720 case RTFfiCHAR:
721 res= docRtfReadText( c, &c, controlWord, &gotArg, &arg, rrc );
722 if ( res < 0 )
723 { SLDEB(controlWord,res); rval= -1; goto ready; }
724 break;
725
726 case RTFfiTAB:
727 strcpy( controlWord, "tab" );
728 /*FALLTHROUGH*/
729
730 case RTFfiWORD:
731 rcw= docRtfFindPropertyWord( controlWord );
732 if ( ! rcw )
733 {
734 if ( rrc->rrcComplainUnknown && ! rrc->rrcInIgnoredGroup )
735 { LSDEB(rrc->rrCurrentLine,controlWord); }
736
737 res= docRtfFindControl( rrc, &c,
738 controlWord, &gotArg, &arg );
739 if ( res < 0 )
740 { LDEB(res); rval= -1; goto ready; }
741 }
742 else{
743 if ( rcw->rcwType == RTCtypeDEST )
744 {
745 SLDEB(rcw->rcwWord,rcw->rcwType);
746
747 res= docRtfFindControl( rrc, &c,
748 controlWord, &gotArg, &arg );
749 if ( res < 0 )
750 { LDEB(res); rval= -1; goto ready; }
751 }
752 else{
753 res= docRtfConsumeWord( rrc, rcw,
754 &c, controlWord, &gotArg, &arg );
755 if ( res < 0 )
756 { LDEB(res); rval= -1; goto ready; }
757 }
758 }
759 break;
760 case RTFfiCTRLGROUP:
761 rcw= docRtfFindWord( controlWord, groupWords );
762 if ( ! rcw )
763 { rcw= docRtfFindPropertyWord( controlWord ); }
764 if ( rcw )
765 {
766 if ( rcw->rcwType == RTCtypeDEST )
767 {
768 groupFound:
769 if ( rrc->rrcInIgnoredGroup )
770 {
771 res= docRtfReadGroup( (const RtfControlWord *)0,
772 0, 0, rrc, (RtfControlWord *)0,
773 docRtfIgnoreText, (RtfCommitGroup)0 );
774 }
775 else{
776 res= docRtfApplyControlWord( rcw,
777 gotArg, arg, rrc );
778 }
779 if ( res < 0 )
780 { LSDEB(res,controlWord); rval= -1; goto ready; }
781 }
782 else{
783 if ( docRtfReadGroupX( rcw, rcw, gotArg, arg, rrc,
784 groupWords, addParticule, (RtfCommitGroup)0 ) )
785 { SDEB(rcw->rcwWord); return -1; }
786 }
787 }
788 else{
789 if ( rrc->rrcComplainUnknown && ! rrc->rrcInIgnoredGroup )
790 { LSDEB(rrc->rrCurrentLine,controlWord); }
791
792 if ( docRtfReadUnknownGroup( rrc ) )
793 { LSDEB(rrc->rrCurrentLine,controlWord); return -1; }
794 }
795
796 c= 0x0;
797 res= docRtfFindControl( rrc, &c, controlWord, &gotArg, &arg );
798 if ( res < 0 )
799 { LDEB(res); rval= -1; goto ready; }
800 break;
801
802 case RTFfiSTARGROUP:
803 rcw= docRtfFindWord( controlWord, groupWords );
804 if ( rcw )
805 { goto groupFound; }
806 rcw= docRtfFindPropertyWord( controlWord );
807 if ( rcw && rcw->rcwType == RTCtypeDEST )
808 { goto groupFound; }
809
810 if ( rcw )
811 {
812 if ( ! gotArg )
813 { arg= -1; }
814
815 rcwApplyFirst= rcw;
816 argApplyFirst= arg;
817 gotArgApplyFirst= gotArg;
818
819 goto textGroup;
820 }
821
822 rrc->rrcInIgnoredGroup++;
823
824 if ( docRtfReadUnknownGroup( rrc ) )
825 { LDEB(1); rrc->rrcInIgnoredGroup--; rval= -1; goto ready; }
826
827 rrc->rrcInIgnoredGroup--;
828
829 res= docRtfFindControl( rrc, &c,
830 controlWord, &gotArg, &arg );
831 if ( res < 0 )
832 { LDEB(res); rval= -1; goto ready; }
833 break;
834
835 case RTFfiTEXTGROUP:
836 rcwApplyFirst= (RtfControlWord *)0;
837 argApplyFirst= -1;
838 gotArgApplyFirst= 0;
839
840 textGroup:
841 if ( docRtfReadGroupX( (const RtfControlWord *)0,
842 rcwApplyFirst, gotArgApplyFirst, argApplyFirst,
843 rrc, groupWords,
844 addParticule, (RtfCommitGroup)0 ) )
845 { LDEB(1); rval= -1; goto ready; }
846
847 res= docRtfFindControl( rrc, &c,
848 controlWord, &gotArg, &arg );
849 if ( res < 0 )
850 { LDEB(res); rval= -1; goto ready; }
851 break;
852
853 default:
854 LDEB(res); rval= -1; goto ready;
855 }
856 }
857
858 ready:
859 rrc->rrcAddParticule= savedAddParticule;
860
861 return rval;
862 }
863
864 /************************************************************************/
865 /* */
866 /* Apply a text group. */
867 /* */
868 /************************************************************************/
869
docRtfApplyDocEncodedTextGroup(const RtfControlWord * rcw,int arg,RtfReader * rrc)870 int docRtfApplyDocEncodedTextGroup(
871 const RtfControlWord * rcw,
872 int arg,
873 RtfReader * rrc )
874 {
875 const int gotArg= 0;
876
877 if ( docRtfReadGroup( rcw, gotArg, arg, rrc,
878 (const RtfControlWord *)0,
879 docRtfSaveDocEncodedText,
880 rcw->rwcCommitGroup ) )
881 { SDEB(rcw->rcwWord); return -1; }
882
883 return 0;
884 }
885
docRtfApplyRawBytesGroup(const RtfControlWord * rcw,int arg,RtfReader * rrc)886 int docRtfApplyRawBytesGroup( const RtfControlWord * rcw,
887 int arg,
888 RtfReader * rrc )
889 {
890 const int gotArg= 0;
891
892 if ( docRtfReadGroup( rcw, gotArg, arg, rrc,
893 (const RtfControlWord *)0,
894 docRtfSaveRawBytes,
895 rcw->rwcCommitGroup ) )
896 { SDEB(rcw->rcwWord); return -1; }
897
898 return 0;
899 }
900
901 /************************************************************************/
902 /* */
903 /* Just ignore a control word. */
904 /* */
905 /************************************************************************/
906
docRtfIgnoreWord(const RtfControlWord * rcw,int arg,RtfReader * rrc)907 int docRtfIgnoreWord( const RtfControlWord * rcw,
908 int arg,
909 RtfReader * rrc )
910 { return 0; }
911
912