]> gcc.gnu.org Git - gcc.git/blame - gcc/m2/mc-boot/GDynamicStrings.c
Remove unused parameter warning via introducing attribute unused.
[gcc.git] / gcc / m2 / mc-boot / GDynamicStrings.c
CommitLineData
7401123f
GM
1/* do not edit automatically generated by mc from DynamicStrings. */
2/* DynamicStrings.mod provides a dynamic string type and procedures.
3
4Copyright (C) 2001-2021 Free Software Foundation, Inc.
5Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6
7This file is part of GNU Modula-2.
8
9GNU Modula-2 is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 3, or (at your option)
12any later version.
13
14GNU Modula-2 is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17General Public License for more details.
18
19Under Section 7 of GPL version 3, you are granted additional
20permissions described in the GCC Runtime Library Exception, version
213.1, as published by the Free Software Foundation.
22
23You should have received a copy of the GNU General Public License and
24a copy of the GCC Runtime Library Exception along with this program;
25see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26<http://www.gnu.org/licenses/>. */
27
28#include "config.h"
29#include "system.h"
30# if !defined (PROC_D)
31# define PROC_D
32 typedef void (*PROC_t) (void);
33 typedef struct { PROC_t proc; } PROC;
34# endif
35
36# if !defined (TRUE)
37# define TRUE (1==1)
38# endif
39
40# if !defined (FALSE)
41# define FALSE (1==0)
42# endif
43
44# include "GStorage.h"
45#if defined(__cplusplus)
46# undef NULL
47# define NULL 0
48#endif
49#define _DynamicStrings_H
50#define _DynamicStrings_C
51
52# include "Glibc.h"
53# include "GStrLib.h"
54# include "GStorage.h"
55# include "GAssertion.h"
56# include "GSYSTEM.h"
57# include "GASCII.h"
58# include "GM2RTS.h"
59
60# define MaxBuf 127
61# define PoisonOn FALSE
62# define DebugOn FALSE
63# define CheckOn FALSE
64# define TraceOn FALSE
65typedef struct Contents_r Contents;
66
67typedef struct DebugInfo_r DebugInfo;
68
69typedef struct stringRecord_r stringRecord;
70
71typedef struct descriptor_r descriptor;
72
73typedef descriptor *Descriptor;
74
75typedef struct frameRec_r frameRec;
76
77typedef frameRec *frame;
78
51bc4b81 79typedef struct _T3_a _T3;
7401123f
GM
80
81typedef enum {inuse, marked, onlist, poisoned} desState;
82
83typedef stringRecord *DynamicStrings_String;
84
85struct DebugInfo_r {
86 DynamicStrings_String next;
87 void *file;
88 unsigned int line;
89 void *proc;
90 };
91
92struct descriptor_r {
93 unsigned int charStarUsed;
94 void *charStar;
95 unsigned int charStarSize;
96 unsigned int charStarValid;
97 desState state;
98 DynamicStrings_String garbage;
99 };
100
101struct frameRec_r {
102 DynamicStrings_String alloc;
103 DynamicStrings_String dealloc;
104 frame next;
105 };
106
51bc4b81 107struct _T3_a { char array[(MaxBuf-1)+1]; };
7401123f 108struct Contents_r {
51bc4b81 109 _T3 buf;
7401123f
GM
110 unsigned int len;
111 DynamicStrings_String next;
112 };
113
114struct stringRecord_r {
115 Contents contents;
116 Descriptor head;
117 DebugInfo debug;
118 };
119
120static unsigned int Initialized;
121static frame frameHead;
122static DynamicStrings_String captured;
123
124/*
125 InitString - creates and returns a String type object.
126 Initial contents are, a.
127*/
128
51bc4b81 129extern "C" DynamicStrings_String DynamicStrings_InitString (const char *a_, unsigned int _a_high);
7401123f
GM
130
131/*
132 KillString - frees String, s, and its contents.
133 NIL is returned.
134*/
135
51bc4b81 136extern "C" DynamicStrings_String DynamicStrings_KillString (DynamicStrings_String s);
7401123f
GM
137
138/*
139 Fin - finishes with a string, it calls KillString with, s.
140 The purpose of the procedure is to provide a short cut
141 to calling KillString and then testing the return result.
142*/
143
51bc4b81 144extern "C" void DynamicStrings_Fin (DynamicStrings_String s);
7401123f
GM
145
146/*
147 InitStringCharStar - initializes and returns a String to contain the C string.
148*/
149
51bc4b81 150extern "C" DynamicStrings_String DynamicStrings_InitStringCharStar (void * a);
7401123f
GM
151
152/*
153 InitStringChar - initializes and returns a String to contain the single character, ch.
154*/
155
51bc4b81 156extern "C" DynamicStrings_String DynamicStrings_InitStringChar (char ch);
7401123f
GM
157
158/*
159 Mark - marks String, s, ready for garbage collection.
160*/
161
51bc4b81 162extern "C" DynamicStrings_String DynamicStrings_Mark (DynamicStrings_String s);
7401123f
GM
163
164/*
165 Length - returns the length of the String, s.
166*/
167
51bc4b81 168extern "C" unsigned int DynamicStrings_Length (DynamicStrings_String s);
7401123f
GM
169
170/*
171 ConCat - returns String, a, after the contents of, b, have been appended.
172*/
173
51bc4b81 174extern "C" DynamicStrings_String DynamicStrings_ConCat (DynamicStrings_String a, DynamicStrings_String b);
7401123f
GM
175
176/*
177 ConCatChar - returns String, a, after character, ch, has been appended.
178*/
179
51bc4b81 180extern "C" DynamicStrings_String DynamicStrings_ConCatChar (DynamicStrings_String a, char ch);
7401123f
GM
181
182/*
183 Assign - assigns the contents of, b, into, a.
184 String, a, is returned.
185*/
186
51bc4b81 187extern "C" DynamicStrings_String DynamicStrings_Assign (DynamicStrings_String a, DynamicStrings_String b);
7401123f
GM
188
189/*
190 Dup - duplicate a String, s, returning the copy of s.
191*/
192
51bc4b81 193extern "C" DynamicStrings_String DynamicStrings_Dup (DynamicStrings_String s);
7401123f
GM
194
195/*
196 Add - returns a new String which contains the contents of a and b.
197*/
198
51bc4b81 199extern "C" DynamicStrings_String DynamicStrings_Add (DynamicStrings_String a, DynamicStrings_String b);
7401123f
GM
200
201/*
202 Equal - returns TRUE if String, a, and, b, are equal.
203*/
204
51bc4b81 205extern "C" unsigned int DynamicStrings_Equal (DynamicStrings_String a, DynamicStrings_String b);
7401123f
GM
206
207/*
208 EqualCharStar - returns TRUE if contents of String, s, is the same as the
209 string, a.
210*/
211
51bc4b81 212extern "C" unsigned int DynamicStrings_EqualCharStar (DynamicStrings_String s, void * a);
7401123f
GM
213
214/*
215 EqualArray - returns TRUE if contents of String, s, is the same as the
216 string, a.
217*/
218
51bc4b81 219extern "C" unsigned int DynamicStrings_EqualArray (DynamicStrings_String s, const char *a_, unsigned int _a_high);
7401123f
GM
220
221/*
222 Mult - returns a new string which is n concatenations of String, s.
223*/
224
51bc4b81 225extern "C" DynamicStrings_String DynamicStrings_Mult (DynamicStrings_String s, unsigned int n);
7401123f
GM
226
227/*
228 Slice - returns a new string which contains the elements
229 low..high-1
230
231 strings start at element 0
232 Slice(s, 0, 2) will return elements 0, 1 but not 2
233 Slice(s, 1, 3) will return elements 1, 2 but not 3
234 Slice(s, 2, 0) will return elements 2..max
235 Slice(s, 3, -1) will return elements 3..max-1
236 Slice(s, 4, -2) will return elements 4..max-2
237*/
238
51bc4b81 239extern "C" DynamicStrings_String DynamicStrings_Slice (DynamicStrings_String s, int low, int high);
7401123f
GM
240
241/*
242 Index - returns the indice of the first occurance of, ch, in
243 String, s. -1 is returned if, ch, does not exist.
244 The search starts at position, o.
245*/
246
51bc4b81 247extern "C" int DynamicStrings_Index (DynamicStrings_String s, char ch, unsigned int o);
7401123f
GM
248
249/*
250 RIndex - returns the indice of the last occurance of, ch,
251 in String, s. The search starts at position, o.
252 -1 is returned if, ch, is not found.
253*/
254
51bc4b81 255extern "C" int DynamicStrings_RIndex (DynamicStrings_String s, char ch, unsigned int o);
7401123f
GM
256
257/*
258 RemoveComment - assuming that, comment, is a comment delimiter
259 which indicates anything to its right is a comment
260 then strip off the comment and also any white space
261 on the remaining right hand side.
262 It leaves any white space on the left hand side alone.
263*/
264
51bc4b81 265extern "C" DynamicStrings_String DynamicStrings_RemoveComment (DynamicStrings_String s, char comment);
7401123f
GM
266
267/*
268 RemoveWhitePrefix - removes any leading white space from String, s.
269 A new string is returned.
270*/
271
51bc4b81 272extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePrefix (DynamicStrings_String s);
7401123f
GM
273
274/*
275 RemoveWhitePostfix - removes any leading white space from String, s.
276 A new string is returned.
277*/
278
51bc4b81 279extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePostfix (DynamicStrings_String s);
7401123f
GM
280
281/*
282 ToUpper - returns string, s, after it has had its lower case characters
283 replaced by upper case characters.
284 The string, s, is not duplicated.
285*/
286
51bc4b81 287extern "C" DynamicStrings_String DynamicStrings_ToUpper (DynamicStrings_String s);
7401123f
GM
288
289/*
290 ToLower - returns string, s, after it has had its upper case characters
291 replaced by lower case characters.
292 The string, s, is not duplicated.
293*/
294
51bc4b81 295extern "C" DynamicStrings_String DynamicStrings_ToLower (DynamicStrings_String s);
7401123f
GM
296
297/*
298 CopyOut - copies string, s, to a.
299*/
300
51bc4b81 301extern "C" void DynamicStrings_CopyOut (char *a, unsigned int _a_high, DynamicStrings_String s);
7401123f
GM
302
303/*
304 char - returns the character, ch, at position, i, in String, s.
305*/
306
51bc4b81 307extern "C" char DynamicStrings_char (DynamicStrings_String s, int i);
7401123f
GM
308
309/*
310 string - returns the C style char * of String, s.
311*/
312
51bc4b81 313extern "C" void * DynamicStrings_string (DynamicStrings_String s);
7401123f
GM
314
315/*
316 InitStringDB - the debug version of InitString.
317*/
318
51bc4b81 319extern "C" DynamicStrings_String DynamicStrings_InitStringDB (const char *a_, unsigned int _a_high, const char *file_, unsigned int _file_high, unsigned int line);
7401123f
GM
320
321/*
322 InitStringCharStarDB - the debug version of InitStringCharStar.
323*/
324
51bc4b81 325extern "C" DynamicStrings_String DynamicStrings_InitStringCharStarDB (void * a, const char *file_, unsigned int _file_high, unsigned int line);
7401123f
GM
326
327/*
328 InitStringCharDB - the debug version of InitStringChar.
329*/
330
51bc4b81 331extern "C" DynamicStrings_String DynamicStrings_InitStringCharDB (char ch, const char *file_, unsigned int _file_high, unsigned int line);
7401123f
GM
332
333/*
334 MultDB - the debug version of MultDB.
335*/
336
51bc4b81 337extern "C" DynamicStrings_String DynamicStrings_MultDB (DynamicStrings_String s, unsigned int n, const char *file_, unsigned int _file_high, unsigned int line);
7401123f
GM
338
339/*
340 DupDB - the debug version of Dup.
341*/
342
51bc4b81 343extern "C" DynamicStrings_String DynamicStrings_DupDB (DynamicStrings_String s, const char *file_, unsigned int _file_high, unsigned int line);
7401123f
GM
344
345/*
346 SliceDB - debug version of Slice.
347*/
348
51bc4b81 349extern "C" DynamicStrings_String DynamicStrings_SliceDB (DynamicStrings_String s, int low, int high, const char *file_, unsigned int _file_high, unsigned int line);
7401123f
GM
350
351/*
352 PushAllocation - pushes the current allocation/deallocation lists.
353*/
354
51bc4b81 355extern "C" void DynamicStrings_PushAllocation (void);
7401123f
GM
356
357/*
358 PopAllocation - test to see that all strings are deallocated since
359 the last push. Then it pops to the previous
360 allocation/deallocation lists.
361
362 If halt is true then the application terminates
363 with an exit code of 1.
364*/
365
51bc4b81 366extern "C" void DynamicStrings_PopAllocation (unsigned int halt);
7401123f
GM
367
368/*
369 PopAllocationExemption - test to see that all strings are deallocated, except
370 string, e, since the last push.
371 Then it pops to the previous allocation/deallocation
372 lists.
373
374 If halt is true then the application terminates
375 with an exit code of 1.
376*/
377
51bc4b81 378extern "C" DynamicStrings_String DynamicStrings_PopAllocationExemption (unsigned int halt, DynamicStrings_String e);
7401123f
GM
379
380/*
381 writeStringDesc write out debugging information about string, s. */
382
383static void writeStringDesc (DynamicStrings_String s);
384
385/*
386 writeNspace -
387*/
388
389static void writeNspace (unsigned int n);
390
391/*
392 DumpStringInfo -
393*/
394
395static void DumpStringInfo (DynamicStrings_String s, unsigned int i);
396
397/*
398 DumpStringInfo -
399*/
400
401static void stop (void);
402
403/*
404 doDSdbEnter -
405*/
406
407static void doDSdbEnter (void);
408
409/*
410 doDSdbExit -
411*/
412
413static void doDSdbExit (DynamicStrings_String s);
414
415/*
416 DSdbEnter -
417*/
418
419static void DSdbEnter (void);
420
421/*
422 DSdbExit -
423*/
424
425static void DSdbExit (DynamicStrings_String s);
426static unsigned int Capture (DynamicStrings_String s);
427
428/*
429 Min -
430*/
431
432static unsigned int Min (unsigned int a, unsigned int b);
433
434/*
435 Max -
436*/
437
438static unsigned int Max (unsigned int a, unsigned int b);
439
440/*
441 writeString - writes a string to stdout.
442*/
443
51bc4b81 444static void writeString (const char *a_, unsigned int _a_high);
7401123f
GM
445
446/*
447 writeCstring - writes a C string to stdout.
448*/
449
450static void writeCstring (void * a);
451
452/*
453 writeCard -
454*/
455
456static void writeCard (unsigned int c);
457
458/*
459 writeLongcard -
460*/
461
462static void writeLongcard (long unsigned int l);
463
464/*
465 writeAddress -
466*/
467
468static void writeAddress (void * a);
469
470/*
471 writeLn - writes a newline.
472*/
473
474static void writeLn (void);
475
476/*
477 AssignDebug - assigns, file, and, line, information to string, s.
478*/
479
51bc4b81 480static DynamicStrings_String AssignDebug (DynamicStrings_String s, const char *file_, unsigned int _file_high, unsigned int line, const char *proc_, unsigned int _proc_high);
7401123f
GM
481
482/*
483 IsOn - returns TRUE if, s, is on one of the debug lists.
484*/
485
486static unsigned int IsOn (DynamicStrings_String list, DynamicStrings_String s);
487
488/*
489 AddTo - adds string, s, to, list.
490*/
491
492static void AddTo (DynamicStrings_String *list, DynamicStrings_String s);
493
494/*
495 SubFrom - removes string, s, from, list.
496*/
497
498static void SubFrom (DynamicStrings_String *list, DynamicStrings_String s);
499
500/*
501 AddAllocated - adds string, s, to the head of the allocated list.
502*/
503
504static void AddAllocated (DynamicStrings_String s);
505
506/*
507 AddDeallocated - adds string, s, to the head of the deallocated list.
508*/
509
510static void AddDeallocated (DynamicStrings_String s);
511
512/*
513 IsOnAllocated - returns TRUE if the string, s, has ever been allocated.
514*/
515
516static unsigned int IsOnAllocated (DynamicStrings_String s);
517
518/*
519 IsOnDeallocated - returns TRUE if the string, s, has ever been deallocated.
520*/
521
522static unsigned int IsOnDeallocated (DynamicStrings_String s);
523
524/*
525 SubAllocated - removes string, s, from the list of allocated strings.
526*/
527
528static void SubAllocated (DynamicStrings_String s);
529
530/*
531 SubDeallocated - removes string, s, from the list of deallocated strings.
532*/
533
534static void SubDeallocated (DynamicStrings_String s);
535
536/*
537 SubDebugInfo - removes string, s, from the list of allocated strings.
538*/
539
540static void SubDebugInfo (DynamicStrings_String s);
541
542/*
543 AddDebugInfo - adds string, s, to the list of allocated strings.
544*/
545
546static void AddDebugInfo (DynamicStrings_String s);
547
548/*
549 ConcatContents - add the contents of string, a, where, h, is the
550 total length of, a. The offset is in, o.
551*/
552
51bc4b81 553static void ConcatContents (Contents *c, const char *a_, unsigned int _a_high, unsigned int h, unsigned int o);
7401123f
GM
554
555/*
556 DeallocateCharStar - deallocates any charStar.
557*/
558
559static void DeallocateCharStar (DynamicStrings_String s);
560
561/*
562 CheckPoisoned - checks for a poisoned string, s.
563*/
564
565static DynamicStrings_String CheckPoisoned (DynamicStrings_String s);
566
567/*
568 MarkInvalid - marks the char * version of String, s, as invalid.
569*/
570
571static void MarkInvalid (DynamicStrings_String s);
572
573/*
574 ConcatContentsAddress - concatenate the string, a, where, h, is the
575 total length of, a.
576*/
577
578static void ConcatContentsAddress (Contents *c, void * a, unsigned int h);
579
580/*
581 AddToGarbage - adds String, b, onto the garbage list of, a. Providing
582 the state of b is marked. The state is then altered to
583 onlist. String, a, is returned.
584*/
585
586static DynamicStrings_String AddToGarbage (DynamicStrings_String a, DynamicStrings_String b);
587
588/*
589 IsOnGarbage - returns TRUE if, s, is on string, e, garbage list.
590*/
591
592static unsigned int IsOnGarbage (DynamicStrings_String e, DynamicStrings_String s);
593
594/*
595 IsWhite - returns TRUE if, ch, is a space or a tab.
596*/
597
598static unsigned int IsWhite (char ch);
599
600/*
601 DumpState -
602*/
603
604static void DumpState (DynamicStrings_String s);
605
606/*
607 DumpStringSynopsis -
608*/
609
610static void DumpStringSynopsis (DynamicStrings_String s);
611
612/*
613 DumpString - displays the contents of string, s.
614*/
615
616static void DumpString (DynamicStrings_String s);
617
618/*
619 Init - initialize the module.
620*/
621
622static void Init (void);
623
624
625/*
626 writeStringDesc write out debugging information about string, s. */
627
628static void writeStringDesc (DynamicStrings_String s)
629{
630 writeCstring (s->debug.file);
51bc4b81 631 writeString ((const char *) ":", 1);
7401123f 632 writeCard (s->debug.line);
51bc4b81 633 writeString ((const char *) ":", 1);
7401123f 634 writeCstring (s->debug.proc);
51bc4b81
GM
635 writeString ((const char *) " ", 1);
636 writeAddress (reinterpret_cast<void *> (s));
637 writeString ((const char *) " ", 1);
7401123f
GM
638 switch (s->head->state)
639 {
640 case inuse:
51bc4b81 641 writeString ((const char *) "still in use (", 14);
7401123f 642 writeCard (s->contents.len);
51bc4b81 643 writeString ((const char *) ") characters", 12);
7401123f
GM
644 break;
645
646 case marked:
51bc4b81 647 writeString ((const char *) "marked", 6);
7401123f
GM
648 break;
649
650 case onlist:
51bc4b81 651 writeString ((const char *) "on a (lost) garbage list", 24);
7401123f
GM
652 break;
653
654 case poisoned:
51bc4b81 655 writeString ((const char *) "poisoned", 8);
7401123f
GM
656 break;
657
658
659 default:
51bc4b81 660 writeString ((const char *) "unknown state", 13);
7401123f
GM
661 break;
662 }
663}
664
665
666/*
667 writeNspace -
668*/
669
670static void writeNspace (unsigned int n)
671{
672 while (n > 0)
673 {
51bc4b81 674 writeString ((const char *) " ", 1);
7401123f
GM
675 n -= 1;
676 }
677}
678
679
680/*
681 DumpStringInfo -
682*/
683
684static void DumpStringInfo (DynamicStrings_String s, unsigned int i)
685{
686 DynamicStrings_String t;
687
688 if (s != NULL)
689 {
690 writeNspace (i);
691 writeStringDesc (s);
692 writeLn ();
693 if (s->head->garbage != NULL)
694 {
695 writeNspace (i);
51bc4b81 696 writeString ((const char *) "garbage list:", 13);
7401123f
GM
697 writeLn ();
698 do {
699 s = s->head->garbage;
700 DumpStringInfo (s, i+1);
701 writeLn ();
702 } while (! (s == NULL));
703 }
704 }
705}
706
707
708/*
709 DumpStringInfo -
710*/
711
712static void stop (void)
713{
714}
715
716
717/*
718 doDSdbEnter -
719*/
720
721static void doDSdbEnter (void)
722{
723 if (CheckOn)
724 {
725 DynamicStrings_PushAllocation ();
726 }
727}
728
729
730/*
731 doDSdbExit -
732*/
733
734static void doDSdbExit (DynamicStrings_String s)
735{
736 if (CheckOn)
737 {
dce2ffd5 738 s = DynamicStrings_PopAllocationExemption (TRUE, s);
7401123f
GM
739 }
740}
741
742
743/*
744 DSdbEnter -
745*/
746
747static void DSdbEnter (void)
748{
749}
750
751
752/*
753 DSdbExit -
754*/
755
756static void DSdbExit (DynamicStrings_String s)
757{
758}
759
760static unsigned int Capture (DynamicStrings_String s)
761{
762 /*
763 * #undef GM2_DEBUG_DYNAMICSTINGS
764 * #if defined(GM2_DEBUG_DYNAMICSTINGS)
765 * # define DSdbEnter doDSdbEnter
766 * # define DSdbExit doDSdbExit
767 * # define CheckOn TRUE
768 * # define TraceOn TRUE
769 * #endif
770 */
771 captured = s;
d08981bf 772 return 1;
7401123f
GM
773 /* static analysis guarentees a RETURN statement will be used before here. */
774 __builtin_unreachable ();
775}
776
777
778/*
779 Min -
780*/
781
782static unsigned int Min (unsigned int a, unsigned int b)
783{
784 if (a < b)
785 {
786 return a;
787 }
788 else
789 {
790 return b;
791 }
792 /* static analysis guarentees a RETURN statement will be used before here. */
793 __builtin_unreachable ();
794}
795
796
797/*
798 Max -
799*/
800
801static unsigned int Max (unsigned int a, unsigned int b)
802{
803 if (a > b)
804 {
805 return a;
806 }
807 else
808 {
809 return b;
810 }
811 /* static analysis guarentees a RETURN statement will be used before here. */
812 __builtin_unreachable ();
813}
814
815
816/*
817 writeString - writes a string to stdout.
818*/
819
51bc4b81 820static void writeString (const char *a_, unsigned int _a_high)
7401123f
GM
821{
822 int i;
823 char a[_a_high+1];
824
825 /* make a local copy of each unbounded array. */
826 memcpy (a, a_, _a_high+1);
827
51bc4b81 828 i = static_cast<int> (libc_write (1, &a, static_cast<size_t> (StrLib_StrLen ((const char *) a, _a_high))));
7401123f
GM
829}
830
831
832/*
833 writeCstring - writes a C string to stdout.
834*/
835
836static void writeCstring (void * a)
837{
838 int i;
839
840 if (a == NULL)
841 {
51bc4b81 842 writeString ((const char *) "(null)", 6);
7401123f
GM
843 }
844 else
845 {
51bc4b81 846 i = static_cast<int> (libc_write (1, a, libc_strlen (a)));
7401123f
GM
847 }
848}
849
850
851/*
852 writeCard -
853*/
854
855static void writeCard (unsigned int c)
856{
857 char ch;
858 int i;
859
860 if (c > 9)
861 {
862 writeCard (c / 10);
863 writeCard (c % 10);
864 }
865 else
866 {
867 ch = ((char) ( ((unsigned int) ('0'))+c));
51bc4b81 868 i = static_cast<int> (libc_write (1, &ch, static_cast<size_t> (1)));
7401123f
GM
869 }
870}
871
872
873/*
874 writeLongcard -
875*/
876
877static void writeLongcard (long unsigned int l)
878{
879 char ch;
880 int i;
881
882 if (l > 16)
883 {
884 writeLongcard (l / 16);
885 writeLongcard (l % 16);
886 }
887 else if (l < 10)
888 {
889 /* avoid dangling else. */
890 ch = ((char) ( ((unsigned int) ('0'))+((unsigned int ) (l))));
51bc4b81 891 i = static_cast<int> (libc_write (1, &ch, static_cast<size_t> (1)));
7401123f
GM
892 }
893 else if (l < 16)
894 {
895 /* avoid dangling else. */
896 ch = ((char) (( ((unsigned int) ('a'))+((unsigned int ) (l)))-10));
51bc4b81 897 i = static_cast<int> (libc_write (1, &ch, static_cast<size_t> (1)));
7401123f
GM
898 }
899}
900
901
902/*
903 writeAddress -
904*/
905
906static void writeAddress (void * a)
907{
908 writeLongcard ((long unsigned int ) (a));
909}
910
911
912/*
913 writeLn - writes a newline.
914*/
915
916static void writeLn (void)
917{
918 char ch;
919 int i;
920
dce2ffd5 921 ch = ASCII_lf;
51bc4b81 922 i = static_cast<int> (libc_write (1, &ch, static_cast<size_t> (1)));
7401123f
GM
923}
924
925
926/*
927 AssignDebug - assigns, file, and, line, information to string, s.
928*/
929
51bc4b81 930static DynamicStrings_String AssignDebug (DynamicStrings_String s, const char *file_, unsigned int _file_high, unsigned int line, const char *proc_, unsigned int _proc_high)
7401123f
GM
931{
932 void * f;
933 void * p;
934 char file[_file_high+1];
935 char proc[_proc_high+1];
936
937 /* make a local copy of each unbounded array. */
938 memcpy (file, file_, _file_high+1);
939 memcpy (proc, proc_, _proc_high+1);
940
941 f = &file;
942 p = &proc;
51bc4b81
GM
943 Storage_ALLOCATE (&s->debug.file, (StrLib_StrLen ((const char *) file, _file_high))+1);
944 if ((libc_strncpy (s->debug.file, f, (StrLib_StrLen ((const char *) file, _file_high))+1)) == NULL)
7401123f
GM
945 {} /* empty. */
946 s->debug.line = line;
51bc4b81
GM
947 Storage_ALLOCATE (&s->debug.proc, (StrLib_StrLen ((const char *) proc, _proc_high))+1);
948 if ((libc_strncpy (s->debug.proc, p, (StrLib_StrLen ((const char *) proc, _proc_high))+1)) == NULL)
7401123f
GM
949 {} /* empty. */
950 return s;
951 /* static analysis guarentees a RETURN statement will be used before here. */
952 __builtin_unreachable ();
953}
954
955
956/*
957 IsOn - returns TRUE if, s, is on one of the debug lists.
958*/
959
960static unsigned int IsOn (DynamicStrings_String list, DynamicStrings_String s)
961{
962 while ((list != s) && (list != NULL))
963 {
964 list = list->debug.next;
965 }
966 return list == s;
967 /* static analysis guarentees a RETURN statement will be used before here. */
968 __builtin_unreachable ();
969}
970
971
972/*
973 AddTo - adds string, s, to, list.
974*/
975
976static void AddTo (DynamicStrings_String *list, DynamicStrings_String s)
977{
978 if ((*list) == NULL)
979 {
980 (*list) = s;
d08981bf 981 s->debug.next = NULL;
7401123f
GM
982 }
983 else
984 {
985 s->debug.next = (*list);
986 (*list) = s;
987 }
988}
989
990
991/*
992 SubFrom - removes string, s, from, list.
993*/
994
995static void SubFrom (DynamicStrings_String *list, DynamicStrings_String s)
996{
997 DynamicStrings_String p;
998
999 if ((*list) == s)
1000 {
1001 (*list) = s->debug.next;
1002 }
1003 else
1004 {
1005 p = (*list);
1006 while ((p->debug.next != NULL) && (p->debug.next != s))
1007 {
1008 p = p->debug.next;
1009 }
1010 if (p->debug.next == s)
1011 {
1012 p->debug.next = s->debug.next;
1013 }
1014 else
1015 {
1016 /* not found, quit */
dce2ffd5 1017 return ;
7401123f
GM
1018 }
1019 }
d08981bf 1020 s->debug.next = NULL;
7401123f
GM
1021}
1022
1023
1024/*
1025 AddAllocated - adds string, s, to the head of the allocated list.
1026*/
1027
1028static void AddAllocated (DynamicStrings_String s)
1029{
1030 Init ();
1031 AddTo (&frameHead->alloc, s);
1032}
1033
1034
1035/*
1036 AddDeallocated - adds string, s, to the head of the deallocated list.
1037*/
1038
1039static void AddDeallocated (DynamicStrings_String s)
1040{
1041 Init ();
1042 AddTo (&frameHead->dealloc, s);
1043}
1044
1045
1046/*
1047 IsOnAllocated - returns TRUE if the string, s, has ever been allocated.
1048*/
1049
1050static unsigned int IsOnAllocated (DynamicStrings_String s)
1051{
1052 frame f;
1053
1054 Init ();
1055 f = frameHead;
1056 do {
1057 if (IsOn (f->alloc, s))
1058 {
1059 return TRUE;
1060 }
1061 else
1062 {
1063 f = f->next;
1064 }
1065 } while (! (f == NULL));
1066 return FALSE;
1067 /* static analysis guarentees a RETURN statement will be used before here. */
1068 __builtin_unreachable ();
1069}
1070
1071
1072/*
1073 IsOnDeallocated - returns TRUE if the string, s, has ever been deallocated.
1074*/
1075
1076static unsigned int IsOnDeallocated (DynamicStrings_String s)
1077{
1078 frame f;
1079
1080 Init ();
1081 f = frameHead;
1082 do {
1083 if (IsOn (f->dealloc, s))
1084 {
1085 return TRUE;
1086 }
1087 else
1088 {
1089 f = f->next;
1090 }
1091 } while (! (f == NULL));
1092 return FALSE;
1093 /* static analysis guarentees a RETURN statement will be used before here. */
1094 __builtin_unreachable ();
1095}
1096
1097
1098/*
1099 SubAllocated - removes string, s, from the list of allocated strings.
1100*/
1101
1102static void SubAllocated (DynamicStrings_String s)
1103{
1104 frame f;
1105
1106 Init ();
1107 f = frameHead;
1108 do {
1109 if (IsOn (f->alloc, s))
1110 {
1111 SubFrom (&f->alloc, s);
dce2ffd5 1112 return ;
7401123f
GM
1113 }
1114 else
1115 {
1116 f = f->next;
1117 }
1118 } while (! (f == NULL));
1119}
1120
1121
1122/*
1123 SubDeallocated - removes string, s, from the list of deallocated strings.
1124*/
1125
1126static void SubDeallocated (DynamicStrings_String s)
1127{
1128 frame f;
1129
1130 Init ();
1131 f = frameHead;
1132 do {
1133 if (IsOn (f->dealloc, s))
1134 {
1135 SubFrom (&f->dealloc, s);
dce2ffd5 1136 return ;
7401123f
GM
1137 }
1138 else
1139 {
1140 f = f->next;
1141 }
1142 } while (! (f == NULL));
1143}
1144
1145
1146/*
1147 SubDebugInfo - removes string, s, from the list of allocated strings.
1148*/
1149
1150static void SubDebugInfo (DynamicStrings_String s)
1151{
1152 if (IsOnDeallocated (s))
1153 {
1154 Assertion_Assert (! DebugOn);
1155 /* string has already been deallocated */
dce2ffd5 1156 return ;
7401123f
GM
1157 }
1158 if (IsOnAllocated (s))
1159 {
1160 SubAllocated (s);
1161 AddDeallocated (s);
1162 }
1163 else
1164 {
1165 /* string has not been allocated */
1166 Assertion_Assert (! DebugOn);
1167 }
1168}
1169
1170
1171/*
1172 AddDebugInfo - adds string, s, to the list of allocated strings.
1173*/
1174
1175static void AddDebugInfo (DynamicStrings_String s)
1176{
d08981bf 1177 s->debug.next = NULL;
7401123f 1178 s->debug.file = NULL;
d08981bf 1179 s->debug.line = 0;
7401123f
GM
1180 s->debug.proc = NULL;
1181 if (CheckOn)
1182 {
1183 AddAllocated (s);
1184 }
1185}
1186
1187
1188/*
1189 ConcatContents - add the contents of string, a, where, h, is the
1190 total length of, a. The offset is in, o.
1191*/
1192
51bc4b81 1193static void ConcatContents (Contents *c, const char *a_, unsigned int _a_high, unsigned int h, unsigned int o)
7401123f
GM
1194{
1195 unsigned int i;
1196 char a[_a_high+1];
1197
1198 /* make a local copy of each unbounded array. */
1199 memcpy (a, a_, _a_high+1);
1200
1201 i = (*c).len;
1202 while ((o < h) && (i < MaxBuf))
1203 {
1204 (*c).buf.array[i] = a[o];
1205 o += 1;
1206 i += 1;
1207 }
1208 if (o < h)
1209 {
d08981bf 1210 (*c).len = MaxBuf;
7401123f 1211 Storage_ALLOCATE ((void **) &(*c).next, sizeof (stringRecord));
d08981bf
GM
1212 (*c).next->head = NULL;
1213 (*c).next->contents.len = 0;
1214 (*c).next->contents.next = NULL;
51bc4b81 1215 ConcatContents (&(*c).next->contents, (const char *) a, _a_high, h, o);
7401123f 1216 AddDebugInfo ((*c).next);
06c977f8 1217 (*c).next = AssignDebug ((*c).next, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 722, (const char *) "ConcatContents", 14);
7401123f
GM
1218 }
1219 else
1220 {
1221 (*c).len = i;
1222 }
1223}
1224
1225
1226/*
1227 DeallocateCharStar - deallocates any charStar.
1228*/
1229
1230static void DeallocateCharStar (DynamicStrings_String s)
1231{
1232 if ((s != NULL) && (s->head != NULL))
1233 {
1234 if (s->head->charStarUsed && (s->head->charStar != NULL))
1235 {
1236 Storage_DEALLOCATE (&s->head->charStar, s->head->charStarSize);
1237 }
1238 s->head->charStarUsed = FALSE;
1239 s->head->charStar = NULL;
d08981bf 1240 s->head->charStarSize = 0;
7401123f
GM
1241 s->head->charStarValid = FALSE;
1242 }
1243}
1244
1245
1246/*
1247 CheckPoisoned - checks for a poisoned string, s.
1248*/
1249
1250static DynamicStrings_String CheckPoisoned (DynamicStrings_String s)
1251{
1252 if (((PoisonOn && (s != NULL)) && (s->head != NULL)) && (s->head->state == poisoned))
1253 {
1254 M2RTS_HALT (-1);
1255 __builtin_unreachable ();
1256 }
1257 return s;
1258 /* static analysis guarentees a RETURN statement will be used before here. */
1259 __builtin_unreachable ();
1260}
1261
1262
1263/*
1264 MarkInvalid - marks the char * version of String, s, as invalid.
1265*/
1266
1267static void MarkInvalid (DynamicStrings_String s)
1268{
1269 if (PoisonOn)
1270 {
dce2ffd5 1271 s = CheckPoisoned (s);
7401123f
GM
1272 }
1273 if (s->head != NULL)
1274 {
1275 s->head->charStarValid = FALSE;
1276 }
1277}
1278
1279
1280/*
1281 ConcatContentsAddress - concatenate the string, a, where, h, is the
1282 total length of, a.
1283*/
1284
1285static void ConcatContentsAddress (Contents *c, void * a, unsigned int h)
1286{
51bc4b81
GM
1287 typedef char *_T1;
1288
1289 _T1 p;
7401123f
GM
1290 unsigned int i;
1291 unsigned int j;
7401123f 1292
d08981bf 1293 j = 0;
7401123f 1294 i = (*c).len;
51bc4b81 1295 p = static_cast<_T1> (a);
7401123f
GM
1296 while ((j < h) && (i < MaxBuf))
1297 {
1298 (*c).buf.array[i] = (*p);
1299 i += 1;
1300 j += 1;
1301 p += 1;
1302 }
1303 if (j < h)
1304 {
1305 /* avoid dangling else. */
d08981bf 1306 (*c).len = MaxBuf;
7401123f 1307 Storage_ALLOCATE ((void **) &(*c).next, sizeof (stringRecord));
d08981bf
GM
1308 (*c).next->head = NULL;
1309 (*c).next->contents.len = 0;
1310 (*c).next->contents.next = NULL;
51bc4b81 1311 ConcatContentsAddress (&(*c).next->contents, reinterpret_cast<void *> (p), h-j);
7401123f
GM
1312 AddDebugInfo ((*c).next);
1313 if (TraceOn)
1314 {
06c977f8 1315 (*c).next = AssignDebug ((*c).next, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 917, (const char *) "ConcatContentsAddress", 21);
7401123f
GM
1316 }
1317 }
1318 else
1319 {
1320 (*c).len = i;
d08981bf 1321 (*c).next = NULL;
7401123f
GM
1322 }
1323}
1324
1325
1326/*
1327 AddToGarbage - adds String, b, onto the garbage list of, a. Providing
1328 the state of b is marked. The state is then altered to
1329 onlist. String, a, is returned.
1330*/
1331
1332static DynamicStrings_String AddToGarbage (DynamicStrings_String a, DynamicStrings_String b)
1333{
1334 DynamicStrings_String c;
1335
1336 if (PoisonOn)
1337 {
dce2ffd5
GM
1338 a = CheckPoisoned (a);
1339 b = CheckPoisoned (b);
7401123f
GM
1340 }
1341 /*
1342 IF (a#NIL) AND (a#b) AND (a^.head^.state=marked)
1343 THEN
1344 writeString('warning trying to add to a marked string') ; writeLn
1345 END ;
1346 */
1347 if (((((a != b) && (a != NULL)) && (b != NULL)) && (b->head->state == marked)) && (a->head->state == inuse))
1348 {
1349 c = a;
1350 while (c->head->garbage != NULL)
1351 {
1352 c = c->head->garbage;
1353 }
1354 c->head->garbage = b;
1355 b->head->state = onlist;
1356 if (CheckOn)
1357 {
1358 SubDebugInfo (b);
1359 }
1360 }
1361 return a;
1362 /* static analysis guarentees a RETURN statement will be used before here. */
1363 __builtin_unreachable ();
1364}
1365
1366
1367/*
1368 IsOnGarbage - returns TRUE if, s, is on string, e, garbage list.
1369*/
1370
1371static unsigned int IsOnGarbage (DynamicStrings_String e, DynamicStrings_String s)
1372{
1373 if ((e != NULL) && (s != NULL))
1374 {
1375 while (e->head->garbage != NULL)
1376 {
1377 if (e->head->garbage == s)
1378 {
1379 return TRUE;
1380 }
1381 else
1382 {
1383 e = e->head->garbage;
1384 }
1385 }
1386 }
1387 return FALSE;
1388 /* static analysis guarentees a RETURN statement will be used before here. */
1389 __builtin_unreachable ();
1390}
1391
1392
1393/*
1394 IsWhite - returns TRUE if, ch, is a space or a tab.
1395*/
1396
1397static unsigned int IsWhite (char ch)
1398{
1399 return (ch == ' ') || (ch == ASCII_tab);
1400 /* static analysis guarentees a RETURN statement will be used before here. */
1401 __builtin_unreachable ();
1402}
1403
1404
1405/*
1406 DumpState -
1407*/
1408
1409static void DumpState (DynamicStrings_String s)
1410{
1411 switch (s->head->state)
1412 {
1413 case inuse:
51bc4b81 1414 writeString ((const char *) "still in use (", 14);
7401123f 1415 writeCard (s->contents.len);
51bc4b81 1416 writeString ((const char *) ") characters", 12);
7401123f
GM
1417 break;
1418
1419 case marked:
51bc4b81 1420 writeString ((const char *) "marked", 6);
7401123f
GM
1421 break;
1422
1423 case onlist:
51bc4b81 1424 writeString ((const char *) "on a garbage list", 17);
7401123f
GM
1425 break;
1426
1427 case poisoned:
51bc4b81 1428 writeString ((const char *) "poisoned", 8);
7401123f
GM
1429 break;
1430
1431
1432 default:
51bc4b81 1433 writeString ((const char *) "unknown state", 13);
7401123f
GM
1434 break;
1435 }
1436}
1437
1438
1439/*
1440 DumpStringSynopsis -
1441*/
1442
1443static void DumpStringSynopsis (DynamicStrings_String s)
1444{
1445 writeCstring (s->debug.file);
51bc4b81 1446 writeString ((const char *) ":", 1);
7401123f 1447 writeCard (s->debug.line);
51bc4b81 1448 writeString ((const char *) ":", 1);
7401123f 1449 writeCstring (s->debug.proc);
51bc4b81
GM
1450 writeString ((const char *) " string ", 8);
1451 writeAddress (reinterpret_cast<void *> (s));
1452 writeString ((const char *) " ", 1);
7401123f
GM
1453 DumpState (s);
1454 if (IsOnAllocated (s))
1455 {
51bc4b81 1456 writeString ((const char *) " globally allocated", 19);
7401123f
GM
1457 }
1458 else if (IsOnDeallocated (s))
1459 {
1460 /* avoid dangling else. */
51bc4b81 1461 writeString ((const char *) " globally deallocated", 21);
7401123f
GM
1462 }
1463 else
1464 {
1465 /* avoid dangling else. */
51bc4b81 1466 writeString ((const char *) " globally unknown", 17);
7401123f
GM
1467 }
1468 writeLn ();
1469}
1470
1471
1472/*
1473 DumpString - displays the contents of string, s.
1474*/
1475
1476static void DumpString (DynamicStrings_String s)
1477{
1478 DynamicStrings_String t;
1479
1480 if (s != NULL)
1481 {
1482 DumpStringSynopsis (s);
1483 if ((s->head != NULL) && (s->head->garbage != NULL))
1484 {
51bc4b81 1485 writeString ((const char *) "display chained strings on the garbage list", 43);
7401123f
GM
1486 writeLn ();
1487 t = s->head->garbage;
1488 while (t != NULL)
1489 {
1490 DumpStringSynopsis (t);
1491 t = t->head->garbage;
1492 }
1493 }
1494 }
1495}
1496
1497
1498/*
1499 Init - initialize the module.
1500*/
1501
1502static void Init (void)
1503{
1504 if (! Initialized)
1505 {
1506 Initialized = TRUE;
d08981bf 1507 frameHead = NULL;
7401123f
GM
1508 DynamicStrings_PushAllocation ();
1509 }
1510}
1511
1512
1513/*
1514 InitString - creates and returns a String type object.
1515 Initial contents are, a.
1516*/
1517
51bc4b81 1518extern "C" DynamicStrings_String DynamicStrings_InitString (const char *a_, unsigned int _a_high)
7401123f
GM
1519{
1520 DynamicStrings_String s;
1521 char a[_a_high+1];
1522
1523 /* make a local copy of each unbounded array. */
1524 memcpy (a, a_, _a_high+1);
1525
1526 Storage_ALLOCATE ((void **) &s, sizeof (stringRecord));
d08981bf
GM
1527 s->contents.len = 0;
1528 s->contents.next = NULL;
51bc4b81 1529 ConcatContents (&s->contents, (const char *) a, _a_high, StrLib_StrLen ((const char *) a, _a_high), 0);
7401123f
GM
1530 Storage_ALLOCATE ((void **) &s->head, sizeof (descriptor));
1531 s->head->charStarUsed = FALSE;
1532 s->head->charStar = NULL;
d08981bf 1533 s->head->charStarSize = 0;
7401123f 1534 s->head->charStarValid = FALSE;
d08981bf 1535 s->head->garbage = NULL;
7401123f
GM
1536 s->head->state = inuse;
1537 AddDebugInfo (s);
1538 if (TraceOn)
1539 {
06c977f8 1540 s = AssignDebug (s, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 758, (const char *) "InitString", 10);
7401123f
GM
1541 }
1542 return s;
1543 /* static analysis guarentees a RETURN statement will be used before here. */
1544 __builtin_unreachable ();
1545}
1546
1547
1548/*
1549 KillString - frees String, s, and its contents.
1550 NIL is returned.
1551*/
1552
51bc4b81 1553extern "C" DynamicStrings_String DynamicStrings_KillString (DynamicStrings_String s)
7401123f
GM
1554{
1555 DynamicStrings_String t;
1556
1557 if (PoisonOn)
1558 {
dce2ffd5 1559 s = CheckPoisoned (s);
7401123f
GM
1560 }
1561 if (s != NULL)
1562 {
1563 if (CheckOn)
1564 {
1565 /* avoid gcc warning by using compound statement even if not strictly necessary. */
1566 if (IsOnAllocated (s))
1567 {
1568 SubAllocated (s);
1569 }
1570 else if (IsOnDeallocated (s))
1571 {
1572 /* avoid dangling else. */
1573 SubDeallocated (s);
1574 }
1575 }
1576 if (s->head != NULL)
1577 {
1578 s->head->state = poisoned;
dce2ffd5 1579 s->head->garbage = DynamicStrings_KillString (s->head->garbage);
7401123f
GM
1580 if (! PoisonOn)
1581 {
1582 DeallocateCharStar (s);
1583 }
1584 if (! PoisonOn)
1585 {
1586 Storage_DEALLOCATE ((void **) &s->head, sizeof (descriptor));
d08981bf 1587 s->head = NULL;
7401123f
GM
1588 }
1589 }
dce2ffd5 1590 t = DynamicStrings_KillString (s->contents.next);
7401123f
GM
1591 if (! PoisonOn)
1592 {
1593 Storage_DEALLOCATE ((void **) &s, sizeof (stringRecord));
1594 }
1595 }
d08981bf 1596 return NULL;
7401123f
GM
1597 /* static analysis guarentees a RETURN statement will be used before here. */
1598 __builtin_unreachable ();
1599}
1600
1601
1602/*
1603 Fin - finishes with a string, it calls KillString with, s.
1604 The purpose of the procedure is to provide a short cut
1605 to calling KillString and then testing the return result.
1606*/
1607
51bc4b81 1608extern "C" void DynamicStrings_Fin (DynamicStrings_String s)
7401123f
GM
1609{
1610 if ((DynamicStrings_KillString (s)) != NULL)
1611 {
1612 M2RTS_HALT (-1);
1613 __builtin_unreachable ();
1614 }
1615}
1616
1617
1618/*
1619 InitStringCharStar - initializes and returns a String to contain the C string.
1620*/
1621
51bc4b81 1622extern "C" DynamicStrings_String DynamicStrings_InitStringCharStar (void * a)
7401123f
GM
1623{
1624 DynamicStrings_String s;
1625
1626 Storage_ALLOCATE ((void **) &s, sizeof (stringRecord));
d08981bf
GM
1627 s->contents.len = 0;
1628 s->contents.next = NULL;
7401123f
GM
1629 if (a != NULL)
1630 {
51bc4b81 1631 ConcatContentsAddress (&s->contents, a, static_cast<unsigned int> (libc_strlen (a)));
7401123f
GM
1632 }
1633 Storage_ALLOCATE ((void **) &s->head, sizeof (descriptor));
1634 s->head->charStarUsed = FALSE;
1635 s->head->charStar = NULL;
d08981bf 1636 s->head->charStarSize = 0;
7401123f 1637 s->head->charStarValid = FALSE;
d08981bf 1638 s->head->garbage = NULL;
7401123f
GM
1639 s->head->state = inuse;
1640 AddDebugInfo (s);
1641 if (TraceOn)
1642 {
06c977f8 1643 s = AssignDebug (s, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 957, (const char *) "InitStringCharStar", 18);
7401123f
GM
1644 }
1645 return s;
1646 /* static analysis guarentees a RETURN statement will be used before here. */
1647 __builtin_unreachable ();
1648}
1649
1650
1651/*
1652 InitStringChar - initializes and returns a String to contain the single character, ch.
1653*/
1654
51bc4b81 1655extern "C" DynamicStrings_String DynamicStrings_InitStringChar (char ch)
7401123f 1656{
51bc4b81 1657 typedef struct _T4_a _T4;
7401123f 1658
51bc4b81
GM
1659 struct _T4_a { char array[1+1]; };
1660 _T4 a;
7401123f
GM
1661 DynamicStrings_String s;
1662
1663 a.array[0] = ch;
dce2ffd5
GM
1664 a.array[1] = ASCII_nul;
1665 s = DynamicStrings_InitString ((const char *) &a.array[0], 1);
7401123f
GM
1666 if (TraceOn)
1667 {
06c977f8 1668 s = AssignDebug (s, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 977, (const char *) "InitStringChar", 14);
7401123f
GM
1669 }
1670 return s;
1671 /* static analysis guarentees a RETURN statement will be used before here. */
1672 __builtin_unreachable ();
1673}
1674
1675
1676/*
1677 Mark - marks String, s, ready for garbage collection.
1678*/
1679
51bc4b81 1680extern "C" DynamicStrings_String DynamicStrings_Mark (DynamicStrings_String s)
7401123f
GM
1681{
1682 if (PoisonOn)
1683 {
dce2ffd5 1684 s = CheckPoisoned (s);
7401123f
GM
1685 }
1686 if ((s != NULL) && (s->head->state == inuse))
1687 {
1688 s->head->state = marked;
1689 }
1690 return s;
1691 /* static analysis guarentees a RETURN statement will be used before here. */
1692 __builtin_unreachable ();
1693}
1694
1695
1696/*
1697 Length - returns the length of the String, s.
1698*/
1699
51bc4b81 1700extern "C" unsigned int DynamicStrings_Length (DynamicStrings_String s)
7401123f
GM
1701{
1702 if (s == NULL)
1703 {
d08981bf 1704 return 0;
7401123f
GM
1705 }
1706 else
1707 {
dce2ffd5 1708 return s->contents.len+(DynamicStrings_Length (s->contents.next));
7401123f
GM
1709 }
1710 /* static analysis guarentees a RETURN statement will be used before here. */
1711 __builtin_unreachable ();
1712}
1713
1714
1715/*
1716 ConCat - returns String, a, after the contents of, b, have been appended.
1717*/
1718
51bc4b81 1719extern "C" DynamicStrings_String DynamicStrings_ConCat (DynamicStrings_String a, DynamicStrings_String b)
7401123f
GM
1720{
1721 DynamicStrings_String t;
1722
1723 if (PoisonOn)
1724 {
dce2ffd5
GM
1725 a = CheckPoisoned (a);
1726 b = CheckPoisoned (b);
7401123f
GM
1727 }
1728 if (a == b)
1729 {
dce2ffd5 1730 return DynamicStrings_ConCat (a, DynamicStrings_Mark (DynamicStrings_Dup (b)));
7401123f
GM
1731 }
1732 else if (a != NULL)
1733 {
1734 /* avoid dangling else. */
dce2ffd5 1735 a = AddToGarbage (a, b);
7401123f
GM
1736 MarkInvalid (a);
1737 t = a;
1738 while (b != NULL)
1739 {
1740 while ((t->contents.len == MaxBuf) && (t->contents.next != NULL))
1741 {
1742 t = t->contents.next;
1743 }
51bc4b81 1744 ConcatContents (&t->contents, (const char *) &b->contents.buf.array[0], (MaxBuf-1), b->contents.len, 0);
7401123f
GM
1745 b = b->contents.next;
1746 }
1747 }
1748 if ((a == NULL) && (b != NULL))
1749 {
1750 M2RTS_HALT (-1);
1751 __builtin_unreachable ();
1752 }
1753 return a;
1754 /* static analysis guarentees a RETURN statement will be used before here. */
1755 __builtin_unreachable ();
1756}
1757
1758
1759/*
1760 ConCatChar - returns String, a, after character, ch, has been appended.
1761*/
1762
51bc4b81 1763extern "C" DynamicStrings_String DynamicStrings_ConCatChar (DynamicStrings_String a, char ch)
7401123f 1764{
51bc4b81 1765 typedef struct _T5_a _T5;
7401123f 1766
51bc4b81
GM
1767 struct _T5_a { char array[1+1]; };
1768 _T5 b;
7401123f
GM
1769 DynamicStrings_String t;
1770
1771 if (PoisonOn)
1772 {
dce2ffd5 1773 a = CheckPoisoned (a);
7401123f
GM
1774 }
1775 b.array[0] = ch;
1776 b.array[1] = ASCII_nul;
1777 t = a;
1778 MarkInvalid (a);
1779 while ((t->contents.len == MaxBuf) && (t->contents.next != NULL))
1780 {
1781 t = t->contents.next;
1782 }
51bc4b81 1783 ConcatContents (&t->contents, (const char *) &b.array[0], 1, 1, 0);
7401123f
GM
1784 return a;
1785 /* static analysis guarentees a RETURN statement will be used before here. */
1786 __builtin_unreachable ();
1787}
1788
1789
1790/*
1791 Assign - assigns the contents of, b, into, a.
1792 String, a, is returned.
1793*/
1794
51bc4b81 1795extern "C" DynamicStrings_String DynamicStrings_Assign (DynamicStrings_String a, DynamicStrings_String b)
7401123f
GM
1796{
1797 if (PoisonOn)
1798 {
dce2ffd5
GM
1799 a = CheckPoisoned (a);
1800 b = CheckPoisoned (b);
7401123f
GM
1801 }
1802 if ((a != NULL) && (b != NULL))
1803 {
dce2ffd5 1804 a->contents.next = DynamicStrings_KillString (a->contents.next);
d08981bf 1805 a->contents.len = 0;
7401123f 1806 }
dce2ffd5 1807 return DynamicStrings_ConCat (a, b);
7401123f
GM
1808 /* static analysis guarentees a RETURN statement will be used before here. */
1809 __builtin_unreachable ();
1810}
1811
1812
1813/*
1814 Dup - duplicate a String, s, returning the copy of s.
1815*/
1816
51bc4b81 1817extern "C" DynamicStrings_String DynamicStrings_Dup (DynamicStrings_String s)
7401123f
GM
1818{
1819 if (PoisonOn)
1820 {
dce2ffd5 1821 s = CheckPoisoned (s);
7401123f 1822 }
dce2ffd5 1823 s = DynamicStrings_Assign (DynamicStrings_InitString ((const char *) "", 0), s);
7401123f
GM
1824 if (TraceOn)
1825 {
06c977f8 1826 s = AssignDebug (s, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1173, (const char *) "Dup", 3);
7401123f
GM
1827 }
1828 return s;
1829 /* static analysis guarentees a RETURN statement will be used before here. */
1830 __builtin_unreachable ();
1831}
1832
1833
1834/*
1835 Add - returns a new String which contains the contents of a and b.
1836*/
1837
51bc4b81 1838extern "C" DynamicStrings_String DynamicStrings_Add (DynamicStrings_String a, DynamicStrings_String b)
7401123f
GM
1839{
1840 if (PoisonOn)
1841 {
dce2ffd5
GM
1842 a = CheckPoisoned (a);
1843 b = CheckPoisoned (b);
7401123f 1844 }
dce2ffd5 1845 a = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "", 0), a), b);
7401123f
GM
1846 if (TraceOn)
1847 {
06c977f8 1848 a = AssignDebug (a, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1193, (const char *) "Add", 3);
7401123f
GM
1849 }
1850 return a;
1851 /* static analysis guarentees a RETURN statement will be used before here. */
1852 __builtin_unreachable ();
1853}
1854
1855
1856/*
1857 Equal - returns TRUE if String, a, and, b, are equal.
1858*/
1859
51bc4b81 1860extern "C" unsigned int DynamicStrings_Equal (DynamicStrings_String a, DynamicStrings_String b)
7401123f
GM
1861{
1862 unsigned int i;
1863
1864 if (PoisonOn)
1865 {
dce2ffd5
GM
1866 a = CheckPoisoned (a);
1867 b = CheckPoisoned (b);
7401123f
GM
1868 }
1869 if ((DynamicStrings_Length (a)) == (DynamicStrings_Length (b)))
1870 {
1871 while ((a != NULL) && (b != NULL))
1872 {
d08981bf 1873 i = 0;
7401123f
GM
1874 Assertion_Assert (a->contents.len == b->contents.len);
1875 while (i < a->contents.len)
1876 {
1877 if (a->contents.buf.array[i] != a->contents.buf.array[i])
1878 {
1879 M2RTS_HALT (-1);
1880 __builtin_unreachable ();
1881 }
1882 if (b->contents.buf.array[i] != b->contents.buf.array[i])
1883 {
1884 M2RTS_HALT (-1);
1885 __builtin_unreachable ();
1886 }
1887 if (a->contents.buf.array[i] != b->contents.buf.array[i])
1888 {
1889 return FALSE;
1890 }
1891 i += 1;
1892 }
1893 a = a->contents.next;
1894 b = b->contents.next;
1895 }
1896 return TRUE;
1897 }
1898 else
1899 {
1900 return FALSE;
1901 }
1902 /* static analysis guarentees a RETURN statement will be used before here. */
1903 __builtin_unreachable ();
1904}
1905
1906
1907/*
1908 EqualCharStar - returns TRUE if contents of String, s, is the same as the
1909 string, a.
1910*/
1911
51bc4b81 1912extern "C" unsigned int DynamicStrings_EqualCharStar (DynamicStrings_String s, void * a)
7401123f
GM
1913{
1914 DynamicStrings_String t;
1915
1916 if (PoisonOn)
1917 {
dce2ffd5 1918 s = CheckPoisoned (s);
7401123f 1919 }
dce2ffd5 1920 t = DynamicStrings_InitStringCharStar (a);
7401123f
GM
1921 if (TraceOn)
1922 {
06c977f8 1923 t = AssignDebug (t, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1258, (const char *) "EqualCharStar", 13);
7401123f 1924 }
dce2ffd5 1925 t = AddToGarbage (t, s);
7401123f
GM
1926 if (DynamicStrings_Equal (t, s))
1927 {
dce2ffd5 1928 t = DynamicStrings_KillString (t);
7401123f
GM
1929 return TRUE;
1930 }
1931 else
1932 {
dce2ffd5 1933 t = DynamicStrings_KillString (t);
7401123f
GM
1934 return FALSE;
1935 }
1936 /* static analysis guarentees a RETURN statement will be used before here. */
1937 __builtin_unreachable ();
1938}
1939
1940
1941/*
1942 EqualArray - returns TRUE if contents of String, s, is the same as the
1943 string, a.
1944*/
1945
51bc4b81 1946extern "C" unsigned int DynamicStrings_EqualArray (DynamicStrings_String s, const char *a_, unsigned int _a_high)
7401123f
GM
1947{
1948 DynamicStrings_String t;
1949 char a[_a_high+1];
1950
1951 /* make a local copy of each unbounded array. */
1952 memcpy (a, a_, _a_high+1);
1953
1954 if (PoisonOn)
1955 {
dce2ffd5 1956 s = CheckPoisoned (s);
7401123f 1957 }
dce2ffd5 1958 t = DynamicStrings_InitString ((const char *) a, _a_high);
7401123f
GM
1959 if (TraceOn)
1960 {
06c977f8 1961 t = AssignDebug (t, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1288, (const char *) "EqualArray", 10);
7401123f 1962 }
dce2ffd5 1963 t = AddToGarbage (t, s);
7401123f
GM
1964 if (DynamicStrings_Equal (t, s))
1965 {
dce2ffd5 1966 t = DynamicStrings_KillString (t);
7401123f
GM
1967 return TRUE;
1968 }
1969 else
1970 {
dce2ffd5 1971 t = DynamicStrings_KillString (t);
7401123f
GM
1972 return FALSE;
1973 }
1974 /* static analysis guarentees a RETURN statement will be used before here. */
1975 __builtin_unreachable ();
1976}
1977
1978
1979/*
1980 Mult - returns a new string which is n concatenations of String, s.
1981*/
1982
51bc4b81 1983extern "C" DynamicStrings_String DynamicStrings_Mult (DynamicStrings_String s, unsigned int n)
7401123f
GM
1984{
1985 if (PoisonOn)
1986 {
dce2ffd5 1987 s = CheckPoisoned (s);
7401123f
GM
1988 }
1989 if (n <= 0)
1990 {
dce2ffd5 1991 s = AddToGarbage (DynamicStrings_InitString ((const char *) "", 0), s);
7401123f
GM
1992 }
1993 else
1994 {
dce2ffd5 1995 s = DynamicStrings_ConCat (DynamicStrings_Mult (s, n-1), s);
7401123f
GM
1996 }
1997 if (TraceOn)
1998 {
06c977f8 1999 s = AssignDebug (s, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1320, (const char *) "Mult", 4);
7401123f
GM
2000 }
2001 return s;
2002 /* static analysis guarentees a RETURN statement will be used before here. */
2003 __builtin_unreachable ();
2004}
2005
2006
2007/*
2008 Slice - returns a new string which contains the elements
2009 low..high-1
2010
2011 strings start at element 0
2012 Slice(s, 0, 2) will return elements 0, 1 but not 2
2013 Slice(s, 1, 3) will return elements 1, 2 but not 3
2014 Slice(s, 2, 0) will return elements 2..max
2015 Slice(s, 3, -1) will return elements 3..max-1
2016 Slice(s, 4, -2) will return elements 4..max-2
2017*/
2018
51bc4b81 2019extern "C" DynamicStrings_String DynamicStrings_Slice (DynamicStrings_String s, int low, int high)
7401123f
GM
2020{
2021 DynamicStrings_String d;
2022 DynamicStrings_String t;
2023 int start;
2024 int end;
2025 int o;
2026
2027 if (PoisonOn)
2028 {
dce2ffd5 2029 s = CheckPoisoned (s);
7401123f
GM
2030 }
2031 if (low < 0)
2032 {
dce2ffd5 2033 low = ((int ) (DynamicStrings_Length (s)))+low;
7401123f
GM
2034 }
2035 if (high <= 0)
2036 {
dce2ffd5 2037 high = ((int ) (DynamicStrings_Length (s)))+high;
7401123f
GM
2038 }
2039 else
2040 {
2041 /* make sure high is <= Length (s) */
d08981bf 2042 high = Min (DynamicStrings_Length (s), static_cast<unsigned int> (high));
7401123f 2043 }
dce2ffd5
GM
2044 d = DynamicStrings_InitString ((const char *) "", 0);
2045 d = AddToGarbage (d, s);
d08981bf 2046 o = 0;
7401123f
GM
2047 t = d;
2048 while (s != NULL)
2049 {
2050 if (low < (o+((int ) (s->contents.len))))
2051 {
2052 if (o > high)
2053 {
d08981bf 2054 s = NULL;
7401123f
GM
2055 }
2056 else
2057 {
2058 /* found sliceable unit */
2059 if (low < o)
2060 {
d08981bf 2061 start = 0;
7401123f
GM
2062 }
2063 else
2064 {
dce2ffd5 2065 start = low-o;
7401123f 2066 }
d08981bf 2067 end = Max (Min (MaxBuf, static_cast<unsigned int> (high-o)), 0);
7401123f
GM
2068 while (t->contents.len == MaxBuf)
2069 {
2070 if (t->contents.next == NULL)
2071 {
2072 Storage_ALLOCATE ((void **) &t->contents.next, sizeof (stringRecord));
d08981bf
GM
2073 t->contents.next->head = NULL;
2074 t->contents.next->contents.len = 0;
7401123f
GM
2075 AddDebugInfo (t->contents.next);
2076 if (TraceOn)
2077 {
06c977f8 2078 t->contents.next = AssignDebug (t->contents.next, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1388, (const char *) "Slice", 5);
7401123f
GM
2079 }
2080 }
2081 t = t->contents.next;
2082 }
51bc4b81 2083 ConcatContentsAddress (&t->contents, &s->contents.buf.array[start], static_cast<unsigned int> (end-start));
7401123f
GM
2084 o += s->contents.len;
2085 s = s->contents.next;
2086 }
2087 }
2088 else
2089 {
2090 o += s->contents.len;
2091 s = s->contents.next;
2092 }
2093 }
2094 if (TraceOn)
2095 {
06c977f8 2096 d = AssignDebug (d, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1405, (const char *) "Slice", 5);
7401123f
GM
2097 }
2098 return d;
2099 /* static analysis guarentees a RETURN statement will be used before here. */
2100 __builtin_unreachable ();
2101}
2102
2103
2104/*
2105 Index - returns the indice of the first occurance of, ch, in
2106 String, s. -1 is returned if, ch, does not exist.
2107 The search starts at position, o.
2108*/
2109
51bc4b81 2110extern "C" int DynamicStrings_Index (DynamicStrings_String s, char ch, unsigned int o)
7401123f
GM
2111{
2112 unsigned int i;
2113 unsigned int k;
2114
2115 if (PoisonOn)
2116 {
dce2ffd5 2117 s = CheckPoisoned (s);
7401123f 2118 }
d08981bf 2119 k = 0;
7401123f
GM
2120 while (s != NULL)
2121 {
2122 if ((k+s->contents.len) < o)
2123 {
2124 k += s->contents.len;
2125 }
2126 else
2127 {
dce2ffd5 2128 i = o-k;
7401123f
GM
2129 while (i < s->contents.len)
2130 {
2131 if (s->contents.buf.array[i] == ch)
2132 {
d08981bf 2133 return k+i;
7401123f
GM
2134 }
2135 i += 1;
2136 }
2137 k += i;
2138 o = k;
2139 }
2140 s = s->contents.next;
2141 }
d08981bf 2142 return -1;
7401123f
GM
2143 /* static analysis guarentees a RETURN statement will be used before here. */
2144 __builtin_unreachable ();
2145}
2146
2147
2148/*
2149 RIndex - returns the indice of the last occurance of, ch,
2150 in String, s. The search starts at position, o.
2151 -1 is returned if, ch, is not found.
2152*/
2153
51bc4b81 2154extern "C" int DynamicStrings_RIndex (DynamicStrings_String s, char ch, unsigned int o)
7401123f
GM
2155{
2156 unsigned int i;
2157 unsigned int k;
2158 int j;
2159
2160 if (PoisonOn)
2161 {
dce2ffd5 2162 s = CheckPoisoned (s);
7401123f 2163 }
d08981bf
GM
2164 j = -1;
2165 k = 0;
7401123f
GM
2166 while (s != NULL)
2167 {
2168 if ((k+s->contents.len) < o)
2169 {
2170 k += s->contents.len;
2171 }
2172 else
2173 {
2174 if (o < k)
2175 {
d08981bf 2176 i = 0;
7401123f
GM
2177 }
2178 else
2179 {
dce2ffd5 2180 i = o-k;
7401123f
GM
2181 }
2182 while (i < s->contents.len)
2183 {
2184 if (s->contents.buf.array[i] == ch)
2185 {
d08981bf 2186 j = k;
7401123f
GM
2187 }
2188 k += 1;
2189 i += 1;
2190 }
2191 }
2192 s = s->contents.next;
2193 }
2194 return j;
2195 /* static analysis guarentees a RETURN statement will be used before here. */
2196 __builtin_unreachable ();
2197}
2198
2199
2200/*
2201 RemoveComment - assuming that, comment, is a comment delimiter
2202 which indicates anything to its right is a comment
2203 then strip off the comment and also any white space
2204 on the remaining right hand side.
2205 It leaves any white space on the left hand side alone.
2206*/
2207
51bc4b81 2208extern "C" DynamicStrings_String DynamicStrings_RemoveComment (DynamicStrings_String s, char comment)
7401123f
GM
2209{
2210 int i;
2211
dce2ffd5 2212 i = DynamicStrings_Index (s, comment, 0);
7401123f
GM
2213 if (i == 0)
2214 {
dce2ffd5 2215 s = DynamicStrings_InitString ((const char *) "", 0);
7401123f
GM
2216 }
2217 else if (i > 0)
2218 {
2219 /* avoid dangling else. */
dce2ffd5 2220 s = DynamicStrings_RemoveWhitePostfix (DynamicStrings_Slice (DynamicStrings_Mark (s), 0, i));
7401123f
GM
2221 }
2222 if (TraceOn)
2223 {
06c977f8 2224 s = AssignDebug (s, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1517, (const char *) "RemoveComment", 13);
7401123f
GM
2225 }
2226 return s;
2227 /* static analysis guarentees a RETURN statement will be used before here. */
2228 __builtin_unreachable ();
2229}
2230
2231
2232/*
2233 RemoveWhitePrefix - removes any leading white space from String, s.
2234 A new string is returned.
2235*/
2236
51bc4b81 2237extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePrefix (DynamicStrings_String s)
7401123f
GM
2238{
2239 unsigned int i;
2240
d08981bf 2241 i = 0;
51bc4b81 2242 while (IsWhite (DynamicStrings_char (s, static_cast<int> (i))))
7401123f
GM
2243 {
2244 i += 1;
2245 }
dce2ffd5 2246 s = DynamicStrings_Slice (s, (int ) (i), 0);
7401123f
GM
2247 if (TraceOn)
2248 {
06c977f8 2249 s = AssignDebug (s, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1629, (const char *) "RemoveWhitePrefix", 17);
7401123f
GM
2250 }
2251 return s;
2252 /* static analysis guarentees a RETURN statement will be used before here. */
2253 __builtin_unreachable ();
2254}
2255
2256
2257/*
2258 RemoveWhitePostfix - removes any leading white space from String, s.
2259 A new string is returned.
2260*/
2261
51bc4b81 2262extern "C" DynamicStrings_String DynamicStrings_RemoveWhitePostfix (DynamicStrings_String s)
7401123f
GM
2263{
2264 int i;
2265
dce2ffd5 2266 i = ((int ) (DynamicStrings_Length (s)))-1;
7401123f
GM
2267 while ((i >= 0) && (IsWhite (DynamicStrings_char (s, i))))
2268 {
2269 i -= 1;
2270 }
dce2ffd5 2271 s = DynamicStrings_Slice (s, 0, i+1);
7401123f
GM
2272 if (TraceOn)
2273 {
06c977f8 2274 s = AssignDebug (s, (const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 1651, (const char *) "RemoveWhitePostfix", 18);
7401123f
GM
2275 }
2276 return s;
2277 /* static analysis guarentees a RETURN statement will be used before here. */
2278 __builtin_unreachable ();
2279}
2280
2281
2282/*
2283 ToUpper - returns string, s, after it has had its lower case characters
2284 replaced by upper case characters.
2285 The string, s, is not duplicated.
2286*/
2287
51bc4b81 2288extern "C" DynamicStrings_String DynamicStrings_ToUpper (DynamicStrings_String s)
7401123f
GM
2289{
2290 char ch;
2291 unsigned int i;
2292 DynamicStrings_String t;
2293
2294 if (s != NULL)
2295 {
2296 MarkInvalid (s);
2297 t = s;
2298 while (t != NULL)
2299 {
d08981bf 2300 i = 0;
7401123f
GM
2301 while (i < t->contents.len)
2302 {
2303 ch = t->contents.buf.array[i];
2304 if ((ch >= 'a') && (ch <= 'z'))
2305 {
2306 t->contents.buf.array[i] = ((char) (( ((unsigned int) (ch))- ((unsigned int) ('a')))+ ((unsigned int) ('A'))));
2307 }
2308 i += 1;
2309 }
2310 t = t->contents.next;
2311 }
2312 }
2313 return s;
2314 /* static analysis guarentees a RETURN statement will be used before here. */
2315 __builtin_unreachable ();
2316}
2317
2318
2319/*
2320 ToLower - returns string, s, after it has had its upper case characters
2321 replaced by lower case characters.
2322 The string, s, is not duplicated.
2323*/
2324
51bc4b81 2325extern "C" DynamicStrings_String DynamicStrings_ToLower (DynamicStrings_String s)
7401123f
GM
2326{
2327 char ch;
2328 unsigned int i;
2329 DynamicStrings_String t;
2330
2331 if (s != NULL)
2332 {
2333 MarkInvalid (s);
2334 t = s;
2335 while (t != NULL)
2336 {
d08981bf 2337 i = 0;
7401123f
GM
2338 while (i < t->contents.len)
2339 {
2340 ch = t->contents.buf.array[i];
2341 if ((ch >= 'A') && (ch <= 'Z'))
2342 {
2343 t->contents.buf.array[i] = ((char) (( ((unsigned int) (ch))- ((unsigned int) ('A')))+ ((unsigned int) ('a'))));
2344 }
2345 i += 1;
2346 }
2347 t = t->contents.next;
2348 }
2349 }
2350 return s;
2351 /* static analysis guarentees a RETURN statement will be used before here. */
2352 __builtin_unreachable ();
2353}
2354
2355
2356/*
2357 CopyOut - copies string, s, to a.
2358*/
2359
51bc4b81 2360extern "C" void DynamicStrings_CopyOut (char *a, unsigned int _a_high, DynamicStrings_String s)
7401123f
GM
2361{
2362 unsigned int i;
2363 unsigned int l;
2364
dce2ffd5 2365 l = Min (_a_high+1, DynamicStrings_Length (s));
d08981bf 2366 i = 0;
7401123f
GM
2367 while (i < l)
2368 {
dce2ffd5 2369 a[i] = DynamicStrings_char (s, static_cast<int> (i));
7401123f
GM
2370 i += 1;
2371 }
2372 if (i <= _a_high)
2373 {
2374 a[i] = ASCII_nul;
2375 }
2376}
2377
2378
2379/*
2380 char - returns the character, ch, at position, i, in String, s.
2381*/
2382
51bc4b81 2383extern "C" char DynamicStrings_char (DynamicStrings_String s, int i)
7401123f
GM
2384{
2385 unsigned int c;
2386
2387 if (PoisonOn)
2388 {
dce2ffd5 2389 s = CheckPoisoned (s);
7401123f
GM
2390 }
2391 if (i < 0)
2392 {
2393 c = (unsigned int ) (((int ) (DynamicStrings_Length (s)))+i);
2394 }
2395 else
2396 {
d08981bf 2397 c = i;
7401123f
GM
2398 }
2399 while ((s != NULL) && (c >= s->contents.len))
2400 {
2401 c -= s->contents.len;
2402 s = s->contents.next;
2403 }
2404 if ((s == NULL) || (c >= s->contents.len))
2405 {
2406 return ASCII_nul;
2407 }
2408 else
2409 {
2410 return s->contents.buf.array[c];
2411 }
2412 /* static analysis guarentees a RETURN statement will be used before here. */
2413 __builtin_unreachable ();
2414}
2415
2416
2417/*
2418 string - returns the C style char * of String, s.
2419*/
2420
51bc4b81 2421extern "C" void * DynamicStrings_string (DynamicStrings_String s)
7401123f 2422{
51bc4b81
GM
2423 typedef char *_T2;
2424
7401123f
GM
2425 DynamicStrings_String a;
2426 unsigned int l;
2427 unsigned int i;
51bc4b81 2428 _T2 p;
7401123f
GM
2429
2430 if (PoisonOn)
2431 {
dce2ffd5 2432 s = CheckPoisoned (s);
7401123f
GM
2433 }
2434 if (s == NULL)
2435 {
2436 return NULL;
2437 }
2438 else
2439 {
2440 if (! s->head->charStarValid)
2441 {
dce2ffd5 2442 l = DynamicStrings_Length (s);
7401123f
GM
2443 if (! (s->head->charStarUsed && (s->head->charStarSize > l)))
2444 {
2445 DeallocateCharStar (s);
2446 Storage_ALLOCATE (&s->head->charStar, l+1);
dce2ffd5 2447 s->head->charStarSize = l+1;
7401123f
GM
2448 s->head->charStarUsed = TRUE;
2449 }
51bc4b81 2450 p = static_cast<_T2> (s->head->charStar);
7401123f
GM
2451 a = s;
2452 while (a != NULL)
2453 {
d08981bf 2454 i = 0;
7401123f
GM
2455 while (i < a->contents.len)
2456 {
2457 (*p) = a->contents.buf.array[i];
2458 i += 1;
2459 p += 1;
2460 }
2461 a = a->contents.next;
2462 }
2463 (*p) = ASCII_nul;
2464 s->head->charStarValid = TRUE;
2465 }
2466 return s->head->charStar;
2467 }
2468 /* static analysis guarentees a RETURN statement will be used before here. */
2469 __builtin_unreachable ();
2470}
2471
2472
2473/*
2474 InitStringDB - the debug version of InitString.
2475*/
2476
51bc4b81 2477extern "C" DynamicStrings_String DynamicStrings_InitStringDB (const char *a_, unsigned int _a_high, const char *file_, unsigned int _file_high, unsigned int line)
7401123f
GM
2478{
2479 char a[_a_high+1];
2480 char file[_file_high+1];
2481
2482 /* make a local copy of each unbounded array. */
2483 memcpy (a, a_, _a_high+1);
2484 memcpy (file, file_, _file_high+1);
2485
dce2ffd5 2486 return AssignDebug (DynamicStrings_InitString ((const char *) a, _a_high), (const char *) file, _file_high, line, (const char *) "InitString", 10);
7401123f
GM
2487 /* static analysis guarentees a RETURN statement will be used before here. */
2488 __builtin_unreachable ();
2489}
2490
2491
2492/*
2493 InitStringCharStarDB - the debug version of InitStringCharStar.
2494*/
2495
51bc4b81 2496extern "C" DynamicStrings_String DynamicStrings_InitStringCharStarDB (void * a, const char *file_, unsigned int _file_high, unsigned int line)
7401123f
GM
2497{
2498 char file[_file_high+1];
2499
2500 /* make a local copy of each unbounded array. */
2501 memcpy (file, file_, _file_high+1);
2502
dce2ffd5 2503 return AssignDebug (DynamicStrings_InitStringCharStar (a), (const char *) file, _file_high, line, (const char *) "InitStringCharStar", 18);
7401123f
GM
2504 /* static analysis guarentees a RETURN statement will be used before here. */
2505 __builtin_unreachable ();
2506}
2507
2508
2509/*
2510 InitStringCharDB - the debug version of InitStringChar.
2511*/
2512
51bc4b81 2513extern "C" DynamicStrings_String DynamicStrings_InitStringCharDB (char ch, const char *file_, unsigned int _file_high, unsigned int line)
7401123f
GM
2514{
2515 char file[_file_high+1];
2516
2517 /* make a local copy of each unbounded array. */
2518 memcpy (file, file_, _file_high+1);
2519
dce2ffd5 2520 return AssignDebug (DynamicStrings_InitStringChar (ch), (const char *) file, _file_high, line, (const char *) "InitStringChar", 14);
7401123f
GM
2521 /* static analysis guarentees a RETURN statement will be used before here. */
2522 __builtin_unreachable ();
2523}
2524
2525
2526/*
2527 MultDB - the debug version of MultDB.
2528*/
2529
51bc4b81 2530extern "C" DynamicStrings_String DynamicStrings_MultDB (DynamicStrings_String s, unsigned int n, const char *file_, unsigned int _file_high, unsigned int line)
7401123f
GM
2531{
2532 char file[_file_high+1];
2533
2534 /* make a local copy of each unbounded array. */
2535 memcpy (file, file_, _file_high+1);
2536
dce2ffd5 2537 return AssignDebug (DynamicStrings_Mult (s, n), (const char *) file, _file_high, line, (const char *) "Mult", 4);
7401123f
GM
2538 /* static analysis guarentees a RETURN statement will be used before here. */
2539 __builtin_unreachable ();
2540}
2541
2542
2543/*
2544 DupDB - the debug version of Dup.
2545*/
2546
51bc4b81 2547extern "C" DynamicStrings_String DynamicStrings_DupDB (DynamicStrings_String s, const char *file_, unsigned int _file_high, unsigned int line)
7401123f
GM
2548{
2549 char file[_file_high+1];
2550
2551 /* make a local copy of each unbounded array. */
2552 memcpy (file, file_, _file_high+1);
2553
dce2ffd5 2554 return AssignDebug (DynamicStrings_Dup (s), (const char *) file, _file_high, line, (const char *) "Dup", 3);
7401123f
GM
2555 /* static analysis guarentees a RETURN statement will be used before here. */
2556 __builtin_unreachable ();
2557}
2558
2559
2560/*
2561 SliceDB - debug version of Slice.
2562*/
2563
51bc4b81 2564extern "C" DynamicStrings_String DynamicStrings_SliceDB (DynamicStrings_String s, int low, int high, const char *file_, unsigned int _file_high, unsigned int line)
7401123f
GM
2565{
2566 char file[_file_high+1];
2567
2568 /* make a local copy of each unbounded array. */
2569 memcpy (file, file_, _file_high+1);
2570
2571 DSdbEnter ();
dce2ffd5 2572 s = AssignDebug (DynamicStrings_Slice (s, low, high), (const char *) file, _file_high, line, (const char *) "Slice", 5);
7401123f
GM
2573 DSdbExit (s);
2574 return s;
2575 /* static analysis guarentees a RETURN statement will be used before here. */
2576 __builtin_unreachable ();
2577}
2578
2579
2580/*
2581 PushAllocation - pushes the current allocation/deallocation lists.
2582*/
2583
51bc4b81 2584extern "C" void DynamicStrings_PushAllocation (void)
7401123f
GM
2585{
2586 frame f;
2587
2588 if (CheckOn)
2589 {
2590 Init ();
2591 Storage_ALLOCATE ((void **) &f, sizeof (frameRec));
2592 f->next = frameHead;
d08981bf
GM
2593 f->alloc = NULL;
2594 f->dealloc = NULL;
7401123f
GM
2595 frameHead = f;
2596 }
2597}
2598
2599
2600/*
2601 PopAllocation - test to see that all strings are deallocated since
2602 the last push. Then it pops to the previous
2603 allocation/deallocation lists.
2604
2605 If halt is true then the application terminates
2606 with an exit code of 1.
2607*/
2608
51bc4b81 2609extern "C" void DynamicStrings_PopAllocation (unsigned int halt)
7401123f
GM
2610{
2611 if (CheckOn)
2612 {
d08981bf 2613 if ((DynamicStrings_PopAllocationExemption (halt, NULL)) == NULL)
7401123f
GM
2614 {} /* empty. */
2615 }
2616}
2617
2618
2619/*
2620 PopAllocationExemption - test to see that all strings are deallocated, except
2621 string, e, since the last push.
2622 Then it pops to the previous allocation/deallocation
2623 lists.
2624
2625 If halt is true then the application terminates
2626 with an exit code of 1.
2627*/
2628
51bc4b81 2629extern "C" DynamicStrings_String DynamicStrings_PopAllocationExemption (unsigned int halt, DynamicStrings_String e)
7401123f
GM
2630{
2631 DynamicStrings_String s;
2632 frame f;
2633 unsigned int b;
2634
2635 Init ();
2636 if (CheckOn)
2637 {
2638 /* avoid gcc warning by using compound statement even if not strictly necessary. */
2639 if (frameHead == NULL)
2640 {
2641 stop ();
2642 /* writeString ("mismatched number of PopAllocation's compared to PushAllocation's") */
06c977f8 2643 M2RTS_Halt ((const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/DynamicStrings.mod", 62, 176, (const char *) "PopAllocationExemption", 22, (const char *) "mismatched number of PopAllocation's compared to PushAllocation's", 65);
7401123f
GM
2644 }
2645 else
2646 {
2647 if (frameHead->alloc != NULL)
2648 {
2649 b = FALSE;
2650 s = frameHead->alloc;
2651 while (s != NULL)
2652 {
2653 if (! (((e == s) || (IsOnGarbage (e, s))) || (IsOnGarbage (s, e))))
2654 {
2655 if (! b)
2656 {
51bc4b81 2657 writeString ((const char *) "the following strings have been lost", 36);
7401123f
GM
2658 writeLn ();
2659 b = TRUE;
2660 }
2661 DumpStringInfo (s, 0);
2662 }
2663 s = s->debug.next;
2664 }
2665 if (b && halt)
2666 {
2667 libc_exit (1);
2668 }
2669 }
2670 frameHead = frameHead->next;
2671 }
2672 }
2673 return e;
2674 /* static analysis guarentees a RETURN statement will be used before here. */
2675 __builtin_unreachable ();
2676}
2677
206c4f77 2678extern "C" void _M2_DynamicStrings_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
7401123f
GM
2679{
2680 Initialized = FALSE;
2681 Init ();
2682}
2683
206c4f77 2684extern "C" void _M2_DynamicStrings_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
7401123f
GM
2685{
2686}
This page took 0.355939 seconds and 5 git commands to generate.