/* do not edit automatically generated by mc from DynamicStrings. */ /* DynamicStrings.mod provides a dynamic string type and procedures. Copyright (C) 2001-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 # 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 #include #include #include #include # include "GStorage.h" #include #if defined(__cplusplus) # undef NULL # define NULL 0 #endif #define _DynamicStrings_H #define _DynamicStrings_C # include "Glibc.h" # include "GStrLib.h" # include "GStorage.h" # include "GAssertion.h" # include "GSYSTEM.h" # include "GASCII.h" # include "GM2RTS.h" # define MaxBuf 127 # define PoisonOn false # define DebugOn false # define CheckOn false # define TraceOn false typedef struct DynamicStrings_Contents_r DynamicStrings_Contents; typedef struct DynamicStrings_DebugInfo_r DynamicStrings_DebugInfo; typedef struct DynamicStrings_stringRecord_r DynamicStrings_stringRecord; typedef struct DynamicStrings_descriptor_r DynamicStrings_descriptor; typedef DynamicStrings_descriptor *DynamicStrings_Descriptor; typedef struct DynamicStrings_frameRec_r DynamicStrings_frameRec; typedef DynamicStrings_frameRec *DynamicStrings_frame; typedef struct DynamicStrings__T3_a DynamicStrings__T3; typedef enum {DynamicStrings_inuse, DynamicStrings_marked, DynamicStrings_onlist, DynamicStrings_poisoned} DynamicStrings_desState; typedef DynamicStrings_stringRecord *DynamicStrings_String; struct DynamicStrings_DebugInfo_r { DynamicStrings_String next; void *file; unsigned int line; void *proc; }; struct DynamicStrings_descriptor_r { bool charStarUsed; void *charStar; unsigned int charStarSize; bool charStarValid; DynamicStrings_desState state; DynamicStrings_String garbage; }; struct DynamicStrings_frameRec_r { DynamicStrings_String alloc; DynamicStrings_String dealloc; DynamicStrings_frame next; }; struct DynamicStrings__T3_a { char array[(MaxBuf-1)+1]; }; struct DynamicStrings_Contents_r { DynamicStrings__T3 buf; unsigned int len; DynamicStrings_String next; }; struct DynamicStrings_stringRecord_r { DynamicStrings_Contents contents; DynamicStrings_Descriptor head; DynamicStrings_DebugInfo debug; }; static bool Initialized; static DynamicStrings_frame frameHead; static DynamicStrings_String captured; /* InitString - creates and returns a String type object. Initial contents are, a. */ extern "C" DynamicStrings_String DynamicStrings_InitString (const char *a_, unsigned int _a_high); /* KillString - frees String, s, and its contents. NIL is returned. */ extern "C" DynamicStrings_String DynamicStrings_KillString (DynamicStrings_String s); /* Fin - finishes with a string, it calls KillString with, s. The purpose of the procedure is to provide a short cut to calling KillString and then testing the return result. */ extern "C" void DynamicStrings_Fin (DynamicStrings_String s); /* InitStringCharStar - initializes and returns a String to contain the C string. */ extern "C" DynamicStrings_String DynamicStrings_InitStringCharStar (void * a); /* InitStringChar - initializes and returns a String to contain the single character, ch. */ extern "C" DynamicStrings_String DynamicStrings_InitStringChar (char ch); /* Mark - marks String, s, ready for garbage collection. */ extern "C" DynamicStrings_String DynamicStrings_Mark (DynamicStrings_String s); /* Length - returns the length of the String, s. */ extern "C" unsigned int DynamicStrings_Length (DynamicStrings_String s); /* ConCat - returns String, a, after the contents of, b, have been appended. */ extern "C" DynamicStrings_String DynamicStrings_ConCat (DynamicStrings_String a, DynamicStrings_String b); /* ConCatChar - returns String, a, after character, ch, has been appended. */ extern "C" DynamicStrings_String DynamicStrings_ConCatChar (DynamicStrings_String a, char ch); /* Assign - assigns the contents of, b, into, a. String, a, is returned. */ extern "C" DynamicStrings_String DynamicStrings_Assign (DynamicStrings_String a, DynamicStrings_String b); /* Dup - duplicate a String, s, returning the copy of s. */ extern "C" DynamicStrings_String DynamicStrings_Dup (DynamicStrings_String s); /* Add - returns a new String which contains the contents of a and b. */ extern "C" DynamicStrings_String DynamicStrings_Add (DynamicStrings_String a, DynamicStrings_String b); /* Equal - returns TRUE if String, a, and, b, are equal. */ extern "C" bool DynamicStrings_Equal (DynamicStrings_String a, DynamicStrings_String b); /* EqualCharStar - returns TRUE if contents of String, s, is the same as the string, a. */ extern "C" bool DynamicStrings_EqualCharStar (DynamicStrings_String s, void * a); /* EqualArray - returns TRUE if contents of String, s, is the same as the string, a. */ extern "C" bool DynamicStrings_EqualArray (DynamicStrings_String s, const char *a_, unsigned int _a_high); /* Mult - returns a new string which is n concatenations of String, s. */ extern "C" DynamicStrings_String DynamicStrings_Mult (DynamicStrings_String s, unsigned int n); /* Slice - returns a new string which contains the elements low..high-1 strings start at element 0 Slice(s, 0, 2) will return elements 0, 1 but not 2 Slice(s, 1, 3) will return elements 1, 2 but not 3 Slice(s, 2, 0) will return elements 2..max Slice(s, 3, -1) will return elements 3..max-1 Slice(s, 4, -2) will return elements 4..max-2 */ extern "C" DynamicStrings_String DynamicStrings_Slice (DynamicStrings_String s, int low, int high); /* Index - returns the indice of the first occurance of, ch, in String, s. -1 is returned if, ch, does not exist. The search starts at position, o. */ extern "C" int DynamicStrings_Index (DynamicStrings_String s, char ch, unsigned int o); /* RIndex - returns the indice of the last occurance of, ch, in String, s. The search starts at position, o. -1 is returned if, ch, is not found. */ extern "C" int DynamicStrings_RIndex (DynamicStrings_String s, char ch, unsigned int o); /* RemoveComment - assuming that, comment, is a comment delimiter which indicates anything to its right is a comment then strip off the comment and also any white space on the remaining right hand side. It leaves any white space on the left hand side alone. */ extern "C" DynamicStrings_String DynamicStrings_RemoveComment (DynamicStrings_String s, char comment); /* RemoveWhitePrefix - removes any leading white space from String, s. A new string is returned. */ extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePrefix (DynamicStrings_String s); /* RemoveWhitePostfix - removes any leading white space from String, s. A new string is returned. */ extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePostfix (DynamicStrings_String s); /* ToUpper - returns string, s, after it has had its lower case characters replaced by upper case characters. The string, s, is not duplicated. */ extern "C" DynamicStrings_String DynamicStrings_ToUpper (DynamicStrings_String s); /* ToLower - returns string, s, after it has had its upper case characters replaced by lower case characters. The string, s, is not duplicated. */ extern "C" DynamicStrings_String DynamicStrings_ToLower (DynamicStrings_String s); /* CopyOut - copies string, s, to a. */ extern "C" void DynamicStrings_CopyOut (char *a, unsigned int _a_high, DynamicStrings_String s); /* char - returns the character, ch, at position, i, in String, s. */ extern "C" char DynamicStrings_char (DynamicStrings_String s, int i); /* string - returns the C style char * of String, s. */ extern "C" void * DynamicStrings_string (DynamicStrings_String s); /* InitStringDB - the debug version of InitString. */ extern "C" DynamicStrings_String DynamicStrings_InitStringDB (const char *a_, unsigned int _a_high, const char *file_, unsigned int _file_high, unsigned int line); /* InitStringCharStarDB - the debug version of InitStringCharStar. */ extern "C" DynamicStrings_String DynamicStrings_InitStringCharStarDB (void * a, const char *file_, unsigned int _file_high, unsigned int line); /* InitStringCharDB - the debug version of InitStringChar. */ extern "C" DynamicStrings_String DynamicStrings_InitStringCharDB (char ch, const char *file_, unsigned int _file_high, unsigned int line); /* MultDB - the debug version of MultDB. */ extern "C" DynamicStrings_String DynamicStrings_MultDB (DynamicStrings_String s, unsigned int n, const char *file_, unsigned int _file_high, unsigned int line); /* DupDB - the debug version of Dup. */ extern "C" DynamicStrings_String DynamicStrings_DupDB (DynamicStrings_String s, const char *file_, unsigned int _file_high, unsigned int line); /* SliceDB - debug version of Slice. */ extern "C" DynamicStrings_String DynamicStrings_SliceDB (DynamicStrings_String s, int low, int high, const char *file_, unsigned int _file_high, unsigned int line); /* PushAllocation - pushes the current allocation/deallocation lists. */ extern "C" void DynamicStrings_PushAllocation (void); /* PopAllocation - test to see that all strings are deallocated since the last push. Then it pops to the previous allocation/deallocation lists. If halt is true then the application terminates with an exit code of 1. */ extern "C" void DynamicStrings_PopAllocation (bool halt); /* PopAllocationExemption - test to see that all strings are deallocated, except string e since the last push. Post-condition: it pops to the previous allocation/deallocation lists. If halt is true then the application terminates with an exit code of 1. */ extern "C" DynamicStrings_String DynamicStrings_PopAllocationExemption (bool halt, DynamicStrings_String e); /* writeStringDesc write out debugging information about string, s. */ static void writeStringDesc (DynamicStrings_String s); /* writeNspace - */ static void writeNspace (unsigned int n); /* DumpStringInfo - */ static void DumpStringInfo (DynamicStrings_String s, unsigned int i); /* DumpStringInfo - */ static void stop (void); /* doDSdbEnter - */ static void doDSdbEnter (void); /* doDSdbExit - */ static void doDSdbExit (DynamicStrings_String s); /* DSdbEnter - */ static void DSdbEnter (void); /* DSdbExit - */ static void DSdbExit (DynamicStrings_String s); static unsigned int Capture (DynamicStrings_String s); /* Min - */ static unsigned int Min (unsigned int a, unsigned int b); /* Max - */ static unsigned int Max (unsigned int a, unsigned int b); /* writeString - writes a string to stdout. */ static void writeString (const char *a_, unsigned int _a_high); /* writeCstring - writes a C string to stdout. */ static void writeCstring (void * a); /* writeCard - */ static void writeCard (unsigned int c); /* writeLongcard - */ static void writeLongcard (long unsigned int l); /* writeAddress - writes out the address of a with a C style hex prefix. */ static void writeAddress (void * a); /* writeLn - writes a newline. */ static void writeLn (void); /* AssignDebug - assigns, file, and, line, information to string, s. */ static DynamicStrings_String AssignDebug (DynamicStrings_String s, const char *file_, unsigned int _file_high, unsigned int line, const char *proc_, unsigned int _proc_high); /* IsOn - returns TRUE if, s, is on one of the debug lists. */ static bool IsOn (DynamicStrings_String list, DynamicStrings_String s); /* AddTo - adds string, s, to, list. */ static void AddTo (DynamicStrings_String *list, DynamicStrings_String s); /* SubFrom - removes string, s, from, list. */ static void SubFrom (DynamicStrings_String *list, DynamicStrings_String s); /* AddAllocated - adds string, s, to the head of the allocated list. */ static void AddAllocated (DynamicStrings_String s); /* AddDeallocated - adds string, s, to the head of the deallocated list. */ static void AddDeallocated (DynamicStrings_String s); /* IsOnAllocated - returns TRUE if the string, s, has ever been allocated. */ static bool IsOnAllocated (DynamicStrings_String s); /* IsOnDeallocated - returns TRUE if the string, s, has ever been deallocated. */ static bool IsOnDeallocated (DynamicStrings_String s); /* SubAllocated - removes string, s, from the list of allocated strings. */ static void SubAllocated (DynamicStrings_String s); /* SubDeallocated - removes string, s, from the list of deallocated strings. */ static void SubDeallocated (DynamicStrings_String s); /* SubDebugInfo - removes string, s, from the list of allocated strings. */ static void SubDebugInfo (DynamicStrings_String s); /* AddDebugInfo - adds string, s, to the list of allocated strings. */ static void AddDebugInfo (DynamicStrings_String s); /* ConcatContents - add the contents of string, a, where, h, is the total length of, a. The offset is in, o. */ static void ConcatContents (DynamicStrings_Contents *c, const char *a_, unsigned int _a_high, unsigned int h, unsigned int o); /* DeallocateCharStar - deallocates any charStar. */ static void DeallocateCharStar (DynamicStrings_String s); /* CheckPoisoned - checks for a poisoned string, s. */ static DynamicStrings_String CheckPoisoned (DynamicStrings_String s); /* MarkInvalid - marks the char * version of String, s, as invalid. */ static void MarkInvalid (DynamicStrings_String s); /* ConcatContentsAddress - concatenate the string, a, where, h, is the total length of, a. */ static void ConcatContentsAddress (DynamicStrings_Contents *c, void * a, unsigned int h); /* AddToGarbage - adds String, b, onto the garbage list of, a. Providing the state of b is marked. The state is then altered to onlist. String, a, is returned. */ static DynamicStrings_String AddToGarbage (DynamicStrings_String a, DynamicStrings_String b); /* IsOnGarbage - returns TRUE if, s, is on string, e, garbage list. */ static bool IsOnGarbage (DynamicStrings_String e, DynamicStrings_String s); /* IsWhite - returns TRUE if, ch, is a space or a tab. */ static bool IsWhite (char ch); /* DumpState - */ static void DumpState (DynamicStrings_String s); /* DumpStringSynopsis - */ static void DumpStringSynopsis (DynamicStrings_String s); /* DumpString - displays the contents of string, s. */ static void DumpString (DynamicStrings_String s); /* Init - initialize the module. */ static void Init (void); /* writeStringDesc write out debugging information about string, s. */ static void writeStringDesc (DynamicStrings_String s) { writeCstring (s->debug.file); writeString ((const char *) ":", 1); writeCard (s->debug.line); writeString ((const char *) ":", 1); writeCstring (s->debug.proc); writeString ((const char *) " ", 1); writeAddress (reinterpret_cast (s)); writeString ((const char *) " ", 1); switch (s->head->state) { case DynamicStrings_inuse: writeString ((const char *) "still in use (", 14); writeCard (s->contents.len); writeString ((const char *) ") characters", 12); break; case DynamicStrings_marked: writeString ((const char *) "marked", 6); break; case DynamicStrings_onlist: writeString ((const char *) "on a (lost) garbage list", 24); break; case DynamicStrings_poisoned: writeString ((const char *) "poisoned", 8); break; default: writeString ((const char *) "unknown state", 13); break; } } /* writeNspace - */ static void writeNspace (unsigned int n) { while (n > 0) { writeString ((const char *) " ", 1); n -= 1; } } /* DumpStringInfo - */ static void DumpStringInfo (DynamicStrings_String s, unsigned int i) { if (s != NULL) { writeNspace (i); writeStringDesc (s); writeLn (); if (s->head->garbage != NULL) { writeNspace (i); writeString ((const char *) "garbage list:", 13); writeLn (); do { s = s->head->garbage; DumpStringInfo (s, i+1); writeLn (); } while (! (s == NULL)); } } } /* DumpStringInfo - */ static void stop (void) { } /* doDSdbEnter - */ static void doDSdbEnter (void) { if (CheckOn) { DynamicStrings_PushAllocation (); } } /* doDSdbExit - */ static void doDSdbExit (DynamicStrings_String s) { if (CheckOn) { s = DynamicStrings_PopAllocationExemption (true, s); } } /* DSdbEnter - */ static void DSdbEnter (void) { } /* DSdbExit - */ static void DSdbExit (DynamicStrings_String s) { } static unsigned int Capture (DynamicStrings_String s) { /* * #undef GM2_DEBUG_DYNAMICSTINGS * #if defined(GM2_DEBUG_DYNAMICSTINGS) * # define DSdbEnter doDSdbEnter * # define DSdbExit doDSdbExit * # define CheckOn TRUE * # define TraceOn TRUE * #endif */ captured = s; return 1; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Min - */ static unsigned int Min (unsigned int a, unsigned int b) { if (a < b) { return a; } else { return b; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Max - */ static unsigned int Max (unsigned int a, unsigned int b) { if (a > b) { return a; } else { return b; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* writeString - writes a string to stdout. */ static void writeString (const char *a_, unsigned int _a_high) { int i; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); i = static_cast (libc_write (1, &a, static_cast (StrLib_StrLen ((const char *) a, _a_high)))); } /* writeCstring - writes a C string to stdout. */ static void writeCstring (void * a) { int i; if (a == NULL) { writeString ((const char *) "(null)", 6); } else { i = static_cast (libc_write (1, a, libc_strlen (a))); } } /* writeCard - */ static void writeCard (unsigned int c) { char ch; int i; if (c > 9) { writeCard (c / 10); writeCard (c % 10); } else { ch = ((char) ( ((unsigned int) ('0'))+c)); i = static_cast (libc_write (1, &ch, static_cast (1))); } } /* writeLongcard - */ static void writeLongcard (long unsigned int l) { char ch; int i; if (l > 16) { writeLongcard (l / 16); writeLongcard (l % 16); } else if (l < 10) { /* avoid dangling else. */ ch = ((char) ( ((unsigned int) ('0'))+((unsigned int ) (l)))); i = static_cast (libc_write (1, &ch, static_cast (1))); } else if (l < 16) { /* avoid dangling else. */ ch = ((char) (( ((unsigned int) ('a'))+((unsigned int ) (l)))-10)); i = static_cast (libc_write (1, &ch, static_cast (1))); } } /* writeAddress - writes out the address of a with a C style hex prefix. */ static void writeAddress (void * a) { typedef struct writeAddress__T4_a writeAddress__T4; struct writeAddress__T4_a { char array[30+1]; }; writeAddress__T4 buffer; libc_snprintf (&buffer, static_cast (sizeof (buffer)), (const char *) "0x%", 3, a); writeString ((const char *) &buffer.array[0], 30); } /* writeLn - writes a newline. */ static void writeLn (void) { char ch; int i; ch = ASCII_lf; i = static_cast (libc_write (1, &ch, static_cast (1))); } /* AssignDebug - assigns, file, and, line, information to string, s. */ static DynamicStrings_String AssignDebug (DynamicStrings_String s, const char *file_, unsigned int _file_high, unsigned int line, const char *proc_, unsigned int _proc_high) { void * f; void * p; char file[_file_high+1]; char proc[_proc_high+1]; /* make a local copy of each unbounded array. */ memcpy (file, file_, _file_high+1); memcpy (proc, proc_, _proc_high+1); f = &file; p = &proc; Storage_ALLOCATE (&s->debug.file, (StrLib_StrLen ((const char *) file, _file_high))+1); if ((libc_strncpy (s->debug.file, f, (StrLib_StrLen ((const char *) file, _file_high))+1)) == NULL) {} /* empty. */ s->debug.line = line; Storage_ALLOCATE (&s->debug.proc, (StrLib_StrLen ((const char *) proc, _proc_high))+1); if ((libc_strncpy (s->debug.proc, p, (StrLib_StrLen ((const char *) proc, _proc_high))+1)) == NULL) {} /* empty. */ return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* IsOn - returns TRUE if, s, is on one of the debug lists. */ static bool IsOn (DynamicStrings_String list, DynamicStrings_String s) { while ((list != s) && (list != NULL)) { list = list->debug.next; } return list == s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* AddTo - adds string, s, to, list. */ static void AddTo (DynamicStrings_String *list, DynamicStrings_String s) { if ((*list) == NULL) { (*list) = s; s->debug.next = NULL; } else { s->debug.next = (*list); (*list) = s; } } /* SubFrom - removes string, s, from, list. */ static void SubFrom (DynamicStrings_String *list, DynamicStrings_String s) { DynamicStrings_String p; if ((*list) == s) { (*list) = s->debug.next; } else { p = (*list); while ((p->debug.next != NULL) && (p->debug.next != s)) { p = p->debug.next; } if (p->debug.next == s) { p->debug.next = s->debug.next; } else { /* not found, quit */ return ; } } s->debug.next = NULL; } /* AddAllocated - adds string, s, to the head of the allocated list. */ static void AddAllocated (DynamicStrings_String s) { Init (); AddTo (&frameHead->alloc, s); } /* AddDeallocated - adds string, s, to the head of the deallocated list. */ static void AddDeallocated (DynamicStrings_String s) { Init (); AddTo (&frameHead->dealloc, s); } /* IsOnAllocated - returns TRUE if the string, s, has ever been allocated. */ static bool IsOnAllocated (DynamicStrings_String s) { DynamicStrings_frame f; Init (); f = frameHead; do { if (IsOn (f->alloc, s)) { return true; } else { f = f->next; } } while (! (f == NULL)); return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* IsOnDeallocated - returns TRUE if the string, s, has ever been deallocated. */ static bool IsOnDeallocated (DynamicStrings_String s) { DynamicStrings_frame f; Init (); f = frameHead; do { if (IsOn (f->dealloc, s)) { return true; } else { f = f->next; } } while (! (f == NULL)); return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* SubAllocated - removes string, s, from the list of allocated strings. */ static void SubAllocated (DynamicStrings_String s) { DynamicStrings_frame f; Init (); f = frameHead; do { if (IsOn (f->alloc, s)) { SubFrom (&f->alloc, s); return ; } else { f = f->next; } } while (! (f == NULL)); } /* SubDeallocated - removes string, s, from the list of deallocated strings. */ static void SubDeallocated (DynamicStrings_String s) { DynamicStrings_frame f; Init (); f = frameHead; do { if (IsOn (f->dealloc, s)) { SubFrom (&f->dealloc, s); return ; } else { f = f->next; } } while (! (f == NULL)); } /* SubDebugInfo - removes string, s, from the list of allocated strings. */ static void SubDebugInfo (DynamicStrings_String s) { if (IsOnDeallocated (s)) { Assertion_Assert (! DebugOn); /* string has already been deallocated */ return ; } if (IsOnAllocated (s)) { SubAllocated (s); AddDeallocated (s); } else { /* string has not been allocated */ Assertion_Assert (! DebugOn); } } /* AddDebugInfo - adds string, s, to the list of allocated strings. */ static void AddDebugInfo (DynamicStrings_String s) { s->debug.next = NULL; s->debug.file = NULL; s->debug.line = 0; s->debug.proc = NULL; if (CheckOn) { AddAllocated (s); } } /* ConcatContents - add the contents of string, a, where, h, is the total length of, a. The offset is in, o. */ static void ConcatContents (DynamicStrings_Contents *c, const char *a_, unsigned int _a_high, unsigned int h, unsigned int o) { unsigned int i; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); i = (*c).len; while ((o < h) && (i < MaxBuf)) { (*c).buf.array[i] = a[o]; o += 1; i += 1; } if (o < h) { (*c).len = MaxBuf; Storage_ALLOCATE ((void **) &(*c).next, sizeof (DynamicStrings_stringRecord)); (*c).next->head = NULL; (*c).next->contents.len = 0; (*c).next->contents.next = NULL; ConcatContents (&(*c).next->contents, (const char *) a, _a_high, h, o); AddDebugInfo ((*c).next); (*c).next = AssignDebug ((*c).next, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 722, (const char *) "ConcatContents", 14); } else { (*c).len = i; } } /* DeallocateCharStar - deallocates any charStar. */ static void DeallocateCharStar (DynamicStrings_String s) { if ((s != NULL) && (s->head != NULL)) { if (s->head->charStarUsed && (s->head->charStar != NULL)) { Storage_DEALLOCATE (&s->head->charStar, s->head->charStarSize); } s->head->charStarUsed = false; s->head->charStar = NULL; s->head->charStarSize = 0; s->head->charStarValid = false; } } /* CheckPoisoned - checks for a poisoned string, s. */ static DynamicStrings_String CheckPoisoned (DynamicStrings_String s) { if (((PoisonOn && (s != NULL)) && (s->head != NULL)) && (s->head->state == DynamicStrings_poisoned)) { M2RTS_HALT (-1); __builtin_unreachable (); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* MarkInvalid - marks the char * version of String, s, as invalid. */ static void MarkInvalid (DynamicStrings_String s) { if (PoisonOn) { s = CheckPoisoned (s); } if (s->head != NULL) { s->head->charStarValid = false; } } /* ConcatContentsAddress - concatenate the string, a, where, h, is the total length of, a. */ static void ConcatContentsAddress (DynamicStrings_Contents *c, void * a, unsigned int h) { typedef char *ConcatContentsAddress__T1; ConcatContentsAddress__T1 p; unsigned int i; unsigned int j; j = 0; i = (*c).len; p = static_cast (a); while ((j < h) && (i < MaxBuf)) { (*c).buf.array[i] = (*p); i += 1; j += 1; p += 1; } if (j < h) { /* avoid dangling else. */ (*c).len = MaxBuf; Storage_ALLOCATE ((void **) &(*c).next, sizeof (DynamicStrings_stringRecord)); (*c).next->head = NULL; (*c).next->contents.len = 0; (*c).next->contents.next = NULL; ConcatContentsAddress (&(*c).next->contents, reinterpret_cast (p), h-j); AddDebugInfo ((*c).next); if (TraceOn) { (*c).next = AssignDebug ((*c).next, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 917, (const char *) "ConcatContentsAddress", 21); } } else { (*c).len = i; (*c).next = NULL; } } /* AddToGarbage - adds String, b, onto the garbage list of, a. Providing the state of b is marked. The state is then altered to onlist. String, a, is returned. */ static DynamicStrings_String AddToGarbage (DynamicStrings_String a, DynamicStrings_String b) { DynamicStrings_String c; if (PoisonOn) { a = CheckPoisoned (a); b = CheckPoisoned (b); } /* IF (a#NIL) AND (a#b) AND (a^.head^.state=marked) THEN writeString('warning trying to add to a marked string') ; writeLn END ; */ if (((((a != b) && (a != NULL)) && (b != NULL)) && (b->head->state == DynamicStrings_marked)) && (a->head->state == DynamicStrings_inuse)) { c = a; while (c->head->garbage != NULL) { c = c->head->garbage; } c->head->garbage = b; b->head->state = DynamicStrings_onlist; if (CheckOn) { SubDebugInfo (b); } } return a; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* IsOnGarbage - returns TRUE if, s, is on string, e, garbage list. */ static bool IsOnGarbage (DynamicStrings_String e, DynamicStrings_String s) { if ((e != NULL) && (s != NULL)) { while (e->head->garbage != NULL) { if (e->head->garbage == s) { return true; } else { e = e->head->garbage; } } } return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* IsWhite - returns TRUE if, ch, is a space or a tab. */ static bool IsWhite (char ch) { return (ch == ' ') || (ch == ASCII_tab); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* DumpState - */ static void DumpState (DynamicStrings_String s) { switch (s->head->state) { case DynamicStrings_inuse: writeString ((const char *) "still in use (", 14); writeCard (s->contents.len); writeString ((const char *) ") characters", 12); break; case DynamicStrings_marked: writeString ((const char *) "marked", 6); break; case DynamicStrings_onlist: writeString ((const char *) "on a garbage list", 17); break; case DynamicStrings_poisoned: writeString ((const char *) "poisoned", 8); break; default: writeString ((const char *) "unknown state", 13); break; } } /* DumpStringSynopsis - */ static void DumpStringSynopsis (DynamicStrings_String s) { writeCstring (s->debug.file); writeString ((const char *) ":", 1); writeCard (s->debug.line); writeString ((const char *) ":", 1); writeCstring (s->debug.proc); writeString ((const char *) " string ", 8); writeAddress (reinterpret_cast (s)); writeString ((const char *) " ", 1); DumpState (s); if (IsOnAllocated (s)) { writeString ((const char *) " globally allocated", 19); } else if (IsOnDeallocated (s)) { /* avoid dangling else. */ writeString ((const char *) " globally deallocated", 21); } else { /* avoid dangling else. */ writeString ((const char *) " globally unknown", 17); } writeLn (); } /* DumpString - displays the contents of string, s. */ static void DumpString (DynamicStrings_String s) { DynamicStrings_String t; if (s != NULL) { DumpStringSynopsis (s); if ((s->head != NULL) && (s->head->garbage != NULL)) { writeString ((const char *) "display chained strings on the garbage list", 43); writeLn (); t = s->head->garbage; while (t != NULL) { DumpStringSynopsis (t); t = t->head->garbage; } } } } /* Init - initialize the module. */ static void Init (void) { if (! Initialized) { Initialized = true; frameHead = NULL; DynamicStrings_PushAllocation (); } } /* InitString - creates and returns a String type object. Initial contents are, a. */ extern "C" DynamicStrings_String DynamicStrings_InitString (const char *a_, unsigned int _a_high) { DynamicStrings_String s; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); Storage_ALLOCATE ((void **) &s, sizeof (DynamicStrings_stringRecord)); s->contents.len = 0; s->contents.next = NULL; ConcatContents (&s->contents, (const char *) a, _a_high, StrLib_StrLen ((const char *) a, _a_high), 0); Storage_ALLOCATE ((void **) &s->head, sizeof (DynamicStrings_descriptor)); s->head->charStarUsed = false; s->head->charStar = NULL; s->head->charStarSize = 0; s->head->charStarValid = false; s->head->garbage = NULL; s->head->state = DynamicStrings_inuse; AddDebugInfo (s); if (TraceOn) { s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 758, (const char *) "InitString", 10); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* KillString - frees String, s, and its contents. NIL is returned. */ extern "C" DynamicStrings_String DynamicStrings_KillString (DynamicStrings_String s) { DynamicStrings_String t; if (PoisonOn) { s = CheckPoisoned (s); } if (s != NULL) { if (CheckOn) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (IsOnAllocated (s)) { SubAllocated (s); } else if (IsOnDeallocated (s)) { /* avoid dangling else. */ SubDeallocated (s); } } if (s->head != NULL) { s->head->state = DynamicStrings_poisoned; s->head->garbage = DynamicStrings_KillString (s->head->garbage); if (! PoisonOn) { DeallocateCharStar (s); } if (! PoisonOn) { Storage_DEALLOCATE ((void **) &s->head, sizeof (DynamicStrings_descriptor)); s->head = NULL; } } t = DynamicStrings_KillString (s->contents.next); if (! PoisonOn) { Storage_DEALLOCATE ((void **) &s, sizeof (DynamicStrings_stringRecord)); } } return NULL; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Fin - finishes with a string, it calls KillString with, s. The purpose of the procedure is to provide a short cut to calling KillString and then testing the return result. */ extern "C" void DynamicStrings_Fin (DynamicStrings_String s) { if ((DynamicStrings_KillString (s)) != NULL) { M2RTS_HALT (-1); __builtin_unreachable (); } } /* InitStringCharStar - initializes and returns a String to contain the C string. */ extern "C" DynamicStrings_String DynamicStrings_InitStringCharStar (void * a) { DynamicStrings_String s; Storage_ALLOCATE ((void **) &s, sizeof (DynamicStrings_stringRecord)); s->contents.len = 0; s->contents.next = NULL; if (a != NULL) { ConcatContentsAddress (&s->contents, a, static_cast (libc_strlen (a))); } Storage_ALLOCATE ((void **) &s->head, sizeof (DynamicStrings_descriptor)); s->head->charStarUsed = false; s->head->charStar = NULL; s->head->charStarSize = 0; s->head->charStarValid = false; s->head->garbage = NULL; s->head->state = DynamicStrings_inuse; AddDebugInfo (s); if (TraceOn) { s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 957, (const char *) "InitStringCharStar", 18); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* InitStringChar - initializes and returns a String to contain the single character, ch. */ extern "C" DynamicStrings_String DynamicStrings_InitStringChar (char ch) { typedef struct InitStringChar__T5_a InitStringChar__T5; struct InitStringChar__T5_a { char array[1+1]; }; InitStringChar__T5 a; DynamicStrings_String s; a.array[0] = ch; a.array[1] = ASCII_nul; s = DynamicStrings_InitString ((const char *) &a.array[0], 1); if (TraceOn) { s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 977, (const char *) "InitStringChar", 14); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Mark - marks String, s, ready for garbage collection. */ extern "C" DynamicStrings_String DynamicStrings_Mark (DynamicStrings_String s) { if (PoisonOn) { s = CheckPoisoned (s); } if ((s != NULL) && (s->head->state == DynamicStrings_inuse)) { s->head->state = DynamicStrings_marked; } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Length - returns the length of the String, s. */ extern "C" unsigned int DynamicStrings_Length (DynamicStrings_String s) { if (s == NULL) { return 0; } else { return s->contents.len+(DynamicStrings_Length (s->contents.next)); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ConCat - returns String, a, after the contents of, b, have been appended. */ extern "C" DynamicStrings_String DynamicStrings_ConCat (DynamicStrings_String a, DynamicStrings_String b) { DynamicStrings_String t; if (PoisonOn) { a = CheckPoisoned (a); b = CheckPoisoned (b); } if (a == b) { return DynamicStrings_ConCat (a, DynamicStrings_Mark (DynamicStrings_Dup (b))); } else if (a != NULL) { /* avoid dangling else. */ a = AddToGarbage (a, b); MarkInvalid (a); t = a; while (b != NULL) { while ((t->contents.len == MaxBuf) && (t->contents.next != NULL)) { t = t->contents.next; } ConcatContents (&t->contents, (const char *) &b->contents.buf.array[0], (MaxBuf-1), b->contents.len, 0); b = b->contents.next; } } if ((a == NULL) && (b != NULL)) { M2RTS_HALT (-1); __builtin_unreachable (); } return a; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ConCatChar - returns String, a, after character, ch, has been appended. */ extern "C" DynamicStrings_String DynamicStrings_ConCatChar (DynamicStrings_String a, char ch) { typedef struct ConCatChar__T6_a ConCatChar__T6; struct ConCatChar__T6_a { char array[1+1]; }; ConCatChar__T6 b; DynamicStrings_String t; if (PoisonOn) { a = CheckPoisoned (a); } b.array[0] = ch; b.array[1] = ASCII_nul; t = a; MarkInvalid (a); while ((t->contents.len == MaxBuf) && (t->contents.next != NULL)) { t = t->contents.next; } ConcatContents (&t->contents, (const char *) &b.array[0], 1, 1, 0); return a; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Assign - assigns the contents of, b, into, a. String, a, is returned. */ extern "C" DynamicStrings_String DynamicStrings_Assign (DynamicStrings_String a, DynamicStrings_String b) { if (PoisonOn) { a = CheckPoisoned (a); b = CheckPoisoned (b); } if ((a != NULL) && (b != NULL)) { a->contents.next = DynamicStrings_KillString (a->contents.next); a->contents.len = 0; } return DynamicStrings_ConCat (a, b); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Dup - duplicate a String, s, returning the copy of s. */ extern "C" DynamicStrings_String DynamicStrings_Dup (DynamicStrings_String s) { if (PoisonOn) { s = CheckPoisoned (s); } s = DynamicStrings_Assign (DynamicStrings_InitString ((const char *) "", 0), s); if (TraceOn) { s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1173, (const char *) "Dup", 3); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Add - returns a new String which contains the contents of a and b. */ extern "C" DynamicStrings_String DynamicStrings_Add (DynamicStrings_String a, DynamicStrings_String b) { if (PoisonOn) { a = CheckPoisoned (a); b = CheckPoisoned (b); } a = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "", 0), a), b); if (TraceOn) { a = AssignDebug (a, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1193, (const char *) "Add", 3); } return a; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Equal - returns TRUE if String, a, and, b, are equal. */ extern "C" bool DynamicStrings_Equal (DynamicStrings_String a, DynamicStrings_String b) { unsigned int i; if (PoisonOn) { a = CheckPoisoned (a); b = CheckPoisoned (b); } if ((DynamicStrings_Length (a)) == (DynamicStrings_Length (b))) { while ((a != NULL) && (b != NULL)) { i = 0; Assertion_Assert (a->contents.len == b->contents.len); while (i < a->contents.len) { if (a->contents.buf.array[i] != b->contents.buf.array[i]) { return false; } i += 1; } a = a->contents.next; b = b->contents.next; } return true; } else { return false; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* EqualCharStar - returns TRUE if contents of String, s, is the same as the string, a. */ extern "C" bool DynamicStrings_EqualCharStar (DynamicStrings_String s, void * a) { DynamicStrings_String t; if (PoisonOn) { s = CheckPoisoned (s); } t = DynamicStrings_InitStringCharStar (a); if (TraceOn) { t = AssignDebug (t, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1250, (const char *) "EqualCharStar", 13); } t = AddToGarbage (t, s); if (DynamicStrings_Equal (t, s)) { t = DynamicStrings_KillString (t); return true; } else { t = DynamicStrings_KillString (t); return false; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* EqualArray - returns TRUE if contents of String, s, is the same as the string, a. */ extern "C" bool DynamicStrings_EqualArray (DynamicStrings_String s, const char *a_, unsigned int _a_high) { DynamicStrings_String t; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); if (PoisonOn) { s = CheckPoisoned (s); } t = DynamicStrings_InitString ((const char *) a, _a_high); if (TraceOn) { t = AssignDebug (t, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1280, (const char *) "EqualArray", 10); } t = AddToGarbage (t, s); if (DynamicStrings_Equal (t, s)) { t = DynamicStrings_KillString (t); return true; } else { t = DynamicStrings_KillString (t); return false; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Mult - returns a new string which is n concatenations of String, s. */ extern "C" DynamicStrings_String DynamicStrings_Mult (DynamicStrings_String s, unsigned int n) { if (PoisonOn) { s = CheckPoisoned (s); } if (n <= 0) { s = AddToGarbage (DynamicStrings_InitString ((const char *) "", 0), s); } else { s = DynamicStrings_ConCat (DynamicStrings_Mult (s, n-1), s); } if (TraceOn) { s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1312, (const char *) "Mult", 4); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Slice - returns a new string which contains the elements low..high-1 strings start at element 0 Slice(s, 0, 2) will return elements 0, 1 but not 2 Slice(s, 1, 3) will return elements 1, 2 but not 3 Slice(s, 2, 0) will return elements 2..max Slice(s, 3, -1) will return elements 3..max-1 Slice(s, 4, -2) will return elements 4..max-2 */ extern "C" DynamicStrings_String DynamicStrings_Slice (DynamicStrings_String s, int low, int high) { DynamicStrings_String d; DynamicStrings_String t; int start; int end; int o; if (PoisonOn) { s = CheckPoisoned (s); } if (low < 0) { low = ((int ) (DynamicStrings_Length (s)))+low; } if (high <= 0) { high = ((int ) (DynamicStrings_Length (s)))+high; } else { /* make sure high is <= Length (s) */ high = Min (DynamicStrings_Length (s), static_cast (high)); } d = DynamicStrings_InitString ((const char *) "", 0); d = AddToGarbage (d, s); o = 0; t = d; while (s != NULL) { if (low < (o+((int ) (s->contents.len)))) { if (o > high) { s = NULL; } else { /* found sliceable unit */ if (low < o) { start = 0; } else { start = low-o; } end = Max (Min (MaxBuf, static_cast (high-o)), 0); while (t->contents.len == MaxBuf) { if (t->contents.next == NULL) { Storage_ALLOCATE ((void **) &t->contents.next, sizeof (DynamicStrings_stringRecord)); t->contents.next->head = NULL; t->contents.next->contents.len = 0; AddDebugInfo (t->contents.next); if (TraceOn) { t->contents.next = AssignDebug (t->contents.next, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1380, (const char *) "Slice", 5); } } t = t->contents.next; } ConcatContentsAddress (&t->contents, &s->contents.buf.array[start], static_cast (end-start)); o += s->contents.len; s = s->contents.next; } } else { o += s->contents.len; s = s->contents.next; } } if (TraceOn) { d = AssignDebug (d, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1397, (const char *) "Slice", 5); } return d; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Index - returns the indice of the first occurance of, ch, in String, s. -1 is returned if, ch, does not exist. The search starts at position, o. */ extern "C" int DynamicStrings_Index (DynamicStrings_String s, char ch, unsigned int o) { unsigned int i; unsigned int k; if (PoisonOn) { s = CheckPoisoned (s); } k = 0; while (s != NULL) { if ((k+s->contents.len) < o) { k += s->contents.len; } else { i = o-k; while (i < s->contents.len) { if (s->contents.buf.array[i] == ch) { return k+i; } i += 1; } k += i; o = k; } s = s->contents.next; } return -1; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* RIndex - returns the indice of the last occurance of, ch, in String, s. The search starts at position, o. -1 is returned if, ch, is not found. */ extern "C" int DynamicStrings_RIndex (DynamicStrings_String s, char ch, unsigned int o) { unsigned int i; unsigned int k; int j; if (PoisonOn) { s = CheckPoisoned (s); } j = -1; k = 0; while (s != NULL) { if ((k+s->contents.len) < o) { k += s->contents.len; } else { if (o < k) { i = 0; } else { i = o-k; } while (i < s->contents.len) { if (s->contents.buf.array[i] == ch) { j = k; } k += 1; i += 1; } } s = s->contents.next; } return j; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* RemoveComment - assuming that, comment, is a comment delimiter which indicates anything to its right is a comment then strip off the comment and also any white space on the remaining right hand side. It leaves any white space on the left hand side alone. */ extern "C" DynamicStrings_String DynamicStrings_RemoveComment (DynamicStrings_String s, char comment) { int i; i = DynamicStrings_Index (s, comment, 0); if (i == 0) { s = DynamicStrings_InitString ((const char *) "", 0); } else if (i > 0) { /* avoid dangling else. */ s = DynamicStrings_RemoveWhitePostfix (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, i)); } if (TraceOn) { s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1509, (const char *) "RemoveComment", 13); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* RemoveWhitePrefix - removes any leading white space from String, s. A new string is returned. */ extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePrefix (DynamicStrings_String s) { unsigned int i; i = 0; while (IsWhite (DynamicStrings_char (s, static_cast (i)))) { i += 1; } s = DynamicStrings_Slice (s, (int ) (i), 0); if (TraceOn) { s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1621, (const char *) "RemoveWhitePrefix", 17); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* RemoveWhitePostfix - removes any leading white space from String, s. A new string is returned. */ extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePostfix (DynamicStrings_String s) { int i; i = ((int ) (DynamicStrings_Length (s)))-1; while ((i >= 0) && (IsWhite (DynamicStrings_char (s, i)))) { i -= 1; } s = DynamicStrings_Slice (s, 0, i+1); if (TraceOn) { s = AssignDebug (s, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, 1643, (const char *) "RemoveWhitePostfix", 18); } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ToUpper - returns string, s, after it has had its lower case characters replaced by upper case characters. The string, s, is not duplicated. */ extern "C" DynamicStrings_String DynamicStrings_ToUpper (DynamicStrings_String s) { char ch; unsigned int i; DynamicStrings_String t; if (s != NULL) { MarkInvalid (s); t = s; while (t != NULL) { i = 0; while (i < t->contents.len) { ch = t->contents.buf.array[i]; if ((ch >= 'a') && (ch <= 'z')) { t->contents.buf.array[i] = ((char) (( ((unsigned int) (ch))- ((unsigned int) ('a')))+ ((unsigned int) ('A')))); } i += 1; } t = t->contents.next; } } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ToLower - returns string, s, after it has had its upper case characters replaced by lower case characters. The string, s, is not duplicated. */ extern "C" DynamicStrings_String DynamicStrings_ToLower (DynamicStrings_String s) { char ch; unsigned int i; DynamicStrings_String t; if (s != NULL) { MarkInvalid (s); t = s; while (t != NULL) { i = 0; while (i < t->contents.len) { ch = t->contents.buf.array[i]; if ((ch >= 'A') && (ch <= 'Z')) { t->contents.buf.array[i] = ((char) (( ((unsigned int) (ch))- ((unsigned int) ('A')))+ ((unsigned int) ('a')))); } i += 1; } t = t->contents.next; } } return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* CopyOut - copies string, s, to a. */ extern "C" void DynamicStrings_CopyOut (char *a, unsigned int _a_high, DynamicStrings_String s) { unsigned int i; unsigned int l; l = Min (_a_high+1, DynamicStrings_Length (s)); i = 0; while (i < l) { a[i] = DynamicStrings_char (s, static_cast (i)); i += 1; } if (i <= _a_high) { a[i] = ASCII_nul; } } /* char - returns the character, ch, at position, i, in String, s. */ extern "C" char DynamicStrings_char (DynamicStrings_String s, int i) { unsigned int c; if (PoisonOn) { s = CheckPoisoned (s); } if (i < 0) { c = (unsigned int ) (((int ) (DynamicStrings_Length (s)))+i); } else { c = i; } while ((s != NULL) && (c >= s->contents.len)) { c -= s->contents.len; s = s->contents.next; } if ((s == NULL) || (c >= s->contents.len)) { return ASCII_nul; } else { return s->contents.buf.array[c]; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* string - returns the C style char * of String, s. */ extern "C" void * DynamicStrings_string (DynamicStrings_String s) { typedef char *string__T2; DynamicStrings_String a; unsigned int l; unsigned int i; string__T2 p; if (PoisonOn) { s = CheckPoisoned (s); } if (s == NULL) { return NULL; } else { if (! s->head->charStarValid) { l = DynamicStrings_Length (s); if (! (s->head->charStarUsed && (s->head->charStarSize > l))) { DeallocateCharStar (s); Storage_ALLOCATE (&s->head->charStar, l+1); s->head->charStarSize = l+1; s->head->charStarUsed = true; } p = static_cast (s->head->charStar); a = s; while (a != NULL) { i = 0; while (i < a->contents.len) { (*p) = a->contents.buf.array[i]; i += 1; p += 1; } a = a->contents.next; } (*p) = ASCII_nul; s->head->charStarValid = true; } return s->head->charStar; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* InitStringDB - the debug version of InitString. */ extern "C" DynamicStrings_String DynamicStrings_InitStringDB (const char *a_, unsigned int _a_high, const char *file_, unsigned int _file_high, unsigned int line) { char a[_a_high+1]; char file[_file_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); memcpy (file, file_, _file_high+1); return AssignDebug (DynamicStrings_InitString ((const char *) a, _a_high), (const char *) file, _file_high, line, (const char *) "InitString", 10); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* InitStringCharStarDB - the debug version of InitStringCharStar. */ extern "C" DynamicStrings_String DynamicStrings_InitStringCharStarDB (void * a, const char *file_, unsigned int _file_high, unsigned int line) { char file[_file_high+1]; /* make a local copy of each unbounded array. */ memcpy (file, file_, _file_high+1); return AssignDebug (DynamicStrings_InitStringCharStar (a), (const char *) file, _file_high, line, (const char *) "InitStringCharStar", 18); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* InitStringCharDB - the debug version of InitStringChar. */ extern "C" DynamicStrings_String DynamicStrings_InitStringCharDB (char ch, const char *file_, unsigned int _file_high, unsigned int line) { char file[_file_high+1]; /* make a local copy of each unbounded array. */ memcpy (file, file_, _file_high+1); return AssignDebug (DynamicStrings_InitStringChar (ch), (const char *) file, _file_high, line, (const char *) "InitStringChar", 14); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* MultDB - the debug version of MultDB. */ extern "C" DynamicStrings_String DynamicStrings_MultDB (DynamicStrings_String s, unsigned int n, const char *file_, unsigned int _file_high, unsigned int line) { char file[_file_high+1]; /* make a local copy of each unbounded array. */ memcpy (file, file_, _file_high+1); return AssignDebug (DynamicStrings_Mult (s, n), (const char *) file, _file_high, line, (const char *) "Mult", 4); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* DupDB - the debug version of Dup. */ extern "C" DynamicStrings_String DynamicStrings_DupDB (DynamicStrings_String s, const char *file_, unsigned int _file_high, unsigned int line) { char file[_file_high+1]; /* make a local copy of each unbounded array. */ memcpy (file, file_, _file_high+1); return AssignDebug (DynamicStrings_Dup (s), (const char *) file, _file_high, line, (const char *) "Dup", 3); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* SliceDB - debug version of Slice. */ extern "C" DynamicStrings_String DynamicStrings_SliceDB (DynamicStrings_String s, int low, int high, const char *file_, unsigned int _file_high, unsigned int line) { char file[_file_high+1]; /* make a local copy of each unbounded array. */ memcpy (file, file_, _file_high+1); DSdbEnter (); s = AssignDebug (DynamicStrings_Slice (s, low, high), (const char *) file, _file_high, line, (const char *) "Slice", 5); DSdbExit (s); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* PushAllocation - pushes the current allocation/deallocation lists. */ extern "C" void DynamicStrings_PushAllocation (void) { DynamicStrings_frame f; if (CheckOn) { Init (); Storage_ALLOCATE ((void **) &f, sizeof (DynamicStrings_frameRec)); f->next = frameHead; f->alloc = NULL; f->dealloc = NULL; frameHead = f; } } /* PopAllocation - test to see that all strings are deallocated since the last push. Then it pops to the previous allocation/deallocation lists. If halt is true then the application terminates with an exit code of 1. */ extern "C" void DynamicStrings_PopAllocation (bool halt) { if (CheckOn) { if ((DynamicStrings_PopAllocationExemption (halt, NULL)) == NULL) {} /* empty. */ } } /* PopAllocationExemption - test to see that all strings are deallocated, except string e since the last push. Post-condition: it pops to the previous allocation/deallocation lists. If halt is true then the application terminates with an exit code of 1. */ extern "C" DynamicStrings_String DynamicStrings_PopAllocationExemption (bool halt, DynamicStrings_String e) { DynamicStrings_String s; bool b; Init (); if (CheckOn) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (frameHead == NULL) { stop (); M2RTS_Halt ((const char *) "mismatched number of PopAllocation's compared to PushAllocation's", 65, (const char *) "../../gcc-read-write/gcc/m2/gm2-libs/DynamicStrings.mod", 55, (const char *) "PopAllocationExemption", 22, 174); } else { /* writeString ("mismatched number of PopAllocation's compared to PushAllocation's") */ if (frameHead->alloc != NULL) { b = false; s = frameHead->alloc; while (s != NULL) { if (! (((e == s) || (IsOnGarbage (e, s))) || (IsOnGarbage (s, e)))) { if (! b) { writeString ((const char *) "the following strings have been lost", 36); writeLn (); b = true; } DumpStringInfo (s, 0); } s = s->debug.next; } if (b && halt) { libc_exit (1); } } frameHead = frameHead->next; } } return e; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } extern "C" void _M2_DynamicStrings_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { Initialized = false; Init (); } extern "C" void _M2_DynamicStrings_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { }