| /* do not edit automatically generated by mc from DynamicStrings. */ |
| /* DynamicStrings.mod provides a dynamic string type and procedures. |
| |
| Copyright (C) 2001-2025 Free Software Foundation, Inc. |
| Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. |
| |
| 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 |
| <http://www.gnu.org/licenses/>. */ |
| |
| #include "config.h" |
| #include "system.h" |
| #include <stdbool.h> |
| # 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 "GStorage.h" |
| #if defined(__cplusplus) |
| # undef NULL |
| # define NULL 0 |
| #endif |
| #define _DynamicStrings_C |
| |
| #include "GDynamicStrings.h" |
| # 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__opaque; |
| |
| struct DynamicStrings_DebugInfo_r { |
| DynamicStrings_String__opaque 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__opaque garbage; |
| }; |
| |
| struct DynamicStrings_frameRec_r { |
| DynamicStrings_String__opaque alloc; |
| DynamicStrings_String__opaque 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__opaque next; |
| }; |
| |
| struct DynamicStrings_stringRecord_r { |
| DynamicStrings_Contents contents; |
| DynamicStrings_Descriptor head; |
| DynamicStrings_DebugInfo debug; |
| }; |
| |
| static bool Initialized; |
| static DynamicStrings_frame frameHead; |
| static DynamicStrings_String__opaque 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); |
| |
| /* |
| ReplaceChar - returns string s after it has changed all occurances of from to to. |
| */ |
| |
| extern "C" DynamicStrings_String DynamicStrings_ReplaceChar (DynamicStrings_String s, char from, char to); |
| |
| /* |
| 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. The search |
| is performed left to right. |
| */ |
| |
| extern "C" int DynamicStrings_RIndex (DynamicStrings_String s, char ch, unsigned int o); |
| |
| /* |
| ReverseIndex - returns the indice of the last occurance of ch |
| in String s. The search starts at position o |
| and searches from right to left. The start position |
| may be indexed negatively from the right (-1 is the |
| last index). |
| The return value if ch is found will always be positive. |
| -1 is returned if ch is not found. |
| */ |
| |
| extern "C" int DynamicStrings_ReverseIndex (DynamicStrings_String s, char ch, 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__opaque s); |
| |
| /* |
| writeNspace - |
| */ |
| |
| static void writeNspace (unsigned int n); |
| |
| /* |
| DumpStringInfo - |
| */ |
| |
| static void DumpStringInfo (DynamicStrings_String__opaque s, unsigned int i); |
| |
| /* |
| DumpStringInfo - |
| */ |
| |
| static void stop (void); |
| |
| /* |
| doDSdbEnter - |
| */ |
| |
| static void doDSdbEnter (void); |
| |
| /* |
| doDSdbExit - |
| */ |
| |
| static void doDSdbExit (DynamicStrings_String__opaque s); |
| |
| /* |
| DSdbEnter - |
| */ |
| |
| static void DSdbEnter (void); |
| |
| /* |
| DSdbExit - |
| */ |
| |
| static void DSdbExit (DynamicStrings_String__opaque s); |
| static unsigned int Capture (DynamicStrings_String__opaque 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__opaque AssignDebug (DynamicStrings_String__opaque 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__opaque list, DynamicStrings_String__opaque s); |
| |
| /* |
| AddTo - adds string, s, to, list. |
| */ |
| |
| static void AddTo (DynamicStrings_String__opaque *list, DynamicStrings_String__opaque s); |
| |
| /* |
| SubFrom - removes string, s, from, list. |
| */ |
| |
| static void SubFrom (DynamicStrings_String__opaque *list, DynamicStrings_String__opaque s); |
| |
| /* |
| AddAllocated - adds string, s, to the head of the allocated list. |
| */ |
| |
| static void AddAllocated (DynamicStrings_String__opaque s); |
| |
| /* |
| AddDeallocated - adds string, s, to the head of the deallocated list. |
| */ |
| |
| static void AddDeallocated (DynamicStrings_String__opaque s); |
| |
| /* |
| IsOnAllocated - returns TRUE if the string, s, has ever been allocated. |
| */ |
| |
| static bool IsOnAllocated (DynamicStrings_String__opaque s); |
| |
| /* |
| IsOnDeallocated - returns TRUE if the string, s, has ever been deallocated. |
| */ |
| |
| static bool IsOnDeallocated (DynamicStrings_String__opaque s); |
| |
| /* |
| SubAllocated - removes string, s, from the list of allocated strings. |
| */ |
| |
| static void SubAllocated (DynamicStrings_String__opaque s); |
| |
| /* |
| SubDeallocated - removes string, s, from the list of deallocated strings. |
| */ |
| |
| static void SubDeallocated (DynamicStrings_String__opaque s); |
| |
| /* |
| SubDebugInfo - removes string, s, from the list of allocated strings. |
| */ |
| |
| static void SubDebugInfo (DynamicStrings_String__opaque s); |
| |
| /* |
| AddDebugInfo - adds string, s, to the list of allocated strings. |
| */ |
| |
| static void AddDebugInfo (DynamicStrings_String__opaque 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__opaque s); |
| |
| /* |
| CheckPoisoned - checks for a poisoned string, s. |
| */ |
| |
| static DynamicStrings_String__opaque CheckPoisoned (DynamicStrings_String__opaque s); |
| |
| /* |
| MarkInvalid - marks the char * version of String, s, as invalid. |
| */ |
| |
| static void MarkInvalid (DynamicStrings_String__opaque 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__opaque AddToGarbage (DynamicStrings_String__opaque a, DynamicStrings_String__opaque b); |
| |
| /* |
| IsOnGarbage - returns TRUE if, s, is on string, e, garbage list. |
| */ |
| |
| static bool IsOnGarbage (DynamicStrings_String__opaque e, DynamicStrings_String__opaque s); |
| |
| /* |
| IsWhite - returns TRUE if, ch, is a space or a tab. |
| */ |
| |
| static bool IsWhite (char ch); |
| |
| /* |
| DumpState - |
| */ |
| |
| static void DumpState (DynamicStrings_String__opaque s); |
| |
| /* |
| DumpStringSynopsis - |
| */ |
| |
| static void DumpStringSynopsis (DynamicStrings_String__opaque s); |
| |
| /* |
| DumpString - displays the contents of string, s. |
| */ |
| |
| static void DumpString (DynamicStrings_String__opaque s); |
| |
| /* |
| Init - initialize the module. |
| */ |
| |
| static void Init (void); |
| |
| |
| /* |
| writeStringDesc write out debugging information about string, s. */ |
| |
| static void writeStringDesc (DynamicStrings_String__opaque 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 <void *> (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__opaque 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__opaque s) |
| { |
| if (CheckOn) |
| { |
| s = static_cast<DynamicStrings_String__opaque> (DynamicStrings_PopAllocationExemption (true, static_cast<DynamicStrings_String> (s))); |
| } |
| } |
| |
| |
| /* |
| DSdbEnter - |
| */ |
| |
| static void DSdbEnter (void) |
| { |
| } |
| |
| |
| /* |
| DSdbExit - |
| */ |
| |
| static void DSdbExit (DynamicStrings_String__opaque s) |
| { |
| } |
| |
| static unsigned int Capture (DynamicStrings_String__opaque 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<int> (libc_write (1, const_cast<void*> (static_cast<const void*>(a)), static_cast<size_t> (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<int> (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<int> (libc_write (1, &ch, static_cast<size_t> (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<int> (libc_write (1, &ch, static_cast<size_t> (1))); |
| } |
| else if (l < 16) |
| { |
| /* avoid dangling else. */ |
| ch = ((char) (( ((unsigned int) ('a'))+((unsigned int ) (l)))-10)); |
| i = static_cast<int> (libc_write (1, &ch, static_cast<size_t> (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<size_t> (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<int> (libc_write (1, &ch, static_cast<size_t> (1))); |
| } |
| |
| |
| /* |
| AssignDebug - assigns, file, and, line, information to string, s. |
| */ |
| |
| static DynamicStrings_String__opaque AssignDebug (DynamicStrings_String__opaque 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 = const_cast<void*> (static_cast<const void*>(file)); |
| p = const_cast<void*> (static_cast<const void*>(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__opaque list, DynamicStrings_String__opaque 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__opaque *list, DynamicStrings_String__opaque s) |
| { |
| if ((*list) == NULL) |
| { |
| (*list) = s; |
| s->debug.next = static_cast<DynamicStrings_String__opaque> (NULL); |
| } |
| else |
| { |
| s->debug.next = (*list); |
| (*list) = s; |
| } |
| } |
| |
| |
| /* |
| SubFrom - removes string, s, from, list. |
| */ |
| |
| static void SubFrom (DynamicStrings_String__opaque *list, DynamicStrings_String__opaque s) |
| { |
| DynamicStrings_String__opaque 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 = static_cast<DynamicStrings_String__opaque> (NULL); |
| } |
| |
| |
| /* |
| AddAllocated - adds string, s, to the head of the allocated list. |
| */ |
| |
| static void AddAllocated (DynamicStrings_String__opaque s) |
| { |
| Init (); |
| AddTo (&frameHead->alloc, s); |
| } |
| |
| |
| /* |
| AddDeallocated - adds string, s, to the head of the deallocated list. |
| */ |
| |
| static void AddDeallocated (DynamicStrings_String__opaque s) |
| { |
| Init (); |
| AddTo (&frameHead->dealloc, s); |
| } |
| |
| |
| /* |
| IsOnAllocated - returns TRUE if the string, s, has ever been allocated. |
| */ |
| |
| static bool IsOnAllocated (DynamicStrings_String__opaque 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__opaque 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__opaque 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__opaque 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__opaque 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__opaque s) |
| { |
| s->debug.next = static_cast<DynamicStrings_String__opaque> (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 = static_cast<DynamicStrings_String__opaque> (NULL); |
| ConcatContents (&(*c).next->contents, (const char *) a, _a_high, h, o); |
| AddDebugInfo ((*c).next); |
| (*c).next = AssignDebug ((*c).next, (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 722, (const char *) "ConcatContents", 14); |
| } |
| else |
| { |
| (*c).len = i; |
| } |
| } |
| |
| |
| /* |
| DeallocateCharStar - deallocates any charStar. |
| */ |
| |
| static void DeallocateCharStar (DynamicStrings_String__opaque 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__opaque CheckPoisoned (DynamicStrings_String__opaque 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__opaque 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<ConcatContentsAddress__T1> (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 = static_cast<DynamicStrings_String__opaque> (NULL); |
| ConcatContentsAddress (&(*c).next->contents, reinterpret_cast <void *> (p), h-j); |
| AddDebugInfo ((*c).next); |
| if (TraceOn) |
| { |
| (*c).next = AssignDebug ((*c).next, (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 917, (const char *) "ConcatContentsAddress", 21); |
| } |
| } |
| else |
| { |
| (*c).len = i; |
| (*c).next = static_cast<DynamicStrings_String__opaque> (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__opaque AddToGarbage (DynamicStrings_String__opaque a, DynamicStrings_String__opaque b) |
| { |
| DynamicStrings_String__opaque 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__opaque e, DynamicStrings_String__opaque 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__opaque 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__opaque 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 <void *> (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__opaque s) |
| { |
| DynamicStrings_String__opaque 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__opaque 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 = static_cast<DynamicStrings_String__opaque> (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 = static_cast<DynamicStrings_String__opaque> (NULL); |
| s->head->state = DynamicStrings_inuse; |
| AddDebugInfo (s); |
| if (TraceOn) |
| { |
| s = AssignDebug (s, (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 758, (const char *) "InitString", 10); |
| } |
| return static_cast<DynamicStrings_String> (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__opaque t; |
| |
| if (PoisonOn) |
| { |
| s = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| if (s != NULL) |
| { |
| if (CheckOn) |
| { |
| /* avoid gcc warning by using compound statement even if not strictly necessary. */ |
| if (IsOnAllocated (static_cast<DynamicStrings_String__opaque> (s))) |
| { |
| SubAllocated (static_cast<DynamicStrings_String__opaque> (s)); |
| } |
| else if (IsOnDeallocated (static_cast<DynamicStrings_String__opaque> (s))) |
| { |
| /* avoid dangling else. */ |
| SubDeallocated (static_cast<DynamicStrings_String__opaque> (s)); |
| } |
| } |
| if (static_cast<DynamicStrings_String__opaque> (s)->head != NULL) |
| { |
| static_cast<DynamicStrings_String__opaque> (s)->head->state = DynamicStrings_poisoned; |
| static_cast<DynamicStrings_String__opaque> (s)->head->garbage = static_cast<DynamicStrings_String__opaque> (DynamicStrings_KillString (static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (s)->head->garbage))); |
| if (! PoisonOn) |
| { |
| DeallocateCharStar (static_cast<DynamicStrings_String__opaque> (s)); |
| } |
| if (! PoisonOn) |
| { |
| Storage_DEALLOCATE ((void **) &static_cast<DynamicStrings_String__opaque> (s)->head, sizeof (DynamicStrings_descriptor)); |
| static_cast<DynamicStrings_String__opaque> (s)->head = NULL; |
| } |
| } |
| t = static_cast<DynamicStrings_String__opaque> (DynamicStrings_KillString (static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (s)->contents.next))); |
| if (! PoisonOn) |
| { |
| Storage_DEALLOCATE ((void **) &s, sizeof (DynamicStrings_stringRecord)); |
| } |
| } |
| return static_cast<DynamicStrings_String> (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__opaque s; |
| |
| Storage_ALLOCATE ((void **) &s, sizeof (DynamicStrings_stringRecord)); |
| s->contents.len = 0; |
| s->contents.next = static_cast<DynamicStrings_String__opaque> (NULL); |
| if (a != NULL) |
| { |
| ConcatContentsAddress (&s->contents, a, static_cast<unsigned int> (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 = static_cast<DynamicStrings_String__opaque> (NULL); |
| s->head->state = DynamicStrings_inuse; |
| AddDebugInfo (s); |
| if (TraceOn) |
| { |
| s = AssignDebug (s, (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 957, (const char *) "InitStringCharStar", 18); |
| } |
| return static_cast<DynamicStrings_String> (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__opaque s; |
| |
| a.array[0] = ch; |
| a.array[1] = ASCII_nul; |
| s = static_cast<DynamicStrings_String__opaque> (DynamicStrings_InitString ((const char *) &a.array[0], 1)); |
| if (TraceOn) |
| { |
| s = AssignDebug (s, (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 977, (const char *) "InitStringChar", 14); |
| } |
| return static_cast<DynamicStrings_String> (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 = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| if ((s != NULL) && (static_cast<DynamicStrings_String__opaque> (s)->head->state == DynamicStrings_inuse)) |
| { |
| static_cast<DynamicStrings_String__opaque> (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 static_cast<DynamicStrings_String__opaque> (s)->contents.len+(DynamicStrings_Length (static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (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__opaque t; |
| |
| if (PoisonOn) |
| { |
| a = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (a))); |
| b = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (b))); |
| } |
| if (a == b) |
| { |
| return DynamicStrings_ConCat (a, DynamicStrings_Mark (DynamicStrings_Dup (b))); |
| } |
| else if (a != NULL) |
| { |
| /* avoid dangling else. */ |
| a = static_cast<DynamicStrings_String> (AddToGarbage (static_cast<DynamicStrings_String__opaque> (a), static_cast<DynamicStrings_String__opaque> (b))); |
| MarkInvalid (static_cast<DynamicStrings_String__opaque> (a)); |
| t = static_cast<DynamicStrings_String__opaque> (a); |
| while (b != NULL) |
| { |
| while ((t->contents.len == MaxBuf) && (t->contents.next != NULL)) |
| { |
| t = t->contents.next; |
| } |
| ConcatContents (&t->contents, (const char *) &static_cast<DynamicStrings_String__opaque> (b)->contents.buf.array[0], (MaxBuf-1), static_cast<DynamicStrings_String__opaque> (b)->contents.len, 0); |
| b = static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (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__opaque t; |
| |
| if (PoisonOn) |
| { |
| a = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (a))); |
| } |
| b.array[0] = ch; |
| b.array[1] = ASCII_nul; |
| t = static_cast<DynamicStrings_String__opaque> (a); |
| MarkInvalid (static_cast<DynamicStrings_String__opaque> (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 = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (a))); |
| b = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (b))); |
| } |
| if ((a != NULL) && (b != NULL)) |
| { |
| static_cast<DynamicStrings_String__opaque> (a)->contents.next = static_cast<DynamicStrings_String__opaque> (DynamicStrings_KillString (static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (a)->contents.next))); |
| static_cast<DynamicStrings_String__opaque> (a)->contents.len = 0; |
| } |
| return DynamicStrings_ConCat (a, b); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| ReplaceChar - returns string s after it has changed all occurances of from to to. |
| */ |
| |
| extern "C" DynamicStrings_String DynamicStrings_ReplaceChar (DynamicStrings_String s, char from, char to) |
| { |
| DynamicStrings_String__opaque t; |
| unsigned int i; |
| |
| t = static_cast<DynamicStrings_String__opaque> (s); |
| while (t != NULL) |
| { |
| i = 0; |
| while (i < t->contents.len) |
| { |
| if (t->contents.buf.array[i] == from) |
| { |
| t->contents.buf.array[i] = to; |
| } |
| i += 1; |
| } |
| t = t->contents.next; |
| } |
| return s; |
| /* 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 = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| s = DynamicStrings_Assign (DynamicStrings_InitString ((const char *) "", 0), s); |
| if (TraceOn) |
| { |
| s = static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (s), (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1198, (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 = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (a))); |
| b = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (b))); |
| } |
| a = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "", 0), a), b); |
| if (TraceOn) |
| { |
| a = static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (a), (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1218, (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 = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (a))); |
| b = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (b))); |
| } |
| if ((DynamicStrings_Length (a)) == (DynamicStrings_Length (b))) |
| { |
| while ((a != NULL) && (b != NULL)) |
| { |
| i = 0; |
| Assertion_Assert (static_cast<DynamicStrings_String__opaque> (a)->contents.len == static_cast<DynamicStrings_String__opaque> (b)->contents.len); |
| while (i < static_cast<DynamicStrings_String__opaque> (a)->contents.len) |
| { |
| if (static_cast<DynamicStrings_String__opaque> (a)->contents.buf.array[i] != static_cast<DynamicStrings_String__opaque> (b)->contents.buf.array[i]) |
| { |
| return false; |
| } |
| i += 1; |
| } |
| a = static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (a)->contents.next); |
| b = static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (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__opaque t; |
| |
| if (PoisonOn) |
| { |
| s = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| t = static_cast<DynamicStrings_String__opaque> (DynamicStrings_InitStringCharStar (a)); |
| if (TraceOn) |
| { |
| t = AssignDebug (t, (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1275, (const char *) "EqualCharStar", 13); |
| } |
| t = AddToGarbage (t, static_cast<DynamicStrings_String__opaque> (s)); |
| if (DynamicStrings_Equal (static_cast<DynamicStrings_String> (t), s)) |
| { |
| t = static_cast<DynamicStrings_String__opaque> (DynamicStrings_KillString (static_cast<DynamicStrings_String> (t))); |
| return true; |
| } |
| else |
| { |
| t = static_cast<DynamicStrings_String__opaque> (DynamicStrings_KillString (static_cast<DynamicStrings_String> (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__opaque t; |
| char a[_a_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (a, a_, _a_high+1); |
| |
| if (PoisonOn) |
| { |
| s = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| t = static_cast<DynamicStrings_String__opaque> (DynamicStrings_InitString ((const char *) a, _a_high)); |
| if (TraceOn) |
| { |
| t = AssignDebug (t, (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1305, (const char *) "EqualArray", 10); |
| } |
| t = AddToGarbage (t, static_cast<DynamicStrings_String__opaque> (s)); |
| if (DynamicStrings_Equal (static_cast<DynamicStrings_String> (t), s)) |
| { |
| t = static_cast<DynamicStrings_String__opaque> (DynamicStrings_KillString (static_cast<DynamicStrings_String> (t))); |
| return true; |
| } |
| else |
| { |
| t = static_cast<DynamicStrings_String__opaque> (DynamicStrings_KillString (static_cast<DynamicStrings_String> (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 = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| if (n <= 0) |
| { |
| s = static_cast<DynamicStrings_String> (AddToGarbage (static_cast<DynamicStrings_String__opaque> (DynamicStrings_InitString ((const char *) "", 0)), static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| else |
| { |
| s = DynamicStrings_ConCat (DynamicStrings_Mult (s, n-1), s); |
| } |
| if (TraceOn) |
| { |
| s = static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (s), (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1337, (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__opaque d; |
| DynamicStrings_String__opaque t; |
| int start; |
| int stop; |
| int o; |
| |
| if (PoisonOn) |
| { |
| s = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (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<unsigned int> (high)); |
| } |
| d = static_cast<DynamicStrings_String__opaque> (DynamicStrings_InitString ((const char *) "", 0)); |
| d = AddToGarbage (d, static_cast<DynamicStrings_String__opaque> (s)); |
| o = 0; |
| t = d; |
| while (s != NULL) |
| { |
| if (low < (o+((int ) (static_cast<DynamicStrings_String__opaque> (s)->contents.len)))) |
| { |
| if (o > high) |
| { |
| s = static_cast<DynamicStrings_String> (NULL); |
| } |
| else |
| { |
| /* found sliceable unit */ |
| if (low < o) |
| { |
| start = 0; |
| } |
| else |
| { |
| start = low-o; |
| } |
| stop = Max (Min (MaxBuf, static_cast<unsigned int> (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/m2/gm2-libs/DynamicStrings.mod", 40, 1405, (const char *) "Slice", 5); |
| } |
| } |
| t = t->contents.next; |
| } |
| ConcatContentsAddress (&t->contents, &static_cast<DynamicStrings_String__opaque> (s)->contents.buf.array[start], static_cast<unsigned int> (stop-start)); |
| o += static_cast<DynamicStrings_String__opaque> (s)->contents.len; |
| s = static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (s)->contents.next); |
| } |
| } |
| else |
| { |
| o += static_cast<DynamicStrings_String__opaque> (s)->contents.len; |
| s = static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (s)->contents.next); |
| } |
| } |
| if (TraceOn) |
| { |
| d = AssignDebug (d, (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1422, (const char *) "Slice", 5); |
| } |
| return static_cast<DynamicStrings_String> (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 = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| k = 0; |
| while (s != NULL) |
| { |
| if ((k+static_cast<DynamicStrings_String__opaque> (s)->contents.len) < o) |
| { |
| k += static_cast<DynamicStrings_String__opaque> (s)->contents.len; |
| } |
| else |
| { |
| i = o-k; |
| while (i < static_cast<DynamicStrings_String__opaque> (s)->contents.len) |
| { |
| if (static_cast<DynamicStrings_String__opaque> (s)->contents.buf.array[i] == ch) |
| { |
| return k+i; |
| } |
| i += 1; |
| } |
| k += i; |
| o = k; |
| } |
| s = static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (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. The search |
| is performed left to right. |
| */ |
| |
| extern "C" int DynamicStrings_RIndex (DynamicStrings_String s, char ch, unsigned int o) |
| { |
| unsigned int i; |
| unsigned int k; |
| int j; |
| |
| if (PoisonOn) |
| { |
| s = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| j = -1; |
| k = 0; |
| while (s != NULL) |
| { |
| if ((k+static_cast<DynamicStrings_String__opaque> (s)->contents.len) < o) |
| { |
| k += static_cast<DynamicStrings_String__opaque> (s)->contents.len; |
| } |
| else |
| { |
| if (o < k) |
| { |
| i = 0; |
| } |
| else |
| { |
| i = o-k; |
| } |
| while (i < static_cast<DynamicStrings_String__opaque> (s)->contents.len) |
| { |
| if (static_cast<DynamicStrings_String__opaque> (s)->contents.buf.array[i] == ch) |
| { |
| j = k; |
| } |
| k += 1; |
| i += 1; |
| } |
| } |
| s = static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (s)->contents.next); |
| } |
| return j; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| ReverseIndex - returns the indice of the last occurance of ch |
| in String s. The search starts at position o |
| and searches from right to left. The start position |
| may be indexed negatively from the right (-1 is the |
| last index). |
| The return value if ch is found will always be positive. |
| -1 is returned if ch is not found. |
| */ |
| |
| extern "C" int DynamicStrings_ReverseIndex (DynamicStrings_String s, char ch, int o) |
| { |
| unsigned int c; |
| |
| if (PoisonOn) |
| { |
| s = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| if (o < 0) |
| { |
| o = ((int ) (DynamicStrings_Length (s)))+o; |
| if (o < 0) |
| { |
| return -1; |
| } |
| } |
| if (((unsigned int ) (o)) < (DynamicStrings_Length (s))) |
| { |
| while (o >= 0) |
| { |
| if ((DynamicStrings_char (s, o)) == ch) |
| { |
| return o; |
| } |
| else |
| { |
| o -= 1; |
| } |
| } |
| } |
| return -1; |
| /* 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 = static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (s), (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1576, (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<int> (i)))) |
| { |
| i += 1; |
| } |
| s = DynamicStrings_Slice (s, (int ) (i), 0); |
| if (TraceOn) |
| { |
| s = static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (s), (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1688, (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 = static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (s), (const char *) "../../gcc/m2/gm2-libs/DynamicStrings.mod", 40, 1710, (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__opaque t; |
| |
| if (s != NULL) |
| { |
| MarkInvalid (static_cast<DynamicStrings_String__opaque> (s)); |
| t = static_cast<DynamicStrings_String__opaque> (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__opaque t; |
| |
| if (s != NULL) |
| { |
| MarkInvalid (static_cast<DynamicStrings_String__opaque> (s)); |
| t = static_cast<DynamicStrings_String__opaque> (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) |
| { |
| const_cast<char *>(a)[i] = DynamicStrings_char (s, static_cast<int> (i)); |
| i += 1; |
| } |
| if (i <= _a_high) |
| { |
| const_cast<char *>(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 = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| if (i < 0) |
| { |
| c = (unsigned int ) (((int ) (DynamicStrings_Length (s)))+i); |
| } |
| else |
| { |
| c = i; |
| } |
| while ((s != NULL) && (c >= static_cast<DynamicStrings_String__opaque> (s)->contents.len)) |
| { |
| c -= static_cast<DynamicStrings_String__opaque> (s)->contents.len; |
| s = static_cast<DynamicStrings_String> (static_cast<DynamicStrings_String__opaque> (s)->contents.next); |
| } |
| if ((s == NULL) || (c >= static_cast<DynamicStrings_String__opaque> (s)->contents.len)) |
| { |
| return ASCII_nul; |
| } |
| else |
| { |
| return static_cast<DynamicStrings_String__opaque> (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__opaque a; |
| unsigned int l; |
| unsigned int i; |
| string__T2 p; |
| |
| if (PoisonOn) |
| { |
| s = static_cast<DynamicStrings_String> (CheckPoisoned (static_cast<DynamicStrings_String__opaque> (s))); |
| } |
| if (s == NULL) |
| { |
| return NULL; |
| } |
| else |
| { |
| if (! static_cast<DynamicStrings_String__opaque> (s)->head->charStarValid) |
| { |
| l = DynamicStrings_Length (s); |
| if (! (static_cast<DynamicStrings_String__opaque> (s)->head->charStarUsed && (static_cast<DynamicStrings_String__opaque> (s)->head->charStarSize > l))) |
| { |
| DeallocateCharStar (static_cast<DynamicStrings_String__opaque> (s)); |
| Storage_ALLOCATE (&static_cast<DynamicStrings_String__opaque> (s)->head->charStar, l+1); |
| static_cast<DynamicStrings_String__opaque> (s)->head->charStarSize = l+1; |
| static_cast<DynamicStrings_String__opaque> (s)->head->charStarUsed = true; |
| } |
| p = static_cast<string__T2> (static_cast<DynamicStrings_String__opaque> (s)->head->charStar); |
| a = static_cast<DynamicStrings_String__opaque> (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; |
| static_cast<DynamicStrings_String__opaque> (s)->head->charStarValid = true; |
| } |
| return static_cast<DynamicStrings_String__opaque> (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 static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (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 static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (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 static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (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 static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (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 static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (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 = static_cast<DynamicStrings_String> (AssignDebug (static_cast<DynamicStrings_String__opaque> (DynamicStrings_Slice (s, low, high)), (const char *) file, _file_high, line, (const char *) "Slice", 5)); |
| DSdbExit (static_cast<DynamicStrings_String__opaque> (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 = static_cast<DynamicStrings_String__opaque> (NULL); |
| f->dealloc = static_cast<DynamicStrings_String__opaque> (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, static_cast<DynamicStrings_String> (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__opaque 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/m2/gm2-libs/DynamicStrings.mod", 40, (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 (static_cast<DynamicStrings_String__opaque> (e), s))) || (IsOnGarbage (s, static_cast<DynamicStrings_String__opaque> (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[]) |
| { |
| } |