Branch data Line data Source code
1 : : /*
2 : : Copyright (c) 2010-2014 Jeremiah Martell
3 : : All rights reserved.
4 : :
5 : : Redistribution and use in source and binary forms, with or without modification,
6 : : are permitted provided that the following conditions are met:
7 : :
8 : : - Redistributions of source code must retain the above copyright notice,
9 : : this list of conditions and the following disclaimer.
10 : : - Redistributions in binary form must reproduce the above copyright notice,
11 : : this list of conditions and the following disclaimer in the documentation
12 : : and/or other materials provided with the distribution.
13 : : - Neither the name of Jeremiah Martell nor the name of GeekHorse nor the
14 : : name of Trot nor the names of its contributors may be used to endorse or
15 : : promote products derived from this software without specific prior written
16 : : permission.
17 : :
18 : : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 : : ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 : : WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 : : DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 : : ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 : : (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 : : LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 : : ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 : : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 : : SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 : : */
29 : :
30 : : /******************************************************************************/
31 : : /*!
32 : : \file
33 : : Encodes a trot list into a textual format.
34 : : */
35 : : #define TROT_FILE_NUMBER 6
36 : :
37 : : /******************************************************************************/
38 : : #include "trot.h"
39 : : #include "trotInternal.h"
40 : :
41 : : /******************************************************************************/
42 : : static TROT_RC appendLeftBracketAndTags( TrotList *lCharacters, TrotList *l );
43 : : static TROT_RC appendAbsTwinLocation( TrotList *lCharacters, TrotList *l );
44 : : static TROT_RC appendNumber( TrotList *lCharacters, TROT_INT n );
45 : : static TROT_RC appendText( TrotList *lCharacters, TrotList *l, TROT_INT count, TROT_INT *index );
46 : :
47 : : /******************************************************************************/
48 : : /*!
49 : : \brief Encodes a list into a list of characters.
50 : : \param[in] listToEncode The list to encode
51 : : \param[out] lCharacters_A On success, the encoding.
52 : : \return TROT_RC
53 : :
54 : : listToEncode is not modified.
55 : : lCharacters_A is created, and caller is responsible for freeing.
56 : : */
57 : 8925 : TROT_RC trotEncode( TrotList *listToEncode, TrotList **lCharacters_A )
58 : : {
59 : : /* DATA */
60 : 8925 : TROT_RC rc = TROT_RC_SUCCESS;
61 : :
62 : 8925 : TrotList *newCharacters = NULL;
63 : :
64 : 8925 : TrotList *lParentStack = NULL;
65 : 8925 : TROT_INT parentStackCount = 0;
66 : :
67 : 8925 : TrotList *lParentIndicesStack = NULL;
68 : :
69 : 8925 : TrotList *lCurrentList = NULL;
70 : :
71 : 8925 : TROT_INT tag = 0;
72 : 8925 : TROT_INT childrenCount = 0;
73 : 8925 : TROT_INT index = 1;
74 : :
75 : 8925 : TROT_INT kind = 0;
76 : :
77 : 8925 : TROT_INT n = 0;
78 : :
79 : 8925 : TrotList *lChildList = NULL;
80 : :
81 : :
82 : : /* PRECOND */
83 [ + + ]: 8925 : ERR_IF( listToEncode == NULL, TROT_RC_ERROR_PRECOND );
84 [ + + ]: 8924 : ERR_IF( lCharacters_A == NULL, TROT_RC_ERROR_PRECOND );
85 [ + + ]: 8923 : ERR_IF( (*lCharacters_A) != NULL, TROT_RC_ERROR_PRECOND );
86 : :
87 : :
88 : : /* CODE */
89 : : /* create "give back" list */
90 : 8922 : rc = trotListInit( &newCharacters );
91 [ + + ]: 8922 : ERR_IF_PASSTHROUGH;
92 : :
93 : : /* create parent stack, so we can "go up" */
94 : 8746 : rc = trotListInit( &lParentStack );
95 [ + + ]: 8746 : ERR_IF_PASSTHROUGH;
96 : :
97 : 8570 : rc = trotListInit( &lParentIndicesStack );
98 [ + + ]: 8570 : ERR_IF_PASSTHROUGH;
99 : :
100 : : /* setup */
101 : 8394 : rc = trotListTwin( listToEncode, &lCurrentList );
102 [ + + ]: 8394 : ERR_IF_PASSTHROUGH;
103 : :
104 : 8372 : lCurrentList->laPointsTo->encodingChildNumber = -1;
105 : :
106 : : /* start our encoding */
107 : 8372 : rc = appendLeftBracketAndTags( newCharacters, lCurrentList );
108 [ + + ]: 8372 : ERR_IF_PASSTHROUGH;
109 : :
110 : : /* go through list */
111 : : while ( 1 )
112 : : {
113 : : /* do we have a next child? */
114 : :
115 : : /* get count */
116 : 282358 : rc = trotListGetCount( lCurrentList, &childrenCount );
117 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
118 : :
119 : : /* are we out of children? */
120 [ + + ]: 282358 : if ( index > childrenCount )
121 : : {
122 : : /* append "]" */
123 : 54013 : rc = trotListAppendInt( newCharacters, ']' );
124 [ + + ]: 54013 : ERR_IF_PASSTHROUGH;
125 : :
126 : : /* append space */
127 : 54009 : rc = trotListAppendInt( newCharacters, ' ' );
128 [ + + ]: 54009 : ERR_IF_PASSTHROUGH;
129 : :
130 : : /* do we have a parent? */
131 : 53997 : rc = trotListGetCount( lParentStack, &parentStackCount );
132 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
133 : :
134 [ + + ]: 53997 : if ( parentStackCount == 0 )
135 : : {
136 : : /* break, we're done */
137 : 7042 : break;
138 : : }
139 : :
140 : : /* go up to parent */
141 : 46955 : trotListFree( &lCurrentList );
142 : 46955 : rc = trotListRemoveList( lParentStack, -1, &lCurrentList );
143 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
144 : :
145 : 46955 : rc = trotListRemoveInt( lParentIndicesStack, -1, &index );
146 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
147 : :
148 : : /* increment */
149 : 46955 : index += 1;
150 : :
151 : : /* continue */
152 : 46955 : continue;
153 : : }
154 : :
155 : : /* get kind */
156 : 228345 : rc = trotListGetKind( lCurrentList, index, &kind );
157 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
158 : :
159 [ + + ]: 228345 : if ( kind == TROT_KIND_INT )
160 : : {
161 : : /* get tag */
162 : 101742 : rc = trotListGetTag( lCurrentList, &tag );
163 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
164 : :
165 : : /* if tag'd text, append in text format */
166 [ + + ]: 101742 : if ( tag == TROT_TAG_TEXT )
167 : : {
168 : 747 : rc = appendText( newCharacters, lCurrentList, childrenCount, &index );
169 [ + + ]: 747 : ERR_IF_PASSTHROUGH;
170 : : }
171 : : /* else append in number format */
172 : : else
173 : : {
174 : : /* get int */
175 : 100995 : rc = trotListGetInt( lCurrentList, index, &n );
176 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
177 : :
178 : : /* append number */
179 : 100995 : rc = appendNumber( newCharacters, n );
180 [ + + ]: 100995 : ERR_IF_PASSTHROUGH;
181 : :
182 : : /* append space */
183 : 100967 : rc = trotListAppendInt( newCharacters, ' ' );
184 [ + + ]: 100967 : ERR_IF_PASSTHROUGH;
185 : : }
186 : : }
187 : : else /* kind == TROT_KIND_LIST */
188 : : {
189 : : PARANOID_ERR_IF( kind != TROT_KIND_LIST );
190 : :
191 : : /* get child list */
192 : 126603 : trotListFree( &lChildList );
193 : 126603 : rc = trotListGetList( lCurrentList, index, &lChildList );
194 [ + + ]: 126603 : ERR_IF_PASSTHROUGH;
195 : :
196 : : PARANOID_ERR_IF( lChildList->laPointsTo == NULL );
197 : : /* if we've already encoded this list, then append the reference location
198 : : Example: @.1.2.3
199 : : */
200 [ + + ]: 126411 : if ( lChildList->laPointsTo->encodingChildNumber != 0 )
201 : : {
202 : : /* append reference location */
203 : 78890 : rc = appendAbsTwinLocation( newCharacters, lChildList );
204 [ + + ]: 78890 : ERR_IF_PASSTHROUGH;
205 : : }
206 : : /* else we havent encoded this list yet, so encode it normally */
207 : : else
208 : : {
209 : 47521 : lChildList->laPointsTo->encodingChildNumber = index;
210 : 47521 : lChildList->laPointsTo->encodingParent = lCurrentList->laPointsTo;
211 : :
212 : 47521 : rc = appendLeftBracketAndTags( newCharacters, lChildList );
213 [ + + ]: 47521 : ERR_IF_PASSTHROUGH;
214 : :
215 : : /* push to parent stacks, setup vars */
216 : 47473 : rc = trotListAppendList( lParentStack, lCurrentList );
217 [ + + ]: 47473 : ERR_IF_PASSTHROUGH;
218 : :
219 : 47179 : rc = trotListAppendInt( lParentIndicesStack, index );
220 [ + + ]: 47179 : ERR_IF_PASSTHROUGH;
221 : :
222 : 46983 : trotListFree( &lCurrentList );
223 : 46983 : lCurrentList = lChildList;
224 : 46983 : lChildList = NULL;
225 : :
226 : 46983 : index = 0;
227 : :
228 : : PARANOID_ERR_IF( lCurrentList->laPointsTo == NULL );
229 : : }
230 : :
231 : : } /* end if (kind) */
232 : :
233 : : /* increment */
234 : 227075 : index += 1;
235 : :
236 : 274030 : } /* end while(1) */
237 : :
238 : : /* go through tree again, resetting encodingChildNumber and encodingParent */
239 : :
240 : : /* create parent stack, so we can "go up" */
241 : 7042 : trotListFree( &lParentStack );
242 : 7042 : rc = trotListInit( &lParentStack );
243 [ + + ]: 7042 : ERR_IF_PASSTHROUGH;
244 : :
245 : 6866 : trotListFree( &lParentIndicesStack );
246 : 6866 : rc = trotListInit( &lParentIndicesStack );
247 [ + + ]: 6866 : ERR_IF_PASSTHROUGH;
248 : :
249 : : /* setup */
250 : 6690 : trotListFree( &lCurrentList );
251 : 6690 : rc = trotListTwin( listToEncode, &lCurrentList );
252 [ + + ]: 6690 : ERR_IF_PASSTHROUGH;
253 : :
254 : 6668 : index = 1;
255 : :
256 : : PARANOID_ERR_IF( lCurrentList->laPointsTo == NULL );
257 : :
258 : : /* go through list */
259 : : while ( 1 )
260 : : {
261 : : /* do we have a next child? */
262 : :
263 : : /* get count */
264 : 327854 : rc = trotListGetCount( lCurrentList, &childrenCount );
265 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
266 : :
267 : : /* are we out of children? */
268 [ + + ]: 327854 : if ( index > childrenCount )
269 : : {
270 : : /* do we have a parent? */
271 : 42771 : rc = trotListGetCount( lParentStack, &parentStackCount );
272 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
273 : :
274 [ + + ]: 42771 : if ( parentStackCount == 0 )
275 : : {
276 : : /* break, we're done */
277 : 5922 : break;
278 : : }
279 : :
280 : : /* go up to parent */
281 : 36849 : trotListFree( &lCurrentList );
282 : 36849 : rc = trotListRemoveList( lParentStack, -1, &lCurrentList );
283 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
284 : :
285 : 36849 : rc = trotListRemoveInt( lParentIndicesStack, -1, &index );
286 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
287 : :
288 : : /* increment */
289 : 36849 : index += 1;
290 : :
291 : : /* continue */
292 : 36849 : continue;
293 : : }
294 : :
295 : : /* get kind */
296 : 285083 : rc = trotListGetKind( lCurrentList, index, &kind );
297 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
298 : :
299 [ + + ]: 285083 : if ( kind == TROT_KIND_LIST )
300 : : {
301 : : /* get child list */
302 : 145972 : trotListFree( &lChildList );
303 : 145972 : rc = trotListGetList( lCurrentList, index, &lChildList );
304 [ + + ]: 145972 : ERR_IF_PASSTHROUGH;
305 : :
306 : : PARANOID_ERR_IF( lChildList->laPointsTo == NULL );
307 : : /* if this list has an encoding number */
308 [ + + ]: 145726 : if ( lChildList->laPointsTo->encodingChildNumber != 0 )
309 : : {
310 : : /* reset encoding members */
311 : 37403 : lChildList->laPointsTo->encodingChildNumber = 0;
312 : 37403 : lChildList->laPointsTo->encodingParent = NULL;
313 : :
314 : : /* push to parent stacks, setup vars */
315 : 37403 : rc = trotListAppendList( lParentStack, lCurrentList );
316 [ + + ]: 37403 : ERR_IF_PASSTHROUGH;
317 : :
318 : 37103 : rc = trotListAppendInt( lParentIndicesStack, index );
319 [ + + ]: 37103 : ERR_IF_PASSTHROUGH;
320 : :
321 : 36903 : trotListFree( &lCurrentList );
322 : 36903 : lCurrentList = lChildList;
323 : 36903 : lChildList = NULL;
324 : :
325 : 36903 : index = 0;
326 : :
327 : : PARANOID_ERR_IF( lCurrentList->laPointsTo == NULL );
328 : : }
329 : :
330 : : } /* end if ( kind == TROT_KIND_LIST ) */
331 : :
332 : : /* increment */
333 : 284337 : index += 1;
334 : :
335 : 321186 : } /* end while ( 1 ) */
336 : :
337 : 5922 : listToEncode->laPointsTo->encodingChildNumber = 0;
338 : :
339 : :
340 : : /* give back */
341 : 5922 : (*lCharacters_A) = newCharacters;
342 : 5922 : newCharacters = NULL;
343 : :
344 : :
345 : : /* CLEANUP */
346 : : cleanup:
347 : :
348 : 8925 : trotListFree( &newCharacters );
349 : 8925 : trotListFree( &lParentStack );
350 : 8925 : trotListFree( &lParentIndicesStack );
351 : 8925 : trotListFree( &lCurrentList );
352 : 8925 : trotListFree( &lChildList );
353 : :
354 : 8925 : return rc;
355 : : }
356 : :
357 : : /******************************************************************************/
358 : : /*!
359 : : \brief Append encoding of left bracket and it's tags.
360 : : \param[in] lCharacters List of characters to append to.
361 : : \param[in] l List we're appending the encoding of. We need this to get the
362 : : tags.
363 : : \return TROT_RC
364 : :
365 : : lCharacters will have encoding text appended to it.
366 : : l will not be modified.
367 : :
368 : : Example:
369 : : If l had a tag of 1 and a userTag of 55, then we would append to lCharacters
370 : : this:
371 : : "[ ~1 `55 "
372 : : */
373 : 55893 : static TROT_RC appendLeftBracketAndTags( TrotList *lCharacters, TrotList *l )
374 : : {
375 : : /* DATA */
376 : 55893 : TROT_RC rc = TROT_RC_SUCCESS;
377 : :
378 : 55893 : TROT_INT tag = 0;
379 : :
380 : :
381 : : /* PRECOND */
382 : : PARANOID_ERR_IF( lCharacters == NULL );
383 : : PARANOID_ERR_IF( l == NULL );
384 : :
385 : :
386 : : /* CODE */
387 : : /* append "[ " */
388 : 55893 : rc = trotListAppendInt( lCharacters, '[' );
389 [ + + ]: 55893 : ERR_IF_PASSTHROUGH;
390 : 55837 : rc = trotListAppendInt( lCharacters, ' ' );
391 [ + + ]: 55837 : ERR_IF_PASSTHROUGH;
392 : :
393 : : /* append tag */
394 : 55825 : tag = l->laPointsTo->tag;
395 : :
396 [ + + ]: 55825 : if ( tag != 0 )
397 : : {
398 : 14391 : rc = trotListAppendInt( lCharacters, '~' );
399 [ + + ]: 14391 : ERR_IF_PASSTHROUGH;
400 : 14387 : rc = appendNumber( lCharacters, tag );
401 [ + + ]: 14387 : ERR_IF_PASSTHROUGH;
402 : :
403 : 14383 : rc = trotListAppendInt( lCharacters, ' ' );
404 [ + + ]: 14383 : ERR_IF_PASSTHROUGH;
405 : : }
406 : :
407 : : /* append userTag */
408 : 55813 : tag = l->laPointsTo->userTag;
409 : :
410 [ + + ]: 55813 : if ( tag != 0 )
411 : : {
412 : 13647 : rc = trotListAppendInt( lCharacters, '`' );
413 [ + + ]: 13647 : ERR_IF_PASSTHROUGH;
414 : 13643 : rc = appendNumber( lCharacters, tag );
415 [ + + ]: 13643 : ERR_IF_PASSTHROUGH;
416 : :
417 : 13639 : rc = trotListAppendInt( lCharacters, ' ' );
418 [ + + ]: 13639 : ERR_IF_PASSTHROUGH;
419 : : }
420 : :
421 : : /* CLEANUP */
422 : : cleanup:
423 : :
424 : 55893 : return rc;
425 : : }
426 : :
427 : : /******************************************************************************/
428 : : /*!
429 : : \brief Appends encoding of a textual-reference.
430 : : \param[in] lCharacters List of characters to append to.
431 : : \param[in] l List we're appending the textual-reference encoding of.
432 : : \return TROT_RC
433 : :
434 : : lCharacters will have the encoding text appended to it.
435 : : l will not be modified.
436 : : */
437 : 78890 : static TROT_RC appendAbsTwinLocation( TrotList *lCharacters, TrotList *l )
438 : : {
439 : : /* DATA */
440 : 78890 : TROT_RC rc = TROT_RC_SUCCESS;
441 : :
442 : 78890 : TrotList *lAddress = NULL;
443 : 78890 : TROT_INT address = 0;
444 : :
445 : 78890 : TROT_INT index = 0;
446 : 78890 : TROT_INT count = 0;
447 : :
448 : 78890 : TrotListActual *laParent = NULL;
449 : :
450 : :
451 : : /* PRECOND */
452 : : PARANOID_ERR_IF( lCharacters == NULL );
453 : : PARANOID_ERR_IF( l == NULL );
454 : :
455 : :
456 : : /* CODE */
457 : : /* append "@" */
458 : 78890 : rc = trotListAppendInt( lCharacters, '@' );
459 [ + + ]: 78890 : ERR_IF_PASSTHROUGH;
460 : :
461 : : /* if encodingChildNumber is -1, just need "@" */
462 [ + + ]: 78878 : if ( l->laPointsTo->encodingChildNumber == -1 )
463 : : {
464 : : /* append space */
465 : 44458 : rc = trotListAppendInt( lCharacters, ' ' );
466 [ + + ]: 44458 : ERR_IF_PASSTHROUGH;
467 : :
468 : 44450 : goto cleanup;
469 : : }
470 : :
471 : : /* create lAddress */
472 : 34420 : rc = trotListInit( &lAddress );
473 [ + + ]: 34420 : ERR_IF_PASSTHROUGH;
474 : :
475 : 34100 : laParent = l->laPointsTo;
476 [ + + ]: 68129 : while ( laParent->encodingChildNumber > 0 )
477 : : {
478 : 34109 : rc = trotListInsertInt( lAddress, 1, laParent->encodingChildNumber );
479 [ + + ]: 34109 : ERR_IF_PASSTHROUGH;
480 : :
481 : 34029 : laParent = laParent->encodingParent;
482 : : PARANOID_ERR_IF( laParent == NULL );
483 : : }
484 : :
485 : : /* get count */
486 : 34020 : rc = trotListGetCount( lAddress, &count );
487 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
488 : :
489 : : /* foreach parent */
490 : 34020 : index = 1;
491 [ + + ]: 68041 : while ( index <= count )
492 : : {
493 : : /* get parent */
494 : 34029 : rc = trotListGetInt( lAddress, index, &address );
495 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
496 : :
497 : : /* append '.' */
498 : 34029 : rc = trotListAppendInt( lCharacters, '.' );
499 [ + + ]: 34029 : ERR_IF_PASSTHROUGH;
500 : :
501 : : /* append number */
502 : 34025 : rc = appendNumber( lCharacters, address );
503 [ + + ]: 34025 : ERR_IF_PASSTHROUGH;
504 : :
505 : : /* increment */
506 : 34021 : index += 1;
507 : : }
508 : :
509 : : /* append space */
510 : 34012 : rc = trotListAppendInt( lCharacters, ' ' );
511 [ + + ]: 34012 : ERR_IF_PASSTHROUGH;
512 : :
513 : :
514 : : /* CLEANUP */
515 : : cleanup:
516 : :
517 : 78890 : trotListFree( &lAddress );
518 : :
519 : 78890 : return rc;
520 : : }
521 : :
522 : : /******************************************************************************/
523 : : /*!
524 : : \brief Appends encoding of a number.
525 : : \param[in] lCharacters List of characters to append to.
526 : : \param[in] n Number to append.
527 : : \return TROT_RC
528 : :
529 : : lCharacters will have encoding text appended to it.
530 : : */
531 : 168486 : static TROT_RC appendNumber( TrotList *lCharacters, TROT_INT n )
532 : : {
533 : : /* DATA */
534 : 168486 : TROT_RC rc = TROT_RC_SUCCESS;
535 : :
536 : : TROT_INT numberString[ TROT_INT_MIN_STRING_LENGTH + 1 ];
537 : 168486 : TROT_INT *s = NULL;
538 : :
539 : :
540 : : /* PRECOND */
541 : : PARANOID_ERR_IF( lCharacters == NULL );
542 : :
543 : :
544 : : /* CODE */
545 : : /* special case: 0 */
546 [ + + ]: 168486 : if ( n == 0 )
547 : : {
548 : 4127 : rc = trotListAppendInt( lCharacters, '0' );
549 [ + + ]: 4127 : ERR_IF_PASSTHROUGH;
550 : :
551 : 4123 : goto cleanup;
552 : : }
553 : :
554 : : /* create numberString */
555 : 164359 : s = &(numberString[ TROT_INT_MIN_STRING_LENGTH ]);
556 : 164359 : (*s) = '\0';
557 : :
558 : : /* create number string */
559 [ + + ]: 164359 : if ( n < 0 )
560 : : {
561 [ + + ]: 171 : while ( n != 0 )
562 : : {
563 : 147 : s -= 1;
564 : 147 : (*s) = '0' - ( n % 10 );
565 : :
566 : 147 : n /= 10;
567 : : }
568 : :
569 : 24 : s -= 1;
570 : 24 : (*s) = '-';
571 : : }
572 : : else
573 : : {
574 [ + + ]: 441692 : while ( n != 0 )
575 : : {
576 : 277357 : s -= 1;
577 : 277357 : (*s) = '0' + ( n % 10 );
578 : :
579 : 277357 : n /= 10;
580 : : }
581 : : }
582 : :
583 : : /* append numberString to lCharacters */
584 [ + + ]: 441799 : while ( (*s) != '\0' )
585 : : {
586 : 277492 : rc = trotListAppendInt( lCharacters, (*s) );
587 [ + + ]: 277492 : ERR_IF_PASSTHROUGH;
588 : :
589 : 277440 : s += 1;
590 : : }
591 : :
592 : :
593 : : /* CLEANUP */
594 : : cleanup:
595 : :
596 : 168486 : return rc;
597 : : }
598 : :
599 : : /******************************************************************************/
600 : : /*!
601 : : \brief Appends ints in text format
602 : : \param[in] lCharacters List of characters to append to.
603 : : \param[in] l The list we're encoding
604 : : \param[in] count Count of l
605 : : \param[in] index Current index of l
606 : : \return TROT_RC
607 : :
608 : : lCharacters will have encoding text appended to it.
609 : : index will be incremented
610 : : */
611 : 747 : static TROT_RC appendText( TrotList *lCharacters, TrotList *l, TROT_INT count, TROT_INT *index )
612 : : {
613 : : /* DATA */
614 : 747 : TROT_RC rc = TROT_RC_SUCCESS;
615 : :
616 : 747 : TROT_INT kind = 0;
617 : 747 : TROT_INT character = 0;
618 : 747 : TROT_INT state = 0;
619 : :
620 : :
621 : : /* PRECOND */
622 : : PARANOID_ERR_IF( lCharacters == NULL );
623 : : PARANOID_ERR_IF( l == NULL );
624 : : PARANOID_ERR_IF( index == NULL );
625 : :
626 : :
627 : : /* CODE */
628 : : /* go through ints, break if we hit a list */
629 [ + + ]: 17675 : while ( (*index) <= count )
630 : : {
631 : : /* get kind */
632 : 16975 : rc = trotListGetKind( l, (*index), &kind );
633 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
634 : :
635 [ + + ]: 16975 : if ( kind != TROT_KIND_INT )
636 : : {
637 : : /* go back */
638 : 3 : (*index) -= 1;
639 : :
640 : 3 : break;
641 : : }
642 : :
643 : : /* get character */
644 : 16972 : rc = trotListGetInt( l, (*index), &character );
645 : : PARANOID_ERR_IF( rc != TROT_RC_SUCCESS );
646 : :
647 : : /* is printable character? */
648 : : /* not fully unicode correct, but good enough for now */
649 : : /* FUTURE IMPROVEMENT */
650 [ + + ]: 16972 : if ( character != '\"'
651 [ + + ][ + + ]: 16966 : && ( character >= ' ' && character <= '~' )
652 : : )
653 : : {
654 [ + + ]: 11528 : if ( state == 0 )
655 : : {
656 : : /* append " */
657 : 5856 : rc = trotListAppendInt( lCharacters, '\"' );
658 [ + + ]: 5856 : ERR_IF_PASSTHROUGH;
659 : :
660 : 5852 : state = 1;
661 : : }
662 : :
663 : : /* append character */
664 : 11524 : rc = trotListAppendInt( lCharacters, character );
665 [ + + ]: 11524 : ERR_IF_PASSTHROUGH;
666 : : }
667 : : else
668 : : {
669 [ + + ]: 5444 : if ( state == 1 )
670 : : {
671 : : /* append " */
672 : 5441 : rc = trotListAppendInt( lCharacters, '\"' );
673 [ + + ]: 5441 : ERR_IF_PASSTHROUGH;
674 : :
675 : : /* append space */
676 : 5437 : rc = trotListAppendInt( lCharacters, ' ' );
677 [ + + ]: 5437 : ERR_IF_PASSTHROUGH;
678 : :
679 : 5433 : state = 0;
680 : : }
681 : :
682 : : /* append in number format */
683 : 5436 : rc = appendNumber( lCharacters, character );
684 [ + + ]: 5436 : ERR_IF_PASSTHROUGH;
685 : :
686 : : /* append space */
687 : 5420 : rc = trotListAppendInt( lCharacters, ' ' );
688 [ + + ]: 5420 : ERR_IF_PASSTHROUGH;
689 : : }
690 : :
691 : : /* increment */
692 : 16928 : (*index) += 1;
693 : : }
694 : :
695 [ + + ]: 703 : if ( state == 1 )
696 : : {
697 : : /* append " */
698 : 399 : rc = trotListAppendInt( lCharacters, '\"' );
699 [ + + ]: 399 : ERR_IF_PASSTHROUGH;
700 : :
701 : : /* append space */
702 : 395 : rc = trotListAppendInt( lCharacters, ' ' );
703 [ + + ]: 395 : ERR_IF_PASSTHROUGH;
704 : : }
705 : :
706 : :
707 : : /* CLEANUP */
708 : : cleanup:
709 : :
710 : 747 : return rc;
711 : : }
712 : :
|