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