/* do not edit automatically generated by mc from FormatStrings. */ /* FormatStrings.mod provides a pseudo printf capability. Copyright (C) 2005-2023 Free Software Foundation, Inc. Contributed by Gaius Mulley . This file is part of GNU Modula-2. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Under Section 7 of GPL version 3, you are granted additional permissions described in the GCC Runtime Library Exception, version 3.1, as published by the Free Software Foundation. You should have received a copy of the GNU General Public License and a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ #include "config.h" #include "system.h" #include # if !defined (PROC_D) # define PROC_D typedef void (*PROC_t) (void); typedef struct { PROC_t proc; } PROC; # endif # if !defined (TRUE) # define TRUE (1==1) # endif # if !defined (FALSE) # define FALSE (1==0) # endif #if defined(__cplusplus) # undef NULL # define NULL 0 #endif #define _FormatStrings_H #define _FormatStrings_C # include "GDynamicStrings.h" # include "GStringConvert.h" # include "GSYSTEM.h" # include "GASCII.h" # include "GM2RTS.h" /* Sprintf0 - returns a String containing, s, after it has had its escape sequences translated. */ extern "C" DynamicStrings_String FormatStrings_Sprintf0 (DynamicStrings_String fmt); /* Sprintf1 - returns a String containing, s, together with encapsulated entity, w. It only formats the first %s or %d with n. */ extern "C" DynamicStrings_String FormatStrings_Sprintf1 (DynamicStrings_String fmt, const unsigned char *w_, unsigned int _w_high); /* Sprintf2 - returns a string, s, which has been formatted. */ 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); /* Sprintf3 - returns a string, s, which has been formatted. */ 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); /* Sprintf4 - returns a string, s, which has been formatted. */ 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); /* HandleEscape - translates \a, \b, \e, \f, , \r, \x[hex] \[octal] into their respective ascii codes. It also converts \[any] into a single [any] character. */ extern "C" DynamicStrings_String FormatStrings_HandleEscape (DynamicStrings_String s); /* doDSdbEnter - */ static void doDSdbEnter (void); /* doDSdbExit - */ static void doDSdbExit (DynamicStrings_String s); /* DSdbEnter - */ static void DSdbEnter (void); /* DSdbExit - */ static void DSdbExit (DynamicStrings_String s); /* IsDigit - returns TRUE if ch lies in the range: 0..9 */ static bool IsDigit (char ch); /* Cast - casts a := b */ static void Cast (unsigned char *a, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high); /* isHex - */ static bool isHex (char ch); /* toHex - */ static unsigned int toHex (char ch); /* toOct - */ static unsigned int toOct (char ch); /* isOct - */ static bool isOct (char ch); /* FormatString - returns a String containing, s, together with encapsulated entity, w. It only formats the first %s or %d or %u with n. A new string is returned. */ static DynamicStrings_String FormatString (DynamicStrings_String fmt, int *startpos, DynamicStrings_String in, const unsigned char *w_, unsigned int _w_high); /* FormatString - returns a String containing, s, together with encapsulated entity, w. It only formats the first %s or %d or %u with n. A new string is returned. */ static DynamicStrings_String PerformFormatString (DynamicStrings_String fmt, int *startpos, DynamicStrings_String in, const unsigned char *w_, unsigned int _w_high); /* Copy - copies, fmt[start:end] -> in and returns in. Providing that start >= 0. */ static DynamicStrings_String Copy (DynamicStrings_String fmt, DynamicStrings_String in, int start, int end); /* HandlePercent - pre-condition: s, is a string. Post-condition: a new string is returned which is a copy of, s, except %% is transformed into %. */ static DynamicStrings_String HandlePercent (DynamicStrings_String fmt, DynamicStrings_String s, int startpos); /* doDSdbEnter - */ static void doDSdbEnter (void) { DynamicStrings_PushAllocation (); } /* doDSdbExit - */ static void doDSdbExit (DynamicStrings_String s) { s = DynamicStrings_PopAllocationExemption (true, s); } /* DSdbEnter - */ static void DSdbEnter (void) { } /* DSdbExit - */ static void DSdbExit (DynamicStrings_String s) { } /* IsDigit - returns TRUE if ch lies in the range: 0..9 */ static bool IsDigit (char ch) { return (ch >= '0') && (ch <= '9'); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Cast - casts a := b */ static void Cast (unsigned char *a, unsigned int _a_high, const unsigned char *b_, unsigned int _b_high) { unsigned int i; unsigned char b[_b_high+1]; /* make a local copy of each unbounded array. */ memcpy (b, b_, _b_high+1); if (_a_high == _b_high) { for (i=0; i<=_a_high; i++) { a[i] = b[i]; } } else { M2RTS_HALT (-1); __builtin_unreachable (); } } /* isHex - */ static bool isHex (char ch) { return (((ch >= '0') && (ch <= '9')) || ((ch >= 'A') && (ch <= 'F'))) || ((ch >= 'a') && (ch <= 'f')); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* toHex - */ static unsigned int toHex (char ch) { if ((ch >= '0') && (ch <= '9')) { return ((unsigned int) (ch))- ((unsigned int) ('0')); } else if ((ch >= 'A') && (ch <= 'F')) { /* avoid dangling else. */ return ( ((unsigned int) (ch))- ((unsigned int) ('A')))+10; } else { /* avoid dangling else. */ return ( ((unsigned int) (ch))- ((unsigned int) ('a')))+10; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* toOct - */ static unsigned int toOct (char ch) { return ((unsigned int) (ch))- ((unsigned int) ('0')); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* isOct - */ static bool isOct (char ch) { return (ch >= '0') && (ch <= '8'); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* FormatString - returns a String containing, s, together with encapsulated entity, w. It only formats the first %s or %d or %u with n. A new string is returned. */ static DynamicStrings_String FormatString (DynamicStrings_String fmt, int *startpos, DynamicStrings_String in, const unsigned char *w_, unsigned int _w_high) { DynamicStrings_String s; unsigned char w[_w_high+1]; /* make a local copy of each unbounded array. */ memcpy (w, w_, _w_high+1); DSdbEnter (); if ((*startpos) >= 0) { s = PerformFormatString (fmt, startpos, in, (const unsigned char *) w, _w_high); } else { s = DynamicStrings_Dup (in); } DSdbExit (s); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* FormatString - returns a String containing, s, together with encapsulated entity, w. It only formats the first %s or %d or %u with n. A new string is returned. */ static DynamicStrings_String PerformFormatString (DynamicStrings_String fmt, int *startpos, DynamicStrings_String in, const unsigned char *w_, unsigned int _w_high) { bool left; unsigned int u; int c; int width; int nextperc; int afterperc; char leader; char ch; char ch2; DynamicStrings_String p; unsigned char w[_w_high+1]; /* make a local copy of each unbounded array. */ memcpy (w, w_, _w_high+1); while ((*startpos) >= 0) { nextperc = DynamicStrings_Index (fmt, '%', static_cast ((*startpos))); afterperc = nextperc; if (nextperc >= 0) { afterperc += 1; if ((DynamicStrings_char (fmt, afterperc)) == '-') { left = true; afterperc += 1; } else { left = false; } ch = DynamicStrings_char (fmt, afterperc); if (ch == '0') { leader = '0'; } else { leader = ' '; } width = 0; while (IsDigit (ch)) { width = (width*10)+((int ) ( ((unsigned int) (ch))- ((unsigned int) ('0')))); afterperc += 1; ch = DynamicStrings_char (fmt, afterperc); } if ((ch == 'c') || (ch == 's')) { afterperc += 1; if (ch == 'c') { ch2 = static_cast (w[0]); p = DynamicStrings_ConCatChar (DynamicStrings_InitString ((const char *) "", 0), ch2); } else { Cast ((unsigned char *) &p, (sizeof (p)-1), (const unsigned char *) w, _w_high); p = DynamicStrings_Dup (p); } if ((width > 0) && (((int ) (DynamicStrings_Length (p))) < width)) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (left) { /* place trailing spaces after, p. */ p = DynamicStrings_ConCat (p, DynamicStrings_Mark (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " ", 1)), static_cast (width-((int ) (DynamicStrings_Length (p))))))); } else { /* padd string, p, with leading spaces. */ p = DynamicStrings_ConCat (DynamicStrings_Mult (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " ", 1)), static_cast (width-((int ) (DynamicStrings_Length (p))))), DynamicStrings_Mark (p)); } } /* include string, p, into, in. */ if (nextperc > 0) { in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc)); } in = DynamicStrings_ConCat (in, p); (*startpos) = afterperc; DSdbExit (static_cast (NULL)); return in; } else if (ch == 'd') { /* avoid dangling else. */ afterperc += 1; Cast ((unsigned char *) &c, (sizeof (c)-1), (const unsigned char *) w, _w_high); in = Copy (fmt, in, (*startpos), nextperc); in = DynamicStrings_ConCat (in, StringConvert_IntegerToString (c, static_cast (width), leader, false, 10, false)); (*startpos) = afterperc; DSdbExit (static_cast (NULL)); return in; } else if (ch == 'x') { /* avoid dangling else. */ afterperc += 1; Cast ((unsigned char *) &u, (sizeof (u)-1), (const unsigned char *) w, _w_high); in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc)); in = DynamicStrings_ConCat (in, StringConvert_CardinalToString (u, static_cast (width), leader, 16, true)); (*startpos) = afterperc; DSdbExit (static_cast (NULL)); return in; } else if (ch == 'u') { /* avoid dangling else. */ afterperc += 1; Cast ((unsigned char *) &u, (sizeof (u)-1), (const unsigned char *) w, _w_high); in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc)); in = DynamicStrings_ConCat (in, StringConvert_CardinalToString (u, static_cast (width), leader, 10, false)); (*startpos) = afterperc; DSdbExit (static_cast (NULL)); return in; } else { /* avoid dangling else. */ afterperc += 1; /* copy format string. */ if (nextperc > 0) { in = DynamicStrings_ConCat (in, DynamicStrings_Slice (fmt, (*startpos), nextperc)); } /* and the character after the %. */ in = DynamicStrings_ConCat (in, DynamicStrings_Mark (DynamicStrings_InitStringChar (ch))); } (*startpos) = afterperc; } else { /* nothing to do. */ DSdbExit (static_cast (NULL)); return in; } } DSdbExit (static_cast (NULL)); return in; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Copy - copies, fmt[start:end] -> in and returns in. Providing that start >= 0. */ static DynamicStrings_String Copy (DynamicStrings_String fmt, DynamicStrings_String in, int start, int end) { if (start >= 0) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (end > 0) { in = DynamicStrings_ConCat (in, DynamicStrings_Mark (DynamicStrings_Slice (fmt, start, end))); } else if (end < 0) { /* avoid dangling else. */ in = DynamicStrings_ConCat (in, DynamicStrings_Mark (DynamicStrings_Slice (fmt, start, 0))); } } return in; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* HandlePercent - pre-condition: s, is a string. Post-condition: a new string is returned which is a copy of, s, except %% is transformed into %. */ static DynamicStrings_String HandlePercent (DynamicStrings_String fmt, DynamicStrings_String s, int startpos) { int prevpos; if ((startpos == ((int ) (DynamicStrings_Length (fmt)))) || (startpos < 0)) { return s; } else { prevpos = startpos; while ((startpos >= 0) && (prevpos < ((int ) (DynamicStrings_Length (fmt))))) { startpos = DynamicStrings_Index (fmt, '%', static_cast (startpos)); if (startpos >= prevpos) { if (startpos > 0) { s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Slice (fmt, prevpos, startpos))); } startpos += 1; if ((DynamicStrings_char (fmt, startpos)) == '%') { s = DynamicStrings_ConCatChar (s, '%'); startpos += 1; } prevpos = startpos; } } if (prevpos < ((int ) (DynamicStrings_Length (fmt)))) { s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_Slice (fmt, prevpos, 0))); } return s; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Sprintf0 - returns a String containing, s, after it has had its escape sequences translated. */ extern "C" DynamicStrings_String FormatStrings_Sprintf0 (DynamicStrings_String fmt) { DynamicStrings_String s; DSdbEnter (); fmt = FormatStrings_HandleEscape (fmt); s = HandlePercent (fmt, DynamicStrings_InitString ((const char *) "", 0), 0); DSdbExit (s); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Sprintf1 - returns a String containing, s, together with encapsulated entity, w. It only formats the first %s or %d with n. */ extern "C" DynamicStrings_String FormatStrings_Sprintf1 (DynamicStrings_String fmt, const unsigned char *w_, unsigned int _w_high) { int i; DynamicStrings_String s; unsigned char w[_w_high+1]; /* make a local copy of each unbounded array. */ memcpy (w, w_, _w_high+1); DSdbEnter (); fmt = FormatStrings_HandleEscape (fmt); i = 0; s = FormatString (fmt, &i, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w, _w_high); s = HandlePercent (fmt, s, i); DSdbExit (s); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Sprintf2 - returns a string, s, which has been formatted. */ 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) { int i; DynamicStrings_String s; unsigned char w1[_w1_high+1]; unsigned char w2[_w2_high+1]; /* make a local copy of each unbounded array. */ memcpy (w1, w1_, _w1_high+1); memcpy (w2, w2_, _w2_high+1); DSdbEnter (); fmt = FormatStrings_HandleEscape (fmt); i = 0; s = FormatString (fmt, &i, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w1, _w1_high); s = FormatString (fmt, &i, s, (const unsigned char *) w2, _w2_high); s = HandlePercent (fmt, s, i); DSdbExit (s); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Sprintf3 - returns a string, s, which has been formatted. */ 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) { int i; DynamicStrings_String s; unsigned char w1[_w1_high+1]; unsigned char w2[_w2_high+1]; unsigned char w3[_w3_high+1]; /* make a local copy of each unbounded array. */ memcpy (w1, w1_, _w1_high+1); memcpy (w2, w2_, _w2_high+1); memcpy (w3, w3_, _w3_high+1); DSdbEnter (); fmt = FormatStrings_HandleEscape (fmt); i = 0; s = FormatString (fmt, &i, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w1, _w1_high); s = FormatString (fmt, &i, s, (const unsigned char *) w2, _w2_high); s = FormatString (fmt, &i, s, (const unsigned char *) w3, _w3_high); s = HandlePercent (fmt, s, i); DSdbExit (s); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Sprintf4 - returns a string, s, which has been formatted. */ 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) { int i; DynamicStrings_String s; unsigned char w1[_w1_high+1]; unsigned char w2[_w2_high+1]; unsigned char w3[_w3_high+1]; unsigned char w4[_w4_high+1]; /* make a local copy of each unbounded array. */ memcpy (w1, w1_, _w1_high+1); memcpy (w2, w2_, _w2_high+1); memcpy (w3, w3_, _w3_high+1); memcpy (w4, w4_, _w4_high+1); DSdbEnter (); fmt = FormatStrings_HandleEscape (fmt); i = 0; s = FormatString (fmt, &i, DynamicStrings_InitString ((const char *) "", 0), (const unsigned char *) w1, _w1_high); s = FormatString (fmt, &i, s, (const unsigned char *) w2, _w2_high); s = FormatString (fmt, &i, s, (const unsigned char *) w3, _w3_high); s = FormatString (fmt, &i, s, (const unsigned char *) w4, _w4_high); s = HandlePercent (fmt, s, i); DSdbExit (s); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* HandleEscape - translates \a, \b, \e, \f, , \r, \x[hex] \[octal] into their respective ascii codes. It also converts \[any] into a single [any] character. */ extern "C" DynamicStrings_String FormatStrings_HandleEscape (DynamicStrings_String s) { DynamicStrings_String d; int i; int j; char ch; unsigned char b; DSdbEnter (); d = DynamicStrings_InitString ((const char *) "", 0); i = DynamicStrings_Index (s, '\\', 0); j = 0; while (i >= 0) { if (i > 0) { /* initially i might be zero which means the end of the string, which is not what we want. */ d = DynamicStrings_ConCat (d, DynamicStrings_Slice (s, j, i)); } ch = DynamicStrings_char (s, i+1); if (ch == 'a') { /* requires a bell. */ d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_bel))); } else if (ch == 'b') { /* avoid dangling else. */ /* requires a backspace. */ d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_bs))); } else if (ch == 'e') { /* avoid dangling else. */ /* requires a escape. */ d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_esc))); } else if (ch == 'f') { /* avoid dangling else. */ /* requires a formfeed. */ d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_ff))); } else if (ch == 'n') { /* avoid dangling else. */ /* requires a newline. */ d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_nl))); } else if (ch == 'r') { /* avoid dangling else. */ /* requires a carriage return. */ d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_cr))); } else if (ch == 't') { /* avoid dangling else. */ /* requires a tab. */ d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ASCII_tab))); } else if (ch == 'x') { /* avoid dangling else. */ i += 1; if (isHex (DynamicStrings_char (s, i+1))) { b = (unsigned char ) (toHex (DynamicStrings_char (s, i+1))); i += 1; if (isHex (DynamicStrings_char (s, i+1))) { b = (unsigned char ) ((((unsigned int ) (b))*0x010)+(toHex (DynamicStrings_char (s, i+1)))); d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar ((char ) (b)))); } } } else if (isOct (ch)) { /* avoid dangling else. */ b = (unsigned char ) (toOct (ch)); i += 1; if (isOct (DynamicStrings_char (s, i+1))) { b = (unsigned char ) ((((unsigned int ) (b))*8)+(toOct (DynamicStrings_char (s, i+1)))); i += 1; if (isOct (DynamicStrings_char (s, i+1))) { b = (unsigned char ) ((((unsigned int ) (b))*8)+(toOct (DynamicStrings_char (s, i+1)))); } } d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar ((char ) (b)))); } else { /* avoid dangling else. */ /* copy escaped character. */ d = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_InitStringChar (ch))); } i += 2; j = i; i = DynamicStrings_Index (s, '\\', (unsigned int ) (i)); } /* s := Assign(s, Mark(ConCat(d, Mark(Slice(s, j, 0))))) ; dont Mark(s) in the Slice as we Assign contents */ s = DynamicStrings_ConCat (d, DynamicStrings_Mark (DynamicStrings_Slice (DynamicStrings_Mark (s), j, 0))); DSdbExit (s); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } extern "C" void _M2_FormatStrings_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { } extern "C" void _M2_FormatStrings_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { }