1 /* do not edit automatically generated by mc from FormatStrings. */
2 /* FormatStrings.mod provides a pseudo printf capability.
4 Copyright (C) 2005-2021 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
7 This file is part of GNU Modula-2.
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)
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.
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.
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/>. */
30 # if !defined (PROC_D)
32 typedef void (*PROC_t
) (void);
33 typedef struct { PROC_t proc
; } PROC
;
44 #if defined(__cplusplus)
48 #define _FormatStrings_H
49 #define _FormatStrings_C
51 # include "GDynamicStrings.h"
52 # include "GStringConvert.h"
59 Sprintf0 - returns a String containing, s, after it has had its
60 escape sequences translated.
63 extern "C" DynamicStrings_String
FormatStrings_Sprintf0 (DynamicStrings_String fmt
);
66 Sprintf1 - returns a String containing, s, together with encapsulated
67 entity, w. It only formats the first %s or %d with n.
70 extern "C" DynamicStrings_String
FormatStrings_Sprintf1 (DynamicStrings_String fmt
, const unsigned char *w_
, unsigned int _w_high
);
73 Sprintf2 - returns a string, s, which has been formatted.
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
);
79 Sprintf3 - returns a string, s, which has been formatted.
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
);
85 Sprintf4 - returns a string, s, which has been formatted.
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
);
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.
97 extern "C" DynamicStrings_String
FormatStrings_HandleEscape (DynamicStrings_String s
);
103 static void doDSdbEnter (void);
109 static void doDSdbExit (DynamicStrings_String s
);
115 static void DSdbEnter (void);
121 static void DSdbExit (DynamicStrings_String s
);
124 IsDigit - returns TRUE if ch lies in the range: 0..9
127 static unsigned int IsDigit (char ch
);
133 static void Cast (unsigned char *a
, unsigned int _a_high
, const unsigned char *b_
, unsigned int _b_high
);
139 static unsigned int isHex (char ch
);
145 static unsigned int toHex (char ch
);
151 static unsigned int toOct (char ch
);
157 static unsigned int isOct (char ch
);
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.
165 static DynamicStrings_String
FormatString (DynamicStrings_String fmt
, int *startpos
, DynamicStrings_String in
, const unsigned char *w_
, unsigned int _w_high
);
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.
173 static DynamicStrings_String
PerformFormatString (DynamicStrings_String fmt
, int *startpos
, DynamicStrings_String in
, const unsigned char *w_
, unsigned int _w_high
);
176 Copy - copies, fmt[start:end] -> in and returns in. Providing that start >= 0.
179 static DynamicStrings_String
Copy (DynamicStrings_String fmt
, DynamicStrings_String in
, int start
, int end
);
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 %.
187 static DynamicStrings_String
HandlePercent (DynamicStrings_String fmt
, DynamicStrings_String s
, int startpos
);
194 static void doDSdbEnter (void)
196 DynamicStrings_PushAllocation ();
204 static void doDSdbExit (DynamicStrings_String s
)
206 s
= DynamicStrings_PopAllocationExemption (TRUE
, s
);
214 static void DSdbEnter (void)
223 static void DSdbExit (DynamicStrings_String s
)
229 IsDigit - returns TRUE if ch lies in the range: 0..9
232 static unsigned int IsDigit (char ch
)
234 return (ch
>= '0') && (ch
<= '9');
235 /* static analysis guarentees a RETURN statement will be used before here. */
236 __builtin_unreachable ();
244 static void Cast (unsigned char *a
, unsigned int _a_high
, const unsigned char *b_
, unsigned int _b_high
)
247 unsigned char b
[_b_high
+1];
249 /* make a local copy of each unbounded array. */
250 memcpy (b
, b_
, _b_high
+1);
252 if (_a_high
== _b_high
)
254 for (i
=0; i
<=_a_high
; i
++)
262 __builtin_unreachable ();
271 static unsigned int isHex (char ch
)
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 ();
283 static unsigned int toHex (char ch
)
285 if ((ch
>= '0') && (ch
<= '9'))
287 return ((unsigned int) (ch
))- ((unsigned int) ('0'));
289 else if ((ch
>= 'A') && (ch
<= 'F'))
291 /* avoid dangling else. */
292 return ( ((unsigned int) (ch
))- ((unsigned int) ('A')))+10;
296 /* avoid dangling else. */
297 return ( ((unsigned int) (ch
))- ((unsigned int) ('a')))+10;
299 /* static analysis guarentees a RETURN statement will be used before here. */
300 __builtin_unreachable ();
308 static unsigned int toOct (char ch
)
310 return ((unsigned int) (ch
))- ((unsigned int) ('0'));
311 /* static analysis guarentees a RETURN statement will be used before here. */
312 __builtin_unreachable ();
320 static unsigned int isOct (char ch
)
322 return (ch
>= '0') && (ch
<= '8');
323 /* static analysis guarentees a RETURN statement will be used before here. */
324 __builtin_unreachable ();
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.
334 static DynamicStrings_String
FormatString (DynamicStrings_String fmt
, int *startpos
, DynamicStrings_String in
, const unsigned char *w_
, unsigned int _w_high
)
336 DynamicStrings_String s
;
337 unsigned char w
[_w_high
+1];
339 /* make a local copy of each unbounded array. */
340 memcpy (w
, w_
, _w_high
+1);
343 if ((*startpos
) >= 0)
345 s
= PerformFormatString (fmt
, startpos
, in
, (const unsigned char *) w
, _w_high
);
349 s
= DynamicStrings_Dup (in
);
353 /* static analysis guarentees a RETURN statement will be used before here. */
354 __builtin_unreachable ();
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.
364 static DynamicStrings_String
PerformFormatString (DynamicStrings_String fmt
, int *startpos
, DynamicStrings_String in
, const unsigned char *w_
, unsigned int _w_high
)
376 DynamicStrings_String p
;
377 unsigned char w
[_w_high
+1];
379 /* make a local copy of each unbounded array. */
380 memcpy (w
, w_
, _w_high
+1);
382 while ((*startpos
) >= 0)
384 nextperc
= DynamicStrings_Index (fmt
, '%', static_cast<unsigned int> ((*startpos
)));
385 afterperc
= nextperc
;
389 if ((DynamicStrings_char (fmt
, afterperc
)) == '-')
398 ch
= DynamicStrings_char (fmt
, afterperc
);
410 width
= (width
*10)+((int ) ( ((unsigned int) (ch
))- ((unsigned int) ('0'))));
412 ch
= DynamicStrings_char (fmt
, afterperc
);
414 if ((ch
== 'c') || (ch
== 's'))
419 ch2
= static_cast<char> (w
[0]);
420 p
= DynamicStrings_ConCatChar (DynamicStrings_InitString ((const char *) "", 0), ch2
);
424 Cast ((unsigned char *) &p
, (sizeof (p
)-1), (const unsigned char *) w
, _w_high
);
425 p
= DynamicStrings_Dup (p
);
427 if ((width
> 0) && (((int ) (DynamicStrings_Length (p
))) < width
))
429 /* avoid gcc warning by using compound statement even if not strictly necessary. */
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
)))))));
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
));
441 /* include string, p, into, in. */
444 in
= DynamicStrings_ConCat (in
, DynamicStrings_Slice (fmt
, (*startpos
), nextperc
));
446 in
= DynamicStrings_ConCat (in
, p
);
447 (*startpos
) = afterperc
;
448 DSdbExit (static_cast<DynamicStrings_String
> (NULL
));
453 /* avoid dangling else. */
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
));
464 /* avoid dangling else. */
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
));
475 /* avoid dangling else. */
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
));
486 /* avoid dangling else. */
488 /* copy format string. */
491 in
= DynamicStrings_ConCat (in
, DynamicStrings_Slice (fmt
, (*startpos
), nextperc
));
493 /* and the character after the %. */
494 in
= DynamicStrings_ConCat (in
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ch
)));
496 (*startpos
) = afterperc
;
501 DSdbExit (static_cast<DynamicStrings_String
> (NULL
));
505 DSdbExit (static_cast<DynamicStrings_String
> (NULL
));
507 /* static analysis guarentees a RETURN statement will be used before here. */
508 __builtin_unreachable ();
513 Copy - copies, fmt[start:end] -> in and returns in. Providing that start >= 0.
516 static DynamicStrings_String
Copy (DynamicStrings_String fmt
, DynamicStrings_String in
, int start
, int end
)
520 /* avoid gcc warning by using compound statement even if not strictly necessary. */
523 in
= DynamicStrings_ConCat (in
, DynamicStrings_Mark (DynamicStrings_Slice (fmt
, start
, end
)));
527 /* avoid dangling else. */
528 in
= DynamicStrings_ConCat (in
, DynamicStrings_Mark (DynamicStrings_Slice (fmt
, start
, 0)));
532 /* static analysis guarentees a RETURN statement will be used before here. */
533 __builtin_unreachable ();
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 %.
543 static DynamicStrings_String
HandlePercent (DynamicStrings_String fmt
, DynamicStrings_String s
, int startpos
)
546 DynamicStrings_String result
;
548 if ((startpos
== (DynamicStrings_Length (fmt
))) || (startpos
< 0))
555 while ((startpos
>= 0) && (prevpos
< ((int ) (DynamicStrings_Length (fmt
)))))
557 startpos
= DynamicStrings_Index (fmt
, '%', static_cast<unsigned int> (startpos
));
558 if (startpos
>= prevpos
)
562 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_Slice (fmt
, prevpos
, startpos
)));
565 if ((DynamicStrings_char (fmt
, startpos
)) == '%')
567 s
= DynamicStrings_ConCatChar (s
, '%');
573 if (prevpos
< ((int ) (DynamicStrings_Length (fmt
))))
575 s
= DynamicStrings_ConCat (s
, DynamicStrings_Mark (DynamicStrings_Slice (fmt
, prevpos
, 0)));
579 /* static analysis guarentees a RETURN statement will be used before here. */
580 __builtin_unreachable ();
585 Sprintf0 - returns a String containing, s, after it has had its
586 escape sequences translated.
589 extern "C" DynamicStrings_String
FormatStrings_Sprintf0 (DynamicStrings_String fmt
)
591 DynamicStrings_String s
;
594 fmt
= FormatStrings_HandleEscape (fmt
);
595 s
= HandlePercent (fmt
, DynamicStrings_InitString ((const char *) "", 0), 0);
598 /* static analysis guarentees a RETURN statement will be used before here. */
599 __builtin_unreachable ();
604 Sprintf1 - returns a String containing, s, together with encapsulated
605 entity, w. It only formats the first %s or %d with n.
608 extern "C" DynamicStrings_String
FormatStrings_Sprintf1 (DynamicStrings_String fmt
, const unsigned char *w_
, unsigned int _w_high
)
611 DynamicStrings_String s
;
612 unsigned char w
[_w_high
+1];
614 /* make a local copy of each unbounded array. */
615 memcpy (w
, w_
, _w_high
+1);
618 fmt
= FormatStrings_HandleEscape (fmt
);
620 s
= FormatString (fmt
, &i
, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w
, _w_high
);
621 s
= HandlePercent (fmt
, s
, i
);
624 /* static analysis guarentees a RETURN statement will be used before here. */
625 __builtin_unreachable ();
630 Sprintf2 - returns a string, s, which has been formatted.
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
)
636 DynamicStrings_String s
;
637 unsigned char w1
[_w1_high
+1];
638 unsigned char w2
[_w2_high
+1];
640 /* make a local copy of each unbounded array. */
641 memcpy (w1
, w1_
, _w1_high
+1);
642 memcpy (w2
, w2_
, _w2_high
+1);
645 fmt
= FormatStrings_HandleEscape (fmt
);
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
);
652 /* static analysis guarentees a RETURN statement will be used before here. */
653 __builtin_unreachable ();
658 Sprintf3 - returns a string, s, which has been formatted.
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
)
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];
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);
675 fmt
= FormatStrings_HandleEscape (fmt
);
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
);
683 /* static analysis guarentees a RETURN statement will be used before here. */
684 __builtin_unreachable ();
689 Sprintf4 - returns a string, s, which has been formatted.
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
)
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];
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);
708 fmt
= FormatStrings_HandleEscape (fmt
);
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
);
717 /* static analysis guarentees a RETURN statement will be used before here. */
718 __builtin_unreachable ();
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.
729 extern "C" DynamicStrings_String
FormatStrings_HandleEscape (DynamicStrings_String s
)
731 DynamicStrings_String d
;
738 d
= DynamicStrings_InitString ((const char *) "", 0);
739 i
= DynamicStrings_Index (s
, '\\', 0);
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
));
748 ch
= DynamicStrings_char (s
, i
+1);
751 /* requires a bell. */
752 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_bel
)));
756 /* avoid dangling else. */
757 /* requires a backspace. */
758 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_bs
)));
762 /* avoid dangling else. */
763 /* requires a escape. */
764 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_esc
)));
768 /* avoid dangling else. */
769 /* requires a formfeed. */
770 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_ff
)));
774 /* avoid dangling else. */
775 /* requires a newline. */
776 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_nl
)));
780 /* avoid dangling else. */
781 /* requires a carriage return. */
782 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_cr
)));
786 /* avoid dangling else. */
787 /* requires a tab. */
788 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_tab
)));
792 /* avoid dangling else. */
794 if (isHex (DynamicStrings_char (s
, i
+1)))
796 b
= (unsigned char ) (toHex (DynamicStrings_char (s
, i
+1)));
798 if (isHex (DynamicStrings_char (s
, i
+1)))
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
))));
807 /* avoid dangling else. */
808 b
= (unsigned char ) (toOct (ch
));
810 if (isOct (DynamicStrings_char (s
, i
+1)))
812 b
= (unsigned char ) ((((unsigned int ) (b
))*8)+(toOct (DynamicStrings_char (s
, i
+1))));
814 if (isOct (DynamicStrings_char (s
, i
+1)))
816 b
= (unsigned char ) ((((unsigned int ) (b
))*8)+(toOct (DynamicStrings_char (s
, i
+1))));
819 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar ((char ) (b
))));
823 /* avoid dangling else. */
824 /* copy escaped character. */
825 d
= DynamicStrings_ConCat (d
, DynamicStrings_Mark (DynamicStrings_InitStringChar (ch
)));
829 i
= DynamicStrings_Index (s
, '\\', (unsigned int ) (i
));
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)));
835 /* static analysis guarentees a RETURN statement will be used before here. */
836 __builtin_unreachable ();
839 extern "C" void _M2_FormatStrings_init (__attribute__((unused
)) int argc
,__attribute__((unused
)) char *argv
[],__attribute__((unused
)) char *envp
[])
843 extern "C" void _M2_FormatStrings_finish (__attribute__((unused
)) int argc
,__attribute__((unused
)) char *argv
[],__attribute__((unused
)) char *envp
[])