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