1 /************************************************************************/
2 /*									*/
3 /*  Read an RTF text file into a BufferDocument				*/
4 /*  Read fields, bookmarks.						*/
5 /*									*/
6 /************************************************************************/
7 
8 #   include	"docRtfConfig.h"
9 
10 #   include	<stdlib.h>
11 #   include	<string.h>
12 #   include	<stdio.h>
13 #   include	<ctype.h>
14 
15 #   include	<appDebugon.h>
16 
17 #   include	"docRtfReaderImpl.h"
18 #   include	<docField.h>
19 #   include	<docParaParticules.h>
20 #   include	<docTreeType.h>
21 #   include	<docBookmarkField.h>
22 
23 /************************************************************************/
24 /*									*/
25 /*  To ensure proper field/bookmark nesting.. A stack op active		*/
26 /*  is kept to be flushed at the appropriate transitions. (Field end,	*/
27 /*  field start, paragraph end.)					*/
28 /*									*/
29 /************************************************************************/
30 
31 typedef struct RtfFieldStackLevel
32     {
33     DocumentField *		rfslField;
34     SelectionScope		rfslSelectionScope;
35     EditPosition		rfslStartPosition;
36     int				rfslParticule;
37     struct RtfFieldStackLevel *	rfslPrev;
38     } RtfFieldStackLevel;
39 
40 /************************************************************************/
41 /*									*/
42 /*  Consume a field.							*/
43 /*									*/
44 /************************************************************************/
45 
docRtfReadFldrslt(const RtfControlWord * rcw,int arg,RtfReader * rrc)46 static int docRtfReadFldrslt(	const RtfControlWord *	rcw,
47 				int			arg,
48 				RtfReader *	rrc )
49     {
50     int			res;
51 
52     res= docRtfReadGroup( rcw, 0, 0, rrc,
53 				docRtfDocumentGroups,
54 				docRtfTextParticule, (RtfCommitGroup)0 );
55 
56     if  ( res )
57 	{ SLDEB(rcw->rcwWord,res);	}
58 
59     return res;
60     }
61 
docRtfCommitFldinst(const RtfControlWord * rcw,RtfReader * rrc)62 static int docRtfCommitFldinst(	const RtfControlWord *	rcw,
63 				RtfReader *		rrc )
64     {
65     RtfFieldStackLevel *	rfsl= rrc->rrcFieldStack;
66     DocumentField *		df= rfsl->rfslField;
67     int				kind;
68 
69     char *			text= (char *)0;
70     int				size;
71     const int			removeSemicolon= 0;
72 
73     if  ( ! rfsl )
74 	{ XDEB(rfsl); return 0;	}
75 
76     df= rfsl->rfslField;
77 
78     if  ( docRtfStoreSavedText( &text, &size, rrc, removeSemicolon ) )
79 	{ LDEB(1); return -1;	}
80     if  ( docSetFieldInst( df, text, size ) )
81 	{ LDEB(size); return -1;	}
82 
83     if  ( text )
84 	{ free( text );		}
85 
86     kind= docFieldKindFromInstructions( df );
87     if  ( kind >= 0 )
88 	{ df->dfKind= kind;	}
89 
90     return 0;
91     }
92 
93 /************************************************************************/
94 /*									*/
95 /*  Move a bookmark inside the field instructions to the exterior.	*/
96 /*									*/
97 /************************************************************************/
98 
99 # if 0
100 static int docRtfBkmkStartX(	const RtfControlWord *		rcw,
101 				int				arg,
102 				RtfReader *		rrc )
103     {
104     RtfFieldStackLevel *	here;
105     RtfFieldStackLevel *	prev;
106     RtfFieldStackLevel *	prpr;
107 
108     if  ( docRtfBkmkStart( rcw, arg, rrc ) )
109 	{ LDEB(1); return -1;	}
110 
111     here= rrc->rrcFieldStack;
112     if  ( ! here )
113 	{ XDEB(here); return -1;	}
114     prev= rrc->rrcFieldStack->rfslPrev;
115     if  ( ! prev )
116 	{ XDEB(prev); return -1;	}
117     prpr= rrc->rrcFieldStack->rfslPrev->rfslPrev;
118 
119     here->rfslStartPosition= prev->rfslStartPosition;
120     here->rfslField->dfHeadPosition= here->rfslStartPosition;
121 
122     rrc->rrcFieldStack= prev;
123     rrc->rrcFieldStack->rfslPrev= here;
124     rrc->rrcFieldStack->rfslPrev->rfslPrev= prpr;
125 
126     return 0;
127     }
128 
129 static int docRtfReadFieldX(	const RtfControlWord *	rcw,
130 				int			arg,
131 				RtfReader *		rrc )
132     {
133     int		res;
134 
135     res= docRtfReadField( rcw, arg, rrc );
136 
137     return res;
138     }
139 
140 # endif
141 
142 static RtfControlWord	docRtfFldinstGroups[]=
143     {
144 #	if 0
145 	RTF_DEST_XX( "bkmkstart",	FPpropFLDINST,	docRtfBkmkStartX ),
146 	RTF_DEST_XX( "field",		RTFidFIELD,	docRtfReadFieldX ),
147 #	endif
148 
149 	{ (char *)0, 0, 0 }
150     };
151 
docRtfReadFldinst(const RtfControlWord * rcw,int arg,RtfReader * rrc)152 static int docRtfReadFldinst(	const RtfControlWord *	rcw,
153 				int			arg,
154 				RtfReader *	rrc )
155     {
156     int		res;
157 
158     res= docRtfReadGroup( rcw, 0, 0, rrc, docRtfFldinstGroups,
159 						docRtfSaveDocEncodedText,
160 						docRtfCommitFldinst );
161 
162     if  ( res )
163 	{ SLDEB(rcw->rcwWord,res);	}
164 
165     return res;
166     }
167 
168 static RtfControlWord	docRtfFieldGroups[]=
169 {
170     RTF_DEST_XX( "fldrslt",	FPpropFLDRSLT,	docRtfReadFldrslt ),
171     RTF_DEST_XX( "fldinst",	FPpropFLDINST,	docRtfReadFldinst ),
172 
173     { (char *)0, 0, 0 }
174 };
175 
docRtfReadPushField(int * pPart,DocumentField ** pField,int kind,RtfReader * rrc,const char * fieldinst,int size)176 static int docRtfReadPushField(		int *			pPart,
177 					DocumentField **	pField,
178 					int			kind,
179 					RtfReader *		rrc,
180 					const char *		fieldinst,
181 					int			size )
182     {
183     int				rval= 0;
184     BufferDocument *		bd= rrc->rrDocument;
185     BufferItem *		paraNode;
186     int				part;
187 
188     RtfReadingState *		rrs= rrc->rrcState;
189     RtfFieldStackLevel *	rfsl= (RtfFieldStackLevel *)0;
190 
191     paraNode= docRtfGetParaNode( rrc );
192     if  ( ! paraNode )
193 	{ XDEB(paraNode); rval= -1; goto ready; }
194 
195     part= paraNode->biParaParticuleCount;
196 
197     rfsl= (RtfFieldStackLevel *)malloc( sizeof(RtfFieldStackLevel) );
198     if  ( ! rfsl )
199 	{ XDEB(rfsl); rval= -1; goto ready;	}
200 
201     rfsl->rfslSelectionScope= rrc->rrcSelectionScope;
202     rfsl->rfslStartPosition.epParaNr= docNumberOfParagraph( paraNode );
203     rfsl->rfslStartPosition.epStroff= docParaStrlen( paraNode );
204     rfsl->rfslParticule= paraNode->biParaParticuleCount;
205     rfsl->rfslPrev= rrc->rrcFieldStack;
206 
207     rfsl->rfslField= docClaimField( &(bd->bdFieldList) );
208     if  ( ! rfsl->rfslField )
209 	{ XDEB(rfsl->rfslField); rval= -1; goto ready;	}
210     rfsl->rfslField->dfKind= kind;
211     rfsl->rfslField->dfSelectionScope= rfsl->rfslSelectionScope;
212     rfsl->rfslField->dfHeadPosition= rfsl->rfslStartPosition;
213 
214     if  ( rrs->rrsTextShadingChanged )
215 	{ docRtfRefreshTextShading( rrc, rrs );	}
216 
217     if  ( docInsertAdminParticule( bd, paraNode,
218 					    rfsl->rfslParticule,
219 					    rfsl->rfslStartPosition.epStroff,
220 					    rfsl->rfslField->dfFieldNumber,
221 					    DOCkindFIELDHEAD,
222 					    &(rrs->rrsTextAttribute) ) )
223 	{ LDEB(1); rval= -1; goto ready;	}
224 
225     rrc->rrcAfterNoteref= 0;
226     rrc->rrAfterParaHeadField= 0;
227 
228     if  ( size > 0 )
229 	{
230 	if  ( docSetFieldInst( rfsl->rfslField, fieldinst, size ) )
231 	    { LDEB(size); rval= -1; goto ready;	}
232 	}
233 
234     *pField= rfsl->rfslField;
235     *pPart= part;
236     rrc->rrcFieldStack= rfsl; rfsl= (RtfFieldStackLevel *)0; /* steal */
237 
238   ready:
239 
240     if  ( rfsl )
241 	{ free( rfsl );	}
242 
243     return rval;
244     }
245 
docRtfTerminateField(const RtfFieldStackLevel * rfsl,RtfReader * rrc)246 static int docRtfTerminateField(	const RtfFieldStackLevel *	rfsl,
247 					RtfReader *			rrc )
248     {
249     BufferItem *	bi= rrc->rrcNode;
250     RtfReadingState *	rrs= rrc->rrcState;
251     BufferDocument *	bd= rrc->rrDocument;
252 
253     int			paraNr;
254     int			stroff;
255     int			part;
256 
257     EditPosition	epTail;
258 
259     if  ( ! bi )
260 	{ XDEB(bi); return -1;	}
261     if  ( bi->biLevel != DOClevPARA )
262 	{
263 	DocumentPosition	dp;
264 
265 	if  ( docTailPosition( &dp, bi ) )
266 	    { XDEB(bi); return -1;	}
267 
268 	bi= dp.dpNode;
269 	}
270 
271     if  ( rrs->rrsTextShadingChanged )
272 	{ docRtfRefreshTextShading( rrc, rrs );	}
273 
274     paraNr= docNumberOfParagraph( bi );
275     stroff= docParaStrlen( bi );
276     part= bi->biParaParticuleCount;
277 
278     if  ( docInsertAdminParticule( bd, bi, part, stroff,
279 					    rfsl->rfslField->dfFieldNumber,
280 					    DOCkindFIELDTAIL,
281 					    &(rrs->rrsTextAttribute) ) )
282 	{ LDEB(1); return -1;	}
283 
284     epTail.epParaNr= paraNr;
285     epTail.epStroff= stroff;
286     docSetFieldTail( rfsl->rfslField, &epTail );
287 
288     if  ( rfsl->rfslPrev )
289 	{
290 	if  ( docAddChildToField( rfsl->rfslField, rfsl->rfslPrev->rfslField ) )
291 	    { LDEB(1); return -1;	}
292 	}
293     else{
294 	if  ( docAddRootFieldToTree( rrc->rrcTree, rfsl->rfslField ) )
295 	    { LDEB(1); return -1;	}
296 	}
297 
298     rrc->rrcLastFieldNumber= rfsl->rfslField->dfFieldNumber;
299     rrc->rrcAfterNoteref= 0;
300     rrc->rrAfterParaHeadField= 0;
301 
302     return 0;
303     }
304 
305 /************************************************************************/
306 /*									*/
307 /*  Pop a particular field from the field stack.			*/
308 /*  Improper field/bookmark nesting may cause enclosed fields to be	*/
309 /*  closed and hence that the field that we try to close/pop has	*/
310 /*  already  been closed/popped.					*/
311 /*									*/
312 /************************************************************************/
313 
docRtfPopFieldFromFieldStack(DocumentField * df,RtfReader * rrc)314 static int docRtfPopFieldFromFieldStack(	DocumentField *		df,
315 						RtfReader *	rrc )
316     {
317     RtfFieldStackLevel *	rfsl;
318 
319     rfsl= rrc->rrcFieldStack;
320     while( rfsl )
321 	{
322 	if  ( rfsl->rfslField == df )
323 	    { break;	}
324 
325 	rfsl= rfsl->rfslPrev;
326 	}
327 
328     if  ( ! rfsl )
329 	{ return 0;	}
330 
331     rfsl= rrc->rrcFieldStack;
332     while( rfsl )
333 	{
334 	int	last= ( rfsl->rfslField == df );
335 
336 	if  ( docRtfTerminateField( rfsl, rrc ) )
337 	    { LDEB(1); return -1;	}
338 
339 	rrc->rrcFieldStack= rfsl->rfslPrev;
340 	free( rfsl );
341 
342 	if  ( last )
343 	    { break;	}
344 
345 	rfsl= rrc->rrcFieldStack;
346 	}
347 
348     return 0;
349     }
350 
docRtfPopScopeFromFieldStack(RtfReader * rrc)351 int docRtfPopScopeFromFieldStack(	RtfReader *	rrc )
352     {
353     RtfFieldStackLevel *	rfsl;
354 
355     rfsl= rrc->rrcFieldStack;
356     while( rfsl )
357 	{
358 	if  ( ! docSelectionSameScope( &(rfsl->rfslSelectionScope),
359 						&(rrc->rrcSelectionScope) ) )
360 	    { break;	}
361 
362 	if  ( docRtfTerminateField( rfsl, rrc ) )
363 	    { LDEB(1); return -1;	}
364 
365 	rrc->rrcFieldStack= rfsl->rfslPrev;
366 	free( rfsl );
367 	rfsl= rrc->rrcFieldStack;
368 	}
369 
370     return 0;
371     }
372 
docRtfPopParaFromFieldStack(RtfReader * rrc,int paraNr)373 int docRtfPopParaFromFieldStack(	RtfReader *	rrc,
374 					int			paraNr )
375     {
376     RtfFieldStackLevel *	rfsl;
377 
378     rfsl= rrc->rrcFieldStack;
379     while( rfsl )
380 	{
381 	const FieldKindInformation *	fki;
382 
383 	if  ( ! docSelectionSameScope( &(rfsl->rfslSelectionScope),
384 						&(rrc->rrcSelectionScope) ) )
385 	    { break;	}
386 
387 	if  ( rfsl->rfslField->dfHeadPosition.epParaNr != paraNr )
388 	    { break;	}
389 
390 	if  ( rfsl->rfslField->dfKind >= DOC_FieldKindCount	)
391 	    { break;	}
392 	fki= DOC_FieldKinds+ rfsl->rfslField->dfKind;
393 	if  ( fki->fkiLevel != DOClevSPAN )
394 	    { break;	}
395 
396 	if  ( docRtfTerminateField( rfsl, rrc ) )
397 	    { LDEB(1); return -1;	}
398 
399 	rrc->rrcFieldStack= rfsl->rfslPrev;
400 	free( rfsl );
401 	rfsl= rrc->rrcFieldStack;
402 	}
403 
404     return 0;
405     }
406 
docRtfReadField(const RtfControlWord * rcw,int arg,RtfReader * rrc)407 int docRtfReadField(	const RtfControlWord *	rcw,
408 			int			arg,
409 			RtfReader *	rrc )
410     {
411     int			res;
412 
413     int			startParticule;
414     DocumentField *	df= (DocumentField *)0;
415 
416     /*  docRtfReadPushField() adjusts level */
417     if  ( docRtfReadPushField( &startParticule, &df, DOCfkUNKNOWN, rrc,
418 							(char *)0, 0 ) )
419 	{ SDEB(rcw->rcwWord); return -1;	}
420 
421     res= docRtfReadGroup( rcw, 0, 0, rrc,
422 				docRtfFieldGroups,
423 				docRtfIgnoreText, (RtfCommitGroup)0 );
424     if  ( res )
425 	{ SLDEB(rcw->rcwWord,res);	}
426 
427     if  ( docRtfPopFieldFromFieldStack( df, rrc ) )
428 	{ LDEB(df->dfFieldNumber); return -1;	}
429 
430     return res;
431     }
432 
433 /************************************************************************/
434 /*									*/
435 /*  Trick: Remember rtf for lookup words in field data.			*/
436 /*									*/
437 /************************************************************************/
438 
docRtfLookupWord(const RtfControlWord * rcw,int arg,RtfReader * rrc)439 int docRtfLookupWord(		const RtfControlWord *	rcw,
440 				int			arg,
441 				RtfReader *		rrc )
442     {
443     RtfFieldStackLevel *	rfsl= rrc->rrcFieldStack;
444     char			scratch[40];
445 
446     int				startParticule;
447     DocumentField *		df= (DocumentField *)0;
448 
449     const char *		fieldinst= (const char *)0;
450     int				size= 0;
451 
452     switch( rcw->rcwID )
453 	{
454 	case RTFlookupTCF:
455 	case RTFlookupTCL:
456 	    while( rfsl					&&
457 		   rfsl->rfslField->dfKind != DOCfkTC	&&
458 		   rfsl->rfslField->dfKind != DOCfkTCN	)
459 		{ rfsl= rfsl->rfslPrev;	}
460 	    if  ( ! rfsl )
461 		{ SXDEB(rcw->rcwWord,rfsl); return 0;	}
462 	    break;
463 
464 	case RTFlookupXEF:
465 	case RTFlookupBXE:
466 	case RTFlookupIXE:
467 	    while( rfsl					&&
468 		   rfsl->rfslField->dfKind != DOCfkXE	)
469 		{ rfsl= rfsl->rfslPrev;	}
470 	    if  ( ! rfsl )
471 		{ SXDEB(rcw->rcwWord,rfsl); return 0;	}
472 	    break;
473 
474 	case RTFlookupTC:
475 	    /*  docRtfReadPushField() adjusts level */
476 	    if  ( docRtfReadPushField( &startParticule, &df, DOCfkTC, rrc,
477 							    fieldinst, size ) )
478 		{ LDEB(1); return -1;	}
479 	    return 0;
480 
481 	case RTFlookupTCN:
482 	    /*  docRtfReadPushField() adjusts level */
483 	    if  ( docRtfReadPushField( &startParticule, &df, DOCfkTCN, rrc,
484 							    fieldinst, size ) )
485 		{ LDEB(1); return -1;	}
486 	    return 0;
487 
488 	default:
489 	    SDEB(rcw->rcwWord); return 0;
490 	}
491 
492     switch( rcw->rcwID )
493 	{
494 	case RTFlookupXEF:
495 	case RTFlookupTCF:
496 	case RTFlookupTCL:
497 	    sprintf( scratch, "\\%s%d", rcw->rcwWord, arg );
498 	    if  ( docAddToFieldData( rfsl->rfslField,
499 						scratch, strlen( scratch ) ) )
500 		{ SDEB(rcw->rcwWord); return -1;	}
501 	    return 0;
502 
503 	case RTFlookupBXE:
504 	case RTFlookupIXE:
505 	    sprintf( scratch, "\\%s", rcw->rcwWord );
506 	    if  ( docAddToFieldData( rfsl->rfslField,
507 						scratch, strlen( scratch ) ) )
508 		{ SDEB(rcw->rcwWord); return -1;	}
509 	    return 0;
510 
511 	default:
512 	    SDEB(rcw->rcwWord); return 0;
513 	}
514     }
515 
docRtfLookupEntry(const RtfControlWord * rcw,int arg,RtfReader * rrc)516 int docRtfLookupEntry(		const RtfControlWord *	rcw,
517 				int			arg,
518 				RtfReader *	rrc )
519     {
520     int			res;
521 
522     int			fieldKind;
523 
524     int			startParticule;
525     DocumentField *	df= (DocumentField *)0;
526 
527     const char *	fieldinst= (const char *)0;
528     int			size= 0;
529 
530     switch( rcw->rcwID )
531 	{
532 	case DOCfkXE:
533 	    fieldKind= DOCfkXE;
534 	    break;
535 
536 	case DOCfkTC:
537 	    fieldKind= DOCfkTC;
538 	    break;
539 
540 	case DOCfkTCN:
541 	    fieldKind= DOCfkTCN;
542 	    break;
543 
544 	default:
545 	    SDEB(rcw->rcwWord); return -1;
546 	}
547 
548     /*  docRtfReadPushField() adjusts level */
549     if  ( docRtfReadPushField( &startParticule, &df, fieldKind, rrc,
550 							fieldinst, size ) )
551 	{ SDEB(rcw->rcwWord); return -1;	}
552 
553     res= docRtfReadGroup( rcw, 0, 0, rrc,
554 				(RtfControlWord *)0,
555 				docRtfTextParticule, (RtfCommitGroup)0 );
556 
557     if  ( res )
558 	{ SLDEB(rcw->rcwWord,res);	}
559 
560     if  ( docRtfPopFieldFromFieldStack( df, rrc ) )
561 	{ SDEB(rcw->rcwWord); return -1;	}
562 
563     return res;
564     }
565 
566 /************************************************************************/
567 /*									*/
568 /*  Process bookmarks.							*/
569 /*									*/
570 /************************************************************************/
571 
docRtfCommitBookmarkName(const RtfControlWord * rcw,RtfReader * rrc)572 static int docRtfCommitBookmarkName(	const RtfControlWord *	rcw,
573 					RtfReader *		rrc )
574     {
575     if  ( docRtfMemoryBufferAppendText( &(rrc->rrcBookmark), rrc ) )
576 	{ LDEB(1); return -1;	}
577 
578     if  ( rrc->rrcBookmark.mbSize > DOCmaxBOOKMARK )
579 	{
580 	LLDEB(rrc->rrcBookmark.mbSize,DOCmaxBOOKMARK);
581 	utilMemoryBufferSetSize( &(rrc->rrcBookmark), DOCmaxBOOKMARK );
582 	}
583 
584     return 0;
585     }
586 
docRtfBkmkStart(const RtfControlWord * rcw,int arg,RtfReader * rrc)587 int docRtfBkmkStart(	const RtfControlWord *		rcw,
588 			int				arg,
589 			RtfReader *		rrc )
590     {
591     int			res;
592 
593     int			startParticule;
594     DocumentField *	df= (DocumentField *)0;
595 
596     const char *	fieldinst= (const char *)0;
597     int			size= 0;
598 
599     utilMemoryBufferSetSize( &(rrc->rrcBookmark), 0 );
600 
601     /*  docRtfReadPushField() adjusts level */
602     if  ( docRtfReadPushField( &startParticule, &df, DOCfkBOOKMARK, rrc,
603 							    fieldinst, size ) )
604 	{ LDEB(1); return -1;	}
605 
606     res= docRtfReadGroup( rcw, 0, 0, rrc,
607 						(RtfControlWord *)0,
608 						docRtfSaveDocEncodedText,
609 						docRtfCommitBookmarkName );
610 
611     if  ( res )
612 	{ SLDEB(rcw->rcwWord,res); return res;	}
613 
614     if  ( docSetBookmarkField( &(df->dfInstructions), &(rrc->rrcBookmark) ) )
615 	{ LDEB(1); return -1;	}
616     df->dfKind= DOCfkBOOKMARK;
617 
618     /* Do not pop field stack */
619 
620     return res;
621     }
622 
docRtfBkmkEnd(const RtfControlWord * rcw,int arg,RtfReader * rrc)623 int docRtfBkmkEnd(	const RtfControlWord *	rcw,
624 			int			arg,
625 			RtfReader *	rrc )
626     {
627     BufferDocument *	bd= rrc->rrDocument;
628 
629     int			res;
630     int			fieldNumber;
631 
632     DocumentField *	df;
633 
634     /*  do not push the field */
635 
636     utilMemoryBufferSetSize( &(rrc->rrcBookmark), 0 );
637 
638     if  ( ! docRtfGetParaNode( rrc ) )
639 	{ SDEB(rcw->rcwWord); return -1; }
640 
641     res= docRtfReadGroup( rcw, 0, 0, rrc, (RtfControlWord *)0,
642 						docRtfSaveDocEncodedText,
643 						docRtfCommitBookmarkName );
644 
645     if  ( res )
646 	{ SLDEB(rcw->rcwWord,res); return res;	}
647 
648     fieldNumber= docFindBookmarkField( &df, &(bd->bdFieldList),
649 							&(rrc->rrcBookmark) );
650     if  ( fieldNumber < 0 )
651 	{ /*SDEB((char *)rrc->rrcBookmarkName);*/ return 0;	}
652 
653     if  ( docRtfPopFieldFromFieldStack( df, rrc ) )
654 	{ LDEB(fieldNumber);	}
655 
656     return res;
657     }
658 
659 /************************************************************************/
660 /*									*/
661 /*  Translate a special character to the corresponding field type.	*/
662 /*									*/
663 /************************************************************************/
664 
docRtfSpecialField(int fieldKind,const char * fieldinst,int fieldsize,const char * fieldRslt,RtfReader * rrc)665 DocumentField * docRtfSpecialField(
666 				int			fieldKind,
667 				const char *		fieldinst,
668 				int			fieldsize,
669 				const char *		fieldRslt,
670 				RtfReader *	rrc )
671     {
672     int			startParticule;
673     DocumentField *	df;
674 
675     /*  docRtfReadPushField() adjusts level */
676     if  ( docRtfReadPushField( &startParticule, &df, fieldKind, rrc,
677 						    fieldinst, fieldsize ) )
678 	{ LDEB(1); return (DocumentField *)0;	}
679 
680     if  ( fieldRslt )
681 	{
682 	/*  fieldRslt is an ascii string from the Ted source code here,	*/
683 	/*  so its encoding is irrelevant.				*/
684 
685 	if  ( docRtfTextParticule( rrc, fieldRslt, strlen( fieldRslt ) ) )
686 	    { LDEB(2); return (DocumentField *)0;	}
687 	}
688 
689     if  ( docRtfPopFieldFromFieldStack( df, rrc ) )
690 	{ LDEB(1); return (DocumentField *)0;	}
691 
692     return df;
693     }
694 
695 /************************************************************************/
696 /*									*/
697 /*  Handle an rtf control word that results in a special character in	*/
698 /*  the RTF spec, but that is implemented as a field in Ted.		*/
699 /*									*/
700 /************************************************************************/
701 
docRtfTextSpecialToField(const RtfControlWord * rcw,int arg,RtfReader * rrc)702 int docRtfTextSpecialToField(	const RtfControlWord *	rcw,
703 				int			arg,
704 				RtfReader *		rrc )
705     {
706     const char *		fieldinst= (const char *)"?";
707     int				fieldsize= 1;
708     const char *		fieldRslt= (const char *)"?";
709 
710     int				afterNoteref= 0;
711 
712     switch( rcw->rcwID )
713 	{
714 	case DOCfkPAGE:
715 	    fieldinst= " PAGE ";
716 	    fieldsize= 6;
717 	    break;
718 	case DOCfkDATE:
719 	    fieldinst= " DATE \\* MERGEFORMAT ";
720 	    fieldsize= 21;
721 	    break;
722 	case DOCfkTIME:
723 	    fieldinst= " TIME \\* MERGEFORMAT ";
724 	    fieldsize= 21;
725 	    break;
726 	case DOCfkSECTION:
727 	    fieldinst= " SECTION ";
728 	    fieldsize= 9;
729 	    break;
730 
731 	case DOCfkCHFTN:
732 	    fieldinst= " -CHFTN ";
733 	    fieldsize= 8;
734 	    fieldRslt= (const char *)"1";
735 	    afterNoteref= 1;
736 	    break;
737 	case DOCfkCHATN:
738 	    fieldinst= " -CHATN ";
739 	    fieldsize= 8;
740 	    fieldRslt= (const char *)"!";
741 	    afterNoteref= 1;
742 	    break;
743 
744 	default:
745 	    SDEB(rcw->rcwWord); return -1;
746 	}
747 
748     if  ( ! docRtfSpecialField( rcw->rcwID,
749 				    fieldinst, fieldsize, fieldRslt, rrc ) )
750 	{ SDEB(rcw->rcwWord); return -1;	}
751 
752     rrc->rrcAfterNoteref= afterNoteref;
753     rrc->rrAfterParaHeadField= afterNoteref != 0;
754 
755     return 0;
756     }
757 
758 /************************************************************************/
759 /*									*/
760 /*  Read a group that results in a text field.				*/
761 /*									*/
762 /************************************************************************/
763 
docRtfReadTextField(const RtfControlWord * rcw,int arg,RtfReader * rrc)764 int docRtfReadTextField(	const RtfControlWord *	rcw,
765 				int			arg,
766 				RtfReader *		rrc )
767     {
768     int			res;
769 
770     int			startParticule;
771     DocumentField *	df= (DocumentField *)0;
772 
773     const char *	fieldinst= (const char *)0;
774     int			size= 0;
775 
776 #   if 0
777     /*  Will be added later on, as the table nesting is given inside */
778     /*  the field, we have a problem if we start the paragraph now. */
779     if  ( rcw->rcwID == DOCfkLISTTEXT )
780 	{
781 	rrc->rrAfterParaHeadField= 1;
782 	return docRtfSkipGroup( rcw, arg, rrc );
783 	}
784 #   endif
785 
786     /*  docRtfReadPushField() adjusts level */
787     if  ( docRtfReadPushField( &startParticule, &df, rcw->rcwID, rrc,
788 							    fieldinst, size ) )
789 	{ SDEB(rcw->rcwWord); return -1;	}
790 
791     res= docRtfReadGroup( rcw, 0, 0, rrc,
792 				docRtfDocumentGroups,
793 				docRtfTextParticule, (RtfCommitGroup)0 );
794     if  ( res )
795 	{ SLDEB(rcw->rcwWord,res);	}
796 
797     if  ( docRtfPopFieldFromFieldStack( df, rrc ) )
798 	{ LDEB(1);	}
799 
800     if  ( rcw->rcwID == DOCfkLISTTEXT )
801 	{ rrc->rrAfterParaHeadField= 1;	}
802 
803     return res;
804     }
805 
806 /************************************************************************/
807 /*									*/
808 /*  Handle a field property when reading RTF.				*/
809 /*									*/
810 /************************************************************************/
811 
docRtfRememberFieldProperty(const RtfControlWord * rcw,int arg,RtfReader * rrc)812 int docRtfRememberFieldProperty(	const RtfControlWord *	rcw,
813 					int			arg,
814 					RtfReader *		rrc )
815     {
816     RtfFieldStackLevel *	rfsl= rrc->rrcFieldStack;
817 
818     if  ( ! rfsl )
819 	{ SXDEB(rcw->rcwWord,rrc->rrcFieldStack); return 0;	}
820 
821     if  ( docSetFieldProperty( rfsl->rfslField, rcw->rcwID, arg ) )
822 	{ SLDEB(rcw->rcwWord,arg); return 0;	}
823 
824     return 0;
825     }
826 
827 /************************************************************************/
828 /*									*/
829 /*  Handle a note property when reading RTF.				*/
830 /*									*/
831 /************************************************************************/
832 
docRtfRememberNoteProperty(const RtfControlWord * rcw,int arg,RtfReader * rrc)833 int docRtfRememberNoteProperty(	const RtfControlWord *	rcw,
834 				int			arg,
835 				RtfReader *		rrc )
836     {
837     switch( rcw->rcwID )
838 	{
839 	case NOTEpropTREE_TYPE:
840 	    if  ( rrc->rrcSelectionScope.ssTreeType != DOCinFOOTNOTE )
841 		{ LLDEB(rrc->rrcSelectionScope.ssTreeType,DOCinFOOTNOTE); }
842 	    else{
843 		rrc->rrcSelectionScope.ssTreeType= rcw->rcwEnumValue;
844 		rrc->rrcNoteProperties.npTreeType= rcw->rcwEnumValue;
845 		}
846 	    break;
847 
848 	case NOTEpropAUTO_NUMBER:
849 	    rrc->rrcNoteProperties.npAutoNumber= arg != 0;
850 	    break;
851 
852 	default:
853 	    SDEB(rcw->rcwWord); return -1;
854 	}
855 
856     PROPmaskADD( &(rrc->rrcNotePropertyMask), rcw->rcwID );
857 
858     return 0;
859     }
860 
861