Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gml_scanner.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file gml_scanner.cpp
1 /* This software is distributed under the GNU Lesser General Public License */
2 //==========================================================================
3 //
4 // gml_scanner.cpp - Scanner for the GML - file format
5 //
6 //==========================================================================
7 // $Id: gml_scanner.cpp,v 1.10 2001/11/07 13:58:10 pick Exp $
8 
9 #include <GTL/gml_scanner.h>
10 
11 #include <cstdlib>
12 #include <cctype>
13 #include <cassert>
14 #include <cstring>
15 
16 #ifdef __GTL_MSVCC
17 # ifdef _DEBUG
18 # ifndef SEARCH_MEMORY_LEAKS_ENABLED
19 # error SEARCH NOT ENABLED
20 # endif
21 # define new DEBUG_NEW
22 # undef THIS_FILE
23  static char THIS_FILE[] = __FILE__;
24 # endif // _DEBUG
25 #endif // __GTL_MSVCC
26 
28 
29 /*
30  * ISO8859-1 coding of chars >= 160
31  */
32 
33 const char* GML_table[] = {
34  "&nbsp;", /* 160 */
35  "&iexcl;",
36  "&cent;",
37  "&pound;",
38  "&curren;",
39  "&yen;",
40  "&brvbar;",
41  "&sect;",
42  "&uml;",
43  "&copy;",
44  "&ordf;", /* 170 */
45  "&laquo;",
46  "&not;",
47  "&shy;",
48  "&reg;",
49  "&macr;",
50  "&deg;",
51  "&plusmn;",
52  "&sup2;",
53  "&sup3;", /* 180 */
54  "&acute;",
55  "&micro;",
56  "&para;",
57  "&middot;",
58  "&cedil;",
59  "&sup1;",
60  "&ordm;",
61  "&raquo;",
62  "&frac14;",
63  "&frac12;",
64  "&frac34;", /* 190 */
65  "&iquest;",
66  "&Agrave;",
67  "&Aacute;",
68  "&Acirc;",
69  "&Atilde;",
70  "&Auml;",
71  "&Aring;",
72  "&AElig;",
73  "&Ccedil;",
74  "&Egrave;", /* 200 */
75  "&Eacute;",
76  "&Ecirc;",
77  "&Euml;",
78  "&Igrave;",
79  "&Iacute;",
80  "&Icirc;",
81  "&Iuml;",
82  "&ETH;",
83  "&Ntilde;",
84  "&Ograve;", /* 210 */
85  "&Oacute;",
86  "&Ocirc;",
87  "&Otilde;",
88  "&Ouml;",
89  "&times;",
90  "&Oslash;",
91  "&Ugrave;",
92  "&Uacute;",
93  "&Ucirc;",
94  "&Uuml;", /* 220 */
95  "&Yacute;",
96  "&THORN;",
97  "&szlig;",
98  "&agrave;",
99  "&aacute;",
100  "&acirc;",
101  "&atilde;",
102  "&auml;",
103  "&aring;",
104  "&aelig;", /* 230 */
105  "&ccedil;",
106  "&egrave;",
107  "&eacute;",
108  "&ecirc;",
109  "&euml;",
110  "&igrave;",
111  "&iacute;",
112  "&icirc;",
113  "&iuml;",
114  "&eth;", /* 240 */
115  "&ntilde;",
116  "&ograve;",
117  "&oacute;",
118  "&ocirc;",
119  "&otilde;",
120  "&ouml;",
121  "&divide;",
122  "&oslash;",
123  "&ugrave;",
124  "&uacute;", /* 250 */
125  "&ucirc;",
126  "&uuml;",
127  "&yacute;",
128  "&thorn;",
129  "&yuml;"
130 };
131 
132 
133 unsigned int GML_line;
134 unsigned int GML_column;
135 
136 
137 int GML_search_ISO (char* str, int len) {
138 
139  int i;
140  int ret = '&';
141 
142  //
143  // First check the extraordinary ones
144  //
145 
146  if (!strncmp (str, "&quot;", len)) {
147  return 34;
148  } else if (!strncmp (str, "&amp;", len)) {
149  return 38;
150  } else if (!strncmp (str, "&lt;", len)) {
151  return 60;
152  } else if (!strncmp (str, "&gt;", len)) {
153  return 62;
154  }
155 
156  for (i = 0; i < 96; i++) {
157  if (!strncmp (str, GML_table[i], len)) {
158  ret = i + 160;
159  break;
160  }
161  }
162 
163  return ret;
164 }
165 
166 
167 void GML_init () {
168 
169  GML_line = 1;
170  GML_column = 1;
171 }
172 
173 
174 
175 struct GML_token GML_scanner (FILE* source) {
176 
177  int cur_max_size = INITIAL_SIZE;
178  static char buffer[INITIAL_SIZE];
179  char* tmp = buffer;
180  char* ret = tmp;
181  struct GML_token token;
182  int is_float = 0;
183  int count = 0;
184  int next;
185  char ISO_buffer[8];
186  int ISO_count;
187 
188  assert (source != NULL);
189 
190  /*
191  * eliminate preceeding white spaces
192  */
193 
194  do {
195  next = fgetc (source);
196  GML_column++;
197 
198  if (next == '\n') {
199  GML_line++;
200  GML_column = 1;
201  } else if (next == EOF) {
202  token.kind = GML_END;
203  return token;
204  }
205  } while (isspace (next));
206 
207  if (isdigit (next) || next == '.' || next == '+' || next == '-') {
208 
209  /*
210  * floating point or integer
211  */
212 
213  do {
214  if (count == INITIAL_SIZE - 1) {
216  token.value.err.line = GML_line;
217  token.value.err.column = GML_column + count;
218  token.kind = GML_ERROR;
219  return token;
220  }
221 
222  if (next == '.' || next == 'E') {
223  is_float = 1;
224  }
225 
226  buffer[count] = next;
227  count++;
228  next = fgetc (source);
229 
230  } while (!isspace(next) && next != ']');
231 
232  if (next == ']') {
233  ungetc (next, source);
234  }
235 
236  buffer[count] = 0;
237 
238  if (next == '\n') {
239  GML_line++;
240  GML_column = 1;
241  } else {
242  GML_column += count;
243  }
244 
245  if (is_float) {
246  token.value.floating = atof (tmp);
247  token.kind = GML_DOUBLE;
248  } else {
249  token.value.integer = atol (tmp);
250  token.kind = GML_INT;
251  }
252 
253  return token;
254 
255  } else if (isalpha (next) || next == '_') {
256 
257  /*
258  * key
259  */
260 
261  do {
262  if (count == cur_max_size - 1) {
263  *tmp = 0;
264  tmp = (char*) malloc(2 * cur_max_size * sizeof (char));
265  strcpy (tmp, ret);
266 
267  if (cur_max_size > INITIAL_SIZE) {
268  free (ret);
269  }
270 
271  ret = tmp;
272  tmp += count;
273  cur_max_size *= 2;
274  }
275 
276  if (!isalnum (next) && next != '_') {
278  token.value.err.line = GML_line;
279  token.value.err.column = GML_column + count;
280  token.kind = GML_ERROR;
281 
282  if (cur_max_size > INITIAL_SIZE) {
283  free (ret);
284  }
285 
286  return token;
287  }
288 
289  *tmp++ = next;
290  count++;
291  next = fgetc (source);
292  } while (!isspace (next) && next != EOF);
293 
294  if (next == '\n') {
295  GML_line++;
296  GML_column = 1;
297  } else {
298  GML_column += count;
299  }
300 
301  *tmp = 0;
302  token.kind = GML_KEY;
303  token.value.str = (char*) malloc((count+1) * sizeof (char));
304  strcpy (token.value.str, ret);
305 
306  if (cur_max_size > INITIAL_SIZE) {
307  free (ret);
308  }
309 
310  return token;
311 
312  } else {
313  /*
314  * comments, brackets and strings
315  */
316 
317  switch (next) {
318  case '#':
319  do {
320  next = fgetc (source);
321  } while (next != '\n' && next != EOF);
322 
323  GML_line++;
324  GML_column = 1;
325  return GML_scanner (source);
326 
327  case '[':
328  token.kind = GML_L_BRACKET;
329  return token;
330 
331  case ']':
332  token.kind = GML_R_BRACKET;
333  return token;
334 
335  case '"':
336  next = fgetc (source);
337  GML_column++;
338 
339  while (next != '"') {
340 
341  if (count >= cur_max_size - 8) {
342  *tmp = 0;
343  tmp = (char*) malloc (2 * cur_max_size * sizeof(char));
344  strcpy (tmp, ret);
345 
346  if (cur_max_size > INITIAL_SIZE) {
347  free (ret);
348  }
349 
350  ret = tmp;
351  tmp += count;
352  cur_max_size *= 2;
353  }
354 
355  if (next == '&') {
356  ISO_count = 0;
357 
358  while (next != ';') {
359  if (next == '"' || next == EOF) {
360  ungetc (next, source);
361  ISO_count = 0;
362  break;
363  }
364 
365  if (ISO_count < 8) {
366  ISO_buffer[ISO_count] = next;
367  ISO_count++;
368  }
369 
370  next = fgetc (source);
371  }
372 
373  if (ISO_count == 8) {
374  ISO_count = 0;
375  }
376 
377  if (ISO_count) {
378  ISO_buffer[ISO_count] = ';';
379  ISO_count++;
380  next = GML_search_ISO (ISO_buffer, ISO_count);
381  ISO_count = 0;
382  } else {
383  next = '&';
384  }
385  }
386 
387  *tmp++ = next;
388  count++;
389  GML_column++;
390 
391  next = fgetc (source);
392 
393  if (next == EOF) {
395  token.value.err.line = GML_line;
396  token.value.err.column = GML_column + count;
397  token.kind = GML_ERROR;
398 
399  if (cur_max_size > INITIAL_SIZE) {
400  free (ret);
401  }
402 
403  return token;
404  }
405 
406  if (next == '\n') {
407  GML_line++;
408  GML_column = 1;
409  }
410  }
411 
412  *tmp = 0;
413  token.kind = GML_STRING;
414  token.value.str = (char*) malloc((count+1) * sizeof (char));
415  strcpy (token.value.str, ret);
416 
417  if (cur_max_size > INITIAL_SIZE) {
418  free (ret);
419  }
420 
421  return token;
422 
423  default:
425  token.value.err.line = GML_line;
426  token.value.err.column = GML_column;
427  token.kind = GML_ERROR;
428  return token;
429  }
430  }
431 }
432 
434 
435 //--------------------------------------------------------------------------
436 // end of file
437 //--------------------------------------------------------------------------