1 /************************************************************************/
2 /*									*/
3 /*  Manage fields.							*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"docBaseConfig.h"
8 
9 #   include	<stdlib.h>
10 #   include	<string.h>
11 
12 #   include	<appDebugon.h>
13 
14 #   include	"docFieldInstructions.h"
15 
16 /************************************************************************/
17 /*									*/
18 /*  Manage fields.							*/
19 /*									*/
20 /************************************************************************/
21 
docCleanInstructionsComponent(InstructionsComponent * ic)22 static void docCleanInstructionsComponent(	InstructionsComponent *	ic )
23     { utilCleanMemoryBuffer( &(ic->icBuffer) );	}
24 
docInitInstructionsComponent(InstructionsComponent * ic)25 static void docInitInstructionsComponent(	InstructionsComponent *	ic )
26     {
27     utilInitMemoryBuffer( &(ic->icBuffer) );
28 
29     ic->icIsFlag= 0;
30     ic->icIsQuoted= 0;
31     }
32 
docCopyInstructionsComponent(InstructionsComponent * to,const InstructionsComponent * from)33 static int docCopyInstructionsComponent( InstructionsComponent *	to,
34 					const InstructionsComponent *	from )
35     {
36     if  ( utilCopyMemoryBuffer( &(to->icBuffer), &(from->icBuffer) ) )
37 	{ LDEB(1); return -1;	}
38 
39     to->icIsFlag= from->icIsFlag;
40     to->icIsQuoted= from->icIsQuoted;
41 
42     return 0;
43     }
44 
docInitFieldInstructions(FieldInstructions * fi)45 void docInitFieldInstructions(	FieldInstructions *	fi )
46     {
47     fi->fiComponents= (InstructionsComponent *)0;
48     fi->fiComponentCount= 0;
49     }
50 
docCleanFieldInstructions(FieldInstructions * fi)51 void docCleanFieldInstructions(	FieldInstructions *	fi )
52     {
53     if  ( fi->fiComponents )
54 	{
55 	int		i;
56 
57 	for ( i= 0; i < fi->fiComponentCount; i++ )
58 	    {
59 	    docCleanInstructionsComponent( &(fi->fiComponents[i]) );
60 	    }
61 
62 	free( fi->fiComponents );
63 	}
64 
65     return;
66     }
67 
docAllocateComponents(FieldInstructions * fi,int n)68 int docAllocateComponents(	FieldInstructions *		fi,
69 				int				n )
70     {
71     InstructionsComponent *	fresh;
72 
73     if  ( n == 0 )
74 	{
75 	docCleanFieldInstructions( fi );
76 	fi->fiComponents= (InstructionsComponent *)0;
77 	fi->fiComponentCount= 0;
78 	return 0;
79 	}
80 
81     while( fi->fiComponentCount > n )
82 	{
83 	fi->fiComponentCount--;
84 	docCleanInstructionsComponent( fi->fiComponents+
85 					fi->fiComponentCount );
86 	}
87 
88     fresh= realloc( fi->fiComponents,
89 				    n* sizeof(InstructionsComponent) );
90     if  ( ! fresh )
91 	{ LXDEB(n,fresh); return -1;	}
92     fi->fiComponents= fresh;
93 
94     while( fi->fiComponentCount < n )
95 	{
96 	docInitInstructionsComponent( fi->fiComponents+
97 					fi->fiComponentCount++ );
98 	}
99 
100     return 0;
101     }
102 
103 /************************************************************************/
104 /*									*/
105 /*  Copy the properties of a field.					*/
106 /*									*/
107 /*  Only properties that have an application meaning are copied. The	*/
108 /*  set is determined by what can appaer in RTF.			*/
109 /*									*/
110 /************************************************************************/
111 
docCopyFieldInstructions(FieldInstructions * fiTo,const FieldInstructions * fiFrom)112 int docCopyFieldInstructions(	FieldInstructions *		fiTo,
113 				const FieldInstructions *	fiFrom )
114     {
115     int			i;
116 
117     if  ( docAllocateComponents( fiTo,
118 					fiFrom->fiComponentCount ) )
119 	{ LDEB(fiFrom->fiComponentCount); return -1;	}
120 
121     for ( i= 0; i < fiTo->fiComponentCount; i++ )
122 	{
123 	if  ( docCopyInstructionsComponent(
124 				    fiTo->fiComponents+ i,
125 				    fiFrom->fiComponents+ i ) )
126 	    { LDEB(i); return -1;	}
127 	}
128 
129     return 0;
130     }
131 
132 /************************************************************************/
133 /*									*/
134 /*  Split field instructions in a vector of arguments.			*/
135 /*									*/
136 /************************************************************************/
137 
docSplitFieldInstructions(InstructionsComponent * ic,const char * bytes,int count)138 static int docSplitFieldInstructions(
139 				InstructionsComponent *		ic,
140 				const char *			bytes,
141 				int				count )
142     {
143     const char *	from= bytes;
144     int			offset= 0;
145     int			n= 0;
146 
147     for (;;)
148 	{
149 	int		size= 0;
150 	const char *	head= from;
151 	int		quoted= 0;
152 	int		flag= 0;
153 
154 	int		unmatchedQuote= 0;
155 
156 	while( offset < count && *from == ' ' )
157 	    { offset++; from++;	}
158 
159 	if  ( offset >= count )
160 	    { break;	}
161 
162 	if  ( from[0] == '\\'		&&
163 	      offset < count- 1		&&
164 	      from[1] != ' '		)
165 	    {
166 	    if  ( ic )
167 		{
168 		if  ( utilMemoryBufferSetBytes( &(ic->icBuffer),
169 					    (const unsigned char *)from, 2 ) )
170 		    { LDEB(1); return -1;	}
171 
172 		ic->icIsFlag= 1;
173 		ic->icIsQuoted= 0;
174 		ic++;
175 		}
176 
177 	    offset += 2;  from += 2; n++;
178 	    continue;
179 	    }
180 
181 	if  ( from[0] == '"' )
182 	    {
183 	    offset++; from++;
184 
185 	    if  ( from[0] == '"' )
186 		{ offset++; from++; continue; }
187 
188 	    head= from;
189 	    quoted= 1;
190 	    flag= 0;
191 	    while( offset < count && *from != '"' )
192 		{ size++; offset++; from++;	}
193 
194 	    if  ( offset >= count )
195 		{ SLLDEB(bytes,offset,count); unmatchedQuote= 1;	}
196 	    else{ offset++; from++;					}
197 	    }
198 	else{
199 	    head= from;
200 	    quoted= 0;
201 	    flag= *from == '\\';
202 	    while( offset < count && *from != ' ' )
203 		{ size++; offset++; from++;	}
204 	    }
205 
206 	if  ( ic )
207 	    {
208 	    if  ( utilMemoryBufferSetBytes( &(ic->icBuffer),
209 					(const unsigned char *)head, size ) )
210 		{ LDEB(1); return -1;	}
211 
212 	    if  ( unmatchedQuote					&&
213 		  utilMemoryBufferAppendString( &(ic->icBuffer), "\"" )	)
214 		{ LDEB(unmatchedQuote); return -1;	}
215 
216 	    ic->icIsFlag= flag;
217 	    ic->icIsQuoted= quoted;
218 	    ic++;
219 	    }
220 
221 	n++;
222 	}
223 
224     return n;
225     }
226 
docSetFieldInstructions(FieldInstructions * fi,const char * bytes,int size)227 int docSetFieldInstructions(	FieldInstructions *	fi,
228 				const char *		bytes,
229 				int			size )
230     {
231     int		n;
232 
233     n= docSplitFieldInstructions( (InstructionsComponent *)0, bytes, size );
234     if  ( n < 0 )
235 	{ LDEB(n); return -1;	}
236 
237     if  ( docAllocateComponents( fi, n ) )
238 	{ LDEB(n); return -1;	}
239 
240     n= docSplitFieldInstructions( fi->fiComponents, bytes, size );
241     if  ( n < 0 )
242 	{ LDEB(n); return -1;	}
243 
244     return 0;
245     }
246 
docFieldMustBeQuoted(const InstructionsComponent * ic)247 static int docFieldMustBeQuoted(	const InstructionsComponent *	ic )
248     {
249     const MemoryBuffer *	mb= &(ic->icBuffer);
250     int				i;
251 
252     if  ( utilMemoryBufferIsEmpty( mb ) )
253 	{ return 1;	}
254     if  ( mb->mbBytes[0] == '\\' )
255 	{ return 1;	}
256 
257     for ( i= 0; i < mb->mbSize; i++ )
258 	{
259 	if  ( mb->mbBytes[i] == ' ' )
260 	    { return 1;	}
261 	}
262 
263     return 0;
264     }
265 
docFieldSetComponentBuffer(InstructionsComponent * ic,const MemoryBuffer * mb)266 static int docFieldSetComponentBuffer(	InstructionsComponent *	ic,
267 					const MemoryBuffer *	mb )
268     {
269     if  ( utilCopyMemoryBuffer( &(ic->icBuffer), mb ) )
270 	{ LDEB(1); return -1;	}
271 
272     ic->icIsFlag= 0;
273     ic->icIsQuoted= docFieldMustBeQuoted( ic );
274 
275     return 0;
276     }
277 
docFieldInstructionsAddFlag(FieldInstructions * fi,int flag)278 int docFieldInstructionsAddFlag(	FieldInstructions *	fi,
279 					int			flag )
280     {
281     unsigned char		scratch[3];
282     InstructionsComponent *	ic;
283 
284     if  ( docAllocateComponents( fi, fi->fiComponentCount+ 1 ) )
285 	{ LDEB(fi->fiComponentCount); return -1;	}
286 
287     scratch[0]= '\\';
288     scratch[1]= flag;
289     scratch[2]= '\0';
290 
291     ic= &(fi->fiComponents[fi->fiComponentCount- 1]);
292 
293     if  ( utilMemoryBufferSetBytes( &(ic->icBuffer), scratch, 2 ) )
294 	{ LDEB(2); return -1;	}
295 
296     ic->icIsFlag= 1;
297     ic->icIsQuoted= 0;
298 
299     return 0;
300     }
301 
docStartFieldInstructions(FieldInstructions * fi,const char * kindName,int kindSize)302 int docStartFieldInstructions(	FieldInstructions *	fi,
303 				const char *		kindName,
304 				int			kindSize )
305     {
306     if  ( docAllocateComponents( fi, 1 ) )
307 	{ LDEB(2); return -1;	}
308 
309     if  ( utilMemoryBufferSetBytes( &(fi->fiComponents[0].icBuffer),
310 				(const unsigned char *)kindName, kindSize ) )
311 	{ LDEB(kindSize); return -1;	}
312 
313     fi->fiComponents[0].icIsFlag= 0;
314     fi->fiComponents[0].icIsQuoted= 0;
315 
316     return 0;
317     }
318 
docFieldInstructionsAddArgFlagIfSet(FieldInstructions * fi,int flag,const MemoryBuffer * valueName)319 int docFieldInstructionsAddArgFlagIfSet( FieldInstructions *	fi,
320 					int			flag,
321 					const MemoryBuffer *	valueName )
322     {
323     if  ( ! utilMemoryBufferIsEmpty( valueName ) )
324 	{ return docFieldInstructionsAddArgFlag( fi, flag, valueName );	}
325     else{ return 0;							}
326     }
327 
docFieldInstructionsAddArgFlag(FieldInstructions * fi,int flag,const MemoryBuffer * valueName)328 int docFieldInstructionsAddArgFlag(	FieldInstructions *	fi,
329 					int			flag,
330 					const MemoryBuffer *	valueName )
331     {
332     unsigned char		scratch[3];
333     InstructionsComponent *	ic;
334 
335     if  ( docAllocateComponents( fi, fi->fiComponentCount+ 2 ) )
336 	{ LDEB(fi->fiComponentCount); return -1;	}
337 
338     scratch[0]= '\\';
339     scratch[1]= flag;
340     scratch[2]= '\0';
341 
342     ic= &(fi->fiComponents[fi->fiComponentCount- 2]);
343 
344     if  ( utilMemoryBufferSetBytes( &(ic->icBuffer), scratch, 2 ) )
345 	{ LDEB(2); return -1;	}
346 
347     ic->icIsFlag= 1;
348     ic->icIsQuoted= 0;
349 
350     ic++;
351 
352     if  ( docFieldSetComponentBuffer( ic, valueName ) )
353 	{ LDEB(1); return -1;	}
354 
355     return 0;
356     }
357 
docFieldInstructionsAddComponent(FieldInstructions * fi,const MemoryBuffer * mb)358 int docFieldInstructionsAddComponent(	FieldInstructions *	fi,
359 					const MemoryBuffer *	mb )
360     {
361     InstructionsComponent *	ic;
362 
363     if  ( docAllocateComponents( fi, fi->fiComponentCount+ 1 ) )
364 	{ LDEB(fi->fiComponentCount); return -1;	}
365 
366     ic= fi->fiComponents + fi->fiComponentCount- 1;
367 
368     if  ( docFieldSetComponentBuffer( ic, mb ) )
369 	{ LDEB(1); return -1;	}
370 
371     return 0;
372     }
373 
docComponentIsFlag(const FieldInstructions * fi,int comp,int flag)374 int docComponentIsFlag(		const FieldInstructions *	fi,
375 				int				comp,
376 				int				flag )
377     {
378     const InstructionsComponent *	ic= fi->fiComponents+ comp;
379 
380     if  ( ! ic->icIsFlag )
381 	{ return 0;	}
382     if  ( ic->icBuffer.mbSize != 2 )
383 	{ return 0;	}
384     if  ( ic->icBuffer.mbBytes[0] != '\\' )
385 	{ return 0;	}
386     if  ( ic->icBuffer.mbBytes[1] != flag )
387 	{ return 0;	}
388 
389     return 1;
390     }
391 
docComponentIsArgFlag(const FieldInstructions * fi,int comp,int flag)392 int docComponentIsArgFlag(	const FieldInstructions *	fi,
393 				int				comp,
394 				int				flag )
395     {
396     if  ( comp > fi->fiComponentCount- 2 )
397 	{ return 0;	}
398 
399     return docComponentIsFlag( fi, comp, flag );
400     }
401 
docComponentEqualsWord(const InstructionsComponent * ic,const char * word,int len)402 int docComponentEqualsWord(	const InstructionsComponent *	ic,
403 				const char *			word,
404 				int				len )
405     {
406     if  ( ic->icBuffer.mbSize != len )
407 	{ return 0;	}
408     if  ( memcmp( ic->icBuffer.mbBytes, word, len ) )
409 	{ return 0;	}
410 
411     return 1;
412     }
413 
docComponentEqualsWordNoCase(const InstructionsComponent * ic,const char * word,int len)414 int docComponentEqualsWordNoCase( const InstructionsComponent *	ic,
415 				const char *			word,
416 				int				len )
417     {
418     int		i;
419 
420     if  ( ic->icBuffer.mbSize != len )
421 	{ return 0;	}
422 
423     for ( i= 0; i < len; i++ )
424 	{
425 	if  ( tolower( ic->icBuffer.mbBytes[i] ) != tolower( word[i] ) )
426 	    { return 0;	}
427 	}
428 
429     return 1;
430     }
431