]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/m2/mc-boot/GFormatStrings.c
Merge modula-2 front end onto gcc.
[thirdparty/gcc.git] / gcc / m2 / mc-boot / GFormatStrings.c
1 /* do not edit automatically generated by mc from FormatStrings. */
2 /* FormatStrings.mod provides a pseudo printf capability.
3
4 Copyright (C) 2005-2021 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6
7 This file is part of GNU Modula-2.
8
9 GNU Modula-2 is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 GNU Modula-2 is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
22
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
27
28 #include "config.h"
29 #include "system.h"
30 # if !defined (PROC_D)
31 # define PROC_D
32 typedef void (*PROC_t) (void);
33 typedef struct { PROC_t proc; } PROC;
34 # endif
35
36 # if !defined (TRUE)
37 # define TRUE (1==1)
38 # endif
39
40 # if !defined (FALSE)
41 # define FALSE (1==0)
42 # endif
43
44 #if defined(__cplusplus)
45 # undef NULL
46 # define NULL 0
47 #endif
48 #define _FormatStrings_H
49 #define _FormatStrings_C
50
51 # include "GDynamicStrings.h"
52 # include "GStringConvert.h"
53 # include "GSYSTEM.h"
54 # include "GASCII.h"
55 # include "GM2RTS.h"
56
57
58 /*
59 Sprintf0 - returns a String containing, s, after it has had its
60 escape sequences translated.
61 */
62
63 extern "C" DynamicStrings_String FormatStrings_Sprintf0 (DynamicStrings_String fmt);
64
65 /*
66 Sprintf1 - returns a String containing, s, together with encapsulated
67 entity, w. It only formats the first %s or %d with n.
68 */
69
70 extern "C" DynamicStrings_String FormatStrings_Sprintf1 (DynamicStrings_String fmt, const unsigned char *w_, unsigned int _w_high);
71
72 /*
73 Sprintf2 - returns a string, s, which has been formatted.
74 */
75
76 extern "C" DynamicStrings_String FormatStrings_Sprintf2 (DynamicStrings_String fmt, const unsigned char *w1_, unsigned int _w1_high, const unsigned char *w2_, unsigned int _w2_high);
77
78 /*
79 Sprintf3 - returns a string, s, which has been formatted.
80 */
81
82 extern "C" DynamicStrings_String FormatStrings_Sprintf3 (DynamicStrings_String fmt, const unsigned char *w1_, unsigned int _w1_high, const unsigned char *w2_, unsigned int _w2_high, const unsigned char *w3_, unsigned int _w3_high);
83
84 /*
85 Sprintf4 - returns a string, s, which has been formatted.
86 */
87
88 extern "C" DynamicStrings_String FormatStrings_Sprintf4 (DynamicStrings_String fmt, const unsigned char *w1_, unsigned int _w1_high, const unsigned char *w2_, unsigned int _w2_high, const unsigned char *w3_, unsigned int _w3_high, const unsigned char *w4_, unsigned int _w4_high);
89
90 /*
91 HandleEscape - translates \a, \b, \e, \f,
92 , \r, \x[hex] \[octal] into
93 their respective ascii codes. It also converts \[any] into
94 a single [any] character.
95 */
96
97 extern "C" DynamicStrings_String FormatStrings_HandleEscape (DynamicStrings_String s);
98
99 /*
100 doDSdbEnter -
101 */
102
103 static void doDSdbEnter (void);
104
105 /*
106 doDSdbExit -
107 */
108
109 static void doDSdbExit (DynamicStrings_String s);
110
111 /*
112 DSdbEnter -
113 */
114
115 static void DSdbEnter (void);
116
117 /*
118 DSdbExit -
119 */
120
121 static void DSdbExit (DynamicStrings_String s);
122
123 /*
124 IsDigit - returns TRUE if ch lies in the range: 0..9
125 */
126
127 static unsigned int IsDigit (char ch);
128
129 /*
130 Cast - casts a := b
131 */
132
133 static void Cast (unsigned char *a, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high);
134
135 /*
136 isHex -
137 */
138
139 static unsigned int isHex (char ch);
140
141 /*
142 toHex -
143 */
144
145 static unsigned int toHex (char ch);
146
147 /*
148 toOct -
149 */
150
151 static unsigned int toOct (char ch);
152
153 /*
154 isOct -
155 */
156
157 static unsigned int isOct (char ch);
158
159 /*
160 FormatString - returns a String containing, s, together with encapsulated
161 entity, w. It only formats the first %s or %d or %u with n.
162 A new string is returned.
163 */
164
165 static DynamicStrings_String FormatString (DynamicStrings_String fmt, int *startpos, DynamicStrings_String in, const unsigned char *w_, unsigned int _w_high);
166
167 /*
168 FormatString - returns a String containing, s, together with encapsulated
169 entity, w. It only formats the first %s or %d or %u with n.
170 A new string is returned.
171 */
172
173 static DynamicStrings_String PerformFormatString (DynamicStrings_String fmt, int *startpos, DynamicStrings_String in, const unsigned char *w_, unsigned int _w_high);
174
175 /*
176 Copy - copies, fmt[start:end] -> in and returns in. Providing that start >= 0.
177 */
178
179 static DynamicStrings_String Copy (DynamicStrings_String fmt, DynamicStrings_String in, int start, int end);
180
181 /*
182 HandlePercent - pre-condition: s, is a string.
183 Post-condition: a new string is returned which is a copy of,
184 s, except %% is transformed into %.
185 */
186
187 static DynamicStrings_String HandlePercent (DynamicStrings_String fmt, DynamicStrings_String s, int startpos);
188
189
190 /*
191 doDSdbEnter -
192 */
193
194 static void doDSdbEnter (void)
195 {
196 DynamicStrings_PushAllocation ();
197 }
198
199
200 /*
201 doDSdbExit -
202 */
203
204 static void doDSdbExit (DynamicStrings_String s)
205 {
206 s = DynamicStrings_PopAllocationExemption (TRUE, s);
207 }
208
209
210 /*
211 DSdbEnter -
212 */
213
214 static void DSdbEnter (void)
215 {
216 }
217
218
219 /*
220 DSdbExit -
221 */
222
223 static void DSdbExit (DynamicStrings_String s)
224 {
225 }
226
227
228 /*
229 IsDigit - returns TRUE if ch lies in the range: 0..9
230 */
231
232 static unsigned int IsDigit (char ch)
233 {
234 return (ch >= '0') && (ch <= '9');
235 /* static analysis guarentees a RETURN statement will be used before here. */
236 __builtin_unreachable ();
237 }
238
239
240 /*
241 Cast - casts a := b
242 */
243
244 static void Cast (unsigned char *a, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high)
245 {
246 unsigned int i;
247 unsigned char b[_b_high+1];
248
249 /* make a local copy of each unbounded array. */
250 memcpy (b, b_, _b_high+1);
251
252 if (_a_high == _b_high)
253 {
254 for (i=0; i<=_a_high; i++)
255 {
256 a[i] = b[i];
257 }
258 }
259 else
260 {
261 M2RTS_HALT (-1);
262 __builtin_unreachable ();
263 }
264 }
265
266
267 /*
268 isHex -
269 */
270
271 static unsigned int isHex (char ch)
272 {
273 return (((ch >= '0') && (ch <= '9')) || ((ch >= 'A') && (ch <= 'F'))) || ((ch >= 'a') && (ch <= 'f'));
274 /* static analysis guarentees a RETURN statement will be used before here. */
275 __builtin_unreachable ();
276 }
277
278
279 /*
280 toHex -
281 */
282
283 static unsigned int toHex (char ch)
284 {
285 if ((ch >= '0') && (ch <= '9'))
286 {
287 return ((unsigned int) (ch))- ((unsigned int) ('0'));
288 }
289 else if ((ch >= 'A') && (ch <= 'F'))
290 {
291 /* avoid dangling else. */
292 return ( ((unsigned int) (ch))- ((unsigned int) ('A')))+10;
293 }
294 else
295 {
296 /* avoid dangling else. */
297 return ( ((unsigned int) (ch))- ((unsigned int) ('a')))+10;
298 }
299 /* static analysis guarentees a RETURN statement will be used before here. */
300 __builtin_unreachable ();
301 }
302
303
304 /*
305 toOct -
306 */
307
308 static unsigned int toOct (char ch)
309 {
310 return ((unsigned int) (ch))- ((unsigned int) ('0'));
311 /* static analysis guarentees a RETURN statement will be used before here. */
312 __builtin_unreachable ();
313 }
314
315
316 /*
317 isOct -
318 */
319
320 static unsigned int isOct (char ch)
321 {
322 return (ch >= '0') && (ch <= '8');
323 /* static analysis guarentees a RETURN statement will be used before here. */
324 __builtin_unreachable ();
325 }
326
327
328 /*
329 FormatString - returns a String containing, s, together with encapsulated
330 entity, w. It only formats the first %s or %d or %u with n.
331 A new string is returned.
332 */
333
334 static DynamicStrings_String FormatString (DynamicStrings_String fmt, int *startpos, DynamicStrings_String in, const unsigned char *w_, unsigned int _w_high)
335 {
336 DynamicStrings_String s;
337 unsigned char w[_w_high+1];
338
339 /* make a local copy of each unbounded array. */
340 memcpy (w, w_, _w_high+1);
341
342 DSdbEnter ();
343 if ((*startpos) >= 0)
344 {
345 s = PerformFormatString (fmt, startpos, in, (const unsigned char *) w, _w_high);
346 }
347 else
348 {
349 s = DynamicStrings_Dup (in);
350 }
351 DSdbExit (s);
352 return s;
353 /* static analysis guarentees a RETURN statement will be used before here. */
354 __builtin_unreachable ();
355 }
356
357
358 /*
359 FormatString - returns a String containing, s, together with encapsulated
360 entity, w. It only formats the first %s or %d or %u with n.
361 A new string is returned.
362 */
363
364 static DynamicStrings_String PerformFormatString (DynamicStrings_String fmt, int *startpos, DynamicStrings_String in, const unsigned char *w_, unsigned int _w_high)
365 {
366 unsigned int left;
367 unsigned int u;
368 int c;
369 int width;
370 int nextperc;
371 int afterperc;
372 int endpos;
373 char leader;
374 char ch;
375 char ch2;
376 DynamicStrings_String p;
377 unsigned char w[_w_high+1];
378
379 /* make a local copy of each unbounded array. */
380 memcpy (w, w_, _w_high+1);
381
382 while ((*startpos) >= 0)
383 {
384 nextperc = DynamicStrings_Index (fmt, '%', static_cast<unsigned int> ((*startpos)));
385 afterperc = nextperc;
386 if (nextperc >= 0)
387 {
388 afterperc += 1;
389 if ((DynamicStrings_char (fmt, afterperc)) == '-')
390 {
391 left = TRUE;
392 afterperc += 1;
393 }
394 else
395 {
396 left = FALSE;
397 }
398 ch = DynamicStrings_char (fmt, afterperc);
399 if (ch == '0')
400 {
401 leader = '0';
402 }
403 else
404 {
405 leader = ' ';
406 }
407 width = 0;
408 while (IsDigit (ch))
409 {
410 width = (width*10)+((int ) ( ((unsigned int) (ch))- ((unsigned int) ('0'))));
411 afterperc += 1;
412 ch = DynamicStrings_char (fmt, afterperc);
413 }
414 if ((ch == 'c') || (ch == 's'))
415 {
416 afterperc += 1;
417 if (ch == 'c')
418 {
419 ch2 = static_cast<char> (w[0]);
420 p = DynamicStrings_ConCatChar (DynamicStrings_InitString ((const char *) "", 0), ch2);
421 }
422 else
423 {
424 Cast ((unsigned char *) &p, (sizeof (p)-1), (const unsigned char *) w, _w_high);
425 p = DynamicStrings_Dup (p);
426 }
427 if ((width > 0) && (((int ) (DynamicStrings_Length (p))) < width))
428 {
429 /* avoid gcc warning by using compound statement even if not strictly necessary. */
430 if (left)
431 {
432 /* place trailing spaces after, p. */
433 p = DynamicStrings_ConCat (p, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " ", 1)), static_cast<unsigned int> (width-((int ) (DynamicStrings_Length (p)))))));
434 }
435 else
436 {
437 /* padd string, p, with leading spaces. */
438 p = DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " ", 1)), static_cast<unsigned int> (width-((int ) (DynamicStrings_Length (p))))), DynamicStrings_Mark (p));
439 }
440 }
441 /* include string, p, into, in. */
442 if (nextperc > 0)
443 {
444 in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc));
445 }
446 in = DynamicStrings_ConCat (in, p);
447 (*startpos) = afterperc;
448 DSdbExit (static_cast<DynamicStrings_String> (NULL));
449 return in;
450 }
451 else if (ch == 'd')
452 {
453 /* avoid dangling else. */
454 afterperc += 1;
455 Cast ((unsigned char *) &c, (sizeof (c)-1), (const unsigned char *) w, _w_high);
456 in = Copy (fmt, in, (*startpos), nextperc);
457 in = DynamicStrings_ConCat (in, StringConvert_IntegerToString (c, static_cast<unsigned int> (width), leader, FALSE, 10, FALSE));
458 (*startpos) = afterperc;
459 DSdbExit (static_cast<DynamicStrings_String> (NULL));
460 return in;
461 }
462 else if (ch == 'x')
463 {
464 /* avoid dangling else. */
465 afterperc += 1;
466 Cast ((unsigned char *) &u, (sizeof (u)-1), (const unsigned char *) w, _w_high);
467 in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc));
468 in = DynamicStrings_ConCat (in, StringConvert_CardinalToString (u, static_cast<unsigned int> (width), leader, 16, TRUE));
469 (*startpos) = afterperc;
470 DSdbExit (static_cast<DynamicStrings_String> (NULL));
471 return in;
472 }
473 else if (ch == 'u')
474 {
475 /* avoid dangling else. */
476 afterperc += 1;
477 Cast ((unsigned char *) &u, (sizeof (u)-1), (const unsigned char *) w, _w_high);
478 in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc));
479 in = DynamicStrings_ConCat (in, StringConvert_CardinalToString (u, static_cast<unsigned int> (width), leader, 10, FALSE));
480 (*startpos) = afterperc;
481 DSdbExit (static_cast<DynamicStrings_String> (NULL));
482 return in;
483 }
484 else
485 {
486 /* avoid dangling else. */
487 afterperc += 1;
488 /* copy format string. */
489 if (nextperc > 0)
490 {
491 in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc));
492 }
493 /* and the character after the %. */
494 in = DynamicStrings_ConCat (in, DynamicStrings_Mark (DynamicStrings_InitStringChar (ch)));
495 }
496 (*startpos) = afterperc;
497 }
498 else
499 {
500 /* nothing to do. */
501 DSdbExit (static_cast<DynamicStrings_String> (NULL));
502 return in;
503 }
504 }
505 DSdbExit (static_cast<DynamicStrings_String> (NULL));
506 return in;
507 /* static analysis guarentees a RETURN statement will be used before here. */
508 __builtin_unreachable ();
509 }
510
511
512 /*
513 Copy - copies, fmt[start:end] -> in and returns in. Providing that start >= 0.
514 */
515
516 static DynamicStrings_String Copy (DynamicStrings_String fmt, DynamicStrings_String in, int start, int end)
517 {
518 if (start >= 0)
519 {
520 /* avoid gcc warning by using compound statement even if not strictly necessary. */
521 if (end > 0)
522 {
523 in = DynamicStrings_ConCat (in, DynamicStrings_Mark (DynamicStrings_Slice (fmt, start, end)));
524 }
525 else if (end < 0)
526 {
527 /* avoid dangling else. */
528 in = DynamicStrings_ConCat (in, DynamicStrings_Mark (DynamicStrings_Slice (fmt, start, 0)));
529 }
530 }
531 return in;
532 /* static analysis guarentees a RETURN statement will be used before here. */
533 __builtin_unreachable ();
534 }
535
536
537 /*
538 HandlePercent - pre-condition: s, is a string.
539 Post-condition: a new string is returned which is a copy of,
540 s, except %% is transformed into %.
541 */
542
543 static DynamicStrings_String HandlePercent (DynamicStrings_String fmt, DynamicStrings_String s, int startpos)
544 {
545 int prevpos;
546 DynamicStrings_String result;
547
548 if ((startpos == (DynamicStrings_Length (fmt))) || (startpos < 0))
549 {
550 return s;
551 }
552 else
553 {
554 prevpos = startpos;
555 while ((startpos >= 0) && (prevpos < ((int ) (DynamicStrings_Length (fmt)))))
556 {
557 startpos = DynamicStrings_Index (fmt, '%', static_cast<unsigned int> (startpos));
558 if (startpos >= prevpos)
559 {
560 if (startpos > 0)
561 {
562 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Slice (fmt, prevpos, startpos)));
563 }
564 startpos += 1;
565 if ((DynamicStrings_char (fmt, startpos)) == '%')
566 {
567 s = DynamicStrings_ConCatChar (s, '%');
568 startpos += 1;
569 }
570 prevpos = startpos;
571 }
572 }
573 if (prevpos < ((int ) (DynamicStrings_Length (fmt))))
574 {
575 s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Slice (fmt, prevpos, 0)));
576 }
577 return s;
578 }
579 /* static analysis guarentees a RETURN statement will be used before here. */
580 __builtin_unreachable ();
581 }
582
583
584 /*
585 Sprintf0 - returns a String containing, s, after it has had its
586 escape sequences translated.
587 */
588
589 extern "C" DynamicStrings_String FormatStrings_Sprintf0 (DynamicStrings_String fmt)
590 {
591 DynamicStrings_String s;
592
593 DSdbEnter ();
594 fmt = FormatStrings_HandleEscape (fmt);
595 s = HandlePercent (fmt, DynamicStrings_InitString ((const char *) "", 0), 0);
596 DSdbExit (s);
597 return s;
598 /* static analysis guarentees a RETURN statement will be used before here. */
599 __builtin_unreachable ();
600 }
601
602
603 /*
604 Sprintf1 - returns a String containing, s, together with encapsulated
605 entity, w. It only formats the first %s or %d with n.
606 */
607
608 extern "C" DynamicStrings_String FormatStrings_Sprintf1 (DynamicStrings_String fmt, const unsigned char *w_, unsigned int _w_high)
609 {
610 int i;
611 DynamicStrings_String s;
612 unsigned char w[_w_high+1];
613
614 /* make a local copy of each unbounded array. */
615 memcpy (w, w_, _w_high+1);
616
617 DSdbEnter ();
618 fmt = FormatStrings_HandleEscape (fmt);
619 i = 0;
620 s = FormatString (fmt, &i, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w, _w_high);
621 s = HandlePercent (fmt, s, i);
622 DSdbExit (s);
623 return s;
624 /* static analysis guarentees a RETURN statement will be used before here. */
625 __builtin_unreachable ();
626 }
627
628
629 /*
630 Sprintf2 - returns a string, s, which has been formatted.
631 */
632
633 extern "C" DynamicStrings_String FormatStrings_Sprintf2 (DynamicStrings_String fmt, const unsigned char *w1_, unsigned int _w1_high, const unsigned char *w2_, unsigned int _w2_high)
634 {
635 int i;
636 DynamicStrings_String s;
637 unsigned char w1[_w1_high+1];
638 unsigned char w2[_w2_high+1];
639
640 /* make a local copy of each unbounded array. */
641 memcpy (w1, w1_, _w1_high+1);
642 memcpy (w2, w2_, _w2_high+1);
643
644 DSdbEnter ();
645 fmt = FormatStrings_HandleEscape (fmt);
646 i = 0;
647 s = FormatString (fmt, &i, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w1, _w1_high);
648 s = FormatString (fmt, &i, s, (const unsigned char *) w2, _w2_high);
649 s = HandlePercent (fmt, s, i);
650 DSdbExit (s);
651 return s;
652 /* static analysis guarentees a RETURN statement will be used before here. */
653 __builtin_unreachable ();
654 }
655
656
657 /*
658 Sprintf3 - returns a string, s, which has been formatted.
659 */
660
661 extern "C" DynamicStrings_String FormatStrings_Sprintf3 (DynamicStrings_String fmt, const unsigned char *w1_, unsigned int _w1_high, const unsigned char *w2_, unsigned int _w2_high, const unsigned char *w3_, unsigned int _w3_high)
662 {
663 int i;
664 DynamicStrings_String s;
665 unsigned char w1[_w1_high+1];
666 unsigned char w2[_w2_high+1];
667 unsigned char w3[_w3_high+1];
668
669 /* make a local copy of each unbounded array. */
670 memcpy (w1, w1_, _w1_high+1);
671 memcpy (w2, w2_, _w2_high+1);
672 memcpy (w3, w3_, _w3_high+1);
673
674 DSdbEnter ();
675 fmt = FormatStrings_HandleEscape (fmt);
676 i = 0;
677 s = FormatString (fmt, &i, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w1, _w1_high);
678 s = FormatString (fmt, &i, s, (const unsigned char *) w2, _w2_high);
679 s = FormatString (fmt, &i, s, (const unsigned char *) w3, _w3_high);
680 s = HandlePercent (fmt, s, i);
681 DSdbExit (s);
682 return s;
683 /* static analysis guarentees a RETURN statement will be used before here. */
684 __builtin_unreachable ();
685 }
686
687
688 /*
689 Sprintf4 - returns a string, s, which has been formatted.
690 */
691
692 extern "C" DynamicStrings_String FormatStrings_Sprintf4 (DynamicStrings_String fmt, const unsigned char *w1_, unsigned int _w1_high, const unsigned char *w2_, unsigned int _w2_high, const unsigned char *w3_, unsigned int _w3_high, const unsigned char *w4_, unsigned int _w4_high)
693 {
694 int i;
695 DynamicStrings_String s;
696 unsigned char w1[_w1_high+1];
697 unsigned char w2[_w2_high+1];
698 unsigned char w3[_w3_high+1];
699 unsigned char w4[_w4_high+1];
700
701 /* make a local copy of each unbounded array. */
702 memcpy (w1, w1_, _w1_high+1);
703 memcpy (w2, w2_, _w2_high+1);
704 memcpy (w3, w3_, _w3_high+1);
705 memcpy (w4, w4_, _w4_high+1);
706
707 DSdbEnter ();
708 fmt = FormatStrings_HandleEscape (fmt);
709 i = 0;
710 s = FormatString (fmt, &i, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w1, _w1_high);
711 s = FormatString (fmt, &i, s, (const unsigned char *) w2, _w2_high);
712 s = FormatString (fmt, &i, s, (const unsigned char *) w3, _w3_high);
713 s = FormatString (fmt, &i, s, (const unsigned char *) w4, _w4_high);
714 s = HandlePercent (fmt, s, i);
715 DSdbExit (s);
716 return s;
717 /* static analysis guarentees a RETURN statement will be used before here. */
718 __builtin_unreachable ();
719 }
720
721
722 /*
723 HandleEscape - translates \a, \b, \e, \f,
724 , \r, \x[hex] \[octal] into
725 their respective ascii codes. It also converts \[any] into
726 a single [any] character.
727 */
728
729 extern "C" DynamicStrings_String FormatStrings_HandleEscape (DynamicStrings_String s)
730 {
731 DynamicStrings_String d;
732 int i;
733 int j;
734 char ch;
735 unsigned char b;
736
737 DSdbEnter ();
738 d = DynamicStrings_InitString ((const char *) "", 0);
739 i = DynamicStrings_Index (s, '\\', 0);
740 j = 0;
741 while (i >= 0)
742 {
743 if (i > 0)
744 {
745 /* initially i might be zero which means the end of the string, which is not what we want. */
746 d = DynamicStrings_ConCat (d, DynamicStrings_Slice (s, j, i));
747 }
748 ch = DynamicStrings_char (s, i+1);
749 if (ch == 'a')
750 {
751 /* requires a bell. */
752 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_bel)));
753 }
754 else if (ch == 'b')
755 {
756 /* avoid dangling else. */
757 /* requires a backspace. */
758 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_bs)));
759 }
760 else if (ch == 'e')
761 {
762 /* avoid dangling else. */
763 /* requires a escape. */
764 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_esc)));
765 }
766 else if (ch == 'f')
767 {
768 /* avoid dangling else. */
769 /* requires a formfeed. */
770 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_ff)));
771 }
772 else if (ch == 'n')
773 {
774 /* avoid dangling else. */
775 /* requires a newline. */
776 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_nl)));
777 }
778 else if (ch == 'r')
779 {
780 /* avoid dangling else. */
781 /* requires a carriage return. */
782 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_cr)));
783 }
784 else if (ch == 't')
785 {
786 /* avoid dangling else. */
787 /* requires a tab. */
788 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_tab)));
789 }
790 else if (ch == 'x')
791 {
792 /* avoid dangling else. */
793 i += 1;
794 if (isHex (DynamicStrings_char (s, i+1)))
795 {
796 b = (unsigned char ) (toHex (DynamicStrings_char (s, i+1)));
797 i += 1;
798 if (isHex (DynamicStrings_char (s, i+1)))
799 {
800 b = (unsigned char ) ((((unsigned int ) (b))*0x010)+(toHex (DynamicStrings_char (s, i+1))));
801 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar ((char ) (b))));
802 }
803 }
804 }
805 else if (isOct (ch))
806 {
807 /* avoid dangling else. */
808 b = (unsigned char ) (toOct (ch));
809 i += 1;
810 if (isOct (DynamicStrings_char (s, i+1)))
811 {
812 b = (unsigned char ) ((((unsigned int ) (b))*8)+(toOct (DynamicStrings_char (s, i+1))));
813 i += 1;
814 if (isOct (DynamicStrings_char (s, i+1)))
815 {
816 b = (unsigned char ) ((((unsigned int ) (b))*8)+(toOct (DynamicStrings_char (s, i+1))));
817 }
818 }
819 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar ((char ) (b))));
820 }
821 else
822 {
823 /* avoid dangling else. */
824 /* copy escaped character. */
825 d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ch)));
826 }
827 i += 2;
828 j = i;
829 i = DynamicStrings_Index (s, '\\', (unsigned int ) (i));
830 }
831 /* s := Assign(s, Mark(ConCat(d, Mark(Slice(s, j, 0))))) ; dont Mark(s) in the Slice as we Assign contents */
832 s = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), j, 0)));
833 DSdbExit (s);
834 return s;
835 /* static analysis guarentees a RETURN statement will be used before here. */
836 __builtin_unreachable ();
837 }
838
839 extern "C" void _M2_FormatStrings_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
840 {
841 }
842
843 extern "C" void _M2_FormatStrings_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
844 {
845 }