1 /*
2 Z88DK Z80 Macro Assembler
3 
4 Dynamic strings
5 
6 Copyright (C) Gunther Strube, InterLogic 1993-99
7 Copyright (C) Paulo Custodio, 2011-2020
8 License: The Artistic License 2.0, http://www.perlfoundation.org/artistic_license_2_0
9 Repository: https://github.com/z88dk/z88dk
10 */
11 
12 #pragma once
13 
14 #include "alloc.h"
15 #include "dbg.h"
16 #include "types.h"
17 #include <stdio.h>
18 #include <stdarg.h>
19 
20 #ifndef va_copy
21 #define va_copy(dst, src)  ((void)((dst) = (src)))
22 #endif
23 
24 /* maximum length of strings, must be at least FILENAME_MAX */
25 #include <stdio.h>			/* FILENAME_MAX */
26 #define MAXLINE			MAX( 1024, FILENAME_MAX )
27 
28 /*-----------------------------------------------------------------------------
29 *   Str structure
30 *----------------------------------------------------------------------------*/
31 typedef struct _Str {
32 	char   *data;				/* point at string data */
33 	int 	len;				/* length of string */
34 	int		size;				/* size of allocated buffer > len to allow for '\0' */
35 	struct {
ReadTopology(string filename,Topology & top)36 		bool	header_alloc : 1;	/* true if header is allocated in the heap */
37 		bool	data_alloc   : 1;	/* true if data is allocated in the heap
38 									   and can be reallocated and freed */
39 	} flag;
40 } Str;
41 
42 /*-----------------------------------------------------------------------------
43 *   declare and define an initialized Str * as global or static variable
44 *	if string is expanded, data is copied to a malloc'ed area
45 *	use STR_DELETE at the end of functions having STR_DEFINE to free
46 *	that memory
ReadTopolFile(string file)47 *----------------------------------------------------------------------------*/
48 #define STR_DECLARE( name )			Str *name
49 
50 #define STR_DEFINE( name, size )	struct { \
51 										char data[ (size) ]; \
52 										Str  str; \
53 									} _##name##_data = { \
54 										"", \
55 										{ _##name##_data.data, 0, (size), \
56 										  { false, false } } \
ParseRoot(tools::Property & property)57 									}; \
58 									Str *name = & _##name##_data.str
59 
60 #define STR_DELETE( name )			Str_delete( name )
61 
62 #ifndef STR_SIZE
63 #define STR_SIZE					MAX(256, FILENAME_MAX)	/* default string size */
64 #endif
65 
66 /*-----------------------------------------------------------------------------
67 *   Accessors
68 *----------------------------------------------------------------------------*/
69 #define Str_data( str )				( (str)->data )
70 #define Str_len( str )				( (str)->len )
71 #define Str_size( str )				( (str)->size )
72 
73 /*-----------------------------------------------------------------------------
74 *   initialize and delete
75 *----------------------------------------------------------------------------*/
76 
77 /* allocate a Str on the heap and return pointer; die on error */
78 extern Str *Str_new_(int size);
79 #define     Str_new( size )			(check_ptr_die(Str_new_(size), != NULL, "Str_new failed" ))
80 
81 /* free a string */
82 extern void Str_delete_(Str *str);
83 #define     Str_delete( str )		(Str_delete_(str), (str) = NULL)
ParseBox(tools::Property & p)84 
85 /* reserve space for at least more size chars plus '\0'
86    does nothing if buffer is already large enough */
87 extern void Str_reserve(Str *str, int size);
88 
89 /*-----------------------------------------------------------------------------
90 *   Set strings
91 *----------------------------------------------------------------------------*/
ParseMolecules(tools::Property & p)92 
93 /* clear the string, keep allocated space */
94 extern void Str_clear(Str *str);
95 
96 /* sync length in case string was modified in place */
97 extern void Str_sync_len(Str *str);
98 
99 /* set / append string */
100 extern void Str_set(Str *str, const char *source);
101 extern void Str_append(Str *str, const char *source);
102 
103 /* set / append substring */
104 extern void Str_set_n(Str *str, const char *source, int count);
105 extern void Str_append_n(Str *str, const char *source, int count);
106 
107 /* set / append bytes */
108 extern void Str_set_bytes(Str *str, const char *source, int size);
109 extern void Str_append_bytes(Str *str, const char *source, int size);
110 
111 /* set / append char */
112 extern void Str_set_char(Str *str, char ch);
113 extern void Str_append_char(Str *str, char ch);
114 
115 /* set / append with printf-like parameters */
116 extern void Str_sprintf(Str *str, const char *format, ...);
117 extern void Str_append_sprintf(Str *str, const char *format, ...);
118 
119 /* set / append with va_list argument */
120 extern void Str_vsprintf(Str *str, const char *format, va_list argptr);
121 extern void Str_append_vsprintf(Str *str, const char *format, va_list argptr);
122 
123 /*-----------------------------------------------------------------------------
124 *   Modify strings
125 *----------------------------------------------------------------------------*/
126 
127 /* get one line from input, convert end-of-line sequences,
128 *  return string including one LF character
129 *  return false on end of input */
130 extern bool Str_getline(Str *str, FILE *fp);
131