3
gg_gml.c -- GML parser/lexer
5
version 3.0, 2011 July 20
7
Author: Sandro Furieri a.furieri@lqt.it
9
------------------------------------------------------------------------------
11
Version: MPL 1.1/GPL 2.0/LGPL 2.1
13
The contents of this file are subject to the Mozilla Public License Version
14
1.1 (the "License"); you may not use this file except in compliance with
15
the License. You may obtain a copy of the License at
16
http://www.mozilla.org/MPL/
18
Software distributed under the License is distributed on an "AS IS" basis,
19
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20
for the specific language governing rights and limitations under the
23
The Original Code is the SpatiaLite library
25
The Initial Developer of the Original Code is Alessandro Furieri
27
Portions created by the Initial Developer are Copyright (C) 2011
28
the Initial Developer. All Rights Reserved.
30
Alternatively, the contents of this file may be used under the terms of
31
either the GNU General Public License Version 2 or later (the "GPL"), or
32
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33
in which case the provisions of the GPL or the LGPL are applicable instead
34
of those above. If you wish to allow use of your version of this file only
35
under the terms of either the GPL or the LGPL, and not to allow others to
36
use your version of this file under the terms of the MPL, indicate your
37
decision by deleting the provisions above and replace them with the notice
38
and other provisions required by the GPL or the LGPL. If you do not delete
39
the provisions above, a recipient may use your version of this file under
40
the terms of any one of the MPL, the GPL or the LGPL.
44
#include <sys/types.h>
51
#ifdef SPL_AMALGAMATION /* spatialite-amalgamation */
52
#include <spatialite/sqlite3.h>
57
#include <spatialite/gaiageo.h>
61
#define GML_PARSER_OPEN_NODE 1
62
#define GML_PARSER_SELF_CLOSED_NODE 2
63
#define GML_PARSER_CLOSED_NODE 3
65
#define GAIA_GML_UNKNOWN 0
66
#define GAIA_GML_POINT 1
67
#define GAIA_GML_LINESTRING 2
68
#define GAIA_GML_CURVE 3
69
#define GAIA_GML_POLYGON 4
70
#define GAIA_GML_MULTIPOINT 5
71
#define GAIA_GML_MULTILINESTRING 6
72
#define GAIA_GML_MULTICURVE 7
73
#define GAIA_GML_MULTIPOLYGON 8
74
#define GAIA_GML_MULTISURFACE 9
75
#define GAIA_GML_MULTIGEOMETRY 10
78
** This is a linked-list struct to store all the values for each token.
80
typedef struct gmlFlexTokenStruct
83
struct gmlFlexTokenStruct *Next;
86
typedef struct gml_coord
89
struct gml_coord *Next;
91
typedef gmlCoord *gmlCoordPtr;
93
typedef struct gml_attr
97
struct gml_attr *Next;
99
typedef gmlAttr *gmlAttrPtr;
101
typedef struct gml_node
106
struct gml_attr *Attributes;
107
struct gml_coord *Coordinates;
108
struct gml_node *Next;
110
typedef gmlNode *gmlNodePtr;
112
typedef struct gml_dynamic_ring
114
gaiaDynamicLinePtr ring;
117
struct gml_dynamic_ring *next;
119
typedef gmlDynamicRing *gmlDynamicRingPtr;
121
typedef struct gml_dynamic_polygon
123
struct gml_dynamic_ring *first;
124
struct gml_dynamic_ring *last;
126
typedef gmlDynamicPolygon *gmlDynamicPolygonPtr;
129
gml_proj_params (sqlite3 * sqlite, int srid, char *proj_params)
131
/* retrives the PROJ params from SPATIAL_SYS_REF table, if possible */
141
"SELECT proj4text FROM spatial_ref_sys WHERE srid = %d", srid);
142
ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
143
if (ret != SQLITE_OK)
145
fprintf (stderr, "unknown SRID: %d\t<%s>\n", srid, errMsg);
146
sqlite3_free (errMsg);
149
for (i = 1; i <= rows; i++)
150
strcpy (proj_params, results[(i * columns)]);
151
if (*proj_params == '\0')
152
fprintf (stderr, "unknown SRID: %d\n", srid);
153
sqlite3_free_table (results);
156
static gmlDynamicPolygonPtr
157
gml_alloc_dyn_polygon (void)
159
/* creating a dynamic polygon (ring collection) */
160
gmlDynamicPolygonPtr p = malloc (sizeof (gmlDynamicPolygon));
167
gml_free_dyn_polygon (gmlDynamicPolygonPtr dyn)
169
/* deleting a dynamic polygon (ring collection) */
171
gmlDynamicRingPtr rn;
179
gaiaFreeDynamicLine (r->ring);
187
gml_add_polygon_ring (gmlDynamicPolygonPtr dyn_pg, gaiaDynamicLinePtr dyn,
188
int interior, int has_z)
190
/* inserting a further ring into the collection (dynamic polygon) */
191
gmlDynamicRingPtr p = malloc (sizeof (gmlDynamicRing));
193
p->interior = interior;
196
if (dyn_pg->first == NULL)
198
if (dyn_pg->last != NULL)
199
dyn_pg->last->next = p;
204
gml_freeString (char **ptr)
206
/* releasing a string from the lexer */
213
gml_saveString (char **ptr, const char *str)
215
/* saving a string from the lexer */
216
int len = strlen (str);
217
gml_freeString (ptr);
218
*ptr = malloc (len + 1);
223
gml_coord (void *value)
225
/* creating a coord Item */
227
gmlFlexToken *tok = (gmlFlexToken *) value;
228
gmlCoordPtr c = malloc (sizeof (gmlCoord));
229
len = strlen (tok->value);
230
c->Value = malloc (len + 1);
231
strcpy (c->Value, tok->value);
237
gml_freeCoordinate (gmlCoordPtr c)
239
/* deleting a GML coordinate */
248
gml_attribute (void *key, void *value)
250
/* creating an attribute */
252
gmlFlexToken *k_tok = (gmlFlexToken *) key;
253
gmlFlexToken *v_tok = (gmlFlexToken *) value;
254
gmlAttrPtr a = malloc (sizeof (gmlAttr));
255
len = strlen (k_tok->value);
256
a->Key = malloc (len + 1);
257
strcpy (a->Key, k_tok->value);
258
len = strlen (v_tok->value);
259
/* we need to de-quote the string, removing first and last ".." */
260
if (*(v_tok->value + 0) == '"' && *(v_tok->value + len - 1) == '"')
262
a->Value = malloc (len - 1);
263
memcpy (a->Value, v_tok->value + 1, len - 1);
264
*(a->Value + len - 1) = '\0';
268
a->Value = malloc (len + 1);
269
strcpy (a->Value, v_tok->value);
276
gml_freeAttribute (gmlAttrPtr a)
278
/* deleting a GML attribute */
289
gml_freeNode (gmlNodePtr n)
291
/* deleting a GML node */
302
gml_freeAttribute (a);
309
gml_freeCoordinate (c);
318
gml_freeTree (gmlNodePtr t)
320
/* deleting a GML tree */
333
gml_createNode (void *tag, void *attributes, void *coords)
335
/* creating a node */
337
gmlFlexToken *tok = (gmlFlexToken *) tag;
338
gmlNodePtr n = malloc (sizeof (gmlNode));
339
len = strlen (tok->value);
340
n->Tag = malloc (len + 1);
341
strcpy (n->Tag, tok->value);
342
n->Type = GML_PARSER_OPEN_NODE;
344
n->Attributes = attributes;
345
n->Coordinates = coords;
351
gml_createSelfClosedNode (void *tag, void *attributes)
353
/* creating a self-closed node */
355
gmlFlexToken *tok = (gmlFlexToken *) tag;
356
gmlNodePtr n = malloc (sizeof (gmlNode));
357
len = strlen (tok->value);
358
n->Tag = malloc (len + 1);
359
strcpy (n->Tag, tok->value);
360
n->Type = GML_PARSER_SELF_CLOSED_NODE;
362
n->Attributes = attributes;
363
n->Coordinates = NULL;
369
gml_closingNode (void *tag)
371
/* creating a closing node */
373
gmlFlexToken *tok = (gmlFlexToken *) tag;
374
gmlNodePtr n = malloc (sizeof (gmlNode));
375
len = strlen (tok->value);
376
n->Tag = malloc (len + 1);
377
strcpy (n->Tag, tok->value);
378
n->Type = GML_PARSER_CLOSED_NODE;
380
n->Attributes = NULL;
381
n->Coordinates = NULL;
387
gml_cleanup (gmlFlexToken * token)
390
gmlFlexToken *ptok_n;
397
if (ptok->value != NULL)
406
gml_xferString (char **p, const char *str)
408
/* saving some token */
416
*p = malloc (len + 1);
421
guessGmlSrid (gmlNodePtr node)
423
/* attempting to guess the SRID */
425
gmlAttrPtr attr = node->Attributes;
428
if (strcmp (attr->Key, "srsName") == 0)
430
len = strlen (attr->Value);
433
if (strncmp (attr->Value, "EPSG:", 5) == 0)
434
return atoi (attr->Value + 5);
438
if (strncmp (attr->Value, "urn:ogc:def:crs:EPSG:", 21) ==
441
int i = strlen (attr->Value) - 1;
444
if (*(attr->Value + i) == ':')
445
return atoi (attr->Value + i + 1);
456
gml_get_srsDimension (gmlNodePtr node)
458
/* attempting to establis if there is a Z coordinate */
459
gmlAttrPtr attr = node->Attributes;
462
if (strcmp (attr->Key, "srsDimension") == 0)
464
if (atoi (attr->Value) == 3)
475
guessGmlGeometryType (gmlNodePtr node)
477
/* attempting to guess the Geometry Type for a GML node */
478
int type = GAIA_GML_UNKNOWN;
479
if (strcmp (node->Tag, "gml:Point") == 0
480
|| strcmp (node->Tag, "Point") == 0)
481
type = GAIA_GML_POINT;
482
if (strcmp (node->Tag, "gml:LineString") == 0
483
|| strcmp (node->Tag, "LineString") == 0)
484
type = GAIA_GML_LINESTRING;
485
if (strcmp (node->Tag, "gml:Curve") == 0
486
|| strcmp (node->Tag, "Curve") == 0)
487
type = GAIA_GML_CURVE;
488
if (strcmp (node->Tag, "gml:Polygon") == 0
489
|| strcmp (node->Tag, "Polygon") == 0)
490
type = GAIA_GML_POLYGON;
491
if (strcmp (node->Tag, "gml:MultiPoint") == 0
492
|| strcmp (node->Tag, "MultiPoint") == 0)
493
type = GAIA_GML_MULTIPOINT;
494
if (strcmp (node->Tag, "gml:MultiLineString") == 0
495
|| strcmp (node->Tag, "MultiLineString") == 0)
496
type = GAIA_GML_MULTILINESTRING;
497
if (strcmp (node->Tag, "gml:MultiCurve") == 0
498
|| strcmp (node->Tag, "MultiCurve") == 0)
499
type = GAIA_GML_MULTICURVE;
500
if (strcmp (node->Tag, "gml:MultiPolygon") == 0
501
|| strcmp (node->Tag, "MultiPolygon") == 0)
502
type = GAIA_GML_MULTIPOLYGON;
503
if (strcmp (node->Tag, "gml:MultiSurface") == 0
504
|| strcmp (node->Tag, "MultiSurface") == 0)
505
type = GAIA_GML_MULTISURFACE;
506
if (strcmp (node->Tag, "gml:MultiGeometry") == 0
507
|| strcmp (node->Tag, "MultiGeometry") == 0)
508
type = GAIA_GML_MULTIGEOMETRY;
513
gml_check_coord (const char *value)
515
/* checking a GML coordinate */
517
const char *p = value;
518
if (*p == '+' || *p == '-')
529
else if (*p >= '0' && *p <= '9')
539
gml_extract_coords (const char *value, double *x, double *y, double *z,
542
/* extracting GML v2.x coords from a comma-separated string */
543
const char *in = value;
555
if (!gml_check_coord (buf))
584
/* parsing the last item */
587
if (!gml_check_coord (buf))
612
gml_parse_point_v2 (gmlCoordPtr coord, double *x, double *y, double *z,
615
/* parsing GML v2.x <gml:coordinates> [Point] */
617
gmlCoordPtr c = coord;
620
if (!gml_extract_coords (c->Value, x, y, z, &count))
638
gml_parse_point_v3 (gmlCoordPtr coord, double *x, double *y, double *z,
641
/* parsing GML v2.x <gml:pos> [Point] */
643
gmlCoordPtr c = coord;
646
if (!gml_check_coord (c->Value))
651
*x = atof (c->Value);
655
*y = atof (c->Value);
659
*z = atof (c->Value);
682
gml_parse_point (gaiaGeomCollPtr geom, gmlNodePtr node, int srid,
685
/* parsing a <gml:Point> */
691
gaiaGeomCollPtr last;
693
if (strcmp (node->Tag, "gml:coordinates") == 0
694
|| strcmp (node->Tag, "coordinates") == 0)
696
/* parsing a GML v.2.x <gml:Point> */
697
if (!gml_parse_point_v2 (node->Coordinates, &x, &y, &z, &has_z))
702
if (strcmp (node->Tag, "gml:coordinates") == 0
703
|| strcmp (node->Tag, "coordinates") == 0)
710
if (strcmp (node->Tag, "gml:Point") == 0
711
|| strcmp (node->Tag, "Point") == 0)
718
if (strcmp (node->Tag, "gml:pos") == 0 || strcmp (node->Tag, "pos") == 0)
720
/* parsing a GML v.3.x <gml:Point> */
721
if (!gml_parse_point_v3 (node->Coordinates, &x, &y, &z, &has_z))
726
if (strcmp (node->Tag, "gml:pos") == 0
727
|| strcmp (node->Tag, "pos") == 0)
734
if (strcmp (node->Tag, "gml:Point") == 0
735
|| strcmp (node->Tag, "Point") == 0)
745
/* ok, GML nodes match as expected */
748
pt = gaiaAllocGeomCollXYZ ();
750
gaiaAddPointToGeomCollXYZ (pt, x, y, z);
754
pt = gaiaAllocGeomColl ();
756
gaiaAddPointToGeomColl (pt, x, y);
761
/* searching the last Geometry within chain */
762
if (last->Next == NULL)
771
gml_extract_multi_coord (const char *value, double *x, double *y, double *z,
772
int *count, int *follow)
774
/* extracting GML v2.x coords from a comma-separated string */
775
const char *in = value;
788
if (!gml_check_coord (buf))
817
/* parsing the last item */
820
if (!gml_check_coord (buf))
849
gml_extract_multi_coords (gmlCoordPtr coord, double *x, double *y, double *z,
850
int *count, gmlCoordPtr * next)
852
/* extracting GML v2.x coords from a comma-separated string */
854
gmlCoordPtr c = coord;
857
if (!gml_extract_multi_coord (c->Value, x, y, z, count, &follow))
859
if (!follow && c->Next != NULL)
861
if (*(c->Next->Value) == ',')
876
gml_add_point_to_line (gaiaDynamicLinePtr dyn, double x, double y)
878
/* appending a point */
879
gaiaAppendPointToDynamicLine (dyn, x, y);
883
gml_add_point_to_lineZ (gaiaDynamicLinePtr dyn, double x, double y, double z)
885
/* appending a point */
886
gaiaAppendPointZToDynamicLine (dyn, x, y, z);
890
gml_parse_coordinates (gmlCoordPtr coord, gaiaDynamicLinePtr dyn, int *has_z)
892
/* parsing GML v2.x <gml:coordinates> [Linestring or Ring] */
898
gmlCoordPtr c = coord;
901
if (!gml_extract_multi_coords (c, &x, &y, &z, &count, &next))
906
gml_add_point_to_line (dyn, x, y);
911
gml_add_point_to_lineZ (dyn, x, y, z);
922
gml_parse_posList (gmlCoordPtr coord, gaiaDynamicLinePtr dyn, int has_z)
924
/* parsing GML v3.x <gml:posList> [Linestring or Ring] */
929
gmlCoordPtr c = coord;
932
if (!gml_check_coord (c->Value))
944
gml_add_point_to_line (dyn, x, y);
963
gml_add_point_to_lineZ (dyn, x, y, z);
976
gml_count_dyn_points (gaiaDynamicLinePtr dyn)
978
/* count how many vertices are into sone linestring/ring */
980
gaiaPointPtr pt = dyn->First;
990
gml_parse_linestring (gaiaGeomCollPtr geom, gmlNodePtr node, int srid,
993
/* parsing a <gml:LineString> */
995
gaiaGeomCollPtr last;
996
gaiaLinestringPtr new_ln;
998
gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine ();
1003
if (strcmp (node->Tag, "gml:coordinates") == 0
1004
|| strcmp (node->Tag, "coordinates") == 0)
1006
/* parsing a GML v.2.x <gml:LineString> */
1007
if (!gml_parse_coordinates (node->Coordinates, dyn, &has_z))
1012
if (strcmp (node->Tag, "gml:coordinates") == 0
1013
|| strcmp (node->Tag, "coordinates") == 0)
1020
if (strcmp (node->Tag, "gml:LineString") == 0
1021
|| strcmp (node->Tag, "LineString") == 0)
1028
if (strcmp (node->Tag, "gml:posList") == 0
1029
|| strcmp (node->Tag, "posList") == 0)
1031
/* parsing a GML v.3.x <gml:LineString> */
1032
has_z = gml_get_srsDimension (node);
1033
if (!gml_parse_posList (node->Coordinates, dyn, has_z))
1038
if (strcmp (node->Tag, "gml:posList") == 0
1039
|| strcmp (node->Tag, "posList") == 0)
1046
if (strcmp (node->Tag, "gml:LineString") == 0
1047
|| strcmp (node->Tag, "LineString") == 0)
1057
/* ok, GML nodes match as expected */
1058
points = gml_count_dyn_points (dyn);
1063
ln = gaiaAllocGeomCollXYZ ();
1065
new_ln = gaiaAddLinestringToGeomColl (ln, points);
1070
gaiaSetPointXYZ (new_ln->Coords, iv, pt->X, pt->Y, pt->Z);
1077
ln = gaiaAllocGeomColl ();
1079
new_ln = gaiaAddLinestringToGeomColl (ln, points);
1084
gaiaSetPoint (new_ln->Coords, iv, pt->X, pt->Y);
1092
/* searching the last Geometry within chain */
1093
if (last->Next == NULL)
1098
gaiaFreeDynamicLine (dyn);
1102
gaiaFreeDynamicLine (dyn);
1107
gml_parse_curve (gaiaGeomCollPtr geom, gmlNodePtr node, int srid,
1110
/* parsing a <gml:Curve> */
1112
gaiaGeomCollPtr last;
1113
gaiaLinestringPtr new_ln;
1115
gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine ();
1120
if (strcmp (node->Tag, "gml:segments") == 0
1121
|| strcmp (node->Tag, "segments") == 0)
1123
/* parsing a GML v.3.x <gml:Curve> */
1127
if (strcmp (node->Tag, "gml:LineStringSegment") == 0
1128
|| strcmp (node->Tag, "LineStringSegment") == 0)
1135
if (strcmp (node->Tag, "gml:posList") == 0
1136
|| strcmp (node->Tag, "posList") == 0)
1140
has_z = gml_get_srsDimension (node);
1141
if (!gml_parse_posList (node->Coordinates, dyn, has_z))
1146
if (strcmp (node->Tag, "gml:posList") == 0
1147
|| strcmp (node->Tag, "posList") == 0)
1154
if (strcmp (node->Tag, "gml:LineStringSegment") == 0
1155
|| strcmp (node->Tag, "LineStringSegment") == 0)
1162
if (strcmp (node->Tag, "gml:segments") == 0
1163
|| strcmp (node->Tag, "segments") == 0)
1170
if (strcmp (node->Tag, "gml:Curve") == 0
1171
|| strcmp (node->Tag, "Curve") == 0)
1181
/* ok, GML nodes match as expected */
1182
points = gml_count_dyn_points (dyn);
1187
ln = gaiaAllocGeomCollXYZ ();
1189
new_ln = gaiaAddLinestringToGeomColl (ln, points);
1194
gaiaSetPointXYZ (new_ln->Coords, iv, pt->X, pt->Y, pt->Z);
1201
ln = gaiaAllocGeomColl ();
1203
new_ln = gaiaAddLinestringToGeomColl (ln, points);
1208
gaiaSetPoint (new_ln->Coords, iv, pt->X, pt->Y);
1216
/* searching the last Geometry within chain */
1217
if (last->Next == NULL)
1222
gaiaFreeDynamicLine (dyn);
1226
gaiaFreeDynamicLine (dyn);
1230
static gaiaDynamicLinePtr
1231
gml_parse_ring (gmlNodePtr node, int *interior, int *has_z, gmlNodePtr * next)
1233
/* parsing a generic GML ring */
1234
gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine ();
1237
if (strcmp (node->Tag, "gml:outerBoundaryIs") == 0
1238
|| strcmp (node->Tag, "outerBoundaryIs") == 0)
1240
/* parsing a GML v.2.x <gml:outerBoundaryIs> */
1244
if (strcmp (node->Tag, "gml:LinearRing") == 0
1245
|| strcmp (node->Tag, "LinearRing") == 0)
1252
if (strcmp (node->Tag, "gml:coordinates") == 0
1253
|| strcmp (node->Tag, "coordinates") == 0)
1255
/* parsing a GML v.2.x <gml:coordinates> */
1256
if (!gml_parse_coordinates (node->Coordinates, dyn, has_z))
1261
if (strcmp (node->Tag, "gml:coordinates") == 0
1262
|| strcmp (node->Tag, "coordinates") == 0)
1267
else if (strcmp (node->Tag, "gml:posList") == 0
1268
|| strcmp (node->Tag, "posList") == 0)
1270
/* parsing a GML v.3.x <gml:posList> */
1271
*has_z = gml_get_srsDimension (node);
1272
if (!gml_parse_posList (node->Coordinates, dyn, *has_z))
1277
if (strcmp (node->Tag, "gml:posList") == 0
1278
|| strcmp (node->Tag, "posList") == 0)
1288
if (strcmp (node->Tag, "gml:LinearRing") == 0
1289
|| strcmp (node->Tag, "LinearRing") == 0)
1296
if (strcmp (node->Tag, "gml:outerBoundaryIs") == 0
1297
|| strcmp (node->Tag, "outerBoundaryIs") == 0)
1305
if (strcmp (node->Tag, "gml:innerBoundaryIs") == 0
1306
|| strcmp (node->Tag, "innerBoundaryIs") == 0)
1308
/* parsing a GML v.2.x <gml:innerBoundaryIs> */
1312
if (strcmp (node->Tag, "gml:LinearRing") == 0
1313
|| strcmp (node->Tag, "LinearRing") == 0)
1320
if (strcmp (node->Tag, "gml:coordinates") == 0
1321
|| strcmp (node->Tag, "coordinates") == 0)
1323
/* parsing a GML v.2.x <gml:coordinates> */
1324
if (!gml_parse_coordinates (node->Coordinates, dyn, has_z))
1329
if (strcmp (node->Tag, "gml:coordinates") == 0
1330
|| strcmp (node->Tag, "coordinates") == 0)
1335
else if (strcmp (node->Tag, "gml:posList") == 0
1336
|| strcmp (node->Tag, "posList") == 0)
1338
/* parsing a GML v.3.x <gml:posList> */
1339
*has_z = gml_get_srsDimension (node);
1340
if (!gml_parse_posList (node->Coordinates, dyn, *has_z))
1345
if (strcmp (node->Tag, "gml:posList") == 0
1346
|| strcmp (node->Tag, "posList") == 0)
1356
if (strcmp (node->Tag, "gml:LinearRing") == 0
1357
|| strcmp (node->Tag, "LinearRing") == 0)
1364
if (strcmp (node->Tag, "gml:innerBoundaryIs") == 0
1365
|| strcmp (node->Tag, "innerBoundaryIs") == 0)
1373
if (strcmp (node->Tag, "gml:exterior") == 0
1374
|| strcmp (node->Tag, "exterior") == 0)
1376
/* parsing a GML v.3.x <gml:exterior> */
1380
if (strcmp (node->Tag, "gml:LinearRing") == 0
1381
|| strcmp (node->Tag, "LinearRing") == 0)
1388
if (strcmp (node->Tag, "gml:posList") == 0
1389
|| strcmp (node->Tag, "posList") == 0)
1393
*has_z = gml_get_srsDimension (node);
1394
if (!gml_parse_posList (node->Coordinates, dyn, *has_z))
1399
if (strcmp (node->Tag, "gml:posList") == 0
1400
|| strcmp (node->Tag, "posList") == 0)
1407
if (strcmp (node->Tag, "gml:LinearRing") == 0
1408
|| strcmp (node->Tag, "LinearRing") == 0)
1415
if (strcmp (node->Tag, "gml:exterior") == 0
1416
|| strcmp (node->Tag, "exterior") == 0)
1424
if (strcmp (node->Tag, "gml:interior") == 0
1425
|| strcmp (node->Tag, "interior") == 0)
1427
/* parsing a GML v.3.x <gml:interior> */
1431
if (strcmp (node->Tag, "gml:LinearRing") == 0
1432
|| strcmp (node->Tag, "LinearRing") == 0)
1439
if (strcmp (node->Tag, "gml:posList") == 0
1440
|| strcmp (node->Tag, "posList") == 0)
1444
*has_z = gml_get_srsDimension (node);
1445
if (!gml_parse_posList (node->Coordinates, dyn, *has_z))
1450
if (strcmp (node->Tag, "gml:posList") == 0
1451
|| strcmp (node->Tag, "posList") == 0)
1458
if (strcmp (node->Tag, "gml:LinearRing") == 0
1459
|| strcmp (node->Tag, "LinearRing") == 0)
1466
if (strcmp (node->Tag, "gml:interior") == 0
1467
|| strcmp (node->Tag, "interior") == 0)
1477
gaiaFreeDynamicLine (dyn);
1482
gml_parse_polygon (gaiaGeomCollPtr geom, gmlNodePtr node, int srid,
1483
gmlNodePtr * next_n)
1485
/* parsing a <gml:Polygon> */
1494
gaiaGeomCollPtr last_g;
1495
gaiaPolygonPtr new_pg;
1497
gaiaDynamicLinePtr dyn;
1499
gaiaDynamicLinePtr exterior_ring;
1501
gmlDynamicRingPtr dyn_rng;
1502
gmlDynamicPolygonPtr dyn_pg = gml_alloc_dyn_polygon ();
1503
gmlNodePtr n = node;
1506
/* looping on rings */
1507
if (strcmp (n->Tag, "gml:Polygon") == 0
1508
|| strcmp (n->Tag, "Polygon") == 0)
1513
dyn = gml_parse_ring (n, &interior, &has_z, &next);
1516
if (gml_count_dyn_points (dyn) < 4)
1518
/* cannot be a valid ring */
1521
/* checking if the ring is closed */
1524
if (dyn->First->X == dyn->Last->X
1525
&& dyn->First->Y == dyn->Last->Y
1526
&& dyn->First->Z == dyn->Last->Z)
1533
if (dyn->First->X == dyn->Last->X
1534
&& dyn->First->Y == dyn->Last->Y)
1539
gml_add_polygon_ring (dyn_pg, dyn, interior, has_z);
1542
/* ok, GML nodes match as expected */
1546
dyn_rng = dyn_pg->first;
1549
/* verifying the rings collection */
1550
if (dyn_rng->has_z == 0)
1552
if (dyn_rng->interior)
1557
points = gml_count_dyn_points (dyn_rng->ring);
1558
exterior_ring = dyn_rng->ring;
1560
dyn_rng = dyn_rng->next;
1562
if (outers != 1) /* no exterior ring declared */
1567
pg = gaiaAllocGeomCollXYZ ();
1569
new_pg = gaiaAddPolygonToGeomColl (pg, points, inners);
1570
/* initializing the EXTERIOR RING */
1571
ring = new_pg->Exterior;
1572
pt = exterior_ring->First;
1576
gaiaSetPointXYZ (ring->Coords, iv, pt->X, pt->Y, pt->Z);
1580
dyn_rng = dyn_pg->first;
1583
/* initializing any INTERIOR RING */
1584
if (dyn_rng->interior == 0)
1586
dyn_rng = dyn_rng->next;
1589
points = gml_count_dyn_points (dyn_rng->ring);
1590
ring = gaiaAddInteriorRing (new_pg, ib, points);
1592
pt = dyn_rng->ring->First;
1596
gaiaSetPointXYZ (ring->Coords, iv, pt->X, pt->Y, pt->Z);
1600
dyn_rng = dyn_rng->next;
1605
pg = gaiaAllocGeomColl ();
1607
new_pg = gaiaAddPolygonToGeomColl (pg, points, inners);
1608
/* initializing the EXTERIOR RING */
1609
ring = new_pg->Exterior;
1610
pt = exterior_ring->First;
1614
gaiaSetPoint (ring->Coords, iv, pt->X, pt->Y);
1618
dyn_rng = dyn_pg->first;
1621
/* initializing any INTERIOR RING */
1622
if (dyn_rng->interior == 0)
1624
dyn_rng = dyn_rng->next;
1627
points = gml_count_dyn_points (dyn_rng->ring);
1628
ring = gaiaAddInteriorRing (new_pg, ib, points);
1630
pt = dyn_rng->ring->First;
1634
gaiaSetPoint (ring->Coords, iv, pt->X, pt->Y);
1638
dyn_rng = dyn_rng->next;
1645
/* searching the last Geometry within chain */
1646
if (last_g->Next == NULL)
1648
last_g = last_g->Next;
1651
gml_free_dyn_polygon (dyn_pg);
1655
gml_free_dyn_polygon (dyn_pg);
1660
gml_parse_multi_point (gaiaGeomCollPtr geom, gmlNodePtr node)
1662
/* parsing a <gml:MultiPoint> */
1665
gmlNodePtr n = node;
1668
/* looping on Point Members */
1669
if (n->Next == NULL)
1671
/* verifying the last GML node */
1672
if (strcmp (n->Tag, "gml:MultiPoint") == 0
1673
|| strcmp (n->Tag, "MultiPoint") == 0)
1678
if (strcmp (n->Tag, "gml:pointMember") == 0
1679
|| strcmp (n->Tag, "pointMember") == 0)
1686
if (strcmp (n->Tag, "gml:Point") == 0
1687
|| strcmp (n->Tag, "Point") == 0)
1691
srid = guessGmlSrid (n);
1695
if (!gml_parse_point (geom, n, srid, &next))
1700
if (strcmp (n->Tag, "gml:pointMember") == 0
1701
|| strcmp (n->Tag, "pointMember") == 0)
1711
gml_parse_multi_linestring (gaiaGeomCollPtr geom, gmlNodePtr node)
1713
/* parsing a <gml:MultiLineString> */
1716
gmlNodePtr n = node;
1719
/* looping on LineString Members */
1720
if (n->Next == NULL)
1722
/* verifying the last GML node */
1723
if (strcmp (n->Tag, "gml:MultiLineString") == 0
1724
|| strcmp (n->Tag, "MultiLineString") == 0)
1729
if (strcmp (n->Tag, "gml:lineStringMember") == 0
1730
|| strcmp (n->Tag, "lineStringMember") == 0)
1737
if (strcmp (n->Tag, "gml:LineString") == 0
1738
|| strcmp (n->Tag, "LineString") == 0)
1742
srid = guessGmlSrid (n);
1746
if (!gml_parse_linestring (geom, n, srid, &next))
1751
if (strcmp (n->Tag, "gml:lineStringMember") == 0
1752
|| strcmp (n->Tag, "lineStringMember") == 0)
1762
gml_parse_multi_curve (gaiaGeomCollPtr geom, gmlNodePtr node)
1764
/* parsing a <gml:MultiCurve> */
1767
gmlNodePtr n = node;
1770
/* looping on Curve Members */
1771
if (n->Next == NULL)
1773
/* verifying the last GML node */
1774
if (strcmp (n->Tag, "gml:MultiCurve") == 0
1775
|| strcmp (n->Tag, "MultiCurve") == 0)
1780
if (strcmp (n->Tag, "gml:curveMember") == 0
1781
|| strcmp (n->Tag, "curveMember") == 0)
1788
if (strcmp (n->Tag, "gml:Curve") == 0
1789
|| strcmp (n->Tag, "Curve") == 0)
1793
srid = guessGmlSrid (n);
1797
if (!gml_parse_curve (geom, n, srid, &next))
1802
if (strcmp (n->Tag, "gml:curveMember") == 0
1803
|| strcmp (n->Tag, "curveMember") == 0)
1813
gml_parse_multi_polygon (gaiaGeomCollPtr geom, gmlNodePtr node)
1815
/* parsing a <gml:MultiPolygon> */
1818
gmlNodePtr n = node;
1821
/* looping on Polygon Members */
1822
if (n->Next == NULL)
1824
/* verifying the last GML node */
1825
if (strcmp (n->Tag, "gml:MultiPolygon") == 0
1826
|| strcmp (n->Tag, "MultiPolygon") == 0)
1831
if (strcmp (n->Tag, "gml:polygonMember") == 0
1832
|| strcmp (n->Tag, "polygonMember") == 0)
1839
if (strcmp (n->Tag, "gml:Polygon") == 0
1840
|| strcmp (n->Tag, "Polygon") == 0)
1844
srid = guessGmlSrid (n);
1848
if (!gml_parse_polygon (geom, n, srid, &next))
1853
if (strcmp (n->Tag, "gml:polygonMember") == 0
1854
|| strcmp (n->Tag, "polygonMember") == 0)
1864
gml_parse_multi_surface (gaiaGeomCollPtr geom, gmlNodePtr node)
1866
/* parsing a <gml:MultiSurface> */
1869
gmlNodePtr n = node;
1872
/* looping on Surface Members */
1873
if (n->Next == NULL)
1875
/* verifying the last GML node */
1876
if (strcmp (n->Tag, "gml:MultiSurface") == 0
1877
|| strcmp (n->Tag, "MultiSurface") == 0)
1882
if (strcmp (n->Tag, "gml:surfaceMember") == 0
1883
|| strcmp (n->Tag, "surfaceMember") == 0)
1890
if (strcmp (n->Tag, "gml:Polygon") == 0
1891
|| strcmp (n->Tag, "Polygon") == 0)
1895
srid = guessGmlSrid (n);
1899
if (!gml_parse_polygon (geom, n, srid, &next))
1904
if (strcmp (n->Tag, "gml:surfaceMember") == 0
1905
|| strcmp (n->Tag, "surfaceMember") == 0)
1915
gml_parse_multi_geometry (gaiaGeomCollPtr geom, gmlNodePtr node)
1917
/* parsing a <gml:MultiGeometry> */
1920
gmlNodePtr n = node;
1923
/* looping on Geometry Members */
1924
if (n->Next == NULL)
1926
/* verifying the last GML node */
1927
if (strcmp (n->Tag, "gml:MultiGeometry") == 0
1928
|| strcmp (n->Tag, "MultiGeometry") == 0)
1933
if (strcmp (n->Tag, "gml:geometryMember") == 0
1934
|| strcmp (n->Tag, "geometryMember") == 0)
1941
if (strcmp (n->Tag, "gml:Point") == 0
1942
|| strcmp (n->Tag, "Point") == 0)
1944
srid = guessGmlSrid (n);
1948
if (!gml_parse_point (geom, n, srid, &next))
1952
else if (strcmp (n->Tag, "gml:LineString") == 0
1953
|| strcmp (n->Tag, "LineString") == 0)
1955
srid = guessGmlSrid (n);
1959
if (!gml_parse_linestring (geom, n, srid, &next))
1963
else if (strcmp (n->Tag, "gml:Curve") == 0
1964
|| strcmp (n->Tag, "Curve") == 0)
1966
srid = guessGmlSrid (n);
1970
if (!gml_parse_curve (geom, n, srid, &next))
1974
else if (strcmp (n->Tag, "gml:Polygon") == 0
1975
|| strcmp (n->Tag, "Polygon") == 0)
1977
srid = guessGmlSrid (n);
1981
if (!gml_parse_polygon (geom, n, srid, &next))
1989
if (strcmp (n->Tag, "gml:geometryMember") == 0
1990
|| strcmp (n->Tag, "geometryMember") == 0)
1999
static gaiaGeomCollPtr
2000
gml_validate_geometry (gaiaGeomCollPtr chain, sqlite3 * sqlite_handle)
2008
gaiaLinestringPtr ln;
2010
gaiaPointPtr save_pt;
2011
gaiaLinestringPtr save_ln;
2012
gaiaPolygonPtr save_pg;
2019
gaiaGeomCollPtr geom;
2020
char proj_from[2048];
2028
if (g->DimensionModel == GAIA_XY)
2030
if (g->DimensionModel == GAIA_XY_Z)
2040
ln = g->FirstLinestring;
2047
pg = g->FirstPolygon;
2056
if (pts == 1 && lns == 0 && pgs == 0)
2062
geom = gaiaAllocGeomColl ();
2063
geom->Srid = chain->Srid;
2064
if (chain->DeclaredType == GAIA_MULTIPOINT)
2065
geom->DeclaredType = GAIA_MULTIPOINT;
2066
else if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2067
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2069
geom->DeclaredType = GAIA_POINT;
2070
gaiaAddPointToGeomColl (geom, save_pt->X, save_pt->Y);
2076
geom = gaiaAllocGeomCollXYZ ();
2077
geom->Srid = chain->Srid;
2078
if (chain->DeclaredType == GAIA_MULTIPOINT)
2079
geom->DeclaredType = GAIA_MULTIPOINT;
2080
else if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2081
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2083
geom->DeclaredType = GAIA_POINT;
2084
gaiaAddPointToGeomCollXYZ (geom, save_pt->X, save_pt->Y,
2089
if (pts == 0 && lns == 1 && pgs == 0)
2095
geom = gaiaAllocGeomColl ();
2100
geom = gaiaAllocGeomCollXYZ ();
2102
geom->Srid = chain->Srid;
2103
if (chain->DeclaredType == GAIA_MULTILINESTRING)
2104
geom->DeclaredType = GAIA_MULTILINESTRING;
2105
else if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2106
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2108
geom->DeclaredType = GAIA_LINESTRING;
2109
ln = gaiaAddLinestringToGeomColl (geom, save_ln->Points);
2110
gaiaCopyLinestringCoords (ln, save_ln);
2113
if (pts == 0 && lns == 0 && pgs == 1)
2119
geom = gaiaAllocGeomColl ();
2124
geom = gaiaAllocGeomCollXYZ ();
2126
geom->Srid = chain->Srid;
2127
if (chain->DeclaredType == GAIA_MULTIPOLYGON)
2128
geom->DeclaredType = GAIA_MULTIPOLYGON;
2129
else if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2130
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2132
geom->DeclaredType = GAIA_POLYGON;
2133
i_ring = save_pg->Exterior;
2134
pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points,
2135
save_pg->NumInteriors);
2136
o_ring = pg->Exterior;
2137
gaiaCopyRingCoords (o_ring, i_ring);
2138
for (ib = 0; ib < save_pg->NumInteriors; ib++)
2140
i_ring = save_pg->Interiors + ib;
2141
o_ring = gaiaAddInteriorRing (pg, ib, i_ring->Points);
2142
gaiaCopyRingCoords (o_ring, i_ring);
2146
if (pts >= 1 && lns == 0 && pgs == 0)
2152
geom = gaiaAllocGeomColl ();
2153
geom->Srid = chain->Srid;
2154
if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2155
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2157
geom->DeclaredType = GAIA_MULTIPOINT;
2161
if (geom->Srid == -1)
2163
/* we haven't yet set any SRID */
2164
geom->Srid = g->Srid;
2168
if (g->Srid != geom->Srid && g->Srid != -1
2169
&& sqlite_handle != NULL)
2171
/* we'll try to apply a reprojection */
2172
#ifndef OMIT_PROJ /* but only if PROJ.4 is actually available */
2173
gml_proj_params (sqlite_handle, g->Srid, proj_from);
2174
gml_proj_params (sqlite_handle, geom->Srid,
2176
if (*proj_to == '\0' || *proj_from == '\0')
2180
g2 = gaiaTransform (g, proj_from, proj_to);
2188
pt = g2->FirstPoint;
2191
gaiaAddPointToGeomColl (geom, pt->X, pt->Y);
2195
gaiaFreeGeomColl (g2);
2203
geom = gaiaAllocGeomCollXYZ ();
2204
geom->Srid = chain->Srid;
2205
if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2206
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2208
geom->DeclaredType = GAIA_MULTIPOINT;
2212
if (geom->Srid == -1)
2214
/* we haven't yet a SRID set */
2215
geom->Srid = g->Srid;
2219
if (g->Srid != geom->Srid && g->Srid != -1
2220
&& sqlite_handle != NULL)
2222
/* we'll try to apply a reprojection */
2223
#ifndef OMIT_PROJ /* but only if PROJ.4 is actually available */
2224
gml_proj_params (sqlite_handle, g->Srid, proj_from);
2225
gml_proj_params (sqlite_handle, geom->Srid,
2227
if (*proj_to == '\0' || *proj_from == '\0')
2231
g2 = gaiaTransform (g, proj_from, proj_to);
2239
pt = g2->FirstPoint;
2242
gaiaAddPointToGeomCollXYZ (geom, pt->X, pt->Y,
2247
gaiaFreeGeomColl (g2);
2253
if (pts == 0 && lns >= 1 && pgs == 0)
2255
/* MULTILINESTRING */
2259
geom = gaiaAllocGeomColl ();
2260
geom->Srid = chain->Srid;
2261
if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2262
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2264
geom->DeclaredType = GAIA_MULTILINESTRING;
2268
if (geom->Srid == -1)
2270
/* we haven't yet set any SRID */
2271
geom->Srid = g->Srid;
2275
if (g->Srid != geom->Srid && g->Srid != -1
2276
&& sqlite_handle != NULL)
2278
/* we'll try to apply a reprojection */
2279
#ifndef OMIT_PROJ /* but only if PROJ.4 is actually available */
2280
gml_proj_params (sqlite_handle, g->Srid, proj_from);
2281
gml_proj_params (sqlite_handle, geom->Srid,
2283
if (*proj_to == '\0' || *proj_from == '\0')
2287
g2 = gaiaTransform (g, proj_from, proj_to);
2295
ln = g2->FirstLinestring;
2299
gaiaAddLinestringToGeomColl (geom, ln->Points);
2300
gaiaCopyLinestringCoords (save_ln, ln);
2304
gaiaFreeGeomColl (g2);
2312
geom = gaiaAllocGeomCollXYZ ();
2313
geom->Srid = chain->Srid;
2314
if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2315
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2317
geom->DeclaredType = GAIA_MULTILINESTRING;
2321
if (geom->Srid == -1)
2323
/* we haven't yet a SRID set */
2324
geom->Srid = g->Srid;
2328
if (g->Srid != geom->Srid && g->Srid != -1
2329
&& sqlite_handle != NULL)
2331
/* we'll try to apply a reprojection */
2332
#ifndef OMIT_PROJ /* but only if PROJ.4 is actually available */
2333
gml_proj_params (sqlite_handle, g->Srid, proj_from);
2334
gml_proj_params (sqlite_handle, geom->Srid,
2336
if (*proj_to == '\0' || *proj_from == '\0')
2340
g2 = gaiaTransform (g, proj_from, proj_to);
2348
ln = g2->FirstLinestring;
2352
gaiaAddLinestringToGeomColl (geom, ln->Points);
2353
gaiaCopyLinestringCoords (save_ln, ln);
2357
gaiaFreeGeomColl (g2);
2363
if (pts == 0 && lns == 0 && pgs >= 1)
2369
geom = gaiaAllocGeomColl ();
2370
geom->Srid = chain->Srid;
2371
if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2372
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2374
geom->DeclaredType = GAIA_MULTIPOLYGON;
2378
if (geom->Srid == -1)
2380
/* we haven't yet set any SRID */
2381
geom->Srid = g->Srid;
2385
if (g->Srid != geom->Srid && g->Srid != -1
2386
&& sqlite_handle != NULL)
2388
/* we'll try to apply a reprojection */
2389
#ifndef OMIT_PROJ /* but only if PROJ.4 is actually available */
2390
gml_proj_params (sqlite_handle, g->Srid, proj_from);
2391
gml_proj_params (sqlite_handle, geom->Srid,
2393
if (*proj_to == '\0' || *proj_from == '\0')
2397
g2 = gaiaTransform (g, proj_from, proj_to);
2405
pg = g2->FirstPolygon;
2408
i_ring = pg->Exterior;
2410
gaiaAddPolygonToGeomColl (geom, i_ring->Points,
2412
o_ring = save_pg->Exterior;
2413
gaiaCopyRingCoords (o_ring, i_ring);
2414
for (ib = 0; ib < pg->NumInteriors; ib++)
2416
i_ring = pg->Interiors + ib;
2418
gaiaAddInteriorRing (save_pg, ib,
2420
gaiaCopyRingCoords (o_ring, i_ring);
2425
gaiaFreeGeomColl (g2);
2433
geom = gaiaAllocGeomCollXYZ ();
2434
geom->Srid = chain->Srid;
2435
if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION)
2436
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2438
geom->DeclaredType = GAIA_MULTIPOLYGON;
2442
if (geom->Srid == -1)
2444
/* we haven't yet a SRID set */
2445
geom->Srid = g->Srid;
2449
if (g->Srid != geom->Srid && g->Srid != -1
2450
&& sqlite_handle != NULL)
2452
/* we'll try to apply a reprojection */
2453
#ifndef OMIT_PROJ /* but only if PROJ.4 is actually available */
2454
gml_proj_params (sqlite_handle, g->Srid, proj_from);
2455
gml_proj_params (sqlite_handle, geom->Srid,
2457
if (*proj_to == '\0' || *proj_from == '\0')
2461
g2 = gaiaTransform (g, proj_from, proj_to);
2469
pg = g2->FirstPolygon;
2472
i_ring = pg->Exterior;
2474
gaiaAddPolygonToGeomColl (geom, i_ring->Points,
2476
o_ring = save_pg->Exterior;
2477
gaiaCopyRingCoords (o_ring, i_ring);
2478
for (ib = 0; ib < pg->NumInteriors; ib++)
2480
i_ring = pg->Interiors + ib;
2482
gaiaAddInteriorRing (save_pg, ib,
2484
gaiaCopyRingCoords (o_ring, i_ring);
2489
gaiaFreeGeomColl (g2);
2495
if ((pts + lns + pgs) > 0)
2497
/* GEOMETRYCOLLECTION */
2501
geom = gaiaAllocGeomColl ();
2502
geom->Srid = chain->Srid;
2503
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2507
if (geom->Srid == -1)
2509
/* we haven't yet set any SRID */
2510
geom->Srid = g->Srid;
2514
if (g->Srid != geom->Srid && g->Srid != -1
2515
&& sqlite_handle != NULL)
2517
/* we'll try to apply a reprojection */
2518
#ifndef OMIT_PROJ /* but only if PROJ.4 is actually available */
2519
gml_proj_params (sqlite_handle, g->Srid, proj_from);
2520
gml_proj_params (sqlite_handle, geom->Srid,
2522
if (*proj_to == '\0' || *proj_from == '\0')
2526
g2 = gaiaTransform (g, proj_from, proj_to);
2534
pt = g2->FirstPoint;
2537
gaiaAddPointToGeomColl (geom, pt->X, pt->Y);
2540
ln = g2->FirstLinestring;
2544
gaiaAddLinestringToGeomColl (geom, ln->Points);
2545
gaiaCopyLinestringCoords (save_ln, ln);
2548
pg = g2->FirstPolygon;
2551
i_ring = pg->Exterior;
2553
gaiaAddPolygonToGeomColl (geom, i_ring->Points,
2555
o_ring = save_pg->Exterior;
2556
gaiaCopyRingCoords (o_ring, i_ring);
2557
for (ib = 0; ib < pg->NumInteriors; ib++)
2559
i_ring = pg->Interiors + ib;
2561
gaiaAddInteriorRing (save_pg, ib,
2563
gaiaCopyRingCoords (o_ring, i_ring);
2568
gaiaFreeGeomColl (g2);
2576
geom = gaiaAllocGeomCollXYZ ();
2577
geom->Srid = chain->Srid;
2578
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2582
if (geom->Srid == -1)
2584
/* we haven't yet a SRID set */
2585
geom->Srid = g->Srid;
2589
if (g->Srid != geom->Srid && g->Srid != -1
2590
&& sqlite_handle != NULL)
2592
/* we'll try to apply a reprojection */
2593
#ifndef OMIT_PROJ /* but only if PROJ.4 is actually available */
2594
gml_proj_params (sqlite_handle, g->Srid, proj_from);
2595
gml_proj_params (sqlite_handle, geom->Srid,
2597
if (*proj_to == '\0' || *proj_from == '\0')
2601
g2 = gaiaTransform (g, proj_from, proj_to);
2609
pt = g2->FirstPoint;
2612
gaiaAddPointToGeomCollXYZ (geom, pt->X, pt->Y,
2616
ln = g2->FirstLinestring;
2620
gaiaAddLinestringToGeomColl (geom, ln->Points);
2621
gaiaCopyLinestringCoords (save_ln, ln);
2624
pg = g2->FirstPolygon;
2627
i_ring = pg->Exterior;
2629
gaiaAddPolygonToGeomColl (geom, i_ring->Points,
2631
o_ring = save_pg->Exterior;
2632
gaiaCopyRingCoords (o_ring, i_ring);
2633
for (ib = 0; ib < pg->NumInteriors; ib++)
2635
i_ring = pg->Interiors + ib;
2637
gaiaAddInteriorRing (save_pg, ib,
2639
gaiaCopyRingCoords (o_ring, i_ring);
2644
gaiaFreeGeomColl (g2);
2654
gml_free_geom_chain (gaiaGeomCollPtr geom)
2656
/* deleting a chain of preliminary geometries */
2661
gaiaFreeGeomColl (geom);
2666
static gaiaGeomCollPtr
2667
gml_build_geometry (gmlNodePtr tree, sqlite3 * sqlite_handle)
2669
/* attempting to build a geometry from GML nodes */
2670
gaiaGeomCollPtr geom;
2671
gaiaGeomCollPtr result;
2677
geom_type = guessGmlGeometryType (tree);
2678
if (geom_type == GAIA_GML_UNKNOWN)
2680
/* unsupported main geometry type */
2683
/* creating the main geometry */
2684
geom = gaiaAllocGeomColl ();
2685
geom->Srid = guessGmlSrid (tree);
2689
/* parsing GML nodes accordingly with declared GML type */
2690
case GAIA_GML_POINT:
2691
geom->DeclaredType = GAIA_POINT;
2692
if (!gml_parse_point (geom, tree->Next, geom->Srid, &next))
2695
case GAIA_GML_LINESTRING:
2696
geom->DeclaredType = GAIA_LINESTRING;
2697
if (!gml_parse_linestring (geom, tree->Next, geom->Srid, &next))
2700
case GAIA_GML_CURVE:
2701
geom->DeclaredType = GAIA_LINESTRING;
2702
if (!gml_parse_curve (geom, tree->Next, geom->Srid, &next))
2705
case GAIA_GML_POLYGON:
2706
geom->DeclaredType = GAIA_POLYGON;
2707
if (!gml_parse_polygon (geom, tree->Next, geom->Srid, &next))
2712
case GAIA_GML_MULTIPOINT:
2713
geom->DeclaredType = GAIA_MULTIPOINT;
2714
if (!gml_parse_multi_point (geom, tree->Next))
2717
case GAIA_GML_MULTILINESTRING:
2718
geom->DeclaredType = GAIA_MULTILINESTRING;
2719
if (!gml_parse_multi_linestring (geom, tree->Next))
2722
case GAIA_GML_MULTICURVE:
2723
geom->DeclaredType = GAIA_MULTILINESTRING;
2724
if (!gml_parse_multi_curve (geom, tree->Next))
2727
case GAIA_GML_MULTIPOLYGON:
2728
geom->DeclaredType = GAIA_MULTIPOLYGON;
2729
if (!gml_parse_multi_polygon (geom, tree->Next))
2732
case GAIA_GML_MULTISURFACE:
2733
geom->DeclaredType = GAIA_MULTIPOLYGON;
2734
if (!gml_parse_multi_surface (geom, tree->Next))
2737
case GAIA_GML_MULTIGEOMETRY:
2738
geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
2739
if (!gml_parse_multi_geometry (geom, tree->Next))
2744
/* attempting to build the final geometry */
2745
result = gml_validate_geometry (geom, sqlite_handle);
2748
gml_free_geom_chain (geom);
2752
gml_free_geom_chain (geom);
2759
** CAVEAT: we must redefine any Lemon/Flex own macro
2761
#define YYMINORTYPE GML_MINORTYPE
2762
#define YY_CHAR GML_YY_CHAR
2763
#define input gml_input
2764
#define ParseAlloc gmlParseAlloc
2765
#define ParseFree gmlParseFree
2766
#define ParseStackPeak gmlParseStackPeak
2767
#define Parse gmlParse
2768
#define yyStackEntry gml_yyStackEntry
2769
#define yyzerominor gml_yyzerominor
2770
#define yy_accept gml_yy_accept
2771
#define yy_action gml_yy_action
2772
#define yy_base gml_yy_base
2773
#define yy_buffer_stack gml_yy_buffer_stack
2774
#define yy_buffer_stack_max gml_yy_buffer_stack_max
2775
#define yy_buffer_stack_top gml_yy_buffer_stack_top
2776
#define yy_c_buf_p gml_yy_c_buf_p
2777
#define yy_chk gml_yy_chk
2778
#define yy_def gml_yy_def
2779
#define yy_default gml_yy_default
2780
#define yy_destructor gml_yy_destructor
2781
#define yy_ec gml_yy_ec
2782
#define yy_fatal_error gml_yy_fatal_error
2783
#define yy_find_reduce_action gml_yy_find_reduce_action
2784
#define yy_find_shift_action gml_yy_find_shift_action
2785
#define yy_get_next_buffer gml_yy_get_next_buffer
2786
#define yy_get_previous_state gml_yy_get_previous_state
2787
#define yy_init gml_yy_init
2788
#define yy_init_globals gml_yy_init_globals
2789
#define yy_lookahead gml_yy_lookahead
2790
#define yy_meta gml_yy_meta
2791
#define yy_nxt gml_yy_nxt
2792
#define yy_parse_failed gml_yy_parse_failed
2793
#define yy_pop_parser_stack gml_yy_pop_parser_stack
2794
#define yy_reduce gml_yy_reduce
2795
#define yy_reduce_ofst gml_yy_reduce_ofst
2796
#define yy_shift gml_yy_shift
2797
#define yy_shift_ofst gml_yy_shift_ofst
2798
#define yy_start gml_yy_start
2799
#define yy_state_type gml_yy_state_type
2800
#define yy_syntax_error gml_yy_syntax_error
2801
#define yy_trans_info gml_yy_trans_info
2802
#define yy_try_NUL_trans gml_yy_try_NUL_trans
2803
#define yyParser gml_yyParser
2804
#define yyStackEntry gml_yyStackEntry
2805
#define yyStackOverflow gml_yyStackOverflow
2806
#define yyRuleInfo gml_yyRuleInfo
2807
#define yyunput gml_yyunput
2808
#define yyzerominor gml_yyzerominor
2809
#define yyTraceFILE gml_yyTraceFILE
2810
#define yyTracePrompt gml_yyTracePrompt
2811
#define yyTokenName gml_yyTokenName
2812
#define yyRuleName gml_yyRuleName
2813
#define ParseTrace gml_ParseTrace
2817
GML_LEMON_H_START - LEMON generated header starts here
2819
#define GML_NEWLINE 1
2823
#define GML_KEYWORD 5
2828
GML_LEMON_H_END - LEMON generated header ends here
2835
struct symtab *symp;
2837
#define YYSTYPE gml_yystype
2840
/* extern YYSTYPE yylval; */
2846
GML_LEMON_START - LEMON generated code starts here
2849
/* Driver template for the LEMON parser generator.
2850
** The author disclaims copyright to this source code.
2852
/* First off, code is included that follows the "include" declaration
2853
** in the input grammar file. */
2856
/* Next is all token values, in a form suitable for use by makeheaders.
2857
** This section will be null unless lemon is run with the -m switch.
2860
** These constants (all generated automatically by the parser generator)
2861
** specify the various kinds of tokens (terminals) that the parser
2864
** Each symbol here is a terminal symbol in the grammar.
2866
/* Make sure the INTERFACE macro is defined.
2869
# define INTERFACE 1
2871
/* The next thing included is series of defines which control
2872
** various aspects of the generated parser.
2873
** YYCODETYPE is the data type used for storing terminal
2874
** and nonterminal numbers. "unsigned char" is
2875
** used if there are fewer than 250 terminals
2876
** and nonterminals. "int" is used otherwise.
2877
** YYNOCODE is a number of type YYCODETYPE which corresponds
2878
** to no legal terminal or nonterminal number. This
2879
** number is used to fill in empty slots of the hash
2881
** YYFALLBACK If defined, this indicates that one or more tokens
2882
** have fall-back values which should be used if the
2883
** original value of the token will not parse.
2884
** YYACTIONTYPE is the data type used for storing terminal
2885
** and nonterminal numbers. "unsigned char" is
2886
** used if there are fewer than 250 rules and
2887
** states combined. "int" is used otherwise.
2888
** ParseTOKENTYPE is the data type used for minor tokens given
2889
** directly to the parser from the tokenizer.
2890
** YYMINORTYPE is the data type used for all minor tokens.
2891
** This is typically a union of many types, one of
2892
** which is ParseTOKENTYPE. The entry in the union
2893
** for base tokens is called "yy0".
2894
** YYSTACKDEPTH is the maximum depth of the parser's stack. If
2895
** zero the stack is dynamically sized using realloc()
2896
** ParseARG_SDECL A static variable declaration for the %extra_argument
2897
** ParseARG_PDECL A parameter declaration for the %extra_argument
2898
** ParseARG_STORE Code to store %extra_argument into yypParser
2899
** ParseARG_FETCH Code to extract %extra_argument from yypParser
2900
** YYNSTATE the combined number of states.
2901
** YYNRULE the number of rules in the grammar
2902
** YYERRORSYMBOL is the code number of the error symbol. If not
2903
** defined, then do no error processing.
2905
#define YYCODETYPE unsigned char
2907
#define YYACTIONTYPE unsigned char
2908
#define ParseTOKENTYPE void *
2913
#ifndef YYSTACKDEPTH
2914
#define YYSTACKDEPTH 1000000
2916
#define ParseARG_SDECL gmlNodePtr *result ;
2917
#define ParseARG_PDECL , gmlNodePtr *result
2918
#define ParseARG_FETCH gmlNodePtr *result = yypParser->result
2919
#define ParseARG_STORE yypParser->result = result
2922
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
2923
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
2924
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
2926
/* The yyzerominor constant is used to initialize instances of
2927
** YYMINORTYPE objects to zero. */
2928
static const YYMINORTYPE yyzerominor = { 0 };
2930
/* Define the yytestcase() macro to be a no-op if is not already defined
2933
** Applications can choose to define yytestcase() in the %include section
2934
** to a macro that can assist in verifying code coverage. For production
2935
** code the yytestcase() macro should be turned off. But it is useful
2939
# define yytestcase(X)
2943
/* Next are the tables used to determine what action to take based on the
2944
** current state and lookahead token. These tables are used to implement
2945
** functions that take a state number and lookahead value and return an
2948
** Suppose the action integer is N. Then the action is determined as
2951
** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
2952
** token onto the stack and goto state N.
2954
** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
2956
** N == YYNSTATE+YYNRULE A syntax error has occurred.
2958
** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
2960
** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
2961
** slots in the yy_action[] table.
2963
** The action table is constructed as a single large table named yy_action[].
2964
** Given state S and lookahead X, the action is computed as
2966
** yy_action[ yy_shift_ofst[S] + X ]
2968
** If the index value yy_shift_ofst[S]+X is out of range or if the value
2969
** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
2970
** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
2971
** and that yy_default[S] should be used instead.
2973
** The formula above is for computing the action when the lookahead is
2974
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
2975
** a reduce action) then the yy_reduce_ofst[] array is used in place of
2976
** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
2977
** YY_SHIFT_USE_DFLT.
2979
** The following are the tables generated in this section:
2981
** yy_action[] A single table containing all actions.
2982
** yy_lookahead[] A table containing the lookahead for each entry in
2983
** yy_action. Used to detect hash collisions.
2984
** yy_shift_ofst[] For each state, the offset into yy_action for
2985
** shifting terminals.
2986
** yy_reduce_ofst[] For each state, the offset into yy_action for
2987
** shifting non-terminals after a reduce.
2988
** yy_default[] Default action for each state.
2990
static const YYACTIONTYPE yy_action[] = {
2991
/* 0 */ 20, 28, 29, 4, 48, 5, 3, 3, 5, 5,
2992
/* 10 */ 42, 84, 1, 42, 42, 47, 46, 2, 10, 5,
2993
/* 20 */ 21, 12, 32, 23, 42, 38, 22, 6, 49, 23,
2994
/* 30 */ 13, 19, 14, 15, 35, 8, 8, 10, 25, 11,
2995
/* 40 */ 18, 34, 33, 45, 37, 16, 40, 17, 41, 14,
2996
/* 50 */ 9, 23, 43, 7, 45, 27, 30, 26, 31, 36,
2997
/* 60 */ 39, 44, 24,
2999
static const YYCODETYPE yy_lookahead[] = {
3000
/* 0 */ 12, 13, 14, 15, 16, 17, 15, 15, 17, 17,
3001
/* 10 */ 22, 10, 11, 22, 22, 24, 24, 15, 18, 17,
3002
/* 20 */ 2, 3, 8, 5, 22, 25, 2, 3, 0, 5,
3003
/* 30 */ 18, 19, 4, 20, 21, 20, 20, 18, 2, 3,
3004
/* 40 */ 2, 26, 26, 5, 25, 20, 21, 20, 21, 4,
3005
/* 50 */ 18, 5, 23, 20, 5, 1, 3, 23, 3, 7,
3008
#define YY_SHIFT_USE_DFLT (-1)
3009
#define YY_SHIFT_MAX 26
3010
static const signed char yy_shift_ofst[] = {
3011
/* 0 */ -1, 28, 45, 45, 45, 18, 14, 14, 14, 46,
3012
/* 10 */ 46, 14, 14, 24, 38, 14, 14, 14, 49, 36,
3013
/* 20 */ 54, 53, 55, 56, 52, 57, 58,
3015
#define YY_REDUCE_USE_DFLT (-13)
3016
#define YY_REDUCE_MAX 18
3017
static const signed char yy_reduce_ofst[] = {
3018
/* 0 */ 1, -12, -9, -8, 2, 12, 13, 15, 16, 0,
3019
/* 10 */ 19, 25, 27, 32, 29, 33, 33, 33, 34,
3021
static const YYACTIONTYPE yy_default[] = {
3022
/* 0 */ 50, 83, 72, 72, 54, 83, 60, 80, 80, 76,
3023
/* 10 */ 76, 61, 59, 83, 83, 64, 66, 62, 83, 83,
3024
/* 20 */ 83, 83, 83, 83, 83, 83, 83, 51, 52, 53,
3025
/* 30 */ 56, 57, 79, 81, 82, 65, 75, 77, 78, 58,
3026
/* 40 */ 67, 63, 68, 69, 70, 71, 73, 74, 55,
3028
#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
3030
/* The next table maps tokens into fallback tokens. If a construct
3031
** like the following:
3033
** %fallback ID X Y Z.
3035
** appears in the grammar, then ID becomes a fallback token for X, Y,
3036
** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
3037
** but it does not parse, the type of the token is changed to ID and
3038
** the parse is retried before an error is thrown.
3041
static const YYCODETYPE yyFallback[] = {
3043
#endif /* YYFALLBACK */
3045
/* The following structure represents a single element of the
3046
** parser's stack. Information stored includes:
3048
** + The state number for the parser at this level of the stack.
3050
** + The value of the token stored at this level of the stack.
3051
** (In other words, the "major" token.)
3053
** + The semantic value stored at this level of the stack. This is
3054
** the information used by the action routines in the grammar.
3055
** It is sometimes called the "minor" token.
3057
struct yyStackEntry {
3058
YYACTIONTYPE stateno; /* The state-number */
3059
YYCODETYPE major; /* The major token value. This is the code
3060
** number for the token at this stack level */
3061
YYMINORTYPE minor; /* The user-supplied minor token value. This
3062
** is the value of the token */
3064
typedef struct yyStackEntry yyStackEntry;
3066
/* The state of the parser is completely contained in an instance of
3067
** the following structure */
3069
int yyidx; /* Index of top element in stack */
3070
#ifdef YYTRACKMAXSTACKDEPTH
3071
int yyidxMax; /* Maximum value of yyidx */
3073
int yyerrcnt; /* Shifts left before out of the error */
3074
ParseARG_SDECL /* A place to hold %extra_argument */
3076
int yystksz; /* Current side of the stack */
3077
yyStackEntry *yystack; /* The parser's stack */
3079
yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
3082
typedef struct yyParser yyParser;
3086
static FILE *yyTraceFILE = 0;
3087
static char *yyTracePrompt = 0;
3092
** Turn parser tracing on by giving a stream to which to write the trace
3093
** and a prompt to preface each trace message. Tracing is turned off
3094
** by making either argument NULL
3098
** <li> A FILE* to which trace output should be written.
3099
** If NULL, then tracing is turned off.
3100
** <li> A prefix string written at the beginning of every
3101
** line of trace output. If NULL, then tracing is
3108
void ParseTrace(FILE *TraceFILE, char *zTracePrompt){
3109
yyTraceFILE = TraceFILE;
3110
yyTracePrompt = zTracePrompt;
3111
if( yyTraceFILE==0 ) yyTracePrompt = 0;
3112
else if( yyTracePrompt==0 ) yyTraceFILE = 0;
3117
/* For tracing shifts, the names of all terminals and nonterminals
3118
** are required. The following table supplies these names */
3119
static const char *const yyTokenName[] = {
3120
"$", "GML_NEWLINE", "GML_END", "GML_CLOSE",
3121
"GML_OPEN", "GML_KEYWORD", "GML_EQ", "GML_VALUE",
3122
"GML_COORD", "error", "main", "in",
3123
"state", "program", "gml_tree", "node",
3124
"node_chain", "open_tag", "attr", "attributes",
3125
"coord", "coord_chain", "close_tag", "keyword",
3126
"extra_nodes", "extra_attr", "extra_coord",
3131
/* For tracing reduce actions, the names of all rules are required.
3133
static const char *const yyRuleName[] = {
3134
/* 0 */ "main ::= in",
3136
/* 2 */ "in ::= in state GML_NEWLINE",
3137
/* 3 */ "state ::= program",
3138
/* 4 */ "program ::= gml_tree",
3139
/* 5 */ "gml_tree ::= node",
3140
/* 6 */ "gml_tree ::= node_chain",
3141
/* 7 */ "node ::= open_tag GML_END GML_CLOSE",
3142
/* 8 */ "node ::= open_tag attr GML_END GML_CLOSE",
3143
/* 9 */ "node ::= open_tag attributes GML_END GML_CLOSE",
3144
/* 10 */ "node ::= open_tag GML_CLOSE",
3145
/* 11 */ "node ::= open_tag attr GML_CLOSE",
3146
/* 12 */ "node ::= open_tag attributes GML_CLOSE",
3147
/* 13 */ "node ::= open_tag GML_CLOSE coord",
3148
/* 14 */ "node ::= open_tag GML_CLOSE coord_chain",
3149
/* 15 */ "node ::= open_tag attr GML_CLOSE coord",
3150
/* 16 */ "node ::= open_tag attr GML_CLOSE coord_chain",
3151
/* 17 */ "node ::= open_tag attributes GML_CLOSE coord",
3152
/* 18 */ "node ::= open_tag attributes GML_CLOSE coord_chain",
3153
/* 19 */ "node ::= close_tag",
3154
/* 20 */ "open_tag ::= GML_OPEN keyword",
3155
/* 21 */ "close_tag ::= GML_OPEN GML_END keyword GML_CLOSE",
3156
/* 22 */ "keyword ::= GML_KEYWORD",
3157
/* 23 */ "extra_nodes ::=",
3158
/* 24 */ "extra_nodes ::= node extra_nodes",
3159
/* 25 */ "node_chain ::= node node extra_nodes",
3160
/* 26 */ "attr ::= GML_KEYWORD GML_EQ GML_VALUE",
3161
/* 27 */ "extra_attr ::=",
3162
/* 28 */ "extra_attr ::= attr extra_attr",
3163
/* 29 */ "attributes ::= attr attr extra_attr",
3164
/* 30 */ "coord ::= GML_COORD",
3165
/* 31 */ "extra_coord ::=",
3166
/* 32 */ "extra_coord ::= coord extra_coord",
3167
/* 33 */ "coord_chain ::= coord coord extra_coord",
3174
** Try to increase the size of the parser stack.
3176
static void yyGrowStack(yyParser *p){
3180
newSize = p->yystksz*2 + 100;
3181
pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
3184
p->yystksz = newSize;
3187
fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
3188
yyTracePrompt, p->yystksz);
3196
** This function allocates a new parser.
3197
** The only argument is a pointer to a function which works like
3201
** A pointer to the function used to allocate memory.
3204
** A pointer to a parser. This pointer is used in subsequent calls
3205
** to Parse and ParseFree.
3207
void *ParseAlloc(void *(*mallocProc)(size_t)){
3209
pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
3211
pParser->yyidx = -1;
3212
#ifdef YYTRACKMAXSTACKDEPTH
3213
pParser->yyidxMax = 0;
3216
pParser->yystack = NULL;
3217
pParser->yystksz = 0;
3218
yyGrowStack(pParser);
3224
/* The following function deletes the value associated with a
3225
** symbol. The symbol can be either a terminal or nonterminal.
3226
** "yymajor" is the symbol code, and "yypminor" is a pointer to
3229
static void yy_destructor(
3230
yyParser *yypParser, /* The parser */
3231
YYCODETYPE yymajor, /* Type code for object to destroy */
3232
YYMINORTYPE *yypminor /* The object to be destroyed */
3236
/* Here is inserted the actions which take place when a
3237
** terminal or non-terminal is destroyed. This can happen
3238
** when the symbol is popped from the stack during a
3239
** reduce or during error processing or when a parser is
3240
** being destroyed before it is finished parsing.
3242
** Note: during a reduce, the only symbols destroyed are those
3243
** which appear on the RHS of the rule, but which are not used
3244
** inside the C code.
3246
default: break; /* If no destructor action specified: do nothing */
3251
** Pop the parser's stack once.
3253
** If there is a destructor routine associated with the token which
3254
** is popped from the stack, then call it.
3256
** Return the major token number for the symbol popped.
3258
static int yy_pop_parser_stack(yyParser *pParser){
3260
yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
3262
if( pParser->yyidx<0 ) return 0;
3264
if( yyTraceFILE && pParser->yyidx>=0 ){
3265
fprintf(yyTraceFILE,"%sPopping %s\n",
3267
yyTokenName[yytos->major]);
3270
yymajor = yytos->major;
3271
yy_destructor(pParser, yymajor, &yytos->minor);
3277
** Deallocate and destroy a parser. Destructors are all called for
3278
** all stack elements before shutting the parser down.
3282
** <li> A pointer to the parser. This should be a pointer
3283
** obtained from ParseAlloc.
3284
** <li> A pointer to a function used to reclaim memory obtained
3289
void *p, /* The parser to be deleted */
3290
void (*freeProc)(void*) /* Function used to reclaim memory */
3292
yyParser *pParser = (yyParser*)p;
3293
if( pParser==0 ) return;
3294
while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
3296
free(pParser->yystack);
3298
(*freeProc)((void*)pParser);
3302
** Return the peak depth of the stack for a parser.
3304
#ifdef YYTRACKMAXSTACKDEPTH
3305
int ParseStackPeak(void *p){
3306
yyParser *pParser = (yyParser*)p;
3307
return pParser->yyidxMax;
3312
** Find the appropriate action for a parser given the terminal
3313
** look-ahead token iLookAhead.
3315
** If the look-ahead token is YYNOCODE, then check to see if the action is
3316
** independent of the look-ahead. If it is, return the action, otherwise
3317
** return YY_NO_ACTION.
3319
static int yy_find_shift_action(
3320
yyParser *pParser, /* The parser */
3321
YYCODETYPE iLookAhead /* The look-ahead token */
3324
int stateno = pParser->yystack[pParser->yyidx].stateno;
3326
if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
3327
return yy_default[stateno];
3329
assert( iLookAhead!=YYNOCODE );
3331
if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
3334
YYCODETYPE iFallback; /* Fallback token */
3335
if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
3336
&& (iFallback = yyFallback[iLookAhead])!=0 ){
3339
fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
3340
yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
3343
return yy_find_shift_action(pParser, iFallback);
3348
int j = i - iLookAhead + YYWILDCARD;
3349
if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){
3352
fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
3353
yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
3356
return yy_action[j];
3359
#endif /* YYWILDCARD */
3361
return yy_default[stateno];
3363
return yy_action[i];
3368
** Find the appropriate action for a parser given the non-terminal
3369
** look-ahead token iLookAhead.
3371
** If the look-ahead token is YYNOCODE, then check to see if the action is
3372
** independent of the look-ahead. If it is, return the action, otherwise
3373
** return YY_NO_ACTION.
3375
static int yy_find_reduce_action(
3376
int stateno, /* Current state number */
3377
YYCODETYPE iLookAhead /* The look-ahead token */
3380
#ifdef YYERRORSYMBOL
3381
if( stateno>YY_REDUCE_MAX ){
3382
return yy_default[stateno];
3385
assert( stateno<=YY_REDUCE_MAX );
3387
i = yy_reduce_ofst[stateno];
3388
assert( i!=YY_REDUCE_USE_DFLT );
3389
assert( iLookAhead!=YYNOCODE );
3391
#ifdef YYERRORSYMBOL
3392
if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
3393
return yy_default[stateno];
3396
assert( i>=0 && i<YY_SZ_ACTTAB );
3397
assert( yy_lookahead[i]==iLookAhead );
3399
return yy_action[i];
3403
** The following routine is called if the stack overflows.
3405
static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
3410
fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
3413
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
3414
/* Here code is inserted which will execute if the parser
3415
** stack every overflows */
3417
fprintf(stderr,"Giving up. Parser stack overflow\n");
3418
ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
3422
** Perform a shift action.
3424
static void yy_shift(
3425
yyParser *yypParser, /* The parser to be shifted */
3426
int yyNewState, /* The new state to shift in */
3427
int yyMajor, /* The major token to shift in */
3428
YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */
3430
yyStackEntry *yytos;
3432
#ifdef YYTRACKMAXSTACKDEPTH
3433
if( yypParser->yyidx>yypParser->yyidxMax ){
3434
yypParser->yyidxMax = yypParser->yyidx;
3438
if( yypParser->yyidx>=YYSTACKDEPTH ){
3439
yyStackOverflow(yypParser, yypMinor);
3443
if( yypParser->yyidx>=yypParser->yystksz ){
3444
yyGrowStack(yypParser);
3445
if( yypParser->yyidx>=yypParser->yystksz ){
3446
yyStackOverflow(yypParser, yypMinor);
3451
yytos = &yypParser->yystack[yypParser->yyidx];
3452
yytos->stateno = (YYACTIONTYPE)yyNewState;
3453
yytos->major = (YYCODETYPE)yyMajor;
3454
yytos->minor = *yypMinor;
3456
if( yyTraceFILE && yypParser->yyidx>0 ){
3458
fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
3459
fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
3460
for(i=1; i<=yypParser->yyidx; i++)
3461
fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
3462
fprintf(yyTraceFILE,"\n");
3467
/* The following table contains information about every rule that
3468
** is used during the reduce.
3470
static const struct {
3471
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
3472
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
3510
static void yy_accept(yyParser*); /* Forward Declaration */
3513
** Perform a reduce action and the shift that must immediately
3514
** follow the reduce.
3516
static void yy_reduce(
3517
yyParser *yypParser, /* The parser */
3518
int yyruleno /* Number of the rule by which to reduce */
3520
int yygoto; /* The next state */
3521
int yyact; /* The next action */
3522
YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
3523
yyStackEntry *yymsp; /* The top of the parser's stack */
3524
int yysize; /* Amount to pop the stack */
3526
yymsp = &yypParser->yystack[yypParser->yyidx];
3528
if( yyTraceFILE && yyruleno>=0
3529
&& yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
3530
fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
3531
yyRuleName[yyruleno]);
3535
/* Silence complaints from purify about yygotominor being uninitialized
3536
** in some cases when it is copied into the stack after the following
3537
** switch. yygotominor is uninitialized when a rule reduces that does
3538
** not set the value of its left-hand side nonterminal. Leaving the
3539
** value of the nonterminal uninitialized is utterly harmless as long
3540
** as the value is never used. So really the only thing this code
3541
** accomplishes is to quieten purify.
3543
** 2007-01-16: The wireshark project (www.wireshark.org) reports that
3544
** without this code, their parser segfaults. I'm not sure what there
3545
** parser is doing to make this happen. This is the second bug report
3546
** from wireshark this week. Clearly they are stressing Lemon in ways
3547
** that it has not been previously stressed... (SQLite ticket #2172)
3549
/*memset(&yygotominor, 0, sizeof(yygotominor));*/
3550
yygotominor = yyzerominor;
3554
/* Beginning here are the reduction cases. A typical example
3557
** #line <lineno> <grammarfile>
3558
** { ... } // User supplied code
3559
** #line <lineno> <thisfile>
3562
case 5: /* gml_tree ::= node */
3563
case 6: /* gml_tree ::= node_chain */ yytestcase(yyruleno==6);
3564
{ *result = yymsp[0].minor.yy0; }
3566
case 7: /* node ::= open_tag GML_END GML_CLOSE */
3567
{ yygotominor.yy0 = gml_createSelfClosedNode((void *)yymsp[-2].minor.yy0, NULL); }
3569
case 8: /* node ::= open_tag attr GML_END GML_CLOSE */
3570
case 9: /* node ::= open_tag attributes GML_END GML_CLOSE */ yytestcase(yyruleno==9);
3571
{ yygotominor.yy0 = gml_createSelfClosedNode((void *)yymsp[-3].minor.yy0, (void *)yymsp[-2].minor.yy0); }
3573
case 10: /* node ::= open_tag GML_CLOSE */
3574
{ yygotominor.yy0 = gml_createNode((void *)yymsp[-1].minor.yy0, NULL, NULL); }
3576
case 11: /* node ::= open_tag attr GML_CLOSE */
3577
case 12: /* node ::= open_tag attributes GML_CLOSE */ yytestcase(yyruleno==12);
3578
{ yygotominor.yy0 = gml_createNode((void *)yymsp[-2].minor.yy0, (void *)yymsp[-1].minor.yy0, NULL); }
3580
case 13: /* node ::= open_tag GML_CLOSE coord */
3581
case 14: /* node ::= open_tag GML_CLOSE coord_chain */ yytestcase(yyruleno==14);
3582
{ yygotominor.yy0 = gml_createNode((void *)yymsp[-2].minor.yy0, NULL, (void *)yymsp[0].minor.yy0); }
3584
case 15: /* node ::= open_tag attr GML_CLOSE coord */
3585
case 16: /* node ::= open_tag attr GML_CLOSE coord_chain */ yytestcase(yyruleno==16);
3586
case 17: /* node ::= open_tag attributes GML_CLOSE coord */ yytestcase(yyruleno==17);
3587
case 18: /* node ::= open_tag attributes GML_CLOSE coord_chain */ yytestcase(yyruleno==18);
3588
{ yygotominor.yy0 = gml_createNode((void *)yymsp[-3].minor.yy0, (void *)yymsp[-2].minor.yy0, (void *)yymsp[0].minor.yy0); }
3590
case 19: /* node ::= close_tag */
3591
{ yygotominor.yy0 = gml_closingNode((void *)yymsp[0].minor.yy0); }
3593
case 20: /* open_tag ::= GML_OPEN keyword */
3594
case 22: /* keyword ::= GML_KEYWORD */ yytestcase(yyruleno==22);
3595
{ yygotominor.yy0 = yymsp[0].minor.yy0; }
3597
case 21: /* close_tag ::= GML_OPEN GML_END keyword GML_CLOSE */
3598
{ yygotominor.yy0 = yymsp[-1].minor.yy0; }
3600
case 23: /* extra_nodes ::= */
3601
case 27: /* extra_attr ::= */ yytestcase(yyruleno==27);
3602
case 31: /* extra_coord ::= */ yytestcase(yyruleno==31);
3603
{ yygotominor.yy0 = NULL; }
3605
case 24: /* extra_nodes ::= node extra_nodes */
3606
{ ((gmlNodePtr)yymsp[-1].minor.yy0)->Next = (gmlNodePtr)yymsp[0].minor.yy0; yygotominor.yy0 = yymsp[-1].minor.yy0; }
3608
case 25: /* node_chain ::= node node extra_nodes */
3610
((gmlNodePtr)yymsp[-1].minor.yy0)->Next = (gmlNodePtr)yymsp[0].minor.yy0;
3611
((gmlNodePtr)yymsp[-2].minor.yy0)->Next = (gmlNodePtr)yymsp[-1].minor.yy0;
3612
yygotominor.yy0 = yymsp[-2].minor.yy0;
3615
case 26: /* attr ::= GML_KEYWORD GML_EQ GML_VALUE */
3616
{ yygotominor.yy0 = gml_attribute((void *)yymsp[-2].minor.yy0, (void *)yymsp[0].minor.yy0); }
3618
case 28: /* extra_attr ::= attr extra_attr */
3619
{ ((gmlAttrPtr)yymsp[-1].minor.yy0)->Next = (gmlAttrPtr)yymsp[0].minor.yy0; yygotominor.yy0 = yymsp[-1].minor.yy0; }
3621
case 29: /* attributes ::= attr attr extra_attr */
3623
((gmlAttrPtr)yymsp[-1].minor.yy0)->Next = (gmlAttrPtr)yymsp[0].minor.yy0;
3624
((gmlAttrPtr)yymsp[-2].minor.yy0)->Next = (gmlAttrPtr)yymsp[-1].minor.yy0;
3625
yygotominor.yy0 = yymsp[-2].minor.yy0;
3628
case 30: /* coord ::= GML_COORD */
3629
{ yygotominor.yy0 = gml_coord((void *)yymsp[0].minor.yy0); }
3631
case 32: /* extra_coord ::= coord extra_coord */
3632
{ ((gmlCoordPtr)yymsp[-1].minor.yy0)->Next = (gmlCoordPtr)yymsp[0].minor.yy0; yygotominor.yy0 = yymsp[-1].minor.yy0; }
3634
case 33: /* coord_chain ::= coord coord extra_coord */
3636
((gmlCoordPtr)yymsp[-1].minor.yy0)->Next = (gmlCoordPtr)yymsp[0].minor.yy0;
3637
((gmlCoordPtr)yymsp[-2].minor.yy0)->Next = (gmlCoordPtr)yymsp[-1].minor.yy0;
3638
yygotominor.yy0 = yymsp[-2].minor.yy0;
3642
/* (0) main ::= in */ yytestcase(yyruleno==0);
3643
/* (1) in ::= */ yytestcase(yyruleno==1);
3644
/* (2) in ::= in state GML_NEWLINE */ yytestcase(yyruleno==2);
3645
/* (3) state ::= program */ yytestcase(yyruleno==3);
3646
/* (4) program ::= gml_tree */ yytestcase(yyruleno==4);
3649
yygoto = yyRuleInfo[yyruleno].lhs;
3650
yysize = yyRuleInfo[yyruleno].nrhs;
3651
yypParser->yyidx -= yysize;
3652
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
3653
if( yyact < YYNSTATE ){
3655
/* If we are not debugging and the reduce action popped at least
3656
** one element off the stack, then we can push the new element back
3657
** onto the stack here, and skip the stack overflow test in yy_shift().
3658
** That gives a significant speed improvement. */
3662
yymsp->stateno = (YYACTIONTYPE)yyact;
3663
yymsp->major = (YYCODETYPE)yygoto;
3664
yymsp->minor = yygotominor;
3668
yy_shift(yypParser,yyact,yygoto,&yygotominor);
3671
assert( yyact == YYNSTATE + YYNRULE + 1 );
3672
yy_accept(yypParser);
3677
** The following code executes when the parse fails
3679
#ifndef YYNOERRORRECOVERY
3680
static void yy_parse_failed(
3681
yyParser *yypParser /* The parser */
3686
fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
3689
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
3690
/* Here code is inserted which will be executed whenever the
3692
ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
3694
#endif /* YYNOERRORRECOVERY */
3697
** The following code executes when a syntax error first occurs.
3699
static void yy_syntax_error(
3700
yyParser *yypParser, /* The parser */
3701
int yymajor, /* The major type of the error token */
3702
YYMINORTYPE yyminor /* The minor type of the error token */
3705
#define TOKEN (yyminor.yy0)
3708
** when the LEMON parser encounters an error
3709
** then this global variable is set
3711
gml_parse_error = 1;
3713
ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
3717
** The following is executed when the parser accepts
3719
static void yy_accept(
3720
yyParser *yypParser /* The parser */
3725
fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
3728
while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
3729
/* Here code is inserted which will be executed whenever the
3730
** parser accepts */
3731
ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
3734
/* The main parser program.
3735
** The first argument is a pointer to a structure obtained from
3736
** "ParseAlloc" which describes the current state of the parser.
3737
** The second argument is the major token number. The third is
3738
** the minor token. The fourth optional argument is whatever the
3739
** user wants (and specified in the grammar) and is available for
3740
** use by the action routines.
3744
** <li> A pointer to the parser (an opaque structure.)
3745
** <li> The major token number.
3746
** <li> The minor token number.
3747
** <li> An option argument of a grammar-specified type.
3754
void *yyp, /* The parser */
3755
int yymajor, /* The major token code number */
3756
ParseTOKENTYPE yyminor /* The value for the token */
3757
ParseARG_PDECL /* Optional %extra_argument parameter */
3759
YYMINORTYPE yyminorunion;
3760
int yyact; /* The parser action. */
3761
int yyendofinput; /* True if we are at the end of input */
3762
#ifdef YYERRORSYMBOL
3763
int yyerrorhit = 0; /* True if yymajor has invoked an error */
3765
yyParser *yypParser; /* The parser */
3767
/* (re)initialize the parser, if necessary */
3768
yypParser = (yyParser*)yyp;
3769
if( yypParser->yyidx<0 ){
3771
if( yypParser->yystksz <=0 ){
3772
/*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
3773
yyminorunion = yyzerominor;
3774
yyStackOverflow(yypParser, &yyminorunion);
3778
yypParser->yyidx = 0;
3779
yypParser->yyerrcnt = -1;
3780
yypParser->yystack[0].stateno = 0;
3781
yypParser->yystack[0].major = 0;
3783
yyminorunion.yy0 = yyminor;
3784
yyendofinput = (yymajor==0);
3789
fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
3794
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
3795
if( yyact<YYNSTATE ){
3796
assert( !yyendofinput ); /* Impossible to shift the $ token */
3797
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
3798
yypParser->yyerrcnt--;
3800
}else if( yyact < YYNSTATE + YYNRULE ){
3801
yy_reduce(yypParser,yyact-YYNSTATE);
3803
assert( yyact == YY_ERROR_ACTION );
3804
#ifdef YYERRORSYMBOL
3809
fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
3812
#ifdef YYERRORSYMBOL
3813
/* A syntax error has occurred.
3814
** The response to an error depends upon whether or not the
3815
** grammar defines an error token "ERROR".
3817
** This is what we do if the grammar does define ERROR:
3819
** * Call the %syntax_error function.
3821
** * Begin popping the stack until we enter a state where
3822
** it is legal to shift the error symbol, then shift
3823
** the error symbol.
3825
** * Set the error count to three.
3827
** * Begin accepting and shifting new tokens. No new error
3828
** processing will occur until three tokens have been
3829
** shifted successfully.
3832
if( yypParser->yyerrcnt<0 ){
3833
yy_syntax_error(yypParser,yymajor,yyminorunion);
3835
yymx = yypParser->yystack[yypParser->yyidx].major;
3836
if( yymx==YYERRORSYMBOL || yyerrorhit ){
3839
fprintf(yyTraceFILE,"%sDiscard input token %s\n",
3840
yyTracePrompt,yyTokenName[yymajor]);
3843
yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
3847
yypParser->yyidx >= 0 &&
3848
yymx != YYERRORSYMBOL &&
3849
(yyact = yy_find_reduce_action(
3850
yypParser->yystack[yypParser->yyidx].stateno,
3851
YYERRORSYMBOL)) >= YYNSTATE
3853
yy_pop_parser_stack(yypParser);
3855
if( yypParser->yyidx < 0 || yymajor==0 ){
3856
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
3857
yy_parse_failed(yypParser);
3859
}else if( yymx!=YYERRORSYMBOL ){
3862
yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
3865
yypParser->yyerrcnt = 3;
3867
#elif defined(YYNOERRORRECOVERY)
3868
/* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
3869
** do any kind of error recovery. Instead, simply invoke the syntax
3870
** error routine and continue going as if nothing had happened.
3872
** Applications can set this macro (for example inside %include) if
3873
** they intend to abandon the parse upon the first syntax error seen.
3875
yy_syntax_error(yypParser,yymajor,yyminorunion);
3876
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
3879
#else /* YYERRORSYMBOL is not defined */
3880
/* This is what we do if the grammar does not define ERROR:
3882
** * Report an error message, and throw away the input token.
3884
** * If the input token is $, then fail the parse.
3886
** As before, subsequent error messages are suppressed until
3887
** three input tokens have been successfully shifted.
3889
if( yypParser->yyerrcnt<=0 ){
3890
yy_syntax_error(yypParser,yymajor,yyminorunion);
3892
yypParser->yyerrcnt = 3;
3893
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
3895
yy_parse_failed(yypParser);
3900
}while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
3906
GML_LEMON_END - LEMON generated code ends here
3926
** CAVEAT: there is an incompatibility between LEMON and FLEX
3927
** this macro resolves the issue
3930
#define yy_accept yy_gml_flex_accept
3935
GML_FLEX_START - FLEX generated code starts here
3940
#define YY_INT_ALIGNED short int
3942
/* A lexical scanner generated by flex */
3944
#define yy_create_buffer Gml_create_buffer
3945
#define yy_delete_buffer Gml_delete_buffer
3946
#define yy_flex_debug Gml_flex_debug
3947
#define yy_init_buffer Gml_init_buffer
3948
#define yy_flush_buffer Gml_flush_buffer
3949
#define yy_load_buffer_state Gml_load_buffer_state
3950
#define yy_switch_to_buffer Gml_switch_to_buffer
3952
#define yyleng Gmlleng
3953
#define yylex Gmllex
3954
#define yylineno Gmllineno
3955
#define yyout Gmlout
3956
#define yyrestart Gmlrestart
3957
#define yytext Gmltext
3958
#define yywrap Gmlwrap
3959
#define yyalloc Gmlalloc
3960
#define yyrealloc Gmlrealloc
3961
#define yyfree Gmlfree
3963
#define FLEX_SCANNER
3964
#define YY_FLEX_MAJOR_VERSION 2
3965
#define YY_FLEX_MINOR_VERSION 5
3966
#define YY_FLEX_SUBMINOR_VERSION 35
3967
#if YY_FLEX_SUBMINOR_VERSION > 0
3971
/* First, we deal with platform-specific or compiler-specific issues. */
3973
/* begin standard C headers. */
3979
/* end standard C headers. */
3981
/* flex integer type definitions */
3986
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
3988
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
3990
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
3991
* if you want the limit (max/min) macros for int types.
3993
#ifndef __STDC_LIMIT_MACROS
3994
#define __STDC_LIMIT_MACROS 1
3997
#include <inttypes.h>
3998
typedef int8_t flex_int8_t;
3999
typedef uint8_t flex_uint8_t;
4000
typedef int16_t flex_int16_t;
4001
typedef uint16_t flex_uint16_t;
4002
typedef int32_t flex_int32_t;
4003
typedef uint32_t flex_uint32_t;
4005
typedef signed char flex_int8_t;
4006
typedef short int flex_int16_t;
4007
typedef int flex_int32_t;
4008
typedef unsigned char flex_uint8_t;
4009
typedef unsigned short int flex_uint16_t;
4010
typedef unsigned int flex_uint32_t;
4012
/* Limits of integral types. */
4014
#define INT8_MIN (-128)
4017
#define INT16_MIN (-32767-1)
4020
#define INT32_MIN (-2147483647-1)
4023
#define INT8_MAX (127)
4026
#define INT16_MAX (32767)
4029
#define INT32_MAX (2147483647)
4032
#define UINT8_MAX (255U)
4035
#define UINT16_MAX (65535U)
4038
#define UINT32_MAX (4294967295U)
4043
#endif /* ! FLEXINT_H */
4047
/* The "const" storage-class-modifier is valid. */
4048
#define YY_USE_CONST
4050
#else /* ! __cplusplus */
4052
/* C99 requires __STDC__ to be defined as 1. */
4053
#if defined (__STDC__)
4055
#define YY_USE_CONST
4057
#endif /* defined (__STDC__) */
4058
#endif /* ! __cplusplus */
4061
#define yyconst const
4066
/* Returned upon end-of-file. */
4069
/* Promotes a possibly negative, possibly signed char to an unsigned
4070
* integer for use as an array index. If the signed char is negative,
4071
* we want to instead treat it as an 8-bit unsigned char, hence the
4074
#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
4076
/* Enter a start condition. This macro really ought to take a parameter,
4077
* but we do it the disgusting crufty way forced on us by the ()-less
4078
* definition of BEGIN.
4080
#define BEGIN (yy_start) = 1 + 2 *
4082
/* Translate the current start state into a value that can be later handed
4083
* to BEGIN to return to the state. The YYSTATE alias is for lex
4086
#define YY_START (((yy_start) - 1) / 2)
4087
#define YYSTATE YY_START
4089
/* Action number for EOF rule of a given start state. */
4090
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
4092
/* Special action meaning "start processing a new file". */
4093
#define YY_NEW_FILE Gmlrestart(Gmlin )
4095
#define YY_END_OF_BUFFER_CHAR 0
4097
/* Size of default input buffer. */
4100
/* On IA-64, the buffer size is 16k, not 8k.
4101
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
4102
* Ditto for the __ia64__ case accordingly.
4104
#define YY_BUF_SIZE 32768
4106
#define YY_BUF_SIZE 16384
4107
#endif /* __ia64__ */
4110
/* The state buf must be large enough to hold one state per character in the main buffer.
4112
#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
4114
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
4115
#define YY_TYPEDEF_YY_BUFFER_STATE
4116
typedef struct yy_buffer_state *YY_BUFFER_STATE;
4121
extern FILE *Gmlin, *Gmlout;
4123
#define EOB_ACT_CONTINUE_SCAN 0
4124
#define EOB_ACT_END_OF_FILE 1
4125
#define EOB_ACT_LAST_MATCH 2
4127
/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
4128
* access to the local variable yy_act. Since yyless() is a macro, it would break
4129
* existing scanners that call yyless() from OUTSIDE Gmllex.
4130
* One obvious solution it to make yy_act a global. I tried that, and saw
4131
* a 5% performance hit in a non-Gmllineno scanner, because yy_act is
4132
* normally declared as a register variable-- so it is not worth it.
4134
#define YY_LESS_LINENO(n) \
4137
for ( yyl = n; yyl < Gmlleng; ++yyl )\
4138
if ( Gmltext[yyl] == '\n' )\
4142
/* Return all but the first "n" matched characters back to the input stream. */
4146
/* Undo effects of setting up Gmltext. */ \
4147
int yyless_macro_arg = (n); \
4148
YY_LESS_LINENO(yyless_macro_arg);\
4149
*yy_cp = (yy_hold_char); \
4150
YY_RESTORE_YY_MORE_OFFSET \
4151
(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
4152
YY_DO_BEFORE_ACTION; /* set up Gmltext again */ \
4156
#define unput(c) yyunput( c, (yytext_ptr) )
4158
#ifndef YY_TYPEDEF_YY_SIZE_T
4159
#define YY_TYPEDEF_YY_SIZE_T
4160
typedef size_t yy_size_t;
4163
#ifndef YY_STRUCT_YY_BUFFER_STATE
4164
#define YY_STRUCT_YY_BUFFER_STATE
4165
struct yy_buffer_state
4167
FILE *yy_input_file;
4169
char *yy_ch_buf; /* input buffer */
4170
char *yy_buf_pos; /* current position in input buffer */
4172
/* Size of input buffer in bytes, not including room for EOB
4175
yy_size_t yy_buf_size;
4177
/* Number of characters read into yy_ch_buf, not including EOB
4182
/* Whether we "own" the buffer - i.e., we know we created it,
4183
* and can realloc() it to grow it, and should free() it to
4186
int yy_is_our_buffer;
4188
/* Whether this is an "interactive" input source; if so, and
4189
* if we're using stdio for input, then we want to use getc()
4190
* instead of fread(), to make sure we stop fetching input after
4193
int yy_is_interactive;
4195
/* Whether we're considered to be at the beginning of a line.
4196
* If so, '^' rules will be active on the next match, otherwise
4201
int yy_bs_lineno; /**< The line count. */
4202
int yy_bs_column; /**< The column count. */
4204
/* Whether to try to fill the input buffer when we reach the
4209
int yy_buffer_status;
4211
#define YY_BUFFER_NEW 0
4212
#define YY_BUFFER_NORMAL 1
4213
/* When an EOF's been seen but there's still some text to process
4214
* then we mark the buffer as YY_EOF_PENDING, to indicate that we
4215
* shouldn't try reading from the input source any more. We might
4216
* still have a bunch of tokens to match, though, because of
4217
* possible backing-up.
4219
* When we actually see the EOF, we change the status to "new"
4220
* (via Gmlrestart()), so that the user can continue scanning by
4221
* just pointing Gmlin at a new input file.
4223
#define YY_BUFFER_EOF_PENDING 2
4226
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
4228
/* Stack of input buffers. */
4229
static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
4230
static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
4231
static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
4233
/* We provide macros for accessing buffer states in case in the
4234
* future we want to put the buffer states in a more general
4237
* Returns the top of the stack, or NULL.
4239
#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
4240
? (yy_buffer_stack)[(yy_buffer_stack_top)] \
4243
/* Same as previous macro, but useful when we know that the buffer stack is not
4244
* NULL or when we need an lvalue. For internal use only.
4246
#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
4248
/* yy_hold_char holds the character lost when Gmltext is formed. */
4249
static char yy_hold_char;
4250
static int yy_n_chars; /* number of characters read into yy_ch_buf */
4253
/* Points to current character in buffer. */
4254
static char *yy_c_buf_p = (char *) 0;
4255
static int yy_init = 0; /* whether we need to initialize */
4256
static int yy_start = 0; /* start state number */
4258
/* Flag which is used to allow Gmlwrap()'s to do buffer switches
4259
* instead of setting up a fresh Gmlin. A bit of a hack ...
4261
static int yy_did_buffer_switch_on_eof;
4263
void Gmlrestart (FILE *input_file );
4264
void Gml_switch_to_buffer (YY_BUFFER_STATE new_buffer );
4265
YY_BUFFER_STATE Gml_create_buffer (FILE *file,int size );
4266
void Gml_delete_buffer (YY_BUFFER_STATE b );
4267
void Gml_flush_buffer (YY_BUFFER_STATE b );
4268
void Gmlpush_buffer_state (YY_BUFFER_STATE new_buffer );
4269
void Gmlpop_buffer_state (void );
4271
static void Gmlensure_buffer_stack (void );
4272
static void Gml_load_buffer_state (void );
4273
static void Gml_init_buffer (YY_BUFFER_STATE b,FILE *file );
4275
#define YY_FLUSH_BUFFER Gml_flush_buffer(YY_CURRENT_BUFFER )
4277
YY_BUFFER_STATE Gml_scan_buffer (char *base,yy_size_t size );
4278
YY_BUFFER_STATE Gml_scan_string (yyconst char *yy_str );
4279
YY_BUFFER_STATE Gml_scan_bytes (yyconst char *bytes,int len );
4281
void *Gmlalloc (yy_size_t );
4282
void *Gmlrealloc (void *,yy_size_t );
4283
void Gmlfree (void * );
4285
#define yy_new_buffer Gml_create_buffer
4287
#define yy_set_interactive(is_interactive) \
4289
if ( ! YY_CURRENT_BUFFER ){ \
4290
Gmlensure_buffer_stack (); \
4291
YY_CURRENT_BUFFER_LVALUE = \
4292
Gml_create_buffer(Gmlin,YY_BUF_SIZE ); \
4294
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
4297
#define yy_set_bol(at_bol) \
4299
if ( ! YY_CURRENT_BUFFER ){\
4300
Gmlensure_buffer_stack (); \
4301
YY_CURRENT_BUFFER_LVALUE = \
4302
Gml_create_buffer(Gmlin,YY_BUF_SIZE ); \
4304
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
4307
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
4309
/* Begin user sect3 */
4311
typedef unsigned char YY_CHAR;
4313
FILE *Gmlin = (FILE *) 0, *Gmlout = (FILE *) 0;
4315
typedef int yy_state_type;
4317
#define YY_FLEX_LEX_COMPAT
4318
extern int Gmllineno;
4322
extern char Gmltext[];
4324
static yy_state_type yy_get_previous_state (void );
4325
static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
4326
static int yy_get_next_buffer (void );
4327
static void yy_fatal_error (yyconst char msg[] );
4329
/* Done after the current pattern has been matched and before the
4330
* corresponding action - sets up Gmltext.
4332
#define YY_DO_BEFORE_ACTION \
4333
(yytext_ptr) = yy_bp; \
4334
Gmlleng = (size_t) (yy_cp - yy_bp); \
4335
(yy_hold_char) = *yy_cp; \
4337
if ( Gmlleng + (yy_more_offset) >= YYLMAX ) \
4338
YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \
4339
yy_flex_strncpy( &Gmltext[(yy_more_offset)], (yytext_ptr), Gmlleng + 1 ); \
4340
Gmlleng += (yy_more_offset); \
4341
(yy_prev_more_offset) = (yy_more_offset); \
4342
(yy_more_offset) = 0; \
4343
(yy_c_buf_p) = yy_cp;
4345
#define YY_NUM_RULES 11
4346
#define YY_END_OF_BUFFER 12
4347
/* This struct is not used in this scanner,
4348
but its presence is necessary. */
4349
struct yy_trans_info
4351
flex_int32_t yy_verify;
4352
flex_int32_t yy_nxt;
4354
static yyconst flex_int16_t yy_acclist[34] =
4356
5, 5, 12, 10, 11, 8, 10, 11, 9, 11,
4357
10, 11, 5, 10, 11, 1, 10, 11, 3, 10,
4358
11, 2, 10, 11, 4, 10, 11, 7, 10, 11,
4362
static yyconst flex_int16_t yy_accept[20] =
4364
1, 2, 3, 4, 6, 9, 11, 13, 16, 19,
4365
22, 25, 28, 31, 31, 32, 33, 34, 34
4368
static yyconst flex_int32_t yy_ec[256] =
4370
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
4371
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4372
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4373
1, 2, 1, 4, 1, 1, 1, 1, 1, 1,
4374
1, 1, 5, 5, 5, 5, 6, 7, 7, 7,
4375
7, 7, 7, 7, 7, 7, 7, 8, 1, 9,
4376
10, 11, 1, 1, 12, 12, 12, 12, 12, 12,
4377
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
4378
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
4379
1, 1, 1, 1, 12, 1, 12, 12, 12, 12,
4381
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
4382
12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
4383
12, 12, 1, 1, 1, 1, 1, 1, 1, 1,
4384
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4385
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4386
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4387
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4388
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4389
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4390
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4392
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4393
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4394
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4395
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4396
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4400
static yyconst flex_int32_t yy_meta[13] =
4402
1, 1, 1, 1, 2, 1, 3, 4, 5, 1,
4406
static yyconst flex_int16_t yy_base[22] =
4408
0, 0, 23, 24, 24, 24, 18, 0, 24, 24,
4409
24, 24, 0, 17, 24, 0, 0, 24, 12, 15,
4413
static yyconst flex_int16_t yy_def[22] =
4415
18, 1, 18, 18, 18, 18, 19, 20, 18, 18,
4416
18, 18, 21, 19, 18, 20, 21, 0, 18, 18,
4420
static yyconst flex_int16_t yy_nxt[37] =
4422
4, 5, 6, 7, 8, 9, 8, 4, 10, 11,
4423
12, 13, 14, 14, 14, 14, 16, 16, 17, 17,
4424
15, 15, 18, 3, 18, 18, 18, 18, 18, 18,
4425
18, 18, 18, 18, 18, 18
4428
static yyconst flex_int16_t yy_chk[37] =
4430
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4431
1, 1, 19, 19, 19, 19, 20, 20, 21, 21,
4432
14, 7, 3, 18, 18, 18, 18, 18, 18, 18,
4433
18, 18, 18, 18, 18, 18
4436
/* Table of booleans, true if rule could match eol. */
4437
static yyconst flex_int32_t yy_rule_can_match_eol[12] =
4439
0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, };
4441
extern int Gml_flex_debug;
4442
int Gml_flex_debug = 0;
4444
static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;
4445
static char *yy_full_match;
4449
*yy_cp = (yy_hold_char); /* undo effects of setting up Gmltext */ \
4450
yy_cp = (yy_full_match); /* restore poss. backed-over text */ \
4455
static int yy_more_offset = 0;
4456
static int yy_prev_more_offset = 0;
4457
#define yymore() ((yy_more_offset) = yy_flex_strlen( Gmltext ))
4458
#define YY_NEED_STRLEN
4459
#define YY_MORE_ADJ 0
4460
#define YY_RESTORE_YY_MORE_OFFSET \
4462
(yy_more_offset) = (yy_prev_more_offset); \
4463
Gmlleng -= (yy_more_offset); \
4469
char Gmltext[YYLMAX];
4471
#line 1 "gmlLexer.l"
4473
gmlLexer.l -- GML parser - FLEX config
4475
version 2.4, 2011 June 3
4477
Author: Sandro Furieri a.furieri@lqt.it
4479
------------------------------------------------------------------------------
4481
Version: MPL 1.1/GPL 2.0/LGPL 2.1
4483
The contents of this file are subject to the Mozilla Public License Version
4484
1.1 (the "License"); you may not use this file except in compliance with
4485
the License. You may obtain a copy of the License at
4486
http://www.mozilla.org/MPL/
4488
Software distributed under the License is distributed on an "AS IS" basis,
4489
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
4490
for the specific language governing rights and limitations under the
4493
The Original Code is the SpatiaLite library
4495
The Initial Developer of the Original Code is Alessandro Furieri
4497
Portions created by the Initial Developer are Copyright (C) 2011
4498
the Initial Developer. All Rights Reserved.
4500
Alternatively, the contents of this file may be used under the terms of
4501
either the GNU General Public License Version 2 or later (the "GPL"), or
4502
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
4503
in which case the provisions of the GPL or the LGPL are applicable instead
4504
of those above. If you wish to allow use of your version of this file only
4505
under the terms of either the GPL or the LGPL, and not to allow others to
4506
use your version of this file under the terms of the MPL, indicate your
4507
decision by deleting the provisions above and replace them with the notice
4508
and other provisions required by the GPL or the LGPL. If you do not delete
4509
the provisions above, a recipient may use your version of this file under
4510
the terms of any one of the MPL, the GPL or the LGPL.
4513
#line 46 "gmlLexer.l"
4515
/* For debugging purposes */
4516
int gml_line = 1, gml_col = 1;
4519
* The main string-token matcher.
4520
* The lower case part is probably not needed. We should really be converting
4521
* The string to all uppercase/lowercase to make it case iNsEnSiTiVe.
4522
* What Flex will do is, For the input string, beginning from the front, Flex
4523
* will try to match with any of the defined tokens from below. Flex will
4524
* then match the string of longest length. Suppose the string is: POINTM,
4525
* Flex would match both POINT and POINTM, but since POINTM is the longer
4526
* of the two tokens, FLEX will match POINTM.
4528
#line 593 "lex.Gml.c"
4532
#ifndef YY_NO_UNISTD_H
4533
/* Special case for "unistd.h", since it is non-ANSI. We include it way
4534
* down here because we want the user's section 1 to have been scanned first.
4535
* The user has a chance to override it with an option.
4540
#ifndef YY_EXTRA_TYPE
4541
#define YY_EXTRA_TYPE void *
4544
static int yy_init_globals (void );
4546
/* Accessor methods to globals.
4547
These are made visible to non-reentrant scanners for convenience. */
4549
int Gmllex_destroy (void );
4551
int Gmlget_debug (void );
4553
void Gmlset_debug (int debug_flag );
4555
YY_EXTRA_TYPE Gmlget_extra (void );
4557
void Gmlset_extra (YY_EXTRA_TYPE user_defined );
4559
FILE *Gmlget_in (void );
4561
void Gmlset_in (FILE * in_str );
4563
FILE *Gmlget_out (void );
4565
void Gmlset_out (FILE * out_str );
4567
int Gmlget_leng (void );
4569
char *Gmlget_text (void );
4571
int Gmlget_lineno (void );
4573
void Gmlset_lineno (int line_number );
4575
/* Macros after this point can all be overridden by user definitions in
4579
#ifndef YY_SKIP_YYWRAP
4581
extern "C" int Gmlwrap (void );
4583
extern int Gmlwrap (void );
4587
static void yyunput (int c,char *buf_ptr );
4590
static void yy_flex_strncpy (char *,yyconst char *,int );
4593
#ifdef YY_NEED_STRLEN
4594
static int yy_flex_strlen (yyconst char * );
4600
static int yyinput (void );
4602
static int input (void );
4607
/* Amount of stuff to slurp up with each read. */
4608
#ifndef YY_READ_BUF_SIZE
4610
/* On IA-64, the buffer size is 16k, not 8k */
4611
#define YY_READ_BUF_SIZE 16384
4613
#define YY_READ_BUF_SIZE 8192
4614
#endif /* __ia64__ */
4617
/* Copy whatever the last rule matched to the standard output. */
4619
/* This used to be an fputs(), but since the string might contain NUL's,
4620
* we now use fwrite().
4622
#define ECHO do { if (fwrite( Gmltext, Gmlleng, 1, Gmlout )) {} } while (0)
4625
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
4626
* is returned in "result".
4629
#define YY_INPUT(buf,result,max_size) \
4630
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
4634
for ( n = 0; n < max_size && \
4635
(c = getc( Gmlin )) != EOF && c != '\n'; ++n ) \
4636
buf[n] = (char) c; \
4638
buf[n++] = (char) c; \
4639
if ( c == EOF && ferror( Gmlin ) ) \
4640
YY_FATAL_ERROR( "input in flex scanner failed" ); \
4646
while ( (result = fread(buf, 1, max_size, Gmlin))==0 && ferror(Gmlin)) \
4648
if( errno != EINTR) \
4650
YY_FATAL_ERROR( "input in flex scanner failed" ); \
4661
/* No semi-colon after return; correct usage is to write "yyterminate();" -
4662
* we don't want an extra ';' after the "return" because that will cause
4663
* some compilers to complain about unreachable statements.
4666
#define yyterminate() return YY_NULL
4669
/* Number of entries by which start-condition stack grows. */
4670
#ifndef YY_START_STACK_INCR
4671
#define YY_START_STACK_INCR 25
4674
/* Report a fatal error. */
4675
#ifndef YY_FATAL_ERROR
4676
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
4679
/* end tables serialization structures and prototypes */
4681
/* Default declaration of generated scanner - a define so the user can
4682
* easily add parameters.
4685
#define YY_DECL_IS_OURS 1
4687
extern int Gmllex (void);
4689
#define YY_DECL int Gmllex (void)
4690
#endif /* !YY_DECL */
4692
/* Code executed at the beginning of each rule, after Gmltext and Gmlleng
4695
#ifndef YY_USER_ACTION
4696
#define YY_USER_ACTION
4699
/* Code executed at the end of each rule. */
4701
#define YY_BREAK break;
4704
#define YY_RULE_SETUP \
4707
/** The main scanner function which does all the work.
4711
register yy_state_type yy_current_state;
4712
register char *yy_cp, *yy_bp;
4713
register int yy_act;
4715
#line 62 "gmlLexer.l"
4717
#line 782 "lex.Gml.c"
4727
/* Create the reject buffer large enough to save one state per allowed character. */
4728
if ( ! (yy_state_buf) )
4729
(yy_state_buf) = (yy_state_type *)Gmlalloc(YY_STATE_BUF_SIZE );
4730
if ( ! (yy_state_buf) )
4731
YY_FATAL_ERROR( "out of dynamic memory in Gmllex()" );
4734
(yy_start) = 1; /* first start state */
4742
if ( ! YY_CURRENT_BUFFER ) {
4743
Gmlensure_buffer_stack ();
4744
YY_CURRENT_BUFFER_LVALUE =
4745
Gml_create_buffer(Gmlin,YY_BUF_SIZE );
4748
Gml_load_buffer_state( );
4751
while ( 1 ) /* loops until end-of-file is reached */
4753
yy_cp = (yy_c_buf_p);
4755
/* Support of Gmltext. */
4756
*yy_cp = (yy_hold_char);
4758
/* yy_bp points to the position in yy_ch_buf of the start of
4763
yy_current_state = (yy_start);
4765
(yy_state_ptr) = (yy_state_buf);
4766
*(yy_state_ptr)++ = yy_current_state;
4771
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
4772
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
4774
yy_current_state = (int) yy_def[yy_current_state];
4775
if ( yy_current_state >= 19 )
4776
yy_c = yy_meta[(unsigned int) yy_c];
4778
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
4779
*(yy_state_ptr)++ = yy_current_state;
4782
while ( yy_base[yy_current_state] != 24 );
4785
yy_current_state = *--(yy_state_ptr);
4786
(yy_lp) = yy_accept[yy_current_state];
4787
find_rule: /* we branch to this label when backing up */
4788
for ( ; ; ) /* until we find what rule we matched */
4790
if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] )
4792
yy_act = yy_acclist[(yy_lp)];
4794
(yy_full_match) = yy_cp;
4799
yy_current_state = *--(yy_state_ptr);
4800
(yy_lp) = yy_accept[yy_current_state];
4803
YY_DO_BEFORE_ACTION;
4805
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
4808
for ( yyl = (yy_prev_more_offset); yyl < Gmlleng; ++yyl )
4809
if ( Gmltext[yyl] == '\n' )
4815
do_action: /* This label is used only to access EOF actions. */
4818
{ /* beginning of action switch */
4821
#line 63 "gmlLexer.l"
4822
{ gml_freeString(&(GmlLval.pval)); return GML_END; }
4826
#line 64 "gmlLexer.l"
4827
{ gml_freeString(&(GmlLval.pval)); return GML_EQ; }
4831
#line 65 "gmlLexer.l"
4832
{ gml_freeString(&(GmlLval.pval)); return GML_OPEN; }
4836
#line 66 "gmlLexer.l"
4837
{ gml_freeString(&(GmlLval.pval)); return GML_CLOSE; }
4841
#line 67 "gmlLexer.l"
4842
{ gml_saveString(&(GmlLval.pval), Gmltext); return GML_COORD; }
4845
/* rule 6 can match eol */
4847
#line 68 "gmlLexer.l"
4848
{ gml_saveString(&(GmlLval.pval), Gmltext); return GML_VALUE; }
4852
#line 69 "gmlLexer.l"
4853
{ gml_saveString(&(GmlLval.pval), Gmltext); return GML_KEYWORD; }
4857
#line 71 "gmlLexer.l"
4858
{ gml_freeString(&(GmlLval.pval)); gml_col += (int) strlen(Gmltext); } /* ignore but count white space */
4861
/* rule 9 can match eol */
4863
#line 73 "gmlLexer.l"
4864
{ gml_freeString(&(GmlLval.pval)); gml_col = 0; ++gml_line; }
4868
#line 75 "gmlLexer.l"
4869
{ gml_freeString(&(GmlLval.pval)); gml_col += (int) strlen(Gmltext); return -1; }
4873
#line 76 "gmlLexer.l"
4876
#line 941 "lex.Gml.c"
4877
case YY_STATE_EOF(INITIAL):
4880
case YY_END_OF_BUFFER:
4882
/* Amount of text matched not including the EOB char. */
4883
int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
4885
/* Undo the effects of YY_DO_BEFORE_ACTION. */
4886
*yy_cp = (yy_hold_char);
4887
YY_RESTORE_YY_MORE_OFFSET
4889
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
4891
/* We're scanning a new file or input source. It's
4892
* possible that this happened because the user
4893
* just pointed Gmlin at a new source and called
4894
* Gmllex(). If so, then we have to assure
4895
* consistency between YY_CURRENT_BUFFER and our
4896
* globals. Here is the right place to do so, because
4897
* this is the first action (other than possibly a
4898
* back-up) that will match for the new input source.
4900
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
4901
YY_CURRENT_BUFFER_LVALUE->yy_input_file = Gmlin;
4902
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
4905
/* Note that here we test for yy_c_buf_p "<=" to the position
4906
* of the first EOB in the buffer, since yy_c_buf_p will
4907
* already have been incremented past the NUL character
4908
* (since all states make transitions on EOB to the
4909
* end-of-buffer state). Contrast this with the test
4912
if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
4913
{ /* This was really a NUL. */
4914
yy_state_type yy_next_state;
4916
(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
4918
yy_current_state = yy_get_previous_state( );
4920
/* Okay, we're now positioned to make the NUL
4921
* transition. We couldn't have
4922
* yy_get_previous_state() go ahead and do it
4923
* for us because it doesn't know how to deal
4924
* with the possibility of jamming (and we don't
4925
* want to build jamming into it because then it
4926
* will run more slowly).
4929
yy_next_state = yy_try_NUL_trans( yy_current_state );
4931
yy_bp = (yytext_ptr) + YY_MORE_ADJ;
4933
if ( yy_next_state )
4935
/* Consume the NUL. */
4936
yy_cp = ++(yy_c_buf_p);
4937
yy_current_state = yy_next_state;
4943
yy_cp = (yy_c_buf_p);
4944
goto yy_find_action;
4948
else switch ( yy_get_next_buffer( ) )
4950
case EOB_ACT_END_OF_FILE:
4952
(yy_did_buffer_switch_on_eof) = 0;
4956
/* Note: because we've taken care in
4957
* yy_get_next_buffer() to have set up
4958
* Gmltext, we can now set up
4959
* yy_c_buf_p so that if some total
4960
* hoser (like flex itself) wants to
4961
* call the scanner after we return the
4962
* YY_NULL, it'll still work - another
4963
* YY_NULL will get returned.
4965
(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
4967
yy_act = YY_STATE_EOF(YY_START);
4973
if ( ! (yy_did_buffer_switch_on_eof) )
4979
case EOB_ACT_CONTINUE_SCAN:
4981
(yytext_ptr) + yy_amount_of_matched_text;
4983
yy_current_state = yy_get_previous_state( );
4985
yy_cp = (yy_c_buf_p);
4986
yy_bp = (yytext_ptr) + YY_MORE_ADJ;
4989
case EOB_ACT_LAST_MATCH:
4991
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
4993
yy_current_state = yy_get_previous_state( );
4995
yy_cp = (yy_c_buf_p);
4996
yy_bp = (yytext_ptr) + YY_MORE_ADJ;
4997
goto yy_find_action;
5004
"fatal flex scanner internal error--no action found" );
5005
} /* end of action switch */
5006
} /* end of scanning one token */
5007
} /* end of Gmllex */
5009
/* yy_get_next_buffer - try to read in a new buffer
5011
* Returns a code representing an action:
5012
* EOB_ACT_LAST_MATCH -
5013
* EOB_ACT_CONTINUE_SCAN - continue scanning from current position
5014
* EOB_ACT_END_OF_FILE - end of file
5016
static int yy_get_next_buffer (void)
5018
register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
5019
register char *source = (yytext_ptr);
5020
register int number_to_move, i;
5023
if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
5025
"fatal flex scanner internal error--end of buffer missed" );
5027
if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
5028
{ /* Don't try to fill the buffer, so this is an EOF. */
5029
if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
5031
/* We matched a single character, the EOB, so
5032
* treat this as a final EOF.
5034
return EOB_ACT_END_OF_FILE;
5039
/* We matched some text prior to the EOB, first
5042
return EOB_ACT_LAST_MATCH;
5046
/* Try to read more data. */
5048
/* First move last chars to start of buffer. */
5049
number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
5051
for ( i = 0; i < number_to_move; ++i )
5052
*(dest++) = *(source++);
5054
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
5055
/* don't do the read, it's not guaranteed to return an EOF,
5058
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
5063
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
5065
while ( num_to_read <= 0 )
5066
{ /* Not enough room in the buffer - grow it. */
5069
"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
5073
if ( num_to_read > YY_READ_BUF_SIZE )
5074
num_to_read = YY_READ_BUF_SIZE;
5076
/* Read in more data. */
5077
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
5078
(yy_n_chars), (size_t) num_to_read );
5080
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
5083
if ( (yy_n_chars) == 0 )
5085
if ( number_to_move == YY_MORE_ADJ )
5087
ret_val = EOB_ACT_END_OF_FILE;
5093
ret_val = EOB_ACT_LAST_MATCH;
5094
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
5095
YY_BUFFER_EOF_PENDING;
5100
ret_val = EOB_ACT_CONTINUE_SCAN;
5102
if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
5103
/* Extend the array by 50%, plus the number we really need. */
5104
yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
5105
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) Gmlrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
5106
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
5107
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
5110
(yy_n_chars) += number_to_move;
5111
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
5112
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
5114
(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
5119
/* yy_get_previous_state - get the state just before the EOB char was reached */
5121
static yy_state_type yy_get_previous_state (void)
5123
register yy_state_type yy_current_state;
5124
register char *yy_cp;
5126
yy_current_state = (yy_start);
5128
(yy_state_ptr) = (yy_state_buf);
5129
*(yy_state_ptr)++ = yy_current_state;
5131
for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
5133
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
5134
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
5136
yy_current_state = (int) yy_def[yy_current_state];
5137
if ( yy_current_state >= 19 )
5138
yy_c = yy_meta[(unsigned int) yy_c];
5140
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
5141
*(yy_state_ptr)++ = yy_current_state;
5144
return yy_current_state;
5147
/* yy_try_NUL_trans - try to make a transition on the NUL character
5150
* next_state = yy_try_NUL_trans( current_state );
5152
static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
5154
register int yy_is_jam;
5156
register YY_CHAR yy_c = 1;
5157
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
5159
yy_current_state = (int) yy_def[yy_current_state];
5160
if ( yy_current_state >= 19 )
5161
yy_c = yy_meta[(unsigned int) yy_c];
5163
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
5164
yy_is_jam = (yy_current_state == 18);
5166
*(yy_state_ptr)++ = yy_current_state;
5168
return yy_is_jam ? 0 : yy_current_state;
5171
static void yyunput (int c, register char * yy_bp )
5173
register char *yy_cp;
5175
yy_cp = (yy_c_buf_p);
5177
/* undo effects of setting up Gmltext */
5178
*yy_cp = (yy_hold_char);
5180
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
5181
{ /* need to shift things up to make room */
5182
/* +2 for EOB chars. */
5183
register int number_to_move = (yy_n_chars) + 2;
5184
register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
5185
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
5186
register char *source =
5187
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
5189
while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
5190
*--dest = *--source;
5192
yy_cp += (int) (dest - source);
5193
yy_bp += (int) (dest - source);
5194
YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
5195
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
5197
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
5198
YY_FATAL_ERROR( "flex scanner push-back overflow" );
5201
*--yy_cp = (char) c;
5207
(yytext_ptr) = yy_bp;
5208
(yy_hold_char) = *yy_cp;
5209
(yy_c_buf_p) = yy_cp;
5214
static int yyinput (void)
5216
static int input (void)
5222
*(yy_c_buf_p) = (yy_hold_char);
5224
if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
5226
/* yy_c_buf_p now points to the character we want to return.
5227
* If this occurs *before* the EOB characters, then it's a
5228
* valid NUL; if not, then we've hit the end of the buffer.
5230
if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
5231
/* This was really a NUL. */
5232
*(yy_c_buf_p) = '\0';
5235
{ /* need more input */
5236
int offset = (yy_c_buf_p) - (yytext_ptr);
5239
switch ( yy_get_next_buffer( ) )
5241
case EOB_ACT_LAST_MATCH:
5242
/* This happens because yy_g_n_b()
5243
* sees that we've accumulated a
5244
* token and flags that we need to
5245
* try matching the token before
5246
* proceeding. But for input(),
5247
* there's no matching to consider.
5248
* So convert the EOB_ACT_LAST_MATCH
5249
* to EOB_ACT_END_OF_FILE.
5252
/* Reset buffer status. */
5257
case EOB_ACT_END_OF_FILE:
5262
if ( ! (yy_did_buffer_switch_on_eof) )
5271
case EOB_ACT_CONTINUE_SCAN:
5272
(yy_c_buf_p) = (yytext_ptr) + offset;
5278
c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
5279
*(yy_c_buf_p) = '\0'; /* preserve Gmltext */
5280
(yy_hold_char) = *++(yy_c_buf_p);
5289
#endif /* ifndef YY_NO_INPUT */
5291
/** Immediately switch to a different input stream.
5292
* @param input_file A readable stream.
5294
* @note This function does not reset the start condition to @c INITIAL .
5296
void Gmlrestart (FILE * input_file )
5299
if ( ! YY_CURRENT_BUFFER ){
5300
Gmlensure_buffer_stack ();
5301
YY_CURRENT_BUFFER_LVALUE =
5302
Gml_create_buffer(Gmlin,YY_BUF_SIZE );
5305
Gml_init_buffer(YY_CURRENT_BUFFER,input_file );
5306
Gml_load_buffer_state( );
5309
/** Switch to a different input buffer.
5310
* @param new_buffer The new input buffer.
5313
void Gml_switch_to_buffer (YY_BUFFER_STATE new_buffer )
5316
/* TODO. We should be able to replace this entire function body
5318
* Gmlpop_buffer_state();
5319
* Gmlpush_buffer_state(new_buffer);
5321
Gmlensure_buffer_stack ();
5322
if ( YY_CURRENT_BUFFER == new_buffer )
5325
if ( YY_CURRENT_BUFFER )
5327
/* Flush out information for old buffer. */
5328
*(yy_c_buf_p) = (yy_hold_char);
5329
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
5330
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
5333
YY_CURRENT_BUFFER_LVALUE = new_buffer;
5334
Gml_load_buffer_state( );
5336
/* We don't actually know whether we did this switch during
5337
* EOF (Gmlwrap()) processing, but the only time this flag
5338
* is looked at is after Gmlwrap() is called, so it's safe
5339
* to go ahead and always set it.
5341
(yy_did_buffer_switch_on_eof) = 1;
5344
static void Gml_load_buffer_state (void)
5346
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
5347
(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
5348
Gmlin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
5349
(yy_hold_char) = *(yy_c_buf_p);
5352
/** Allocate and initialize an input buffer state.
5353
* @param file A readable stream.
5354
* @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
5356
* @return the allocated buffer state.
5358
YY_BUFFER_STATE Gml_create_buffer (FILE * file, int size )
5362
b = (YY_BUFFER_STATE) Gmlalloc(sizeof( struct yy_buffer_state ) );
5364
YY_FATAL_ERROR( "out of dynamic memory in Gml_create_buffer()" );
5366
b->yy_buf_size = size;
5368
/* yy_ch_buf has to be 2 characters longer than the size given because
5369
* we need to put in 2 end-of-buffer characters.
5371
b->yy_ch_buf = (char *) Gmlalloc(b->yy_buf_size + 2 );
5372
if ( ! b->yy_ch_buf )
5373
YY_FATAL_ERROR( "out of dynamic memory in Gml_create_buffer()" );
5375
b->yy_is_our_buffer = 1;
5377
Gml_init_buffer(b,file );
5382
/** Destroy the buffer.
5383
* @param b a buffer created with Gml_create_buffer()
5386
void Gml_delete_buffer (YY_BUFFER_STATE b )
5392
if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
5393
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
5395
if ( b->yy_is_our_buffer )
5396
Gmlfree((void *) b->yy_ch_buf );
5398
Gmlfree((void *) b );
5402
extern int isatty (int );
5403
#endif /* __cplusplus */
5405
/* Initializes or reinitializes a buffer.
5406
* This function is sometimes called more than once on the same buffer,
5407
* such as during a Gmlrestart() or at EOF.
5409
static void Gml_init_buffer (YY_BUFFER_STATE b, FILE * file )
5414
Gml_flush_buffer(b );
5416
b->yy_input_file = file;
5417
b->yy_fill_buffer = 1;
5419
/* If b is the current buffer, then Gml_init_buffer was _probably_
5420
* called from Gmlrestart() or through yy_get_next_buffer.
5421
* In that case, we don't want to reset the lineno or column.
5423
if (b != YY_CURRENT_BUFFER){
5424
b->yy_bs_lineno = 1;
5425
b->yy_bs_column = 0;
5428
b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
5433
/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
5434
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
5437
void Gml_flush_buffer (YY_BUFFER_STATE b )
5444
/* We always need two end-of-buffer characters. The first causes
5445
* a transition to the end-of-buffer state. The second causes
5446
* a jam in that state.
5448
b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
5449
b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
5451
b->yy_buf_pos = &b->yy_ch_buf[0];
5454
b->yy_buffer_status = YY_BUFFER_NEW;
5456
if ( b == YY_CURRENT_BUFFER )
5457
Gml_load_buffer_state( );
5460
/** Pushes the new state onto the stack. The new state becomes
5461
* the current state. This function will allocate the stack
5463
* @param new_buffer The new state.
5466
void Gmlpush_buffer_state (YY_BUFFER_STATE new_buffer )
5468
if (new_buffer == NULL)
5471
Gmlensure_buffer_stack();
5473
/* This block is copied from Gml_switch_to_buffer. */
5474
if ( YY_CURRENT_BUFFER )
5476
/* Flush out information for old buffer. */
5477
*(yy_c_buf_p) = (yy_hold_char);
5478
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
5479
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
5482
/* Only push if top exists. Otherwise, replace top. */
5483
if (YY_CURRENT_BUFFER)
5484
(yy_buffer_stack_top)++;
5485
YY_CURRENT_BUFFER_LVALUE = new_buffer;
5487
/* copied from Gml_switch_to_buffer. */
5488
Gml_load_buffer_state( );
5489
(yy_did_buffer_switch_on_eof) = 1;
5492
/** Removes and deletes the top of the stack, if present.
5493
* The next element becomes the new top.
5496
void Gmlpop_buffer_state (void)
5498
if (!YY_CURRENT_BUFFER)
5501
Gml_delete_buffer(YY_CURRENT_BUFFER );
5502
YY_CURRENT_BUFFER_LVALUE = NULL;
5503
if ((yy_buffer_stack_top) > 0)
5504
--(yy_buffer_stack_top);
5506
if (YY_CURRENT_BUFFER) {
5507
Gml_load_buffer_state( );
5508
(yy_did_buffer_switch_on_eof) = 1;
5512
/* Allocates the stack if it does not exist.
5513
* Guarantees space for at least one push.
5515
static void Gmlensure_buffer_stack (void)
5519
if (!(yy_buffer_stack)) {
5521
/* First allocation is just for 2 elements, since we don't know if this
5522
* scanner will even need a stack. We use 2 instead of 1 to avoid an
5523
* immediate realloc on the next call.
5526
(yy_buffer_stack) = (struct yy_buffer_state**)Gmlalloc
5527
(num_to_alloc * sizeof(struct yy_buffer_state*)
5529
if ( ! (yy_buffer_stack) )
5530
YY_FATAL_ERROR( "out of dynamic memory in Gmlensure_buffer_stack()" );
5532
memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
5534
(yy_buffer_stack_max) = num_to_alloc;
5535
(yy_buffer_stack_top) = 0;
5539
if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
5541
/* Increase the buffer to prepare for a possible push. */
5542
int grow_size = 8 /* arbitrary grow size */;
5544
num_to_alloc = (yy_buffer_stack_max) + grow_size;
5545
(yy_buffer_stack) = (struct yy_buffer_state**)Gmlrealloc
5547
num_to_alloc * sizeof(struct yy_buffer_state*)
5549
if ( ! (yy_buffer_stack) )
5550
YY_FATAL_ERROR( "out of dynamic memory in Gmlensure_buffer_stack()" );
5552
/* zero only the new slots.*/
5553
memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
5554
(yy_buffer_stack_max) = num_to_alloc;
5558
/** Setup the input buffer state to scan directly from a user-specified character buffer.
5559
* @param base the character buffer
5560
* @param size the size in bytes of the character buffer
5562
* @return the newly allocated buffer state object.
5564
YY_BUFFER_STATE Gml_scan_buffer (char * base, yy_size_t size )
5569
base[size-2] != YY_END_OF_BUFFER_CHAR ||
5570
base[size-1] != YY_END_OF_BUFFER_CHAR )
5571
/* They forgot to leave room for the EOB's. */
5574
b = (YY_BUFFER_STATE) Gmlalloc(sizeof( struct yy_buffer_state ) );
5576
YY_FATAL_ERROR( "out of dynamic memory in Gml_scan_buffer()" );
5578
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
5579
b->yy_buf_pos = b->yy_ch_buf = base;
5580
b->yy_is_our_buffer = 0;
5581
b->yy_input_file = 0;
5582
b->yy_n_chars = b->yy_buf_size;
5583
b->yy_is_interactive = 0;
5585
b->yy_fill_buffer = 0;
5586
b->yy_buffer_status = YY_BUFFER_NEW;
5588
Gml_switch_to_buffer(b );
5593
/** Setup the input buffer state to scan a string. The next call to Gmllex() will
5594
* scan from a @e copy of @a str.
5595
* @param yystr a NUL-terminated string to scan
5597
* @return the newly allocated buffer state object.
5598
* @note If you want to scan bytes that may contain NUL values, then use
5599
* Gml_scan_bytes() instead.
5601
YY_BUFFER_STATE Gml_scan_string (yyconst char * yystr )
5604
return Gml_scan_bytes(yystr,strlen(yystr) );
5607
/** Setup the input buffer state to scan the given bytes. The next call to Gmllex() will
5608
* scan from a @e copy of @a bytes.
5609
* @param yybytes the byte buffer to scan
5610
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
5612
* @return the newly allocated buffer state object.
5614
YY_BUFFER_STATE Gml_scan_bytes (yyconst char * yybytes, int _yybytes_len )
5621
/* Get memory for full buffer, including space for trailing EOB's. */
5622
n = _yybytes_len + 2;
5623
buf = (char *) Gmlalloc(n );
5625
YY_FATAL_ERROR( "out of dynamic memory in Gml_scan_bytes()" );
5627
for ( i = 0; i < _yybytes_len; ++i )
5628
buf[i] = yybytes[i];
5630
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
5632
b = Gml_scan_buffer(buf,n );
5634
YY_FATAL_ERROR( "bad buffer in Gml_scan_bytes()" );
5636
/* It's okay to grow etc. this buffer, and we should throw it
5637
* away when we're done.
5639
b->yy_is_our_buffer = 1;
5644
#ifndef YY_EXIT_FAILURE
5645
#define YY_EXIT_FAILURE 2
5648
static void yy_fatal_error (yyconst char* msg )
5650
(void) fprintf( stderr, "%s\n", msg );
5651
exit( YY_EXIT_FAILURE );
5654
/* Redefine yyless() so it works in section 3 code. */
5660
/* Undo effects of setting up Gmltext. */ \
5661
int yyless_macro_arg = (n); \
5662
YY_LESS_LINENO(yyless_macro_arg);\
5663
Gmltext[Gmlleng] = (yy_hold_char); \
5664
(yy_c_buf_p) = Gmltext + yyless_macro_arg; \
5665
(yy_hold_char) = *(yy_c_buf_p); \
5666
*(yy_c_buf_p) = '\0'; \
5667
Gmlleng = yyless_macro_arg; \
5671
/* Accessor methods (get/set functions) to struct members. */
5673
/** Get the current line number.
5676
int Gmlget_lineno (void)
5682
/** Get the input stream.
5685
FILE *Gmlget_in (void)
5690
/** Get the output stream.
5693
FILE *Gmlget_out (void)
5698
/** Get the length of the current token.
5701
int Gmlget_leng (void)
5706
/** Get the current token.
5710
char *Gmlget_text (void)
5715
/** Set the current line number.
5716
* @param line_number
5719
void Gmlset_lineno (int line_number )
5722
Gmllineno = line_number;
5725
/** Set the input stream. This does not discard the current
5727
* @param in_str A readable stream.
5729
* @see Gml_switch_to_buffer
5731
void Gmlset_in (FILE * in_str )
5736
void Gmlset_out (FILE * out_str )
5741
int Gmlget_debug (void)
5743
return Gml_flex_debug;
5746
void Gmlset_debug (int bdebug )
5748
Gml_flex_debug = bdebug ;
5751
static int yy_init_globals (void)
5753
/* Initialization is the same as for the non-reentrant scanner.
5754
* This function is called from Gmllex_destroy(), so don't allocate here.
5757
/* We do not touch Gmllineno unless the option is enabled. */
5760
(yy_buffer_stack) = 0;
5761
(yy_buffer_stack_top) = 0;
5762
(yy_buffer_stack_max) = 0;
5763
(yy_c_buf_p) = (char *) 0;
5769
(yy_full_match) = 0;
5772
/* Defined in main.c */
5778
Gmlout = (FILE *) 0;
5781
/* For future reference: Set errno on error, since we are called by
5787
/* Gmllex_destroy is for both reentrant and non-reentrant scanners. */
5788
int Gmllex_destroy (void)
5791
/* Pop the buffer stack, destroying each element. */
5792
while(YY_CURRENT_BUFFER){
5793
Gml_delete_buffer(YY_CURRENT_BUFFER );
5794
YY_CURRENT_BUFFER_LVALUE = NULL;
5795
Gmlpop_buffer_state();
5798
/* Destroy the stack itself. */
5799
Gmlfree((yy_buffer_stack) );
5800
(yy_buffer_stack) = NULL;
5802
Gmlfree ( (yy_state_buf) );
5803
(yy_state_buf) = NULL;
5805
/* Reset the globals. This is important in a non-reentrant scanner so the next time
5806
* Gmllex() is called, initialization will occur. */
5813
* Internal utility routines.
5817
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
5820
for ( i = 0; i < n; ++i )
5825
#ifdef YY_NEED_STRLEN
5826
static int yy_flex_strlen (yyconst char * s )
5829
for ( n = 0; s[n]; ++n )
5836
void *Gmlalloc (yy_size_t size )
5838
return (void *) malloc( size );
5841
void *Gmlrealloc (void * ptr, yy_size_t size )
5843
/* The cast to (char *) in the following accommodates both
5844
* implementations that use char* generic pointers, and those
5845
* that use void* generic pointers. It works with the latter
5846
* because both ANSI C and C++ allow castless assignment from
5847
* any pointer type to void*, and deal with argument conversions
5848
* as though doing an assignment.
5850
return (void *) realloc( (char *) ptr, size );
5853
void Gmlfree (void * ptr )
5855
free( (char *) ptr ); /* see Gmlrealloc() for (char *) cast */
5858
#define YYTABLES_NAME "yytables"
5860
#line 76 "gmlLexer.l"
5864
* reset the line and column count
5868
void gml_reset_lexer(void)
5877
* gmlError() is invoked when the lexer or the parser encounter
5878
* an error. The error message is passed via *s
5882
void GmlError(char *s)
5884
printf("error: %s at line: %d col: %d\n",s,gml_line,gml_col);
5895
GML_FLEX_END - FLEX generated code ends here
5901
gaiaParseGml (const unsigned char *dirty_buffer, sqlite3 * sqlite_handle)
5903
void *pParser = ParseAlloc (malloc);
5904
/* Linked-list of token values */
5905
gmlFlexToken *tokens = malloc (sizeof (gmlFlexToken));
5906
/* Pointer to the head of the list */
5907
gmlFlexToken *head = tokens;
5909
gmlNodePtr result = NULL;
5910
gaiaGeomCollPtr geom = NULL;
5912
GmlLval.pval = NULL;
5913
tokens->value = NULL;
5914
tokens->Next = NULL;
5915
gml_parse_error = 0;
5916
Gml_scan_string ((char *) dirty_buffer);
5919
/ Keep tokenizing until we reach the end
5920
/ yylex() will return the next matching Token for us.
5922
while ((yv = yylex ()) != 0)
5926
gml_parse_error = 1;
5929
tokens->Next = malloc (sizeof (gmlFlexToken));
5930
tokens->Next->Next = NULL;
5932
/GmlLval is a global variable from FLEX.
5933
/GmlLval is defined in gmlLexglobal.h
5935
gml_xferString (&(tokens->Next->value), GmlLval.pval);
5936
/* Pass the token to the wkt parser created from lemon */
5937
Parse (pParser, yv, &(tokens->Next->value), &result);
5938
tokens = tokens->Next;
5940
/* This denotes the end of a line as well as the end of the parser */
5941
Parse (pParser, GML_NEWLINE, 0, &result);
5942
ParseFree (pParser, free);
5945
/* Assigning the token as the end to avoid seg faults while cleaning */
5946
tokens->Next = NULL;
5948
gml_freeString (&(GmlLval.pval));
5950
if (gml_parse_error)
5953
gml_freeTree (result);
5957
/* attempting to build a geometry from GML */
5958
geom = gml_build_geometry (result, sqlite_handle);
5959
gml_freeTree (result);
5965
** CAVEAT: we must now undefine any Lemon/Flex own macro
5971
#undef YY_SHIFT_USE_DFLT
5972
#undef YY_REDUCE_USE_DFLT
5973
#undef YY_REDUCE_MAX
5974
#undef YY_FLUSH_BUFFER
5975
#undef YY_DO_BEFORE_ACTION
5977
#undef YY_END_OF_BUFFER
5984
#undef YY_CURRENT_BUFFER
5985
#undef YY_CURRENT_BUFFER_LVALUE
5986
#undef YY_STATE_BUF_SIZE
5988
#undef YY_FATAL_ERROR
5995
#undef ParseStackPeak
6014
#undef yy_buffer_stack
6015
#undef yy_buffer_stack_max
6016
#undef yy_buffer_stack_top
6019
#undef yy_create_buffer
6022
#undef yy_delete_buffer
6023
#undef yy_destructor
6025
#undef yy_fatal_error
6026
#undef yy_find_reduce_action
6027
#undef yy_find_shift_action
6028
#undef yy_flex_debug
6029
#undef yy_flush_buffer
6030
#undef yy_get_next_buffer
6031
#undef yy_get_previous_state
6033
#undef yy_init_buffer
6034
#undef yy_init_globals
6035
#undef yy_load_buffer
6036
#undef yy_load_buffer_state
6039
#undef yy_new_buffer
6041
#undef yy_parse_failed
6042
#undef yy_pop_parser_stack
6044
#undef yy_reduce_ofst
6046
#undef yy_set_interactive
6048
#undef yy_shift_ofst
6050
#undef yy_state_type
6051
#undef yy_switch_to_buffer
6052
#undef yy_syntax_error
6053
#undef yy_trans_info
6054
#undef yy_try_NUL_trans
6057
#undef yyStackOverflow
6062
#undef ParseARG_SDECL
6063
#undef ParseARG_PDECL
6064
#undef ParseARG_FETCH
6065
#undef ParseARG_STORE
6069
#undef YY_RESTORE_YY_MORE_OFFSET
6070
#undef YY_LESS_LINENO
6071
#undef yyTracePrompt