1 #ifndef PARS_H
2 /*
3  * Simple ASCII file parsing object.
4  * Used as a base for the CGATS.5 and IT8.7 family file I/O class
5  */
6 
7 /*
8  * Version 2.01
9  *
10  * Author: Graeme W. Gill
11  * Date:   20/12/95
12  *
13  * Copyright 1995, 1996, 2002 Graeme W. Gill
14  * All rights reserved.
15  *
16  * This material is licensed with an "MIT" free use license:-
17  * see the License4.txt file in this directory for licensing details.
18  */
19 
20 #ifdef __cplusplus
21 	extern "C" {
22 #endif
23 
24 #undef CGATS_DEBUG_MALLOC	/* Turns on partial support for filename and linenumber capture */
25 
26 /* - - - - - - - - - - - - - - - - - - - - -  */
27 
28 /* System interface objects. The defaults can be replaced */
29 /* for adaption to different system environments */
30 
31 /* - - - - - - - - - - - - - - - - - - - - -  */
32 
33 #ifdef CGATS_DEBUG_MALLOC
34 
35 /* Heap allocator class interface definition */
36 #define CGATS_ALLOC_BASE																	\
37 	/* Public: */																			\
38 																							\
39 	void *(*dmalloc) (struct _cgatsAlloc *p, size_t size, char *file, int line);			\
40 	void *(*dcalloc) (struct _cgatsAlloc *p, size_t num, size_t size, char *file, int line);\
41 	void *(*drealloc)(struct _cgatsAlloc *p, void *ptr, size_t size, char *file, int line);	\
42 	void  (*dfree)   (struct _cgatsAlloc *p, void *ptr, char *file, int line);				\
43 																							\
44 	/* we're done with the allocator object */												\
45 	void (*del)(struct _cgatsAlloc *p);														\
46 
47 #if defined(_PARS_C_) || defined(_CGATS_C_)	|| defined(_PARSSTD_C_) /* only inside implimentation */
48 #define malloc( p, size )	    dmalloc( p, size, __FILE__, __LINE__ )
49 #define calloc( p, num, size )	dcalloc( p, num, size, __FILE__, __LINE__ )
50 #define realloc( p, ptr, size )	drealloc( p, ptr, size, __FILE__, __LINE__ )
51 #define free( p, ptr )	        dfree( p, ptr , __FILE__, __LINE__ )
52 #endif
53 
54 #else /* !CGATS_DEBUG_MALLOC */
55 
56 /* Heap allocator class interface definition */
57 #define CGATS_ALLOC_BASE																	\
58 	/* Public: */																			\
59 																							\
60 	void *(*malloc) (struct _cgatsAlloc *p, size_t size);									\
61 	void *(*calloc) (struct _cgatsAlloc *p, size_t num, size_t size);						\
62 	void *(*realloc)(struct _cgatsAlloc *p, void *ptr, size_t size);						\
63 	void  (*free)   (struct _cgatsAlloc *p, void *ptr);										\
64 																							\
65 	/* we're done with the allocator object */												\
66 	void (*del)(struct _cgatsAlloc *p);														\
67 
68 #endif /* !CGATS_DEBUG_MALLOC */
69 
70 /* Common heap allocator interface class */
71 struct _cgatsAlloc {
72 	CGATS_ALLOC_BASE
73 }; typedef struct _cgatsAlloc cgatsAlloc;
74 
75 /* - - - - - - - - - - - - - - - - - - - - -  */
76 
77 /* Available when SEPARATE_STD is not defined: */
78 /* Implementation of heap class based on standard system malloc */
79 struct _cgatsAllocStd {
80 	CGATS_ALLOC_BASE
81 }; typedef struct _cgatsAllocStd cgatsAllocStd;
82 
83 /* Create a standard alloc object */
84 cgatsAlloc *new_cgatsAllocStd(void);
85 
86 
87 /* - - - - - - - - - - - - - - - - - - - - -  */
88 
89 /* File access class interface definition */
90 #define CGATS_FILE_BASE																		\
91 	/* Public: */																			\
92 																							\
93 	/* Get the size of the file (Only valid for reading file). */							\
94 	size_t (*get_size) (struct _cgatsFile *p);												\
95 																							\
96 	/* Set current position to offset. Return 0 on success, nz on failure. */				\
97 	int    (*seek) (struct _cgatsFile *p, unsigned int offset);									\
98 																							\
99 	/* Read count items of size length. Return number of items successfully read. */ 		\
100 	size_t (*read) (struct _cgatsFile *p, void *buffer, size_t size, size_t count);			\
101 																							\
102 	/* Read a single character */													 		\
103 	int (*getch) (struct _cgatsFile *p);													\
104 																							\
105 	/* write count items of size length. Return number of items successfully written. */ 	\
106 	size_t (*write)(struct _cgatsFile *p, void *buffer, size_t size, size_t count);			\
107 																							\
108 	/* printf to the file */																\
109 	int (*gprintf)(struct _cgatsFile *p, const char *format, ...);							\
110 																							\
111 	/* flush all write data out to secondary storage. Return nz on failure. */				\
112 	int (*flush)(struct _cgatsFile *p);														\
113 																							\
114 	/* return the filename if known, NULL if not */											\
115 	char *(*fname)(struct _cgatsFile *p);													\
116 																							\
117 	/* Return the memory buffer. Error if not cgatsFileMem */								\
118 	int (*get_buf)(struct _cgatsFile *p, unsigned char **buf, size_t *len);					\
119 																							\
120 	/* we're done with the file object, close & free it */									\
121 	/* return nz on failure */																\
122 	int (*del)(struct _cgatsFile *p);														\
123 
124 /* Common file interface class */
125 struct _cgatsFile {
126 	CGATS_FILE_BASE
127 }; typedef struct _cgatsFile cgatsFile;
128 
129 
130 /* - - - - - - - - - - - - - - - - - - - - -  */
131 
132 /* Available when SEPARATE_STD is not defined: */
133 
134 /* Implementation of file access class based on standard file I/O */
135 struct _cgatsFileStd {
136 	CGATS_FILE_BASE
137 
138 	/* Private: */
139 	cgatsAlloc *al;		/* Heap allocator */
140 	int      del_al;	/* NZ if heap allocator should be deleted */
141 	FILE     *fp;
142 	int   doclose;		/* nz if free should close */
143 	char *filename;		/* NULL if not known */
144 
145 	/* Private: */
146 	size_t size;    /* Size of the file (For read) */
147 
148 }; typedef struct _cgatsFileStd cgatsFileStd;
149 
150 /* Create given a file name */
151 cgatsFile *new_cgatsFileStd_name(const char *name, const char *mode);
152 
153 /* Create given a (binary) FILE* */
154 cgatsFile *new_cgatsFileStd_fp(FILE *fp);
155 
156 /* Create given a file name and allocator */
157 cgatsFile *new_cgatsFileStd_name_a(const char *name, const char *mode, cgatsAlloc *al);
158 
159 /* Create given a (binary) FILE* and allocator */
160 cgatsFile *new_cgatsFileStd_fp_a(FILE *fp, cgatsAlloc *al);
161 
162 
163 /* - - - - - - - - - - - - - - - - - - - - -  */
164 /* Implementation of file access class based on a memory image */
165 /* The buffer is assumed to be allocated with the given heap allocator */
166 /* Pass base = NULL, length = 0 for no initial buffer */
167 
168 /* ~~ should ad method that returns buffer and length */
169 
170 struct _cgatsFileMem {
171 	CGATS_FILE_BASE
172 
173 	/* Private: */
174 	cgatsAlloc *al;		/* Heap allocator */
175 	int      del_al;	/* NZ if heap allocator should be deleted */
176 	int      del_buf;	/* NZ if memory file buffer should be deleted */
177 	unsigned char *start, *cur, *end, *aend;
178 
179 }; typedef struct _cgatsFileMem cgatsFileMem;
180 
181 /* Create a memory image file access class with given allocator */
182 /* The buffer is not delete with the object. */
183 cgatsFile *new_cgatsFileMem_a(void *base, size_t length, cgatsAlloc *al);
184 
185 /* Create a memory image file access class with given allocator */
186 /* and delete buffer when cgatsFile is deleted. */
187 cgatsFile *new_cgatsFileMem_ad(void *base, size_t length, cgatsAlloc *al);
188 
189 /* This is avalailable if SEPARATE_STD is not defined: */
190 
191 /* Create a memory image file access class with the std allocator */
192 /* The buffer is not delete with the object. */
193 cgatsFile *new_cgatsFileMem(void *base, size_t length);
194 
195 /* Create a memory image file access class with the std allocator */
196 /* and delete buffer when cgatsFile is deleted. */
197 cgatsFile *new_cgatsFileMem_d(void *base, size_t length);
198 
199 
200 /* - - - - - - - - - - - - - - - - - - - - -  */
201 
202 struct _parse {
203 	/* Public Variables */
204 	int line;		/* Current line number */
205 	int token;		/* Current token number */
206 
207 	/* Public Methods */
208 	void (*del)(struct _parse *p);				/* Delete the object */
209 	void (*reset_del)(struct _parse *p);		/* Reset the parsing delimiters */
210 	void (*add_del)(struct _parse *p,			/* Add to the parsing delimiters */
211 	    char *t, char *nr,
212 	    char *c, char *q);
213 	int (*read_line)(struct _parse *p);			/* Read in a line. Return 0 if read failed, */
214 												/* -1 on other error */
215 	char *(*get_token)(struct _parse *p);		/* Return a pointer to the next token, */
216 												/* NULL if no tokens. set errc NZ on other error */
217 
218 	/* Private */
219 	cgatsAlloc *al;	/* Memory allocator */
220 	int del_al;		/* Flag to indicate we al->del() */
221 	cgatsFile *fp;	/* File we're dealing with */
222 	int ltflag;		/* Last terminator flag */
223 	int q;			/* Quote */
224 	char *b;		/* Line buffer */
225 	int bs;			/* Buffer size */
226 	int bo;			/* Next buffer offset */
227 	int to;			/* Token parsing offset into b */
228 	char *tb;		/* Token buffer */
229 	int tbs;		/* Token buffer size */
230 	char delf[256];		/* Parsing delimiter flags */
231 	/* Parsing flags */
232 #define PARS_TERM	0x01		/* Terminates a token */
233 #define PARS_SKIP	0x02		/* Character is not read */
234 #define PARS_COMM	0x04		/* Character starts a comment */
235 #define PARS_QUOTE	0x08		/* Character starts/ends a quoted string */
236 
237 	char err[200];		/* Error message */
238 	int errc;			/* Error code */
239 }; typedef struct _parse parse;
240 
241 /* Creator */
242 extern parse *new_parse_al(cgatsAlloc *al, cgatsFile *fp);	/* With allocator class */
243 
244 /* Available when SEPARATE_STD is not defined: */
245 extern parse *new_parse(cgatsFile *fp);					/* Default allocator */
246 
247 #ifdef __cplusplus
248 	}
249 #endif
250 
251 #define PARS_H
252 #endif /* PARS_H */
253 
254