Fossil SCM

In Pikchr: Add support for macros. Also if the width or height of an object are zero or less, then autofit the corresponding dimension.

drh 2020-09-28 00:14 trunk
Commit 6dd3a5b75ffd5ba3bf07c88a0efdf68613e0000daff7db72ee2dcae98bb00f38
1 file changed +2633 -2354
+2633 -2354
--- src/pikchr.c
+++ src/pikchr.c
@@ -68,47 +68,47 @@
6868
**
6969
** Each call to pikchr() uses a single instance of the Pik structure to
7070
** track its internal state. The Pik structure lives for the duration
7171
** of the pikchr() call.
7272
**
73
-** The input is a sequence of objects or "elements". Each element is
74
-** parsed into a PElem object. These are stored on an extensible array
75
-** called PEList. All parameters to each PElem are computed as the
76
-** object is parsed. (Hence, the parameters to a PElem may only refer
77
-** to prior elements.) Once the PElem is completely assembled, it is
78
-** added to the end of a PEList and never changes thereafter - except,
79
-** PElem objects that are part of a "[...]" block might have their
73
+** The input is a sequence of objects or "statements". Each statement is
74
+** parsed into a PObj object. These are stored on an extensible array
75
+** called PList. All parameters to each PObj are computed as the
76
+** object is parsed. (Hence, the parameters to a PObj may only refer
77
+** to prior statements.) Once the PObj is completely assembled, it is
78
+** added to the end of a PList and never changes thereafter - except,
79
+** PObj objects that are part of a "[...]" block might have their
8080
** absolute position shifted when the outer [...] block is positioned.
81
-** But apart from this repositioning, PElem objects are unchanged once
82
-** they are added to the list. The order of elements on a PEList does
81
+** But apart from this repositioning, PObj objects are unchanged once
82
+** they are added to the list. The order of statements on a PList does
8383
** not change.
8484
**
85
-** After all input has been parsed, the top-level PEList is walked to
85
+** After all input has been parsed, the top-level PList is walked to
8686
** generate output. Sub-lists resulting from [...] blocks are scanned
8787
** as they are encountered. All input must be collected and parsed ahead
88
-** of output generation because the size and position of elements must be
88
+** of output generation because the size and position of statements must be
8989
** known in order to compute a bounding box on the output.
9090
**
91
-** Each PElem is on a "layer". (The common case is that all PElem's are
91
+** Each PObj is on a "layer". (The common case is that all PObj's are
9292
** on a single layer, but multiple layers are possible.) A separate pass
9393
** is made through the list for each layer.
9494
**
95
-** After all output is generated, the Pik object and all the PEList
96
-** and PElem objects are deallocated and the generated output string is
95
+** After all output is generated, the Pik object and all the PList
96
+** and PObj objects are deallocated and the generated output string is
9797
** returned. Upon any error, the Pik.nErr flag is set, processing quickly
9898
** stops, and the stack unwinds. No attempt is made to continue reading
9999
** input after an error.
100100
**
101
-** Most elements begin with a class name like "box" or "arrow" or "move".
102
-** There is a class named "text" which is used for elements that begin
101
+** Most statements begin with a class name like "box" or "arrow" or "move".
102
+** There is a class named "text" which is used for statements that begin
103103
** with a string literal. You can also specify the "text" class.
104104
** A Sublist ("[...]") is a single object that contains a pointer to
105
-** its subelements, all gathered onto a separate PEList object.
105
+** its substatements, all gathered onto a separate PList object.
106106
**
107107
** Variables go into PVar objects that form a linked list.
108108
**
109
-** Each PElem has zero or one names. Input constructs that attempt
109
+** Each PObj has zero or one names. Input constructs that attempt
110110
** to assign a new name from an older name, for example:
111111
**
112112
** Abc: Abc + (0.5cm, 0)
113113
**
114114
** Statements like these generate a new "noop" object at the specified
@@ -131,18 +131,19 @@
131131
** compiler warnings with -Wextra */
132132
#define UNUSED_PARAMETER(X) (void)(X)
133133
134134
typedef struct Pik Pik; /* Complete parsing context */
135135
typedef struct PToken PToken; /* A single token */
136
-typedef struct PElem PElem; /* A single diagram object or "element" */
137
-typedef struct PEList PEList; /* A list of elements */
138
-typedef struct PClass PClass; /* Description of elements types */
136
+typedef struct PObj PObj; /* A single diagram object */
137
+typedef struct PList PList; /* A list of diagram objects */
138
+typedef struct PClass PClass; /* Description of statements types */
139139
typedef double PNum; /* Numeric value */
140140
typedef struct PRel PRel; /* Absolute or percentage value */
141141
typedef struct PPoint PPoint; /* A position in 2-D space */
142142
typedef struct PVar PVar; /* script-defined variable */
143143
typedef struct PBox PBox; /* A bounding box */
144
+typedef struct PMacro PMacro; /* A "define" macro */
144145
145146
/* Compass points */
146147
#define CP_N 1
147148
#define CP_NE 2
148149
#define CP_E 3
@@ -181,15 +182,15 @@
181182
/* Text position and style flags. Stored in PToken.eCode so limited
182183
** to 15 bits. */
183184
#define TP_LJUST 0x0001 /* left justify...... */
184185
#define TP_RJUST 0x0002 /* ...Right justify */
185186
#define TP_JMASK 0x0003 /* Mask for justification bits */
186
-#define TP_ABOVE2 0x0004 /* Position text way above PElem.ptAt */
187
-#define TP_ABOVE 0x0008 /* Position text above PElem.ptAt */
187
+#define TP_ABOVE2 0x0004 /* Position text way above PObj.ptAt */
188
+#define TP_ABOVE 0x0008 /* Position text above PObj.ptAt */
188189
#define TP_CENTER 0x0010 /* On the line */
189
-#define TP_BELOW 0x0020 /* Position text below PElem.ptAt */
190
-#define TP_BELOW2 0x0040 /* Position text way below PElem.ptAt */
190
+#define TP_BELOW 0x0020 /* Position text below PObj.ptAt */
191
+#define TP_BELOW2 0x0040 /* Position text way below PObj.ptAt */
191192
#define TP_VMASK 0x007c /* Mask for text positioning flags */
192193
#define TP_BIG 0x0100 /* Larger font */
193194
#define TP_SMALL 0x0200 /* Smaller font */
194195
#define TP_XTRA 0x0400 /* Amplify TP_BIG or TP_SMALL */
195196
#define TP_SZMASK 0x0700 /* Font size mask */
@@ -254,10 +255,11 @@
254255
}
255256
256257
/* Extra token types not generated by LEMON but needed by the
257258
** tokenizer
258259
*/
260
+#define T_PARAMETER 253 /* $1, $2, ..., $9 */
259261
#define T_WHITESPACE 254 /* Whitespace of comments */
260262
#define T_ERROR 255 /* Any text that is not a valid token */
261263
262264
/* Directions of movement */
263265
#define DIR_RIGHT 0
@@ -266,12 +268,12 @@
266268
#define DIR_UP 3
267269
#define ValidDir(X) ((X)>=0 && (X)<=3)
268270
#define IsUpDown(X) (((X)&1)==1)
269271
#define IsLeftRight(X) (((X)&1)==0)
270272
271
-/* Bitmask for the various attributes for PElem. These bits are
272
-** collected in PElem.mProp and PElem.mCalc to check for constraint
273
+/* Bitmask for the various attributes for PObj. These bits are
274
+** collected in PObj.mProp and PObj.mCalc to check for constraint
273275
** errors. */
274276
#define A_WIDTH 0x0001
275277
#define A_HEIGHT 0x0002
276278
#define A_RADIUS 0x0004
277279
#define A_THICKNESS 0x0008
@@ -281,20 +283,21 @@
281283
#define A_ARROW 0x0080
282284
#define A_FROM 0x0100
283285
#define A_CW 0x0200
284286
#define A_AT 0x0400
285287
#define A_TO 0x0800 /* one or more movement attributes */
288
+#define A_FIT 0x1000
286289
287290
288
-/* A single element */
289
-struct PElem {
290
- const PClass *type; /* Element type */
291
+/* A single graphics object */
292
+struct PObj {
293
+ const PClass *type; /* Object type or class */
291294
PToken errTok; /* Reference token for error messages */
292295
PPoint ptAt; /* Reference point for the object */
293296
PPoint ptEnter, ptExit; /* Entry and exit points */
294
- PEList *pSublist; /* Substructure for [...] elements */
295
- char *zName; /* Name assigned to this element */
297
+ PList *pSublist; /* Substructure for [...] objects */
298
+ char *zName; /* Name assigned to this statement */
296299
PNum w; /* "width" property */
297300
PNum h; /* "height" property */
298301
PNum rad; /* "radius" property */
299302
PNum sw; /* "thickness" property. (Mnemonic: "stroke width")*/
300303
PNum dotted; /* "dotted" property. <=0.0 for off */
@@ -317,33 +320,41 @@
317320
int nPath; /* Number of path points */
318321
PPoint *aPath; /* Array of path points */
319322
PBox bbox; /* Bounding box */
320323
};
321324
322
-/* A list of elements */
323
-struct PEList {
324
- int n; /* Number of elements in the list */
325
+/* A list of graphics objects */
326
+struct PList {
327
+ int n; /* Number of statements in the list */
325328
int nAlloc; /* Allocated slots in a[] */
326
- PElem **a; /* Pointers to individual elements */
329
+ PObj **a; /* Pointers to individual objects */
330
+};
331
+
332
+/* A macro definition */
333
+struct PMacro {
334
+ PMacro *pNext; /* Next in the list */
335
+ PToken macroName; /* Name of the macro */
336
+ PToken macroBody; /* Body of the macro */
337
+ int inUse; /* Do not allow recursion */
327338
};
328339
329340
/* Each call to the pikchr() subroutine uses an instance of the following
330341
** object to pass around context to all of its subroutines.
331342
*/
332343
struct Pik {
333344
unsigned nErr; /* Number of errors seen */
334
- const char *zIn; /* Input PIKCHR-language text. zero-terminated */
335
- unsigned int nIn; /* Number of bytes in zIn */
345
+ PToken sIn; /* Input Pikchr-language text */
336346
char *zOut; /* Result accumulates here */
337347
unsigned int nOut; /* Bytes written to zOut[] so far */
338348
unsigned int nOutAlloc; /* Space allocated to zOut[] */
339349
unsigned char eDir; /* Current direction */
340350
unsigned int mFlags; /* Flags passed to pikchr() */
341
- PElem *cur; /* Element under construction */
342
- PEList *list; /* Element list under construction */
351
+ PObj *cur; /* Object under construction */
352
+ PList *list; /* Object list under construction */
353
+ PMacro *pMacros; /* List of all defined macros */
343354
PVar *pVar; /* Application-defined variables */
344
- PBox bbox; /* Bounding box around all elements */
355
+ PBox bbox; /* Bounding box around all statements */
345356
/* Cache of layout values. <=0.0 for unknown... */
346357
PNum rScale; /* Multiply to convert inches to pixels */
347358
PNum fontScale; /* Scale fonts by this percent */
348359
PNum charWidth; /* Character width */
349360
PNum charHeight; /* Character height */
@@ -353,14 +364,17 @@
353364
char thenFlag; /* True if "then" seen */
354365
char samePath; /* aTPath copied by "same" */
355366
const char *zClass; /* Class name for the <svg> */
356367
int wSVG, hSVG; /* Width and height of the <svg> */
357368
/* Paths for lines are constructed here first, then transferred into
358
- ** the PElem object at the end: */
369
+ ** the PObj object at the end: */
359370
int nTPath; /* Number of entries on aTPath[] */
360371
int mTPath; /* For last entry, 1: x set, 2: y set */
361372
PPoint aTPath[1000]; /* Path under construction */
373
+ /* Error contexts */
374
+ unsigned int nCtx; /* Number of error contexts */
375
+ PToken aCtx[10]; /* Nested error contexts */
362376
};
363377
364378
365379
/*
366380
** The behavior of an object class is defined by an instance of
@@ -368,17 +382,17 @@
368382
*/
369383
struct PClass {
370384
const char *zName; /* Name of class */
371385
char isLine; /* True if a line class */
372386
char eJust; /* Use box-style text justification */
373
- void (*xInit)(Pik*,PElem*); /* Initializer */
374
- void (*xNumProp)(Pik*,PElem*,PToken*); /* Value change notification */
375
- void (*xCheck)(Pik*,PElem*); /* Checks to do after parsing */
376
- PPoint (*xChop)(Pik*,PElem*,PPoint*); /* Chopper */
377
- PPoint (*xOffset)(Pik*,PElem*,int); /* Offset from .c to edge point */
378
- void (*xFit)(Pik*,PElem*,PNum w,PNum h); /* Size to fit text */
379
- void (*xRender)(Pik*,PElem*); /* Render */
387
+ void (*xInit)(Pik*,PObj*); /* Initializer */
388
+ void (*xNumProp)(Pik*,PObj*,PToken*); /* Value change notification */
389
+ void (*xCheck)(Pik*,PObj*); /* Checks to do after parsing */
390
+ PPoint (*xChop)(Pik*,PObj*,PPoint*); /* Chopper */
391
+ PPoint (*xOffset)(Pik*,PObj*,int); /* Offset from .c to edge point */
392
+ void (*xFit)(Pik*,PObj*,PNum w,PNum h); /* Size to fit text */
393
+ void (*xRender)(Pik*,PObj*); /* Render */
380394
};
381395
382396
383397
/* Forward declarations */
384398
static void pik_append(Pik*, const char*,int);
@@ -389,70 +403,71 @@
389403
static void pik_append_y(Pik*,const char*,PNum,const char*);
390404
static void pik_append_xy(Pik*,const char*,PNum,PNum);
391405
static void pik_append_dis(Pik*,const char*,PNum,const char*);
392406
static void pik_append_arc(Pik*,PNum,PNum,PNum,PNum);
393407
static void pik_append_clr(Pik*,const char*,PNum,const char*);
394
-static void pik_append_style(Pik*,PElem*,int);
395
-static void pik_append_txt(Pik*,PElem*, PBox*);
396
-static void pik_draw_arrowhead(Pik*,PPoint*pFrom,PPoint*pTo,PElem*);
408
+static void pik_append_style(Pik*,PObj*,int);
409
+static void pik_append_txt(Pik*,PObj*, PBox*);
410
+static void pik_draw_arrowhead(Pik*,PPoint*pFrom,PPoint*pTo,PObj*);
397411
static void pik_chop(PPoint*pFrom,PPoint*pTo,PNum);
398412
static void pik_error(Pik*,PToken*,const char*);
399
-static void pik_elist_free(Pik*,PEList*);
400
-static void pik_elem_free(Pik*,PElem*);
401
-static void pik_render(Pik*,PEList*);
402
-static PEList *pik_elist_append(Pik*,PEList*,PElem*);
403
-static PElem *pik_elem_new(Pik*,PToken*,PToken*,PEList*);
413
+static void pik_elist_free(Pik*,PList*);
414
+static void pik_elem_free(Pik*,PObj*);
415
+static void pik_render(Pik*,PList*);
416
+static PList *pik_elist_append(Pik*,PList*,PObj*);
417
+static PObj *pik_elem_new(Pik*,PToken*,PToken*,PList*);
404418
static void pik_set_direction(Pik*,int);
405
-static void pik_elem_setname(Pik*,PElem*,PToken*);
419
+static void pik_elem_setname(Pik*,PObj*,PToken*);
406420
static void pik_set_var(Pik*,PToken*,PNum,PToken*);
407421
static PNum pik_value(Pik*,const char*,int,int*);
408422
static PNum pik_lookup_color(Pik*,PToken*);
409423
static PNum pik_get_var(Pik*,PToken*);
410424
static PNum pik_atof(PToken*);
411
-static void pik_after_adding_attributes(Pik*,PElem*);
412
-static void pik_elem_move(PElem*,PNum dx, PNum dy);
413
-static void pik_elist_move(PEList*,PNum dx, PNum dy);
425
+static void pik_after_adding_attributes(Pik*,PObj*);
426
+static void pik_elem_move(PObj*,PNum dx, PNum dy);
427
+static void pik_elist_move(PList*,PNum dx, PNum dy);
414428
static void pik_set_numprop(Pik*,PToken*,PRel*);
415429
static void pik_set_clrprop(Pik*,PToken*,PNum);
416430
static void pik_set_dashed(Pik*,PToken*,PNum*);
417
-static void pik_then(Pik*,PToken*,PElem*);
431
+static void pik_then(Pik*,PToken*,PObj*);
418432
static void pik_add_direction(Pik*,PToken*,PRel*);
419433
static void pik_move_hdg(Pik*,PRel*,PToken*,PNum,PToken*,PToken*);
420434
static void pik_evenwith(Pik*,PToken*,PPoint*);
421
-static void pik_set_from(Pik*,PElem*,PToken*,PPoint*);
422
-static void pik_add_to(Pik*,PElem*,PToken*,PPoint*);
435
+static void pik_set_from(Pik*,PObj*,PToken*,PPoint*);
436
+static void pik_add_to(Pik*,PObj*,PToken*,PPoint*);
423437
static void pik_close_path(Pik*,PToken*);
424438
static void pik_set_at(Pik*,PToken*,PPoint*,PToken*);
425439
static short int pik_nth_value(Pik*,PToken*);
426
-static PElem *pik_find_nth(Pik*,PElem*,PToken*);
427
-static PElem *pik_find_byname(Pik*,PElem*,PToken*);
428
-static PPoint pik_place_of_elem(Pik*,PElem*,PToken*);
440
+static PObj *pik_find_nth(Pik*,PObj*,PToken*);
441
+static PObj *pik_find_byname(Pik*,PObj*,PToken*);
442
+static PPoint pik_place_of_elem(Pik*,PObj*,PToken*);
429443
static int pik_bbox_isempty(PBox*);
430444
static void pik_bbox_init(PBox*);
431445
static void pik_bbox_addbox(PBox*,PBox*);
432446
static void pik_bbox_add_xy(PBox*,PNum,PNum);
433447
static void pik_bbox_addellipse(PBox*,PNum x,PNum y,PNum rx,PNum ry);
434448
static void pik_add_txt(Pik*,PToken*,int);
435449
static int pik_text_length(const PToken *pToken);
436
-static void pik_size_to_fit(Pik*,PToken*);
450
+static void pik_size_to_fit(Pik*,PToken*,int);
437451
static int pik_text_position(int,PToken*);
438
-static PNum pik_property_of(PElem*,PToken*);
452
+static PNum pik_property_of(PObj*,PToken*);
439453
static PNum pik_func(Pik*,PToken*,PNum,PNum);
440454
static PPoint pik_position_between(PNum x, PPoint p1, PPoint p2);
441455
static PPoint pik_position_at_angle(PNum dist, PNum r, PPoint pt);
442456
static PPoint pik_position_at_hdg(PNum dist, PToken *pD, PPoint pt);
443
-static void pik_same(Pik *p, PElem*, PToken*);
444
-static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pElem);
457
+static void pik_same(Pik *p, PObj*, PToken*);
458
+static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PObj *pObj);
445459
static PToken pik_next_semantic_token(PToken *pThis);
446460
static void pik_compute_layout_settings(Pik*);
447
-static void pik_behind(Pik*,PElem*);
448
-static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
449
-static PElem *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
461
+static void pik_behind(Pik*,PObj*);
462
+static PObj *pik_assert(Pik*,PNum,PToken*,PNum);
463
+static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
450464
static PNum pik_dist(PPoint*,PPoint*);
465
+static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
451466
452467
453
-#line 479 "pikchr.c"
468
+#line 494 "pikchr.c"
454469
/**************** End of %include directives **********************************/
455470
/* These constants specify the various numeric values for terminal symbols.
456471
***************** Begin token definitions *************************************/
457472
#ifndef T_ID
458473
#define T_ID 1
@@ -470,87 +485,89 @@
470485
#define T_COLON 13
471486
#define T_ASSERT 14
472487
#define T_LP 15
473488
#define T_EQ 16
474489
#define T_RP 17
475
-#define T_FILL 18
476
-#define T_COLOR 19
477
-#define T_THICKNESS 20
478
-#define T_PRINT 21
479
-#define T_STRING 22
480
-#define T_COMMA 23
481
-#define T_CLASSNAME 24
482
-#define T_LB 25
483
-#define T_RB 26
484
-#define T_UP 27
485
-#define T_DOWN 28
486
-#define T_LEFT 29
487
-#define T_RIGHT 30
488
-#define T_CLOSE 31
489
-#define T_CHOP 32
490
-#define T_FROM 33
491
-#define T_TO 34
492
-#define T_THEN 35
493
-#define T_HEADING 36
494
-#define T_GO 37
495
-#define T_AT 38
496
-#define T_WITH 39
497
-#define T_SAME 40
498
-#define T_AS 41
499
-#define T_FIT 42
500
-#define T_BEHIND 43
501
-#define T_UNTIL 44
502
-#define T_EVEN 45
503
-#define T_DOT_E 46
504
-#define T_HEIGHT 47
505
-#define T_WIDTH 48
506
-#define T_RADIUS 49
507
-#define T_DIAMETER 50
508
-#define T_DOTTED 51
509
-#define T_DASHED 52
510
-#define T_CW 53
511
-#define T_CCW 54
512
-#define T_LARROW 55
513
-#define T_RARROW 56
514
-#define T_LRARROW 57
515
-#define T_INVIS 58
516
-#define T_THICK 59
517
-#define T_THIN 60
518
-#define T_CENTER 61
519
-#define T_LJUST 62
520
-#define T_RJUST 63
521
-#define T_ABOVE 64
522
-#define T_BELOW 65
523
-#define T_ITALIC 66
524
-#define T_BOLD 67
525
-#define T_ALIGNED 68
526
-#define T_BIG 69
527
-#define T_SMALL 70
528
-#define T_AND 71
529
-#define T_LT 72
530
-#define T_GT 73
531
-#define T_ON 74
532
-#define T_WAY 75
533
-#define T_BETWEEN 76
534
-#define T_THE 77
535
-#define T_NTH 78
536
-#define T_VERTEX 79
537
-#define T_TOP 80
538
-#define T_BOTTOM 81
539
-#define T_START 82
540
-#define T_END 83
541
-#define T_IN 84
542
-#define T_DOT_U 85
543
-#define T_LAST 86
544
-#define T_NUMBER 87
545
-#define T_FUNC1 88
546
-#define T_FUNC2 89
547
-#define T_DIST 90
548
-#define T_DOT_XY 91
549
-#define T_X 92
550
-#define T_Y 93
551
-#define T_DOT_L 94
490
+#define T_DEFINE 18
491
+#define T_CODEBLOCK 19
492
+#define T_FILL 20
493
+#define T_COLOR 21
494
+#define T_THICKNESS 22
495
+#define T_PRINT 23
496
+#define T_STRING 24
497
+#define T_COMMA 25
498
+#define T_CLASSNAME 26
499
+#define T_LB 27
500
+#define T_RB 28
501
+#define T_UP 29
502
+#define T_DOWN 30
503
+#define T_LEFT 31
504
+#define T_RIGHT 32
505
+#define T_CLOSE 33
506
+#define T_CHOP 34
507
+#define T_FROM 35
508
+#define T_TO 36
509
+#define T_THEN 37
510
+#define T_HEADING 38
511
+#define T_GO 39
512
+#define T_AT 40
513
+#define T_WITH 41
514
+#define T_SAME 42
515
+#define T_AS 43
516
+#define T_FIT 44
517
+#define T_BEHIND 45
518
+#define T_UNTIL 46
519
+#define T_EVEN 47
520
+#define T_DOT_E 48
521
+#define T_HEIGHT 49
522
+#define T_WIDTH 50
523
+#define T_RADIUS 51
524
+#define T_DIAMETER 52
525
+#define T_DOTTED 53
526
+#define T_DASHED 54
527
+#define T_CW 55
528
+#define T_CCW 56
529
+#define T_LARROW 57
530
+#define T_RARROW 58
531
+#define T_LRARROW 59
532
+#define T_INVIS 60
533
+#define T_THICK 61
534
+#define T_THIN 62
535
+#define T_CENTER 63
536
+#define T_LJUST 64
537
+#define T_RJUST 65
538
+#define T_ABOVE 66
539
+#define T_BELOW 67
540
+#define T_ITALIC 68
541
+#define T_BOLD 69
542
+#define T_ALIGNED 70
543
+#define T_BIG 71
544
+#define T_SMALL 72
545
+#define T_AND 73
546
+#define T_LT 74
547
+#define T_GT 75
548
+#define T_ON 76
549
+#define T_WAY 77
550
+#define T_BETWEEN 78
551
+#define T_THE 79
552
+#define T_NTH 80
553
+#define T_VERTEX 81
554
+#define T_TOP 82
555
+#define T_BOTTOM 83
556
+#define T_START 84
557
+#define T_END 85
558
+#define T_IN 86
559
+#define T_DOT_U 87
560
+#define T_LAST 88
561
+#define T_NUMBER 89
562
+#define T_FUNC1 90
563
+#define T_FUNC2 91
564
+#define T_DIST 92
565
+#define T_DOT_XY 93
566
+#define T_X 94
567
+#define T_Y 95
568
+#define T_DOT_L 96
552569
#endif
553570
/**************** End token definitions ***************************************/
554571
555572
/* The next sections is a series of control #defines.
556573
** various aspects of the generated parser.
@@ -606,22 +623,22 @@
606623
#ifndef INTERFACE
607624
# define INTERFACE 1
608625
#endif
609626
/************* Begin control #defines *****************************************/
610627
#define YYCODETYPE unsigned char
611
-#define YYNOCODE 131
628
+#define YYNOCODE 133
612629
#define YYACTIONTYPE unsigned short int
613630
#define pik_parserTOKENTYPE PToken
614631
typedef union {
615632
int yyinit;
616633
pik_parserTOKENTYPE yy0;
617
- PEList* yy56;
618
- int yy116;
619
- PRel yy164;
620
- PPoint yy175;
621
- PElem* yy226;
622
- PNum yy257;
634
+ int yy46;
635
+ PPoint yy47;
636
+ PNum yy121;
637
+ PRel yy134;
638
+ PObj* yy138;
639
+ PList* yy191;
623640
} YYMINORTYPE;
624641
#ifndef YYSTACKDEPTH
625642
#define YYSTACKDEPTH 100
626643
#endif
627644
#define pik_parserARG_SDECL
@@ -633,22 +650,22 @@
633650
#define pik_parserCTX_PDECL ,Pik *p
634651
#define pik_parserCTX_PARAM ,p
635652
#define pik_parserCTX_FETCH Pik *p=yypParser->p;
636653
#define pik_parserCTX_STORE yypParser->p=p;
637654
#define YYFALLBACK 1
638
-#define YYNSTATE 162
639
-#define YYNRULE 153
640
-#define YYNRULE_WITH_ACTION 113
641
-#define YYNTOKEN 95
642
-#define YY_MAX_SHIFT 161
643
-#define YY_MIN_SHIFTREDUCE 282
644
-#define YY_MAX_SHIFTREDUCE 434
645
-#define YY_ERROR_ACTION 435
646
-#define YY_ACCEPT_ACTION 436
647
-#define YY_NO_ACTION 437
648
-#define YY_MIN_REDUCE 438
649
-#define YY_MAX_REDUCE 590
655
+#define YYNSTATE 164
656
+#define YYNRULE 154
657
+#define YYNRULE_WITH_ACTION 114
658
+#define YYNTOKEN 97
659
+#define YY_MAX_SHIFT 163
660
+#define YY_MIN_SHIFTREDUCE 285
661
+#define YY_MAX_SHIFTREDUCE 438
662
+#define YY_ERROR_ACTION 439
663
+#define YY_ACCEPT_ACTION 440
664
+#define YY_NO_ACTION 441
665
+#define YY_MIN_REDUCE 442
666
+#define YY_MAX_REDUCE 595
650667
/************* End control #defines *******************************************/
651668
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
652669
653670
/* Define the yytestcase() macro to be a no-op if is not already defined
654671
** otherwise.
@@ -711,328 +728,324 @@
711728
** yy_reduce_ofst[] For each state, the offset into yy_action for
712729
** shifting non-terminals after a reduce.
713730
** yy_default[] Default action for each state.
714731
**
715732
*********** Begin parsing tables **********************************************/
716
-#define YY_ACTTAB_COUNT (1244)
733
+#define YY_ACTTAB_COUNT (1223)
717734
static const YYACTIONTYPE yy_action[] = {
718
- /* 0 */ 564, 438, 25, 444, 29, 74, 127, 146, 54, 51,
719
- /* 10 */ 564, 36, 445, 113, 120, 159, 119, 126, 419, 420,
720
- /* 20 */ 333, 548, 81, 520, 549, 550, 564, 64, 63, 62,
721
- /* 30 */ 61, 316, 317, 9, 8, 33, 147, 32, 7, 71,
722
- /* 40 */ 125, 28, 329, 66, 568, 300, 50, 333, 333, 333,
723
- /* 50 */ 333, 417, 418, 334, 335, 336, 337, 338, 339, 340,
724
- /* 60 */ 341, 465, 64, 63, 62, 61, 121, 439, 446, 29,
725
- /* 70 */ 36, 465, 30, 442, 368, 292, 486, 159, 119, 419,
726
- /* 80 */ 420, 333, 31, 81, 161, 350, 304, 465, 436, 27,
727
- /* 90 */ 324, 13, 316, 317, 9, 8, 33, 69, 32, 7,
728
- /* 100 */ 71, 125, 83, 329, 66, 483, 159, 119, 333, 333,
729
- /* 110 */ 333, 333, 417, 418, 334, 335, 336, 337, 338, 339,
730
- /* 120 */ 340, 341, 386, 427, 46, 59, 60, 64, 63, 62,
731
- /* 130 */ 61, 307, 84, 368, 322, 35, 2, 293, 386, 427,
732
- /* 140 */ 108, 59, 60, 80, 4, 302, 79, 3, 117, 368,
733
- /* 150 */ 433, 432, 2, 62, 61, 154, 154, 154, 386, 390,
734
- /* 160 */ 391, 59, 60, 518, 159, 119, 433, 432, 47, 102,
735
- /* 170 */ 38, 67, 42, 48, 37, 295, 296, 297, 69, 299,
736
- /* 180 */ 372, 155, 426, 343, 343, 343, 343, 343, 343, 343,
737
- /* 190 */ 343, 343, 343, 371, 157, 566, 77, 566, 426, 106,
738
- /* 200 */ 76, 428, 429, 430, 431, 5, 6, 117, 385, 153,
739
- /* 210 */ 152, 151, 523, 159, 119, 106, 416, 428, 429, 430,
740
- /* 220 */ 431, 415, 427, 117, 385, 153, 152, 151, 386, 427,
741
- /* 230 */ 129, 59, 60, 389, 1, 106, 521, 159, 119, 368,
742
- /* 240 */ 11, 12, 2, 117, 385, 153, 152, 151, 65, 433,
743
- /* 250 */ 432, 64, 63, 62, 61, 349, 433, 432, 136, 140,
744
- /* 260 */ 138, 64, 63, 62, 61, 386, 75, 427, 59, 60,
745
- /* 270 */ 53, 424, 422, 45, 137, 14, 368, 16, 18, 42,
746
- /* 280 */ 55, 426, 154, 154, 154, 44, 145, 144, 426, 64,
747
- /* 290 */ 63, 62, 61, 43, 433, 432, 64, 63, 62, 61,
748
- /* 300 */ 428, 429, 430, 431, 19, 106, 114, 428, 429, 430,
749
- /* 310 */ 431, 20, 68, 117, 385, 153, 152, 151, 15, 352,
750
- /* 320 */ 23, 22, 21, 384, 376, 17, 426, 370, 156, 24,
751
- /* 330 */ 26, 143, 139, 423, 140, 138, 64, 63, 62, 61,
752
- /* 340 */ 374, 57, 106, 58, 375, 428, 429, 430, 431, 383,
753
- /* 350 */ 117, 385, 153, 152, 151, 55, 64, 63, 62, 61,
754
- /* 360 */ 369, 145, 144, 403, 404, 405, 406, 158, 43, 348,
755
- /* 370 */ 70, 140, 138, 64, 63, 62, 61, 386, 464, 39,
756
- /* 380 */ 59, 60, 64, 63, 62, 61, 437, 437, 368, 118,
757
- /* 390 */ 437, 42, 55, 437, 437, 383, 22, 21, 145, 144,
758
- /* 400 */ 395, 49, 437, 524, 24, 43, 143, 139, 423, 437,
759
- /* 410 */ 437, 131, 464, 124, 437, 437, 437, 396, 397, 398,
760
- /* 420 */ 400, 80, 437, 302, 79, 437, 403, 404, 405, 406,
761
- /* 430 */ 440, 446, 29, 22, 21, 386, 442, 437, 59, 60,
762
- /* 440 */ 437, 24, 524, 143, 139, 423, 368, 161, 524, 42,
763
- /* 450 */ 437, 524, 27, 437, 106, 437, 386, 141, 437, 59,
764
- /* 460 */ 60, 437, 117, 385, 153, 152, 151, 368, 437, 437,
765
- /* 470 */ 42, 437, 386, 142, 437, 59, 60, 386, 130, 128,
766
- /* 480 */ 59, 60, 437, 368, 370, 156, 42, 437, 368, 437,
767
- /* 490 */ 386, 42, 437, 59, 60, 386, 437, 437, 59, 60,
768
- /* 500 */ 437, 102, 437, 437, 42, 437, 368, 437, 437, 40,
769
- /* 510 */ 437, 437, 106, 437, 386, 437, 437, 59, 60, 437,
770
- /* 520 */ 117, 385, 153, 152, 151, 368, 437, 437, 41, 64,
771
- /* 530 */ 63, 62, 61, 106, 64, 63, 62, 61, 437, 160,
772
- /* 540 */ 437, 117, 385, 153, 152, 151, 118, 387, 56, 106,
773
- /* 550 */ 437, 437, 437, 437, 106, 437, 437, 117, 385, 153,
774
- /* 560 */ 152, 151, 117, 385, 153, 152, 151, 106, 64, 63,
775
- /* 570 */ 62, 61, 106, 437, 437, 117, 385, 153, 152, 151,
776
- /* 580 */ 117, 385, 153, 152, 151, 419, 420, 333, 437, 437,
777
- /* 590 */ 437, 106, 437, 437, 437, 88, 437, 437, 437, 117,
778
- /* 600 */ 385, 153, 152, 151, 120, 159, 119, 437, 437, 437,
779
- /* 610 */ 10, 470, 470, 437, 333, 333, 333, 333, 417, 418,
780
- /* 620 */ 73, 437, 146, 437, 437, 437, 150, 112, 113, 120,
781
- /* 630 */ 159, 119, 437, 74, 437, 146, 64, 63, 62, 61,
782
- /* 640 */ 122, 113, 120, 159, 119, 72, 437, 146, 437, 347,
783
- /* 650 */ 437, 147, 123, 113, 120, 159, 119, 437, 74, 437,
784
- /* 660 */ 146, 437, 437, 437, 147, 488, 113, 120, 159, 119,
785
- /* 670 */ 437, 437, 74, 437, 146, 437, 147, 437, 437, 487,
786
- /* 680 */ 113, 120, 159, 119, 74, 437, 146, 437, 437, 147,
787
- /* 690 */ 437, 481, 113, 120, 159, 119, 437, 437, 437, 74,
788
- /* 700 */ 437, 146, 88, 147, 437, 437, 475, 113, 120, 159,
789
- /* 710 */ 119, 120, 159, 119, 74, 147, 146, 437, 110, 110,
790
- /* 720 */ 437, 474, 113, 120, 159, 119, 437, 74, 437, 146,
791
- /* 730 */ 147, 437, 437, 150, 471, 113, 120, 159, 119, 437,
792
- /* 740 */ 74, 437, 146, 437, 437, 147, 437, 132, 113, 120,
793
- /* 750 */ 159, 119, 74, 437, 146, 437, 437, 437, 147, 507,
794
- /* 760 */ 113, 120, 159, 119, 437, 74, 437, 146, 437, 437,
795
- /* 770 */ 437, 147, 135, 113, 120, 159, 119, 437, 437, 74,
796
- /* 780 */ 437, 146, 437, 147, 437, 437, 515, 113, 120, 159,
797
- /* 790 */ 119, 74, 437, 146, 437, 437, 147, 437, 517, 113,
798
- /* 800 */ 120, 159, 119, 437, 437, 437, 74, 437, 146, 88,
799
- /* 810 */ 147, 437, 437, 514, 113, 120, 159, 119, 120, 159,
800
- /* 820 */ 119, 74, 147, 146, 437, 111, 111, 437, 516, 113,
801
- /* 830 */ 120, 159, 119, 437, 74, 437, 146, 147, 437, 437,
802
- /* 840 */ 150, 513, 113, 120, 159, 119, 437, 74, 437, 146,
803
- /* 850 */ 437, 437, 147, 437, 512, 113, 120, 159, 119, 74,
804
- /* 860 */ 437, 146, 437, 437, 437, 147, 511, 113, 120, 159,
805
- /* 870 */ 119, 437, 74, 437, 146, 437, 437, 437, 147, 510,
806
- /* 880 */ 113, 120, 159, 119, 437, 437, 74, 437, 146, 437,
807
- /* 890 */ 147, 437, 437, 509, 113, 120, 159, 119, 74, 437,
808
- /* 900 */ 146, 107, 437, 147, 437, 148, 113, 120, 159, 119,
809
- /* 910 */ 120, 159, 119, 74, 469, 146, 85, 147, 437, 437,
810
- /* 920 */ 149, 113, 120, 159, 119, 120, 159, 119, 74, 147,
811
- /* 930 */ 146, 437, 150, 437, 437, 134, 113, 120, 159, 119,
812
- /* 940 */ 437, 74, 437, 146, 147, 107, 437, 150, 133, 113,
813
- /* 950 */ 120, 159, 119, 437, 120, 159, 119, 437, 454, 147,
814
- /* 960 */ 437, 64, 63, 62, 61, 78, 78, 437, 88, 437,
815
- /* 970 */ 437, 437, 147, 437, 383, 437, 150, 120, 159, 119,
816
- /* 980 */ 52, 437, 437, 437, 82, 437, 88, 437, 437, 437,
817
- /* 990 */ 437, 457, 437, 34, 107, 120, 159, 119, 437, 150,
818
- /* 1000 */ 437, 437, 466, 120, 159, 119, 437, 454, 437, 109,
819
- /* 1010 */ 439, 446, 29, 437, 437, 558, 442, 150, 437, 437,
820
- /* 1020 */ 107, 64, 63, 62, 61, 150, 86, 161, 437, 120,
821
- /* 1030 */ 159, 119, 27, 443, 388, 120, 159, 119, 98, 437,
822
- /* 1040 */ 437, 437, 437, 89, 437, 437, 437, 120, 159, 119,
823
- /* 1050 */ 90, 150, 120, 159, 119, 87, 437, 150, 437, 120,
824
- /* 1060 */ 159, 119, 99, 437, 120, 159, 119, 437, 100, 150,
825
- /* 1070 */ 437, 120, 159, 119, 150, 437, 437, 120, 159, 119,
826
- /* 1080 */ 101, 150, 64, 63, 62, 61, 150, 437, 437, 120,
827
- /* 1090 */ 159, 119, 437, 150, 91, 383, 437, 103, 437, 150,
828
- /* 1100 */ 437, 437, 437, 120, 159, 119, 120, 159, 119, 92,
829
- /* 1110 */ 437, 150, 93, 437, 437, 437, 437, 437, 120, 159,
830
- /* 1120 */ 119, 120, 159, 119, 437, 150, 104, 437, 150, 437,
831
- /* 1130 */ 437, 437, 437, 437, 437, 120, 159, 119, 94, 437,
832
- /* 1140 */ 150, 437, 437, 150, 437, 437, 437, 120, 159, 119,
833
- /* 1150 */ 105, 437, 437, 95, 437, 437, 437, 150, 437, 120,
834
- /* 1160 */ 159, 119, 120, 159, 119, 96, 437, 437, 97, 150,
835
- /* 1170 */ 437, 437, 437, 437, 120, 159, 119, 120, 159, 119,
836
- /* 1180 */ 538, 150, 437, 437, 150, 437, 437, 437, 437, 120,
837
- /* 1190 */ 159, 119, 437, 537, 437, 437, 150, 536, 437, 150,
838
- /* 1200 */ 437, 437, 120, 159, 119, 535, 120, 159, 119, 115,
839
- /* 1210 */ 437, 150, 116, 437, 120, 159, 119, 437, 120, 159,
840
- /* 1220 */ 119, 120, 159, 119, 150, 437, 437, 437, 150, 437,
841
- /* 1230 */ 437, 437, 437, 437, 437, 437, 150, 437, 437, 437,
842
- /* 1240 */ 150, 437, 437, 150,
735
+ /* 0 */ 569, 491, 161, 119, 25, 448, 29, 74, 129, 148,
736
+ /* 10 */ 569, 488, 161, 119, 449, 113, 120, 161, 119, 525,
737
+ /* 20 */ 423, 424, 337, 553, 81, 36, 554, 555, 569, 64,
738
+ /* 30 */ 63, 62, 61, 320, 321, 9, 8, 33, 149, 32,
739
+ /* 40 */ 7, 71, 127, 308, 333, 66, 523, 161, 119, 337,
740
+ /* 50 */ 337, 337, 337, 421, 422, 338, 339, 340, 341, 342,
741
+ /* 60 */ 343, 344, 345, 470, 64, 63, 62, 61, 311, 28,
742
+ /* 70 */ 73, 304, 148, 470, 528, 161, 119, 112, 113, 120,
743
+ /* 80 */ 161, 119, 128, 423, 424, 337, 354, 81, 526, 161,
744
+ /* 90 */ 119, 470, 374, 158, 13, 30, 320, 321, 9, 8,
745
+ /* 100 */ 33, 149, 32, 7, 71, 127, 372, 333, 66, 573,
746
+ /* 110 */ 328, 31, 337, 337, 337, 337, 421, 422, 338, 339,
747
+ /* 120 */ 340, 341, 342, 343, 344, 345, 390, 431, 326, 59,
748
+ /* 130 */ 60, 407, 408, 409, 410, 374, 158, 372, 35, 390,
749
+ /* 140 */ 2, 38, 59, 60, 48, 37, 46, 162, 442, 80,
750
+ /* 150 */ 372, 306, 79, 42, 118, 83, 437, 436, 36, 390,
751
+ /* 160 */ 431, 84, 59, 60, 47, 297, 571, 77, 571, 122,
752
+ /* 170 */ 372, 296, 390, 2, 108, 59, 60, 76, 156, 156,
753
+ /* 180 */ 156, 3, 117, 372, 132, 130, 42, 69, 430, 437,
754
+ /* 190 */ 436, 4, 390, 431, 67, 59, 60, 118, 64, 63,
755
+ /* 200 */ 62, 61, 5, 372, 6, 106, 2, 432, 433, 434,
756
+ /* 210 */ 435, 387, 1, 117, 389, 155, 154, 153, 106, 49,
757
+ /* 220 */ 420, 430, 437, 436, 107, 65, 117, 389, 155, 154,
758
+ /* 230 */ 153, 54, 51, 120, 161, 119, 419, 459, 106, 131,
759
+ /* 240 */ 432, 433, 434, 435, 78, 78, 117, 389, 155, 154,
760
+ /* 250 */ 153, 106, 393, 390, 430, 152, 59, 60, 11, 117,
761
+ /* 260 */ 389, 155, 154, 153, 102, 376, 157, 42, 394, 395,
762
+ /* 270 */ 69, 106, 353, 432, 433, 434, 435, 375, 159, 117,
763
+ /* 280 */ 389, 155, 154, 153, 142, 140, 64, 63, 62, 61,
764
+ /* 290 */ 12, 64, 63, 62, 61, 62, 61, 428, 45, 138,
765
+ /* 300 */ 139, 142, 140, 64, 63, 62, 61, 55, 64, 63,
766
+ /* 310 */ 62, 61, 426, 147, 146, 390, 387, 44, 59, 60,
767
+ /* 320 */ 43, 295, 15, 14, 55, 16, 102, 18, 19, 42,
768
+ /* 330 */ 147, 146, 106, 20, 299, 300, 301, 43, 303, 68,
769
+ /* 340 */ 117, 389, 155, 154, 153, 444, 450, 29, 22, 21,
770
+ /* 350 */ 114, 446, 356, 23, 26, 57, 24, 58, 145, 141,
771
+ /* 360 */ 427, 388, 163, 380, 373, 22, 21, 27, 160, 378,
772
+ /* 370 */ 70, 379, 39, 24, 441, 145, 141, 427, 142, 140,
773
+ /* 380 */ 64, 63, 62, 61, 347, 347, 347, 347, 347, 347,
774
+ /* 390 */ 347, 347, 347, 347, 106, 441, 441, 64, 63, 62,
775
+ /* 400 */ 61, 55, 117, 389, 155, 154, 153, 147, 146, 399,
776
+ /* 410 */ 387, 441, 441, 441, 43, 441, 441, 441, 52, 441,
777
+ /* 420 */ 133, 441, 126, 441, 441, 441, 123, 441, 400, 401,
778
+ /* 430 */ 402, 404, 80, 441, 306, 79, 441, 407, 408, 409,
779
+ /* 440 */ 410, 441, 22, 21, 390, 441, 441, 59, 60, 441,
780
+ /* 450 */ 24, 441, 145, 141, 427, 372, 441, 441, 42, 441,
781
+ /* 460 */ 441, 441, 441, 156, 156, 156, 390, 469, 441, 59,
782
+ /* 470 */ 60, 390, 143, 441, 59, 60, 441, 372, 441, 529,
783
+ /* 480 */ 42, 441, 372, 441, 441, 42, 441, 390, 144, 441,
784
+ /* 490 */ 59, 60, 441, 390, 441, 441, 59, 60, 372, 441,
785
+ /* 500 */ 441, 42, 441, 469, 372, 88, 390, 40, 441, 59,
786
+ /* 510 */ 60, 441, 441, 441, 120, 161, 119, 372, 529, 441,
787
+ /* 520 */ 41, 82, 441, 106, 529, 441, 441, 529, 462, 441,
788
+ /* 530 */ 34, 117, 389, 155, 154, 153, 152, 85, 64, 63,
789
+ /* 540 */ 62, 61, 441, 441, 441, 106, 120, 161, 119, 441,
790
+ /* 550 */ 106, 441, 441, 117, 389, 155, 154, 153, 117, 389,
791
+ /* 560 */ 155, 154, 153, 441, 441, 441, 106, 441, 152, 17,
792
+ /* 570 */ 441, 441, 106, 441, 117, 389, 155, 154, 153, 431,
793
+ /* 580 */ 117, 389, 155, 154, 153, 106, 441, 423, 424, 337,
794
+ /* 590 */ 441, 441, 86, 117, 389, 155, 154, 153, 441, 441,
795
+ /* 600 */ 441, 120, 161, 119, 121, 443, 450, 29, 437, 436,
796
+ /* 610 */ 441, 446, 64, 63, 62, 61, 337, 337, 337, 337,
797
+ /* 620 */ 421, 422, 163, 152, 441, 75, 440, 27, 109, 443,
798
+ /* 630 */ 450, 29, 441, 50, 74, 446, 148, 441, 441, 441,
799
+ /* 640 */ 430, 124, 113, 120, 161, 119, 163, 72, 441, 148,
800
+ /* 650 */ 441, 27, 431, 441, 125, 113, 120, 161, 119, 432,
801
+ /* 660 */ 433, 434, 435, 441, 74, 149, 148, 64, 63, 62,
802
+ /* 670 */ 61, 493, 113, 120, 161, 119, 441, 74, 149, 148,
803
+ /* 680 */ 352, 437, 436, 441, 492, 113, 120, 161, 119, 74,
804
+ /* 690 */ 441, 148, 441, 441, 98, 149, 486, 113, 120, 161,
805
+ /* 700 */ 119, 441, 441, 120, 161, 119, 441, 74, 149, 148,
806
+ /* 710 */ 441, 441, 441, 430, 480, 113, 120, 161, 119, 74,
807
+ /* 720 */ 149, 148, 441, 441, 441, 152, 479, 113, 120, 161,
808
+ /* 730 */ 119, 88, 432, 433, 434, 435, 441, 441, 149, 441,
809
+ /* 740 */ 120, 161, 119, 441, 74, 441, 148, 110, 110, 441,
810
+ /* 750 */ 149, 476, 113, 120, 161, 119, 74, 441, 148, 107,
811
+ /* 760 */ 441, 441, 152, 134, 113, 120, 161, 119, 120, 161,
812
+ /* 770 */ 119, 441, 459, 441, 74, 149, 148, 441, 441, 441,
813
+ /* 780 */ 563, 512, 113, 120, 161, 119, 74, 149, 148, 441,
814
+ /* 790 */ 152, 441, 441, 137, 113, 120, 161, 119, 441, 74,
815
+ /* 800 */ 441, 148, 441, 441, 441, 149, 520, 113, 120, 161,
816
+ /* 810 */ 119, 74, 441, 148, 441, 441, 88, 149, 522, 113,
817
+ /* 820 */ 120, 161, 119, 441, 441, 120, 161, 119, 441, 74,
818
+ /* 830 */ 149, 148, 111, 111, 441, 441, 519, 113, 120, 161,
819
+ /* 840 */ 119, 441, 149, 441, 441, 441, 74, 152, 148, 441,
820
+ /* 850 */ 441, 441, 88, 521, 113, 120, 161, 119, 441, 441,
821
+ /* 860 */ 149, 120, 161, 119, 441, 74, 441, 148, 471, 441,
822
+ /* 870 */ 441, 441, 518, 113, 120, 161, 119, 149, 74, 441,
823
+ /* 880 */ 148, 441, 441, 152, 441, 517, 113, 120, 161, 119,
824
+ /* 890 */ 74, 441, 148, 441, 441, 441, 149, 516, 113, 120,
825
+ /* 900 */ 161, 119, 441, 74, 441, 148, 441, 441, 441, 149,
826
+ /* 910 */ 515, 113, 120, 161, 119, 74, 441, 148, 89, 441,
827
+ /* 920 */ 441, 149, 514, 113, 120, 161, 119, 120, 161, 119,
828
+ /* 930 */ 441, 74, 441, 148, 149, 441, 441, 441, 150, 113,
829
+ /* 940 */ 120, 161, 119, 441, 441, 441, 149, 441, 74, 152,
830
+ /* 950 */ 148, 441, 441, 441, 90, 151, 113, 120, 161, 119,
831
+ /* 960 */ 441, 441, 149, 120, 161, 119, 441, 74, 441, 148,
832
+ /* 970 */ 64, 63, 62, 61, 136, 113, 120, 161, 119, 149,
833
+ /* 980 */ 74, 441, 148, 351, 441, 152, 441, 135, 113, 120,
834
+ /* 990 */ 161, 119, 88, 64, 63, 62, 61, 441, 149, 441,
835
+ /* 1000 */ 441, 120, 161, 119, 441, 107, 392, 10, 475, 475,
836
+ /* 1010 */ 441, 149, 441, 441, 120, 161, 119, 107, 474, 64,
837
+ /* 1020 */ 63, 62, 61, 152, 87, 441, 120, 161, 119, 99,
838
+ /* 1030 */ 447, 441, 391, 120, 161, 119, 152, 441, 120, 161,
839
+ /* 1040 */ 119, 100, 441, 441, 64, 63, 62, 61, 152, 441,
840
+ /* 1050 */ 120, 161, 119, 441, 441, 152, 101, 387, 441, 91,
841
+ /* 1060 */ 152, 441, 441, 441, 103, 120, 161, 119, 120, 161,
842
+ /* 1070 */ 119, 92, 152, 120, 161, 119, 441, 441, 441, 441,
843
+ /* 1080 */ 120, 161, 119, 441, 441, 441, 441, 152, 441, 93,
844
+ /* 1090 */ 152, 441, 441, 441, 104, 152, 441, 441, 120, 161,
845
+ /* 1100 */ 119, 441, 152, 120, 161, 119, 441, 94, 441, 441,
846
+ /* 1110 */ 441, 441, 441, 105, 441, 441, 120, 161, 119, 95,
847
+ /* 1120 */ 152, 441, 120, 161, 119, 152, 96, 441, 120, 161,
848
+ /* 1130 */ 119, 97, 441, 441, 441, 120, 161, 119, 152, 441,
849
+ /* 1140 */ 120, 161, 119, 543, 152, 441, 441, 441, 441, 441,
850
+ /* 1150 */ 152, 441, 120, 161, 119, 441, 441, 152, 542, 441,
851
+ /* 1160 */ 441, 541, 152, 441, 441, 441, 540, 120, 161, 119,
852
+ /* 1170 */ 120, 161, 119, 115, 152, 120, 161, 119, 64, 63,
853
+ /* 1180 */ 62, 61, 120, 161, 119, 64, 63, 62, 61, 152,
854
+ /* 1190 */ 441, 116, 152, 441, 441, 441, 441, 152, 441, 53,
855
+ /* 1200 */ 120, 161, 119, 441, 152, 441, 56, 441, 441, 441,
856
+ /* 1210 */ 441, 441, 441, 441, 441, 441, 441, 441, 441, 441,
857
+ /* 1220 */ 441, 441, 152,
843858
};
844859
static const YYCODETYPE yy_lookahead[] = {
845
- /* 0 */ 0, 0, 129, 97, 98, 99, 101, 101, 4, 5,
846
- /* 10 */ 10, 10, 106, 107, 108, 109, 110, 101, 18, 19,
847
- /* 20 */ 20, 100, 22, 101, 103, 104, 26, 4, 5, 6,
848
- /* 30 */ 7, 31, 32, 33, 34, 35, 130, 37, 38, 39,
849
- /* 40 */ 40, 102, 42, 43, 128, 23, 23, 47, 48, 49,
860
+ /* 0 */ 0, 110, 111, 112, 131, 99, 100, 101, 103, 103,
861
+ /* 10 */ 10, 110, 111, 112, 108, 109, 110, 111, 112, 103,
862
+ /* 20 */ 20, 21, 22, 102, 24, 10, 105, 106, 28, 4,
863
+ /* 30 */ 5, 6, 7, 33, 34, 35, 36, 37, 132, 39,
864
+ /* 40 */ 40, 41, 42, 28, 44, 45, 110, 111, 112, 49,
850865
/* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
851
- /* 60 */ 60, 0, 4, 5, 6, 7, 95, 96, 97, 98,
852
- /* 70 */ 10, 10, 121, 102, 12, 17, 108, 109, 110, 18,
853
- /* 80 */ 19, 20, 123, 22, 113, 17, 26, 26, 117, 118,
854
- /* 90 */ 2, 23, 31, 32, 33, 34, 35, 3, 37, 38,
855
- /* 100 */ 39, 40, 111, 42, 43, 108, 109, 110, 47, 48,
856
- /* 110 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
857
- /* 120 */ 59, 60, 1, 2, 36, 4, 5, 4, 5, 6,
858
- /* 130 */ 7, 8, 111, 12, 2, 124, 15, 17, 1, 2,
859
- /* 140 */ 78, 4, 5, 22, 15, 24, 25, 16, 86, 12,
860
- /* 150 */ 29, 30, 15, 6, 7, 18, 19, 20, 1, 92,
861
- /* 160 */ 93, 4, 5, 108, 109, 110, 29, 30, 36, 12,
862
- /* 170 */ 100, 41, 15, 103, 104, 18, 19, 20, 84, 22,
863
- /* 180 */ 24, 25, 61, 61, 62, 63, 64, 65, 66, 67,
864
- /* 190 */ 68, 69, 70, 24, 25, 125, 126, 127, 61, 78,
865
- /* 200 */ 46, 80, 81, 82, 83, 38, 38, 86, 87, 88,
866
- /* 210 */ 89, 90, 108, 109, 110, 78, 39, 80, 81, 82,
867
- /* 220 */ 83, 39, 2, 86, 87, 88, 89, 90, 1, 2,
868
- /* 230 */ 45, 4, 5, 17, 13, 78, 108, 109, 110, 12,
869
- /* 240 */ 23, 71, 15, 86, 87, 88, 89, 90, 94, 29,
870
- /* 250 */ 30, 4, 5, 6, 7, 17, 29, 30, 75, 2,
871
- /* 260 */ 3, 4, 5, 6, 7, 1, 46, 2, 4, 5,
872
- /* 270 */ 23, 76, 76, 16, 77, 3, 12, 3, 3, 15,
873
- /* 280 */ 23, 61, 18, 19, 20, 36, 29, 30, 61, 4,
874
- /* 290 */ 5, 6, 7, 36, 29, 30, 4, 5, 6, 7,
875
- /* 300 */ 80, 81, 82, 83, 3, 78, 91, 80, 81, 82,
876
- /* 310 */ 83, 3, 3, 86, 87, 88, 89, 90, 33, 73,
877
- /* 320 */ 23, 64, 65, 17, 26, 33, 61, 24, 25, 72,
878
- /* 330 */ 15, 74, 75, 76, 2, 3, 4, 5, 6, 7,
879
- /* 340 */ 26, 15, 78, 15, 26, 80, 81, 82, 83, 17,
880
- /* 350 */ 86, 87, 88, 89, 90, 23, 4, 5, 6, 7,
881
- /* 360 */ 12, 29, 30, 27, 28, 29, 30, 85, 36, 17,
882
- /* 370 */ 3, 2, 3, 4, 5, 6, 7, 1, 2, 11,
883
- /* 380 */ 4, 5, 4, 5, 6, 7, 131, 131, 12, 86,
884
- /* 390 */ 131, 15, 23, 131, 131, 17, 64, 65, 29, 30,
885
- /* 400 */ 1, 23, 131, 46, 72, 36, 74, 75, 76, 131,
886
- /* 410 */ 131, 12, 36, 14, 131, 131, 131, 18, 19, 20,
887
- /* 420 */ 21, 22, 131, 24, 25, 131, 27, 28, 29, 30,
888
- /* 430 */ 96, 97, 98, 64, 65, 1, 102, 131, 4, 5,
889
- /* 440 */ 131, 72, 85, 74, 75, 76, 12, 113, 91, 15,
890
- /* 450 */ 131, 94, 118, 131, 78, 131, 1, 2, 131, 4,
891
- /* 460 */ 5, 131, 86, 87, 88, 89, 90, 12, 131, 131,
892
- /* 470 */ 15, 131, 1, 2, 131, 4, 5, 1, 44, 45,
893
- /* 480 */ 4, 5, 131, 12, 24, 25, 15, 131, 12, 131,
894
- /* 490 */ 1, 15, 131, 4, 5, 1, 131, 131, 4, 5,
895
- /* 500 */ 131, 12, 131, 131, 15, 131, 12, 131, 131, 15,
896
- /* 510 */ 131, 131, 78, 131, 1, 131, 131, 4, 5, 131,
897
- /* 520 */ 86, 87, 88, 89, 90, 12, 131, 131, 15, 4,
898
- /* 530 */ 5, 6, 7, 78, 4, 5, 6, 7, 131, 79,
899
- /* 540 */ 131, 86, 87, 88, 89, 90, 86, 17, 23, 78,
900
- /* 550 */ 131, 131, 131, 131, 78, 131, 131, 86, 87, 88,
901
- /* 560 */ 89, 90, 86, 87, 88, 89, 90, 78, 4, 5,
902
- /* 570 */ 6, 7, 78, 131, 131, 86, 87, 88, 89, 90,
903
- /* 580 */ 86, 87, 88, 89, 90, 18, 19, 20, 131, 131,
904
- /* 590 */ 131, 78, 131, 131, 131, 99, 131, 131, 131, 86,
905
- /* 600 */ 87, 88, 89, 90, 108, 109, 110, 131, 131, 131,
906
- /* 610 */ 114, 115, 116, 131, 47, 48, 49, 50, 51, 52,
907
- /* 620 */ 99, 131, 101, 131, 131, 131, 130, 106, 107, 108,
908
- /* 630 */ 109, 110, 131, 99, 131, 101, 4, 5, 6, 7,
909
- /* 640 */ 106, 107, 108, 109, 110, 99, 131, 101, 131, 17,
910
- /* 650 */ 131, 130, 106, 107, 108, 109, 110, 131, 99, 131,
911
- /* 660 */ 101, 131, 131, 131, 130, 106, 107, 108, 109, 110,
912
- /* 670 */ 131, 131, 99, 131, 101, 131, 130, 131, 131, 106,
913
- /* 680 */ 107, 108, 109, 110, 99, 131, 101, 131, 131, 130,
914
- /* 690 */ 131, 106, 107, 108, 109, 110, 131, 131, 131, 99,
915
- /* 700 */ 131, 101, 99, 130, 131, 131, 106, 107, 108, 109,
916
- /* 710 */ 110, 108, 109, 110, 99, 130, 101, 131, 115, 116,
917
- /* 720 */ 131, 106, 107, 108, 109, 110, 131, 99, 131, 101,
918
- /* 730 */ 130, 131, 131, 130, 106, 107, 108, 109, 110, 131,
919
- /* 740 */ 99, 131, 101, 131, 131, 130, 131, 106, 107, 108,
920
- /* 750 */ 109, 110, 99, 131, 101, 131, 131, 131, 130, 106,
921
- /* 760 */ 107, 108, 109, 110, 131, 99, 131, 101, 131, 131,
922
- /* 770 */ 131, 130, 106, 107, 108, 109, 110, 131, 131, 99,
923
- /* 780 */ 131, 101, 131, 130, 131, 131, 106, 107, 108, 109,
924
- /* 790 */ 110, 99, 131, 101, 131, 131, 130, 131, 106, 107,
925
- /* 800 */ 108, 109, 110, 131, 131, 131, 99, 131, 101, 99,
926
- /* 810 */ 130, 131, 131, 106, 107, 108, 109, 110, 108, 109,
927
- /* 820 */ 110, 99, 130, 101, 131, 115, 116, 131, 106, 107,
928
- /* 830 */ 108, 109, 110, 131, 99, 131, 101, 130, 131, 131,
929
- /* 840 */ 130, 106, 107, 108, 109, 110, 131, 99, 131, 101,
930
- /* 850 */ 131, 131, 130, 131, 106, 107, 108, 109, 110, 99,
931
- /* 860 */ 131, 101, 131, 131, 131, 130, 106, 107, 108, 109,
932
- /* 870 */ 110, 131, 99, 131, 101, 131, 131, 131, 130, 106,
933
- /* 880 */ 107, 108, 109, 110, 131, 131, 99, 131, 101, 131,
934
- /* 890 */ 130, 131, 131, 106, 107, 108, 109, 110, 99, 131,
935
- /* 900 */ 101, 99, 131, 130, 131, 106, 107, 108, 109, 110,
936
- /* 910 */ 108, 109, 110, 99, 112, 101, 99, 130, 131, 131,
937
- /* 920 */ 106, 107, 108, 109, 110, 108, 109, 110, 99, 130,
938
- /* 930 */ 101, 131, 130, 131, 131, 106, 107, 108, 109, 110,
939
- /* 940 */ 131, 99, 131, 101, 130, 99, 131, 130, 106, 107,
940
- /* 950 */ 108, 109, 110, 131, 108, 109, 110, 131, 112, 130,
941
- /* 960 */ 131, 4, 5, 6, 7, 119, 120, 131, 99, 131,
942
- /* 970 */ 131, 131, 130, 131, 17, 131, 130, 108, 109, 110,
943
- /* 980 */ 23, 131, 131, 131, 115, 131, 99, 131, 131, 131,
944
- /* 990 */ 131, 122, 131, 124, 99, 108, 109, 110, 131, 130,
945
- /* 1000 */ 131, 131, 115, 108, 109, 110, 131, 112, 131, 95,
946
- /* 1010 */ 96, 97, 98, 131, 131, 120, 102, 130, 131, 131,
947
- /* 1020 */ 99, 4, 5, 6, 7, 130, 99, 113, 131, 108,
948
- /* 1030 */ 109, 110, 118, 112, 17, 108, 109, 110, 99, 131,
949
- /* 1040 */ 131, 131, 131, 99, 131, 131, 131, 108, 109, 110,
950
- /* 1050 */ 99, 130, 108, 109, 110, 99, 131, 130, 131, 108,
951
- /* 1060 */ 109, 110, 99, 131, 108, 109, 110, 131, 99, 130,
952
- /* 1070 */ 131, 108, 109, 110, 130, 131, 131, 108, 109, 110,
953
- /* 1080 */ 99, 130, 4, 5, 6, 7, 130, 131, 131, 108,
954
- /* 1090 */ 109, 110, 131, 130, 99, 17, 131, 99, 131, 130,
955
- /* 1100 */ 131, 131, 131, 108, 109, 110, 108, 109, 110, 99,
956
- /* 1110 */ 131, 130, 99, 131, 131, 131, 131, 131, 108, 109,
957
- /* 1120 */ 110, 108, 109, 110, 131, 130, 99, 131, 130, 131,
958
- /* 1130 */ 131, 131, 131, 131, 131, 108, 109, 110, 99, 131,
959
- /* 1140 */ 130, 131, 131, 130, 131, 131, 131, 108, 109, 110,
960
- /* 1150 */ 99, 131, 131, 99, 131, 131, 131, 130, 131, 108,
961
- /* 1160 */ 109, 110, 108, 109, 110, 99, 131, 131, 99, 130,
962
- /* 1170 */ 131, 131, 131, 131, 108, 109, 110, 108, 109, 110,
963
- /* 1180 */ 99, 130, 131, 131, 130, 131, 131, 131, 131, 108,
964
- /* 1190 */ 109, 110, 131, 99, 131, 131, 130, 99, 131, 130,
965
- /* 1200 */ 131, 131, 108, 109, 110, 99, 108, 109, 110, 99,
966
- /* 1210 */ 131, 130, 99, 131, 108, 109, 110, 131, 108, 109,
967
- /* 1220 */ 110, 108, 109, 110, 130, 131, 131, 131, 130, 131,
968
- /* 1230 */ 131, 131, 131, 131, 131, 131, 130, 131, 131, 131,
969
- /* 1240 */ 130, 131, 131, 130, 95, 95, 95, 95, 95, 95,
970
- /* 1250 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
971
- /* 1260 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
972
- /* 1270 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
973
- /* 1280 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
974
- /* 1290 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
975
- /* 1300 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
976
- /* 1310 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
977
- /* 1320 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
978
- /* 1330 */ 95, 95, 95, 95, 95, 95, 95, 95, 95,
866
+ /* 60 */ 60, 61, 62, 0, 4, 5, 6, 7, 8, 104,
867
+ /* 70 */ 101, 25, 103, 10, 110, 111, 112, 108, 109, 110,
868
+ /* 80 */ 111, 112, 103, 20, 21, 22, 17, 24, 110, 111,
869
+ /* 90 */ 112, 28, 26, 27, 25, 123, 33, 34, 35, 36,
870
+ /* 100 */ 37, 132, 39, 40, 41, 42, 12, 44, 45, 130,
871
+ /* 110 */ 2, 125, 49, 50, 51, 52, 53, 54, 55, 56,
872
+ /* 120 */ 57, 58, 59, 60, 61, 62, 1, 2, 2, 4,
873
+ /* 130 */ 5, 29, 30, 31, 32, 26, 27, 12, 126, 1,
874
+ /* 140 */ 15, 102, 4, 5, 105, 106, 38, 81, 0, 24,
875
+ /* 150 */ 12, 26, 27, 15, 88, 113, 31, 32, 10, 1,
876
+ /* 160 */ 2, 113, 4, 5, 38, 19, 127, 128, 129, 1,
877
+ /* 170 */ 12, 17, 1, 15, 80, 4, 5, 48, 20, 21,
878
+ /* 180 */ 22, 16, 88, 12, 46, 47, 15, 3, 63, 31,
879
+ /* 190 */ 32, 15, 1, 2, 43, 4, 5, 88, 4, 5,
880
+ /* 200 */ 6, 7, 40, 12, 40, 80, 15, 82, 83, 84,
881
+ /* 210 */ 85, 17, 13, 88, 89, 90, 91, 92, 80, 25,
882
+ /* 220 */ 41, 63, 31, 32, 101, 96, 88, 89, 90, 91,
883
+ /* 230 */ 92, 4, 5, 110, 111, 112, 41, 114, 80, 47,
884
+ /* 240 */ 82, 83, 84, 85, 121, 122, 88, 89, 90, 91,
885
+ /* 250 */ 92, 80, 17, 1, 63, 132, 4, 5, 25, 88,
886
+ /* 260 */ 89, 90, 91, 92, 12, 26, 27, 15, 94, 95,
887
+ /* 270 */ 86, 80, 17, 82, 83, 84, 85, 26, 27, 88,
888
+ /* 280 */ 89, 90, 91, 92, 2, 3, 4, 5, 6, 7,
889
+ /* 290 */ 73, 4, 5, 6, 7, 6, 7, 78, 16, 77,
890
+ /* 300 */ 79, 2, 3, 4, 5, 6, 7, 25, 4, 5,
891
+ /* 310 */ 6, 7, 78, 31, 32, 1, 17, 38, 4, 5,
892
+ /* 320 */ 38, 17, 35, 3, 25, 3, 12, 3, 3, 15,
893
+ /* 330 */ 31, 32, 80, 3, 20, 21, 22, 38, 24, 3,
894
+ /* 340 */ 88, 89, 90, 91, 92, 98, 99, 100, 66, 67,
895
+ /* 350 */ 93, 104, 75, 25, 15, 15, 74, 15, 76, 77,
896
+ /* 360 */ 78, 17, 115, 28, 12, 66, 67, 120, 87, 28,
897
+ /* 370 */ 3, 28, 11, 74, 133, 76, 77, 78, 2, 3,
898
+ /* 380 */ 4, 5, 6, 7, 63, 64, 65, 66, 67, 68,
899
+ /* 390 */ 69, 70, 71, 72, 80, 133, 133, 4, 5, 6,
900
+ /* 400 */ 7, 25, 88, 89, 90, 91, 92, 31, 32, 1,
901
+ /* 410 */ 17, 133, 133, 133, 38, 133, 133, 133, 25, 133,
902
+ /* 420 */ 12, 133, 14, 133, 133, 133, 18, 133, 20, 21,
903
+ /* 430 */ 22, 23, 24, 133, 26, 27, 133, 29, 30, 31,
904
+ /* 440 */ 32, 133, 66, 67, 1, 133, 133, 4, 5, 133,
905
+ /* 450 */ 74, 133, 76, 77, 78, 12, 133, 133, 15, 133,
906
+ /* 460 */ 133, 133, 133, 20, 21, 22, 1, 2, 133, 4,
907
+ /* 470 */ 5, 1, 2, 133, 4, 5, 133, 12, 133, 48,
908
+ /* 480 */ 15, 133, 12, 133, 133, 15, 133, 1, 2, 133,
909
+ /* 490 */ 4, 5, 133, 1, 133, 133, 4, 5, 12, 133,
910
+ /* 500 */ 133, 15, 133, 38, 12, 101, 1, 15, 133, 4,
911
+ /* 510 */ 5, 133, 133, 133, 110, 111, 112, 12, 87, 133,
912
+ /* 520 */ 15, 117, 133, 80, 93, 133, 133, 96, 124, 133,
913
+ /* 530 */ 126, 88, 89, 90, 91, 92, 132, 101, 4, 5,
914
+ /* 540 */ 6, 7, 133, 133, 133, 80, 110, 111, 112, 133,
915
+ /* 550 */ 80, 133, 133, 88, 89, 90, 91, 92, 88, 89,
916
+ /* 560 */ 90, 91, 92, 133, 133, 133, 80, 133, 132, 35,
917
+ /* 570 */ 133, 133, 80, 133, 88, 89, 90, 91, 92, 2,
918
+ /* 580 */ 88, 89, 90, 91, 92, 80, 133, 20, 21, 22,
919
+ /* 590 */ 133, 133, 101, 88, 89, 90, 91, 92, 133, 133,
920
+ /* 600 */ 133, 110, 111, 112, 97, 98, 99, 100, 31, 32,
921
+ /* 610 */ 133, 104, 4, 5, 6, 7, 49, 50, 51, 52,
922
+ /* 620 */ 53, 54, 115, 132, 133, 48, 119, 120, 97, 98,
923
+ /* 630 */ 99, 100, 133, 25, 101, 104, 103, 133, 133, 133,
924
+ /* 640 */ 63, 108, 109, 110, 111, 112, 115, 101, 133, 103,
925
+ /* 650 */ 133, 120, 2, 133, 108, 109, 110, 111, 112, 82,
926
+ /* 660 */ 83, 84, 85, 133, 101, 132, 103, 4, 5, 6,
927
+ /* 670 */ 7, 108, 109, 110, 111, 112, 133, 101, 132, 103,
928
+ /* 680 */ 17, 31, 32, 133, 108, 109, 110, 111, 112, 101,
929
+ /* 690 */ 133, 103, 133, 133, 101, 132, 108, 109, 110, 111,
930
+ /* 700 */ 112, 133, 133, 110, 111, 112, 133, 101, 132, 103,
931
+ /* 710 */ 133, 133, 133, 63, 108, 109, 110, 111, 112, 101,
932
+ /* 720 */ 132, 103, 133, 133, 133, 132, 108, 109, 110, 111,
933
+ /* 730 */ 112, 101, 82, 83, 84, 85, 133, 133, 132, 133,
934
+ /* 740 */ 110, 111, 112, 133, 101, 133, 103, 117, 118, 133,
935
+ /* 750 */ 132, 108, 109, 110, 111, 112, 101, 133, 103, 101,
936
+ /* 760 */ 133, 133, 132, 108, 109, 110, 111, 112, 110, 111,
937
+ /* 770 */ 112, 133, 114, 133, 101, 132, 103, 133, 133, 133,
938
+ /* 780 */ 122, 108, 109, 110, 111, 112, 101, 132, 103, 133,
939
+ /* 790 */ 132, 133, 133, 108, 109, 110, 111, 112, 133, 101,
940
+ /* 800 */ 133, 103, 133, 133, 133, 132, 108, 109, 110, 111,
941
+ /* 810 */ 112, 101, 133, 103, 133, 133, 101, 132, 108, 109,
942
+ /* 820 */ 110, 111, 112, 133, 133, 110, 111, 112, 133, 101,
943
+ /* 830 */ 132, 103, 117, 118, 133, 133, 108, 109, 110, 111,
944
+ /* 840 */ 112, 133, 132, 133, 133, 133, 101, 132, 103, 133,
945
+ /* 850 */ 133, 133, 101, 108, 109, 110, 111, 112, 133, 133,
946
+ /* 860 */ 132, 110, 111, 112, 133, 101, 133, 103, 117, 133,
947
+ /* 870 */ 133, 133, 108, 109, 110, 111, 112, 132, 101, 133,
948
+ /* 880 */ 103, 133, 133, 132, 133, 108, 109, 110, 111, 112,
949
+ /* 890 */ 101, 133, 103, 133, 133, 133, 132, 108, 109, 110,
950
+ /* 900 */ 111, 112, 133, 101, 133, 103, 133, 133, 133, 132,
951
+ /* 910 */ 108, 109, 110, 111, 112, 101, 133, 103, 101, 133,
952
+ /* 920 */ 133, 132, 108, 109, 110, 111, 112, 110, 111, 112,
953
+ /* 930 */ 133, 101, 133, 103, 132, 133, 133, 133, 108, 109,
954
+ /* 940 */ 110, 111, 112, 133, 133, 133, 132, 133, 101, 132,
955
+ /* 950 */ 103, 133, 133, 133, 101, 108, 109, 110, 111, 112,
956
+ /* 960 */ 133, 133, 132, 110, 111, 112, 133, 101, 133, 103,
957
+ /* 970 */ 4, 5, 6, 7, 108, 109, 110, 111, 112, 132,
958
+ /* 980 */ 101, 133, 103, 17, 133, 132, 133, 108, 109, 110,
959
+ /* 990 */ 111, 112, 101, 4, 5, 6, 7, 133, 132, 133,
960
+ /* 1000 */ 133, 110, 111, 112, 133, 101, 17, 116, 117, 118,
961
+ /* 1010 */ 133, 132, 133, 133, 110, 111, 112, 101, 114, 4,
962
+ /* 1020 */ 5, 6, 7, 132, 101, 133, 110, 111, 112, 101,
963
+ /* 1030 */ 114, 133, 17, 110, 111, 112, 132, 133, 110, 111,
964
+ /* 1040 */ 112, 101, 133, 133, 4, 5, 6, 7, 132, 133,
965
+ /* 1050 */ 110, 111, 112, 133, 133, 132, 101, 17, 133, 101,
966
+ /* 1060 */ 132, 133, 133, 133, 101, 110, 111, 112, 110, 111,
967
+ /* 1070 */ 112, 101, 132, 110, 111, 112, 133, 133, 133, 133,
968
+ /* 1080 */ 110, 111, 112, 133, 133, 133, 133, 132, 133, 101,
969
+ /* 1090 */ 132, 133, 133, 133, 101, 132, 133, 133, 110, 111,
970
+ /* 1100 */ 112, 133, 132, 110, 111, 112, 133, 101, 133, 133,
971
+ /* 1110 */ 133, 133, 133, 101, 133, 133, 110, 111, 112, 101,
972
+ /* 1120 */ 132, 133, 110, 111, 112, 132, 101, 133, 110, 111,
973
+ /* 1130 */ 112, 101, 133, 133, 133, 110, 111, 112, 132, 133,
974
+ /* 1140 */ 110, 111, 112, 101, 132, 133, 133, 133, 133, 133,
975
+ /* 1150 */ 132, 133, 110, 111, 112, 133, 133, 132, 101, 133,
976
+ /* 1160 */ 133, 101, 132, 133, 133, 133, 101, 110, 111, 112,
977
+ /* 1170 */ 110, 111, 112, 101, 132, 110, 111, 112, 4, 5,
978
+ /* 1180 */ 6, 7, 110, 111, 112, 4, 5, 6, 7, 132,
979
+ /* 1190 */ 133, 101, 132, 133, 133, 133, 133, 132, 133, 25,
980
+ /* 1200 */ 110, 111, 112, 133, 132, 133, 25, 133, 133, 133,
981
+ /* 1210 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
982
+ /* 1220 */ 133, 133, 132, 133, 133, 133, 133, 133, 133, 133,
983
+ /* 1230 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
984
+ /* 1240 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
985
+ /* 1250 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
986
+ /* 1260 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
987
+ /* 1270 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
988
+ /* 1280 */ 133, 133, 133, 97, 97, 97, 97, 97, 97, 97,
989
+ /* 1290 */ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
990
+ /* 1300 */ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
991
+ /* 1310 */ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
979992
};
980
-#define YY_SHIFT_COUNT (161)
993
+#define YY_SHIFT_COUNT (163)
981994
#define YY_SHIFT_MIN (0)
982
-#define YY_SHIFT_MAX (1078)
995
+#define YY_SHIFT_MAX (1181)
983996
static const unsigned short int yy_shift_ofst[] = {
984
- /* 0 */ 399, 121, 137, 227, 227, 227, 227, 227, 227, 227,
985
- /* 10 */ 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
986
- /* 20 */ 227, 227, 227, 227, 227, 227, 227, 157, 434, 476,
987
- /* 30 */ 157, 399, 376, 376, 0, 61, 399, 489, 476, 489,
988
- /* 40 */ 264, 264, 264, 455, 471, 476, 476, 476, 476, 476,
989
- /* 50 */ 476, 494, 476, 476, 513, 476, 476, 476, 476, 476,
990
- /* 60 */ 476, 476, 476, 476, 476, 567, 62, 62, 62, 62,
991
- /* 70 */ 62, 220, 257, 332, 369, 265, 265, 336, 22, 1244,
992
- /* 80 */ 1244, 1244, 1244, 122, 122, 378, 957, 58, 123, 285,
993
- /* 90 */ 292, 352, 23, 632, 247, 1017, 525, 530, 1078, 564,
994
- /* 100 */ 564, 564, 357, 564, 564, 564, 460, 564, 303, 60,
995
- /* 110 */ 88, 132, 68, 4, 67, 147, 147, 156, 169, 94,
996
- /* 120 */ 154, 1, 120, 131, 129, 130, 167, 168, 177, 182,
997
- /* 130 */ 185, 221, 216, 217, 170, 238, 195, 183, 197, 196,
998
- /* 140 */ 272, 274, 275, 249, 301, 308, 309, 215, 246, 297,
999
- /* 150 */ 215, 315, 326, 328, 306, 298, 314, 318, 348, 282,
1000
- /* 160 */ 367, 368,
997
+ /* 0 */ 408, 125, 158, 191, 191, 191, 191, 191, 191, 191,
998
+ /* 10 */ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
999
+ /* 20 */ 191, 191, 191, 191, 191, 191, 191, 314, 138, 171,
1000
+ /* 30 */ 314, 408, 465, 465, 0, 63, 408, 252, 171, 252,
1001
+ /* 40 */ 443, 443, 443, 470, 486, 171, 171, 171, 171, 171,
1002
+ /* 50 */ 171, 492, 171, 171, 505, 171, 171, 171, 171, 171,
1003
+ /* 60 */ 171, 171, 171, 171, 171, 567, 94, 94, 94, 94,
1004
+ /* 70 */ 94, 577, 282, 299, 376, 650, 650, 102, 46, 1223,
1005
+ /* 80 */ 1223, 1223, 1223, 321, 321, 194, 393, 304, 60, 287,
1006
+ /* 90 */ 534, 663, 608, 966, 1174, 989, 1181, 1015, 1040, 25,
1007
+ /* 100 */ 25, 25, 431, 25, 25, 25, 66, 25, 109, 15,
1008
+ /* 110 */ 108, 126, 69, 227, 174, 289, 289, 239, 251, 184,
1009
+ /* 120 */ 129, 148, 146, 168, 154, 165, 176, 151, 162, 164,
1010
+ /* 130 */ 179, 195, 192, 199, 235, 233, 217, 255, 219, 222,
1011
+ /* 140 */ 221, 234, 320, 322, 324, 279, 325, 330, 336, 257,
1012
+ /* 150 */ 277, 328, 257, 339, 340, 342, 344, 335, 341, 343,
1013
+ /* 160 */ 352, 281, 367, 361,
10011014
};
10021015
#define YY_REDUCE_COUNT (82)
10031016
#define YY_REDUCE_MIN (-127)
1004
-#define YY_REDUCE_MAX (1113)
1017
+#define YY_REDUCE_MAX (1090)
10051018
static const short yy_reduce_ofst[] = {
1006
- /* 0 */ -29, -94, 521, 534, 546, 559, 573, 585, 600, 615,
1007
- /* 10 */ 628, 641, 653, 666, 680, 692, 707, 722, 735, 748,
1008
- /* 20 */ 760, 773, 787, 799, 814, 829, 842, 846, 496, 869,
1009
- /* 30 */ 895, 914, 603, 710, 70, 70, 334, 802, 887, 921,
1010
- /* 40 */ 817, 927, 939, 944, 951, 956, 963, 969, 981, 995,
1011
- /* 50 */ 998, 1010, 1013, 1027, 1039, 1051, 1054, 1066, 1069, 1081,
1012
- /* 60 */ 1094, 1098, 1106, 1110, 1113, -79, -32, -3, 55, 104,
1013
- /* 70 */ 128, -84, -127, -127, -127, -95, -78, -61, -49, -41,
1014
- /* 80 */ -9, 21, 11,
1019
+ /* 0 */ 507, -94, -31, 533, 546, 563, 576, 588, 606, 618,
1020
+ /* 10 */ 643, 655, 673, 685, 698, 710, 728, 745, 764, 777,
1021
+ /* 20 */ 789, 802, 814, 830, 847, 866, 879, 123, 891, 404,
1022
+ /* 30 */ 658, 531, 630, 715, 39, 39, 247, 904, 751, 916,
1023
+ /* 40 */ 436, 491, 593, 817, 853, 923, 928, 940, 955, 958,
1024
+ /* 50 */ 963, 970, 988, 993, 1006, 1012, 1018, 1025, 1030, 1042,
1025
+ /* 60 */ 1057, 1060, 1065, 1072, 1090, -79, -109, -99, -64, -36,
1026
+ /* 70 */ -22, -21, -127, -127, -127, -95, -84, -35, -28, -14,
1027
+ /* 80 */ 42, 48, 12,
10151028
};
10161029
static const YYACTIONTYPE yy_default[] = {
1017
- /* 0 */ 441, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1018
- /* 10 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1019
- /* 20 */ 435, 435, 435, 435, 435, 435, 435, 435, 464, 565,
1020
- /* 30 */ 435, 441, 569, 476, 570, 570, 441, 435, 435, 435,
1021
- /* 40 */ 435, 435, 435, 435, 435, 435, 435, 435, 468, 435,
1022
- /* 50 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1023
- /* 60 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1024
- /* 70 */ 435, 435, 435, 435, 435, 435, 435, 435, 447, 461,
1025
- /* 80 */ 498, 498, 565, 459, 484, 435, 435, 435, 462, 435,
1026
- /* 90 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 479,
1027
- /* 100 */ 477, 467, 450, 502, 501, 500, 435, 555, 435, 435,
1028
- /* 110 */ 435, 435, 435, 577, 435, 534, 533, 529, 435, 522,
1029
- /* 120 */ 519, 435, 435, 435, 435, 482, 435, 435, 435, 435,
1030
- /* 130 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1031
- /* 140 */ 435, 435, 435, 435, 435, 435, 435, 581, 435, 435,
1032
- /* 150 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 590,
1033
- /* 160 */ 435, 435,
1030
+ /* 0 */ 445, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1031
+ /* 10 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1032
+ /* 20 */ 439, 439, 439, 439, 439, 439, 439, 439, 469, 570,
1033
+ /* 30 */ 439, 445, 574, 481, 575, 575, 445, 439, 439, 439,
1034
+ /* 40 */ 439, 439, 439, 439, 439, 439, 439, 439, 473, 439,
1035
+ /* 50 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1036
+ /* 60 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1037
+ /* 70 */ 439, 439, 439, 439, 439, 439, 439, 439, 451, 466,
1038
+ /* 80 */ 503, 503, 570, 464, 489, 439, 439, 439, 467, 439,
1039
+ /* 90 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 484,
1040
+ /* 100 */ 482, 472, 455, 507, 506, 505, 439, 560, 439, 439,
1041
+ /* 110 */ 439, 439, 439, 582, 439, 539, 538, 534, 439, 527,
1042
+ /* 120 */ 524, 439, 439, 439, 439, 439, 439, 487, 439, 439,
1043
+ /* 130 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1044
+ /* 140 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 586,
1045
+ /* 150 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1046
+ /* 160 */ 439, 595, 439, 439,
10341047
};
10351048
/********** End of lemon-generated parsing tables *****************************/
10361049
10371050
/* The next table maps tokens (terminal symbols) into fallback tokens.
10381051
** If a construct like the following:
@@ -1066,10 +1079,12 @@
10661079
0, /* COLON => nothing */
10671080
0, /* ASSERT => nothing */
10681081
0, /* LP => nothing */
10691082
0, /* EQ => nothing */
10701083
0, /* RP => nothing */
1084
+ 0, /* DEFINE => nothing */
1085
+ 0, /* CODEBLOCK => nothing */
10711086
0, /* FILL => nothing */
10721087
0, /* COLOR => nothing */
10731088
0, /* THICKNESS => nothing */
10741089
0, /* PRINT => nothing */
10751090
0, /* STRING => nothing */
@@ -1249,283 +1264,286 @@
12491264
/* 13 */ "COLON",
12501265
/* 14 */ "ASSERT",
12511266
/* 15 */ "LP",
12521267
/* 16 */ "EQ",
12531268
/* 17 */ "RP",
1254
- /* 18 */ "FILL",
1255
- /* 19 */ "COLOR",
1256
- /* 20 */ "THICKNESS",
1257
- /* 21 */ "PRINT",
1258
- /* 22 */ "STRING",
1259
- /* 23 */ "COMMA",
1260
- /* 24 */ "CLASSNAME",
1261
- /* 25 */ "LB",
1262
- /* 26 */ "RB",
1263
- /* 27 */ "UP",
1264
- /* 28 */ "DOWN",
1265
- /* 29 */ "LEFT",
1266
- /* 30 */ "RIGHT",
1267
- /* 31 */ "CLOSE",
1268
- /* 32 */ "CHOP",
1269
- /* 33 */ "FROM",
1270
- /* 34 */ "TO",
1271
- /* 35 */ "THEN",
1272
- /* 36 */ "HEADING",
1273
- /* 37 */ "GO",
1274
- /* 38 */ "AT",
1275
- /* 39 */ "WITH",
1276
- /* 40 */ "SAME",
1277
- /* 41 */ "AS",
1278
- /* 42 */ "FIT",
1279
- /* 43 */ "BEHIND",
1280
- /* 44 */ "UNTIL",
1281
- /* 45 */ "EVEN",
1282
- /* 46 */ "DOT_E",
1283
- /* 47 */ "HEIGHT",
1284
- /* 48 */ "WIDTH",
1285
- /* 49 */ "RADIUS",
1286
- /* 50 */ "DIAMETER",
1287
- /* 51 */ "DOTTED",
1288
- /* 52 */ "DASHED",
1289
- /* 53 */ "CW",
1290
- /* 54 */ "CCW",
1291
- /* 55 */ "LARROW",
1292
- /* 56 */ "RARROW",
1293
- /* 57 */ "LRARROW",
1294
- /* 58 */ "INVIS",
1295
- /* 59 */ "THICK",
1296
- /* 60 */ "THIN",
1297
- /* 61 */ "CENTER",
1298
- /* 62 */ "LJUST",
1299
- /* 63 */ "RJUST",
1300
- /* 64 */ "ABOVE",
1301
- /* 65 */ "BELOW",
1302
- /* 66 */ "ITALIC",
1303
- /* 67 */ "BOLD",
1304
- /* 68 */ "ALIGNED",
1305
- /* 69 */ "BIG",
1306
- /* 70 */ "SMALL",
1307
- /* 71 */ "AND",
1308
- /* 72 */ "LT",
1309
- /* 73 */ "GT",
1310
- /* 74 */ "ON",
1311
- /* 75 */ "WAY",
1312
- /* 76 */ "BETWEEN",
1313
- /* 77 */ "THE",
1314
- /* 78 */ "NTH",
1315
- /* 79 */ "VERTEX",
1316
- /* 80 */ "TOP",
1317
- /* 81 */ "BOTTOM",
1318
- /* 82 */ "START",
1319
- /* 83 */ "END",
1320
- /* 84 */ "IN",
1321
- /* 85 */ "DOT_U",
1322
- /* 86 */ "LAST",
1323
- /* 87 */ "NUMBER",
1324
- /* 88 */ "FUNC1",
1325
- /* 89 */ "FUNC2",
1326
- /* 90 */ "DIST",
1327
- /* 91 */ "DOT_XY",
1328
- /* 92 */ "X",
1329
- /* 93 */ "Y",
1330
- /* 94 */ "DOT_L",
1331
- /* 95 */ "element_list",
1332
- /* 96 */ "element",
1333
- /* 97 */ "unnamed_element",
1334
- /* 98 */ "basetype",
1335
- /* 99 */ "expr",
1336
- /* 100 */ "numproperty",
1337
- /* 101 */ "edge",
1338
- /* 102 */ "direction",
1339
- /* 103 */ "dashproperty",
1340
- /* 104 */ "colorproperty",
1341
- /* 105 */ "locproperty",
1342
- /* 106 */ "position",
1343
- /* 107 */ "place",
1344
- /* 108 */ "object",
1345
- /* 109 */ "objectname",
1346
- /* 110 */ "nth",
1347
- /* 111 */ "textposition",
1348
- /* 112 */ "rvalue",
1349
- /* 113 */ "lvalue",
1350
- /* 114 */ "even",
1351
- /* 115 */ "relexpr",
1352
- /* 116 */ "optrelexpr",
1353
- /* 117 */ "document",
1354
- /* 118 */ "print",
1355
- /* 119 */ "prlist",
1356
- /* 120 */ "pritem",
1357
- /* 121 */ "prsep",
1358
- /* 122 */ "attribute_list",
1359
- /* 123 */ "savelist",
1360
- /* 124 */ "alist",
1361
- /* 125 */ "attribute",
1362
- /* 126 */ "go",
1363
- /* 127 */ "boolproperty",
1364
- /* 128 */ "withclause",
1365
- /* 129 */ "between",
1366
- /* 130 */ "place2",
1269
+ /* 18 */ "DEFINE",
1270
+ /* 19 */ "CODEBLOCK",
1271
+ /* 20 */ "FILL",
1272
+ /* 21 */ "COLOR",
1273
+ /* 22 */ "THICKNESS",
1274
+ /* 23 */ "PRINT",
1275
+ /* 24 */ "STRING",
1276
+ /* 25 */ "COMMA",
1277
+ /* 26 */ "CLASSNAME",
1278
+ /* 27 */ "LB",
1279
+ /* 28 */ "RB",
1280
+ /* 29 */ "UP",
1281
+ /* 30 */ "DOWN",
1282
+ /* 31 */ "LEFT",
1283
+ /* 32 */ "RIGHT",
1284
+ /* 33 */ "CLOSE",
1285
+ /* 34 */ "CHOP",
1286
+ /* 35 */ "FROM",
1287
+ /* 36 */ "TO",
1288
+ /* 37 */ "THEN",
1289
+ /* 38 */ "HEADING",
1290
+ /* 39 */ "GO",
1291
+ /* 40 */ "AT",
1292
+ /* 41 */ "WITH",
1293
+ /* 42 */ "SAME",
1294
+ /* 43 */ "AS",
1295
+ /* 44 */ "FIT",
1296
+ /* 45 */ "BEHIND",
1297
+ /* 46 */ "UNTIL",
1298
+ /* 47 */ "EVEN",
1299
+ /* 48 */ "DOT_E",
1300
+ /* 49 */ "HEIGHT",
1301
+ /* 50 */ "WIDTH",
1302
+ /* 51 */ "RADIUS",
1303
+ /* 52 */ "DIAMETER",
1304
+ /* 53 */ "DOTTED",
1305
+ /* 54 */ "DASHED",
1306
+ /* 55 */ "CW",
1307
+ /* 56 */ "CCW",
1308
+ /* 57 */ "LARROW",
1309
+ /* 58 */ "RARROW",
1310
+ /* 59 */ "LRARROW",
1311
+ /* 60 */ "INVIS",
1312
+ /* 61 */ "THICK",
1313
+ /* 62 */ "THIN",
1314
+ /* 63 */ "CENTER",
1315
+ /* 64 */ "LJUST",
1316
+ /* 65 */ "RJUST",
1317
+ /* 66 */ "ABOVE",
1318
+ /* 67 */ "BELOW",
1319
+ /* 68 */ "ITALIC",
1320
+ /* 69 */ "BOLD",
1321
+ /* 70 */ "ALIGNED",
1322
+ /* 71 */ "BIG",
1323
+ /* 72 */ "SMALL",
1324
+ /* 73 */ "AND",
1325
+ /* 74 */ "LT",
1326
+ /* 75 */ "GT",
1327
+ /* 76 */ "ON",
1328
+ /* 77 */ "WAY",
1329
+ /* 78 */ "BETWEEN",
1330
+ /* 79 */ "THE",
1331
+ /* 80 */ "NTH",
1332
+ /* 81 */ "VERTEX",
1333
+ /* 82 */ "TOP",
1334
+ /* 83 */ "BOTTOM",
1335
+ /* 84 */ "START",
1336
+ /* 85 */ "END",
1337
+ /* 86 */ "IN",
1338
+ /* 87 */ "DOT_U",
1339
+ /* 88 */ "LAST",
1340
+ /* 89 */ "NUMBER",
1341
+ /* 90 */ "FUNC1",
1342
+ /* 91 */ "FUNC2",
1343
+ /* 92 */ "DIST",
1344
+ /* 93 */ "DOT_XY",
1345
+ /* 94 */ "X",
1346
+ /* 95 */ "Y",
1347
+ /* 96 */ "DOT_L",
1348
+ /* 97 */ "statement_list",
1349
+ /* 98 */ "statement",
1350
+ /* 99 */ "unnamed_statement",
1351
+ /* 100 */ "basetype",
1352
+ /* 101 */ "expr",
1353
+ /* 102 */ "numproperty",
1354
+ /* 103 */ "edge",
1355
+ /* 104 */ "direction",
1356
+ /* 105 */ "dashproperty",
1357
+ /* 106 */ "colorproperty",
1358
+ /* 107 */ "locproperty",
1359
+ /* 108 */ "position",
1360
+ /* 109 */ "place",
1361
+ /* 110 */ "object",
1362
+ /* 111 */ "objectname",
1363
+ /* 112 */ "nth",
1364
+ /* 113 */ "textposition",
1365
+ /* 114 */ "rvalue",
1366
+ /* 115 */ "lvalue",
1367
+ /* 116 */ "even",
1368
+ /* 117 */ "relexpr",
1369
+ /* 118 */ "optrelexpr",
1370
+ /* 119 */ "document",
1371
+ /* 120 */ "print",
1372
+ /* 121 */ "prlist",
1373
+ /* 122 */ "pritem",
1374
+ /* 123 */ "prsep",
1375
+ /* 124 */ "attribute_list",
1376
+ /* 125 */ "savelist",
1377
+ /* 126 */ "alist",
1378
+ /* 127 */ "attribute",
1379
+ /* 128 */ "go",
1380
+ /* 129 */ "boolproperty",
1381
+ /* 130 */ "withclause",
1382
+ /* 131 */ "between",
1383
+ /* 132 */ "place2",
13671384
};
13681385
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
13691386
13701387
#ifndef NDEBUG
13711388
/* For tracing reduce actions, the names of all rules are required.
13721389
*/
13731390
static const char *const yyRuleName[] = {
1374
- /* 0 */ "document ::= element_list",
1375
- /* 1 */ "element_list ::= element",
1376
- /* 2 */ "element_list ::= element_list EOL element",
1377
- /* 3 */ "element ::=",
1378
- /* 4 */ "element ::= direction",
1379
- /* 5 */ "element ::= lvalue ASSIGN rvalue",
1380
- /* 6 */ "element ::= PLACENAME COLON unnamed_element",
1381
- /* 7 */ "element ::= PLACENAME COLON position",
1382
- /* 8 */ "element ::= unnamed_element",
1383
- /* 9 */ "element ::= print prlist",
1384
- /* 10 */ "element ::= ASSERT LP expr EQ expr RP",
1385
- /* 11 */ "element ::= ASSERT LP position EQ position RP",
1386
- /* 12 */ "rvalue ::= PLACENAME",
1387
- /* 13 */ "pritem ::= FILL",
1388
- /* 14 */ "pritem ::= COLOR",
1389
- /* 15 */ "pritem ::= THICKNESS",
1390
- /* 16 */ "pritem ::= rvalue",
1391
- /* 17 */ "pritem ::= STRING",
1392
- /* 18 */ "prsep ::= COMMA",
1393
- /* 19 */ "unnamed_element ::= basetype attribute_list",
1394
- /* 20 */ "basetype ::= CLASSNAME",
1395
- /* 21 */ "basetype ::= STRING textposition",
1396
- /* 22 */ "basetype ::= LB savelist element_list RB",
1397
- /* 23 */ "savelist ::=",
1398
- /* 24 */ "relexpr ::= expr",
1399
- /* 25 */ "relexpr ::= expr PERCENT",
1400
- /* 26 */ "optrelexpr ::=",
1401
- /* 27 */ "attribute_list ::= relexpr alist",
1402
- /* 28 */ "attribute ::= numproperty relexpr",
1403
- /* 29 */ "attribute ::= dashproperty expr",
1404
- /* 30 */ "attribute ::= dashproperty",
1405
- /* 31 */ "attribute ::= colorproperty rvalue",
1406
- /* 32 */ "attribute ::= go direction optrelexpr",
1407
- /* 33 */ "attribute ::= go direction even position",
1408
- /* 34 */ "attribute ::= CLOSE",
1409
- /* 35 */ "attribute ::= CHOP",
1410
- /* 36 */ "attribute ::= FROM position",
1411
- /* 37 */ "attribute ::= TO position",
1412
- /* 38 */ "attribute ::= THEN",
1413
- /* 39 */ "attribute ::= THEN optrelexpr HEADING expr",
1414
- /* 40 */ "attribute ::= THEN optrelexpr EDGEPT",
1415
- /* 41 */ "attribute ::= GO optrelexpr HEADING expr",
1416
- /* 42 */ "attribute ::= GO optrelexpr EDGEPT",
1417
- /* 43 */ "attribute ::= AT position",
1418
- /* 44 */ "attribute ::= SAME",
1419
- /* 45 */ "attribute ::= SAME AS object",
1420
- /* 46 */ "attribute ::= STRING textposition",
1421
- /* 47 */ "attribute ::= FIT",
1422
- /* 48 */ "attribute ::= BEHIND object",
1423
- /* 49 */ "withclause ::= DOT_E edge AT position",
1424
- /* 50 */ "withclause ::= edge AT position",
1425
- /* 51 */ "numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS",
1426
- /* 52 */ "boolproperty ::= CW",
1427
- /* 53 */ "boolproperty ::= CCW",
1428
- /* 54 */ "boolproperty ::= LARROW",
1429
- /* 55 */ "boolproperty ::= RARROW",
1430
- /* 56 */ "boolproperty ::= LRARROW",
1431
- /* 57 */ "boolproperty ::= INVIS",
1432
- /* 58 */ "boolproperty ::= THICK",
1433
- /* 59 */ "boolproperty ::= THIN",
1434
- /* 60 */ "textposition ::=",
1435
- /* 61 */ "textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL",
1436
- /* 62 */ "position ::= expr COMMA expr",
1437
- /* 63 */ "position ::= place PLUS expr COMMA expr",
1438
- /* 64 */ "position ::= place MINUS expr COMMA expr",
1439
- /* 65 */ "position ::= place PLUS LP expr COMMA expr RP",
1440
- /* 66 */ "position ::= place MINUS LP expr COMMA expr RP",
1441
- /* 67 */ "position ::= LP position COMMA position RP",
1442
- /* 68 */ "position ::= LP position RP",
1443
- /* 69 */ "position ::= expr between position AND position",
1444
- /* 70 */ "position ::= expr LT position COMMA position GT",
1445
- /* 71 */ "position ::= expr ABOVE position",
1446
- /* 72 */ "position ::= expr BELOW position",
1447
- /* 73 */ "position ::= expr LEFT OF position",
1448
- /* 74 */ "position ::= expr RIGHT OF position",
1449
- /* 75 */ "position ::= expr ON HEADING EDGEPT OF position",
1450
- /* 76 */ "position ::= expr HEADING EDGEPT OF position",
1451
- /* 77 */ "position ::= expr EDGEPT OF position",
1452
- /* 78 */ "position ::= expr ON HEADING expr FROM position",
1453
- /* 79 */ "position ::= expr HEADING expr FROM position",
1454
- /* 80 */ "place ::= edge OF object",
1455
- /* 81 */ "place2 ::= object",
1456
- /* 82 */ "place2 ::= object DOT_E edge",
1457
- /* 83 */ "place2 ::= NTH VERTEX OF object",
1458
- /* 84 */ "object ::= nth",
1459
- /* 85 */ "object ::= nth OF|IN object",
1460
- /* 86 */ "objectname ::= PLACENAME",
1461
- /* 87 */ "objectname ::= objectname DOT_U PLACENAME",
1462
- /* 88 */ "nth ::= NTH CLASSNAME",
1463
- /* 89 */ "nth ::= NTH LAST CLASSNAME",
1464
- /* 90 */ "nth ::= LAST CLASSNAME",
1465
- /* 91 */ "nth ::= LAST",
1466
- /* 92 */ "nth ::= NTH LB RB",
1467
- /* 93 */ "nth ::= NTH LAST LB RB",
1468
- /* 94 */ "nth ::= LAST LB RB",
1469
- /* 95 */ "expr ::= expr PLUS expr",
1470
- /* 96 */ "expr ::= expr MINUS expr",
1471
- /* 97 */ "expr ::= expr STAR expr",
1472
- /* 98 */ "expr ::= expr SLASH expr",
1473
- /* 99 */ "expr ::= MINUS expr",
1474
- /* 100 */ "expr ::= PLUS expr",
1475
- /* 101 */ "expr ::= LP expr RP",
1476
- /* 102 */ "expr ::= LP FILL|COLOR|THICKNESS RP",
1477
- /* 103 */ "expr ::= NUMBER",
1478
- /* 104 */ "expr ::= ID",
1479
- /* 105 */ "expr ::= FUNC1 LP expr RP",
1480
- /* 106 */ "expr ::= FUNC2 LP expr COMMA expr RP",
1481
- /* 107 */ "expr ::= DIST LP position COMMA position RP",
1482
- /* 108 */ "expr ::= place2 DOT_XY X",
1483
- /* 109 */ "expr ::= place2 DOT_XY Y",
1484
- /* 110 */ "expr ::= object DOT_L numproperty",
1485
- /* 111 */ "expr ::= object DOT_L dashproperty",
1486
- /* 112 */ "expr ::= object DOT_L colorproperty",
1487
- /* 113 */ "lvalue ::= ID",
1488
- /* 114 */ "lvalue ::= FILL",
1489
- /* 115 */ "lvalue ::= COLOR",
1490
- /* 116 */ "lvalue ::= THICKNESS",
1491
- /* 117 */ "rvalue ::= expr",
1492
- /* 118 */ "print ::= PRINT",
1493
- /* 119 */ "prlist ::= pritem",
1494
- /* 120 */ "prlist ::= prlist prsep pritem",
1495
- /* 121 */ "direction ::= UP",
1496
- /* 122 */ "direction ::= DOWN",
1497
- /* 123 */ "direction ::= LEFT",
1498
- /* 124 */ "direction ::= RIGHT",
1499
- /* 125 */ "optrelexpr ::= relexpr",
1500
- /* 126 */ "attribute_list ::= alist",
1501
- /* 127 */ "alist ::=",
1502
- /* 128 */ "alist ::= alist attribute",
1503
- /* 129 */ "attribute ::= boolproperty",
1504
- /* 130 */ "attribute ::= WITH withclause",
1505
- /* 131 */ "go ::= GO",
1506
- /* 132 */ "go ::=",
1507
- /* 133 */ "even ::= UNTIL EVEN WITH",
1508
- /* 134 */ "even ::= EVEN WITH",
1509
- /* 135 */ "dashproperty ::= DOTTED",
1510
- /* 136 */ "dashproperty ::= DASHED",
1511
- /* 137 */ "colorproperty ::= FILL",
1512
- /* 138 */ "colorproperty ::= COLOR",
1513
- /* 139 */ "position ::= place",
1514
- /* 140 */ "between ::= WAY BETWEEN",
1515
- /* 141 */ "between ::= BETWEEN",
1516
- /* 142 */ "between ::= OF THE WAY BETWEEN",
1517
- /* 143 */ "place ::= place2",
1518
- /* 144 */ "edge ::= CENTER",
1519
- /* 145 */ "edge ::= EDGEPT",
1520
- /* 146 */ "edge ::= TOP",
1521
- /* 147 */ "edge ::= BOTTOM",
1522
- /* 148 */ "edge ::= START",
1523
- /* 149 */ "edge ::= END",
1524
- /* 150 */ "edge ::= RIGHT",
1525
- /* 151 */ "edge ::= LEFT",
1526
- /* 152 */ "object ::= objectname",
1391
+ /* 0 */ "document ::= statement_list",
1392
+ /* 1 */ "statement_list ::= statement",
1393
+ /* 2 */ "statement_list ::= statement_list EOL statement",
1394
+ /* 3 */ "statement ::=",
1395
+ /* 4 */ "statement ::= direction",
1396
+ /* 5 */ "statement ::= lvalue ASSIGN rvalue",
1397
+ /* 6 */ "statement ::= PLACENAME COLON unnamed_statement",
1398
+ /* 7 */ "statement ::= PLACENAME COLON position",
1399
+ /* 8 */ "statement ::= unnamed_statement",
1400
+ /* 9 */ "statement ::= print prlist",
1401
+ /* 10 */ "statement ::= ASSERT LP expr EQ expr RP",
1402
+ /* 11 */ "statement ::= ASSERT LP position EQ position RP",
1403
+ /* 12 */ "statement ::= DEFINE ID CODEBLOCK",
1404
+ /* 13 */ "rvalue ::= PLACENAME",
1405
+ /* 14 */ "pritem ::= FILL",
1406
+ /* 15 */ "pritem ::= COLOR",
1407
+ /* 16 */ "pritem ::= THICKNESS",
1408
+ /* 17 */ "pritem ::= rvalue",
1409
+ /* 18 */ "pritem ::= STRING",
1410
+ /* 19 */ "prsep ::= COMMA",
1411
+ /* 20 */ "unnamed_statement ::= basetype attribute_list",
1412
+ /* 21 */ "basetype ::= CLASSNAME",
1413
+ /* 22 */ "basetype ::= STRING textposition",
1414
+ /* 23 */ "basetype ::= LB savelist statement_list RB",
1415
+ /* 24 */ "savelist ::=",
1416
+ /* 25 */ "relexpr ::= expr",
1417
+ /* 26 */ "relexpr ::= expr PERCENT",
1418
+ /* 27 */ "optrelexpr ::=",
1419
+ /* 28 */ "attribute_list ::= relexpr alist",
1420
+ /* 29 */ "attribute ::= numproperty relexpr",
1421
+ /* 30 */ "attribute ::= dashproperty expr",
1422
+ /* 31 */ "attribute ::= dashproperty",
1423
+ /* 32 */ "attribute ::= colorproperty rvalue",
1424
+ /* 33 */ "attribute ::= go direction optrelexpr",
1425
+ /* 34 */ "attribute ::= go direction even position",
1426
+ /* 35 */ "attribute ::= CLOSE",
1427
+ /* 36 */ "attribute ::= CHOP",
1428
+ /* 37 */ "attribute ::= FROM position",
1429
+ /* 38 */ "attribute ::= TO position",
1430
+ /* 39 */ "attribute ::= THEN",
1431
+ /* 40 */ "attribute ::= THEN optrelexpr HEADING expr",
1432
+ /* 41 */ "attribute ::= THEN optrelexpr EDGEPT",
1433
+ /* 42 */ "attribute ::= GO optrelexpr HEADING expr",
1434
+ /* 43 */ "attribute ::= GO optrelexpr EDGEPT",
1435
+ /* 44 */ "attribute ::= AT position",
1436
+ /* 45 */ "attribute ::= SAME",
1437
+ /* 46 */ "attribute ::= SAME AS object",
1438
+ /* 47 */ "attribute ::= STRING textposition",
1439
+ /* 48 */ "attribute ::= FIT",
1440
+ /* 49 */ "attribute ::= BEHIND object",
1441
+ /* 50 */ "withclause ::= DOT_E edge AT position",
1442
+ /* 51 */ "withclause ::= edge AT position",
1443
+ /* 52 */ "numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS",
1444
+ /* 53 */ "boolproperty ::= CW",
1445
+ /* 54 */ "boolproperty ::= CCW",
1446
+ /* 55 */ "boolproperty ::= LARROW",
1447
+ /* 56 */ "boolproperty ::= RARROW",
1448
+ /* 57 */ "boolproperty ::= LRARROW",
1449
+ /* 58 */ "boolproperty ::= INVIS",
1450
+ /* 59 */ "boolproperty ::= THICK",
1451
+ /* 60 */ "boolproperty ::= THIN",
1452
+ /* 61 */ "textposition ::=",
1453
+ /* 62 */ "textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL",
1454
+ /* 63 */ "position ::= expr COMMA expr",
1455
+ /* 64 */ "position ::= place PLUS expr COMMA expr",
1456
+ /* 65 */ "position ::= place MINUS expr COMMA expr",
1457
+ /* 66 */ "position ::= place PLUS LP expr COMMA expr RP",
1458
+ /* 67 */ "position ::= place MINUS LP expr COMMA expr RP",
1459
+ /* 68 */ "position ::= LP position COMMA position RP",
1460
+ /* 69 */ "position ::= LP position RP",
1461
+ /* 70 */ "position ::= expr between position AND position",
1462
+ /* 71 */ "position ::= expr LT position COMMA position GT",
1463
+ /* 72 */ "position ::= expr ABOVE position",
1464
+ /* 73 */ "position ::= expr BELOW position",
1465
+ /* 74 */ "position ::= expr LEFT OF position",
1466
+ /* 75 */ "position ::= expr RIGHT OF position",
1467
+ /* 76 */ "position ::= expr ON HEADING EDGEPT OF position",
1468
+ /* 77 */ "position ::= expr HEADING EDGEPT OF position",
1469
+ /* 78 */ "position ::= expr EDGEPT OF position",
1470
+ /* 79 */ "position ::= expr ON HEADING expr FROM position",
1471
+ /* 80 */ "position ::= expr HEADING expr FROM position",
1472
+ /* 81 */ "place ::= edge OF object",
1473
+ /* 82 */ "place2 ::= object",
1474
+ /* 83 */ "place2 ::= object DOT_E edge",
1475
+ /* 84 */ "place2 ::= NTH VERTEX OF object",
1476
+ /* 85 */ "object ::= nth",
1477
+ /* 86 */ "object ::= nth OF|IN object",
1478
+ /* 87 */ "objectname ::= PLACENAME",
1479
+ /* 88 */ "objectname ::= objectname DOT_U PLACENAME",
1480
+ /* 89 */ "nth ::= NTH CLASSNAME",
1481
+ /* 90 */ "nth ::= NTH LAST CLASSNAME",
1482
+ /* 91 */ "nth ::= LAST CLASSNAME",
1483
+ /* 92 */ "nth ::= LAST",
1484
+ /* 93 */ "nth ::= NTH LB RB",
1485
+ /* 94 */ "nth ::= NTH LAST LB RB",
1486
+ /* 95 */ "nth ::= LAST LB RB",
1487
+ /* 96 */ "expr ::= expr PLUS expr",
1488
+ /* 97 */ "expr ::= expr MINUS expr",
1489
+ /* 98 */ "expr ::= expr STAR expr",
1490
+ /* 99 */ "expr ::= expr SLASH expr",
1491
+ /* 100 */ "expr ::= MINUS expr",
1492
+ /* 101 */ "expr ::= PLUS expr",
1493
+ /* 102 */ "expr ::= LP expr RP",
1494
+ /* 103 */ "expr ::= LP FILL|COLOR|THICKNESS RP",
1495
+ /* 104 */ "expr ::= NUMBER",
1496
+ /* 105 */ "expr ::= ID",
1497
+ /* 106 */ "expr ::= FUNC1 LP expr RP",
1498
+ /* 107 */ "expr ::= FUNC2 LP expr COMMA expr RP",
1499
+ /* 108 */ "expr ::= DIST LP position COMMA position RP",
1500
+ /* 109 */ "expr ::= place2 DOT_XY X",
1501
+ /* 110 */ "expr ::= place2 DOT_XY Y",
1502
+ /* 111 */ "expr ::= object DOT_L numproperty",
1503
+ /* 112 */ "expr ::= object DOT_L dashproperty",
1504
+ /* 113 */ "expr ::= object DOT_L colorproperty",
1505
+ /* 114 */ "lvalue ::= ID",
1506
+ /* 115 */ "lvalue ::= FILL",
1507
+ /* 116 */ "lvalue ::= COLOR",
1508
+ /* 117 */ "lvalue ::= THICKNESS",
1509
+ /* 118 */ "rvalue ::= expr",
1510
+ /* 119 */ "print ::= PRINT",
1511
+ /* 120 */ "prlist ::= pritem",
1512
+ /* 121 */ "prlist ::= prlist prsep pritem",
1513
+ /* 122 */ "direction ::= UP",
1514
+ /* 123 */ "direction ::= DOWN",
1515
+ /* 124 */ "direction ::= LEFT",
1516
+ /* 125 */ "direction ::= RIGHT",
1517
+ /* 126 */ "optrelexpr ::= relexpr",
1518
+ /* 127 */ "attribute_list ::= alist",
1519
+ /* 128 */ "alist ::=",
1520
+ /* 129 */ "alist ::= alist attribute",
1521
+ /* 130 */ "attribute ::= boolproperty",
1522
+ /* 131 */ "attribute ::= WITH withclause",
1523
+ /* 132 */ "go ::= GO",
1524
+ /* 133 */ "go ::=",
1525
+ /* 134 */ "even ::= UNTIL EVEN WITH",
1526
+ /* 135 */ "even ::= EVEN WITH",
1527
+ /* 136 */ "dashproperty ::= DOTTED",
1528
+ /* 137 */ "dashproperty ::= DASHED",
1529
+ /* 138 */ "colorproperty ::= FILL",
1530
+ /* 139 */ "colorproperty ::= COLOR",
1531
+ /* 140 */ "position ::= place",
1532
+ /* 141 */ "between ::= WAY BETWEEN",
1533
+ /* 142 */ "between ::= BETWEEN",
1534
+ /* 143 */ "between ::= OF THE WAY BETWEEN",
1535
+ /* 144 */ "place ::= place2",
1536
+ /* 145 */ "edge ::= CENTER",
1537
+ /* 146 */ "edge ::= EDGEPT",
1538
+ /* 147 */ "edge ::= TOP",
1539
+ /* 148 */ "edge ::= BOTTOM",
1540
+ /* 149 */ "edge ::= START",
1541
+ /* 150 */ "edge ::= END",
1542
+ /* 151 */ "edge ::= RIGHT",
1543
+ /* 152 */ "edge ::= LEFT",
1544
+ /* 153 */ "object ::= objectname",
15271545
};
15281546
#endif /* NDEBUG */
15291547
15301548
15311549
#if YYSTACKDEPTH<=0
@@ -1647,24 +1665,24 @@
16471665
** Note: during a reduce, the only symbols destroyed are those
16481666
** which appear on the RHS of the rule, but which are *not* used
16491667
** inside the C code.
16501668
*/
16511669
/********* Begin destructor definitions ***************************************/
1652
- case 95: /* element_list */
1653
-{
1654
-#line 468 "pikchr.y"
1655
-pik_elist_free(p,(yypminor->yy56));
1656
-#line 1681 "pikchr.c"
1657
-}
1658
- break;
1659
- case 96: /* element */
1660
- case 97: /* unnamed_element */
1661
- case 98: /* basetype */
1662
-{
1663
-#line 470 "pikchr.y"
1664
-pik_elem_free(p,(yypminor->yy226));
1665
-#line 1690 "pikchr.c"
1670
+ case 97: /* statement_list */
1671
+{
1672
+#line 483 "pikchr.y"
1673
+pik_elist_free(p,(yypminor->yy191));
1674
+#line 1699 "pikchr.c"
1675
+}
1676
+ break;
1677
+ case 98: /* statement */
1678
+ case 99: /* unnamed_statement */
1679
+ case 100: /* basetype */
1680
+{
1681
+#line 485 "pikchr.y"
1682
+pik_elem_free(p,(yypminor->yy138));
1683
+#line 1708 "pikchr.c"
16661684
}
16671685
break;
16681686
/********* End destructor definitions *****************************************/
16691687
default: break; /* If no destructor action specified: do nothing */
16701688
}
@@ -1878,14 +1896,14 @@
18781896
#endif
18791897
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
18801898
/* Here code is inserted which will execute if the parser
18811899
** stack every overflows */
18821900
/******** Begin %stack_overflow code ******************************************/
1883
-#line 502 "pikchr.y"
1901
+#line 517 "pikchr.y"
18841902
18851903
pik_error(p, 0, "parser stack overflow");
1886
-#line 1911 "pikchr.c"
1904
+#line 1929 "pikchr.c"
18871905
/******** End %stack_overflow code ********************************************/
18881906
pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
18891907
pik_parserCTX_STORE
18901908
}
18911909
@@ -1953,321 +1971,323 @@
19531971
}
19541972
19551973
/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
19561974
** of that rule */
19571975
static const YYCODETYPE yyRuleInfoLhs[] = {
1958
- 117, /* (0) document ::= element_list */
1959
- 95, /* (1) element_list ::= element */
1960
- 95, /* (2) element_list ::= element_list EOL element */
1961
- 96, /* (3) element ::= */
1962
- 96, /* (4) element ::= direction */
1963
- 96, /* (5) element ::= lvalue ASSIGN rvalue */
1964
- 96, /* (6) element ::= PLACENAME COLON unnamed_element */
1965
- 96, /* (7) element ::= PLACENAME COLON position */
1966
- 96, /* (8) element ::= unnamed_element */
1967
- 96, /* (9) element ::= print prlist */
1968
- 96, /* (10) element ::= ASSERT LP expr EQ expr RP */
1969
- 96, /* (11) element ::= ASSERT LP position EQ position RP */
1970
- 112, /* (12) rvalue ::= PLACENAME */
1971
- 120, /* (13) pritem ::= FILL */
1972
- 120, /* (14) pritem ::= COLOR */
1973
- 120, /* (15) pritem ::= THICKNESS */
1974
- 120, /* (16) pritem ::= rvalue */
1975
- 120, /* (17) pritem ::= STRING */
1976
- 121, /* (18) prsep ::= COMMA */
1977
- 97, /* (19) unnamed_element ::= basetype attribute_list */
1978
- 98, /* (20) basetype ::= CLASSNAME */
1979
- 98, /* (21) basetype ::= STRING textposition */
1980
- 98, /* (22) basetype ::= LB savelist element_list RB */
1981
- 123, /* (23) savelist ::= */
1982
- 115, /* (24) relexpr ::= expr */
1983
- 115, /* (25) relexpr ::= expr PERCENT */
1984
- 116, /* (26) optrelexpr ::= */
1985
- 122, /* (27) attribute_list ::= relexpr alist */
1986
- 125, /* (28) attribute ::= numproperty relexpr */
1987
- 125, /* (29) attribute ::= dashproperty expr */
1988
- 125, /* (30) attribute ::= dashproperty */
1989
- 125, /* (31) attribute ::= colorproperty rvalue */
1990
- 125, /* (32) attribute ::= go direction optrelexpr */
1991
- 125, /* (33) attribute ::= go direction even position */
1992
- 125, /* (34) attribute ::= CLOSE */
1993
- 125, /* (35) attribute ::= CHOP */
1994
- 125, /* (36) attribute ::= FROM position */
1995
- 125, /* (37) attribute ::= TO position */
1996
- 125, /* (38) attribute ::= THEN */
1997
- 125, /* (39) attribute ::= THEN optrelexpr HEADING expr */
1998
- 125, /* (40) attribute ::= THEN optrelexpr EDGEPT */
1999
- 125, /* (41) attribute ::= GO optrelexpr HEADING expr */
2000
- 125, /* (42) attribute ::= GO optrelexpr EDGEPT */
2001
- 125, /* (43) attribute ::= AT position */
2002
- 125, /* (44) attribute ::= SAME */
2003
- 125, /* (45) attribute ::= SAME AS object */
2004
- 125, /* (46) attribute ::= STRING textposition */
2005
- 125, /* (47) attribute ::= FIT */
2006
- 125, /* (48) attribute ::= BEHIND object */
2007
- 128, /* (49) withclause ::= DOT_E edge AT position */
2008
- 128, /* (50) withclause ::= edge AT position */
2009
- 100, /* (51) numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2010
- 127, /* (52) boolproperty ::= CW */
2011
- 127, /* (53) boolproperty ::= CCW */
2012
- 127, /* (54) boolproperty ::= LARROW */
2013
- 127, /* (55) boolproperty ::= RARROW */
2014
- 127, /* (56) boolproperty ::= LRARROW */
2015
- 127, /* (57) boolproperty ::= INVIS */
2016
- 127, /* (58) boolproperty ::= THICK */
2017
- 127, /* (59) boolproperty ::= THIN */
2018
- 111, /* (60) textposition ::= */
2019
- 111, /* (61) textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2020
- 106, /* (62) position ::= expr COMMA expr */
2021
- 106, /* (63) position ::= place PLUS expr COMMA expr */
2022
- 106, /* (64) position ::= place MINUS expr COMMA expr */
2023
- 106, /* (65) position ::= place PLUS LP expr COMMA expr RP */
2024
- 106, /* (66) position ::= place MINUS LP expr COMMA expr RP */
2025
- 106, /* (67) position ::= LP position COMMA position RP */
2026
- 106, /* (68) position ::= LP position RP */
2027
- 106, /* (69) position ::= expr between position AND position */
2028
- 106, /* (70) position ::= expr LT position COMMA position GT */
2029
- 106, /* (71) position ::= expr ABOVE position */
2030
- 106, /* (72) position ::= expr BELOW position */
2031
- 106, /* (73) position ::= expr LEFT OF position */
2032
- 106, /* (74) position ::= expr RIGHT OF position */
2033
- 106, /* (75) position ::= expr ON HEADING EDGEPT OF position */
2034
- 106, /* (76) position ::= expr HEADING EDGEPT OF position */
2035
- 106, /* (77) position ::= expr EDGEPT OF position */
2036
- 106, /* (78) position ::= expr ON HEADING expr FROM position */
2037
- 106, /* (79) position ::= expr HEADING expr FROM position */
2038
- 107, /* (80) place ::= edge OF object */
2039
- 130, /* (81) place2 ::= object */
2040
- 130, /* (82) place2 ::= object DOT_E edge */
2041
- 130, /* (83) place2 ::= NTH VERTEX OF object */
2042
- 108, /* (84) object ::= nth */
2043
- 108, /* (85) object ::= nth OF|IN object */
2044
- 109, /* (86) objectname ::= PLACENAME */
2045
- 109, /* (87) objectname ::= objectname DOT_U PLACENAME */
2046
- 110, /* (88) nth ::= NTH CLASSNAME */
2047
- 110, /* (89) nth ::= NTH LAST CLASSNAME */
2048
- 110, /* (90) nth ::= LAST CLASSNAME */
2049
- 110, /* (91) nth ::= LAST */
2050
- 110, /* (92) nth ::= NTH LB RB */
2051
- 110, /* (93) nth ::= NTH LAST LB RB */
2052
- 110, /* (94) nth ::= LAST LB RB */
2053
- 99, /* (95) expr ::= expr PLUS expr */
2054
- 99, /* (96) expr ::= expr MINUS expr */
2055
- 99, /* (97) expr ::= expr STAR expr */
2056
- 99, /* (98) expr ::= expr SLASH expr */
2057
- 99, /* (99) expr ::= MINUS expr */
2058
- 99, /* (100) expr ::= PLUS expr */
2059
- 99, /* (101) expr ::= LP expr RP */
2060
- 99, /* (102) expr ::= LP FILL|COLOR|THICKNESS RP */
2061
- 99, /* (103) expr ::= NUMBER */
2062
- 99, /* (104) expr ::= ID */
2063
- 99, /* (105) expr ::= FUNC1 LP expr RP */
2064
- 99, /* (106) expr ::= FUNC2 LP expr COMMA expr RP */
2065
- 99, /* (107) expr ::= DIST LP position COMMA position RP */
2066
- 99, /* (108) expr ::= place2 DOT_XY X */
2067
- 99, /* (109) expr ::= place2 DOT_XY Y */
2068
- 99, /* (110) expr ::= object DOT_L numproperty */
2069
- 99, /* (111) expr ::= object DOT_L dashproperty */
2070
- 99, /* (112) expr ::= object DOT_L colorproperty */
2071
- 113, /* (113) lvalue ::= ID */
2072
- 113, /* (114) lvalue ::= FILL */
2073
- 113, /* (115) lvalue ::= COLOR */
2074
- 113, /* (116) lvalue ::= THICKNESS */
2075
- 112, /* (117) rvalue ::= expr */
2076
- 118, /* (118) print ::= PRINT */
2077
- 119, /* (119) prlist ::= pritem */
2078
- 119, /* (120) prlist ::= prlist prsep pritem */
2079
- 102, /* (121) direction ::= UP */
2080
- 102, /* (122) direction ::= DOWN */
2081
- 102, /* (123) direction ::= LEFT */
2082
- 102, /* (124) direction ::= RIGHT */
2083
- 116, /* (125) optrelexpr ::= relexpr */
2084
- 122, /* (126) attribute_list ::= alist */
2085
- 124, /* (127) alist ::= */
2086
- 124, /* (128) alist ::= alist attribute */
2087
- 125, /* (129) attribute ::= boolproperty */
2088
- 125, /* (130) attribute ::= WITH withclause */
2089
- 126, /* (131) go ::= GO */
2090
- 126, /* (132) go ::= */
2091
- 114, /* (133) even ::= UNTIL EVEN WITH */
2092
- 114, /* (134) even ::= EVEN WITH */
2093
- 103, /* (135) dashproperty ::= DOTTED */
2094
- 103, /* (136) dashproperty ::= DASHED */
2095
- 104, /* (137) colorproperty ::= FILL */
2096
- 104, /* (138) colorproperty ::= COLOR */
2097
- 106, /* (139) position ::= place */
2098
- 129, /* (140) between ::= WAY BETWEEN */
2099
- 129, /* (141) between ::= BETWEEN */
2100
- 129, /* (142) between ::= OF THE WAY BETWEEN */
2101
- 107, /* (143) place ::= place2 */
2102
- 101, /* (144) edge ::= CENTER */
2103
- 101, /* (145) edge ::= EDGEPT */
2104
- 101, /* (146) edge ::= TOP */
2105
- 101, /* (147) edge ::= BOTTOM */
2106
- 101, /* (148) edge ::= START */
2107
- 101, /* (149) edge ::= END */
2108
- 101, /* (150) edge ::= RIGHT */
2109
- 101, /* (151) edge ::= LEFT */
2110
- 108, /* (152) object ::= objectname */
1976
+ 119, /* (0) document ::= statement_list */
1977
+ 97, /* (1) statement_list ::= statement */
1978
+ 97, /* (2) statement_list ::= statement_list EOL statement */
1979
+ 98, /* (3) statement ::= */
1980
+ 98, /* (4) statement ::= direction */
1981
+ 98, /* (5) statement ::= lvalue ASSIGN rvalue */
1982
+ 98, /* (6) statement ::= PLACENAME COLON unnamed_statement */
1983
+ 98, /* (7) statement ::= PLACENAME COLON position */
1984
+ 98, /* (8) statement ::= unnamed_statement */
1985
+ 98, /* (9) statement ::= print prlist */
1986
+ 98, /* (10) statement ::= ASSERT LP expr EQ expr RP */
1987
+ 98, /* (11) statement ::= ASSERT LP position EQ position RP */
1988
+ 98, /* (12) statement ::= DEFINE ID CODEBLOCK */
1989
+ 114, /* (13) rvalue ::= PLACENAME */
1990
+ 122, /* (14) pritem ::= FILL */
1991
+ 122, /* (15) pritem ::= COLOR */
1992
+ 122, /* (16) pritem ::= THICKNESS */
1993
+ 122, /* (17) pritem ::= rvalue */
1994
+ 122, /* (18) pritem ::= STRING */
1995
+ 123, /* (19) prsep ::= COMMA */
1996
+ 99, /* (20) unnamed_statement ::= basetype attribute_list */
1997
+ 100, /* (21) basetype ::= CLASSNAME */
1998
+ 100, /* (22) basetype ::= STRING textposition */
1999
+ 100, /* (23) basetype ::= LB savelist statement_list RB */
2000
+ 125, /* (24) savelist ::= */
2001
+ 117, /* (25) relexpr ::= expr */
2002
+ 117, /* (26) relexpr ::= expr PERCENT */
2003
+ 118, /* (27) optrelexpr ::= */
2004
+ 124, /* (28) attribute_list ::= relexpr alist */
2005
+ 127, /* (29) attribute ::= numproperty relexpr */
2006
+ 127, /* (30) attribute ::= dashproperty expr */
2007
+ 127, /* (31) attribute ::= dashproperty */
2008
+ 127, /* (32) attribute ::= colorproperty rvalue */
2009
+ 127, /* (33) attribute ::= go direction optrelexpr */
2010
+ 127, /* (34) attribute ::= go direction even position */
2011
+ 127, /* (35) attribute ::= CLOSE */
2012
+ 127, /* (36) attribute ::= CHOP */
2013
+ 127, /* (37) attribute ::= FROM position */
2014
+ 127, /* (38) attribute ::= TO position */
2015
+ 127, /* (39) attribute ::= THEN */
2016
+ 127, /* (40) attribute ::= THEN optrelexpr HEADING expr */
2017
+ 127, /* (41) attribute ::= THEN optrelexpr EDGEPT */
2018
+ 127, /* (42) attribute ::= GO optrelexpr HEADING expr */
2019
+ 127, /* (43) attribute ::= GO optrelexpr EDGEPT */
2020
+ 127, /* (44) attribute ::= AT position */
2021
+ 127, /* (45) attribute ::= SAME */
2022
+ 127, /* (46) attribute ::= SAME AS object */
2023
+ 127, /* (47) attribute ::= STRING textposition */
2024
+ 127, /* (48) attribute ::= FIT */
2025
+ 127, /* (49) attribute ::= BEHIND object */
2026
+ 130, /* (50) withclause ::= DOT_E edge AT position */
2027
+ 130, /* (51) withclause ::= edge AT position */
2028
+ 102, /* (52) numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2029
+ 129, /* (53) boolproperty ::= CW */
2030
+ 129, /* (54) boolproperty ::= CCW */
2031
+ 129, /* (55) boolproperty ::= LARROW */
2032
+ 129, /* (56) boolproperty ::= RARROW */
2033
+ 129, /* (57) boolproperty ::= LRARROW */
2034
+ 129, /* (58) boolproperty ::= INVIS */
2035
+ 129, /* (59) boolproperty ::= THICK */
2036
+ 129, /* (60) boolproperty ::= THIN */
2037
+ 113, /* (61) textposition ::= */
2038
+ 113, /* (62) textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2039
+ 108, /* (63) position ::= expr COMMA expr */
2040
+ 108, /* (64) position ::= place PLUS expr COMMA expr */
2041
+ 108, /* (65) position ::= place MINUS expr COMMA expr */
2042
+ 108, /* (66) position ::= place PLUS LP expr COMMA expr RP */
2043
+ 108, /* (67) position ::= place MINUS LP expr COMMA expr RP */
2044
+ 108, /* (68) position ::= LP position COMMA position RP */
2045
+ 108, /* (69) position ::= LP position RP */
2046
+ 108, /* (70) position ::= expr between position AND position */
2047
+ 108, /* (71) position ::= expr LT position COMMA position GT */
2048
+ 108, /* (72) position ::= expr ABOVE position */
2049
+ 108, /* (73) position ::= expr BELOW position */
2050
+ 108, /* (74) position ::= expr LEFT OF position */
2051
+ 108, /* (75) position ::= expr RIGHT OF position */
2052
+ 108, /* (76) position ::= expr ON HEADING EDGEPT OF position */
2053
+ 108, /* (77) position ::= expr HEADING EDGEPT OF position */
2054
+ 108, /* (78) position ::= expr EDGEPT OF position */
2055
+ 108, /* (79) position ::= expr ON HEADING expr FROM position */
2056
+ 108, /* (80) position ::= expr HEADING expr FROM position */
2057
+ 109, /* (81) place ::= edge OF object */
2058
+ 132, /* (82) place2 ::= object */
2059
+ 132, /* (83) place2 ::= object DOT_E edge */
2060
+ 132, /* (84) place2 ::= NTH VERTEX OF object */
2061
+ 110, /* (85) object ::= nth */
2062
+ 110, /* (86) object ::= nth OF|IN object */
2063
+ 111, /* (87) objectname ::= PLACENAME */
2064
+ 111, /* (88) objectname ::= objectname DOT_U PLACENAME */
2065
+ 112, /* (89) nth ::= NTH CLASSNAME */
2066
+ 112, /* (90) nth ::= NTH LAST CLASSNAME */
2067
+ 112, /* (91) nth ::= LAST CLASSNAME */
2068
+ 112, /* (92) nth ::= LAST */
2069
+ 112, /* (93) nth ::= NTH LB RB */
2070
+ 112, /* (94) nth ::= NTH LAST LB RB */
2071
+ 112, /* (95) nth ::= LAST LB RB */
2072
+ 101, /* (96) expr ::= expr PLUS expr */
2073
+ 101, /* (97) expr ::= expr MINUS expr */
2074
+ 101, /* (98) expr ::= expr STAR expr */
2075
+ 101, /* (99) expr ::= expr SLASH expr */
2076
+ 101, /* (100) expr ::= MINUS expr */
2077
+ 101, /* (101) expr ::= PLUS expr */
2078
+ 101, /* (102) expr ::= LP expr RP */
2079
+ 101, /* (103) expr ::= LP FILL|COLOR|THICKNESS RP */
2080
+ 101, /* (104) expr ::= NUMBER */
2081
+ 101, /* (105) expr ::= ID */
2082
+ 101, /* (106) expr ::= FUNC1 LP expr RP */
2083
+ 101, /* (107) expr ::= FUNC2 LP expr COMMA expr RP */
2084
+ 101, /* (108) expr ::= DIST LP position COMMA position RP */
2085
+ 101, /* (109) expr ::= place2 DOT_XY X */
2086
+ 101, /* (110) expr ::= place2 DOT_XY Y */
2087
+ 101, /* (111) expr ::= object DOT_L numproperty */
2088
+ 101, /* (112) expr ::= object DOT_L dashproperty */
2089
+ 101, /* (113) expr ::= object DOT_L colorproperty */
2090
+ 115, /* (114) lvalue ::= ID */
2091
+ 115, /* (115) lvalue ::= FILL */
2092
+ 115, /* (116) lvalue ::= COLOR */
2093
+ 115, /* (117) lvalue ::= THICKNESS */
2094
+ 114, /* (118) rvalue ::= expr */
2095
+ 120, /* (119) print ::= PRINT */
2096
+ 121, /* (120) prlist ::= pritem */
2097
+ 121, /* (121) prlist ::= prlist prsep pritem */
2098
+ 104, /* (122) direction ::= UP */
2099
+ 104, /* (123) direction ::= DOWN */
2100
+ 104, /* (124) direction ::= LEFT */
2101
+ 104, /* (125) direction ::= RIGHT */
2102
+ 118, /* (126) optrelexpr ::= relexpr */
2103
+ 124, /* (127) attribute_list ::= alist */
2104
+ 126, /* (128) alist ::= */
2105
+ 126, /* (129) alist ::= alist attribute */
2106
+ 127, /* (130) attribute ::= boolproperty */
2107
+ 127, /* (131) attribute ::= WITH withclause */
2108
+ 128, /* (132) go ::= GO */
2109
+ 128, /* (133) go ::= */
2110
+ 116, /* (134) even ::= UNTIL EVEN WITH */
2111
+ 116, /* (135) even ::= EVEN WITH */
2112
+ 105, /* (136) dashproperty ::= DOTTED */
2113
+ 105, /* (137) dashproperty ::= DASHED */
2114
+ 106, /* (138) colorproperty ::= FILL */
2115
+ 106, /* (139) colorproperty ::= COLOR */
2116
+ 108, /* (140) position ::= place */
2117
+ 131, /* (141) between ::= WAY BETWEEN */
2118
+ 131, /* (142) between ::= BETWEEN */
2119
+ 131, /* (143) between ::= OF THE WAY BETWEEN */
2120
+ 109, /* (144) place ::= place2 */
2121
+ 103, /* (145) edge ::= CENTER */
2122
+ 103, /* (146) edge ::= EDGEPT */
2123
+ 103, /* (147) edge ::= TOP */
2124
+ 103, /* (148) edge ::= BOTTOM */
2125
+ 103, /* (149) edge ::= START */
2126
+ 103, /* (150) edge ::= END */
2127
+ 103, /* (151) edge ::= RIGHT */
2128
+ 103, /* (152) edge ::= LEFT */
2129
+ 110, /* (153) object ::= objectname */
21112130
};
21122131
21132132
/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
21142133
** of symbols on the right-hand side of that rule. */
21152134
static const signed char yyRuleInfoNRhs[] = {
2116
- -1, /* (0) document ::= element_list */
2117
- -1, /* (1) element_list ::= element */
2118
- -3, /* (2) element_list ::= element_list EOL element */
2119
- 0, /* (3) element ::= */
2120
- -1, /* (4) element ::= direction */
2121
- -3, /* (5) element ::= lvalue ASSIGN rvalue */
2122
- -3, /* (6) element ::= PLACENAME COLON unnamed_element */
2123
- -3, /* (7) element ::= PLACENAME COLON position */
2124
- -1, /* (8) element ::= unnamed_element */
2125
- -2, /* (9) element ::= print prlist */
2126
- -6, /* (10) element ::= ASSERT LP expr EQ expr RP */
2127
- -6, /* (11) element ::= ASSERT LP position EQ position RP */
2128
- -1, /* (12) rvalue ::= PLACENAME */
2129
- -1, /* (13) pritem ::= FILL */
2130
- -1, /* (14) pritem ::= COLOR */
2131
- -1, /* (15) pritem ::= THICKNESS */
2132
- -1, /* (16) pritem ::= rvalue */
2133
- -1, /* (17) pritem ::= STRING */
2134
- -1, /* (18) prsep ::= COMMA */
2135
- -2, /* (19) unnamed_element ::= basetype attribute_list */
2136
- -1, /* (20) basetype ::= CLASSNAME */
2137
- -2, /* (21) basetype ::= STRING textposition */
2138
- -4, /* (22) basetype ::= LB savelist element_list RB */
2139
- 0, /* (23) savelist ::= */
2140
- -1, /* (24) relexpr ::= expr */
2141
- -2, /* (25) relexpr ::= expr PERCENT */
2142
- 0, /* (26) optrelexpr ::= */
2143
- -2, /* (27) attribute_list ::= relexpr alist */
2144
- -2, /* (28) attribute ::= numproperty relexpr */
2145
- -2, /* (29) attribute ::= dashproperty expr */
2146
- -1, /* (30) attribute ::= dashproperty */
2147
- -2, /* (31) attribute ::= colorproperty rvalue */
2148
- -3, /* (32) attribute ::= go direction optrelexpr */
2149
- -4, /* (33) attribute ::= go direction even position */
2150
- -1, /* (34) attribute ::= CLOSE */
2151
- -1, /* (35) attribute ::= CHOP */
2152
- -2, /* (36) attribute ::= FROM position */
2153
- -2, /* (37) attribute ::= TO position */
2154
- -1, /* (38) attribute ::= THEN */
2155
- -4, /* (39) attribute ::= THEN optrelexpr HEADING expr */
2156
- -3, /* (40) attribute ::= THEN optrelexpr EDGEPT */
2157
- -4, /* (41) attribute ::= GO optrelexpr HEADING expr */
2158
- -3, /* (42) attribute ::= GO optrelexpr EDGEPT */
2159
- -2, /* (43) attribute ::= AT position */
2160
- -1, /* (44) attribute ::= SAME */
2161
- -3, /* (45) attribute ::= SAME AS object */
2162
- -2, /* (46) attribute ::= STRING textposition */
2163
- -1, /* (47) attribute ::= FIT */
2164
- -2, /* (48) attribute ::= BEHIND object */
2165
- -4, /* (49) withclause ::= DOT_E edge AT position */
2166
- -3, /* (50) withclause ::= edge AT position */
2167
- -1, /* (51) numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2168
- -1, /* (52) boolproperty ::= CW */
2169
- -1, /* (53) boolproperty ::= CCW */
2170
- -1, /* (54) boolproperty ::= LARROW */
2171
- -1, /* (55) boolproperty ::= RARROW */
2172
- -1, /* (56) boolproperty ::= LRARROW */
2173
- -1, /* (57) boolproperty ::= INVIS */
2174
- -1, /* (58) boolproperty ::= THICK */
2175
- -1, /* (59) boolproperty ::= THIN */
2176
- 0, /* (60) textposition ::= */
2177
- -2, /* (61) textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2178
- -3, /* (62) position ::= expr COMMA expr */
2179
- -5, /* (63) position ::= place PLUS expr COMMA expr */
2180
- -5, /* (64) position ::= place MINUS expr COMMA expr */
2181
- -7, /* (65) position ::= place PLUS LP expr COMMA expr RP */
2182
- -7, /* (66) position ::= place MINUS LP expr COMMA expr RP */
2183
- -5, /* (67) position ::= LP position COMMA position RP */
2184
- -3, /* (68) position ::= LP position RP */
2185
- -5, /* (69) position ::= expr between position AND position */
2186
- -6, /* (70) position ::= expr LT position COMMA position GT */
2187
- -3, /* (71) position ::= expr ABOVE position */
2188
- -3, /* (72) position ::= expr BELOW position */
2189
- -4, /* (73) position ::= expr LEFT OF position */
2190
- -4, /* (74) position ::= expr RIGHT OF position */
2191
- -6, /* (75) position ::= expr ON HEADING EDGEPT OF position */
2192
- -5, /* (76) position ::= expr HEADING EDGEPT OF position */
2193
- -4, /* (77) position ::= expr EDGEPT OF position */
2194
- -6, /* (78) position ::= expr ON HEADING expr FROM position */
2195
- -5, /* (79) position ::= expr HEADING expr FROM position */
2196
- -3, /* (80) place ::= edge OF object */
2197
- -1, /* (81) place2 ::= object */
2198
- -3, /* (82) place2 ::= object DOT_E edge */
2199
- -4, /* (83) place2 ::= NTH VERTEX OF object */
2200
- -1, /* (84) object ::= nth */
2201
- -3, /* (85) object ::= nth OF|IN object */
2202
- -1, /* (86) objectname ::= PLACENAME */
2203
- -3, /* (87) objectname ::= objectname DOT_U PLACENAME */
2204
- -2, /* (88) nth ::= NTH CLASSNAME */
2205
- -3, /* (89) nth ::= NTH LAST CLASSNAME */
2206
- -2, /* (90) nth ::= LAST CLASSNAME */
2207
- -1, /* (91) nth ::= LAST */
2208
- -3, /* (92) nth ::= NTH LB RB */
2209
- -4, /* (93) nth ::= NTH LAST LB RB */
2210
- -3, /* (94) nth ::= LAST LB RB */
2211
- -3, /* (95) expr ::= expr PLUS expr */
2212
- -3, /* (96) expr ::= expr MINUS expr */
2213
- -3, /* (97) expr ::= expr STAR expr */
2214
- -3, /* (98) expr ::= expr SLASH expr */
2215
- -2, /* (99) expr ::= MINUS expr */
2216
- -2, /* (100) expr ::= PLUS expr */
2217
- -3, /* (101) expr ::= LP expr RP */
2218
- -3, /* (102) expr ::= LP FILL|COLOR|THICKNESS RP */
2219
- -1, /* (103) expr ::= NUMBER */
2220
- -1, /* (104) expr ::= ID */
2221
- -4, /* (105) expr ::= FUNC1 LP expr RP */
2222
- -6, /* (106) expr ::= FUNC2 LP expr COMMA expr RP */
2223
- -6, /* (107) expr ::= DIST LP position COMMA position RP */
2224
- -3, /* (108) expr ::= place2 DOT_XY X */
2225
- -3, /* (109) expr ::= place2 DOT_XY Y */
2226
- -3, /* (110) expr ::= object DOT_L numproperty */
2227
- -3, /* (111) expr ::= object DOT_L dashproperty */
2228
- -3, /* (112) expr ::= object DOT_L colorproperty */
2229
- -1, /* (113) lvalue ::= ID */
2230
- -1, /* (114) lvalue ::= FILL */
2231
- -1, /* (115) lvalue ::= COLOR */
2232
- -1, /* (116) lvalue ::= THICKNESS */
2233
- -1, /* (117) rvalue ::= expr */
2234
- -1, /* (118) print ::= PRINT */
2235
- -1, /* (119) prlist ::= pritem */
2236
- -3, /* (120) prlist ::= prlist prsep pritem */
2237
- -1, /* (121) direction ::= UP */
2238
- -1, /* (122) direction ::= DOWN */
2239
- -1, /* (123) direction ::= LEFT */
2240
- -1, /* (124) direction ::= RIGHT */
2241
- -1, /* (125) optrelexpr ::= relexpr */
2242
- -1, /* (126) attribute_list ::= alist */
2243
- 0, /* (127) alist ::= */
2244
- -2, /* (128) alist ::= alist attribute */
2245
- -1, /* (129) attribute ::= boolproperty */
2246
- -2, /* (130) attribute ::= WITH withclause */
2247
- -1, /* (131) go ::= GO */
2248
- 0, /* (132) go ::= */
2249
- -3, /* (133) even ::= UNTIL EVEN WITH */
2250
- -2, /* (134) even ::= EVEN WITH */
2251
- -1, /* (135) dashproperty ::= DOTTED */
2252
- -1, /* (136) dashproperty ::= DASHED */
2253
- -1, /* (137) colorproperty ::= FILL */
2254
- -1, /* (138) colorproperty ::= COLOR */
2255
- -1, /* (139) position ::= place */
2256
- -2, /* (140) between ::= WAY BETWEEN */
2257
- -1, /* (141) between ::= BETWEEN */
2258
- -4, /* (142) between ::= OF THE WAY BETWEEN */
2259
- -1, /* (143) place ::= place2 */
2260
- -1, /* (144) edge ::= CENTER */
2261
- -1, /* (145) edge ::= EDGEPT */
2262
- -1, /* (146) edge ::= TOP */
2263
- -1, /* (147) edge ::= BOTTOM */
2264
- -1, /* (148) edge ::= START */
2265
- -1, /* (149) edge ::= END */
2266
- -1, /* (150) edge ::= RIGHT */
2267
- -1, /* (151) edge ::= LEFT */
2268
- -1, /* (152) object ::= objectname */
2135
+ -1, /* (0) document ::= statement_list */
2136
+ -1, /* (1) statement_list ::= statement */
2137
+ -3, /* (2) statement_list ::= statement_list EOL statement */
2138
+ 0, /* (3) statement ::= */
2139
+ -1, /* (4) statement ::= direction */
2140
+ -3, /* (5) statement ::= lvalue ASSIGN rvalue */
2141
+ -3, /* (6) statement ::= PLACENAME COLON unnamed_statement */
2142
+ -3, /* (7) statement ::= PLACENAME COLON position */
2143
+ -1, /* (8) statement ::= unnamed_statement */
2144
+ -2, /* (9) statement ::= print prlist */
2145
+ -6, /* (10) statement ::= ASSERT LP expr EQ expr RP */
2146
+ -6, /* (11) statement ::= ASSERT LP position EQ position RP */
2147
+ -3, /* (12) statement ::= DEFINE ID CODEBLOCK */
2148
+ -1, /* (13) rvalue ::= PLACENAME */
2149
+ -1, /* (14) pritem ::= FILL */
2150
+ -1, /* (15) pritem ::= COLOR */
2151
+ -1, /* (16) pritem ::= THICKNESS */
2152
+ -1, /* (17) pritem ::= rvalue */
2153
+ -1, /* (18) pritem ::= STRING */
2154
+ -1, /* (19) prsep ::= COMMA */
2155
+ -2, /* (20) unnamed_statement ::= basetype attribute_list */
2156
+ -1, /* (21) basetype ::= CLASSNAME */
2157
+ -2, /* (22) basetype ::= STRING textposition */
2158
+ -4, /* (23) basetype ::= LB savelist statement_list RB */
2159
+ 0, /* (24) savelist ::= */
2160
+ -1, /* (25) relexpr ::= expr */
2161
+ -2, /* (26) relexpr ::= expr PERCENT */
2162
+ 0, /* (27) optrelexpr ::= */
2163
+ -2, /* (28) attribute_list ::= relexpr alist */
2164
+ -2, /* (29) attribute ::= numproperty relexpr */
2165
+ -2, /* (30) attribute ::= dashproperty expr */
2166
+ -1, /* (31) attribute ::= dashproperty */
2167
+ -2, /* (32) attribute ::= colorproperty rvalue */
2168
+ -3, /* (33) attribute ::= go direction optrelexpr */
2169
+ -4, /* (34) attribute ::= go direction even position */
2170
+ -1, /* (35) attribute ::= CLOSE */
2171
+ -1, /* (36) attribute ::= CHOP */
2172
+ -2, /* (37) attribute ::= FROM position */
2173
+ -2, /* (38) attribute ::= TO position */
2174
+ -1, /* (39) attribute ::= THEN */
2175
+ -4, /* (40) attribute ::= THEN optrelexpr HEADING expr */
2176
+ -3, /* (41) attribute ::= THEN optrelexpr EDGEPT */
2177
+ -4, /* (42) attribute ::= GO optrelexpr HEADING expr */
2178
+ -3, /* (43) attribute ::= GO optrelexpr EDGEPT */
2179
+ -2, /* (44) attribute ::= AT position */
2180
+ -1, /* (45) attribute ::= SAME */
2181
+ -3, /* (46) attribute ::= SAME AS object */
2182
+ -2, /* (47) attribute ::= STRING textposition */
2183
+ -1, /* (48) attribute ::= FIT */
2184
+ -2, /* (49) attribute ::= BEHIND object */
2185
+ -4, /* (50) withclause ::= DOT_E edge AT position */
2186
+ -3, /* (51) withclause ::= edge AT position */
2187
+ -1, /* (52) numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2188
+ -1, /* (53) boolproperty ::= CW */
2189
+ -1, /* (54) boolproperty ::= CCW */
2190
+ -1, /* (55) boolproperty ::= LARROW */
2191
+ -1, /* (56) boolproperty ::= RARROW */
2192
+ -1, /* (57) boolproperty ::= LRARROW */
2193
+ -1, /* (58) boolproperty ::= INVIS */
2194
+ -1, /* (59) boolproperty ::= THICK */
2195
+ -1, /* (60) boolproperty ::= THIN */
2196
+ 0, /* (61) textposition ::= */
2197
+ -2, /* (62) textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2198
+ -3, /* (63) position ::= expr COMMA expr */
2199
+ -5, /* (64) position ::= place PLUS expr COMMA expr */
2200
+ -5, /* (65) position ::= place MINUS expr COMMA expr */
2201
+ -7, /* (66) position ::= place PLUS LP expr COMMA expr RP */
2202
+ -7, /* (67) position ::= place MINUS LP expr COMMA expr RP */
2203
+ -5, /* (68) position ::= LP position COMMA position RP */
2204
+ -3, /* (69) position ::= LP position RP */
2205
+ -5, /* (70) position ::= expr between position AND position */
2206
+ -6, /* (71) position ::= expr LT position COMMA position GT */
2207
+ -3, /* (72) position ::= expr ABOVE position */
2208
+ -3, /* (73) position ::= expr BELOW position */
2209
+ -4, /* (74) position ::= expr LEFT OF position */
2210
+ -4, /* (75) position ::= expr RIGHT OF position */
2211
+ -6, /* (76) position ::= expr ON HEADING EDGEPT OF position */
2212
+ -5, /* (77) position ::= expr HEADING EDGEPT OF position */
2213
+ -4, /* (78) position ::= expr EDGEPT OF position */
2214
+ -6, /* (79) position ::= expr ON HEADING expr FROM position */
2215
+ -5, /* (80) position ::= expr HEADING expr FROM position */
2216
+ -3, /* (81) place ::= edge OF object */
2217
+ -1, /* (82) place2 ::= object */
2218
+ -3, /* (83) place2 ::= object DOT_E edge */
2219
+ -4, /* (84) place2 ::= NTH VERTEX OF object */
2220
+ -1, /* (85) object ::= nth */
2221
+ -3, /* (86) object ::= nth OF|IN object */
2222
+ -1, /* (87) objectname ::= PLACENAME */
2223
+ -3, /* (88) objectname ::= objectname DOT_U PLACENAME */
2224
+ -2, /* (89) nth ::= NTH CLASSNAME */
2225
+ -3, /* (90) nth ::= NTH LAST CLASSNAME */
2226
+ -2, /* (91) nth ::= LAST CLASSNAME */
2227
+ -1, /* (92) nth ::= LAST */
2228
+ -3, /* (93) nth ::= NTH LB RB */
2229
+ -4, /* (94) nth ::= NTH LAST LB RB */
2230
+ -3, /* (95) nth ::= LAST LB RB */
2231
+ -3, /* (96) expr ::= expr PLUS expr */
2232
+ -3, /* (97) expr ::= expr MINUS expr */
2233
+ -3, /* (98) expr ::= expr STAR expr */
2234
+ -3, /* (99) expr ::= expr SLASH expr */
2235
+ -2, /* (100) expr ::= MINUS expr */
2236
+ -2, /* (101) expr ::= PLUS expr */
2237
+ -3, /* (102) expr ::= LP expr RP */
2238
+ -3, /* (103) expr ::= LP FILL|COLOR|THICKNESS RP */
2239
+ -1, /* (104) expr ::= NUMBER */
2240
+ -1, /* (105) expr ::= ID */
2241
+ -4, /* (106) expr ::= FUNC1 LP expr RP */
2242
+ -6, /* (107) expr ::= FUNC2 LP expr COMMA expr RP */
2243
+ -6, /* (108) expr ::= DIST LP position COMMA position RP */
2244
+ -3, /* (109) expr ::= place2 DOT_XY X */
2245
+ -3, /* (110) expr ::= place2 DOT_XY Y */
2246
+ -3, /* (111) expr ::= object DOT_L numproperty */
2247
+ -3, /* (112) expr ::= object DOT_L dashproperty */
2248
+ -3, /* (113) expr ::= object DOT_L colorproperty */
2249
+ -1, /* (114) lvalue ::= ID */
2250
+ -1, /* (115) lvalue ::= FILL */
2251
+ -1, /* (116) lvalue ::= COLOR */
2252
+ -1, /* (117) lvalue ::= THICKNESS */
2253
+ -1, /* (118) rvalue ::= expr */
2254
+ -1, /* (119) print ::= PRINT */
2255
+ -1, /* (120) prlist ::= pritem */
2256
+ -3, /* (121) prlist ::= prlist prsep pritem */
2257
+ -1, /* (122) direction ::= UP */
2258
+ -1, /* (123) direction ::= DOWN */
2259
+ -1, /* (124) direction ::= LEFT */
2260
+ -1, /* (125) direction ::= RIGHT */
2261
+ -1, /* (126) optrelexpr ::= relexpr */
2262
+ -1, /* (127) attribute_list ::= alist */
2263
+ 0, /* (128) alist ::= */
2264
+ -2, /* (129) alist ::= alist attribute */
2265
+ -1, /* (130) attribute ::= boolproperty */
2266
+ -2, /* (131) attribute ::= WITH withclause */
2267
+ -1, /* (132) go ::= GO */
2268
+ 0, /* (133) go ::= */
2269
+ -3, /* (134) even ::= UNTIL EVEN WITH */
2270
+ -2, /* (135) even ::= EVEN WITH */
2271
+ -1, /* (136) dashproperty ::= DOTTED */
2272
+ -1, /* (137) dashproperty ::= DASHED */
2273
+ -1, /* (138) colorproperty ::= FILL */
2274
+ -1, /* (139) colorproperty ::= COLOR */
2275
+ -1, /* (140) position ::= place */
2276
+ -2, /* (141) between ::= WAY BETWEEN */
2277
+ -1, /* (142) between ::= BETWEEN */
2278
+ -4, /* (143) between ::= OF THE WAY BETWEEN */
2279
+ -1, /* (144) place ::= place2 */
2280
+ -1, /* (145) edge ::= CENTER */
2281
+ -1, /* (146) edge ::= EDGEPT */
2282
+ -1, /* (147) edge ::= TOP */
2283
+ -1, /* (148) edge ::= BOTTOM */
2284
+ -1, /* (149) edge ::= START */
2285
+ -1, /* (150) edge ::= END */
2286
+ -1, /* (151) edge ::= RIGHT */
2287
+ -1, /* (152) edge ::= LEFT */
2288
+ -1, /* (153) object ::= objectname */
22692289
};
22702290
22712291
static void yy_accept(yyParser*); /* Forward Declaration */
22722292
22732293
/*
@@ -2354,647 +2374,652 @@
23542374
** #line <lineno> <thisfile>
23552375
** break;
23562376
*/
23572377
/********** Begin reduce actions **********************************************/
23582378
YYMINORTYPE yylhsminor;
2359
- case 0: /* document ::= element_list */
2360
-#line 506 "pikchr.y"
2361
-{pik_render(p,yymsp[0].minor.yy56);}
2362
-#line 2387 "pikchr.c"
2363
- break;
2364
- case 1: /* element_list ::= element */
2365
-#line 509 "pikchr.y"
2366
-{ yylhsminor.yy56 = pik_elist_append(p,0,yymsp[0].minor.yy226); }
2367
-#line 2392 "pikchr.c"
2368
- yymsp[0].minor.yy56 = yylhsminor.yy56;
2369
- break;
2370
- case 2: /* element_list ::= element_list EOL element */
2371
-#line 511 "pikchr.y"
2372
-{ yylhsminor.yy56 = pik_elist_append(p,yymsp[-2].minor.yy56,yymsp[0].minor.yy226); }
2373
-#line 2398 "pikchr.c"
2374
- yymsp[-2].minor.yy56 = yylhsminor.yy56;
2375
- break;
2376
- case 3: /* element ::= */
2377
-#line 514 "pikchr.y"
2378
-{ yymsp[1].minor.yy226 = 0; }
2379
-#line 2404 "pikchr.c"
2380
- break;
2381
- case 4: /* element ::= direction */
2382
-#line 515 "pikchr.y"
2383
-{ pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy226=0; }
2384
-#line 2409 "pikchr.c"
2385
- yymsp[0].minor.yy226 = yylhsminor.yy226;
2386
- break;
2387
- case 5: /* element ::= lvalue ASSIGN rvalue */
2388
-#line 516 "pikchr.y"
2389
-{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy257,&yymsp[-1].minor.yy0); yylhsminor.yy226=0;}
2390
-#line 2415 "pikchr.c"
2391
- yymsp[-2].minor.yy226 = yylhsminor.yy226;
2392
- break;
2393
- case 6: /* element ::= PLACENAME COLON unnamed_element */
2394
-#line 518 "pikchr.y"
2395
-{ yylhsminor.yy226 = yymsp[0].minor.yy226; pik_elem_setname(p,yymsp[0].minor.yy226,&yymsp[-2].minor.yy0); }
2396
-#line 2421 "pikchr.c"
2397
- yymsp[-2].minor.yy226 = yylhsminor.yy226;
2398
- break;
2399
- case 7: /* element ::= PLACENAME COLON position */
2400
-#line 520 "pikchr.y"
2401
-{ yylhsminor.yy226 = pik_elem_new(p,0,0,0);
2402
- if(yylhsminor.yy226){ yylhsminor.yy226->ptAt = yymsp[0].minor.yy175; pik_elem_setname(p,yylhsminor.yy226,&yymsp[-2].minor.yy0); }}
2403
-#line 2428 "pikchr.c"
2404
- yymsp[-2].minor.yy226 = yylhsminor.yy226;
2405
- break;
2406
- case 8: /* element ::= unnamed_element */
2407
-#line 522 "pikchr.y"
2408
-{yylhsminor.yy226 = yymsp[0].minor.yy226;}
2409
-#line 2434 "pikchr.c"
2410
- yymsp[0].minor.yy226 = yylhsminor.yy226;
2411
- break;
2412
- case 9: /* element ::= print prlist */
2413
-#line 523 "pikchr.y"
2414
-{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy226=0;}
2415
-#line 2440 "pikchr.c"
2416
- break;
2417
- case 10: /* element ::= ASSERT LP expr EQ expr RP */
2418
-#line 528 "pikchr.y"
2419
-{yymsp[-5].minor.yy226=pik_assert(p,yymsp[-3].minor.yy257,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy257);}
2420
-#line 2445 "pikchr.c"
2421
- break;
2422
- case 11: /* element ::= ASSERT LP position EQ position RP */
2379
+ case 0: /* document ::= statement_list */
2380
+#line 521 "pikchr.y"
2381
+{pik_render(p,yymsp[0].minor.yy191);}
2382
+#line 2407 "pikchr.c"
2383
+ break;
2384
+ case 1: /* statement_list ::= statement */
2385
+#line 524 "pikchr.y"
2386
+{ yylhsminor.yy191 = pik_elist_append(p,0,yymsp[0].minor.yy138); }
2387
+#line 2412 "pikchr.c"
2388
+ yymsp[0].minor.yy191 = yylhsminor.yy191;
2389
+ break;
2390
+ case 2: /* statement_list ::= statement_list EOL statement */
2391
+#line 526 "pikchr.y"
2392
+{ yylhsminor.yy191 = pik_elist_append(p,yymsp[-2].minor.yy191,yymsp[0].minor.yy138); }
2393
+#line 2418 "pikchr.c"
2394
+ yymsp[-2].minor.yy191 = yylhsminor.yy191;
2395
+ break;
2396
+ case 3: /* statement ::= */
2397
+#line 529 "pikchr.y"
2398
+{ yymsp[1].minor.yy138 = 0; }
2399
+#line 2424 "pikchr.c"
2400
+ break;
2401
+ case 4: /* statement ::= direction */
24232402
#line 530 "pikchr.y"
2424
-{yymsp[-5].minor.yy226=pik_position_assert(p,&yymsp[-3].minor.yy175,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy175);}
2425
-#line 2450 "pikchr.c"
2426
- break;
2427
- case 12: /* rvalue ::= PLACENAME */
2428
-#line 541 "pikchr.y"
2429
-{yylhsminor.yy257 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2430
-#line 2455 "pikchr.c"
2431
- yymsp[0].minor.yy257 = yylhsminor.yy257;
2432
- break;
2433
- case 13: /* pritem ::= FILL */
2434
- case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
2435
- case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
2403
+{ pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy138=0; }
2404
+#line 2429 "pikchr.c"
2405
+ yymsp[0].minor.yy138 = yylhsminor.yy138;
2406
+ break;
2407
+ case 5: /* statement ::= lvalue ASSIGN rvalue */
2408
+#line 531 "pikchr.y"
2409
+{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy121,&yymsp[-1].minor.yy0); yylhsminor.yy138=0;}
2410
+#line 2435 "pikchr.c"
2411
+ yymsp[-2].minor.yy138 = yylhsminor.yy138;
2412
+ break;
2413
+ case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2414
+#line 533 "pikchr.y"
2415
+{ yylhsminor.yy138 = yymsp[0].minor.yy138; pik_elem_setname(p,yymsp[0].minor.yy138,&yymsp[-2].minor.yy0); }
2416
+#line 2441 "pikchr.c"
2417
+ yymsp[-2].minor.yy138 = yylhsminor.yy138;
2418
+ break;
2419
+ case 7: /* statement ::= PLACENAME COLON position */
2420
+#line 535 "pikchr.y"
2421
+{ yylhsminor.yy138 = pik_elem_new(p,0,0,0);
2422
+ if(yylhsminor.yy138){ yylhsminor.yy138->ptAt = yymsp[0].minor.yy47; pik_elem_setname(p,yylhsminor.yy138,&yymsp[-2].minor.yy0); }}
2423
+#line 2448 "pikchr.c"
2424
+ yymsp[-2].minor.yy138 = yylhsminor.yy138;
2425
+ break;
2426
+ case 8: /* statement ::= unnamed_statement */
2427
+#line 537 "pikchr.y"
2428
+{yylhsminor.yy138 = yymsp[0].minor.yy138;}
2429
+#line 2454 "pikchr.c"
2430
+ yymsp[0].minor.yy138 = yylhsminor.yy138;
2431
+ break;
2432
+ case 9: /* statement ::= print prlist */
2433
+#line 538 "pikchr.y"
2434
+{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy138=0;}
2435
+#line 2460 "pikchr.c"
2436
+ break;
2437
+ case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2438
+#line 543 "pikchr.y"
2439
+{yymsp[-5].minor.yy138=pik_assert(p,yymsp[-3].minor.yy121,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy121);}
2440
+#line 2465 "pikchr.c"
2441
+ break;
2442
+ case 11: /* statement ::= ASSERT LP position EQ position RP */
2443
+#line 545 "pikchr.y"
2444
+{yymsp[-5].minor.yy138=pik_position_assert(p,&yymsp[-3].minor.yy47,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy47);}
2445
+#line 2470 "pikchr.c"
2446
+ break;
2447
+ case 12: /* statement ::= DEFINE ID CODEBLOCK */
24362448
#line 546 "pikchr.y"
2449
+{yymsp[-2].minor.yy138=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2450
+#line 2475 "pikchr.c"
2451
+ break;
2452
+ case 13: /* rvalue ::= PLACENAME */
2453
+#line 557 "pikchr.y"
2454
+{yylhsminor.yy121 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2455
+#line 2480 "pikchr.c"
2456
+ yymsp[0].minor.yy121 = yylhsminor.yy121;
2457
+ break;
2458
+ case 14: /* pritem ::= FILL */
2459
+ case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
2460
+ case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2461
+#line 562 "pikchr.y"
24372462
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2438
-#line 2463 "pikchr.c"
2439
- break;
2440
- case 16: /* pritem ::= rvalue */
2441
-#line 549 "pikchr.y"
2442
-{pik_append_num(p,"",yymsp[0].minor.yy257);}
2443
-#line 2468 "pikchr.c"
2444
- break;
2445
- case 17: /* pritem ::= STRING */
2446
-#line 550 "pikchr.y"
2463
+#line 2488 "pikchr.c"
2464
+ break;
2465
+ case 17: /* pritem ::= rvalue */
2466
+#line 565 "pikchr.y"
2467
+{pik_append_num(p,"",yymsp[0].minor.yy121);}
2468
+#line 2493 "pikchr.c"
2469
+ break;
2470
+ case 18: /* pritem ::= STRING */
2471
+#line 566 "pikchr.y"
24472472
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2448
-#line 2473 "pikchr.c"
2473
+#line 2498 "pikchr.c"
24492474
break;
2450
- case 18: /* prsep ::= COMMA */
2451
-#line 551 "pikchr.y"
2475
+ case 19: /* prsep ::= COMMA */
2476
+#line 567 "pikchr.y"
24522477
{pik_append(p, " ", 1);}
2453
-#line 2478 "pikchr.c"
2454
- break;
2455
- case 19: /* unnamed_element ::= basetype attribute_list */
2456
-#line 554 "pikchr.y"
2457
-{yylhsminor.yy226 = yymsp[-1].minor.yy226; pik_after_adding_attributes(p,yylhsminor.yy226);}
2458
-#line 2483 "pikchr.c"
2459
- yymsp[-1].minor.yy226 = yylhsminor.yy226;
2460
- break;
2461
- case 20: /* basetype ::= CLASSNAME */
2462
-#line 556 "pikchr.y"
2463
-{yylhsminor.yy226 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2464
-#line 2489 "pikchr.c"
2465
- yymsp[0].minor.yy226 = yylhsminor.yy226;
2466
- break;
2467
- case 21: /* basetype ::= STRING textposition */
2468
-#line 558 "pikchr.y"
2469
-{yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy116; yylhsminor.yy226 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2470
-#line 2495 "pikchr.c"
2471
- yymsp[-1].minor.yy226 = yylhsminor.yy226;
2472
- break;
2473
- case 22: /* basetype ::= LB savelist element_list RB */
2474
-#line 560 "pikchr.y"
2475
-{ p->list = yymsp[-2].minor.yy56; yymsp[-3].minor.yy226 = pik_elem_new(p,0,0,yymsp[-1].minor.yy56); if(yymsp[-3].minor.yy226) yymsp[-3].minor.yy226->errTok = yymsp[0].minor.yy0; }
2476
-#line 2501 "pikchr.c"
2477
- break;
2478
- case 23: /* savelist ::= */
2479
-#line 565 "pikchr.y"
2480
-{yymsp[1].minor.yy56 = p->list; p->list = 0;}
2481
-#line 2506 "pikchr.c"
2482
- break;
2483
- case 24: /* relexpr ::= expr */
2478
+#line 2503 "pikchr.c"
2479
+ break;
2480
+ case 20: /* unnamed_statement ::= basetype attribute_list */
2481
+#line 570 "pikchr.y"
2482
+{yylhsminor.yy138 = yymsp[-1].minor.yy138; pik_after_adding_attributes(p,yylhsminor.yy138);}
2483
+#line 2508 "pikchr.c"
2484
+ yymsp[-1].minor.yy138 = yylhsminor.yy138;
2485
+ break;
2486
+ case 21: /* basetype ::= CLASSNAME */
24842487
#line 572 "pikchr.y"
2485
-{yylhsminor.yy164.rAbs = yymsp[0].minor.yy257; yylhsminor.yy164.rRel = 0;}
2486
-#line 2511 "pikchr.c"
2487
- yymsp[0].minor.yy164 = yylhsminor.yy164;
2488
- break;
2489
- case 25: /* relexpr ::= expr PERCENT */
2490
-#line 573 "pikchr.y"
2491
-{yylhsminor.yy164.rAbs = 0; yylhsminor.yy164.rRel = yymsp[-1].minor.yy257/100;}
2492
-#line 2517 "pikchr.c"
2493
- yymsp[-1].minor.yy164 = yylhsminor.yy164;
2494
- break;
2495
- case 26: /* optrelexpr ::= */
2496
-#line 575 "pikchr.y"
2497
-{yymsp[1].minor.yy164.rAbs = 0; yymsp[1].minor.yy164.rRel = 1.0;}
2498
-#line 2523 "pikchr.c"
2499
- break;
2500
- case 27: /* attribute_list ::= relexpr alist */
2501
-#line 577 "pikchr.y"
2502
-{pik_add_direction(p,0,&yymsp[-1].minor.yy164);}
2503
-#line 2528 "pikchr.c"
2504
- break;
2505
- case 28: /* attribute ::= numproperty relexpr */
2488
+{yylhsminor.yy138 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2489
+#line 2514 "pikchr.c"
2490
+ yymsp[0].minor.yy138 = yylhsminor.yy138;
2491
+ break;
2492
+ case 22: /* basetype ::= STRING textposition */
2493
+#line 574 "pikchr.y"
2494
+{yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy46; yylhsminor.yy138 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2495
+#line 2520 "pikchr.c"
2496
+ yymsp[-1].minor.yy138 = yylhsminor.yy138;
2497
+ break;
2498
+ case 23: /* basetype ::= LB savelist statement_list RB */
2499
+#line 576 "pikchr.y"
2500
+{ p->list = yymsp[-2].minor.yy191; yymsp[-3].minor.yy138 = pik_elem_new(p,0,0,yymsp[-1].minor.yy191); if(yymsp[-3].minor.yy138) yymsp[-3].minor.yy138->errTok = yymsp[0].minor.yy0; }
2501
+#line 2526 "pikchr.c"
2502
+ break;
2503
+ case 24: /* savelist ::= */
25062504
#line 581 "pikchr.y"
2507
-{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy164); }
2508
-#line 2533 "pikchr.c"
2509
- break;
2510
- case 29: /* attribute ::= dashproperty expr */
2511
-#line 582 "pikchr.y"
2512
-{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy257); }
2513
-#line 2538 "pikchr.c"
2514
- break;
2515
- case 30: /* attribute ::= dashproperty */
2516
-#line 583 "pikchr.y"
2517
-{ pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2518
-#line 2543 "pikchr.c"
2519
- break;
2520
- case 31: /* attribute ::= colorproperty rvalue */
2521
-#line 584 "pikchr.y"
2522
-{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy257); }
2505
+{yymsp[1].minor.yy191 = p->list; p->list = 0;}
2506
+#line 2531 "pikchr.c"
2507
+ break;
2508
+ case 25: /* relexpr ::= expr */
2509
+#line 588 "pikchr.y"
2510
+{yylhsminor.yy134.rAbs = yymsp[0].minor.yy121; yylhsminor.yy134.rRel = 0;}
2511
+#line 2536 "pikchr.c"
2512
+ yymsp[0].minor.yy134 = yylhsminor.yy134;
2513
+ break;
2514
+ case 26: /* relexpr ::= expr PERCENT */
2515
+#line 589 "pikchr.y"
2516
+{yylhsminor.yy134.rAbs = 0; yylhsminor.yy134.rRel = yymsp[-1].minor.yy121/100;}
2517
+#line 2542 "pikchr.c"
2518
+ yymsp[-1].minor.yy134 = yylhsminor.yy134;
2519
+ break;
2520
+ case 27: /* optrelexpr ::= */
2521
+#line 591 "pikchr.y"
2522
+{yymsp[1].minor.yy134.rAbs = 0; yymsp[1].minor.yy134.rRel = 1.0;}
25232523
#line 2548 "pikchr.c"
25242524
break;
2525
- case 32: /* attribute ::= go direction optrelexpr */
2526
-#line 585 "pikchr.y"
2527
-{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy164);}
2525
+ case 28: /* attribute_list ::= relexpr alist */
2526
+#line 593 "pikchr.y"
2527
+{pik_add_direction(p,0,&yymsp[-1].minor.yy134);}
25282528
#line 2553 "pikchr.c"
25292529
break;
2530
- case 33: /* attribute ::= go direction even position */
2531
-#line 586 "pikchr.y"
2532
-{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy175);}
2530
+ case 29: /* attribute ::= numproperty relexpr */
2531
+#line 597 "pikchr.y"
2532
+{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy134); }
25332533
#line 2558 "pikchr.c"
25342534
break;
2535
- case 34: /* attribute ::= CLOSE */
2536
-#line 587 "pikchr.y"
2537
-{ pik_close_path(p,&yymsp[0].minor.yy0); }
2535
+ case 30: /* attribute ::= dashproperty expr */
2536
+#line 598 "pikchr.y"
2537
+{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy121); }
25382538
#line 2563 "pikchr.c"
25392539
break;
2540
- case 35: /* attribute ::= CHOP */
2541
-#line 588 "pikchr.y"
2542
-{ p->cur->bChop = 1; }
2540
+ case 31: /* attribute ::= dashproperty */
2541
+#line 599 "pikchr.y"
2542
+{ pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
25432543
#line 2568 "pikchr.c"
25442544
break;
2545
- case 36: /* attribute ::= FROM position */
2546
-#line 589 "pikchr.y"
2547
-{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy175); }
2545
+ case 32: /* attribute ::= colorproperty rvalue */
2546
+#line 600 "pikchr.y"
2547
+{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy121); }
25482548
#line 2573 "pikchr.c"
25492549
break;
2550
- case 37: /* attribute ::= TO position */
2551
-#line 590 "pikchr.y"
2552
-{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy175); }
2550
+ case 33: /* attribute ::= go direction optrelexpr */
2551
+#line 601 "pikchr.y"
2552
+{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy134);}
25532553
#line 2578 "pikchr.c"
25542554
break;
2555
- case 38: /* attribute ::= THEN */
2556
-#line 591 "pikchr.y"
2557
-{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2555
+ case 34: /* attribute ::= go direction even position */
2556
+#line 602 "pikchr.y"
2557
+{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy47);}
25582558
#line 2583 "pikchr.c"
25592559
break;
2560
- case 39: /* attribute ::= THEN optrelexpr HEADING expr */
2561
- case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
2562
-#line 593 "pikchr.y"
2563
-{pik_move_hdg(p,&yymsp[-2].minor.yy164,&yymsp[-1].minor.yy0,yymsp[0].minor.yy257,0,&yymsp[-3].minor.yy0);}
2564
-#line 2589 "pikchr.c"
2565
- break;
2566
- case 40: /* attribute ::= THEN optrelexpr EDGEPT */
2567
- case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
2568
-#line 594 "pikchr.y"
2569
-{pik_move_hdg(p,&yymsp[-1].minor.yy164,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2570
-#line 2595 "pikchr.c"
2571
- break;
2572
- case 43: /* attribute ::= AT position */
2573
-#line 599 "pikchr.y"
2574
-{ pik_set_at(p,0,&yymsp[0].minor.yy175,&yymsp[-1].minor.yy0); }
2575
-#line 2600 "pikchr.c"
2576
- break;
2577
- case 44: /* attribute ::= SAME */
2578
-#line 601 "pikchr.y"
2579
-{pik_same(p,0,&yymsp[0].minor.yy0);}
2580
-#line 2605 "pikchr.c"
2581
- break;
2582
- case 45: /* attribute ::= SAME AS object */
2583
-#line 602 "pikchr.y"
2584
-{pik_same(p,yymsp[0].minor.yy226,&yymsp[-2].minor.yy0);}
2585
-#line 2610 "pikchr.c"
2586
- break;
2587
- case 46: /* attribute ::= STRING textposition */
2560
+ case 35: /* attribute ::= CLOSE */
25882561
#line 603 "pikchr.y"
2589
-{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy116);}
2590
-#line 2615 "pikchr.c"
2562
+{ pik_close_path(p,&yymsp[0].minor.yy0); }
2563
+#line 2588 "pikchr.c"
25912564
break;
2592
- case 47: /* attribute ::= FIT */
2565
+ case 36: /* attribute ::= CHOP */
25932566
#line 604 "pikchr.y"
2594
-{pik_size_to_fit(p,&yymsp[0].minor.yy0); }
2567
+{ p->cur->bChop = 1; }
2568
+#line 2593 "pikchr.c"
2569
+ break;
2570
+ case 37: /* attribute ::= FROM position */
2571
+#line 605 "pikchr.y"
2572
+{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy47); }
2573
+#line 2598 "pikchr.c"
2574
+ break;
2575
+ case 38: /* attribute ::= TO position */
2576
+#line 606 "pikchr.y"
2577
+{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy47); }
2578
+#line 2603 "pikchr.c"
2579
+ break;
2580
+ case 39: /* attribute ::= THEN */
2581
+#line 607 "pikchr.y"
2582
+{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2583
+#line 2608 "pikchr.c"
2584
+ break;
2585
+ case 40: /* attribute ::= THEN optrelexpr HEADING expr */
2586
+ case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2587
+#line 609 "pikchr.y"
2588
+{pik_move_hdg(p,&yymsp[-2].minor.yy134,&yymsp[-1].minor.yy0,yymsp[0].minor.yy121,0,&yymsp[-3].minor.yy0);}
2589
+#line 2614 "pikchr.c"
2590
+ break;
2591
+ case 41: /* attribute ::= THEN optrelexpr EDGEPT */
2592
+ case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2593
+#line 610 "pikchr.y"
2594
+{pik_move_hdg(p,&yymsp[-1].minor.yy134,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
25952595
#line 2620 "pikchr.c"
25962596
break;
2597
- case 48: /* attribute ::= BEHIND object */
2598
-#line 605 "pikchr.y"
2599
-{pik_behind(p,yymsp[0].minor.yy226);}
2597
+ case 44: /* attribute ::= AT position */
2598
+#line 615 "pikchr.y"
2599
+{ pik_set_at(p,0,&yymsp[0].minor.yy47,&yymsp[-1].minor.yy0); }
26002600
#line 2625 "pikchr.c"
26012601
break;
2602
- case 49: /* withclause ::= DOT_E edge AT position */
2603
- case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
2604
-#line 613 "pikchr.y"
2605
-{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy175,&yymsp[-1].minor.yy0); }
2606
-#line 2631 "pikchr.c"
2607
- break;
2608
- case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2602
+ case 45: /* attribute ::= SAME */
26092603
#line 617 "pikchr.y"
2604
+{pik_same(p,0,&yymsp[0].minor.yy0);}
2605
+#line 2630 "pikchr.c"
2606
+ break;
2607
+ case 46: /* attribute ::= SAME AS object */
2608
+#line 618 "pikchr.y"
2609
+{pik_same(p,yymsp[0].minor.yy138,&yymsp[-2].minor.yy0);}
2610
+#line 2635 "pikchr.c"
2611
+ break;
2612
+ case 47: /* attribute ::= STRING textposition */
2613
+#line 619 "pikchr.y"
2614
+{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy46);}
2615
+#line 2640 "pikchr.c"
2616
+ break;
2617
+ case 48: /* attribute ::= FIT */
2618
+#line 620 "pikchr.y"
2619
+{pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2620
+#line 2645 "pikchr.c"
2621
+ break;
2622
+ case 49: /* attribute ::= BEHIND object */
2623
+#line 621 "pikchr.y"
2624
+{pik_behind(p,yymsp[0].minor.yy138);}
2625
+#line 2650 "pikchr.c"
2626
+ break;
2627
+ case 50: /* withclause ::= DOT_E edge AT position */
2628
+ case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2629
+#line 629 "pikchr.y"
2630
+{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy47,&yymsp[-1].minor.yy0); }
2631
+#line 2656 "pikchr.c"
2632
+ break;
2633
+ case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2634
+#line 633 "pikchr.y"
26102635
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
2611
-#line 2636 "pikchr.c"
2636
+#line 2661 "pikchr.c"
26122637
yymsp[0].minor.yy0 = yylhsminor.yy0;
26132638
break;
2614
- case 52: /* boolproperty ::= CW */
2615
-#line 628 "pikchr.y"
2639
+ case 53: /* boolproperty ::= CW */
2640
+#line 644 "pikchr.y"
26162641
{p->cur->cw = 1;}
2617
-#line 2642 "pikchr.c"
2618
- break;
2619
- case 53: /* boolproperty ::= CCW */
2620
-#line 629 "pikchr.y"
2621
-{p->cur->cw = 0;}
2622
-#line 2647 "pikchr.c"
2623
- break;
2624
- case 54: /* boolproperty ::= LARROW */
2625
-#line 630 "pikchr.y"
2626
-{p->cur->larrow=1; p->cur->rarrow=0; }
2627
-#line 2652 "pikchr.c"
2628
- break;
2629
- case 55: /* boolproperty ::= RARROW */
2630
-#line 631 "pikchr.y"
2631
-{p->cur->larrow=0; p->cur->rarrow=1; }
2632
-#line 2657 "pikchr.c"
2633
- break;
2634
- case 56: /* boolproperty ::= LRARROW */
2635
-#line 632 "pikchr.y"
2636
-{p->cur->larrow=1; p->cur->rarrow=1; }
2637
-#line 2662 "pikchr.c"
2638
- break;
2639
- case 57: /* boolproperty ::= INVIS */
2640
-#line 633 "pikchr.y"
2641
-{p->cur->sw = 0.0;}
26422642
#line 2667 "pikchr.c"
26432643
break;
2644
- case 58: /* boolproperty ::= THICK */
2645
-#line 634 "pikchr.y"
2646
-{p->cur->sw *= 1.5;}
2644
+ case 54: /* boolproperty ::= CCW */
2645
+#line 645 "pikchr.y"
2646
+{p->cur->cw = 0;}
26472647
#line 2672 "pikchr.c"
26482648
break;
2649
- case 59: /* boolproperty ::= THIN */
2650
-#line 635 "pikchr.y"
2651
-{p->cur->sw *= 0.67;}
2649
+ case 55: /* boolproperty ::= LARROW */
2650
+#line 646 "pikchr.y"
2651
+{p->cur->larrow=1; p->cur->rarrow=0; }
26522652
#line 2677 "pikchr.c"
26532653
break;
2654
- case 60: /* textposition ::= */
2655
-#line 637 "pikchr.y"
2656
-{yymsp[1].minor.yy116 = 0;}
2654
+ case 56: /* boolproperty ::= RARROW */
2655
+#line 647 "pikchr.y"
2656
+{p->cur->larrow=0; p->cur->rarrow=1; }
26572657
#line 2682 "pikchr.c"
26582658
break;
2659
- case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2660
-#line 640 "pikchr.y"
2661
-{yylhsminor.yy116 = pik_text_position(yymsp[-1].minor.yy116,&yymsp[0].minor.yy0);}
2659
+ case 57: /* boolproperty ::= LRARROW */
2660
+#line 648 "pikchr.y"
2661
+{p->cur->larrow=1; p->cur->rarrow=1; }
26622662
#line 2687 "pikchr.c"
2663
- yymsp[-1].minor.yy116 = yylhsminor.yy116;
2664
- break;
2665
- case 62: /* position ::= expr COMMA expr */
2666
-#line 643 "pikchr.y"
2667
-{yylhsminor.yy175.x=yymsp[-2].minor.yy257; yylhsminor.yy175.y=yymsp[0].minor.yy257;}
2668
-#line 2693 "pikchr.c"
2669
- yymsp[-2].minor.yy175 = yylhsminor.yy175;
2670
- break;
2671
- case 63: /* position ::= place PLUS expr COMMA expr */
2672
-#line 645 "pikchr.y"
2673
-{yylhsminor.yy175.x=yymsp[-4].minor.yy175.x+yymsp[-2].minor.yy257; yylhsminor.yy175.y=yymsp[-4].minor.yy175.y+yymsp[0].minor.yy257;}
2674
-#line 2699 "pikchr.c"
2675
- yymsp[-4].minor.yy175 = yylhsminor.yy175;
2676
- break;
2677
- case 64: /* position ::= place MINUS expr COMMA expr */
2678
-#line 646 "pikchr.y"
2679
-{yylhsminor.yy175.x=yymsp[-4].minor.yy175.x-yymsp[-2].minor.yy257; yylhsminor.yy175.y=yymsp[-4].minor.yy175.y-yymsp[0].minor.yy257;}
2680
-#line 2705 "pikchr.c"
2681
- yymsp[-4].minor.yy175 = yylhsminor.yy175;
2682
- break;
2683
- case 65: /* position ::= place PLUS LP expr COMMA expr RP */
2684
-#line 648 "pikchr.y"
2685
-{yylhsminor.yy175.x=yymsp[-6].minor.yy175.x+yymsp[-3].minor.yy257; yylhsminor.yy175.y=yymsp[-6].minor.yy175.y+yymsp[-1].minor.yy257;}
2686
-#line 2711 "pikchr.c"
2687
- yymsp[-6].minor.yy175 = yylhsminor.yy175;
2688
- break;
2689
- case 66: /* position ::= place MINUS LP expr COMMA expr RP */
2663
+ break;
2664
+ case 58: /* boolproperty ::= INVIS */
2665
+#line 649 "pikchr.y"
2666
+{p->cur->sw = 0.0;}
2667
+#line 2692 "pikchr.c"
2668
+ break;
2669
+ case 59: /* boolproperty ::= THICK */
26902670
#line 650 "pikchr.y"
2691
-{yylhsminor.yy175.x=yymsp[-6].minor.yy175.x-yymsp[-3].minor.yy257; yylhsminor.yy175.y=yymsp[-6].minor.yy175.y-yymsp[-1].minor.yy257;}
2692
-#line 2717 "pikchr.c"
2693
- yymsp[-6].minor.yy175 = yylhsminor.yy175;
2671
+{p->cur->sw *= 1.5;}
2672
+#line 2697 "pikchr.c"
26942673
break;
2695
- case 67: /* position ::= LP position COMMA position RP */
2674
+ case 60: /* boolproperty ::= THIN */
26962675
#line 651 "pikchr.y"
2697
-{yymsp[-4].minor.yy175.x=yymsp[-3].minor.yy175.x; yymsp[-4].minor.yy175.y=yymsp[-1].minor.yy175.y;}
2698
-#line 2723 "pikchr.c"
2699
- break;
2700
- case 68: /* position ::= LP position RP */
2701
-#line 652 "pikchr.y"
2702
-{yymsp[-2].minor.yy175=yymsp[-1].minor.yy175;}
2703
-#line 2728 "pikchr.c"
2704
- break;
2705
- case 69: /* position ::= expr between position AND position */
2706
-#line 654 "pikchr.y"
2707
-{yylhsminor.yy175 = pik_position_between(yymsp[-4].minor.yy257,yymsp[-2].minor.yy175,yymsp[0].minor.yy175);}
2708
-#line 2733 "pikchr.c"
2709
- yymsp[-4].minor.yy175 = yylhsminor.yy175;
2710
- break;
2711
- case 70: /* position ::= expr LT position COMMA position GT */
2676
+{p->cur->sw *= 0.67;}
2677
+#line 2702 "pikchr.c"
2678
+ break;
2679
+ case 61: /* textposition ::= */
2680
+#line 653 "pikchr.y"
2681
+{yymsp[1].minor.yy46 = 0;}
2682
+#line 2707 "pikchr.c"
2683
+ break;
2684
+ case 62: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
27122685
#line 656 "pikchr.y"
2713
-{yylhsminor.yy175 = pik_position_between(yymsp[-5].minor.yy257,yymsp[-3].minor.yy175,yymsp[-1].minor.yy175);}
2714
-#line 2739 "pikchr.c"
2715
- yymsp[-5].minor.yy175 = yylhsminor.yy175;
2716
- break;
2717
- case 71: /* position ::= expr ABOVE position */
2718
-#line 657 "pikchr.y"
2719
-{yylhsminor.yy175=yymsp[0].minor.yy175; yylhsminor.yy175.y += yymsp[-2].minor.yy257;}
2720
-#line 2745 "pikchr.c"
2721
- yymsp[-2].minor.yy175 = yylhsminor.yy175;
2722
- break;
2723
- case 72: /* position ::= expr BELOW position */
2724
-#line 658 "pikchr.y"
2725
-{yylhsminor.yy175=yymsp[0].minor.yy175; yylhsminor.yy175.y -= yymsp[-2].minor.yy257;}
2726
-#line 2751 "pikchr.c"
2727
- yymsp[-2].minor.yy175 = yylhsminor.yy175;
2728
- break;
2729
- case 73: /* position ::= expr LEFT OF position */
2686
+{yylhsminor.yy46 = pik_text_position(yymsp[-1].minor.yy46,&yymsp[0].minor.yy0);}
2687
+#line 2712 "pikchr.c"
2688
+ yymsp[-1].minor.yy46 = yylhsminor.yy46;
2689
+ break;
2690
+ case 63: /* position ::= expr COMMA expr */
27302691
#line 659 "pikchr.y"
2731
-{yylhsminor.yy175=yymsp[0].minor.yy175; yylhsminor.yy175.x -= yymsp[-3].minor.yy257;}
2732
-#line 2757 "pikchr.c"
2733
- yymsp[-3].minor.yy175 = yylhsminor.yy175;
2734
- break;
2735
- case 74: /* position ::= expr RIGHT OF position */
2736
-#line 660 "pikchr.y"
2737
-{yylhsminor.yy175=yymsp[0].minor.yy175; yylhsminor.yy175.x += yymsp[-3].minor.yy257;}
2738
-#line 2763 "pikchr.c"
2739
- yymsp[-3].minor.yy175 = yylhsminor.yy175;
2740
- break;
2741
- case 75: /* position ::= expr ON HEADING EDGEPT OF position */
2692
+{yylhsminor.yy47.x=yymsp[-2].minor.yy121; yylhsminor.yy47.y=yymsp[0].minor.yy121;}
2693
+#line 2718 "pikchr.c"
2694
+ yymsp[-2].minor.yy47 = yylhsminor.yy47;
2695
+ break;
2696
+ case 64: /* position ::= place PLUS expr COMMA expr */
2697
+#line 661 "pikchr.y"
2698
+{yylhsminor.yy47.x=yymsp[-4].minor.yy47.x+yymsp[-2].minor.yy121; yylhsminor.yy47.y=yymsp[-4].minor.yy47.y+yymsp[0].minor.yy121;}
2699
+#line 2724 "pikchr.c"
2700
+ yymsp[-4].minor.yy47 = yylhsminor.yy47;
2701
+ break;
2702
+ case 65: /* position ::= place MINUS expr COMMA expr */
27422703
#line 662 "pikchr.y"
2743
-{yylhsminor.yy175 = pik_position_at_hdg(yymsp[-5].minor.yy257,&yymsp[-2].minor.yy0,yymsp[0].minor.yy175);}
2744
-#line 2769 "pikchr.c"
2745
- yymsp[-5].minor.yy175 = yylhsminor.yy175;
2704
+{yylhsminor.yy47.x=yymsp[-4].minor.yy47.x-yymsp[-2].minor.yy121; yylhsminor.yy47.y=yymsp[-4].minor.yy47.y-yymsp[0].minor.yy121;}
2705
+#line 2730 "pikchr.c"
2706
+ yymsp[-4].minor.yy47 = yylhsminor.yy47;
27462707
break;
2747
- case 76: /* position ::= expr HEADING EDGEPT OF position */
2708
+ case 66: /* position ::= place PLUS LP expr COMMA expr RP */
27482709
#line 664 "pikchr.y"
2749
-{yylhsminor.yy175 = pik_position_at_hdg(yymsp[-4].minor.yy257,&yymsp[-2].minor.yy0,yymsp[0].minor.yy175);}
2750
-#line 2775 "pikchr.c"
2751
- yymsp[-4].minor.yy175 = yylhsminor.yy175;
2710
+{yylhsminor.yy47.x=yymsp[-6].minor.yy47.x+yymsp[-3].minor.yy121; yylhsminor.yy47.y=yymsp[-6].minor.yy47.y+yymsp[-1].minor.yy121;}
2711
+#line 2736 "pikchr.c"
2712
+ yymsp[-6].minor.yy47 = yylhsminor.yy47;
27522713
break;
2753
- case 77: /* position ::= expr EDGEPT OF position */
2714
+ case 67: /* position ::= place MINUS LP expr COMMA expr RP */
27542715
#line 666 "pikchr.y"
2755
-{yylhsminor.yy175 = pik_position_at_hdg(yymsp[-3].minor.yy257,&yymsp[-2].minor.yy0,yymsp[0].minor.yy175);}
2756
-#line 2781 "pikchr.c"
2757
- yymsp[-3].minor.yy175 = yylhsminor.yy175;
2716
+{yylhsminor.yy47.x=yymsp[-6].minor.yy47.x-yymsp[-3].minor.yy121; yylhsminor.yy47.y=yymsp[-6].minor.yy47.y-yymsp[-1].minor.yy121;}
2717
+#line 2742 "pikchr.c"
2718
+ yymsp[-6].minor.yy47 = yylhsminor.yy47;
2719
+ break;
2720
+ case 68: /* position ::= LP position COMMA position RP */
2721
+#line 667 "pikchr.y"
2722
+{yymsp[-4].minor.yy47.x=yymsp[-3].minor.yy47.x; yymsp[-4].minor.yy47.y=yymsp[-1].minor.yy47.y;}
2723
+#line 2748 "pikchr.c"
27582724
break;
2759
- case 78: /* position ::= expr ON HEADING expr FROM position */
2725
+ case 69: /* position ::= LP position RP */
27602726
#line 668 "pikchr.y"
2761
-{yylhsminor.yy175 = pik_position_at_angle(yymsp[-5].minor.yy257,yymsp[-2].minor.yy257,yymsp[0].minor.yy175);}
2762
-#line 2787 "pikchr.c"
2763
- yymsp[-5].minor.yy175 = yylhsminor.yy175;
2727
+{yymsp[-2].minor.yy47=yymsp[-1].minor.yy47;}
2728
+#line 2753 "pikchr.c"
27642729
break;
2765
- case 79: /* position ::= expr HEADING expr FROM position */
2730
+ case 70: /* position ::= expr between position AND position */
27662731
#line 670 "pikchr.y"
2767
-{yylhsminor.yy175 = pik_position_at_angle(yymsp[-4].minor.yy257,yymsp[-2].minor.yy257,yymsp[0].minor.yy175);}
2768
-#line 2793 "pikchr.c"
2769
- yymsp[-4].minor.yy175 = yylhsminor.yy175;
2732
+{yylhsminor.yy47 = pik_position_between(yymsp[-4].minor.yy121,yymsp[-2].minor.yy47,yymsp[0].minor.yy47);}
2733
+#line 2758 "pikchr.c"
2734
+ yymsp[-4].minor.yy47 = yylhsminor.yy47;
2735
+ break;
2736
+ case 71: /* position ::= expr LT position COMMA position GT */
2737
+#line 672 "pikchr.y"
2738
+{yylhsminor.yy47 = pik_position_between(yymsp[-5].minor.yy121,yymsp[-3].minor.yy47,yymsp[-1].minor.yy47);}
2739
+#line 2764 "pikchr.c"
2740
+ yymsp[-5].minor.yy47 = yylhsminor.yy47;
2741
+ break;
2742
+ case 72: /* position ::= expr ABOVE position */
2743
+#line 673 "pikchr.y"
2744
+{yylhsminor.yy47=yymsp[0].minor.yy47; yylhsminor.yy47.y += yymsp[-2].minor.yy121;}
2745
+#line 2770 "pikchr.c"
2746
+ yymsp[-2].minor.yy47 = yylhsminor.yy47;
2747
+ break;
2748
+ case 73: /* position ::= expr BELOW position */
2749
+#line 674 "pikchr.y"
2750
+{yylhsminor.yy47=yymsp[0].minor.yy47; yylhsminor.yy47.y -= yymsp[-2].minor.yy121;}
2751
+#line 2776 "pikchr.c"
2752
+ yymsp[-2].minor.yy47 = yylhsminor.yy47;
2753
+ break;
2754
+ case 74: /* position ::= expr LEFT OF position */
2755
+#line 675 "pikchr.y"
2756
+{yylhsminor.yy47=yymsp[0].minor.yy47; yylhsminor.yy47.x -= yymsp[-3].minor.yy121;}
2757
+#line 2782 "pikchr.c"
2758
+ yymsp[-3].minor.yy47 = yylhsminor.yy47;
2759
+ break;
2760
+ case 75: /* position ::= expr RIGHT OF position */
2761
+#line 676 "pikchr.y"
2762
+{yylhsminor.yy47=yymsp[0].minor.yy47; yylhsminor.yy47.x += yymsp[-3].minor.yy121;}
2763
+#line 2788 "pikchr.c"
2764
+ yymsp[-3].minor.yy47 = yylhsminor.yy47;
2765
+ break;
2766
+ case 76: /* position ::= expr ON HEADING EDGEPT OF position */
2767
+#line 678 "pikchr.y"
2768
+{yylhsminor.yy47 = pik_position_at_hdg(yymsp[-5].minor.yy121,&yymsp[-2].minor.yy0,yymsp[0].minor.yy47);}
2769
+#line 2794 "pikchr.c"
2770
+ yymsp[-5].minor.yy47 = yylhsminor.yy47;
2771
+ break;
2772
+ case 77: /* position ::= expr HEADING EDGEPT OF position */
2773
+#line 680 "pikchr.y"
2774
+{yylhsminor.yy47 = pik_position_at_hdg(yymsp[-4].minor.yy121,&yymsp[-2].minor.yy0,yymsp[0].minor.yy47);}
2775
+#line 2800 "pikchr.c"
2776
+ yymsp[-4].minor.yy47 = yylhsminor.yy47;
27702777
break;
2771
- case 80: /* place ::= edge OF object */
2778
+ case 78: /* position ::= expr EDGEPT OF position */
27722779
#line 682 "pikchr.y"
2773
-{yylhsminor.yy175 = pik_place_of_elem(p,yymsp[0].minor.yy226,&yymsp[-2].minor.yy0);}
2774
-#line 2799 "pikchr.c"
2775
- yymsp[-2].minor.yy175 = yylhsminor.yy175;
2776
- break;
2777
- case 81: /* place2 ::= object */
2778
-#line 683 "pikchr.y"
2779
-{yylhsminor.yy175 = pik_place_of_elem(p,yymsp[0].minor.yy226,0);}
2780
-#line 2805 "pikchr.c"
2781
- yymsp[0].minor.yy175 = yylhsminor.yy175;
2782
- break;
2783
- case 82: /* place2 ::= object DOT_E edge */
2780
+{yylhsminor.yy47 = pik_position_at_hdg(yymsp[-3].minor.yy121,&yymsp[-2].minor.yy0,yymsp[0].minor.yy47);}
2781
+#line 2806 "pikchr.c"
2782
+ yymsp[-3].minor.yy47 = yylhsminor.yy47;
2783
+ break;
2784
+ case 79: /* position ::= expr ON HEADING expr FROM position */
27842785
#line 684 "pikchr.y"
2785
-{yylhsminor.yy175 = pik_place_of_elem(p,yymsp[-2].minor.yy226,&yymsp[0].minor.yy0);}
2786
-#line 2811 "pikchr.c"
2787
- yymsp[-2].minor.yy175 = yylhsminor.yy175;
2788
- break;
2789
- case 83: /* place2 ::= NTH VERTEX OF object */
2790
-#line 685 "pikchr.y"
2791
-{yylhsminor.yy175 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy226);}
2792
-#line 2817 "pikchr.c"
2793
- yymsp[-3].minor.yy175 = yylhsminor.yy175;
2794
- break;
2795
- case 84: /* object ::= nth */
2796
-#line 697 "pikchr.y"
2797
-{yylhsminor.yy226 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2798
-#line 2823 "pikchr.c"
2799
- yymsp[0].minor.yy226 = yylhsminor.yy226;
2800
- break;
2801
- case 85: /* object ::= nth OF|IN object */
2786
+{yylhsminor.yy47 = pik_position_at_angle(yymsp[-5].minor.yy121,yymsp[-2].minor.yy121,yymsp[0].minor.yy47);}
2787
+#line 2812 "pikchr.c"
2788
+ yymsp[-5].minor.yy47 = yylhsminor.yy47;
2789
+ break;
2790
+ case 80: /* position ::= expr HEADING expr FROM position */
2791
+#line 686 "pikchr.y"
2792
+{yylhsminor.yy47 = pik_position_at_angle(yymsp[-4].minor.yy121,yymsp[-2].minor.yy121,yymsp[0].minor.yy47);}
2793
+#line 2818 "pikchr.c"
2794
+ yymsp[-4].minor.yy47 = yylhsminor.yy47;
2795
+ break;
2796
+ case 81: /* place ::= edge OF object */
28022797
#line 698 "pikchr.y"
2803
-{yylhsminor.yy226 = pik_find_nth(p,yymsp[0].minor.yy226,&yymsp[-2].minor.yy0);}
2804
-#line 2829 "pikchr.c"
2805
- yymsp[-2].minor.yy226 = yylhsminor.yy226;
2798
+{yylhsminor.yy47 = pik_place_of_elem(p,yymsp[0].minor.yy138,&yymsp[-2].minor.yy0);}
2799
+#line 2824 "pikchr.c"
2800
+ yymsp[-2].minor.yy47 = yylhsminor.yy47;
2801
+ break;
2802
+ case 82: /* place2 ::= object */
2803
+#line 699 "pikchr.y"
2804
+{yylhsminor.yy47 = pik_place_of_elem(p,yymsp[0].minor.yy138,0);}
2805
+#line 2830 "pikchr.c"
2806
+ yymsp[0].minor.yy47 = yylhsminor.yy47;
28062807
break;
2807
- case 86: /* objectname ::= PLACENAME */
2808
+ case 83: /* place2 ::= object DOT_E edge */
28082809
#line 700 "pikchr.y"
2809
-{yylhsminor.yy226 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2810
-#line 2835 "pikchr.c"
2811
- yymsp[0].minor.yy226 = yylhsminor.yy226;
2812
- break;
2813
- case 87: /* objectname ::= objectname DOT_U PLACENAME */
2814
-#line 702 "pikchr.y"
2815
-{yylhsminor.yy226 = pik_find_byname(p,yymsp[-2].minor.yy226,&yymsp[0].minor.yy0);}
2816
-#line 2841 "pikchr.c"
2817
- yymsp[-2].minor.yy226 = yylhsminor.yy226;
2818
- break;
2819
- case 88: /* nth ::= NTH CLASSNAME */
2820
-#line 704 "pikchr.y"
2810
+{yylhsminor.yy47 = pik_place_of_elem(p,yymsp[-2].minor.yy138,&yymsp[0].minor.yy0);}
2811
+#line 2836 "pikchr.c"
2812
+ yymsp[-2].minor.yy47 = yylhsminor.yy47;
2813
+ break;
2814
+ case 84: /* place2 ::= NTH VERTEX OF object */
2815
+#line 701 "pikchr.y"
2816
+{yylhsminor.yy47 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy138);}
2817
+#line 2842 "pikchr.c"
2818
+ yymsp[-3].minor.yy47 = yylhsminor.yy47;
2819
+ break;
2820
+ case 85: /* object ::= nth */
2821
+#line 713 "pikchr.y"
2822
+{yylhsminor.yy138 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2823
+#line 2848 "pikchr.c"
2824
+ yymsp[0].minor.yy138 = yylhsminor.yy138;
2825
+ break;
2826
+ case 86: /* object ::= nth OF|IN object */
2827
+#line 714 "pikchr.y"
2828
+{yylhsminor.yy138 = pik_find_nth(p,yymsp[0].minor.yy138,&yymsp[-2].minor.yy0);}
2829
+#line 2854 "pikchr.c"
2830
+ yymsp[-2].minor.yy138 = yylhsminor.yy138;
2831
+ break;
2832
+ case 87: /* objectname ::= PLACENAME */
2833
+#line 716 "pikchr.y"
2834
+{yylhsminor.yy138 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2835
+#line 2860 "pikchr.c"
2836
+ yymsp[0].minor.yy138 = yylhsminor.yy138;
2837
+ break;
2838
+ case 88: /* objectname ::= objectname DOT_U PLACENAME */
2839
+#line 718 "pikchr.y"
2840
+{yylhsminor.yy138 = pik_find_byname(p,yymsp[-2].minor.yy138,&yymsp[0].minor.yy0);}
2841
+#line 2866 "pikchr.c"
2842
+ yymsp[-2].minor.yy138 = yylhsminor.yy138;
2843
+ break;
2844
+ case 89: /* nth ::= NTH CLASSNAME */
2845
+#line 720 "pikchr.y"
28212846
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2822
-#line 2847 "pikchr.c"
2847
+#line 2872 "pikchr.c"
28232848
yymsp[-1].minor.yy0 = yylhsminor.yy0;
28242849
break;
2825
- case 89: /* nth ::= NTH LAST CLASSNAME */
2826
-#line 705 "pikchr.y"
2850
+ case 90: /* nth ::= NTH LAST CLASSNAME */
2851
+#line 721 "pikchr.y"
28272852
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2828
-#line 2853 "pikchr.c"
2853
+#line 2878 "pikchr.c"
28292854
yymsp[-2].minor.yy0 = yylhsminor.yy0;
28302855
break;
2831
- case 90: /* nth ::= LAST CLASSNAME */
2832
-#line 706 "pikchr.y"
2856
+ case 91: /* nth ::= LAST CLASSNAME */
2857
+#line 722 "pikchr.y"
28332858
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2834
-#line 2859 "pikchr.c"
2859
+#line 2884 "pikchr.c"
28352860
break;
2836
- case 91: /* nth ::= LAST */
2837
-#line 707 "pikchr.y"
2861
+ case 92: /* nth ::= LAST */
2862
+#line 723 "pikchr.y"
28382863
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2839
-#line 2864 "pikchr.c"
2864
+#line 2889 "pikchr.c"
28402865
yymsp[0].minor.yy0 = yylhsminor.yy0;
28412866
break;
2842
- case 92: /* nth ::= NTH LB RB */
2843
-#line 708 "pikchr.y"
2867
+ case 93: /* nth ::= NTH LB RB */
2868
+#line 724 "pikchr.y"
28442869
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2845
-#line 2870 "pikchr.c"
2870
+#line 2895 "pikchr.c"
28462871
yymsp[-2].minor.yy0 = yylhsminor.yy0;
28472872
break;
2848
- case 93: /* nth ::= NTH LAST LB RB */
2849
-#line 709 "pikchr.y"
2873
+ case 94: /* nth ::= NTH LAST LB RB */
2874
+#line 725 "pikchr.y"
28502875
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2851
-#line 2876 "pikchr.c"
2876
+#line 2901 "pikchr.c"
28522877
yymsp[-3].minor.yy0 = yylhsminor.yy0;
28532878
break;
2854
- case 94: /* nth ::= LAST LB RB */
2855
-#line 710 "pikchr.y"
2856
-{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2857
-#line 2882 "pikchr.c"
2858
- break;
2859
- case 95: /* expr ::= expr PLUS expr */
2860
-#line 712 "pikchr.y"
2861
-{yylhsminor.yy257=yymsp[-2].minor.yy257+yymsp[0].minor.yy257;}
2862
-#line 2887 "pikchr.c"
2863
- yymsp[-2].minor.yy257 = yylhsminor.yy257;
2864
- break;
2865
- case 96: /* expr ::= expr MINUS expr */
2866
-#line 713 "pikchr.y"
2867
-{yylhsminor.yy257=yymsp[-2].minor.yy257-yymsp[0].minor.yy257;}
2868
-#line 2893 "pikchr.c"
2869
- yymsp[-2].minor.yy257 = yylhsminor.yy257;
2870
- break;
2871
- case 97: /* expr ::= expr STAR expr */
2872
-#line 714 "pikchr.y"
2873
-{yylhsminor.yy257=yymsp[-2].minor.yy257*yymsp[0].minor.yy257;}
2874
-#line 2899 "pikchr.c"
2875
- yymsp[-2].minor.yy257 = yylhsminor.yy257;
2876
- break;
2877
- case 98: /* expr ::= expr SLASH expr */
2878
-#line 715 "pikchr.y"
2879
-{
2880
- if( yymsp[0].minor.yy257==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy257 = 0.0; }
2881
- else{ yylhsminor.yy257 = yymsp[-2].minor.yy257/yymsp[0].minor.yy257; }
2882
-}
2883
-#line 2908 "pikchr.c"
2884
- yymsp[-2].minor.yy257 = yylhsminor.yy257;
2885
- break;
2886
- case 99: /* expr ::= MINUS expr */
2887
-#line 719 "pikchr.y"
2888
-{yymsp[-1].minor.yy257=-yymsp[0].minor.yy257;}
2889
-#line 2914 "pikchr.c"
2890
- break;
2891
- case 100: /* expr ::= PLUS expr */
2892
-#line 720 "pikchr.y"
2893
-{yymsp[-1].minor.yy257=yymsp[0].minor.yy257;}
2894
-#line 2919 "pikchr.c"
2895
- break;
2896
- case 101: /* expr ::= LP expr RP */
2897
-#line 721 "pikchr.y"
2898
-{yymsp[-2].minor.yy257=yymsp[-1].minor.yy257;}
2899
-#line 2924 "pikchr.c"
2900
- break;
2901
- case 102: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2902
-#line 722 "pikchr.y"
2903
-{yymsp[-2].minor.yy257=pik_get_var(p,&yymsp[-1].minor.yy0);}
2904
-#line 2929 "pikchr.c"
2905
- break;
2906
- case 103: /* expr ::= NUMBER */
2907
-#line 723 "pikchr.y"
2908
-{yylhsminor.yy257=pik_atof(&yymsp[0].minor.yy0);}
2909
-#line 2934 "pikchr.c"
2910
- yymsp[0].minor.yy257 = yylhsminor.yy257;
2911
- break;
2912
- case 104: /* expr ::= ID */
2913
-#line 724 "pikchr.y"
2914
-{yylhsminor.yy257=pik_get_var(p,&yymsp[0].minor.yy0);}
2915
-#line 2940 "pikchr.c"
2916
- yymsp[0].minor.yy257 = yylhsminor.yy257;
2917
- break;
2918
- case 105: /* expr ::= FUNC1 LP expr RP */
2919
-#line 725 "pikchr.y"
2920
-{yylhsminor.yy257 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy257,0.0);}
2921
-#line 2946 "pikchr.c"
2922
- yymsp[-3].minor.yy257 = yylhsminor.yy257;
2923
- break;
2924
- case 106: /* expr ::= FUNC2 LP expr COMMA expr RP */
2925
-#line 726 "pikchr.y"
2926
-{yylhsminor.yy257 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy257,yymsp[-1].minor.yy257);}
2927
-#line 2952 "pikchr.c"
2928
- yymsp[-5].minor.yy257 = yylhsminor.yy257;
2929
- break;
2930
- case 107: /* expr ::= DIST LP position COMMA position RP */
2931
-#line 727 "pikchr.y"
2932
-{yymsp[-5].minor.yy257 = pik_dist(&yymsp[-3].minor.yy175,&yymsp[-1].minor.yy175);}
2933
-#line 2958 "pikchr.c"
2934
- break;
2935
- case 108: /* expr ::= place2 DOT_XY X */
2936
-#line 728 "pikchr.y"
2937
-{yylhsminor.yy257 = yymsp[-2].minor.yy175.x;}
2938
-#line 2963 "pikchr.c"
2939
- yymsp[-2].minor.yy257 = yylhsminor.yy257;
2940
- break;
2941
- case 109: /* expr ::= place2 DOT_XY Y */
2942
-#line 729 "pikchr.y"
2943
-{yylhsminor.yy257 = yymsp[-2].minor.yy175.y;}
2944
-#line 2969 "pikchr.c"
2945
- yymsp[-2].minor.yy257 = yylhsminor.yy257;
2946
- break;
2947
- case 110: /* expr ::= object DOT_L numproperty */
2948
- case 111: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==111);
2949
- case 112: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==112);
2950
-#line 730 "pikchr.y"
2951
-{yylhsminor.yy257=pik_property_of(yymsp[-2].minor.yy226,&yymsp[0].minor.yy0);}
2952
-#line 2977 "pikchr.c"
2953
- yymsp[-2].minor.yy257 = yylhsminor.yy257;
2879
+ case 95: /* nth ::= LAST LB RB */
2880
+#line 726 "pikchr.y"
2881
+{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2882
+#line 2907 "pikchr.c"
2883
+ break;
2884
+ case 96: /* expr ::= expr PLUS expr */
2885
+#line 728 "pikchr.y"
2886
+{yylhsminor.yy121=yymsp[-2].minor.yy121+yymsp[0].minor.yy121;}
2887
+#line 2912 "pikchr.c"
2888
+ yymsp[-2].minor.yy121 = yylhsminor.yy121;
2889
+ break;
2890
+ case 97: /* expr ::= expr MINUS expr */
2891
+#line 729 "pikchr.y"
2892
+{yylhsminor.yy121=yymsp[-2].minor.yy121-yymsp[0].minor.yy121;}
2893
+#line 2918 "pikchr.c"
2894
+ yymsp[-2].minor.yy121 = yylhsminor.yy121;
2895
+ break;
2896
+ case 98: /* expr ::= expr STAR expr */
2897
+#line 730 "pikchr.y"
2898
+{yylhsminor.yy121=yymsp[-2].minor.yy121*yymsp[0].minor.yy121;}
2899
+#line 2924 "pikchr.c"
2900
+ yymsp[-2].minor.yy121 = yylhsminor.yy121;
2901
+ break;
2902
+ case 99: /* expr ::= expr SLASH expr */
2903
+#line 731 "pikchr.y"
2904
+{
2905
+ if( yymsp[0].minor.yy121==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy121 = 0.0; }
2906
+ else{ yylhsminor.yy121 = yymsp[-2].minor.yy121/yymsp[0].minor.yy121; }
2907
+}
2908
+#line 2933 "pikchr.c"
2909
+ yymsp[-2].minor.yy121 = yylhsminor.yy121;
2910
+ break;
2911
+ case 100: /* expr ::= MINUS expr */
2912
+#line 735 "pikchr.y"
2913
+{yymsp[-1].minor.yy121=-yymsp[0].minor.yy121;}
2914
+#line 2939 "pikchr.c"
2915
+ break;
2916
+ case 101: /* expr ::= PLUS expr */
2917
+#line 736 "pikchr.y"
2918
+{yymsp[-1].minor.yy121=yymsp[0].minor.yy121;}
2919
+#line 2944 "pikchr.c"
2920
+ break;
2921
+ case 102: /* expr ::= LP expr RP */
2922
+#line 737 "pikchr.y"
2923
+{yymsp[-2].minor.yy121=yymsp[-1].minor.yy121;}
2924
+#line 2949 "pikchr.c"
2925
+ break;
2926
+ case 103: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2927
+#line 738 "pikchr.y"
2928
+{yymsp[-2].minor.yy121=pik_get_var(p,&yymsp[-1].minor.yy0);}
2929
+#line 2954 "pikchr.c"
2930
+ break;
2931
+ case 104: /* expr ::= NUMBER */
2932
+#line 739 "pikchr.y"
2933
+{yylhsminor.yy121=pik_atof(&yymsp[0].minor.yy0);}
2934
+#line 2959 "pikchr.c"
2935
+ yymsp[0].minor.yy121 = yylhsminor.yy121;
2936
+ break;
2937
+ case 105: /* expr ::= ID */
2938
+#line 740 "pikchr.y"
2939
+{yylhsminor.yy121=pik_get_var(p,&yymsp[0].minor.yy0);}
2940
+#line 2965 "pikchr.c"
2941
+ yymsp[0].minor.yy121 = yylhsminor.yy121;
2942
+ break;
2943
+ case 106: /* expr ::= FUNC1 LP expr RP */
2944
+#line 741 "pikchr.y"
2945
+{yylhsminor.yy121 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy121,0.0);}
2946
+#line 2971 "pikchr.c"
2947
+ yymsp[-3].minor.yy121 = yylhsminor.yy121;
2948
+ break;
2949
+ case 107: /* expr ::= FUNC2 LP expr COMMA expr RP */
2950
+#line 742 "pikchr.y"
2951
+{yylhsminor.yy121 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy121,yymsp[-1].minor.yy121);}
2952
+#line 2977 "pikchr.c"
2953
+ yymsp[-5].minor.yy121 = yylhsminor.yy121;
2954
+ break;
2955
+ case 108: /* expr ::= DIST LP position COMMA position RP */
2956
+#line 743 "pikchr.y"
2957
+{yymsp[-5].minor.yy121 = pik_dist(&yymsp[-3].minor.yy47,&yymsp[-1].minor.yy47);}
2958
+#line 2983 "pikchr.c"
2959
+ break;
2960
+ case 109: /* expr ::= place2 DOT_XY X */
2961
+#line 744 "pikchr.y"
2962
+{yylhsminor.yy121 = yymsp[-2].minor.yy47.x;}
2963
+#line 2988 "pikchr.c"
2964
+ yymsp[-2].minor.yy121 = yylhsminor.yy121;
2965
+ break;
2966
+ case 110: /* expr ::= place2 DOT_XY Y */
2967
+#line 745 "pikchr.y"
2968
+{yylhsminor.yy121 = yymsp[-2].minor.yy47.y;}
2969
+#line 2994 "pikchr.c"
2970
+ yymsp[-2].minor.yy121 = yylhsminor.yy121;
2971
+ break;
2972
+ case 111: /* expr ::= object DOT_L numproperty */
2973
+ case 112: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==112);
2974
+ case 113: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==113);
2975
+#line 746 "pikchr.y"
2976
+{yylhsminor.yy121=pik_property_of(yymsp[-2].minor.yy138,&yymsp[0].minor.yy0);}
2977
+#line 3002 "pikchr.c"
2978
+ yymsp[-2].minor.yy121 = yylhsminor.yy121;
29542979
break;
29552980
default:
2956
- /* (113) lvalue ::= ID */ yytestcase(yyruleno==113);
2957
- /* (114) lvalue ::= FILL */ yytestcase(yyruleno==114);
2958
- /* (115) lvalue ::= COLOR */ yytestcase(yyruleno==115);
2959
- /* (116) lvalue ::= THICKNESS */ yytestcase(yyruleno==116);
2960
- /* (117) rvalue ::= expr */ yytestcase(yyruleno==117);
2961
- /* (118) print ::= PRINT */ yytestcase(yyruleno==118);
2962
- /* (119) prlist ::= pritem (OPTIMIZED OUT) */ assert(yyruleno!=119);
2963
- /* (120) prlist ::= prlist prsep pritem */ yytestcase(yyruleno==120);
2964
- /* (121) direction ::= UP */ yytestcase(yyruleno==121);
2965
- /* (122) direction ::= DOWN */ yytestcase(yyruleno==122);
2966
- /* (123) direction ::= LEFT */ yytestcase(yyruleno==123);
2967
- /* (124) direction ::= RIGHT */ yytestcase(yyruleno==124);
2968
- /* (125) optrelexpr ::= relexpr (OPTIMIZED OUT) */ assert(yyruleno!=125);
2969
- /* (126) attribute_list ::= alist */ yytestcase(yyruleno==126);
2970
- /* (127) alist ::= */ yytestcase(yyruleno==127);
2971
- /* (128) alist ::= alist attribute */ yytestcase(yyruleno==128);
2972
- /* (129) attribute ::= boolproperty (OPTIMIZED OUT) */ assert(yyruleno!=129);
2973
- /* (130) attribute ::= WITH withclause */ yytestcase(yyruleno==130);
2974
- /* (131) go ::= GO */ yytestcase(yyruleno==131);
2975
- /* (132) go ::= */ yytestcase(yyruleno==132);
2976
- /* (133) even ::= UNTIL EVEN WITH */ yytestcase(yyruleno==133);
2977
- /* (134) even ::= EVEN WITH */ yytestcase(yyruleno==134);
2978
- /* (135) dashproperty ::= DOTTED */ yytestcase(yyruleno==135);
2979
- /* (136) dashproperty ::= DASHED */ yytestcase(yyruleno==136);
2980
- /* (137) colorproperty ::= FILL */ yytestcase(yyruleno==137);
2981
- /* (138) colorproperty ::= COLOR */ yytestcase(yyruleno==138);
2982
- /* (139) position ::= place */ yytestcase(yyruleno==139);
2983
- /* (140) between ::= WAY BETWEEN */ yytestcase(yyruleno==140);
2984
- /* (141) between ::= BETWEEN */ yytestcase(yyruleno==141);
2985
- /* (142) between ::= OF THE WAY BETWEEN */ yytestcase(yyruleno==142);
2986
- /* (143) place ::= place2 */ yytestcase(yyruleno==143);
2987
- /* (144) edge ::= CENTER */ yytestcase(yyruleno==144);
2988
- /* (145) edge ::= EDGEPT */ yytestcase(yyruleno==145);
2989
- /* (146) edge ::= TOP */ yytestcase(yyruleno==146);
2990
- /* (147) edge ::= BOTTOM */ yytestcase(yyruleno==147);
2991
- /* (148) edge ::= START */ yytestcase(yyruleno==148);
2992
- /* (149) edge ::= END */ yytestcase(yyruleno==149);
2993
- /* (150) edge ::= RIGHT */ yytestcase(yyruleno==150);
2994
- /* (151) edge ::= LEFT */ yytestcase(yyruleno==151);
2995
- /* (152) object ::= objectname */ yytestcase(yyruleno==152);
2981
+ /* (114) lvalue ::= ID */ yytestcase(yyruleno==114);
2982
+ /* (115) lvalue ::= FILL */ yytestcase(yyruleno==115);
2983
+ /* (116) lvalue ::= COLOR */ yytestcase(yyruleno==116);
2984
+ /* (117) lvalue ::= THICKNESS */ yytestcase(yyruleno==117);
2985
+ /* (118) rvalue ::= expr */ yytestcase(yyruleno==118);
2986
+ /* (119) print ::= PRINT */ yytestcase(yyruleno==119);
2987
+ /* (120) prlist ::= pritem (OPTIMIZED OUT) */ assert(yyruleno!=120);
2988
+ /* (121) prlist ::= prlist prsep pritem */ yytestcase(yyruleno==121);
2989
+ /* (122) direction ::= UP */ yytestcase(yyruleno==122);
2990
+ /* (123) direction ::= DOWN */ yytestcase(yyruleno==123);
2991
+ /* (124) direction ::= LEFT */ yytestcase(yyruleno==124);
2992
+ /* (125) direction ::= RIGHT */ yytestcase(yyruleno==125);
2993
+ /* (126) optrelexpr ::= relexpr (OPTIMIZED OUT) */ assert(yyruleno!=126);
2994
+ /* (127) attribute_list ::= alist */ yytestcase(yyruleno==127);
2995
+ /* (128) alist ::= */ yytestcase(yyruleno==128);
2996
+ /* (129) alist ::= alist attribute */ yytestcase(yyruleno==129);
2997
+ /* (130) attribute ::= boolproperty (OPTIMIZED OUT) */ assert(yyruleno!=130);
2998
+ /* (131) attribute ::= WITH withclause */ yytestcase(yyruleno==131);
2999
+ /* (132) go ::= GO */ yytestcase(yyruleno==132);
3000
+ /* (133) go ::= */ yytestcase(yyruleno==133);
3001
+ /* (134) even ::= UNTIL EVEN WITH */ yytestcase(yyruleno==134);
3002
+ /* (135) even ::= EVEN WITH */ yytestcase(yyruleno==135);
3003
+ /* (136) dashproperty ::= DOTTED */ yytestcase(yyruleno==136);
3004
+ /* (137) dashproperty ::= DASHED */ yytestcase(yyruleno==137);
3005
+ /* (138) colorproperty ::= FILL */ yytestcase(yyruleno==138);
3006
+ /* (139) colorproperty ::= COLOR */ yytestcase(yyruleno==139);
3007
+ /* (140) position ::= place */ yytestcase(yyruleno==140);
3008
+ /* (141) between ::= WAY BETWEEN */ yytestcase(yyruleno==141);
3009
+ /* (142) between ::= BETWEEN */ yytestcase(yyruleno==142);
3010
+ /* (143) between ::= OF THE WAY BETWEEN */ yytestcase(yyruleno==143);
3011
+ /* (144) place ::= place2 */ yytestcase(yyruleno==144);
3012
+ /* (145) edge ::= CENTER */ yytestcase(yyruleno==145);
3013
+ /* (146) edge ::= EDGEPT */ yytestcase(yyruleno==146);
3014
+ /* (147) edge ::= TOP */ yytestcase(yyruleno==147);
3015
+ /* (148) edge ::= BOTTOM */ yytestcase(yyruleno==148);
3016
+ /* (149) edge ::= START */ yytestcase(yyruleno==149);
3017
+ /* (150) edge ::= END */ yytestcase(yyruleno==150);
3018
+ /* (151) edge ::= RIGHT */ yytestcase(yyruleno==151);
3019
+ /* (152) edge ::= LEFT */ yytestcase(yyruleno==152);
3020
+ /* (153) object ::= objectname */ yytestcase(yyruleno==153);
29963021
break;
29973022
/********** End reduce actions ************************************************/
29983023
};
29993024
assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
30003025
yygoto = yyRuleInfoLhs[yyruleno];
@@ -3050,19 +3075,19 @@
30503075
){
30513076
pik_parserARG_FETCH
30523077
pik_parserCTX_FETCH
30533078
#define TOKEN yyminor
30543079
/************ Begin %syntax_error code ****************************************/
3055
-#line 494 "pikchr.y"
3080
+#line 509 "pikchr.y"
30563081
30573082
if( TOKEN.z && TOKEN.z[0] ){
30583083
pik_error(p, &TOKEN, "syntax error");
30593084
}else{
30603085
pik_error(p, 0, "syntax error");
30613086
}
30623087
UNUSED_PARAMETER(yymajor);
3063
-#line 3088 "pikchr.c"
3088
+#line 3113 "pikchr.c"
30643089
/************ End %syntax_error code ******************************************/
30653090
pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
30663091
pik_parserCTX_STORE
30673092
}
30683093
@@ -3291,11 +3316,11 @@
32913316
#else
32923317
(void)iToken;
32933318
return 0;
32943319
#endif
32953320
}
3296
-#line 735 "pikchr.y"
3321
+#line 751 "pikchr.y"
32973322
32983323
32993324
33003325
/* Chart of the 140 official HTML color names with their
33013326
** corresponding RGB value.
@@ -3497,13 +3522,13 @@
34973522
{ "thickness", 0.015 },
34983523
};
34993524
35003525
35013526
/* Methods for the "arc" class */
3502
-static void arcInit(Pik *p, PElem *pElem){
3503
- pElem->w = pik_value(p, "arcrad",6,0);
3504
- pElem->h = pElem->w;
3527
+static void arcInit(Pik *p, PObj *pObj){
3528
+ pObj->w = pik_value(p, "arcrad",6,0);
3529
+ pObj->h = pObj->w;
35053530
}
35063531
/* Hack: Arcs are here rendered as quadratic Bezier curves rather
35073532
** than true arcs. Multiple reasons: (1) the legacy-PIC parameters
35083533
** that control arcs are obscure and I could not figure out what they
35093534
** mean based on available documentation. (2) Arcs are rarely used,
@@ -3523,65 +3548,65 @@
35233548
m.x += 0.5*rScale*dy;
35243549
m.y -= 0.5*rScale*dx;
35253550
}
35263551
return m;
35273552
}
3528
-static void arcCheck(Pik *p, PElem *pElem){
3553
+static void arcCheck(Pik *p, PObj *pObj){
35293554
PPoint m;
35303555
if( p->nTPath>2 ){
3531
- pik_error(p, &pElem->errTok, "arc geometry error");
3556
+ pik_error(p, &pObj->errTok, "arc geometry error");
35323557
return;
35333558
}
3534
- m = arcControlPoint(pElem->cw, p->aTPath[0], p->aTPath[1], 0.5);
3535
- pik_bbox_add_xy(&pElem->bbox, m.x, m.y);
3559
+ m = arcControlPoint(pObj->cw, p->aTPath[0], p->aTPath[1], 0.5);
3560
+ pik_bbox_add_xy(&pObj->bbox, m.x, m.y);
35363561
}
3537
-static void arcRender(Pik *p, PElem *pElem){
3562
+static void arcRender(Pik *p, PObj *pObj){
35383563
PPoint f, m, t;
3539
- if( pElem->nPath<2 ) return;
3540
- if( pElem->sw<=0.0 ) return;
3541
- f = pElem->aPath[0];
3542
- t = pElem->aPath[1];
3543
- m = arcControlPoint(pElem->cw,f,t,1.0);
3544
- if( pElem->larrow ){
3545
- pik_draw_arrowhead(p,&m,&f,pElem);
3546
- }
3547
- if( pElem->rarrow ){
3548
- pik_draw_arrowhead(p,&m,&t,pElem);
3564
+ if( pObj->nPath<2 ) return;
3565
+ if( pObj->sw<=0.0 ) return;
3566
+ f = pObj->aPath[0];
3567
+ t = pObj->aPath[1];
3568
+ m = arcControlPoint(pObj->cw,f,t,1.0);
3569
+ if( pObj->larrow ){
3570
+ pik_draw_arrowhead(p,&m,&f,pObj);
3571
+ }
3572
+ if( pObj->rarrow ){
3573
+ pik_draw_arrowhead(p,&m,&t,pObj);
35493574
}
35503575
pik_append_xy(p,"<path d=\"M", f.x, f.y);
35513576
pik_append_xy(p,"Q", m.x, m.y);
35523577
pik_append_xy(p," ", t.x, t.y);
35533578
pik_append(p,"\" ",2);
3554
- pik_append_style(p,pElem,0);
3579
+ pik_append_style(p,pObj,0);
35553580
pik_append(p,"\" />\n", -1);
35563581
3557
- pik_append_txt(p, pElem, 0);
3582
+ pik_append_txt(p, pObj, 0);
35583583
}
35593584
35603585
35613586
/* Methods for the "arrow" class */
3562
-static void arrowInit(Pik *p, PElem *pElem){
3563
- pElem->w = pik_value(p, "linewid",7,0);
3564
- pElem->h = pik_value(p, "lineht",6,0);
3565
- pElem->rad = pik_value(p, "linerad",7,0);
3566
- pElem->fill = -1.0;
3567
- pElem->rarrow = 1;
3587
+static void arrowInit(Pik *p, PObj *pObj){
3588
+ pObj->w = pik_value(p, "linewid",7,0);
3589
+ pObj->h = pik_value(p, "lineht",6,0);
3590
+ pObj->rad = pik_value(p, "linerad",7,0);
3591
+ pObj->fill = -1.0;
3592
+ pObj->rarrow = 1;
35683593
}
35693594
35703595
/* Methods for the "box" class */
3571
-static void boxInit(Pik *p, PElem *pElem){
3572
- pElem->w = pik_value(p, "boxwid",6,0);
3573
- pElem->h = pik_value(p, "boxht",5,0);
3574
- pElem->rad = pik_value(p, "boxrad",6,0);
3596
+static void boxInit(Pik *p, PObj *pObj){
3597
+ pObj->w = pik_value(p, "boxwid",6,0);
3598
+ pObj->h = pik_value(p, "boxht",5,0);
3599
+ pObj->rad = pik_value(p, "boxrad",6,0);
35753600
}
35763601
/* Return offset from the center of the box to the compass point
35773602
** given by parameter cp */
3578
-static PPoint boxOffset(Pik *p, PElem *pElem, int cp){
3603
+static PPoint boxOffset(Pik *p, PObj *pObj, int cp){
35793604
PPoint pt = cZeroPoint;
3580
- PNum w2 = 0.5*pElem->w;
3581
- PNum h2 = 0.5*pElem->h;
3582
- PNum rad = pElem->rad;
3605
+ PNum w2 = 0.5*pObj->w;
3606
+ PNum h2 = 0.5*pObj->h;
3607
+ PNum rad = pObj->rad;
35833608
PNum rx;
35843609
if( rad<=0.0 ){
35853610
rx = 0.0;
35863611
}else{
35873612
if( rad>w2 ) rad = w2;
@@ -3601,18 +3626,18 @@
36013626
default: assert(0);
36023627
}
36033628
UNUSED_PARAMETER(p);
36043629
return pt;
36053630
}
3606
-static PPoint boxChop(Pik *p, PElem *pElem, PPoint *pPt){
3631
+static PPoint boxChop(Pik *p, PObj *pObj, PPoint *pPt){
36073632
PNum dx, dy;
36083633
int cp = CP_C;
3609
- PPoint chop = pElem->ptAt;
3610
- if( pElem->w<=0.0 ) return chop;
3611
- if( pElem->h<=0.0 ) return chop;
3612
- dx = (pPt->x - pElem->ptAt.x)*pElem->h/pElem->w;
3613
- dy = (pPt->y - pElem->ptAt.y);
3634
+ PPoint chop = pObj->ptAt;
3635
+ if( pObj->w<=0.0 ) return chop;
3636
+ if( pObj->h<=0.0 ) return chop;
3637
+ dx = (pPt->x - pObj->ptAt.x)*pObj->h/pObj->w;
3638
+ dy = (pPt->y - pObj->ptAt.y);
36143639
if( dx>0.0 ){
36153640
if( dy>=2.414*dx ){
36163641
cp = CP_N;
36173642
}else if( dy>=0.414*dx ){
36183643
cp = CP_NE;
@@ -3634,26 +3659,26 @@
36343659
cp = CP_SW;
36353660
}else{
36363661
cp = CP_S;
36373662
}
36383663
}
3639
- chop = pElem->type->xOffset(p,pElem,cp);
3640
- chop.x += pElem->ptAt.x;
3641
- chop.y += pElem->ptAt.y;
3664
+ chop = pObj->type->xOffset(p,pObj,cp);
3665
+ chop.x += pObj->ptAt.x;
3666
+ chop.y += pObj->ptAt.y;
36423667
return chop;
36433668
}
3644
-static void boxFit(Pik *p, PElem *pElem, PNum w, PNum h){
3645
- if( w>0 ) pElem->w = w;
3646
- if( h>0 ) pElem->h = h;
3669
+static void boxFit(Pik *p, PObj *pObj, PNum w, PNum h){
3670
+ if( w>0 ) pObj->w = w;
3671
+ if( h>0 ) pObj->h = h;
36473672
UNUSED_PARAMETER(p);
36483673
}
3649
-static void boxRender(Pik *p, PElem *pElem){
3650
- PNum w2 = 0.5*pElem->w;
3651
- PNum h2 = 0.5*pElem->h;
3652
- PNum rad = pElem->rad;
3653
- PPoint pt = pElem->ptAt;
3654
- if( pElem->sw>0.0 ){
3674
+static void boxRender(Pik *p, PObj *pObj){
3675
+ PNum w2 = 0.5*pObj->w;
3676
+ PNum h2 = 0.5*pObj->h;
3677
+ PNum rad = pObj->rad;
3678
+ PPoint pt = pObj->ptAt;
3679
+ if( pObj->sw>0.0 ){
36553680
if( rad<=0.0 ){
36563681
pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y-h2);
36573682
pik_append_xy(p,"L", pt.x+w2,pt.y-h2);
36583683
pik_append_xy(p,"L", pt.x+w2,pt.y+h2);
36593684
pik_append_xy(p,"L", pt.x-w2,pt.y+h2);
@@ -3692,112 +3717,112 @@
36923717
pik_append_arc(p, rad, rad, x0, y2);
36933718
if( y2>y1 ) pik_append_xy(p, "L", x0, y1);
36943719
pik_append_arc(p, rad, rad, x1, y0);
36953720
pik_append(p,"Z\" ",-1);
36963721
}
3697
- pik_append_style(p,pElem,1);
3722
+ pik_append_style(p,pObj,1);
36983723
pik_append(p,"\" />\n", -1);
36993724
}
3700
- pik_append_txt(p, pElem, 0);
3725
+ pik_append_txt(p, pObj, 0);
37013726
}
37023727
37033728
/* Methods for the "circle" class */
3704
-static void circleInit(Pik *p, PElem *pElem){
3705
- pElem->w = pik_value(p, "circlerad",9,0)*2;
3706
- pElem->h = pElem->w;
3707
- pElem->rad = 0.5*pElem->w;
3729
+static void circleInit(Pik *p, PObj *pObj){
3730
+ pObj->w = pik_value(p, "circlerad",9,0)*2;
3731
+ pObj->h = pObj->w;
3732
+ pObj->rad = 0.5*pObj->w;
37083733
}
3709
-static void circleNumProp(Pik *p, PElem *pElem, PToken *pId){
3734
+static void circleNumProp(Pik *p, PObj *pObj, PToken *pId){
37103735
/* For a circle, the width must equal the height and both must
37113736
** be twice the radius. Enforce those constraints. */
37123737
switch( pId->eType ){
37133738
case T_RADIUS:
3714
- pElem->w = pElem->h = 2.0*pElem->rad;
3739
+ pObj->w = pObj->h = 2.0*pObj->rad;
37153740
break;
37163741
case T_WIDTH:
3717
- pElem->h = pElem->w;
3718
- pElem->rad = 0.5*pElem->w;
3742
+ pObj->h = pObj->w;
3743
+ pObj->rad = 0.5*pObj->w;
37193744
break;
37203745
case T_HEIGHT:
3721
- pElem->w = pElem->h;
3722
- pElem->rad = 0.5*pElem->w;
3746
+ pObj->w = pObj->h;
3747
+ pObj->rad = 0.5*pObj->w;
37233748
break;
37243749
}
37253750
UNUSED_PARAMETER(p);
37263751
}
3727
-static PPoint circleChop(Pik *p, PElem *pElem, PPoint *pPt){
3752
+static PPoint circleChop(Pik *p, PObj *pObj, PPoint *pPt){
37283753
PPoint chop;
3729
- PNum dx = pPt->x - pElem->ptAt.x;
3730
- PNum dy = pPt->y - pElem->ptAt.y;
3754
+ PNum dx = pPt->x - pObj->ptAt.x;
3755
+ PNum dy = pPt->y - pObj->ptAt.y;
37313756
PNum dist = hypot(dx,dy);
3732
- if( dist<pElem->rad ) return pElem->ptAt;
3733
- chop.x = pElem->ptAt.x + dx*pElem->rad/dist;
3734
- chop.y = pElem->ptAt.y + dy*pElem->rad/dist;
3757
+ if( dist<pObj->rad ) return pObj->ptAt;
3758
+ chop.x = pObj->ptAt.x + dx*pObj->rad/dist;
3759
+ chop.y = pObj->ptAt.y + dy*pObj->rad/dist;
37353760
UNUSED_PARAMETER(p);
37363761
return chop;
37373762
}
3738
-static void circleFit(Pik *p, PElem *pElem, PNum w, PNum h){
3763
+static void circleFit(Pik *p, PObj *pObj, PNum w, PNum h){
37393764
PNum mx = 0.0;
37403765
if( w>0 ) mx = w;
37413766
if( h>mx ) mx = h;
3742
- if( (w*w + h*h) > mx*mx ){
3767
+ if( w*h>0 && (w*w + h*h) > mx*mx ){
37433768
mx = hypot(w,h);
37443769
}
37453770
if( mx>0.0 ){
3746
- pElem->rad = 0.5*mx;
3747
- pElem->w = pElem->h = mx;
3771
+ pObj->rad = 0.5*mx;
3772
+ pObj->w = pObj->h = mx;
37483773
}
37493774
UNUSED_PARAMETER(p);
37503775
}
37513776
3752
-static void circleRender(Pik *p, PElem *pElem){
3753
- PNum r = pElem->rad;
3754
- PPoint pt = pElem->ptAt;
3755
- if( pElem->sw>0.0 ){
3777
+static void circleRender(Pik *p, PObj *pObj){
3778
+ PNum r = pObj->rad;
3779
+ PPoint pt = pObj->ptAt;
3780
+ if( pObj->sw>0.0 ){
37563781
pik_append_x(p,"<circle cx=\"", pt.x, "\"");
37573782
pik_append_y(p," cy=\"", pt.y, "\"");
37583783
pik_append_dis(p," r=\"", r, "\" ");
3759
- pik_append_style(p,pElem,1);
3784
+ pik_append_style(p,pObj,1);
37603785
pik_append(p,"\" />\n", -1);
37613786
}
3762
- pik_append_txt(p, pElem, 0);
3787
+ pik_append_txt(p, pObj, 0);
37633788
}
37643789
37653790
/* Methods for the "cylinder" class */
3766
-static void cylinderInit(Pik *p, PElem *pElem){
3767
- pElem->w = pik_value(p, "cylwid",6,0);
3768
- pElem->h = pik_value(p, "cylht",5,0);
3769
- pElem->rad = pik_value(p, "cylrad",6,0); /* Minor radius of ellipses */
3770
-}
3771
-static void cylinderFit(Pik *p, PElem *pElem, PNum w, PNum h){
3772
- if( w>0 ) pElem->w = w;
3773
- if( h>0 ) pElem->h = h + 4*pElem->rad + pElem->sw;
3791
+static void cylinderInit(Pik *p, PObj *pObj){
3792
+ pObj->w = pik_value(p, "cylwid",6,0);
3793
+ pObj->h = pik_value(p, "cylht",5,0);
3794
+ pObj->rad = pik_value(p, "cylrad",6,0); /* Minor radius of ellipses */
3795
+}
3796
+static void cylinderFit(Pik *p, PObj *pObj, PNum w, PNum h){
3797
+ if( w>0 ) pObj->w = w;
3798
+ if( h>0 ) pObj->h = h + 4*pObj->rad + pObj->sw;
37743799
UNUSED_PARAMETER(p);
37753800
}
3776
-static void cylinderRender(Pik *p, PElem *pElem){
3777
- PNum w2 = 0.5*pElem->w;
3778
- PNum h2 = 0.5*pElem->h;
3779
- PNum rad = pElem->rad;
3780
- PPoint pt = pElem->ptAt;
3781
- if( pElem->sw>0.0 ){
3801
+static void cylinderRender(Pik *p, PObj *pObj){
3802
+ PNum w2 = 0.5*pObj->w;
3803
+ PNum h2 = 0.5*pObj->h;
3804
+ PNum rad = pObj->rad;
3805
+ PPoint pt = pObj->ptAt;
3806
+ if( pObj->sw>0.0 ){
37823807
pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y+h2-rad);
37833808
pik_append_xy(p,"L", pt.x-w2,pt.y-h2+rad);
37843809
pik_append_arc(p,w2,rad,pt.x+w2,pt.y-h2+rad);
37853810
pik_append_xy(p,"L", pt.x+w2,pt.y+h2-rad);
37863811
pik_append_arc(p,w2,rad,pt.x-w2,pt.y+h2-rad);
37873812
pik_append_arc(p,w2,rad,pt.x+w2,pt.y+h2-rad);
37883813
pik_append(p,"\" ",-1);
3789
- pik_append_style(p,pElem,1);
3814
+ pik_append_style(p,pObj,1);
37903815
pik_append(p,"\" />\n", -1);
37913816
}
3792
- pik_append_txt(p, pElem, 0);
3817
+ pik_append_txt(p, pObj, 0);
37933818
}
3794
-static PPoint cylinderOffset(Pik *p, PElem *pElem, int cp){
3819
+static PPoint cylinderOffset(Pik *p, PObj *pObj, int cp){
37953820
PPoint pt = cZeroPoint;
3796
- PNum w2 = pElem->w*0.5;
3797
- PNum h1 = pElem->h*0.5;
3798
- PNum h2 = h1 - pElem->rad;
3821
+ PNum w2 = pObj->w*0.5;
3822
+ PNum h1 = pObj->h*0.5;
3823
+ PNum h2 = h1 - pObj->rad;
37993824
switch( cp ){
38003825
case CP_C: break;
38013826
case CP_N: pt.x = 0.0; pt.y = h1; break;
38023827
case CP_NE: pt.x = w2; pt.y = h2; break;
38033828
case CP_E: pt.x = w2; pt.y = 0.0; break;
@@ -3811,79 +3836,79 @@
38113836
UNUSED_PARAMETER(p);
38123837
return pt;
38133838
}
38143839
38153840
/* Methods for the "dot" class */
3816
-static void dotInit(Pik *p, PElem *pElem){
3817
- pElem->rad = pik_value(p, "dotrad",6,0);
3818
- pElem->h = pElem->w = pElem->rad*6;
3819
- pElem->fill = pElem->color;
3841
+static void dotInit(Pik *p, PObj *pObj){
3842
+ pObj->rad = pik_value(p, "dotrad",6,0);
3843
+ pObj->h = pObj->w = pObj->rad*6;
3844
+ pObj->fill = pObj->color;
38203845
}
3821
-static void dotNumProp(Pik *p, PElem *pElem, PToken *pId){
3846
+static void dotNumProp(Pik *p, PObj *pObj, PToken *pId){
38223847
switch( pId->eType ){
38233848
case T_COLOR:
3824
- pElem->fill = pElem->color;
3849
+ pObj->fill = pObj->color;
38253850
break;
38263851
case T_FILL:
3827
- pElem->color = pElem->fill;
3852
+ pObj->color = pObj->fill;
38283853
break;
38293854
}
38303855
UNUSED_PARAMETER(p);
38313856
}
3832
-static void dotCheck(Pik *p, PElem *pElem){
3833
- pElem->w = pElem->h = 0;
3834
- pik_bbox_addellipse(&pElem->bbox, pElem->ptAt.x, pElem->ptAt.y,
3835
- pElem->rad, pElem->rad);
3836
- UNUSED_PARAMETER(p);
3837
-}
3838
-static PPoint dotOffset(Pik *p, PElem *pElem, int cp){
3839
- UNUSED_PARAMETER(p);
3840
- UNUSED_PARAMETER(pElem);
3857
+static void dotCheck(Pik *p, PObj *pObj){
3858
+ pObj->w = pObj->h = 0;
3859
+ pik_bbox_addellipse(&pObj->bbox, pObj->ptAt.x, pObj->ptAt.y,
3860
+ pObj->rad, pObj->rad);
3861
+ UNUSED_PARAMETER(p);
3862
+}
3863
+static PPoint dotOffset(Pik *p, PObj *pObj, int cp){
3864
+ UNUSED_PARAMETER(p);
3865
+ UNUSED_PARAMETER(pObj);
38413866
UNUSED_PARAMETER(cp);
38423867
return cZeroPoint;
38433868
}
3844
-static void dotRender(Pik *p, PElem *pElem){
3845
- PNum r = pElem->rad;
3846
- PPoint pt = pElem->ptAt;
3847
- if( pElem->sw>0.0 ){
3869
+static void dotRender(Pik *p, PObj *pObj){
3870
+ PNum r = pObj->rad;
3871
+ PPoint pt = pObj->ptAt;
3872
+ if( pObj->sw>0.0 ){
38483873
pik_append_x(p,"<circle cx=\"", pt.x, "\"");
38493874
pik_append_y(p," cy=\"", pt.y, "\"");
38503875
pik_append_dis(p," r=\"", r, "\"");
3851
- pik_append_style(p,pElem,1);
3876
+ pik_append_style(p,pObj,1);
38523877
pik_append(p,"\" />\n", -1);
38533878
}
3854
- pik_append_txt(p, pElem, 0);
3879
+ pik_append_txt(p, pObj, 0);
38553880
}
38563881
38573882
38583883
38593884
/* Methods for the "ellipse" class */
3860
-static void ellipseInit(Pik *p, PElem *pElem){
3861
- pElem->w = pik_value(p, "ellipsewid",10,0);
3862
- pElem->h = pik_value(p, "ellipseht",9,0);
3885
+static void ellipseInit(Pik *p, PObj *pObj){
3886
+ pObj->w = pik_value(p, "ellipsewid",10,0);
3887
+ pObj->h = pik_value(p, "ellipseht",9,0);
38633888
}
3864
-static PPoint ellipseChop(Pik *p, PElem *pElem, PPoint *pPt){
3889
+static PPoint ellipseChop(Pik *p, PObj *pObj, PPoint *pPt){
38653890
PPoint chop;
38663891
PNum s, dq, dist;
3867
- PNum dx = pPt->x - pElem->ptAt.x;
3868
- PNum dy = pPt->y - pElem->ptAt.y;
3869
- if( pElem->w<=0.0 ) return pElem->ptAt;
3870
- if( pElem->h<=0.0 ) return pElem->ptAt;
3871
- s = pElem->h/pElem->w;
3892
+ PNum dx = pPt->x - pObj->ptAt.x;
3893
+ PNum dy = pPt->y - pObj->ptAt.y;
3894
+ if( pObj->w<=0.0 ) return pObj->ptAt;
3895
+ if( pObj->h<=0.0 ) return pObj->ptAt;
3896
+ s = pObj->h/pObj->w;
38723897
dq = dx*s;
38733898
dist = hypot(dq,dy);
3874
- if( dist<pElem->h ) return pElem->ptAt;
3875
- chop.x = pElem->ptAt.x + 0.5*dq*pElem->h/(dist*s);
3876
- chop.y = pElem->ptAt.y + 0.5*dy*pElem->h/dist;
3899
+ if( dist<pObj->h ) return pObj->ptAt;
3900
+ chop.x = pObj->ptAt.x + 0.5*dq*pObj->h/(dist*s);
3901
+ chop.y = pObj->ptAt.y + 0.5*dy*pObj->h/dist;
38773902
UNUSED_PARAMETER(p);
38783903
return chop;
38793904
}
3880
-static PPoint ellipseOffset(Pik *p, PElem *pElem, int cp){
3905
+static PPoint ellipseOffset(Pik *p, PObj *pObj, int cp){
38813906
PPoint pt = cZeroPoint;
3882
- PNum w = pElem->w*0.5;
3907
+ PNum w = pObj->w*0.5;
38833908
PNum w2 = w*0.70710678118654747608;
3884
- PNum h = pElem->h*0.5;
3909
+ PNum h = pObj->h*0.5;
38853910
PNum h2 = h*0.70710678118654747608;
38863911
switch( cp ){
38873912
case CP_C: break;
38883913
case CP_N: pt.x = 0.0; pt.y = h; break;
38893914
case CP_NE: pt.x = w2; pt.y = h2; break;
@@ -3896,38 +3921,38 @@
38963921
default: assert(0);
38973922
}
38983923
UNUSED_PARAMETER(p);
38993924
return pt;
39003925
}
3901
-static void ellipseRender(Pik *p, PElem *pElem){
3902
- PNum w = pElem->w;
3903
- PNum h = pElem->h;
3904
- PPoint pt = pElem->ptAt;
3905
- if( pElem->sw>0.0 ){
3926
+static void ellipseRender(Pik *p, PObj *pObj){
3927
+ PNum w = pObj->w;
3928
+ PNum h = pObj->h;
3929
+ PPoint pt = pObj->ptAt;
3930
+ if( pObj->sw>0.0 ){
39063931
pik_append_x(p,"<ellipse cx=\"", pt.x, "\"");
39073932
pik_append_y(p," cy=\"", pt.y, "\"");
39083933
pik_append_dis(p," rx=\"", w/2.0, "\"");
39093934
pik_append_dis(p," ry=\"", h/2.0, "\" ");
3910
- pik_append_style(p,pElem,1);
3935
+ pik_append_style(p,pObj,1);
39113936
pik_append(p,"\" />\n", -1);
39123937
}
3913
- pik_append_txt(p, pElem, 0);
3938
+ pik_append_txt(p, pObj, 0);
39143939
}
39153940
39163941
/* Methods for the "file" object */
3917
-static void fileInit(Pik *p, PElem *pElem){
3918
- pElem->w = pik_value(p, "filewid",7,0);
3919
- pElem->h = pik_value(p, "fileht",6,0);
3920
- pElem->rad = pik_value(p, "filerad",7,0);
3942
+static void fileInit(Pik *p, PObj *pObj){
3943
+ pObj->w = pik_value(p, "filewid",7,0);
3944
+ pObj->h = pik_value(p, "fileht",6,0);
3945
+ pObj->rad = pik_value(p, "filerad",7,0);
39213946
}
39223947
/* Return offset from the center of the file to the compass point
39233948
** given by parameter cp */
3924
-static PPoint fileOffset(Pik *p, PElem *pElem, int cp){
3949
+static PPoint fileOffset(Pik *p, PObj *pObj, int cp){
39253950
PPoint pt = cZeroPoint;
3926
- PNum w2 = 0.5*pElem->w;
3927
- PNum h2 = 0.5*pElem->h;
3928
- PNum rx = pElem->rad;
3951
+ PNum w2 = 0.5*pObj->w;
3952
+ PNum h2 = 0.5*pObj->h;
3953
+ PNum rx = pObj->rad;
39293954
PNum mn = w2<h2 ? w2 : h2;
39303955
if( rx>mn ) rx = mn;
39313956
if( rx<mn*0.25 ) rx = mn*0.25;
39323957
pt.x = pt.y = 0.0;
39333958
rx *= 0.5;
@@ -3944,132 +3969,133 @@
39443969
default: assert(0);
39453970
}
39463971
UNUSED_PARAMETER(p);
39473972
return pt;
39483973
}
3949
-static void fileFit(Pik *p, PElem *pElem, PNum w, PNum h){
3950
- if( w>0 ) pElem->w = w;
3951
- if( h>0 ) pElem->h = h + 2*pElem->rad;
3974
+static void fileFit(Pik *p, PObj *pObj, PNum w, PNum h){
3975
+ if( w>0 ) pObj->w = w;
3976
+ if( h>0 ) pObj->h = h + 2*pObj->rad;
39523977
UNUSED_PARAMETER(p);
39533978
}
3954
-static void fileRender(Pik *p, PElem *pElem){
3955
- PNum w2 = 0.5*pElem->w;
3956
- PNum h2 = 0.5*pElem->h;
3957
- PNum rad = pElem->rad;
3958
- PPoint pt = pElem->ptAt;
3979
+static void fileRender(Pik *p, PObj *pObj){
3980
+ PNum w2 = 0.5*pObj->w;
3981
+ PNum h2 = 0.5*pObj->h;
3982
+ PNum rad = pObj->rad;
3983
+ PPoint pt = pObj->ptAt;
39593984
PNum mn = w2<h2 ? w2 : h2;
39603985
if( rad>mn ) rad = mn;
39613986
if( rad<mn*0.25 ) rad = mn*0.25;
3962
- if( pElem->sw>0.0 ){
3987
+ if( pObj->sw>0.0 ){
39633988
pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y-h2);
39643989
pik_append_xy(p,"L", pt.x+w2,pt.y-h2);
39653990
pik_append_xy(p,"L", pt.x+w2,pt.y+(h2-rad));
39663991
pik_append_xy(p,"L", pt.x+(w2-rad),pt.y+h2);
39673992
pik_append_xy(p,"L", pt.x-w2,pt.y+h2);
39683993
pik_append(p,"Z\" ",-1);
3969
- pik_append_style(p,pElem,1);
3994
+ pik_append_style(p,pObj,1);
39703995
pik_append(p,"\" />\n",-1);
39713996
pik_append_xy(p,"<path d=\"M", pt.x+(w2-rad), pt.y+h2);
39723997
pik_append_xy(p,"L", pt.x+(w2-rad),pt.y+(h2-rad));
39733998
pik_append_xy(p,"L", pt.x+w2, pt.y+(h2-rad));
39743999
pik_append(p,"\" ",-1);
3975
- pik_append_style(p,pElem,0);
4000
+ pik_append_style(p,pObj,0);
39764001
pik_append(p,"\" />\n",-1);
39774002
}
3978
- pik_append_txt(p, pElem, 0);
4003
+ pik_append_txt(p, pObj, 0);
39794004
}
39804005
39814006
39824007
/* Methods for the "line" class */
3983
-static void lineInit(Pik *p, PElem *pElem){
3984
- pElem->w = pik_value(p, "linewid",7,0);
3985
- pElem->h = pik_value(p, "lineht",6,0);
3986
- pElem->rad = pik_value(p, "linerad",7,0);
3987
- pElem->fill = -1.0;
4008
+static void lineInit(Pik *p, PObj *pObj){
4009
+ pObj->w = pik_value(p, "linewid",7,0);
4010
+ pObj->h = pik_value(p, "lineht",6,0);
4011
+ pObj->rad = pik_value(p, "linerad",7,0);
4012
+ pObj->fill = -1.0;
39884013
}
3989
-static PPoint lineOffset(Pik *p, PElem *pElem, int cp){
4014
+static PPoint lineOffset(Pik *p, PObj *pObj, int cp){
39904015
#if 0
39914016
/* In legacy PIC, the .center of an unclosed line is half way between
39924017
** its .start and .end. */
3993
- if( cp==CP_C && !pElem->bClose ){
4018
+ if( cp==CP_C && !pObj->bClose ){
39944019
PPoint out;
3995
- out.x = 0.5*(pElem->ptEnter.x + pElem->ptExit.x) - pElem->ptAt.x;
3996
- out.y = 0.5*(pElem->ptEnter.x + pElem->ptExit.y) - pElem->ptAt.y;
4020
+ out.x = 0.5*(pObj->ptEnter.x + pObj->ptExit.x) - pObj->ptAt.x;
4021
+ out.y = 0.5*(pObj->ptEnter.x + pObj->ptExit.y) - pObj->ptAt.y;
39974022
return out;
39984023
}
39994024
#endif
4000
- return boxOffset(p,pElem,cp);
4025
+ return boxOffset(p,pObj,cp);
40014026
}
4002
-static void lineRender(Pik *p, PElem *pElem){
4027
+static void lineRender(Pik *p, PObj *pObj){
40034028
int i;
4004
- if( pElem->sw>0.0 ){
4029
+ if( pObj->sw>0.0 ){
40054030
const char *z = "<path d=\"M";
4006
- int n = pElem->nPath;
4007
- if( pElem->larrow ){
4008
- pik_draw_arrowhead(p,&pElem->aPath[1],&pElem->aPath[0],pElem);
4009
- }
4010
- if( pElem->rarrow ){
4011
- pik_draw_arrowhead(p,&pElem->aPath[n-2],&pElem->aPath[n-1],pElem);
4012
- }
4013
- for(i=0; i<pElem->nPath; i++){
4014
- pik_append_xy(p,z,pElem->aPath[i].x,pElem->aPath[i].y);
4031
+ int n = pObj->nPath;
4032
+ if( pObj->larrow ){
4033
+ pik_draw_arrowhead(p,&pObj->aPath[1],&pObj->aPath[0],pObj);
4034
+ }
4035
+ if( pObj->rarrow ){
4036
+ pik_draw_arrowhead(p,&pObj->aPath[n-2],&pObj->aPath[n-1],pObj);
4037
+ }
4038
+ for(i=0; i<pObj->nPath; i++){
4039
+ pik_append_xy(p,z,pObj->aPath[i].x,pObj->aPath[i].y);
40154040
z = "L";
40164041
}
4017
- if( pElem->bClose ){
4042
+ if( pObj->bClose ){
40184043
pik_append(p,"Z",1);
40194044
}else{
4020
- pElem->fill = -1.0;
4045
+ pObj->fill = -1.0;
40214046
}
40224047
pik_append(p,"\" ",-1);
4023
- pik_append_style(p,pElem,pElem->bClose);
4048
+ pik_append_style(p,pObj,pObj->bClose);
40244049
pik_append(p,"\" />\n", -1);
40254050
}
4026
- pik_append_txt(p, pElem, 0);
4051
+ pik_append_txt(p, pObj, 0);
40274052
}
40284053
40294054
/* Methods for the "move" class */
4030
-static void moveInit(Pik *p, PElem *pElem){
4031
- pElem->w = pik_value(p, "movewid",7,0);
4032
- pElem->h = pElem->w;
4033
- pElem->fill = -1.0;
4034
- pElem->color = -1.0;
4035
- pElem->sw = -1.0;
4036
-}
4037
-static void moveRender(Pik *p, PElem *pElem){
4055
+static void moveInit(Pik *p, PObj *pObj){
4056
+ pObj->w = pik_value(p, "movewid",7,0);
4057
+ pObj->h = pObj->w;
4058
+ pObj->fill = -1.0;
4059
+ pObj->color = -1.0;
4060
+ pObj->sw = -1.0;
4061
+}
4062
+static void moveRender(Pik *p, PObj *pObj){
40384063
/* No-op */
40394064
UNUSED_PARAMETER(p);
4040
- UNUSED_PARAMETER(pElem);
4065
+ UNUSED_PARAMETER(pObj);
40414066
}
40424067
40434068
/* Methods for the "oval" class */
4044
-static void ovalInit(Pik *p, PElem *pElem){
4045
- pElem->h = pik_value(p, "ovalht",6,0);
4046
- pElem->w = pik_value(p, "ovalwid",7,0);
4047
- pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
4069
+static void ovalInit(Pik *p, PObj *pObj){
4070
+ pObj->h = pik_value(p, "ovalht",6,0);
4071
+ pObj->w = pik_value(p, "ovalwid",7,0);
4072
+ pObj->rad = 0.5*(pObj->h<pObj->w?pObj->h:pObj->w);
40484073
}
4049
-static void ovalNumProp(Pik *p, PElem *pElem, PToken *pId){
4074
+static void ovalNumProp(Pik *p, PObj *pObj, PToken *pId){
40504075
UNUSED_PARAMETER(p);
40514076
UNUSED_PARAMETER(pId);
40524077
/* Always adjust the radius to be half of the smaller of
40534078
** the width and height. */
4054
- pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
4079
+ pObj->rad = 0.5*(pObj->h<pObj->w?pObj->h:pObj->w);
40554080
}
4056
-static void ovalFit(Pik *p, PElem *pElem, PNum w, PNum h){
4081
+static void ovalFit(Pik *p, PObj *pObj, PNum w, PNum h){
40574082
UNUSED_PARAMETER(p);
4058
- if( w>0 ) pElem->w = w;
4059
- if( h>0 ) pElem->h = h;
4060
- if( pElem->w<pElem->h ) pElem->w = pElem->h;
4083
+ if( w>0 ) pObj->w = w;
4084
+ if( h>0 ) pObj->h = h;
4085
+ if( pObj->w<pObj->h ) pObj->w = pObj->h;
4086
+ pObj->rad = 0.5*(pObj->h<pObj->w?pObj->h:pObj->w);
40614087
}
40624088
40634089
40644090
40654091
/* Methods for the "spline" class */
4066
-static void splineInit(Pik *p, PElem *pElem){
4067
- pElem->w = pik_value(p, "linewid",7,0);
4068
- pElem->h = pik_value(p, "lineht",6,0);
4069
- pElem->rad = 1000;
4070
- pElem->fill = -1.0; /* Disable fill by default */
4092
+static void splineInit(Pik *p, PObj *pObj){
4093
+ pObj->w = pik_value(p, "linewid",7,0);
4094
+ pObj->h = pik_value(p, "lineht",6,0);
4095
+ pObj->rad = 1000;
4096
+ pObj->fill = -1.0; /* Disable fill by default */
40714097
}
40724098
/* Return a point along the path from "f" to "t" that is r units
40734099
** prior to reaching "t", except if the path is less than 2*r total,
40744100
** return the midpoint.
40754101
*/
@@ -4089,14 +4115,14 @@
40894115
}
40904116
m.x = t.x - r*dx;
40914117
m.y = t.y - r*dy;
40924118
return m;
40934119
}
4094
-static void radiusPath(Pik *p, PElem *pElem, PNum r){
4120
+static void radiusPath(Pik *p, PObj *pObj, PNum r){
40954121
int i;
4096
- int n = pElem->nPath;
4097
- const PPoint *a = pElem->aPath;
4122
+ int n = pObj->nPath;
4123
+ const PPoint *a = pObj->aPath;
40984124
PPoint m;
40994125
int isMid = 0;
41004126
41014127
pik_append_xy(p,"<path d=\"M", a[0].x, a[0].y);
41024128
m = radiusMidpoint(a[0], a[1], r, &isMid);
@@ -4110,68 +4136,68 @@
41104136
pik_append_xy(p," L ",m.x,m.y);
41114137
}
41124138
}
41134139
pik_append_xy(p," L ",a[i].x,a[i].y);
41144140
pik_append(p,"\" ",-1);
4115
- pik_append_style(p,pElem,0);
4141
+ pik_append_style(p,pObj,0);
41164142
pik_append(p,"\" />\n", -1);
41174143
}
4118
-static void splineRender(Pik *p, PElem *pElem){
4119
- if( pElem->sw>0.0 ){
4120
- int n = pElem->nPath;
4121
- PNum r = pElem->rad;
4144
+static void splineRender(Pik *p, PObj *pObj){
4145
+ if( pObj->sw>0.0 ){
4146
+ int n = pObj->nPath;
4147
+ PNum r = pObj->rad;
41224148
if( n<3 || r<=0.0 ){
4123
- lineRender(p,pElem);
4149
+ lineRender(p,pObj);
41244150
return;
41254151
}
4126
- if( pElem->larrow ){
4127
- pik_draw_arrowhead(p,&pElem->aPath[1],&pElem->aPath[0],pElem);
4128
- }
4129
- if( pElem->rarrow ){
4130
- pik_draw_arrowhead(p,&pElem->aPath[n-2],&pElem->aPath[n-1],pElem);
4131
- }
4132
- radiusPath(p,pElem,pElem->rad);
4133
- }
4134
- pik_append_txt(p, pElem, 0);
4152
+ if( pObj->larrow ){
4153
+ pik_draw_arrowhead(p,&pObj->aPath[1],&pObj->aPath[0],pObj);
4154
+ }
4155
+ if( pObj->rarrow ){
4156
+ pik_draw_arrowhead(p,&pObj->aPath[n-2],&pObj->aPath[n-1],pObj);
4157
+ }
4158
+ radiusPath(p,pObj,pObj->rad);
4159
+ }
4160
+ pik_append_txt(p, pObj, 0);
41354161
}
41364162
41374163
41384164
/* Methods for the "text" class */
4139
-static void textInit(Pik *p, PElem *pElem){
4165
+static void textInit(Pik *p, PObj *pObj){
41404166
pik_value(p, "textwid",7,0);
41414167
pik_value(p, "textht",6,0);
4142
- pElem->sw = 0.0;
4168
+ pObj->sw = 0.0;
41434169
}
4144
-static PPoint textOffset(Pik *p, PElem *pElem, int cp){
4170
+static PPoint textOffset(Pik *p, PObj *pObj, int cp){
41454171
/* Automatically slim-down the width and height of text
4146
- ** elements so that the bounding box tightly encloses the text,
4172
+ ** statements so that the bounding box tightly encloses the text,
41474173
** then get boxOffset() to do the offset computation.
41484174
*/
4149
- pik_size_to_fit(p, &pElem->errTok);
4150
- return boxOffset(p, pElem, cp);
4175
+ pik_size_to_fit(p, &pObj->errTok,3);
4176
+ return boxOffset(p, pObj, cp);
41514177
}
41524178
41534179
/* Methods for the "sublist" class */
4154
-static void sublistInit(Pik *p, PElem *pElem){
4155
- PEList *pList = pElem->pSublist;
4180
+static void sublistInit(Pik *p, PObj *pObj){
4181
+ PList *pList = pObj->pSublist;
41564182
int i;
41574183
UNUSED_PARAMETER(p);
4158
- pik_bbox_init(&pElem->bbox);
4184
+ pik_bbox_init(&pObj->bbox);
41594185
for(i=0; i<pList->n; i++){
4160
- pik_bbox_addbox(&pElem->bbox, &pList->a[i]->bbox);
4186
+ pik_bbox_addbox(&pObj->bbox, &pList->a[i]->bbox);
41614187
}
4162
- pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
4163
- pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
4164
- pElem->ptAt.x = 0.5*(pElem->bbox.ne.x + pElem->bbox.sw.x);
4165
- pElem->ptAt.y = 0.5*(pElem->bbox.ne.y + pElem->bbox.sw.y);
4166
- pElem->mCalc |= A_WIDTH|A_HEIGHT|A_RADIUS;
4188
+ pObj->w = pObj->bbox.ne.x - pObj->bbox.sw.x;
4189
+ pObj->h = pObj->bbox.ne.y - pObj->bbox.sw.y;
4190
+ pObj->ptAt.x = 0.5*(pObj->bbox.ne.x + pObj->bbox.sw.x);
4191
+ pObj->ptAt.y = 0.5*(pObj->bbox.ne.y + pObj->bbox.sw.y);
4192
+ pObj->mCalc |= A_WIDTH|A_HEIGHT|A_RADIUS;
41674193
}
41684194
41694195
41704196
/*
4171
-** The following array holds all the different kinds of named
4172
-** elements. The special STRING and [] elements are separate.
4197
+** The following array holds all the different kinds of objects.
4198
+** The special [] object is separate.
41734199
*/
41744200
static const PClass aClass[] = {
41754201
{ /* name */ "arc",
41764202
/* isline */ 1,
41774203
/* eJust */ 0,
@@ -4244,11 +4270,11 @@
42444270
/* xInit */ ellipseInit,
42454271
/* xNumProp */ 0,
42464272
/* xCheck */ 0,
42474273
/* xChop */ ellipseChop,
42484274
/* xOffset */ ellipseOffset,
4249
- /* xFit */ 0,
4275
+ /* xFit */ boxFit,
42504276
/* xRender */ ellipseRender
42514277
},
42524278
{ /* name */ "file",
42534279
/* isline */ 0,
42544280
/* eJust */ 1,
@@ -4363,20 +4389,20 @@
43634389
/*
43644390
** Draw an arrowhead on the end of the line segment from pFrom to pTo.
43654391
** Also, shorten the line segment (by changing the value of pTo) so that
43664392
** the shaft of the arrow does not extend into the arrowhead.
43674393
*/
4368
-static void pik_draw_arrowhead(Pik *p, PPoint *f, PPoint *t, PElem *pElem){
4394
+static void pik_draw_arrowhead(Pik *p, PPoint *f, PPoint *t, PObj *pObj){
43694395
PNum dx = t->x - f->x;
43704396
PNum dy = t->y - f->y;
43714397
PNum dist = hypot(dx,dy);
4372
- PNum h = p->hArrow * pElem->sw;
4373
- PNum w = p->wArrow * pElem->sw;
4398
+ PNum h = p->hArrow * pObj->sw;
4399
+ PNum w = p->wArrow * pObj->sw;
43744400
PNum e1, ddx, ddy;
43754401
PNum bx, by;
4376
- if( pElem->color<0.0 ) return;
4377
- if( pElem->sw<=0.0 ) return;
4402
+ if( pObj->color<0.0 ) return;
4403
+ if( pObj->sw<=0.0 ) return;
43784404
if( dist<=0.0 ) return; /* Unable */
43794405
dx /= dist;
43804406
dy /= dist;
43814407
e1 = dist - h;
43824408
if( e1<0.0 ){
@@ -4388,20 +4414,20 @@
43884414
bx = f->x + e1*dx;
43894415
by = f->y + e1*dy;
43904416
pik_append_xy(p,"<polygon points=\"", t->x, t->y);
43914417
pik_append_xy(p," ",bx-ddx, by-ddy);
43924418
pik_append_xy(p," ",bx+ddx, by+ddy);
4393
- pik_append_clr(p,"\" style=\"fill:",pElem->color,"\"/>\n");
4419
+ pik_append_clr(p,"\" style=\"fill:",pObj->color,"\"/>\n");
43944420
pik_chop(f,t,h/2);
43954421
}
43964422
43974423
/*
43984424
** Compute the relative offset to an edge location from the reference for a
4399
-** an element.
4425
+** an statement.
44004426
*/
4401
-static PPoint pik_elem_offset(Pik *p, PElem *pElem, int cp){
4402
- return pElem->type->xOffset(p, pElem, cp);
4427
+static PPoint pik_elem_offset(Pik *p, PObj *pObj, int cp){
4428
+ return pObj->type->xOffset(p, pObj, cp);
44034429
}
44044430
44054431
44064432
/*
44074433
** Append raw text to zOut
@@ -4544,49 +4570,49 @@
45444570
}
45454571
45464572
/* Append a style="..." text. But, leave the quote unterminated, in case
45474573
** the caller wants to add some more.
45484574
*/
4549
-static void pik_append_style(Pik *p, PElem *pElem, int bFill){
4575
+static void pik_append_style(Pik *p, PObj *pObj, int bFill){
45504576
pik_append(p, " style=\"", -1);
4551
- if( pElem->fill>=0 && bFill ){
4552
- pik_append_clr(p, "fill:", pElem->fill, ";");
4577
+ if( pObj->fill>=0 && bFill ){
4578
+ pik_append_clr(p, "fill:", pObj->fill, ";");
45534579
}else{
45544580
pik_append(p,"fill:none;",-1);
45554581
}
4556
- if( pElem->sw>0.0 && pElem->color>=0.0 ){
4557
- PNum sw = pElem->sw;
4582
+ if( pObj->sw>0.0 && pObj->color>=0.0 ){
4583
+ PNum sw = pObj->sw;
45584584
pik_append_dis(p, "stroke-width:", sw, ";");
4559
- if( pElem->nPath>2 && pElem->rad<=pElem->sw ){
4585
+ if( pObj->nPath>2 && pObj->rad<=pObj->sw ){
45604586
pik_append(p, "stroke-linejoin:round;", -1);
45614587
}
4562
- pik_append_clr(p, "stroke:",pElem->color,";");
4563
- if( pElem->dotted>0.0 ){
4564
- PNum v = pElem->dotted;
4588
+ pik_append_clr(p, "stroke:",pObj->color,";");
4589
+ if( pObj->dotted>0.0 ){
4590
+ PNum v = pObj->dotted;
45654591
if( sw<2.1/p->rScale ) sw = 2.1/p->rScale;
45664592
pik_append_dis(p,"stroke-dasharray:",sw,"");
45674593
pik_append_dis(p,",",v,";");
4568
- }else if( pElem->dashed>0.0 ){
4569
- PNum v = pElem->dashed;
4594
+ }else if( pObj->dashed>0.0 ){
4595
+ PNum v = pObj->dashed;
45704596
pik_append_dis(p,"stroke-dasharray:",v,"");
45714597
pik_append_dis(p,",",v,";");
45724598
}
45734599
}
45744600
}
45754601
45764602
/*
45774603
** Compute the vertical locations for all text items in the
4578
-** element pElem. In other words, set every pElem->aTxt[*].eCode
4604
+** object pObj. In other words, set every pObj->aTxt[*].eCode
45794605
** value to contain exactly one of: TP_ABOVE2, TP_ABOVE, TP_CENTER,
45804606
** TP_BELOW, or TP_BELOW2 is set.
45814607
*/
4582
-static void pik_txt_vertical_layout(PElem *pElem){
4608
+static void pik_txt_vertical_layout(PObj *pObj){
45834609
int n, i;
45844610
PToken *aTxt;
4585
- n = pElem->nTxt;
4611
+ n = pObj->nTxt;
45864612
if( n==0 ) return;
4587
- aTxt = pElem->aTxt;
4613
+ aTxt = pObj->aTxt;
45884614
if( n==1 ){
45894615
if( (aTxt[0].eCode & TP_VMASK)==0 ){
45904616
aTxt[0].eCode |= TP_CENTER;
45914617
}
45924618
}else{
@@ -4649,22 +4675,22 @@
46494675
}
46504676
}
46514677
}
46524678
}
46534679
4654
-/* Append multiple <text> SVG element for the text fields of the PElem.
4680
+/* Append multiple <text> SVG elements for the text fields of the PObj.
46554681
** Parameters:
46564682
**
46574683
** p The Pik object into which we are rendering
46584684
**
4659
-** pElem Object containing the text to be rendered
4685
+** pObj Object containing the text to be rendered
46604686
**
46614687
** pBox If not NULL, do no rendering at all. Instead
46624688
** expand the box object so that it will include all
46634689
** of the text.
46644690
*/
4665
-static void pik_append_txt(Pik *p, PElem *pElem, PBox *pBox){
4691
+static void pik_append_txt(Pik *p, PObj *pObj, PBox *pBox){
46664692
PNum dy; /* Half the height of a single line of text */
46674693
PNum dy2; /* Extra vertical space around the center */
46684694
PNum jw; /* Justification margin relative to center */
46694695
int n, i, nz;
46704696
PNum x, y, orig_y;
@@ -4671,35 +4697,35 @@
46714697
const char *z;
46724698
PToken *aTxt;
46734699
int hasCenter = 0;
46744700
46754701
if( p->nErr ) return;
4676
- if( pElem->nTxt==0 ) return;
4677
- aTxt = pElem->aTxt;
4702
+ if( pObj->nTxt==0 ) return;
4703
+ aTxt = pObj->aTxt;
46784704
dy = 0.5*p->charHeight;
4679
- n = pElem->nTxt;
4680
- pik_txt_vertical_layout(pElem);
4681
- x = pElem->ptAt.x;
4705
+ n = pObj->nTxt;
4706
+ pik_txt_vertical_layout(pObj);
4707
+ x = pObj->ptAt.x;
46824708
for(i=0; i<n; i++){
4683
- if( (pElem->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
4709
+ if( (pObj->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
46844710
}
46854711
if( hasCenter ){
46864712
dy2 = dy;
4687
- }else if( pElem->type->isLine ){
4688
- dy2 = pElem->sw;
4713
+ }else if( pObj->type->isLine ){
4714
+ dy2 = pObj->sw;
46894715
}else{
46904716
dy2 = 0.0;
46914717
}
4692
- if( pElem->type->eJust==1 ){
4693
- jw = 0.5*(pElem->w - 0.5*(p->charWidth + pElem->sw));
4718
+ if( pObj->type->eJust==1 ){
4719
+ jw = 0.5*(pObj->w - 0.5*(p->charWidth + pObj->sw));
46944720
}else{
46954721
jw = 0.0;
46964722
}
46974723
for(i=0; i<n; i++){
46984724
PToken *t = &aTxt[i];
46994725
PNum xtraFontScale = 1.0;
4700
- orig_y = pElem->ptAt.y;
4726
+ orig_y = pObj->ptAt.y;
47014727
PNum nx = 0;
47024728
y = 0;
47034729
if( t->eCode & TP_ABOVE2 ) y += dy2 + 3*dy;
47044730
if( t->eCode & TP_ABOVE ) y += dy2 + dy;
47054731
if( t->eCode & TP_BELOW ) y -= dy2 + dy;
@@ -4713,11 +4739,11 @@
47134739
if( pBox!=0 ){
47144740
/* If pBox is not NULL, do not draw any <text>. Instead, just expand
47154741
** pBox to include the text */
47164742
PNum cw = pik_text_length(t)*p->charWidth*xtraFontScale*0.01;
47174743
PNum ch = p->charHeight*0.5*xtraFontScale;
4718
- PNum x0, y0, x1, y1; /* Boundary of text relative to pElem->ptAt */
4744
+ PNum x0, y0, x1, y1; /* Boundary of text relative to pObj->ptAt */
47194745
if( t->eCode & TP_BOLD ) cw *= 1.1;
47204746
if( t->eCode & TP_RJUST ){
47214747
x0 = nx;
47224748
y0 = y-ch;
47234749
x1 = nx-cw;
@@ -4731,14 +4757,14 @@
47314757
x0 = nx+cw/2;
47324758
y0 = y+ch;
47334759
x1 = nx-cw/2;
47344760
y1 = y-ch;
47354761
}
4736
- if( (t->eCode & TP_ALIGN)!=0 && pElem->nPath>=2 ){
4737
- int n = pElem->nPath;
4738
- PNum dx = pElem->aPath[n-1].x - pElem->aPath[0].x;
4739
- PNum dy = pElem->aPath[n-1].y - pElem->aPath[0].y;
4762
+ if( (t->eCode & TP_ALIGN)!=0 && pObj->nPath>=2 ){
4763
+ int n = pObj->nPath;
4764
+ PNum dx = pObj->aPath[n-1].x - pObj->aPath[0].x;
4765
+ PNum dy = pObj->aPath[n-1].y - pObj->aPath[0].y;
47404766
if( dx!=0 || dy!=0 ){
47414767
PNum dist = hypot(dx,dy);
47424768
PNum t;
47434769
dx /= dist;
47444770
dy /= dist;
@@ -4770,22 +4796,22 @@
47704796
pik_append(p, " font-style=\"italic\"", -1);
47714797
}
47724798
if( t->eCode & TP_BOLD ){
47734799
pik_append(p, " font-weight=\"bold\"", -1);
47744800
}
4775
- if( pElem->color>=0.0 ){
4776
- pik_append_clr(p, " fill=\"", pElem->color, "\"");
4801
+ if( pObj->color>=0.0 ){
4802
+ pik_append_clr(p, " fill=\"", pObj->color, "\"");
47774803
}
47784804
xtraFontScale *= p->fontScale;
47794805
if( xtraFontScale<=0.99 || xtraFontScale>=1.01 ){
47804806
pik_append_num(p, " font-size=\"", xtraFontScale*100.0);
47814807
pik_append(p, "%\"", 2);
47824808
}
4783
- if( (t->eCode & TP_ALIGN)!=0 && pElem->nPath>=2 ){
4784
- int n = pElem->nPath;
4785
- PNum dx = pElem->aPath[n-1].x - pElem->aPath[0].x;
4786
- PNum dy = pElem->aPath[n-1].y - pElem->aPath[0].y;
4809
+ if( (t->eCode & TP_ALIGN)!=0 && pObj->nPath>=2 ){
4810
+ int n = pObj->nPath;
4811
+ PNum dx = pObj->aPath[n-1].x - pObj->aPath[0].x;
4812
+ PNum dy = pObj->aPath[n-1].y - pObj->aPath[0].y;
47874813
if( dx!=0 || dy!=0 ){
47884814
PNum ang = atan2(dy,dx)*-180/M_PI;
47894815
pik_append_num(p, " transform=\"rotate(", ang);
47904816
pik_append_xy(p, " ", x, orig_y);
47914817
pik_append(p,")\"",2);
@@ -4808,23 +4834,65 @@
48084834
}
48094835
pik_append(p, "</text>\n", -1);
48104836
}
48114837
}
48124838
4839
+/*
4840
+** Append text (that will go inside of a <pre>...</pre>) that
4841
+** shows the context of an error token.
4842
+*/
4843
+static void pik_error_context(Pik *p, PToken *pErr, int nContext){
4844
+ int iErrPt; /* Index of first byte of error from start of input */
4845
+ int iErrCol; /* Column of the error token on its line */
4846
+ int iStart; /* Start position of the error context */
4847
+ int iEnd; /* End position of the error context */
4848
+ int iLineno; /* Line number of the error */
4849
+ int iFirstLineno; /* Line number of start of error context */
4850
+ int i; /* Loop counter */
4851
+ char zLineno[20]; /* Buffer in which to generate line numbers */
4852
+
4853
+ iErrPt = (int)(pErr->z - p->sIn.z);
4854
+ iLineno = 1;
4855
+ for(i=0; i<iErrPt; i++){
4856
+ if( p->sIn.z[i]=='\n' ){
4857
+ iLineno++;
4858
+ }
4859
+ }
4860
+ iStart = 0;
4861
+ iFirstLineno = 1;
4862
+ while( iFirstLineno+nContext<iLineno ){
4863
+ while( p->sIn.z[iStart]!='\n' ){ iStart++; }
4864
+ iStart++;
4865
+ iFirstLineno++;
4866
+ }
4867
+ for(iEnd=iErrPt; p->sIn.z[iEnd]!=0 && p->sIn.z[iEnd]!='\n'; iEnd++){}
4868
+ i = iStart;
4869
+ while( iFirstLineno<=iLineno ){
4870
+ snprintf(zLineno,sizeof(zLineno)-1,"/* %4d */ ", iFirstLineno++);
4871
+ zLineno[sizeof(zLineno)-1] = 0;
4872
+ pik_append(p, zLineno, -1);
4873
+ for(i=iStart; p->sIn.z[i]!=0 && p->sIn.z[i]!='\n'; i++){}
4874
+ pik_append_text(p, p->sIn.z+iStart, i-iStart, 0);
4875
+ iStart = i+1;
4876
+ pik_append(p, "\n", 1);
4877
+ }
4878
+ for(iErrCol=0, i=iErrPt; i>0 && p->sIn.z[i]!='\n'; iErrCol++, i--){}
4879
+ for(i=0; i<iErrCol+11; i++){ pik_append(p, " ", 1); }
4880
+ for(i=0; i<(int)pErr->n; i++) pik_append(p, "^", 1);
4881
+ pik_append(p, "\n", 1);
4882
+}
4883
+
48134884
48144885
/*
48154886
** Generate an error message for the output. pErr is the token at which
48164887
** the error should point. zMsg is the text of the error message. If
48174888
** either pErr or zMsg is NULL, generate an out-of-memory error message.
48184889
**
48194890
** This routine is a no-op if there has already been an error reported.
48204891
*/
48214892
static void pik_error(Pik *p, PToken *pErr, const char *zMsg){
4822
- int i, j;
4823
- int iCol;
4824
- int nExtra;
4825
- char c;
4893
+ int i;
48264894
if( p==0 ) return;
48274895
if( p->nErr ) return;
48284896
p->nErr++;
48294897
if( zMsg==0 ){
48304898
pik_append(p, "\n<div><p>Out of memory</p></div>\n", -1);
@@ -4833,29 +4901,26 @@
48334901
if( pErr==0 ){
48344902
pik_append(p, "\n", 1);
48354903
pik_append_text(p, zMsg, -1, 0);
48364904
return;
48374905
}
4838
- i = (int)(pErr->z - p->zIn);
4839
- for(j=i; j>0 && p->zIn[j-1]!='\n'; j--){}
4840
- iCol = i - j;
4841
- for(nExtra=0; (c = p->zIn[i+nExtra])!=0 && c!='\n'; nExtra++){}
48424906
pik_append(p, "<div><pre>\n", -1);
4843
- pik_append_text(p, p->zIn, i+nExtra, 3);
4844
- pik_append(p, "\n", 1);
4845
- for(i=0; i<iCol; i++){ pik_append(p, " ", 1); }
4846
- for(i=0; i<(int)pErr->n; i++) pik_append(p, "^", 1);
4847
- pik_append(p, "\nERROR: ", -1);
4907
+ pik_error_context(p, pErr, 5);
4908
+ pik_append(p, "ERROR: ", -1);
48484909
pik_append_text(p, zMsg, -1, 0);
48494910
pik_append(p, "\n", 1);
4850
- pik_append(p, "\n</pre></div>\n", -1);
4911
+ for(i=p->nCtx-1; i>=0; i--){
4912
+ pik_append(p, "Called from:\n", -1);
4913
+ pik_error_context(p, &p->aCtx[i], 0);
4914
+ }
4915
+ pik_append(p, "</pre></div>\n", -1);
48514916
}
48524917
48534918
/*
48544919
** Process an "assert( e1 == e2 )" statement. Always return NULL.
48554920
*/
4856
-static PElem *pik_assert(Pik *p, PNum e1, PToken *pEq, PNum e2){
4921
+static PObj *pik_assert(Pik *p, PNum e1, PToken *pEq, PNum e2){
48574922
char zE1[100], zE2[100], zMsg[300];
48584923
48594924
/* Convert the numbers to strings using %g for comparison. This
48604925
** limits the precision of the comparison to account for rounding error. */
48614926
snprintf(zE1, sizeof(zE1), "%g", e1); zE1[sizeof(zE1)-1] = 0;
@@ -4868,11 +4933,11 @@
48684933
}
48694934
48704935
/*
48714936
** Process an "assert( place1 == place2 )" statement. Always return NULL.
48724937
*/
4873
-static PElem *pik_position_assert(Pik *p, PPoint *e1, PToken *pEq, PPoint *e2){
4938
+static PObj *pik_position_assert(Pik *p, PPoint *e1, PToken *pEq, PPoint *e2){
48744939
char zE1[100], zE2[100], zMsg[210];
48754940
48764941
/* Convert the numbers to strings using %g for comparison. This
48774942
** limits the precision of the comparison to account for rounding error. */
48784943
snprintf(zE1, sizeof(zE1), "(%g,%g)", e1->x, e1->y); zE1[sizeof(zE1)-1] = 0;
@@ -4882,29 +4947,29 @@
48824947
pik_error(p, pEq, zMsg);
48834948
}
48844949
return 0;
48854950
}
48864951
4887
-/* Free a complete list of elements */
4888
-static void pik_elist_free(Pik *p, PEList *pEList){
4952
+/* Free a complete list of objects */
4953
+static void pik_elist_free(Pik *p, PList *pList){
48894954
int i;
4890
- if( pEList==0 ) return;
4891
- for(i=0; i<pEList->n; i++){
4892
- pik_elem_free(p, pEList->a[i]);
4955
+ if( pList==0 ) return;
4956
+ for(i=0; i<pList->n; i++){
4957
+ pik_elem_free(p, pList->a[i]);
48934958
}
4894
- free(pEList->a);
4895
- free(pEList);
4959
+ free(pList->a);
4960
+ free(pList);
48964961
return;
48974962
}
48984963
4899
-/* Free a single element, and its substructure */
4900
-static void pik_elem_free(Pik *p, PElem *pElem){
4901
- if( pElem==0 ) return;
4902
- free(pElem->zName);
4903
- pik_elist_free(p, pElem->pSublist);
4904
- free(pElem->aPath);
4905
- free(pElem);
4964
+/* Free a single object, and its substructure */
4965
+static void pik_elem_free(Pik *p, PObj *pObj){
4966
+ if( pObj==0 ) return;
4967
+ free(pObj->zName);
4968
+ pik_elist_free(p, pObj->pSublist);
4969
+ free(pObj->aPath);
4970
+ free(pObj);
49064971
}
49074972
49084973
/* Convert a numeric literal into a number. Return that number.
49094974
** There is no error handling because the tokenizer has already
49104975
** assured us that the numeric literal is valid.
@@ -5017,42 +5082,42 @@
50175082
if( pA->ne.y<y+ry ) pA->ne.y = y+ry;
50185083
}
50195084
50205085
50215086
5022
-/* Append a new element onto the end of an element_list. The
5023
-** element_list is created if it does not already exist. Return
5024
-** the new element list.
5087
+/* Append a new object onto the end of an object list. The
5088
+** object list is created if it does not already exist. Return
5089
+** the new object list.
50255090
*/
5026
-static PEList *pik_elist_append(Pik *p, PEList *pEList, PElem *pElem){
5027
- if( pElem==0 ) return pEList;
5028
- if( pEList==0 ){
5029
- pEList = malloc(sizeof(*pEList));
5030
- if( pEList==0 ){
5091
+static PList *pik_elist_append(Pik *p, PList *pList, PObj *pObj){
5092
+ if( pObj==0 ) return pList;
5093
+ if( pList==0 ){
5094
+ pList = malloc(sizeof(*pList));
5095
+ if( pList==0 ){
50315096
pik_error(p, 0, 0);
5032
- pik_elem_free(p, pElem);
5097
+ pik_elem_free(p, pObj);
50335098
return 0;
50345099
}
5035
- memset(pEList, 0, sizeof(*pEList));
5100
+ memset(pList, 0, sizeof(*pList));
50365101
}
5037
- if( pEList->n>=pEList->nAlloc ){
5038
- int nNew = (pEList->n+5)*2;
5039
- PElem **pNew = realloc(pEList->a, sizeof(PElem*)*nNew);
5102
+ if( pList->n>=pList->nAlloc ){
5103
+ int nNew = (pList->n+5)*2;
5104
+ PObj **pNew = realloc(pList->a, sizeof(PObj*)*nNew);
50405105
if( pNew==0 ){
50415106
pik_error(p, 0, 0);
5042
- pik_elem_free(p, pElem);
5043
- return pEList;
5044
- }
5045
- pEList->nAlloc = nNew;
5046
- pEList->a = pNew;
5047
- }
5048
- pEList->a[pEList->n++] = pElem;
5049
- p->list = pEList;
5050
- return pEList;
5107
+ pik_elem_free(p, pObj);
5108
+ return pList;
5109
+ }
5110
+ pList->nAlloc = nNew;
5111
+ pList->a = pNew;
5112
+ }
5113
+ pList->a[pList->n++] = pObj;
5114
+ p->list = pList;
5115
+ return pList;
50515116
}
50525117
5053
-/* Convert an element class name into a PClass pointer
5118
+/* Convert an object class name into a PClass pointer
50545119
*/
50555120
static const PClass *pik_find_class(PToken *pId){
50565121
int first = 0;
50575122
int last = count(aClass) - 1;
50585123
do{
@@ -5069,19 +5134,19 @@
50695134
}
50705135
}while( first<=last );
50715136
return 0;
50725137
}
50735138
5074
-/* Allocate and return a new PElem object.
5139
+/* Allocate and return a new PObj object.
50755140
**
5076
-** If pId!=0 then pId is an identifier that defines the element class.
5141
+** If pId!=0 then pId is an identifier that defines the object class.
50775142
** If pStr!=0 then it is a STRING literal that defines a text object.
50785143
** If pSublist!=0 then this is a [...] object. If all three parameters
50795144
** are NULL then this is a no-op object used to define a PLACENAME.
50805145
*/
5081
-static PElem *pik_elem_new(Pik *p, PToken *pId, PToken *pStr,PEList *pSublist){
5082
- PElem *pNew;
5146
+static PObj *pik_elem_new(Pik *p, PToken *pId, PToken *pStr,PList *pSublist){
5147
+ PObj *pNew;
50835148
int miss = 0;
50845149
50855150
if( p->nErr ) return 0;
50865151
pNew = malloc( sizeof(*pNew) );
50875152
if( pNew==0 ){
@@ -5095,11 +5160,11 @@
50955160
p->thenFlag = 0;
50965161
if( p->list==0 || p->list->n==0 ){
50975162
pNew->ptAt.x = pNew->ptAt.y = 0.0;
50985163
pNew->eWith = CP_C;
50995164
}else{
5100
- PElem *pPrior = p->list->a[p->list->n-1];
5165
+ PObj *pPrior = p->list->a[p->list->n-1];
51015166
pNew->ptAt = pPrior->ptExit;
51025167
switch( p->eDir ){
51035168
default: pNew->eWith = CP_W; break;
51045169
case DIR_LEFT: pNew->eWith = CP_E; break;
51055170
case DIR_UP: pNew->eWith = CP_S; break;
@@ -5138,32 +5203,72 @@
51385203
pNew->fill = pik_value(p, "fill",4,0);
51395204
pNew->color = pik_value(p, "color",5,0);
51405205
pClass->xInit(p, pNew);
51415206
return pNew;
51425207
}
5143
- pik_error(p, pId, "unknown element type");
5208
+ pik_error(p, pId, "unknown object type");
51445209
pik_elem_free(p, pNew);
51455210
return 0;
51465211
}
51475212
pNew->type = &noopClass;
51485213
pNew->ptExit = pNew->ptEnter = pNew->ptAt;
51495214
return pNew;
51505215
}
51515216
51525217
/*
5153
-** Set the output direction and exit point for an element.
5218
+** If the ID token in the argument is the name of a macro, return
5219
+** the PMacro object for that macro
5220
+*/
5221
+static PMacro *pik_find_macro(Pik *p, PToken *pId){
5222
+ PMacro *pMac;
5223
+ for(pMac = p->pMacros; pMac; pMac=pMac->pNext){
5224
+ if( pMac->macroName.n==pId->n
5225
+ && strncmp(pMac->macroName.z,pId->z,pId->n)==0
5226
+ ){
5227
+ return pMac;
5228
+ }
5229
+ }
5230
+ return 0;
5231
+}
5232
+
5233
+/* Add a new macro
5234
+*/
5235
+static void pik_add_macro(
5236
+ Pik *p, /* Current Pikchr diagram */
5237
+ PToken *pId, /* The ID token that defines the macro name */
5238
+ PToken *pCode /* Macro body inside of {...} */
5239
+){
5240
+ PMacro *pNew = pik_find_macro(p, pId);
5241
+ if( pNew==0 ){
5242
+ pNew = malloc( sizeof(*pNew) );
5243
+ if( pNew==0 ){
5244
+ pik_error(p, 0, 0);
5245
+ return;
5246
+ }
5247
+ pNew->pNext = p->pMacros;
5248
+ p->pMacros = pNew;
5249
+ pNew->macroName = *pId;
5250
+ }
5251
+ pNew->macroBody.z = pCode->z+1;
5252
+ pNew->macroBody.n = pCode->n-2;
5253
+ pNew->inUse = 0;
5254
+}
5255
+
5256
+
5257
+/*
5258
+** Set the output direction and exit point for an object
51545259
*/
5155
-static void pik_elem_set_exit(PElem *pElem, int eDir){
5260
+static void pik_elem_set_exit(PObj *pObj, int eDir){
51565261
assert( ValidDir(eDir) );
5157
- pElem->outDir = eDir;
5158
- if( !pElem->type->isLine || pElem->bClose ){
5159
- pElem->ptExit = pElem->ptAt;
5160
- switch( pElem->outDir ){
5161
- default: pElem->ptExit.x += pElem->w*0.5; break;
5162
- case DIR_LEFT: pElem->ptExit.x -= pElem->w*0.5; break;
5163
- case DIR_UP: pElem->ptExit.y += pElem->h*0.5; break;
5164
- case DIR_DOWN: pElem->ptExit.y -= pElem->h*0.5; break;
5262
+ pObj->outDir = eDir;
5263
+ if( !pObj->type->isLine || pObj->bClose ){
5264
+ pObj->ptExit = pObj->ptAt;
5265
+ switch( pObj->outDir ){
5266
+ default: pObj->ptExit.x += pObj->w*0.5; break;
5267
+ case DIR_LEFT: pObj->ptExit.x -= pObj->w*0.5; break;
5268
+ case DIR_UP: pObj->ptExit.y += pObj->h*0.5; break;
5269
+ case DIR_DOWN: pObj->ptExit.y -= pObj->h*0.5; break;
51655270
}
51665271
}
51675272
}
51685273
51695274
/* Change the layout direction.
@@ -5188,34 +5293,34 @@
51885293
if( p->list && p->list->n ){
51895294
pik_elem_set_exit(p->list->a[p->list->n-1], eDir);
51905295
}
51915296
}
51925297
5193
-/* Move all coordinates contained within an element (and within its
5298
+/* Move all coordinates contained within an object (and within its
51945299
** substructure) by dx, dy
51955300
*/
5196
-static void pik_elem_move(PElem *pElem, PNum dx, PNum dy){
5301
+static void pik_elem_move(PObj *pObj, PNum dx, PNum dy){
51975302
int i;
5198
- pElem->ptAt.x += dx;
5199
- pElem->ptAt.y += dy;
5200
- pElem->ptEnter.x += dx;
5201
- pElem->ptEnter.y += dy;
5202
- pElem->ptExit.x += dx;
5203
- pElem->ptExit.y += dy;
5204
- pElem->bbox.ne.x += dx;
5205
- pElem->bbox.ne.y += dy;
5206
- pElem->bbox.sw.x += dx;
5207
- pElem->bbox.sw.y += dy;
5208
- for(i=0; i<pElem->nPath; i++){
5209
- pElem->aPath[i].x += dx;
5210
- pElem->aPath[i].y += dy;
5211
- }
5212
- if( pElem->pSublist ){
5213
- pik_elist_move(pElem->pSublist, dx, dy);
5214
- }
5215
-}
5216
-static void pik_elist_move(PEList *pList, PNum dx, PNum dy){
5303
+ pObj->ptAt.x += dx;
5304
+ pObj->ptAt.y += dy;
5305
+ pObj->ptEnter.x += dx;
5306
+ pObj->ptEnter.y += dy;
5307
+ pObj->ptExit.x += dx;
5308
+ pObj->ptExit.y += dy;
5309
+ pObj->bbox.ne.x += dx;
5310
+ pObj->bbox.ne.y += dy;
5311
+ pObj->bbox.sw.x += dx;
5312
+ pObj->bbox.sw.y += dy;
5313
+ for(i=0; i<pObj->nPath; i++){
5314
+ pObj->aPath[i].x += dx;
5315
+ pObj->aPath[i].y += dy;
5316
+ }
5317
+ if( pObj->pSublist ){
5318
+ pik_elist_move(pObj->pSublist, dx, dy);
5319
+ }
5320
+}
5321
+static void pik_elist_move(PList *pList, PNum dx, PNum dy){
52175322
int i;
52185323
for(i=0; i<pList->n; i++){
52195324
pik_elem_move(pList->a[i], dx, dy);
52205325
}
52215326
}
@@ -5223,31 +5328,31 @@
52235328
/*
52245329
** Check to see if it is ok to set the value of paraemeter mThis.
52255330
** Return 0 if it is ok. If it not ok, generate an appropriate
52265331
** error message and return non-zero.
52275332
**
5228
-** Flags are set in pElem so that the same element or conflicting
5229
-** elements may not be set again.
5333
+** Flags are set in pObj so that the same object or conflicting
5334
+** objects may not be set again.
52305335
**
52315336
** To be ok, bit mThis must be clear and no more than one of
52325337
** the bits identified by mBlockers may be set.
52335338
*/
52345339
static int pik_param_ok(
52355340
Pik *p, /* For storing the error message (if any) */
5236
- PElem *pElem, /* The element under construction */
5341
+ PObj *pObj, /* The object under construction */
52375342
PToken *pId, /* Make the error point to this token */
52385343
int mThis /* Value we are trying to set */
52395344
){
5240
- if( pElem->mProp & mThis ){
5345
+ if( pObj->mProp & mThis ){
52415346
pik_error(p, pId, "value is already set");
52425347
return 1;
52435348
}
5244
- if( pElem->mCalc & mThis ){
5349
+ if( pObj->mCalc & mThis ){
52455350
pik_error(p, pId, "value already fixed by prior constraints");
52465351
return 1;
52475352
}
5248
- pElem->mProp |= mThis;
5353
+ pObj->mProp |= mThis;
52495354
return 0;
52505355
}
52515356
52525357
52535358
/*
@@ -5255,56 +5360,56 @@
52555360
**
52565361
** The rAbs term is an absolute value to add in. rRel is
52575362
** a relative value by which to change the current value.
52585363
*/
52595364
void pik_set_numprop(Pik *p, PToken *pId, PRel *pVal){
5260
- PElem *pElem = p->cur;
5365
+ PObj *pObj = p->cur;
52615366
switch( pId->eType ){
52625367
case T_HEIGHT:
5263
- if( pik_param_ok(p, pElem, pId, A_HEIGHT) ) return;
5264
- pElem->h = pElem->h*pVal->rRel + pVal->rAbs;
5368
+ if( pik_param_ok(p, pObj, pId, A_HEIGHT) ) return;
5369
+ pObj->h = pObj->h*pVal->rRel + pVal->rAbs;
52655370
break;
52665371
case T_WIDTH:
5267
- if( pik_param_ok(p, pElem, pId, A_WIDTH) ) return;
5268
- pElem->w = pElem->w*pVal->rRel + pVal->rAbs;
5372
+ if( pik_param_ok(p, pObj, pId, A_WIDTH) ) return;
5373
+ pObj->w = pObj->w*pVal->rRel + pVal->rAbs;
52695374
break;
52705375
case T_RADIUS:
5271
- if( pik_param_ok(p, pElem, pId, A_RADIUS) ) return;
5272
- pElem->rad = pElem->rad*pVal->rRel + pVal->rAbs;
5376
+ if( pik_param_ok(p, pObj, pId, A_RADIUS) ) return;
5377
+ pObj->rad = pObj->rad*pVal->rRel + pVal->rAbs;
52735378
break;
52745379
case T_DIAMETER:
5275
- if( pik_param_ok(p, pElem, pId, A_RADIUS) ) return;
5276
- pElem->rad = pElem->rad*pVal->rRel + 0.5*pVal->rAbs; /* diam it 2x rad */
5380
+ if( pik_param_ok(p, pObj, pId, A_RADIUS) ) return;
5381
+ pObj->rad = pObj->rad*pVal->rRel + 0.5*pVal->rAbs; /* diam it 2x rad */
52775382
break;
52785383
case T_THICKNESS:
5279
- if( pik_param_ok(p, pElem, pId, A_THICKNESS) ) return;
5280
- pElem->sw = pElem->sw*pVal->rRel + pVal->rAbs;
5384
+ if( pik_param_ok(p, pObj, pId, A_THICKNESS) ) return;
5385
+ pObj->sw = pObj->sw*pVal->rRel + pVal->rAbs;
52815386
break;
52825387
}
5283
- if( pElem->type->xNumProp ){
5284
- pElem->type->xNumProp(p, pElem, pId);
5388
+ if( pObj->type->xNumProp ){
5389
+ pObj->type->xNumProp(p, pObj, pId);
52855390
}
52865391
return;
52875392
}
52885393
52895394
/*
52905395
** Set a color property. The argument is an RGB value.
52915396
*/
52925397
void pik_set_clrprop(Pik *p, PToken *pId, PNum rClr){
5293
- PElem *pElem = p->cur;
5398
+ PObj *pObj = p->cur;
52945399
switch( pId->eType ){
52955400
case T_FILL:
5296
- if( pik_param_ok(p, pElem, pId, A_FILL) ) return;
5297
- pElem->fill = rClr;
5401
+ if( pik_param_ok(p, pObj, pId, A_FILL) ) return;
5402
+ pObj->fill = rClr;
52985403
break;
52995404
case T_COLOR:
5300
- if( pik_param_ok(p, pElem, pId, A_COLOR) ) return;
5301
- pElem->color = rClr;
5405
+ if( pik_param_ok(p, pObj, pId, A_COLOR) ) return;
5406
+ pObj->color = rClr;
53025407
break;
53035408
}
5304
- if( pElem->type->xNumProp ){
5305
- pElem->type->xNumProp(p, pElem, pId);
5409
+ if( pObj->type->xNumProp ){
5410
+ pObj->type->xNumProp(p, pObj, pId);
53065411
}
53075412
return;
53085413
}
53095414
53105415
/*
@@ -5312,23 +5417,23 @@
53125417
**
53135418
** Use the value supplied by pVal if available. If pVal==0, use
53145419
** a default.
53155420
*/
53165421
void pik_set_dashed(Pik *p, PToken *pId, PNum *pVal){
5317
- PElem *pElem = p->cur;
5422
+ PObj *pObj = p->cur;
53185423
PNum v;
53195424
switch( pId->eType ){
53205425
case T_DOTTED: {
53215426
v = pVal==0 ? pik_value(p,"dashwid",7,0) : *pVal;
5322
- pElem->dotted = v;
5323
- pElem->dashed = 0.0;
5427
+ pObj->dotted = v;
5428
+ pObj->dashed = 0.0;
53245429
break;
53255430
}
53265431
case T_DASHED: {
53275432
v = pVal==0 ? pik_value(p,"dashwid",7,0) : *pVal;
5328
- pElem->dashed = v;
5329
- pElem->dotted = 0.0;
5433
+ pObj->dashed = v;
5434
+ pObj->dotted = 0.0;
53305435
break;
53315436
}
53325437
}
53335438
}
53345439
@@ -5346,18 +5451,18 @@
53465451
53475452
/* Add a new term to the path for a line-oriented object by transferring
53485453
** the information in the ptTo field over onto the path and into ptFrom
53495454
** resetting the ptTo.
53505455
*/
5351
-static void pik_then(Pik *p, PToken *pToken, PElem *pElem){
5456
+static void pik_then(Pik *p, PToken *pToken, PObj *pObj){
53525457
int n;
5353
- if( !pElem->type->isLine ){
5458
+ if( !pObj->type->isLine ){
53545459
pik_error(p, pToken, "use with line-oriented objects only");
53555460
return;
53565461
}
53575462
n = p->nTPath - 1;
5358
- if( n<1 && (pElem->mProp & A_FROM)==0 ){
5463
+ if( n<1 && (pObj->mProp & A_FROM)==0 ){
53595464
pik_error(p, pToken, "no prior path points");
53605465
return;
53615466
}
53625467
p->thenFlag = 1;
53635468
}
@@ -5375,22 +5480,22 @@
53755480
p->aTPath[n] = p->aTPath[n-1];
53765481
p->mTPath = 0;
53775482
return n;
53785483
}
53795484
5380
-/* Add a direction term to an element. "up 0.5", or "left 3", or "down"
5485
+/* Add a direction term to an object. "up 0.5", or "left 3", or "down"
53815486
** or "down 50%".
53825487
*/
53835488
static void pik_add_direction(Pik *p, PToken *pDir, PRel *pVal){
5384
- PElem *pElem = p->cur;
5489
+ PObj *pObj = p->cur;
53855490
int n;
53865491
int dir;
5387
- if( !pElem->type->isLine ){
5492
+ if( !pObj->type->isLine ){
53885493
if( pDir ){
53895494
pik_error(p, pDir, "use with line-oriented objects only");
53905495
}else{
5391
- PToken x = pik_next_semantic_token(&pElem->errTok);
5496
+ PToken x = pik_next_semantic_token(&pObj->errTok);
53925497
pik_error(p, &x, "syntax error");
53935498
}
53945499
return;
53955500
}
53965501
pik_reset_samepath(p);
@@ -5401,30 +5506,30 @@
54015506
}
54025507
dir = pDir ? pDir->eCode : p->eDir;
54035508
switch( dir ){
54045509
case DIR_UP:
54055510
if( p->mTPath & 2 ) n = pik_next_rpath(p, pDir);
5406
- p->aTPath[n].y += pVal->rAbs + pElem->h*pVal->rRel;
5511
+ p->aTPath[n].y += pVal->rAbs + pObj->h*pVal->rRel;
54075512
p->mTPath |= 2;
54085513
break;
54095514
case DIR_DOWN:
54105515
if( p->mTPath & 2 ) n = pik_next_rpath(p, pDir);
5411
- p->aTPath[n].y -= pVal->rAbs + pElem->h*pVal->rRel;
5516
+ p->aTPath[n].y -= pVal->rAbs + pObj->h*pVal->rRel;
54125517
p->mTPath |= 2;
54135518
break;
54145519
case DIR_RIGHT:
54155520
if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
5416
- p->aTPath[n].x += pVal->rAbs + pElem->w*pVal->rRel;
5521
+ p->aTPath[n].x += pVal->rAbs + pObj->w*pVal->rRel;
54175522
p->mTPath |= 1;
54185523
break;
54195524
case DIR_LEFT:
54205525
if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
5421
- p->aTPath[n].x -= pVal->rAbs + pElem->w*pVal->rRel;
5526
+ p->aTPath[n].x -= pVal->rAbs + pObj->w*pVal->rRel;
54225527
p->mTPath |= 1;
54235528
break;
54245529
}
5425
- pElem->outDir = dir;
5530
+ pObj->outDir = dir;
54265531
}
54275532
54285533
/* Process a movement attribute of one of these forms:
54295534
**
54305535
** pDist pHdgKW rHdg pEdgept
@@ -5437,14 +5542,14 @@
54375542
PToken *pHeading, /* "heading" keyword if present */
54385543
PNum rHdg, /* Angle argument to "heading" keyword */
54395544
PToken *pEdgept, /* EDGEPT keyword "ne", "sw", etc... */
54405545
PToken *pErr /* Token to use for error messages */
54415546
){
5442
- PElem *pElem = p->cur;
5547
+ PObj *pObj = p->cur;
54435548
int n;
54445549
PNum rDist = pDist->rAbs + pik_value(p,"linewid",7,0)*pDist->rRel;
5445
- if( !pElem->type->isLine ){
5550
+ if( !pObj->type->isLine ){
54465551
pik_error(p, pErr, "use with line-oriented objects only");
54475552
return;
54485553
}
54495554
pik_reset_samepath(p);
54505555
do{
@@ -5460,19 +5565,19 @@
54605565
return;
54615566
}else{
54625567
rHdg = pik_hdg_angle[pEdgept->eEdge];
54635568
}
54645569
if( rHdg<=45.0 ){
5465
- pElem->outDir = DIR_UP;
5570
+ pObj->outDir = DIR_UP;
54665571
}else if( rHdg<=135.0 ){
5467
- pElem->outDir = DIR_RIGHT;
5572
+ pObj->outDir = DIR_RIGHT;
54685573
}else if( rHdg<=225.0 ){
5469
- pElem->outDir = DIR_DOWN;
5574
+ pObj->outDir = DIR_DOWN;
54705575
}else if( rHdg<=315.0 ){
5471
- pElem->outDir = DIR_LEFT;
5576
+ pObj->outDir = DIR_LEFT;
54725577
}else{
5473
- pElem->outDir = DIR_UP;
5578
+ pObj->outDir = DIR_UP;
54745579
}
54755580
rHdg *= 0.017453292519943295769; /* degrees to radians */
54765581
p->aTPath[n].x += rDist*sin(rHdg);
54775582
p->aTPath[n].y += rDist*cos(rHdg);
54785583
p->mTPath = 2;
@@ -5484,13 +5589,13 @@
54845589
** pDir is the first keyword, "right" or "left" or "up" or "down".
54855590
** The movement is in that direction until its closest approach to
54865591
** the point specified by pPoint.
54875592
*/
54885593
static void pik_evenwith(Pik *p, PToken *pDir, PPoint *pPlace){
5489
- PElem *pElem = p->cur;
5594
+ PObj *pObj = p->cur;
54905595
int n;
5491
- if( !pElem->type->isLine ){
5596
+ if( !pObj->type->isLine ){
54925597
pik_error(p, pDir, "use with line-oriented objects only");
54935598
return;
54945599
}
54955600
pik_reset_samepath(p);
54965601
n = p->nTPath - 1;
@@ -5510,25 +5615,25 @@
55105615
if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
55115616
p->aTPath[n].x = pPlace->x;
55125617
p->mTPath |= 1;
55135618
break;
55145619
}
5515
- pElem->outDir = pDir->eCode;
5620
+ pObj->outDir = pDir->eCode;
55165621
}
55175622
5518
-/* Set the "from" of an element
5623
+/* Set the "from" of an object
55195624
*/
5520
-static void pik_set_from(Pik *p, PElem *pElem, PToken *pTk, PPoint *pPt){
5521
- if( !pElem->type->isLine ){
5625
+static void pik_set_from(Pik *p, PObj *pObj, PToken *pTk, PPoint *pPt){
5626
+ if( !pObj->type->isLine ){
55225627
pik_error(p, pTk, "use \"at\" to position this object");
55235628
return;
55245629
}
5525
- if( pElem->mProp & A_FROM ){
5630
+ if( pObj->mProp & A_FROM ){
55265631
pik_error(p, pTk, "line start location already fixed");
55275632
return;
55285633
}
5529
- if( pElem->bClose ){
5634
+ if( pObj->bClose ){
55305635
pik_error(p, pTk, "polygon is closed");
55315636
return;
55325637
}
55335638
if( p->nTPath>1 ){
55345639
PNum dx = pPt->x - p->aTPath[0].x;
@@ -5539,22 +5644,22 @@
55395644
p->aTPath[i].y += dy;
55405645
}
55415646
}
55425647
p->aTPath[0] = *pPt;
55435648
p->mTPath = 3;
5544
- pElem->mProp |= A_FROM;
5649
+ pObj->mProp |= A_FROM;
55455650
}
55465651
5547
-/* Set the "to" of an element
5652
+/* Set the "to" of an object
55485653
*/
5549
-static void pik_add_to(Pik *p, PElem *pElem, PToken *pTk, PPoint *pPt){
5654
+static void pik_add_to(Pik *p, PObj *pObj, PToken *pTk, PPoint *pPt){
55505655
int n = p->nTPath-1;
5551
- if( !pElem->type->isLine ){
5656
+ if( !pObj->type->isLine ){
55525657
pik_error(p, pTk, "use \"at\" to position this object");
55535658
return;
55545659
}
5555
- if( pElem->bClose ){
5660
+ if( pObj->bClose ){
55565661
pik_error(p, pTk, "polygon is closed");
55575662
return;
55585663
}
55595664
if( n==0 || p->mTPath==3 || p->thenFlag ){
55605665
n = pik_next_rpath(p, pTk);
@@ -5562,65 +5667,70 @@
55625667
p->aTPath[n] = *pPt;
55635668
p->mTPath = 3;
55645669
}
55655670
55665671
static void pik_close_path(Pik *p, PToken *pErr){
5567
- PElem *pElem = p->cur;
5672
+ PObj *pObj = p->cur;
55685673
if( p->nTPath<3 ){
55695674
pik_error(p, pErr,
55705675
"need at least 3 vertexes in order to close the polygon");
55715676
return;
55725677
}
5573
- if( pElem->bClose ){
5678
+ if( pObj->bClose ){
55745679
pik_error(p, pErr, "polygon already closed");
55755680
return;
55765681
}
5577
- pElem->bClose = 1;
5682
+ pObj->bClose = 1;
55785683
}
55795684
5580
-/* Lower the layer of the current element so that it is behind the
5581
-** given element.
5685
+/* Lower the layer of the current object so that it is behind the
5686
+** given object.
55825687
*/
5583
-static void pik_behind(Pik *p, PElem *pOther){
5584
- PElem *pElem = p->cur;
5585
- if( p->nErr==0 && pElem->iLayer>=pOther->iLayer ){
5586
- pElem->iLayer = pOther->iLayer - 1;
5688
+static void pik_behind(Pik *p, PObj *pOther){
5689
+ PObj *pObj = p->cur;
5690
+ if( p->nErr==0 && pObj->iLayer>=pOther->iLayer ){
5691
+ pObj->iLayer = pOther->iLayer - 1;
55875692
}
55885693
}
55895694
55905695
5591
-/* Set the "at" of an element
5696
+/* Set the "at" of an object
55925697
*/
55935698
static void pik_set_at(Pik *p, PToken *pEdge, PPoint *pAt, PToken *pErrTok){
5594
- PElem *pElem;
5699
+ PObj *pObj;
5700
+ static unsigned char eDirToCp[] = { CP_E, CP_S, CP_W, CP_N };
55955701
if( p->nErr ) return;
5596
- pElem = p->cur;
5702
+ pObj = p->cur;
55975703
5598
- if( pElem->type->isLine ){
5704
+ if( pObj->type->isLine ){
55995705
pik_error(p, pErrTok, "use \"from\" and \"to\" to position this object");
56005706
return;
56015707
}
5602
- if( pElem->mProp & A_AT ){
5708
+ if( pObj->mProp & A_AT ){
56035709
pik_error(p, pErrTok, "location fixed by prior \"at\"");
56045710
return;
56055711
}
5606
- pElem->mProp |= A_AT;
5607
- pElem->eWith = pEdge ? pEdge->eEdge : CP_C;
5608
- pElem->with = *pAt;
5712
+ pObj->mProp |= A_AT;
5713
+ pObj->eWith = pEdge ? pEdge->eEdge : CP_C;
5714
+ if( pObj->eWith>=CP_END ){
5715
+ int dir = pObj->eWith==CP_END ? pObj->outDir : pObj->inDir;
5716
+ pObj->eWith = eDirToCp[dir];
5717
+ }
5718
+ pObj->with = *pAt;
56095719
}
56105720
56115721
/*
5612
-** Try to add a text attribute to an element
5722
+** Try to add a text attribute to an object
56135723
*/
56145724
static void pik_add_txt(Pik *p, PToken *pTxt, int iPos){
5615
- PElem *pElem = p->cur;
5725
+ PObj *pObj = p->cur;
56165726
PToken *pT;
5617
- if( pElem->nTxt >= count(pElem->aTxt) ){
5727
+ if( pObj->nTxt >= count(pObj->aTxt) ){
56185728
pik_error(p, pTxt, "too many text terms");
56195729
return;
56205730
}
5621
- pT = &pElem->aTxt[pElem->nTxt++];
5731
+ pT = &pObj->aTxt[pObj->nTxt++];
56225732
*pT = *pTxt;
56235733
pT->eCode = iPos;
56245734
}
56255735
56265736
/* Merge "text-position" flags
@@ -5813,29 +5923,36 @@
58135923
** underestimates the text size.
58145924
** (4) Previously set attributes will not be altered. In other words,
58155925
** "width 1in fit" might cause the height to change, but the
58165926
** width is now set.
58175927
** (5) This only works for attributes that have an xFit method.
5928
+**
5929
+** The eWhich parameter is:
5930
+**
5931
+** 1: Fit horizontally only
5932
+** 2: Fit vertically only
5933
+** 3: Fit both ways
58185934
*/
5819
-static void pik_size_to_fit(Pik *p, PToken *pFit){
5820
- PElem *pElem;
5935
+static void pik_size_to_fit(Pik *p, PToken *pFit, int eWhich){
5936
+ PObj *pObj;
58215937
PNum w, h;
58225938
PBox bbox;
58235939
if( p->nErr ) return;
5824
- pElem = p->cur;
5940
+ pObj = p->cur;
58255941
5826
- if( pElem->nTxt==0 ){
5942
+ if( pObj->nTxt==0 ){
58275943
pik_error(0, pFit, "no text to fit to");
58285944
return;
58295945
}
5830
- if( pElem->type->xFit==0 ) return;
5946
+ if( pObj->type->xFit==0 ) return;
58315947
pik_bbox_init(&bbox);
58325948
pik_compute_layout_settings(p);
5833
- pik_append_txt(p, pElem, &bbox);
5834
- w = (bbox.ne.x - bbox.sw.x) + p->charWidth;
5835
- h = (bbox.ne.y - bbox.sw.y) + 0.5*p->charHeight;
5836
- pElem->type->xFit(p, pElem, w, h);
5949
+ pik_append_txt(p, pObj, &bbox);
5950
+ w = (eWhich & 1)!=0 ? (bbox.ne.x - bbox.sw.x) + p->charWidth : 0;
5951
+ h = (eWhich & 2)!=0 ? (bbox.ne.y - bbox.sw.y) + 0.5*p->charHeight : 0;
5952
+ pObj->type->xFit(p, pObj, w, h);
5953
+ pObj->mProp |= A_FIT;
58375954
}
58385955
58395956
/* Set a local variable name to "val".
58405957
**
58415958
** The name might be a built-in variable or a color name. In either case,
@@ -5988,15 +6105,15 @@
59886105
}
59896106
if( i==0 && pik_token_eq(pNth,"first")==0 ) i = 1;
59906107
return i;
59916108
}
59926109
5993
-/* Search for the NTH element.
6110
+/* Search for the NTH object.
59946111
**
5995
-** If pBasis is not NULL then it should be a [] element. Use the
5996
-** sublist of that [] element for the search. If pBasis is not a []
5997
-** element, then throw an error.
6112
+** If pBasis is not NULL then it should be a [] object. Use the
6113
+** sublist of that [] object for the search. If pBasis is not a []
6114
+** object, then throw an error.
59986115
**
59996116
** The pNth token describes the N-th search. The pNth->eCode value
60006117
** is one more than the number of items to skip. It is negative
60016118
** to search backwards. If pNth->eType==T_ID, then it is the name
60026119
** of a class to search for. If pNth->eType==T_LB, then
@@ -6003,12 +6120,12 @@
60036120
** search for a [] object. If pNth->eType==T_LAST, then search for
60046121
** any type.
60056122
**
60066123
** Raise an error if the item is not found.
60076124
*/
6008
-static PElem *pik_find_nth(Pik *p, PElem *pBasis, PToken *pNth){
6009
- PEList *pList;
6125
+static PObj *pik_find_nth(Pik *p, PObj *pBasis, PToken *pNth){
6126
+ PList *pList;
60106127
int i, n;
60116128
const PClass *pClass;
60126129
if( pBasis==0 ){
60136130
pList = p->list;
60146131
}else{
@@ -6030,34 +6147,34 @@
60306147
}
60316148
}
60326149
n = pNth->eCode;
60336150
if( n<0 ){
60346151
for(i=pList->n-1; i>=0; i--){
6035
- PElem *pElem = pList->a[i];
6036
- if( pClass && pElem->type!=pClass ) continue;
6152
+ PObj *pObj = pList->a[i];
6153
+ if( pClass && pObj->type!=pClass ) continue;
60376154
n++;
6038
- if( n==0 ){ return pElem; }
6155
+ if( n==0 ){ return pObj; }
60396156
}
60406157
}else{
60416158
for(i=0; i<pList->n; i++){
6042
- PElem *pElem = pList->a[i];
6043
- if( pClass && pElem->type!=pClass ) continue;
6159
+ PObj *pObj = pList->a[i];
6160
+ if( pClass && pObj->type!=pClass ) continue;
60446161
n--;
6045
- if( n==0 ){ return pElem; }
6162
+ if( n==0 ){ return pObj; }
60466163
}
60476164
}
60486165
pik_error(p, pNth, "no such object");
60496166
return 0;
60506167
}
60516168
6052
-/* Search for an element by name.
6169
+/* Search for an object by name.
60536170
**
60546171
** Search in pBasis->pSublist if pBasis is not NULL. If pBasis is NULL
60556172
** then search in p->list.
60566173
*/
6057
-static PElem *pik_find_byname(Pik *p, PElem *pBasis, PToken *pName){
6058
- PEList *pList;
6174
+static PObj *pik_find_byname(Pik *p, PObj *pBasis, PToken *pName){
6175
+ PList *pList;
60596176
int i, j;
60606177
if( pBasis==0 ){
60616178
pList = p->list;
60626179
}else{
60636180
pList = pBasis->pSublist;
@@ -6066,49 +6183,49 @@
60666183
pik_error(p, pName, "no such object");
60676184
return 0;
60686185
}
60696186
/* First look explicitly tagged objects */
60706187
for(i=pList->n-1; i>=0; i--){
6071
- PElem *pElem = pList->a[i];
6072
- if( pElem->zName && pik_token_eq(pName,pElem->zName)==0 ){
6073
- return pElem;
6188
+ PObj *pObj = pList->a[i];
6189
+ if( pObj->zName && pik_token_eq(pName,pObj->zName)==0 ){
6190
+ return pObj;
60746191
}
60756192
}
60766193
/* If not found, do a second pass looking for any object containing
60776194
** text which exactly matches pName */
60786195
for(i=pList->n-1; i>=0; i--){
6079
- PElem *pElem = pList->a[i];
6080
- for(j=0; j<pElem->nTxt; j++){
6081
- if( pElem->aTxt[j].n==pName->n+2
6082
- && memcmp(pElem->aTxt[j].z+1,pName->z,pName->n)==0 ){
6083
- return pElem;
6196
+ PObj *pObj = pList->a[i];
6197
+ for(j=0; j<pObj->nTxt; j++){
6198
+ if( pObj->aTxt[j].n==pName->n+2
6199
+ && memcmp(pObj->aTxt[j].z+1,pName->z,pName->n)==0 ){
6200
+ return pObj;
60846201
}
60856202
}
60866203
}
60876204
pik_error(p, pName, "no such object");
60886205
return 0;
60896206
}
60906207
60916208
/* Change most of the settings for the current object to be the
6092
-** same as the pOther object, or the most recent element of the same
6209
+** same as the pOther object, or the most recent object of the same
60936210
** type if pOther is NULL.
60946211
*/
6095
-static void pik_same(Pik *p, PElem *pOther, PToken *pErrTok){
6096
- PElem *pElem = p->cur;
6212
+static void pik_same(Pik *p, PObj *pOther, PToken *pErrTok){
6213
+ PObj *pObj = p->cur;
60976214
if( p->nErr ) return;
60986215
if( pOther==0 ){
60996216
int i;
61006217
for(i=(p->list ? p->list->n : 0)-1; i>=0; i--){
61016218
pOther = p->list->a[i];
6102
- if( pOther->type==pElem->type ) break;
6219
+ if( pOther->type==pObj->type ) break;
61036220
}
61046221
if( i<0 ){
61056222
pik_error(p, pErrTok, "no prior objects of the same type");
61066223
return;
61076224
}
61086225
}
6109
- if( pOther->nPath && pElem->type->isLine ){
6226
+ if( pOther->nPath && pObj->type->isLine ){
61106227
PNum dx, dy;
61116228
int i;
61126229
dx = p->aTPath[0].x - pOther->aPath[0].x;
61136230
dy = p->aTPath[0].y - pOther->aPath[0].y;
61146231
for(i=1; i<pOther->nPath; i++){
@@ -6117,53 +6234,53 @@
61176234
}
61186235
p->nTPath = pOther->nPath;
61196236
p->mTPath = 3;
61206237
p->samePath = 1;
61216238
}
6122
- if( !pElem->type->isLine ){
6123
- pElem->w = pOther->w;
6124
- pElem->h = pOther->h;
6125
- }
6126
- pElem->rad = pOther->rad;
6127
- pElem->sw = pOther->sw;
6128
- pElem->dashed = pOther->dashed;
6129
- pElem->dotted = pOther->dotted;
6130
- pElem->fill = pOther->fill;
6131
- pElem->color = pOther->color;
6132
- pElem->cw = pOther->cw;
6133
- pElem->larrow = pOther->larrow;
6134
- pElem->rarrow = pOther->rarrow;
6135
- pElem->bClose = pOther->bClose;
6136
- pElem->bChop = pOther->bChop;
6137
- pElem->inDir = pOther->inDir;
6138
- pElem->outDir = pOther->outDir;
6139
- pElem->iLayer = pOther->iLayer;
6140
-}
6141
-
6142
-
6143
-/* Return a "Place" associated with element pElem. If pEdge is NULL
6239
+ if( !pObj->type->isLine ){
6240
+ pObj->w = pOther->w;
6241
+ pObj->h = pOther->h;
6242
+ }
6243
+ pObj->rad = pOther->rad;
6244
+ pObj->sw = pOther->sw;
6245
+ pObj->dashed = pOther->dashed;
6246
+ pObj->dotted = pOther->dotted;
6247
+ pObj->fill = pOther->fill;
6248
+ pObj->color = pOther->color;
6249
+ pObj->cw = pOther->cw;
6250
+ pObj->larrow = pOther->larrow;
6251
+ pObj->rarrow = pOther->rarrow;
6252
+ pObj->bClose = pOther->bClose;
6253
+ pObj->bChop = pOther->bChop;
6254
+ pObj->inDir = pOther->inDir;
6255
+ pObj->outDir = pOther->outDir;
6256
+ pObj->iLayer = pOther->iLayer;
6257
+}
6258
+
6259
+
6260
+/* Return a "Place" associated with object pObj. If pEdge is NULL
61446261
** return the center of the object. Otherwise, return the corner
61456262
** described by pEdge.
61466263
*/
6147
-static PPoint pik_place_of_elem(Pik *p, PElem *pElem, PToken *pEdge){
6264
+static PPoint pik_place_of_elem(Pik *p, PObj *pObj, PToken *pEdge){
61486265
PPoint pt = cZeroPoint;
61496266
const PClass *pClass;
6150
- if( pElem==0 ) return pt;
6267
+ if( pObj==0 ) return pt;
61516268
if( pEdge==0 ){
6152
- return pElem->ptAt;
6269
+ return pObj->ptAt;
61536270
}
6154
- pClass = pElem->type;
6271
+ pClass = pObj->type;
61556272
if( pEdge->eType==T_EDGEPT || (pEdge->eEdge>0 && pEdge->eEdge<CP_END) ){
6156
- pt = pClass->xOffset(p, pElem, pEdge->eEdge);
6157
- pt.x += pElem->ptAt.x;
6158
- pt.y += pElem->ptAt.y;
6273
+ pt = pClass->xOffset(p, pObj, pEdge->eEdge);
6274
+ pt.x += pObj->ptAt.x;
6275
+ pt.y += pObj->ptAt.y;
61596276
return pt;
61606277
}
61616278
if( pEdge->eType==T_START ){
6162
- return pElem->ptEnter;
6279
+ return pObj->ptEnter;
61636280
}else{
6164
- return pElem->ptExit;
6281
+ return pObj->ptExit;
61656282
}
61666283
}
61676284
61686285
/* Do a linear interpolation of two positions.
61696286
*/
@@ -6192,11 +6309,11 @@
61926309
return pik_position_at_angle(dist, pik_hdg_angle[pD->eEdge], pt);
61936310
}
61946311
61956312
/* Return the coordinates for the n-th vertex of a line.
61966313
*/
6197
-static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pObj){
6314
+static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PObj *pObj){
61986315
static const PPoint zero;
61996316
int n;
62006317
if( p->nErr || pObj==0 ) return p->aTPath[0];
62016318
if( !pObj->type->isLine ){
62026319
pik_error(p, pErr, "object is not a line");
@@ -6210,28 +6327,28 @@
62106327
return pObj->aPath[n-1];
62116328
}
62126329
62136330
/* Return the value of a property of an object.
62146331
*/
6215
-static PNum pik_property_of(PElem *pElem, PToken *pProp){
6332
+static PNum pik_property_of(PObj *pObj, PToken *pProp){
62166333
PNum v = 0.0;
62176334
switch( pProp->eType ){
6218
- case T_HEIGHT: v = pElem->h; break;
6219
- case T_WIDTH: v = pElem->w; break;
6220
- case T_RADIUS: v = pElem->rad; break;
6221
- case T_DIAMETER: v = pElem->rad*2.0; break;
6222
- case T_THICKNESS: v = pElem->sw; break;
6223
- case T_DASHED: v = pElem->dashed; break;
6224
- case T_DOTTED: v = pElem->dotted; break;
6225
- case T_FILL: v = pElem->fill; break;
6226
- case T_COLOR: v = pElem->color; break;
6227
- case T_X: v = pElem->ptAt.x; break;
6228
- case T_Y: v = pElem->ptAt.y; break;
6229
- case T_TOP: v = pElem->bbox.ne.y; break;
6230
- case T_BOTTOM: v = pElem->bbox.sw.y; break;
6231
- case T_LEFT: v = pElem->bbox.sw.x; break;
6232
- case T_RIGHT: v = pElem->bbox.ne.x; break;
6335
+ case T_HEIGHT: v = pObj->h; break;
6336
+ case T_WIDTH: v = pObj->w; break;
6337
+ case T_RADIUS: v = pObj->rad; break;
6338
+ case T_DIAMETER: v = pObj->rad*2.0; break;
6339
+ case T_THICKNESS: v = pObj->sw; break;
6340
+ case T_DASHED: v = pObj->dashed; break;
6341
+ case T_DOTTED: v = pObj->dotted; break;
6342
+ case T_FILL: v = pObj->fill; break;
6343
+ case T_COLOR: v = pObj->color; break;
6344
+ case T_X: v = pObj->ptAt.x; break;
6345
+ case T_Y: v = pObj->ptAt.y; break;
6346
+ case T_TOP: v = pObj->bbox.ne.y; break;
6347
+ case T_BOTTOM: v = pObj->bbox.sw.y; break;
6348
+ case T_LEFT: v = pObj->bbox.sw.x; break;
6349
+ case T_RIGHT: v = pObj->bbox.ne.x; break;
62336350
}
62346351
return v;
62356352
}
62366353
62376354
/* Compute one of the built-in functions
@@ -6256,43 +6373,43 @@
62566373
default: v = 0.0;
62576374
}
62586375
return v;
62596376
}
62606377
6261
-/* Attach a name to an element
6378
+/* Attach a name to an object
62626379
*/
6263
-static void pik_elem_setname(Pik *p, PElem *pElem, PToken *pName){
6264
- if( pElem==0 ) return;
6380
+static void pik_elem_setname(Pik *p, PObj *pObj, PToken *pName){
6381
+ if( pObj==0 ) return;
62656382
if( pName==0 ) return;
6266
- free(pElem->zName);
6267
- pElem->zName = malloc(pName->n+1);
6268
- if( pElem->zName==0 ){
6383
+ free(pObj->zName);
6384
+ pObj->zName = malloc(pName->n+1);
6385
+ if( pObj->zName==0 ){
62696386
pik_error(p,0,0);
62706387
}else{
6271
- memcpy(pElem->zName,pName->z,pName->n);
6272
- pElem->zName[pName->n] = 0;
6388
+ memcpy(pObj->zName,pName->z,pName->n);
6389
+ pObj->zName[pName->n] = 0;
62736390
}
62746391
return;
62756392
}
62766393
62776394
/*
62786395
** Search for object located at *pCenter that has an xChop method.
62796396
** Return a pointer to the object, or NULL if not found.
62806397
*/
6281
-static PElem *pik_find_chopper(PEList *pList, PPoint *pCenter){
6398
+static PObj *pik_find_chopper(PList *pList, PPoint *pCenter){
62826399
int i;
62836400
if( pList==0 ) return 0;
62846401
for(i=pList->n-1; i>=0; i--){
6285
- PElem *pElem = pList->a[i];
6286
- if( pElem->type->xChop!=0
6287
- && pElem->ptAt.x==pCenter->x
6288
- && pElem->ptAt.y==pCenter->y
6402
+ PObj *pObj = pList->a[i];
6403
+ if( pObj->type->xChop!=0
6404
+ && pObj->ptAt.x==pCenter->x
6405
+ && pObj->ptAt.y==pCenter->y
62896406
){
6290
- return pElem;
6291
- }else if( pElem->pSublist ){
6292
- pElem = pik_find_chopper(pElem->pSublist,pCenter);
6293
- if( pElem ) return pElem;
6407
+ return pObj;
6408
+ }else if( pObj->pSublist ){
6409
+ pObj = pik_find_chopper(pObj->pSublist,pCenter);
6410
+ if( pObj ) return pObj;
62946411
}
62956412
}
62966413
return 0;
62976414
}
62986415
@@ -6302,180 +6419,199 @@
63026419
** If point pTo is the exact enter of a choppable object,
63036420
** then adjust pTo by the appropriate amount in the direction
63046421
** of pFrom.
63056422
*/
63066423
static void pik_autochop(Pik *p, PPoint *pFrom, PPoint *pTo){
6307
- PElem *pElem = pik_find_chopper(p->list, pTo);
6308
- if( pElem ){
6309
- *pTo = pElem->type->xChop(p, pElem, pFrom);
6424
+ PObj *pObj = pik_find_chopper(p->list, pTo);
6425
+ if( pObj ){
6426
+ *pTo = pObj->type->xChop(p, pObj, pFrom);
63106427
}
63116428
}
63126429
63136430
/* This routine runs after all attributes have been received
6314
-** on an element.
6431
+** on an object.
63156432
*/
6316
-static void pik_after_adding_attributes(Pik *p, PElem *pElem){
6433
+static void pik_after_adding_attributes(Pik *p, PObj *pObj){
63176434
int i;
63186435
PPoint ofst;
63196436
PNum dx, dy;
63206437
63216438
if( p->nErr ) return;
63226439
6323
- /* Position block elements */
6324
- if( pElem->type->isLine==0 ){
6325
- ofst = pik_elem_offset(p, pElem, pElem->eWith);
6326
- dx = (pElem->with.x - ofst.x) - pElem->ptAt.x;
6327
- dy = (pElem->with.y - ofst.y) - pElem->ptAt.y;
6440
+ /* Position block objects */
6441
+ if( pObj->type->isLine==0 ){
6442
+ /* A height or width less than or equal to zero means "autofit".
6443
+ ** Change the height or width to be big enough to contain the text,
6444
+ */
6445
+ if( pObj->h<=0.0 ){
6446
+ if( pObj->nTxt==0 ){
6447
+ pObj->h = 0.0;
6448
+ }else if( pObj->w<=0.0 ){
6449
+ pik_size_to_fit(p, &pObj->errTok, 3);
6450
+ }else{
6451
+ pik_size_to_fit(p, &pObj->errTok, 2);
6452
+ }
6453
+ }
6454
+ if( pObj->w<=0.0 ){
6455
+ if( pObj->nTxt==0 ){
6456
+ pObj->w = 0.0;
6457
+ }else{
6458
+ pik_size_to_fit(p, &pObj->errTok, 1);
6459
+ }
6460
+ }
6461
+ ofst = pik_elem_offset(p, pObj, pObj->eWith);
6462
+ dx = (pObj->with.x - ofst.x) - pObj->ptAt.x;
6463
+ dy = (pObj->with.y - ofst.y) - pObj->ptAt.y;
63286464
if( dx!=0 || dy!=0 ){
6329
- pik_elem_move(pElem, dx, dy);
6465
+ pik_elem_move(pObj, dx, dy);
63306466
}
63316467
}
63326468
63336469
/* For a line object with no movement specified, a single movement
63346470
** of the default length in the current direction
63356471
*/
6336
- if( pElem->type->isLine && p->nTPath<2 ){
6472
+ if( pObj->type->isLine && p->nTPath<2 ){
63376473
pik_next_rpath(p, 0);
63386474
assert( p->nTPath==2 );
6339
- switch( pElem->inDir ){
6340
- default: p->aTPath[1].x += pElem->w; break;
6341
- case DIR_DOWN: p->aTPath[1].y -= pElem->h; break;
6342
- case DIR_LEFT: p->aTPath[1].x -= pElem->w; break;
6343
- case DIR_UP: p->aTPath[1].y += pElem->h; break;
6344
- }
6345
- if( pElem->type->xInit==arcInit ){
6346
- p->eDir = pElem->outDir = (pElem->inDir + (pElem->cw ? 1 : 3))%4;
6347
- switch( pElem->outDir ){
6348
- default: p->aTPath[1].x += pElem->w; break;
6349
- case DIR_DOWN: p->aTPath[1].y -= pElem->h; break;
6350
- case DIR_LEFT: p->aTPath[1].x -= pElem->w; break;
6351
- case DIR_UP: p->aTPath[1].y += pElem->h; break;
6475
+ switch( pObj->inDir ){
6476
+ default: p->aTPath[1].x += pObj->w; break;
6477
+ case DIR_DOWN: p->aTPath[1].y -= pObj->h; break;
6478
+ case DIR_LEFT: p->aTPath[1].x -= pObj->w; break;
6479
+ case DIR_UP: p->aTPath[1].y += pObj->h; break;
6480
+ }
6481
+ if( pObj->type->xInit==arcInit ){
6482
+ p->eDir = pObj->outDir = (pObj->inDir + (pObj->cw ? 1 : 3))%4;
6483
+ switch( pObj->outDir ){
6484
+ default: p->aTPath[1].x += pObj->w; break;
6485
+ case DIR_DOWN: p->aTPath[1].y -= pObj->h; break;
6486
+ case DIR_LEFT: p->aTPath[1].x -= pObj->w; break;
6487
+ case DIR_UP: p->aTPath[1].y += pObj->h; break;
63526488
}
63536489
}
63546490
}
63556491
63566492
/* Initialize the bounding box prior to running xCheck */
6357
- pik_bbox_init(&pElem->bbox);
6493
+ pik_bbox_init(&pObj->bbox);
63586494
63596495
/* Run object-specific code */
6360
- if( pElem->type->xCheck!=0 ){
6361
- pElem->type->xCheck(p,pElem);
6496
+ if( pObj->type->xCheck!=0 ){
6497
+ pObj->type->xCheck(p,pObj);
63626498
if( p->nErr ) return;
63636499
}
63646500
63656501
/* Compute final bounding box, entry and exit points, center
6366
- ** point (ptAt) and path for the element
6502
+ ** point (ptAt) and path for the object
63676503
*/
6368
- if( pElem->type->isLine ){
6369
- pElem->aPath = malloc( sizeof(PPoint)*p->nTPath );
6370
- if( pElem->aPath==0 ){
6504
+ if( pObj->type->isLine ){
6505
+ pObj->aPath = malloc( sizeof(PPoint)*p->nTPath );
6506
+ if( pObj->aPath==0 ){
63716507
pik_error(p, 0, 0);
63726508
return;
63736509
}else{
6374
- pElem->nPath = p->nTPath;
6510
+ pObj->nPath = p->nTPath;
63756511
for(i=0; i<p->nTPath; i++){
6376
- pElem->aPath[i] = p->aTPath[i];
6512
+ pObj->aPath[i] = p->aTPath[i];
63776513
}
63786514
}
63796515
63806516
/* "chop" processing:
63816517
** If the line goes to the center of an object with an
63826518
** xChop method, then use the xChop method to trim the line.
63836519
*/
6384
- if( pElem->bChop && pElem->nPath>=2 ){
6385
- int n = pElem->nPath;
6386
- pik_autochop(p, &pElem->aPath[n-2], &pElem->aPath[n-1]);
6387
- pik_autochop(p, &pElem->aPath[1], &pElem->aPath[0]);
6520
+ if( pObj->bChop && pObj->nPath>=2 ){
6521
+ int n = pObj->nPath;
6522
+ pik_autochop(p, &pObj->aPath[n-2], &pObj->aPath[n-1]);
6523
+ pik_autochop(p, &pObj->aPath[1], &pObj->aPath[0]);
63886524
}
63896525
6390
- pElem->ptEnter = pElem->aPath[0];
6391
- pElem->ptExit = pElem->aPath[pElem->nPath-1];
6526
+ pObj->ptEnter = pObj->aPath[0];
6527
+ pObj->ptExit = pObj->aPath[pObj->nPath-1];
63926528
63936529
/* Compute the center of the line based on the bounding box over
63946530
** the vertexes. This is a difference from PIC. In Pikchr, the
63956531
** center of a line is the center of its bounding box. In PIC, the
63966532
** center of a line is halfway between its .start and .end. For
63976533
** straight lines, this is the same point, but for multi-segment
63986534
** lines the result is usually diferent */
6399
- for(i=0; i<pElem->nPath; i++){
6400
- pik_bbox_add_xy(&pElem->bbox, pElem->aPath[i].x, pElem->aPath[i].y);
6535
+ for(i=0; i<pObj->nPath; i++){
6536
+ pik_bbox_add_xy(&pObj->bbox, pObj->aPath[i].x, pObj->aPath[i].y);
64016537
}
6402
- pElem->ptAt.x = (pElem->bbox.ne.x + pElem->bbox.sw.x)/2.0;
6403
- pElem->ptAt.y = (pElem->bbox.ne.y + pElem->bbox.sw.y)/2.0;
6538
+ pObj->ptAt.x = (pObj->bbox.ne.x + pObj->bbox.sw.x)/2.0;
6539
+ pObj->ptAt.y = (pObj->bbox.ne.y + pObj->bbox.sw.y)/2.0;
64046540
64056541
/* Reset the width and height of the object to be the width and height
64066542
** of the bounding box over vertexes */
6407
- pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
6408
- pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
6543
+ pObj->w = pObj->bbox.ne.x - pObj->bbox.sw.x;
6544
+ pObj->h = pObj->bbox.ne.y - pObj->bbox.sw.y;
64096545
64106546
/* If this is a polygon (if it has the "close" attribute), then
64116547
** adjust the exit point */
6412
- if( pElem->bClose ){
6548
+ if( pObj->bClose ){
64136549
/* For "closed" lines, the .end is one of the .e, .s, .w, or .n
64146550
** points of the bounding box, as with block objects. */
6415
- pik_elem_set_exit(pElem, pElem->inDir);
6551
+ pik_elem_set_exit(pObj, pObj->inDir);
64166552
}
64176553
}else{
6418
- PNum w2 = pElem->w/2.0;
6419
- PNum h2 = pElem->h/2.0;
6420
- pElem->ptEnter = pElem->ptAt;
6421
- pElem->ptExit = pElem->ptAt;
6422
- switch( pElem->inDir ){
6423
- default: pElem->ptEnter.x -= w2; break;
6424
- case DIR_LEFT: pElem->ptEnter.x += w2; break;
6425
- case DIR_UP: pElem->ptEnter.y -= h2; break;
6426
- case DIR_DOWN: pElem->ptEnter.y += h2; break;
6427
- }
6428
- switch( pElem->outDir ){
6429
- default: pElem->ptExit.x += w2; break;
6430
- case DIR_LEFT: pElem->ptExit.x -= w2; break;
6431
- case DIR_UP: pElem->ptExit.y += h2; break;
6432
- case DIR_DOWN: pElem->ptExit.y -= h2; break;
6433
- }
6434
- pik_bbox_add_xy(&pElem->bbox, pElem->ptAt.x - w2, pElem->ptAt.y - h2);
6435
- pik_bbox_add_xy(&pElem->bbox, pElem->ptAt.x + w2, pElem->ptAt.y + h2);
6436
- }
6437
- p->eDir = pElem->outDir;
6438
-}
6439
-
6440
-/* Show basic information about each element as a comment in the
6554
+ PNum w2 = pObj->w/2.0;
6555
+ PNum h2 = pObj->h/2.0;
6556
+ pObj->ptEnter = pObj->ptAt;
6557
+ pObj->ptExit = pObj->ptAt;
6558
+ switch( pObj->inDir ){
6559
+ default: pObj->ptEnter.x -= w2; break;
6560
+ case DIR_LEFT: pObj->ptEnter.x += w2; break;
6561
+ case DIR_UP: pObj->ptEnter.y -= h2; break;
6562
+ case DIR_DOWN: pObj->ptEnter.y += h2; break;
6563
+ }
6564
+ switch( pObj->outDir ){
6565
+ default: pObj->ptExit.x += w2; break;
6566
+ case DIR_LEFT: pObj->ptExit.x -= w2; break;
6567
+ case DIR_UP: pObj->ptExit.y += h2; break;
6568
+ case DIR_DOWN: pObj->ptExit.y -= h2; break;
6569
+ }
6570
+ pik_bbox_add_xy(&pObj->bbox, pObj->ptAt.x - w2, pObj->ptAt.y - h2);
6571
+ pik_bbox_add_xy(&pObj->bbox, pObj->ptAt.x + w2, pObj->ptAt.y + h2);
6572
+ }
6573
+ p->eDir = pObj->outDir;
6574
+}
6575
+
6576
+/* Show basic information about each object as a comment in the
64416577
** generated HTML. Used for testing and debugging. Activated
64426578
** by the (undocumented) "debug = 1;"
64436579
** command.
64446580
*/
6445
-static void pik_elem_render(Pik *p, PElem *pElem){
6581
+static void pik_elem_render(Pik *p, PObj *pObj){
64466582
char *zDir;
6447
- if( pElem==0 ) return;
6583
+ if( pObj==0 ) return;
64486584
pik_append(p,"<!-- ", -1);
6449
- if( pElem->zName ){
6450
- pik_append_text(p, pElem->zName, -1, 0);
6585
+ if( pObj->zName ){
6586
+ pik_append_text(p, pObj->zName, -1, 0);
64516587
pik_append(p, ": ", 2);
64526588
}
6453
- pik_append_text(p, pElem->type->zName, -1, 0);
6454
- if( pElem->nTxt ){
6589
+ pik_append_text(p, pObj->type->zName, -1, 0);
6590
+ if( pObj->nTxt ){
64556591
pik_append(p, " \"", 2);
6456
- pik_append_text(p, pElem->aTxt[0].z+1, pElem->aTxt[0].n-2, 1);
6592
+ pik_append_text(p, pObj->aTxt[0].z+1, pObj->aTxt[0].n-2, 1);
64576593
pik_append(p, "\"", 1);
64586594
}
6459
- pik_append_num(p, " w=", pElem->w);
6460
- pik_append_num(p, " h=", pElem->h);
6461
- pik_append_point(p, " center=", &pElem->ptAt);
6462
- pik_append_point(p, " enter=", &pElem->ptEnter);
6463
- switch( pElem->outDir ){
6595
+ pik_append_num(p, " w=", pObj->w);
6596
+ pik_append_num(p, " h=", pObj->h);
6597
+ pik_append_point(p, " center=", &pObj->ptAt);
6598
+ pik_append_point(p, " enter=", &pObj->ptEnter);
6599
+ switch( pObj->outDir ){
64646600
default: zDir = " right"; break;
64656601
case DIR_LEFT: zDir = " left"; break;
64666602
case DIR_UP: zDir = " up"; break;
64676603
case DIR_DOWN: zDir = " down"; break;
64686604
}
6469
- pik_append_point(p, " exit=", &pElem->ptExit);
6605
+ pik_append_point(p, " exit=", &pObj->ptExit);
64706606
pik_append(p, zDir, -1);
64716607
pik_append(p, " -->\n", -1);
64726608
}
64736609
6474
-/* Render a list of elements
6610
+/* Render a list of objects
64756611
*/
6476
-void pik_elist_render(Pik *p, PEList *pEList){
6612
+void pik_elist_render(Pik *p, PList *pList){
64776613
int i;
64786614
int iNextLayer = 0;
64796615
int iThisLayer;
64806616
int bMoreToDo;
64816617
int miss = 0;
@@ -6483,75 +6619,75 @@
64836619
PNum colorLabel;
64846620
do{
64856621
bMoreToDo = 0;
64866622
iThisLayer = iNextLayer;
64876623
iNextLayer = 0x7fffffff;
6488
- for(i=0; i<pEList->n; i++){
6489
- PElem *pElem = pEList->a[i];
6490
- if( pElem->iLayer>iThisLayer ){
6491
- if( pElem->iLayer<iNextLayer ) iNextLayer = pElem->iLayer;
6624
+ for(i=0; i<pList->n; i++){
6625
+ PObj *pObj = pList->a[i];
6626
+ if( pObj->iLayer>iThisLayer ){
6627
+ if( pObj->iLayer<iNextLayer ) iNextLayer = pObj->iLayer;
64926628
bMoreToDo = 1;
64936629
continue; /* Defer until another round */
6494
- }else if( pElem->iLayer<iThisLayer ){
6630
+ }else if( pObj->iLayer<iThisLayer ){
64956631
continue;
64966632
}
6497
- void (*xRender)(Pik*,PElem*);
6498
- if( mDebug & 1 ) pik_elem_render(p, pElem);
6499
- xRender = pElem->type->xRender;
6633
+ void (*xRender)(Pik*,PObj*);
6634
+ if( mDebug & 1 ) pik_elem_render(p, pObj);
6635
+ xRender = pObj->type->xRender;
65006636
if( xRender ){
6501
- xRender(p, pElem);
6637
+ xRender(p, pObj);
65026638
}
6503
- if( pElem->pSublist ){
6504
- pik_elist_render(p, pElem->pSublist);
6639
+ if( pObj->pSublist ){
6640
+ pik_elist_render(p, pObj->pSublist);
65056641
}
65066642
}
65076643
}while( bMoreToDo );
65086644
65096645
/* If the color_debug_label value is defined, then go through
65106646
** and paint a dot at every label location */
65116647
colorLabel = pik_value(p, "debug_label_color", 17, &miss);
65126648
if( miss==0 && colorLabel>=0.0 ){
6513
- PElem dot;
6649
+ PObj dot;
65146650
memset(&dot, 0, sizeof(dot));
65156651
dot.type = &noopClass;
65166652
dot.rad = 0.015;
65176653
dot.sw = 0.015;
65186654
dot.fill = colorLabel;
65196655
dot.color = colorLabel;
65206656
dot.nTxt = 1;
65216657
dot.aTxt[0].eCode = TP_ABOVE;
6522
- for(i=0; i<pEList->n; i++){
6523
- PElem *pElem = pEList->a[i];
6524
- if( pElem->zName==0 ) continue;
6525
- dot.ptAt = pElem->ptAt;
6526
- dot.aTxt[0].z = pElem->zName;
6527
- dot.aTxt[0].n = (int)strlen(pElem->zName);
6658
+ for(i=0; i<pList->n; i++){
6659
+ PObj *pObj = pList->a[i];
6660
+ if( pObj->zName==0 ) continue;
6661
+ dot.ptAt = pObj->ptAt;
6662
+ dot.aTxt[0].z = pObj->zName;
6663
+ dot.aTxt[0].n = (int)strlen(pObj->zName);
65286664
dotRender(p, &dot);
65296665
}
65306666
}
65316667
}
65326668
6533
-/* Add all elements of the list pEList to the bounding box
6669
+/* Add all objects of the list pList to the bounding box
65346670
*/
6535
-static void pik_bbox_add_elist(Pik *p, PEList *pEList, PNum wArrow){
6671
+static void pik_bbox_add_elist(Pik *p, PList *pList, PNum wArrow){
65366672
int i;
6537
- for(i=0; i<pEList->n; i++){
6538
- PElem *pElem = pEList->a[i];
6539
- if( pElem->sw>0.0 ) pik_bbox_addbox(&p->bbox, &pElem->bbox);
6540
- pik_append_txt(p, pElem, &p->bbox);
6541
- if( pElem->pSublist ) pik_bbox_add_elist(p, pElem->pSublist, wArrow);
6673
+ for(i=0; i<pList->n; i++){
6674
+ PObj *pObj = pList->a[i];
6675
+ if( pObj->sw>0.0 ) pik_bbox_addbox(&p->bbox, &pObj->bbox);
6676
+ pik_append_txt(p, pObj, &p->bbox);
6677
+ if( pObj->pSublist ) pik_bbox_add_elist(p, pObj->pSublist, wArrow);
65426678
65436679
65446680
/* Expand the bounding box to account for arrowheads on lines */
6545
- if( pElem->type->isLine && pElem->nPath>0 ){
6546
- if( pElem->larrow ){
6547
- pik_bbox_addellipse(&p->bbox, pElem->aPath[0].x, pElem->aPath[0].y,
6681
+ if( pObj->type->isLine && pObj->nPath>0 ){
6682
+ if( pObj->larrow ){
6683
+ pik_bbox_addellipse(&p->bbox, pObj->aPath[0].x, pObj->aPath[0].y,
65486684
wArrow, wArrow);
65496685
}
6550
- if( pElem->rarrow ){
6551
- int j = pElem->nPath-1;
6552
- pik_bbox_addellipse(&p->bbox, pElem->aPath[j].x, pElem->aPath[j].y,
6686
+ if( pObj->rarrow ){
6687
+ int j = pObj->nPath-1;
6688
+ pik_bbox_addellipse(&p->bbox, pObj->aPath[j].x, pObj->aPath[j].y,
65536689
wArrow, wArrow);
65546690
}
65556691
}
65566692
}
65576693
}
@@ -6574,15 +6710,15 @@
65746710
p->charWidth = pik_value(p,"charwid",7,0)*p->fontScale;
65756711
p->charHeight = pik_value(p,"charht",6,0)*p->fontScale;
65766712
p->bLayoutVars = 1;
65776713
}
65786714
6579
-/* Render a list of elements. Write the SVG into p->zOut.
6580
-** Delete the input element_list before returnning.
6715
+/* Render a list of objects. Write the SVG into p->zOut.
6716
+** Delete the input object_list before returnning.
65816717
*/
6582
-static void pik_render(Pik *p, PEList *pEList){
6583
- if( pEList==0 ) return;
6718
+static void pik_render(Pik *p, PList *pList){
6719
+ if( pList==0 ) return;
65846720
if( p->nErr==0 ){
65856721
PNum thickness; /* Stroke width */
65866722
PNum margin; /* Extra bounding box margin */
65876723
PNum w, h; /* Drawing width and height */
65886724
PNum wArrow;
@@ -6597,11 +6733,11 @@
65976733
wArrow = p->wArrow*thickness;
65986734
65996735
/* Compute a bounding box over all objects so that we can know
66006736
** how big to declare the SVG canvas */
66016737
pik_bbox_init(&p->bbox);
6602
- pik_bbox_add_elist(p, pEList, wArrow);
6738
+ pik_bbox_add_elist(p, pList, wArrow);
66036739
66046740
/* Expand the bounding box slightly to account for line thickness
66056741
** and the optional "margin = EXPR" setting. */
66066742
p->bbox.ne.x += margin + pik_value(p,"rightmargin",11,0);
66076743
p->bbox.ne.y += margin + pik_value(p,"topmargin",9,0);
@@ -6627,17 +6763,17 @@
66276763
pik_append_num(p, "\" height=\"", p->hSVG);
66286764
pik_append(p, "\"", 1);
66296765
}
66306766
pik_append_dis(p, " viewBox=\"0 0 ",w,"");
66316767
pik_append_dis(p, " ",h,"\">\n");
6632
- pik_elist_render(p, pEList);
6768
+ pik_elist_render(p, pList);
66336769
pik_append(p,"</svg>\n", -1);
66346770
}else{
66356771
p->wSVG = -1;
66366772
p->hSVG = -1;
66376773
}
6638
- pik_elist_free(p, pEList);
6774
+ pik_elist_free(p, pList);
66396775
}
66406776
66416777
66426778
66436779
/*
@@ -6676,10 +6812,11 @@
66766812
{ "close", 5, T_CLOSE, 0, 0 },
66776813
{ "color", 5, T_COLOR, 0, 0 },
66786814
{ "cos", 3, T_FUNC1, FN_COS, 0 },
66796815
{ "cw", 2, T_CW, 0, 0 },
66806816
{ "dashed", 6, T_DASHED, 0, 0 },
6817
+ { "define", 6, T_DEFINE, 0, 0 },
66816818
{ "diameter", 8, T_DIAMETER, 0, 0 },
66826819
{ "dist", 4, T_DIST, 0, 0 },
66836820
{ "dotted", 6, T_DOTTED, 0, 0 },
66846821
{ "down", 4, T_DOWN, DIR_DOWN, 0 },
66856822
{ "e", 1, T_EDGEPT, 0, CP_E },
@@ -6745,11 +6882,11 @@
67456882
{ "y", 1, T_Y, 0, 0 },
67466883
};
67476884
67486885
/*
67496886
** Search a PikWordlist for the given keyword. Return a pointer to the
6750
-** element found. Or return 0 if not found.
6887
+** keyword entry found. Or return 0 if not found.
67516888
*/
67526889
static const PikWord *pik_find_word(
67536890
const char *zIn, /* Word to search for */
67546891
int n, /* Length of zIn */
67556892
const PikWord *aList, /* List to search */
@@ -6787,11 +6924,11 @@
67876924
/*
67886925
** Return the length of next token. The token starts on
67896926
** the pToken->z character. Fill in other fields of the
67906927
** pToken object as appropriate.
67916928
*/
6792
-static int pik_token_length(PToken *pToken){
6929
+static int pik_token_length(PToken *pToken, int bAllowCodeBlock){
67936930
const unsigned char *z = (const unsigned char*)pToken->z;
67946931
int i;
67956932
unsigned char c, c2;
67966933
switch( z[0] ){
67976934
case '\\': {
@@ -6921,10 +7058,35 @@
69217058
}else{
69227059
pToken->eType = T_LT;
69237060
return 1;
69247061
}
69257062
}
7063
+ case '{': {
7064
+ int len, depth;
7065
+ i = 1;
7066
+ if( bAllowCodeBlock ){
7067
+ depth = 1;
7068
+ while( z[i] && depth>0 ){
7069
+ PToken x;
7070
+ x.z = (char*)(z+i);
7071
+ len = pik_token_length(&x, 0);
7072
+ if( len==1 ){
7073
+ if( z[i]=='{' ) depth++;
7074
+ if( z[i]=='}' ) depth--;
7075
+ }
7076
+ i += len;
7077
+ }
7078
+ }else{
7079
+ depth = 0;
7080
+ }
7081
+ if( depth ){
7082
+ pToken->eType = T_ERROR;
7083
+ return 1;
7084
+ }
7085
+ pToken->eType = T_CODEBLOCK;
7086
+ return i;
7087
+ }
69267088
default: {
69277089
c = z[0];
69287090
if( c=='.' ){
69297091
unsigned char c1 = z[1];
69307092
if( islower(c1) ){
@@ -6981,19 +7143,20 @@
69817143
if( nDigit==0 ){
69827144
pToken->eType = T_ERROR;
69837145
return i;
69847146
}
69857147
if( c=='e' || c=='E' ){
7148
+ int iBefore = i;
69867149
i++;
69877150
c2 = z[i];
69887151
if( c2=='+' || c2=='-' ){
69897152
i++;
69907153
c2 = z[i];
69917154
}
69927155
if( c2<'0' || c>'9' ){
69937156
/* This is not an exp */
6994
- i -= 2;
7157
+ i = iBefore;
69957158
}else{
69967159
i++;
69977160
isInt = 0;
69987161
while( (c = z[i])>='0' && c<='9' ){ i++; }
69997162
}
@@ -7018,11 +7181,11 @@
70187181
){
70197182
i += 2;
70207183
}
70217184
pToken->eType = T_NUMBER;
70227185
return i;
7023
- }else if( islower(c) || c=='_' || c=='$' || c=='@' ){
7186
+ }else if( islower(c) ){
70247187
const PikWord *pFound;
70257188
for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
70267189
pFound = pik_find_word((const char*)z, i,
70277190
pik_keywords, count(pik_keywords));
70287191
if( pFound ){
@@ -7040,10 +7203,18 @@
70407203
return i;
70417204
}else if( c>='A' && c<='Z' ){
70427205
for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
70437206
pToken->eType = T_PLACENAME;
70447207
return i;
7208
+ }else if( c=='$' && z[1]>='1' && z[1]<='9' && !isdigit(z[2]) ){
7209
+ pToken->eType = T_PARAMETER;
7210
+ pToken->eCode = z[1] - '1';
7211
+ return 2;
7212
+ }else if( c=='_' || c=='$' || c=='@' ){
7213
+ for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7214
+ pToken->eType = T_ID;
7215
+ return i;
70457216
}else{
70467217
pToken->eType = T_ERROR;
70477218
return 1;
70487219
}
70497220
}
@@ -7060,18 +7231,147 @@
70607231
int i = pThis->n;
70617232
memset(&x, 0, sizeof(x));
70627233
x.z = pThis->z;
70637234
while(1){
70647235
x.z = pThis->z + i;
7065
- sz = pik_token_length(&x);
7236
+ sz = pik_token_length(&x, 1);
70667237
if( x.eType!=T_WHITESPACE ){
70677238
x.n = sz;
70687239
return x;
70697240
}
70707241
i += sz;
70717242
}
70727243
}
7244
+
7245
+/* Parser arguments to a macro invocation
7246
+**
7247
+** (arg1, arg2, ...)
7248
+**
7249
+** Arguments are comma-separated, except that commas within string
7250
+** literals or with (...), {...}, or [...] do not count. The argument
7251
+** list begins and ends with parentheses. There can be at most 9
7252
+** arguments.
7253
+**
7254
+** Return the number of bytes in the argument list.
7255
+*/
7256
+static unsigned int pik_parse_macro_args(
7257
+ Pik *p,
7258
+ const char *z, /* Start of the argument list */
7259
+ int n, /* Available bytes */
7260
+ PToken *args
7261
+){
7262
+ int nArg = 0;
7263
+ int i, sz;
7264
+ int iStart;
7265
+ int depth = 0;
7266
+ PToken x;
7267
+ if( z[0]!='(' ) return 0;
7268
+ args[0].z = z+1;
7269
+ iStart = 1;
7270
+ for(i=1; i<n && z[i]!=')'; i+=sz){
7271
+ x.z = z+i;
7272
+ sz = pik_token_length(&x, 0);
7273
+ if( sz!=1 ) continue;
7274
+ if( z[i]==',' && depth<=0 ){
7275
+ args[nArg].n = i - iStart;
7276
+ if( nArg==8 ){
7277
+ x.z = z;
7278
+ x.n = 1;
7279
+ pik_error(p, &x, "too many macro arguments - max 9");
7280
+ return 0;
7281
+ }
7282
+ nArg++;
7283
+ args[nArg].z = z+i+1;
7284
+ iStart = i+1;
7285
+ depth = 0;
7286
+ }else if( z[i]=='(' || z[i]=='{' || z[i]=='[' ){
7287
+ depth++;
7288
+ }else if( z[i]==')' || z[i]=='}' || z[i]==']' ){
7289
+ depth--;
7290
+ }
7291
+ }
7292
+ if( z[i]==')' ){
7293
+ args[nArg].n = i - iStart;
7294
+ return i+1;
7295
+ }
7296
+ x.z = z;
7297
+ x.n = 1;
7298
+ pik_error(p, &x, "unterminated macro argument list");
7299
+ return 0;
7300
+}
7301
+
7302
+/*
7303
+** Split up the content of a PToken into multiple tokens and
7304
+** send each to the parser.
7305
+*/
7306
+void pik_tokenize(Pik *p, PToken *pIn, yyParser *pParser, PToken *aParam){
7307
+ unsigned int i;
7308
+ int sz = 0;
7309
+ PToken token;
7310
+ PMacro *pMac;
7311
+ for(i=0; i<pIn->n && pIn->z[i] && p->nErr==0; i+=sz){
7312
+ token.eCode = 0;
7313
+ token.eEdge = 0;
7314
+ token.z = pIn->z + i;
7315
+ sz = pik_token_length(&token, 1);
7316
+ if( token.eType==T_WHITESPACE ){
7317
+ /* no-op */
7318
+ }else if( sz>1000 ){
7319
+ token.n = 1;
7320
+ pik_error(p, &token, "token is too long - max length 1000 bytes");
7321
+ break;
7322
+ }else if( token.eType==T_ERROR ){
7323
+ token.n = (unsigned short)(sz & 0xffff);
7324
+ pik_error(p, &token, "unrecognized token");
7325
+ break;
7326
+ }else if( sz+i>pIn->n ){
7327
+ token.n = pIn->n - i;
7328
+ pik_error(p, &token, "syntax error");
7329
+ break;
7330
+ }else if( token.eType==T_PARAMETER ){
7331
+ /* Substitute a parameter into the input stream */
7332
+ if( aParam==0 || aParam[token.eCode].n==0 ){
7333
+ continue;
7334
+ }
7335
+ token.n = (unsigned short)(sz & 0xffff);
7336
+ if( p->nCtx>=count(p->aCtx) ){
7337
+ pik_error(p, &token, "macros nested too deep");
7338
+ }else{
7339
+ p->aCtx[p->nCtx++] = token;
7340
+ pik_tokenize(p, &aParam[token.eCode], pParser, 0);
7341
+ p->nCtx--;
7342
+ }
7343
+ }else if( token.eType==T_ID && (pMac = pik_find_macro(p,&token))!=0 ){
7344
+ PToken args[9];
7345
+ unsigned int j = i+sz;
7346
+ if( pMac->inUse ){
7347
+ pik_error(p, &pMac->macroName, "recursive macro definition");
7348
+ break;
7349
+ }
7350
+ token.n = (short int)(sz & 0xffff);
7351
+ if( p->nCtx>=count(p->aCtx) ){
7352
+ pik_error(p, &token, "macros nested too deep");
7353
+ break;
7354
+ }
7355
+ pMac->inUse = 1;
7356
+ memset(args, 0, sizeof(args));
7357
+ p->aCtx[p->nCtx++] = token;
7358
+ sz += pik_parse_macro_args(p, pIn->z+j, pIn->n-j, args);
7359
+ pik_tokenize(p, &pMac->macroBody, pParser, args);
7360
+ p->nCtx--;
7361
+ pMac->inUse = 0;
7362
+ }else{
7363
+#if 0
7364
+ printf("******** Token %s (%d): \"%.*s\" **************\n",
7365
+ yyTokenName[token.eType], token.eType,
7366
+ (int)(isspace(token.z[0]) ? 0 : sz), token.z);
7367
+#endif
7368
+ token.n = (unsigned short)(sz & 0xffff);
7369
+ pik_parser(pParser, token.eType, token);
7370
+ }
7371
+ }
7372
+}
70737373
70747374
/*
70757375
** Parse the PIKCHR script contained in zText[]. Return a rendering. Or
70767376
** if an error is encountered, return the error text. The error message
70777377
** is HTML formatted. So regardless of what happens, the return text
@@ -7092,52 +7392,26 @@
70927392
const char *zClass, /* Add class="%s" to <svg> markup */
70937393
unsigned int mFlags, /* Flags used to influence rendering behavior */
70947394
int *pnWidth, /* Write width of <svg> here, if not NULL */
70957395
int *pnHeight /* Write height here, if not NULL */
70967396
){
7097
- int i;
7098
- int sz;
7099
- PToken token;
71007397
Pik s;
71017398
yyParser sParse;
71027399
71037400
memset(&s, 0, sizeof(s));
7104
- s.zIn = zText;
7105
- s.nIn = (unsigned int)strlen(zText);
7401
+ s.sIn.z = zText;
7402
+ s.sIn.n = (unsigned int)strlen(zText);
71067403
s.eDir = DIR_RIGHT;
71077404
s.zClass = zClass;
71087405
s.mFlags = mFlags;
71097406
pik_parserInit(&sParse, &s);
71107407
#if 0
71117408
pik_parserTrace(stdout, "parser: ");
71127409
#endif
7113
- for(i=0; zText[i] && s.nErr==0; i+=sz){
7114
- token.eCode = 0;
7115
- token.eEdge = 0;
7116
- token.z = zText + i;
7117
- sz = pik_token_length(&token);
7118
- if( token.eType==T_WHITESPACE ){
7119
- /* no-op */
7120
- }else if( sz>1000 ){
7121
- token.n = 1;
7122
- pik_error(&s, &token, "token is too long - max length 1000 bytes");
7123
- break;
7124
- }else if( token.eType==T_ERROR ){
7125
- token.n = (unsigned short)(sz & 0xffff);
7126
- pik_error(&s, &token, "unrecognized token");
7127
- break;
7128
- }else{
7129
-#if 0
7130
- printf("******** Token %s (%d): \"%.*s\" **************\n",
7131
- yyTokenName[token.eType], token.eType,
7132
- isspace(token.z[0]) ? 0 : token.n, token.z);
7133
-#endif
7134
- token.n = (unsigned short)(sz & 0xffff);
7135
- pik_parser(&sParse, token.eType, token);
7136
- }
7137
- }
7410
+ pik_tokenize(&s, &s.sIn, &sParse, 0);
71387411
if( s.nErr==0 ){
7412
+ PToken token;
71397413
memset(&token,0,sizeof(token));
71407414
token.z = zText;
71417415
pik_parser(&sParse, 0, token);
71427416
}
71437417
pik_parserFinalize(&sParse);
@@ -7147,10 +7421,15 @@
71477421
while( s.pVar ){
71487422
PVar *pNext = s.pVar->pNext;
71497423
free(s.pVar);
71507424
s.pVar = pNext;
71517425
}
7426
+ while( s.pMacros ){
7427
+ PMacro *pNext = s.pMacros->pNext;
7428
+ free(s.pMacros);
7429
+ s.pMacros = pNext;
7430
+ }
71527431
if( pnWidth ) *pnWidth = s.nErr ? -1 : s.wSVG;
71537432
if( pnHeight ) *pnHeight = s.nErr ? -1 : s.hSVG;
71547433
if( s.zOut ){
71557434
s.zOut[s.nOut] = 0;
71567435
s.zOut = realloc(s.zOut, s.nOut+1);
@@ -7317,6 +7596,6 @@
73177596
}
73187597
return 0;
73197598
}
73207599
#endif /* PIKCHR_SHELL */
73217600
7322
-#line 7347 "pikchr.c"
7601
+#line 7626 "pikchr.c"
73237602
--- src/pikchr.c
+++ src/pikchr.c
@@ -68,47 +68,47 @@
68 **
69 ** Each call to pikchr() uses a single instance of the Pik structure to
70 ** track its internal state. The Pik structure lives for the duration
71 ** of the pikchr() call.
72 **
73 ** The input is a sequence of objects or "elements". Each element is
74 ** parsed into a PElem object. These are stored on an extensible array
75 ** called PEList. All parameters to each PElem are computed as the
76 ** object is parsed. (Hence, the parameters to a PElem may only refer
77 ** to prior elements.) Once the PElem is completely assembled, it is
78 ** added to the end of a PEList and never changes thereafter - except,
79 ** PElem objects that are part of a "[...]" block might have their
80 ** absolute position shifted when the outer [...] block is positioned.
81 ** But apart from this repositioning, PElem objects are unchanged once
82 ** they are added to the list. The order of elements on a PEList does
83 ** not change.
84 **
85 ** After all input has been parsed, the top-level PEList is walked to
86 ** generate output. Sub-lists resulting from [...] blocks are scanned
87 ** as they are encountered. All input must be collected and parsed ahead
88 ** of output generation because the size and position of elements must be
89 ** known in order to compute a bounding box on the output.
90 **
91 ** Each PElem is on a "layer". (The common case is that all PElem's are
92 ** on a single layer, but multiple layers are possible.) A separate pass
93 ** is made through the list for each layer.
94 **
95 ** After all output is generated, the Pik object and all the PEList
96 ** and PElem objects are deallocated and the generated output string is
97 ** returned. Upon any error, the Pik.nErr flag is set, processing quickly
98 ** stops, and the stack unwinds. No attempt is made to continue reading
99 ** input after an error.
100 **
101 ** Most elements begin with a class name like "box" or "arrow" or "move".
102 ** There is a class named "text" which is used for elements that begin
103 ** with a string literal. You can also specify the "text" class.
104 ** A Sublist ("[...]") is a single object that contains a pointer to
105 ** its subelements, all gathered onto a separate PEList object.
106 **
107 ** Variables go into PVar objects that form a linked list.
108 **
109 ** Each PElem has zero or one names. Input constructs that attempt
110 ** to assign a new name from an older name, for example:
111 **
112 ** Abc: Abc + (0.5cm, 0)
113 **
114 ** Statements like these generate a new "noop" object at the specified
@@ -131,18 +131,19 @@
131 ** compiler warnings with -Wextra */
132 #define UNUSED_PARAMETER(X) (void)(X)
133
134 typedef struct Pik Pik; /* Complete parsing context */
135 typedef struct PToken PToken; /* A single token */
136 typedef struct PElem PElem; /* A single diagram object or "element" */
137 typedef struct PEList PEList; /* A list of elements */
138 typedef struct PClass PClass; /* Description of elements types */
139 typedef double PNum; /* Numeric value */
140 typedef struct PRel PRel; /* Absolute or percentage value */
141 typedef struct PPoint PPoint; /* A position in 2-D space */
142 typedef struct PVar PVar; /* script-defined variable */
143 typedef struct PBox PBox; /* A bounding box */
 
144
145 /* Compass points */
146 #define CP_N 1
147 #define CP_NE 2
148 #define CP_E 3
@@ -181,15 +182,15 @@
181 /* Text position and style flags. Stored in PToken.eCode so limited
182 ** to 15 bits. */
183 #define TP_LJUST 0x0001 /* left justify...... */
184 #define TP_RJUST 0x0002 /* ...Right justify */
185 #define TP_JMASK 0x0003 /* Mask for justification bits */
186 #define TP_ABOVE2 0x0004 /* Position text way above PElem.ptAt */
187 #define TP_ABOVE 0x0008 /* Position text above PElem.ptAt */
188 #define TP_CENTER 0x0010 /* On the line */
189 #define TP_BELOW 0x0020 /* Position text below PElem.ptAt */
190 #define TP_BELOW2 0x0040 /* Position text way below PElem.ptAt */
191 #define TP_VMASK 0x007c /* Mask for text positioning flags */
192 #define TP_BIG 0x0100 /* Larger font */
193 #define TP_SMALL 0x0200 /* Smaller font */
194 #define TP_XTRA 0x0400 /* Amplify TP_BIG or TP_SMALL */
195 #define TP_SZMASK 0x0700 /* Font size mask */
@@ -254,10 +255,11 @@
254 }
255
256 /* Extra token types not generated by LEMON but needed by the
257 ** tokenizer
258 */
 
259 #define T_WHITESPACE 254 /* Whitespace of comments */
260 #define T_ERROR 255 /* Any text that is not a valid token */
261
262 /* Directions of movement */
263 #define DIR_RIGHT 0
@@ -266,12 +268,12 @@
266 #define DIR_UP 3
267 #define ValidDir(X) ((X)>=0 && (X)<=3)
268 #define IsUpDown(X) (((X)&1)==1)
269 #define IsLeftRight(X) (((X)&1)==0)
270
271 /* Bitmask for the various attributes for PElem. These bits are
272 ** collected in PElem.mProp and PElem.mCalc to check for constraint
273 ** errors. */
274 #define A_WIDTH 0x0001
275 #define A_HEIGHT 0x0002
276 #define A_RADIUS 0x0004
277 #define A_THICKNESS 0x0008
@@ -281,20 +283,21 @@
281 #define A_ARROW 0x0080
282 #define A_FROM 0x0100
283 #define A_CW 0x0200
284 #define A_AT 0x0400
285 #define A_TO 0x0800 /* one or more movement attributes */
 
286
287
288 /* A single element */
289 struct PElem {
290 const PClass *type; /* Element type */
291 PToken errTok; /* Reference token for error messages */
292 PPoint ptAt; /* Reference point for the object */
293 PPoint ptEnter, ptExit; /* Entry and exit points */
294 PEList *pSublist; /* Substructure for [...] elements */
295 char *zName; /* Name assigned to this element */
296 PNum w; /* "width" property */
297 PNum h; /* "height" property */
298 PNum rad; /* "radius" property */
299 PNum sw; /* "thickness" property. (Mnemonic: "stroke width")*/
300 PNum dotted; /* "dotted" property. <=0.0 for off */
@@ -317,33 +320,41 @@
317 int nPath; /* Number of path points */
318 PPoint *aPath; /* Array of path points */
319 PBox bbox; /* Bounding box */
320 };
321
322 /* A list of elements */
323 struct PEList {
324 int n; /* Number of elements in the list */
325 int nAlloc; /* Allocated slots in a[] */
326 PElem **a; /* Pointers to individual elements */
 
 
 
 
 
 
 
 
327 };
328
329 /* Each call to the pikchr() subroutine uses an instance of the following
330 ** object to pass around context to all of its subroutines.
331 */
332 struct Pik {
333 unsigned nErr; /* Number of errors seen */
334 const char *zIn; /* Input PIKCHR-language text. zero-terminated */
335 unsigned int nIn; /* Number of bytes in zIn */
336 char *zOut; /* Result accumulates here */
337 unsigned int nOut; /* Bytes written to zOut[] so far */
338 unsigned int nOutAlloc; /* Space allocated to zOut[] */
339 unsigned char eDir; /* Current direction */
340 unsigned int mFlags; /* Flags passed to pikchr() */
341 PElem *cur; /* Element under construction */
342 PEList *list; /* Element list under construction */
 
343 PVar *pVar; /* Application-defined variables */
344 PBox bbox; /* Bounding box around all elements */
345 /* Cache of layout values. <=0.0 for unknown... */
346 PNum rScale; /* Multiply to convert inches to pixels */
347 PNum fontScale; /* Scale fonts by this percent */
348 PNum charWidth; /* Character width */
349 PNum charHeight; /* Character height */
@@ -353,14 +364,17 @@
353 char thenFlag; /* True if "then" seen */
354 char samePath; /* aTPath copied by "same" */
355 const char *zClass; /* Class name for the <svg> */
356 int wSVG, hSVG; /* Width and height of the <svg> */
357 /* Paths for lines are constructed here first, then transferred into
358 ** the PElem object at the end: */
359 int nTPath; /* Number of entries on aTPath[] */
360 int mTPath; /* For last entry, 1: x set, 2: y set */
361 PPoint aTPath[1000]; /* Path under construction */
 
 
 
362 };
363
364
365 /*
366 ** The behavior of an object class is defined by an instance of
@@ -368,17 +382,17 @@
368 */
369 struct PClass {
370 const char *zName; /* Name of class */
371 char isLine; /* True if a line class */
372 char eJust; /* Use box-style text justification */
373 void (*xInit)(Pik*,PElem*); /* Initializer */
374 void (*xNumProp)(Pik*,PElem*,PToken*); /* Value change notification */
375 void (*xCheck)(Pik*,PElem*); /* Checks to do after parsing */
376 PPoint (*xChop)(Pik*,PElem*,PPoint*); /* Chopper */
377 PPoint (*xOffset)(Pik*,PElem*,int); /* Offset from .c to edge point */
378 void (*xFit)(Pik*,PElem*,PNum w,PNum h); /* Size to fit text */
379 void (*xRender)(Pik*,PElem*); /* Render */
380 };
381
382
383 /* Forward declarations */
384 static void pik_append(Pik*, const char*,int);
@@ -389,70 +403,71 @@
389 static void pik_append_y(Pik*,const char*,PNum,const char*);
390 static void pik_append_xy(Pik*,const char*,PNum,PNum);
391 static void pik_append_dis(Pik*,const char*,PNum,const char*);
392 static void pik_append_arc(Pik*,PNum,PNum,PNum,PNum);
393 static void pik_append_clr(Pik*,const char*,PNum,const char*);
394 static void pik_append_style(Pik*,PElem*,int);
395 static void pik_append_txt(Pik*,PElem*, PBox*);
396 static void pik_draw_arrowhead(Pik*,PPoint*pFrom,PPoint*pTo,PElem*);
397 static void pik_chop(PPoint*pFrom,PPoint*pTo,PNum);
398 static void pik_error(Pik*,PToken*,const char*);
399 static void pik_elist_free(Pik*,PEList*);
400 static void pik_elem_free(Pik*,PElem*);
401 static void pik_render(Pik*,PEList*);
402 static PEList *pik_elist_append(Pik*,PEList*,PElem*);
403 static PElem *pik_elem_new(Pik*,PToken*,PToken*,PEList*);
404 static void pik_set_direction(Pik*,int);
405 static void pik_elem_setname(Pik*,PElem*,PToken*);
406 static void pik_set_var(Pik*,PToken*,PNum,PToken*);
407 static PNum pik_value(Pik*,const char*,int,int*);
408 static PNum pik_lookup_color(Pik*,PToken*);
409 static PNum pik_get_var(Pik*,PToken*);
410 static PNum pik_atof(PToken*);
411 static void pik_after_adding_attributes(Pik*,PElem*);
412 static void pik_elem_move(PElem*,PNum dx, PNum dy);
413 static void pik_elist_move(PEList*,PNum dx, PNum dy);
414 static void pik_set_numprop(Pik*,PToken*,PRel*);
415 static void pik_set_clrprop(Pik*,PToken*,PNum);
416 static void pik_set_dashed(Pik*,PToken*,PNum*);
417 static void pik_then(Pik*,PToken*,PElem*);
418 static void pik_add_direction(Pik*,PToken*,PRel*);
419 static void pik_move_hdg(Pik*,PRel*,PToken*,PNum,PToken*,PToken*);
420 static void pik_evenwith(Pik*,PToken*,PPoint*);
421 static void pik_set_from(Pik*,PElem*,PToken*,PPoint*);
422 static void pik_add_to(Pik*,PElem*,PToken*,PPoint*);
423 static void pik_close_path(Pik*,PToken*);
424 static void pik_set_at(Pik*,PToken*,PPoint*,PToken*);
425 static short int pik_nth_value(Pik*,PToken*);
426 static PElem *pik_find_nth(Pik*,PElem*,PToken*);
427 static PElem *pik_find_byname(Pik*,PElem*,PToken*);
428 static PPoint pik_place_of_elem(Pik*,PElem*,PToken*);
429 static int pik_bbox_isempty(PBox*);
430 static void pik_bbox_init(PBox*);
431 static void pik_bbox_addbox(PBox*,PBox*);
432 static void pik_bbox_add_xy(PBox*,PNum,PNum);
433 static void pik_bbox_addellipse(PBox*,PNum x,PNum y,PNum rx,PNum ry);
434 static void pik_add_txt(Pik*,PToken*,int);
435 static int pik_text_length(const PToken *pToken);
436 static void pik_size_to_fit(Pik*,PToken*);
437 static int pik_text_position(int,PToken*);
438 static PNum pik_property_of(PElem*,PToken*);
439 static PNum pik_func(Pik*,PToken*,PNum,PNum);
440 static PPoint pik_position_between(PNum x, PPoint p1, PPoint p2);
441 static PPoint pik_position_at_angle(PNum dist, PNum r, PPoint pt);
442 static PPoint pik_position_at_hdg(PNum dist, PToken *pD, PPoint pt);
443 static void pik_same(Pik *p, PElem*, PToken*);
444 static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pElem);
445 static PToken pik_next_semantic_token(PToken *pThis);
446 static void pik_compute_layout_settings(Pik*);
447 static void pik_behind(Pik*,PElem*);
448 static PElem *pik_assert(Pik*,PNum,PToken*,PNum);
449 static PElem *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
450 static PNum pik_dist(PPoint*,PPoint*);
 
451
452
453 #line 479 "pikchr.c"
454 /**************** End of %include directives **********************************/
455 /* These constants specify the various numeric values for terminal symbols.
456 ***************** Begin token definitions *************************************/
457 #ifndef T_ID
458 #define T_ID 1
@@ -470,87 +485,89 @@
470 #define T_COLON 13
471 #define T_ASSERT 14
472 #define T_LP 15
473 #define T_EQ 16
474 #define T_RP 17
475 #define T_FILL 18
476 #define T_COLOR 19
477 #define T_THICKNESS 20
478 #define T_PRINT 21
479 #define T_STRING 22
480 #define T_COMMA 23
481 #define T_CLASSNAME 24
482 #define T_LB 25
483 #define T_RB 26
484 #define T_UP 27
485 #define T_DOWN 28
486 #define T_LEFT 29
487 #define T_RIGHT 30
488 #define T_CLOSE 31
489 #define T_CHOP 32
490 #define T_FROM 33
491 #define T_TO 34
492 #define T_THEN 35
493 #define T_HEADING 36
494 #define T_GO 37
495 #define T_AT 38
496 #define T_WITH 39
497 #define T_SAME 40
498 #define T_AS 41
499 #define T_FIT 42
500 #define T_BEHIND 43
501 #define T_UNTIL 44
502 #define T_EVEN 45
503 #define T_DOT_E 46
504 #define T_HEIGHT 47
505 #define T_WIDTH 48
506 #define T_RADIUS 49
507 #define T_DIAMETER 50
508 #define T_DOTTED 51
509 #define T_DASHED 52
510 #define T_CW 53
511 #define T_CCW 54
512 #define T_LARROW 55
513 #define T_RARROW 56
514 #define T_LRARROW 57
515 #define T_INVIS 58
516 #define T_THICK 59
517 #define T_THIN 60
518 #define T_CENTER 61
519 #define T_LJUST 62
520 #define T_RJUST 63
521 #define T_ABOVE 64
522 #define T_BELOW 65
523 #define T_ITALIC 66
524 #define T_BOLD 67
525 #define T_ALIGNED 68
526 #define T_BIG 69
527 #define T_SMALL 70
528 #define T_AND 71
529 #define T_LT 72
530 #define T_GT 73
531 #define T_ON 74
532 #define T_WAY 75
533 #define T_BETWEEN 76
534 #define T_THE 77
535 #define T_NTH 78
536 #define T_VERTEX 79
537 #define T_TOP 80
538 #define T_BOTTOM 81
539 #define T_START 82
540 #define T_END 83
541 #define T_IN 84
542 #define T_DOT_U 85
543 #define T_LAST 86
544 #define T_NUMBER 87
545 #define T_FUNC1 88
546 #define T_FUNC2 89
547 #define T_DIST 90
548 #define T_DOT_XY 91
549 #define T_X 92
550 #define T_Y 93
551 #define T_DOT_L 94
 
 
552 #endif
553 /**************** End token definitions ***************************************/
554
555 /* The next sections is a series of control #defines.
556 ** various aspects of the generated parser.
@@ -606,22 +623,22 @@
606 #ifndef INTERFACE
607 # define INTERFACE 1
608 #endif
609 /************* Begin control #defines *****************************************/
610 #define YYCODETYPE unsigned char
611 #define YYNOCODE 131
612 #define YYACTIONTYPE unsigned short int
613 #define pik_parserTOKENTYPE PToken
614 typedef union {
615 int yyinit;
616 pik_parserTOKENTYPE yy0;
617 PEList* yy56;
618 int yy116;
619 PRel yy164;
620 PPoint yy175;
621 PElem* yy226;
622 PNum yy257;
623 } YYMINORTYPE;
624 #ifndef YYSTACKDEPTH
625 #define YYSTACKDEPTH 100
626 #endif
627 #define pik_parserARG_SDECL
@@ -633,22 +650,22 @@
633 #define pik_parserCTX_PDECL ,Pik *p
634 #define pik_parserCTX_PARAM ,p
635 #define pik_parserCTX_FETCH Pik *p=yypParser->p;
636 #define pik_parserCTX_STORE yypParser->p=p;
637 #define YYFALLBACK 1
638 #define YYNSTATE 162
639 #define YYNRULE 153
640 #define YYNRULE_WITH_ACTION 113
641 #define YYNTOKEN 95
642 #define YY_MAX_SHIFT 161
643 #define YY_MIN_SHIFTREDUCE 282
644 #define YY_MAX_SHIFTREDUCE 434
645 #define YY_ERROR_ACTION 435
646 #define YY_ACCEPT_ACTION 436
647 #define YY_NO_ACTION 437
648 #define YY_MIN_REDUCE 438
649 #define YY_MAX_REDUCE 590
650 /************* End control #defines *******************************************/
651 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
652
653 /* Define the yytestcase() macro to be a no-op if is not already defined
654 ** otherwise.
@@ -711,328 +728,324 @@
711 ** yy_reduce_ofst[] For each state, the offset into yy_action for
712 ** shifting non-terminals after a reduce.
713 ** yy_default[] Default action for each state.
714 **
715 *********** Begin parsing tables **********************************************/
716 #define YY_ACTTAB_COUNT (1244)
717 static const YYACTIONTYPE yy_action[] = {
718 /* 0 */ 564, 438, 25, 444, 29, 74, 127, 146, 54, 51,
719 /* 10 */ 564, 36, 445, 113, 120, 159, 119, 126, 419, 420,
720 /* 20 */ 333, 548, 81, 520, 549, 550, 564, 64, 63, 62,
721 /* 30 */ 61, 316, 317, 9, 8, 33, 147, 32, 7, 71,
722 /* 40 */ 125, 28, 329, 66, 568, 300, 50, 333, 333, 333,
723 /* 50 */ 333, 417, 418, 334, 335, 336, 337, 338, 339, 340,
724 /* 60 */ 341, 465, 64, 63, 62, 61, 121, 439, 446, 29,
725 /* 70 */ 36, 465, 30, 442, 368, 292, 486, 159, 119, 419,
726 /* 80 */ 420, 333, 31, 81, 161, 350, 304, 465, 436, 27,
727 /* 90 */ 324, 13, 316, 317, 9, 8, 33, 69, 32, 7,
728 /* 100 */ 71, 125, 83, 329, 66, 483, 159, 119, 333, 333,
729 /* 110 */ 333, 333, 417, 418, 334, 335, 336, 337, 338, 339,
730 /* 120 */ 340, 341, 386, 427, 46, 59, 60, 64, 63, 62,
731 /* 130 */ 61, 307, 84, 368, 322, 35, 2, 293, 386, 427,
732 /* 140 */ 108, 59, 60, 80, 4, 302, 79, 3, 117, 368,
733 /* 150 */ 433, 432, 2, 62, 61, 154, 154, 154, 386, 390,
734 /* 160 */ 391, 59, 60, 518, 159, 119, 433, 432, 47, 102,
735 /* 170 */ 38, 67, 42, 48, 37, 295, 296, 297, 69, 299,
736 /* 180 */ 372, 155, 426, 343, 343, 343, 343, 343, 343, 343,
737 /* 190 */ 343, 343, 343, 371, 157, 566, 77, 566, 426, 106,
738 /* 200 */ 76, 428, 429, 430, 431, 5, 6, 117, 385, 153,
739 /* 210 */ 152, 151, 523, 159, 119, 106, 416, 428, 429, 430,
740 /* 220 */ 431, 415, 427, 117, 385, 153, 152, 151, 386, 427,
741 /* 230 */ 129, 59, 60, 389, 1, 106, 521, 159, 119, 368,
742 /* 240 */ 11, 12, 2, 117, 385, 153, 152, 151, 65, 433,
743 /* 250 */ 432, 64, 63, 62, 61, 349, 433, 432, 136, 140,
744 /* 260 */ 138, 64, 63, 62, 61, 386, 75, 427, 59, 60,
745 /* 270 */ 53, 424, 422, 45, 137, 14, 368, 16, 18, 42,
746 /* 280 */ 55, 426, 154, 154, 154, 44, 145, 144, 426, 64,
747 /* 290 */ 63, 62, 61, 43, 433, 432, 64, 63, 62, 61,
748 /* 300 */ 428, 429, 430, 431, 19, 106, 114, 428, 429, 430,
749 /* 310 */ 431, 20, 68, 117, 385, 153, 152, 151, 15, 352,
750 /* 320 */ 23, 22, 21, 384, 376, 17, 426, 370, 156, 24,
751 /* 330 */ 26, 143, 139, 423, 140, 138, 64, 63, 62, 61,
752 /* 340 */ 374, 57, 106, 58, 375, 428, 429, 430, 431, 383,
753 /* 350 */ 117, 385, 153, 152, 151, 55, 64, 63, 62, 61,
754 /* 360 */ 369, 145, 144, 403, 404, 405, 406, 158, 43, 348,
755 /* 370 */ 70, 140, 138, 64, 63, 62, 61, 386, 464, 39,
756 /* 380 */ 59, 60, 64, 63, 62, 61, 437, 437, 368, 118,
757 /* 390 */ 437, 42, 55, 437, 437, 383, 22, 21, 145, 144,
758 /* 400 */ 395, 49, 437, 524, 24, 43, 143, 139, 423, 437,
759 /* 410 */ 437, 131, 464, 124, 437, 437, 437, 396, 397, 398,
760 /* 420 */ 400, 80, 437, 302, 79, 437, 403, 404, 405, 406,
761 /* 430 */ 440, 446, 29, 22, 21, 386, 442, 437, 59, 60,
762 /* 440 */ 437, 24, 524, 143, 139, 423, 368, 161, 524, 42,
763 /* 450 */ 437, 524, 27, 437, 106, 437, 386, 141, 437, 59,
764 /* 460 */ 60, 437, 117, 385, 153, 152, 151, 368, 437, 437,
765 /* 470 */ 42, 437, 386, 142, 437, 59, 60, 386, 130, 128,
766 /* 480 */ 59, 60, 437, 368, 370, 156, 42, 437, 368, 437,
767 /* 490 */ 386, 42, 437, 59, 60, 386, 437, 437, 59, 60,
768 /* 500 */ 437, 102, 437, 437, 42, 437, 368, 437, 437, 40,
769 /* 510 */ 437, 437, 106, 437, 386, 437, 437, 59, 60, 437,
770 /* 520 */ 117, 385, 153, 152, 151, 368, 437, 437, 41, 64,
771 /* 530 */ 63, 62, 61, 106, 64, 63, 62, 61, 437, 160,
772 /* 540 */ 437, 117, 385, 153, 152, 151, 118, 387, 56, 106,
773 /* 550 */ 437, 437, 437, 437, 106, 437, 437, 117, 385, 153,
774 /* 560 */ 152, 151, 117, 385, 153, 152, 151, 106, 64, 63,
775 /* 570 */ 62, 61, 106, 437, 437, 117, 385, 153, 152, 151,
776 /* 580 */ 117, 385, 153, 152, 151, 419, 420, 333, 437, 437,
777 /* 590 */ 437, 106, 437, 437, 437, 88, 437, 437, 437, 117,
778 /* 600 */ 385, 153, 152, 151, 120, 159, 119, 437, 437, 437,
779 /* 610 */ 10, 470, 470, 437, 333, 333, 333, 333, 417, 418,
780 /* 620 */ 73, 437, 146, 437, 437, 437, 150, 112, 113, 120,
781 /* 630 */ 159, 119, 437, 74, 437, 146, 64, 63, 62, 61,
782 /* 640 */ 122, 113, 120, 159, 119, 72, 437, 146, 437, 347,
783 /* 650 */ 437, 147, 123, 113, 120, 159, 119, 437, 74, 437,
784 /* 660 */ 146, 437, 437, 437, 147, 488, 113, 120, 159, 119,
785 /* 670 */ 437, 437, 74, 437, 146, 437, 147, 437, 437, 487,
786 /* 680 */ 113, 120, 159, 119, 74, 437, 146, 437, 437, 147,
787 /* 690 */ 437, 481, 113, 120, 159, 119, 437, 437, 437, 74,
788 /* 700 */ 437, 146, 88, 147, 437, 437, 475, 113, 120, 159,
789 /* 710 */ 119, 120, 159, 119, 74, 147, 146, 437, 110, 110,
790 /* 720 */ 437, 474, 113, 120, 159, 119, 437, 74, 437, 146,
791 /* 730 */ 147, 437, 437, 150, 471, 113, 120, 159, 119, 437,
792 /* 740 */ 74, 437, 146, 437, 437, 147, 437, 132, 113, 120,
793 /* 750 */ 159, 119, 74, 437, 146, 437, 437, 437, 147, 507,
794 /* 760 */ 113, 120, 159, 119, 437, 74, 437, 146, 437, 437,
795 /* 770 */ 437, 147, 135, 113, 120, 159, 119, 437, 437, 74,
796 /* 780 */ 437, 146, 437, 147, 437, 437, 515, 113, 120, 159,
797 /* 790 */ 119, 74, 437, 146, 437, 437, 147, 437, 517, 113,
798 /* 800 */ 120, 159, 119, 437, 437, 437, 74, 437, 146, 88,
799 /* 810 */ 147, 437, 437, 514, 113, 120, 159, 119, 120, 159,
800 /* 820 */ 119, 74, 147, 146, 437, 111, 111, 437, 516, 113,
801 /* 830 */ 120, 159, 119, 437, 74, 437, 146, 147, 437, 437,
802 /* 840 */ 150, 513, 113, 120, 159, 119, 437, 74, 437, 146,
803 /* 850 */ 437, 437, 147, 437, 512, 113, 120, 159, 119, 74,
804 /* 860 */ 437, 146, 437, 437, 437, 147, 511, 113, 120, 159,
805 /* 870 */ 119, 437, 74, 437, 146, 437, 437, 437, 147, 510,
806 /* 880 */ 113, 120, 159, 119, 437, 437, 74, 437, 146, 437,
807 /* 890 */ 147, 437, 437, 509, 113, 120, 159, 119, 74, 437,
808 /* 900 */ 146, 107, 437, 147, 437, 148, 113, 120, 159, 119,
809 /* 910 */ 120, 159, 119, 74, 469, 146, 85, 147, 437, 437,
810 /* 920 */ 149, 113, 120, 159, 119, 120, 159, 119, 74, 147,
811 /* 930 */ 146, 437, 150, 437, 437, 134, 113, 120, 159, 119,
812 /* 940 */ 437, 74, 437, 146, 147, 107, 437, 150, 133, 113,
813 /* 950 */ 120, 159, 119, 437, 120, 159, 119, 437, 454, 147,
814 /* 960 */ 437, 64, 63, 62, 61, 78, 78, 437, 88, 437,
815 /* 970 */ 437, 437, 147, 437, 383, 437, 150, 120, 159, 119,
816 /* 980 */ 52, 437, 437, 437, 82, 437, 88, 437, 437, 437,
817 /* 990 */ 437, 457, 437, 34, 107, 120, 159, 119, 437, 150,
818 /* 1000 */ 437, 437, 466, 120, 159, 119, 437, 454, 437, 109,
819 /* 1010 */ 439, 446, 29, 437, 437, 558, 442, 150, 437, 437,
820 /* 1020 */ 107, 64, 63, 62, 61, 150, 86, 161, 437, 120,
821 /* 1030 */ 159, 119, 27, 443, 388, 120, 159, 119, 98, 437,
822 /* 1040 */ 437, 437, 437, 89, 437, 437, 437, 120, 159, 119,
823 /* 1050 */ 90, 150, 120, 159, 119, 87, 437, 150, 437, 120,
824 /* 1060 */ 159, 119, 99, 437, 120, 159, 119, 437, 100, 150,
825 /* 1070 */ 437, 120, 159, 119, 150, 437, 437, 120, 159, 119,
826 /* 1080 */ 101, 150, 64, 63, 62, 61, 150, 437, 437, 120,
827 /* 1090 */ 159, 119, 437, 150, 91, 383, 437, 103, 437, 150,
828 /* 1100 */ 437, 437, 437, 120, 159, 119, 120, 159, 119, 92,
829 /* 1110 */ 437, 150, 93, 437, 437, 437, 437, 437, 120, 159,
830 /* 1120 */ 119, 120, 159, 119, 437, 150, 104, 437, 150, 437,
831 /* 1130 */ 437, 437, 437, 437, 437, 120, 159, 119, 94, 437,
832 /* 1140 */ 150, 437, 437, 150, 437, 437, 437, 120, 159, 119,
833 /* 1150 */ 105, 437, 437, 95, 437, 437, 437, 150, 437, 120,
834 /* 1160 */ 159, 119, 120, 159, 119, 96, 437, 437, 97, 150,
835 /* 1170 */ 437, 437, 437, 437, 120, 159, 119, 120, 159, 119,
836 /* 1180 */ 538, 150, 437, 437, 150, 437, 437, 437, 437, 120,
837 /* 1190 */ 159, 119, 437, 537, 437, 437, 150, 536, 437, 150,
838 /* 1200 */ 437, 437, 120, 159, 119, 535, 120, 159, 119, 115,
839 /* 1210 */ 437, 150, 116, 437, 120, 159, 119, 437, 120, 159,
840 /* 1220 */ 119, 120, 159, 119, 150, 437, 437, 437, 150, 437,
841 /* 1230 */ 437, 437, 437, 437, 437, 437, 150, 437, 437, 437,
842 /* 1240 */ 150, 437, 437, 150,
843 };
844 static const YYCODETYPE yy_lookahead[] = {
845 /* 0 */ 0, 0, 129, 97, 98, 99, 101, 101, 4, 5,
846 /* 10 */ 10, 10, 106, 107, 108, 109, 110, 101, 18, 19,
847 /* 20 */ 20, 100, 22, 101, 103, 104, 26, 4, 5, 6,
848 /* 30 */ 7, 31, 32, 33, 34, 35, 130, 37, 38, 39,
849 /* 40 */ 40, 102, 42, 43, 128, 23, 23, 47, 48, 49,
850 /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
851 /* 60 */ 60, 0, 4, 5, 6, 7, 95, 96, 97, 98,
852 /* 70 */ 10, 10, 121, 102, 12, 17, 108, 109, 110, 18,
853 /* 80 */ 19, 20, 123, 22, 113, 17, 26, 26, 117, 118,
854 /* 90 */ 2, 23, 31, 32, 33, 34, 35, 3, 37, 38,
855 /* 100 */ 39, 40, 111, 42, 43, 108, 109, 110, 47, 48,
856 /* 110 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
857 /* 120 */ 59, 60, 1, 2, 36, 4, 5, 4, 5, 6,
858 /* 130 */ 7, 8, 111, 12, 2, 124, 15, 17, 1, 2,
859 /* 140 */ 78, 4, 5, 22, 15, 24, 25, 16, 86, 12,
860 /* 150 */ 29, 30, 15, 6, 7, 18, 19, 20, 1, 92,
861 /* 160 */ 93, 4, 5, 108, 109, 110, 29, 30, 36, 12,
862 /* 170 */ 100, 41, 15, 103, 104, 18, 19, 20, 84, 22,
863 /* 180 */ 24, 25, 61, 61, 62, 63, 64, 65, 66, 67,
864 /* 190 */ 68, 69, 70, 24, 25, 125, 126, 127, 61, 78,
865 /* 200 */ 46, 80, 81, 82, 83, 38, 38, 86, 87, 88,
866 /* 210 */ 89, 90, 108, 109, 110, 78, 39, 80, 81, 82,
867 /* 220 */ 83, 39, 2, 86, 87, 88, 89, 90, 1, 2,
868 /* 230 */ 45, 4, 5, 17, 13, 78, 108, 109, 110, 12,
869 /* 240 */ 23, 71, 15, 86, 87, 88, 89, 90, 94, 29,
870 /* 250 */ 30, 4, 5, 6, 7, 17, 29, 30, 75, 2,
871 /* 260 */ 3, 4, 5, 6, 7, 1, 46, 2, 4, 5,
872 /* 270 */ 23, 76, 76, 16, 77, 3, 12, 3, 3, 15,
873 /* 280 */ 23, 61, 18, 19, 20, 36, 29, 30, 61, 4,
874 /* 290 */ 5, 6, 7, 36, 29, 30, 4, 5, 6, 7,
875 /* 300 */ 80, 81, 82, 83, 3, 78, 91, 80, 81, 82,
876 /* 310 */ 83, 3, 3, 86, 87, 88, 89, 90, 33, 73,
877 /* 320 */ 23, 64, 65, 17, 26, 33, 61, 24, 25, 72,
878 /* 330 */ 15, 74, 75, 76, 2, 3, 4, 5, 6, 7,
879 /* 340 */ 26, 15, 78, 15, 26, 80, 81, 82, 83, 17,
880 /* 350 */ 86, 87, 88, 89, 90, 23, 4, 5, 6, 7,
881 /* 360 */ 12, 29, 30, 27, 28, 29, 30, 85, 36, 17,
882 /* 370 */ 3, 2, 3, 4, 5, 6, 7, 1, 2, 11,
883 /* 380 */ 4, 5, 4, 5, 6, 7, 131, 131, 12, 86,
884 /* 390 */ 131, 15, 23, 131, 131, 17, 64, 65, 29, 30,
885 /* 400 */ 1, 23, 131, 46, 72, 36, 74, 75, 76, 131,
886 /* 410 */ 131, 12, 36, 14, 131, 131, 131, 18, 19, 20,
887 /* 420 */ 21, 22, 131, 24, 25, 131, 27, 28, 29, 30,
888 /* 430 */ 96, 97, 98, 64, 65, 1, 102, 131, 4, 5,
889 /* 440 */ 131, 72, 85, 74, 75, 76, 12, 113, 91, 15,
890 /* 450 */ 131, 94, 118, 131, 78, 131, 1, 2, 131, 4,
891 /* 460 */ 5, 131, 86, 87, 88, 89, 90, 12, 131, 131,
892 /* 470 */ 15, 131, 1, 2, 131, 4, 5, 1, 44, 45,
893 /* 480 */ 4, 5, 131, 12, 24, 25, 15, 131, 12, 131,
894 /* 490 */ 1, 15, 131, 4, 5, 1, 131, 131, 4, 5,
895 /* 500 */ 131, 12, 131, 131, 15, 131, 12, 131, 131, 15,
896 /* 510 */ 131, 131, 78, 131, 1, 131, 131, 4, 5, 131,
897 /* 520 */ 86, 87, 88, 89, 90, 12, 131, 131, 15, 4,
898 /* 530 */ 5, 6, 7, 78, 4, 5, 6, 7, 131, 79,
899 /* 540 */ 131, 86, 87, 88, 89, 90, 86, 17, 23, 78,
900 /* 550 */ 131, 131, 131, 131, 78, 131, 131, 86, 87, 88,
901 /* 560 */ 89, 90, 86, 87, 88, 89, 90, 78, 4, 5,
902 /* 570 */ 6, 7, 78, 131, 131, 86, 87, 88, 89, 90,
903 /* 580 */ 86, 87, 88, 89, 90, 18, 19, 20, 131, 131,
904 /* 590 */ 131, 78, 131, 131, 131, 99, 131, 131, 131, 86,
905 /* 600 */ 87, 88, 89, 90, 108, 109, 110, 131, 131, 131,
906 /* 610 */ 114, 115, 116, 131, 47, 48, 49, 50, 51, 52,
907 /* 620 */ 99, 131, 101, 131, 131, 131, 130, 106, 107, 108,
908 /* 630 */ 109, 110, 131, 99, 131, 101, 4, 5, 6, 7,
909 /* 640 */ 106, 107, 108, 109, 110, 99, 131, 101, 131, 17,
910 /* 650 */ 131, 130, 106, 107, 108, 109, 110, 131, 99, 131,
911 /* 660 */ 101, 131, 131, 131, 130, 106, 107, 108, 109, 110,
912 /* 670 */ 131, 131, 99, 131, 101, 131, 130, 131, 131, 106,
913 /* 680 */ 107, 108, 109, 110, 99, 131, 101, 131, 131, 130,
914 /* 690 */ 131, 106, 107, 108, 109, 110, 131, 131, 131, 99,
915 /* 700 */ 131, 101, 99, 130, 131, 131, 106, 107, 108, 109,
916 /* 710 */ 110, 108, 109, 110, 99, 130, 101, 131, 115, 116,
917 /* 720 */ 131, 106, 107, 108, 109, 110, 131, 99, 131, 101,
918 /* 730 */ 130, 131, 131, 130, 106, 107, 108, 109, 110, 131,
919 /* 740 */ 99, 131, 101, 131, 131, 130, 131, 106, 107, 108,
920 /* 750 */ 109, 110, 99, 131, 101, 131, 131, 131, 130, 106,
921 /* 760 */ 107, 108, 109, 110, 131, 99, 131, 101, 131, 131,
922 /* 770 */ 131, 130, 106, 107, 108, 109, 110, 131, 131, 99,
923 /* 780 */ 131, 101, 131, 130, 131, 131, 106, 107, 108, 109,
924 /* 790 */ 110, 99, 131, 101, 131, 131, 130, 131, 106, 107,
925 /* 800 */ 108, 109, 110, 131, 131, 131, 99, 131, 101, 99,
926 /* 810 */ 130, 131, 131, 106, 107, 108, 109, 110, 108, 109,
927 /* 820 */ 110, 99, 130, 101, 131, 115, 116, 131, 106, 107,
928 /* 830 */ 108, 109, 110, 131, 99, 131, 101, 130, 131, 131,
929 /* 840 */ 130, 106, 107, 108, 109, 110, 131, 99, 131, 101,
930 /* 850 */ 131, 131, 130, 131, 106, 107, 108, 109, 110, 99,
931 /* 860 */ 131, 101, 131, 131, 131, 130, 106, 107, 108, 109,
932 /* 870 */ 110, 131, 99, 131, 101, 131, 131, 131, 130, 106,
933 /* 880 */ 107, 108, 109, 110, 131, 131, 99, 131, 101, 131,
934 /* 890 */ 130, 131, 131, 106, 107, 108, 109, 110, 99, 131,
935 /* 900 */ 101, 99, 131, 130, 131, 106, 107, 108, 109, 110,
936 /* 910 */ 108, 109, 110, 99, 112, 101, 99, 130, 131, 131,
937 /* 920 */ 106, 107, 108, 109, 110, 108, 109, 110, 99, 130,
938 /* 930 */ 101, 131, 130, 131, 131, 106, 107, 108, 109, 110,
939 /* 940 */ 131, 99, 131, 101, 130, 99, 131, 130, 106, 107,
940 /* 950 */ 108, 109, 110, 131, 108, 109, 110, 131, 112, 130,
941 /* 960 */ 131, 4, 5, 6, 7, 119, 120, 131, 99, 131,
942 /* 970 */ 131, 131, 130, 131, 17, 131, 130, 108, 109, 110,
943 /* 980 */ 23, 131, 131, 131, 115, 131, 99, 131, 131, 131,
944 /* 990 */ 131, 122, 131, 124, 99, 108, 109, 110, 131, 130,
945 /* 1000 */ 131, 131, 115, 108, 109, 110, 131, 112, 131, 95,
946 /* 1010 */ 96, 97, 98, 131, 131, 120, 102, 130, 131, 131,
947 /* 1020 */ 99, 4, 5, 6, 7, 130, 99, 113, 131, 108,
948 /* 1030 */ 109, 110, 118, 112, 17, 108, 109, 110, 99, 131,
949 /* 1040 */ 131, 131, 131, 99, 131, 131, 131, 108, 109, 110,
950 /* 1050 */ 99, 130, 108, 109, 110, 99, 131, 130, 131, 108,
951 /* 1060 */ 109, 110, 99, 131, 108, 109, 110, 131, 99, 130,
952 /* 1070 */ 131, 108, 109, 110, 130, 131, 131, 108, 109, 110,
953 /* 1080 */ 99, 130, 4, 5, 6, 7, 130, 131, 131, 108,
954 /* 1090 */ 109, 110, 131, 130, 99, 17, 131, 99, 131, 130,
955 /* 1100 */ 131, 131, 131, 108, 109, 110, 108, 109, 110, 99,
956 /* 1110 */ 131, 130, 99, 131, 131, 131, 131, 131, 108, 109,
957 /* 1120 */ 110, 108, 109, 110, 131, 130, 99, 131, 130, 131,
958 /* 1130 */ 131, 131, 131, 131, 131, 108, 109, 110, 99, 131,
959 /* 1140 */ 130, 131, 131, 130, 131, 131, 131, 108, 109, 110,
960 /* 1150 */ 99, 131, 131, 99, 131, 131, 131, 130, 131, 108,
961 /* 1160 */ 109, 110, 108, 109, 110, 99, 131, 131, 99, 130,
962 /* 1170 */ 131, 131, 131, 131, 108, 109, 110, 108, 109, 110,
963 /* 1180 */ 99, 130, 131, 131, 130, 131, 131, 131, 131, 108,
964 /* 1190 */ 109, 110, 131, 99, 131, 131, 130, 99, 131, 130,
965 /* 1200 */ 131, 131, 108, 109, 110, 99, 108, 109, 110, 99,
966 /* 1210 */ 131, 130, 99, 131, 108, 109, 110, 131, 108, 109,
967 /* 1220 */ 110, 108, 109, 110, 130, 131, 131, 131, 130, 131,
968 /* 1230 */ 131, 131, 131, 131, 131, 131, 130, 131, 131, 131,
969 /* 1240 */ 130, 131, 131, 130, 95, 95, 95, 95, 95, 95,
970 /* 1250 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
971 /* 1260 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
972 /* 1270 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
973 /* 1280 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
974 /* 1290 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
975 /* 1300 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
976 /* 1310 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
977 /* 1320 */ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
978 /* 1330 */ 95, 95, 95, 95, 95, 95, 95, 95, 95,
979 };
980 #define YY_SHIFT_COUNT (161)
981 #define YY_SHIFT_MIN (0)
982 #define YY_SHIFT_MAX (1078)
983 static const unsigned short int yy_shift_ofst[] = {
984 /* 0 */ 399, 121, 137, 227, 227, 227, 227, 227, 227, 227,
985 /* 10 */ 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
986 /* 20 */ 227, 227, 227, 227, 227, 227, 227, 157, 434, 476,
987 /* 30 */ 157, 399, 376, 376, 0, 61, 399, 489, 476, 489,
988 /* 40 */ 264, 264, 264, 455, 471, 476, 476, 476, 476, 476,
989 /* 50 */ 476, 494, 476, 476, 513, 476, 476, 476, 476, 476,
990 /* 60 */ 476, 476, 476, 476, 476, 567, 62, 62, 62, 62,
991 /* 70 */ 62, 220, 257, 332, 369, 265, 265, 336, 22, 1244,
992 /* 80 */ 1244, 1244, 1244, 122, 122, 378, 957, 58, 123, 285,
993 /* 90 */ 292, 352, 23, 632, 247, 1017, 525, 530, 1078, 564,
994 /* 100 */ 564, 564, 357, 564, 564, 564, 460, 564, 303, 60,
995 /* 110 */ 88, 132, 68, 4, 67, 147, 147, 156, 169, 94,
996 /* 120 */ 154, 1, 120, 131, 129, 130, 167, 168, 177, 182,
997 /* 130 */ 185, 221, 216, 217, 170, 238, 195, 183, 197, 196,
998 /* 140 */ 272, 274, 275, 249, 301, 308, 309, 215, 246, 297,
999 /* 150 */ 215, 315, 326, 328, 306, 298, 314, 318, 348, 282,
1000 /* 160 */ 367, 368,
1001 };
1002 #define YY_REDUCE_COUNT (82)
1003 #define YY_REDUCE_MIN (-127)
1004 #define YY_REDUCE_MAX (1113)
1005 static const short yy_reduce_ofst[] = {
1006 /* 0 */ -29, -94, 521, 534, 546, 559, 573, 585, 600, 615,
1007 /* 10 */ 628, 641, 653, 666, 680, 692, 707, 722, 735, 748,
1008 /* 20 */ 760, 773, 787, 799, 814, 829, 842, 846, 496, 869,
1009 /* 30 */ 895, 914, 603, 710, 70, 70, 334, 802, 887, 921,
1010 /* 40 */ 817, 927, 939, 944, 951, 956, 963, 969, 981, 995,
1011 /* 50 */ 998, 1010, 1013, 1027, 1039, 1051, 1054, 1066, 1069, 1081,
1012 /* 60 */ 1094, 1098, 1106, 1110, 1113, -79, -32, -3, 55, 104,
1013 /* 70 */ 128, -84, -127, -127, -127, -95, -78, -61, -49, -41,
1014 /* 80 */ -9, 21, 11,
1015 };
1016 static const YYACTIONTYPE yy_default[] = {
1017 /* 0 */ 441, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1018 /* 10 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1019 /* 20 */ 435, 435, 435, 435, 435, 435, 435, 435, 464, 565,
1020 /* 30 */ 435, 441, 569, 476, 570, 570, 441, 435, 435, 435,
1021 /* 40 */ 435, 435, 435, 435, 435, 435, 435, 435, 468, 435,
1022 /* 50 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1023 /* 60 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1024 /* 70 */ 435, 435, 435, 435, 435, 435, 435, 435, 447, 461,
1025 /* 80 */ 498, 498, 565, 459, 484, 435, 435, 435, 462, 435,
1026 /* 90 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 479,
1027 /* 100 */ 477, 467, 450, 502, 501, 500, 435, 555, 435, 435,
1028 /* 110 */ 435, 435, 435, 577, 435, 534, 533, 529, 435, 522,
1029 /* 120 */ 519, 435, 435, 435, 435, 482, 435, 435, 435, 435,
1030 /* 130 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 435,
1031 /* 140 */ 435, 435, 435, 435, 435, 435, 435, 581, 435, 435,
1032 /* 150 */ 435, 435, 435, 435, 435, 435, 435, 435, 435, 590,
1033 /* 160 */ 435, 435,
1034 };
1035 /********** End of lemon-generated parsing tables *****************************/
1036
1037 /* The next table maps tokens (terminal symbols) into fallback tokens.
1038 ** If a construct like the following:
@@ -1066,10 +1079,12 @@
1066 0, /* COLON => nothing */
1067 0, /* ASSERT => nothing */
1068 0, /* LP => nothing */
1069 0, /* EQ => nothing */
1070 0, /* RP => nothing */
 
 
1071 0, /* FILL => nothing */
1072 0, /* COLOR => nothing */
1073 0, /* THICKNESS => nothing */
1074 0, /* PRINT => nothing */
1075 0, /* STRING => nothing */
@@ -1249,283 +1264,286 @@
1249 /* 13 */ "COLON",
1250 /* 14 */ "ASSERT",
1251 /* 15 */ "LP",
1252 /* 16 */ "EQ",
1253 /* 17 */ "RP",
1254 /* 18 */ "FILL",
1255 /* 19 */ "COLOR",
1256 /* 20 */ "THICKNESS",
1257 /* 21 */ "PRINT",
1258 /* 22 */ "STRING",
1259 /* 23 */ "COMMA",
1260 /* 24 */ "CLASSNAME",
1261 /* 25 */ "LB",
1262 /* 26 */ "RB",
1263 /* 27 */ "UP",
1264 /* 28 */ "DOWN",
1265 /* 29 */ "LEFT",
1266 /* 30 */ "RIGHT",
1267 /* 31 */ "CLOSE",
1268 /* 32 */ "CHOP",
1269 /* 33 */ "FROM",
1270 /* 34 */ "TO",
1271 /* 35 */ "THEN",
1272 /* 36 */ "HEADING",
1273 /* 37 */ "GO",
1274 /* 38 */ "AT",
1275 /* 39 */ "WITH",
1276 /* 40 */ "SAME",
1277 /* 41 */ "AS",
1278 /* 42 */ "FIT",
1279 /* 43 */ "BEHIND",
1280 /* 44 */ "UNTIL",
1281 /* 45 */ "EVEN",
1282 /* 46 */ "DOT_E",
1283 /* 47 */ "HEIGHT",
1284 /* 48 */ "WIDTH",
1285 /* 49 */ "RADIUS",
1286 /* 50 */ "DIAMETER",
1287 /* 51 */ "DOTTED",
1288 /* 52 */ "DASHED",
1289 /* 53 */ "CW",
1290 /* 54 */ "CCW",
1291 /* 55 */ "LARROW",
1292 /* 56 */ "RARROW",
1293 /* 57 */ "LRARROW",
1294 /* 58 */ "INVIS",
1295 /* 59 */ "THICK",
1296 /* 60 */ "THIN",
1297 /* 61 */ "CENTER",
1298 /* 62 */ "LJUST",
1299 /* 63 */ "RJUST",
1300 /* 64 */ "ABOVE",
1301 /* 65 */ "BELOW",
1302 /* 66 */ "ITALIC",
1303 /* 67 */ "BOLD",
1304 /* 68 */ "ALIGNED",
1305 /* 69 */ "BIG",
1306 /* 70 */ "SMALL",
1307 /* 71 */ "AND",
1308 /* 72 */ "LT",
1309 /* 73 */ "GT",
1310 /* 74 */ "ON",
1311 /* 75 */ "WAY",
1312 /* 76 */ "BETWEEN",
1313 /* 77 */ "THE",
1314 /* 78 */ "NTH",
1315 /* 79 */ "VERTEX",
1316 /* 80 */ "TOP",
1317 /* 81 */ "BOTTOM",
1318 /* 82 */ "START",
1319 /* 83 */ "END",
1320 /* 84 */ "IN",
1321 /* 85 */ "DOT_U",
1322 /* 86 */ "LAST",
1323 /* 87 */ "NUMBER",
1324 /* 88 */ "FUNC1",
1325 /* 89 */ "FUNC2",
1326 /* 90 */ "DIST",
1327 /* 91 */ "DOT_XY",
1328 /* 92 */ "X",
1329 /* 93 */ "Y",
1330 /* 94 */ "DOT_L",
1331 /* 95 */ "element_list",
1332 /* 96 */ "element",
1333 /* 97 */ "unnamed_element",
1334 /* 98 */ "basetype",
1335 /* 99 */ "expr",
1336 /* 100 */ "numproperty",
1337 /* 101 */ "edge",
1338 /* 102 */ "direction",
1339 /* 103 */ "dashproperty",
1340 /* 104 */ "colorproperty",
1341 /* 105 */ "locproperty",
1342 /* 106 */ "position",
1343 /* 107 */ "place",
1344 /* 108 */ "object",
1345 /* 109 */ "objectname",
1346 /* 110 */ "nth",
1347 /* 111 */ "textposition",
1348 /* 112 */ "rvalue",
1349 /* 113 */ "lvalue",
1350 /* 114 */ "even",
1351 /* 115 */ "relexpr",
1352 /* 116 */ "optrelexpr",
1353 /* 117 */ "document",
1354 /* 118 */ "print",
1355 /* 119 */ "prlist",
1356 /* 120 */ "pritem",
1357 /* 121 */ "prsep",
1358 /* 122 */ "attribute_list",
1359 /* 123 */ "savelist",
1360 /* 124 */ "alist",
1361 /* 125 */ "attribute",
1362 /* 126 */ "go",
1363 /* 127 */ "boolproperty",
1364 /* 128 */ "withclause",
1365 /* 129 */ "between",
1366 /* 130 */ "place2",
 
 
1367 };
1368 #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
1369
1370 #ifndef NDEBUG
1371 /* For tracing reduce actions, the names of all rules are required.
1372 */
1373 static const char *const yyRuleName[] = {
1374 /* 0 */ "document ::= element_list",
1375 /* 1 */ "element_list ::= element",
1376 /* 2 */ "element_list ::= element_list EOL element",
1377 /* 3 */ "element ::=",
1378 /* 4 */ "element ::= direction",
1379 /* 5 */ "element ::= lvalue ASSIGN rvalue",
1380 /* 6 */ "element ::= PLACENAME COLON unnamed_element",
1381 /* 7 */ "element ::= PLACENAME COLON position",
1382 /* 8 */ "element ::= unnamed_element",
1383 /* 9 */ "element ::= print prlist",
1384 /* 10 */ "element ::= ASSERT LP expr EQ expr RP",
1385 /* 11 */ "element ::= ASSERT LP position EQ position RP",
1386 /* 12 */ "rvalue ::= PLACENAME",
1387 /* 13 */ "pritem ::= FILL",
1388 /* 14 */ "pritem ::= COLOR",
1389 /* 15 */ "pritem ::= THICKNESS",
1390 /* 16 */ "pritem ::= rvalue",
1391 /* 17 */ "pritem ::= STRING",
1392 /* 18 */ "prsep ::= COMMA",
1393 /* 19 */ "unnamed_element ::= basetype attribute_list",
1394 /* 20 */ "basetype ::= CLASSNAME",
1395 /* 21 */ "basetype ::= STRING textposition",
1396 /* 22 */ "basetype ::= LB savelist element_list RB",
1397 /* 23 */ "savelist ::=",
1398 /* 24 */ "relexpr ::= expr",
1399 /* 25 */ "relexpr ::= expr PERCENT",
1400 /* 26 */ "optrelexpr ::=",
1401 /* 27 */ "attribute_list ::= relexpr alist",
1402 /* 28 */ "attribute ::= numproperty relexpr",
1403 /* 29 */ "attribute ::= dashproperty expr",
1404 /* 30 */ "attribute ::= dashproperty",
1405 /* 31 */ "attribute ::= colorproperty rvalue",
1406 /* 32 */ "attribute ::= go direction optrelexpr",
1407 /* 33 */ "attribute ::= go direction even position",
1408 /* 34 */ "attribute ::= CLOSE",
1409 /* 35 */ "attribute ::= CHOP",
1410 /* 36 */ "attribute ::= FROM position",
1411 /* 37 */ "attribute ::= TO position",
1412 /* 38 */ "attribute ::= THEN",
1413 /* 39 */ "attribute ::= THEN optrelexpr HEADING expr",
1414 /* 40 */ "attribute ::= THEN optrelexpr EDGEPT",
1415 /* 41 */ "attribute ::= GO optrelexpr HEADING expr",
1416 /* 42 */ "attribute ::= GO optrelexpr EDGEPT",
1417 /* 43 */ "attribute ::= AT position",
1418 /* 44 */ "attribute ::= SAME",
1419 /* 45 */ "attribute ::= SAME AS object",
1420 /* 46 */ "attribute ::= STRING textposition",
1421 /* 47 */ "attribute ::= FIT",
1422 /* 48 */ "attribute ::= BEHIND object",
1423 /* 49 */ "withclause ::= DOT_E edge AT position",
1424 /* 50 */ "withclause ::= edge AT position",
1425 /* 51 */ "numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS",
1426 /* 52 */ "boolproperty ::= CW",
1427 /* 53 */ "boolproperty ::= CCW",
1428 /* 54 */ "boolproperty ::= LARROW",
1429 /* 55 */ "boolproperty ::= RARROW",
1430 /* 56 */ "boolproperty ::= LRARROW",
1431 /* 57 */ "boolproperty ::= INVIS",
1432 /* 58 */ "boolproperty ::= THICK",
1433 /* 59 */ "boolproperty ::= THIN",
1434 /* 60 */ "textposition ::=",
1435 /* 61 */ "textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL",
1436 /* 62 */ "position ::= expr COMMA expr",
1437 /* 63 */ "position ::= place PLUS expr COMMA expr",
1438 /* 64 */ "position ::= place MINUS expr COMMA expr",
1439 /* 65 */ "position ::= place PLUS LP expr COMMA expr RP",
1440 /* 66 */ "position ::= place MINUS LP expr COMMA expr RP",
1441 /* 67 */ "position ::= LP position COMMA position RP",
1442 /* 68 */ "position ::= LP position RP",
1443 /* 69 */ "position ::= expr between position AND position",
1444 /* 70 */ "position ::= expr LT position COMMA position GT",
1445 /* 71 */ "position ::= expr ABOVE position",
1446 /* 72 */ "position ::= expr BELOW position",
1447 /* 73 */ "position ::= expr LEFT OF position",
1448 /* 74 */ "position ::= expr RIGHT OF position",
1449 /* 75 */ "position ::= expr ON HEADING EDGEPT OF position",
1450 /* 76 */ "position ::= expr HEADING EDGEPT OF position",
1451 /* 77 */ "position ::= expr EDGEPT OF position",
1452 /* 78 */ "position ::= expr ON HEADING expr FROM position",
1453 /* 79 */ "position ::= expr HEADING expr FROM position",
1454 /* 80 */ "place ::= edge OF object",
1455 /* 81 */ "place2 ::= object",
1456 /* 82 */ "place2 ::= object DOT_E edge",
1457 /* 83 */ "place2 ::= NTH VERTEX OF object",
1458 /* 84 */ "object ::= nth",
1459 /* 85 */ "object ::= nth OF|IN object",
1460 /* 86 */ "objectname ::= PLACENAME",
1461 /* 87 */ "objectname ::= objectname DOT_U PLACENAME",
1462 /* 88 */ "nth ::= NTH CLASSNAME",
1463 /* 89 */ "nth ::= NTH LAST CLASSNAME",
1464 /* 90 */ "nth ::= LAST CLASSNAME",
1465 /* 91 */ "nth ::= LAST",
1466 /* 92 */ "nth ::= NTH LB RB",
1467 /* 93 */ "nth ::= NTH LAST LB RB",
1468 /* 94 */ "nth ::= LAST LB RB",
1469 /* 95 */ "expr ::= expr PLUS expr",
1470 /* 96 */ "expr ::= expr MINUS expr",
1471 /* 97 */ "expr ::= expr STAR expr",
1472 /* 98 */ "expr ::= expr SLASH expr",
1473 /* 99 */ "expr ::= MINUS expr",
1474 /* 100 */ "expr ::= PLUS expr",
1475 /* 101 */ "expr ::= LP expr RP",
1476 /* 102 */ "expr ::= LP FILL|COLOR|THICKNESS RP",
1477 /* 103 */ "expr ::= NUMBER",
1478 /* 104 */ "expr ::= ID",
1479 /* 105 */ "expr ::= FUNC1 LP expr RP",
1480 /* 106 */ "expr ::= FUNC2 LP expr COMMA expr RP",
1481 /* 107 */ "expr ::= DIST LP position COMMA position RP",
1482 /* 108 */ "expr ::= place2 DOT_XY X",
1483 /* 109 */ "expr ::= place2 DOT_XY Y",
1484 /* 110 */ "expr ::= object DOT_L numproperty",
1485 /* 111 */ "expr ::= object DOT_L dashproperty",
1486 /* 112 */ "expr ::= object DOT_L colorproperty",
1487 /* 113 */ "lvalue ::= ID",
1488 /* 114 */ "lvalue ::= FILL",
1489 /* 115 */ "lvalue ::= COLOR",
1490 /* 116 */ "lvalue ::= THICKNESS",
1491 /* 117 */ "rvalue ::= expr",
1492 /* 118 */ "print ::= PRINT",
1493 /* 119 */ "prlist ::= pritem",
1494 /* 120 */ "prlist ::= prlist prsep pritem",
1495 /* 121 */ "direction ::= UP",
1496 /* 122 */ "direction ::= DOWN",
1497 /* 123 */ "direction ::= LEFT",
1498 /* 124 */ "direction ::= RIGHT",
1499 /* 125 */ "optrelexpr ::= relexpr",
1500 /* 126 */ "attribute_list ::= alist",
1501 /* 127 */ "alist ::=",
1502 /* 128 */ "alist ::= alist attribute",
1503 /* 129 */ "attribute ::= boolproperty",
1504 /* 130 */ "attribute ::= WITH withclause",
1505 /* 131 */ "go ::= GO",
1506 /* 132 */ "go ::=",
1507 /* 133 */ "even ::= UNTIL EVEN WITH",
1508 /* 134 */ "even ::= EVEN WITH",
1509 /* 135 */ "dashproperty ::= DOTTED",
1510 /* 136 */ "dashproperty ::= DASHED",
1511 /* 137 */ "colorproperty ::= FILL",
1512 /* 138 */ "colorproperty ::= COLOR",
1513 /* 139 */ "position ::= place",
1514 /* 140 */ "between ::= WAY BETWEEN",
1515 /* 141 */ "between ::= BETWEEN",
1516 /* 142 */ "between ::= OF THE WAY BETWEEN",
1517 /* 143 */ "place ::= place2",
1518 /* 144 */ "edge ::= CENTER",
1519 /* 145 */ "edge ::= EDGEPT",
1520 /* 146 */ "edge ::= TOP",
1521 /* 147 */ "edge ::= BOTTOM",
1522 /* 148 */ "edge ::= START",
1523 /* 149 */ "edge ::= END",
1524 /* 150 */ "edge ::= RIGHT",
1525 /* 151 */ "edge ::= LEFT",
1526 /* 152 */ "object ::= objectname",
 
1527 };
1528 #endif /* NDEBUG */
1529
1530
1531 #if YYSTACKDEPTH<=0
@@ -1647,24 +1665,24 @@
1647 ** Note: during a reduce, the only symbols destroyed are those
1648 ** which appear on the RHS of the rule, but which are *not* used
1649 ** inside the C code.
1650 */
1651 /********* Begin destructor definitions ***************************************/
1652 case 95: /* element_list */
1653 {
1654 #line 468 "pikchr.y"
1655 pik_elist_free(p,(yypminor->yy56));
1656 #line 1681 "pikchr.c"
1657 }
1658 break;
1659 case 96: /* element */
1660 case 97: /* unnamed_element */
1661 case 98: /* basetype */
1662 {
1663 #line 470 "pikchr.y"
1664 pik_elem_free(p,(yypminor->yy226));
1665 #line 1690 "pikchr.c"
1666 }
1667 break;
1668 /********* End destructor definitions *****************************************/
1669 default: break; /* If no destructor action specified: do nothing */
1670 }
@@ -1878,14 +1896,14 @@
1878 #endif
1879 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1880 /* Here code is inserted which will execute if the parser
1881 ** stack every overflows */
1882 /******** Begin %stack_overflow code ******************************************/
1883 #line 502 "pikchr.y"
1884
1885 pik_error(p, 0, "parser stack overflow");
1886 #line 1911 "pikchr.c"
1887 /******** End %stack_overflow code ********************************************/
1888 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1889 pik_parserCTX_STORE
1890 }
1891
@@ -1953,321 +1971,323 @@
1953 }
1954
1955 /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
1956 ** of that rule */
1957 static const YYCODETYPE yyRuleInfoLhs[] = {
1958 117, /* (0) document ::= element_list */
1959 95, /* (1) element_list ::= element */
1960 95, /* (2) element_list ::= element_list EOL element */
1961 96, /* (3) element ::= */
1962 96, /* (4) element ::= direction */
1963 96, /* (5) element ::= lvalue ASSIGN rvalue */
1964 96, /* (6) element ::= PLACENAME COLON unnamed_element */
1965 96, /* (7) element ::= PLACENAME COLON position */
1966 96, /* (8) element ::= unnamed_element */
1967 96, /* (9) element ::= print prlist */
1968 96, /* (10) element ::= ASSERT LP expr EQ expr RP */
1969 96, /* (11) element ::= ASSERT LP position EQ position RP */
1970 112, /* (12) rvalue ::= PLACENAME */
1971 120, /* (13) pritem ::= FILL */
1972 120, /* (14) pritem ::= COLOR */
1973 120, /* (15) pritem ::= THICKNESS */
1974 120, /* (16) pritem ::= rvalue */
1975 120, /* (17) pritem ::= STRING */
1976 121, /* (18) prsep ::= COMMA */
1977 97, /* (19) unnamed_element ::= basetype attribute_list */
1978 98, /* (20) basetype ::= CLASSNAME */
1979 98, /* (21) basetype ::= STRING textposition */
1980 98, /* (22) basetype ::= LB savelist element_list RB */
1981 123, /* (23) savelist ::= */
1982 115, /* (24) relexpr ::= expr */
1983 115, /* (25) relexpr ::= expr PERCENT */
1984 116, /* (26) optrelexpr ::= */
1985 122, /* (27) attribute_list ::= relexpr alist */
1986 125, /* (28) attribute ::= numproperty relexpr */
1987 125, /* (29) attribute ::= dashproperty expr */
1988 125, /* (30) attribute ::= dashproperty */
1989 125, /* (31) attribute ::= colorproperty rvalue */
1990 125, /* (32) attribute ::= go direction optrelexpr */
1991 125, /* (33) attribute ::= go direction even position */
1992 125, /* (34) attribute ::= CLOSE */
1993 125, /* (35) attribute ::= CHOP */
1994 125, /* (36) attribute ::= FROM position */
1995 125, /* (37) attribute ::= TO position */
1996 125, /* (38) attribute ::= THEN */
1997 125, /* (39) attribute ::= THEN optrelexpr HEADING expr */
1998 125, /* (40) attribute ::= THEN optrelexpr EDGEPT */
1999 125, /* (41) attribute ::= GO optrelexpr HEADING expr */
2000 125, /* (42) attribute ::= GO optrelexpr EDGEPT */
2001 125, /* (43) attribute ::= AT position */
2002 125, /* (44) attribute ::= SAME */
2003 125, /* (45) attribute ::= SAME AS object */
2004 125, /* (46) attribute ::= STRING textposition */
2005 125, /* (47) attribute ::= FIT */
2006 125, /* (48) attribute ::= BEHIND object */
2007 128, /* (49) withclause ::= DOT_E edge AT position */
2008 128, /* (50) withclause ::= edge AT position */
2009 100, /* (51) numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2010 127, /* (52) boolproperty ::= CW */
2011 127, /* (53) boolproperty ::= CCW */
2012 127, /* (54) boolproperty ::= LARROW */
2013 127, /* (55) boolproperty ::= RARROW */
2014 127, /* (56) boolproperty ::= LRARROW */
2015 127, /* (57) boolproperty ::= INVIS */
2016 127, /* (58) boolproperty ::= THICK */
2017 127, /* (59) boolproperty ::= THIN */
2018 111, /* (60) textposition ::= */
2019 111, /* (61) textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2020 106, /* (62) position ::= expr COMMA expr */
2021 106, /* (63) position ::= place PLUS expr COMMA expr */
2022 106, /* (64) position ::= place MINUS expr COMMA expr */
2023 106, /* (65) position ::= place PLUS LP expr COMMA expr RP */
2024 106, /* (66) position ::= place MINUS LP expr COMMA expr RP */
2025 106, /* (67) position ::= LP position COMMA position RP */
2026 106, /* (68) position ::= LP position RP */
2027 106, /* (69) position ::= expr between position AND position */
2028 106, /* (70) position ::= expr LT position COMMA position GT */
2029 106, /* (71) position ::= expr ABOVE position */
2030 106, /* (72) position ::= expr BELOW position */
2031 106, /* (73) position ::= expr LEFT OF position */
2032 106, /* (74) position ::= expr RIGHT OF position */
2033 106, /* (75) position ::= expr ON HEADING EDGEPT OF position */
2034 106, /* (76) position ::= expr HEADING EDGEPT OF position */
2035 106, /* (77) position ::= expr EDGEPT OF position */
2036 106, /* (78) position ::= expr ON HEADING expr FROM position */
2037 106, /* (79) position ::= expr HEADING expr FROM position */
2038 107, /* (80) place ::= edge OF object */
2039 130, /* (81) place2 ::= object */
2040 130, /* (82) place2 ::= object DOT_E edge */
2041 130, /* (83) place2 ::= NTH VERTEX OF object */
2042 108, /* (84) object ::= nth */
2043 108, /* (85) object ::= nth OF|IN object */
2044 109, /* (86) objectname ::= PLACENAME */
2045 109, /* (87) objectname ::= objectname DOT_U PLACENAME */
2046 110, /* (88) nth ::= NTH CLASSNAME */
2047 110, /* (89) nth ::= NTH LAST CLASSNAME */
2048 110, /* (90) nth ::= LAST CLASSNAME */
2049 110, /* (91) nth ::= LAST */
2050 110, /* (92) nth ::= NTH LB RB */
2051 110, /* (93) nth ::= NTH LAST LB RB */
2052 110, /* (94) nth ::= LAST LB RB */
2053 99, /* (95) expr ::= expr PLUS expr */
2054 99, /* (96) expr ::= expr MINUS expr */
2055 99, /* (97) expr ::= expr STAR expr */
2056 99, /* (98) expr ::= expr SLASH expr */
2057 99, /* (99) expr ::= MINUS expr */
2058 99, /* (100) expr ::= PLUS expr */
2059 99, /* (101) expr ::= LP expr RP */
2060 99, /* (102) expr ::= LP FILL|COLOR|THICKNESS RP */
2061 99, /* (103) expr ::= NUMBER */
2062 99, /* (104) expr ::= ID */
2063 99, /* (105) expr ::= FUNC1 LP expr RP */
2064 99, /* (106) expr ::= FUNC2 LP expr COMMA expr RP */
2065 99, /* (107) expr ::= DIST LP position COMMA position RP */
2066 99, /* (108) expr ::= place2 DOT_XY X */
2067 99, /* (109) expr ::= place2 DOT_XY Y */
2068 99, /* (110) expr ::= object DOT_L numproperty */
2069 99, /* (111) expr ::= object DOT_L dashproperty */
2070 99, /* (112) expr ::= object DOT_L colorproperty */
2071 113, /* (113) lvalue ::= ID */
2072 113, /* (114) lvalue ::= FILL */
2073 113, /* (115) lvalue ::= COLOR */
2074 113, /* (116) lvalue ::= THICKNESS */
2075 112, /* (117) rvalue ::= expr */
2076 118, /* (118) print ::= PRINT */
2077 119, /* (119) prlist ::= pritem */
2078 119, /* (120) prlist ::= prlist prsep pritem */
2079 102, /* (121) direction ::= UP */
2080 102, /* (122) direction ::= DOWN */
2081 102, /* (123) direction ::= LEFT */
2082 102, /* (124) direction ::= RIGHT */
2083 116, /* (125) optrelexpr ::= relexpr */
2084 122, /* (126) attribute_list ::= alist */
2085 124, /* (127) alist ::= */
2086 124, /* (128) alist ::= alist attribute */
2087 125, /* (129) attribute ::= boolproperty */
2088 125, /* (130) attribute ::= WITH withclause */
2089 126, /* (131) go ::= GO */
2090 126, /* (132) go ::= */
2091 114, /* (133) even ::= UNTIL EVEN WITH */
2092 114, /* (134) even ::= EVEN WITH */
2093 103, /* (135) dashproperty ::= DOTTED */
2094 103, /* (136) dashproperty ::= DASHED */
2095 104, /* (137) colorproperty ::= FILL */
2096 104, /* (138) colorproperty ::= COLOR */
2097 106, /* (139) position ::= place */
2098 129, /* (140) between ::= WAY BETWEEN */
2099 129, /* (141) between ::= BETWEEN */
2100 129, /* (142) between ::= OF THE WAY BETWEEN */
2101 107, /* (143) place ::= place2 */
2102 101, /* (144) edge ::= CENTER */
2103 101, /* (145) edge ::= EDGEPT */
2104 101, /* (146) edge ::= TOP */
2105 101, /* (147) edge ::= BOTTOM */
2106 101, /* (148) edge ::= START */
2107 101, /* (149) edge ::= END */
2108 101, /* (150) edge ::= RIGHT */
2109 101, /* (151) edge ::= LEFT */
2110 108, /* (152) object ::= objectname */
 
2111 };
2112
2113 /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
2114 ** of symbols on the right-hand side of that rule. */
2115 static const signed char yyRuleInfoNRhs[] = {
2116 -1, /* (0) document ::= element_list */
2117 -1, /* (1) element_list ::= element */
2118 -3, /* (2) element_list ::= element_list EOL element */
2119 0, /* (3) element ::= */
2120 -1, /* (4) element ::= direction */
2121 -3, /* (5) element ::= lvalue ASSIGN rvalue */
2122 -3, /* (6) element ::= PLACENAME COLON unnamed_element */
2123 -3, /* (7) element ::= PLACENAME COLON position */
2124 -1, /* (8) element ::= unnamed_element */
2125 -2, /* (9) element ::= print prlist */
2126 -6, /* (10) element ::= ASSERT LP expr EQ expr RP */
2127 -6, /* (11) element ::= ASSERT LP position EQ position RP */
2128 -1, /* (12) rvalue ::= PLACENAME */
2129 -1, /* (13) pritem ::= FILL */
2130 -1, /* (14) pritem ::= COLOR */
2131 -1, /* (15) pritem ::= THICKNESS */
2132 -1, /* (16) pritem ::= rvalue */
2133 -1, /* (17) pritem ::= STRING */
2134 -1, /* (18) prsep ::= COMMA */
2135 -2, /* (19) unnamed_element ::= basetype attribute_list */
2136 -1, /* (20) basetype ::= CLASSNAME */
2137 -2, /* (21) basetype ::= STRING textposition */
2138 -4, /* (22) basetype ::= LB savelist element_list RB */
2139 0, /* (23) savelist ::= */
2140 -1, /* (24) relexpr ::= expr */
2141 -2, /* (25) relexpr ::= expr PERCENT */
2142 0, /* (26) optrelexpr ::= */
2143 -2, /* (27) attribute_list ::= relexpr alist */
2144 -2, /* (28) attribute ::= numproperty relexpr */
2145 -2, /* (29) attribute ::= dashproperty expr */
2146 -1, /* (30) attribute ::= dashproperty */
2147 -2, /* (31) attribute ::= colorproperty rvalue */
2148 -3, /* (32) attribute ::= go direction optrelexpr */
2149 -4, /* (33) attribute ::= go direction even position */
2150 -1, /* (34) attribute ::= CLOSE */
2151 -1, /* (35) attribute ::= CHOP */
2152 -2, /* (36) attribute ::= FROM position */
2153 -2, /* (37) attribute ::= TO position */
2154 -1, /* (38) attribute ::= THEN */
2155 -4, /* (39) attribute ::= THEN optrelexpr HEADING expr */
2156 -3, /* (40) attribute ::= THEN optrelexpr EDGEPT */
2157 -4, /* (41) attribute ::= GO optrelexpr HEADING expr */
2158 -3, /* (42) attribute ::= GO optrelexpr EDGEPT */
2159 -2, /* (43) attribute ::= AT position */
2160 -1, /* (44) attribute ::= SAME */
2161 -3, /* (45) attribute ::= SAME AS object */
2162 -2, /* (46) attribute ::= STRING textposition */
2163 -1, /* (47) attribute ::= FIT */
2164 -2, /* (48) attribute ::= BEHIND object */
2165 -4, /* (49) withclause ::= DOT_E edge AT position */
2166 -3, /* (50) withclause ::= edge AT position */
2167 -1, /* (51) numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2168 -1, /* (52) boolproperty ::= CW */
2169 -1, /* (53) boolproperty ::= CCW */
2170 -1, /* (54) boolproperty ::= LARROW */
2171 -1, /* (55) boolproperty ::= RARROW */
2172 -1, /* (56) boolproperty ::= LRARROW */
2173 -1, /* (57) boolproperty ::= INVIS */
2174 -1, /* (58) boolproperty ::= THICK */
2175 -1, /* (59) boolproperty ::= THIN */
2176 0, /* (60) textposition ::= */
2177 -2, /* (61) textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2178 -3, /* (62) position ::= expr COMMA expr */
2179 -5, /* (63) position ::= place PLUS expr COMMA expr */
2180 -5, /* (64) position ::= place MINUS expr COMMA expr */
2181 -7, /* (65) position ::= place PLUS LP expr COMMA expr RP */
2182 -7, /* (66) position ::= place MINUS LP expr COMMA expr RP */
2183 -5, /* (67) position ::= LP position COMMA position RP */
2184 -3, /* (68) position ::= LP position RP */
2185 -5, /* (69) position ::= expr between position AND position */
2186 -6, /* (70) position ::= expr LT position COMMA position GT */
2187 -3, /* (71) position ::= expr ABOVE position */
2188 -3, /* (72) position ::= expr BELOW position */
2189 -4, /* (73) position ::= expr LEFT OF position */
2190 -4, /* (74) position ::= expr RIGHT OF position */
2191 -6, /* (75) position ::= expr ON HEADING EDGEPT OF position */
2192 -5, /* (76) position ::= expr HEADING EDGEPT OF position */
2193 -4, /* (77) position ::= expr EDGEPT OF position */
2194 -6, /* (78) position ::= expr ON HEADING expr FROM position */
2195 -5, /* (79) position ::= expr HEADING expr FROM position */
2196 -3, /* (80) place ::= edge OF object */
2197 -1, /* (81) place2 ::= object */
2198 -3, /* (82) place2 ::= object DOT_E edge */
2199 -4, /* (83) place2 ::= NTH VERTEX OF object */
2200 -1, /* (84) object ::= nth */
2201 -3, /* (85) object ::= nth OF|IN object */
2202 -1, /* (86) objectname ::= PLACENAME */
2203 -3, /* (87) objectname ::= objectname DOT_U PLACENAME */
2204 -2, /* (88) nth ::= NTH CLASSNAME */
2205 -3, /* (89) nth ::= NTH LAST CLASSNAME */
2206 -2, /* (90) nth ::= LAST CLASSNAME */
2207 -1, /* (91) nth ::= LAST */
2208 -3, /* (92) nth ::= NTH LB RB */
2209 -4, /* (93) nth ::= NTH LAST LB RB */
2210 -3, /* (94) nth ::= LAST LB RB */
2211 -3, /* (95) expr ::= expr PLUS expr */
2212 -3, /* (96) expr ::= expr MINUS expr */
2213 -3, /* (97) expr ::= expr STAR expr */
2214 -3, /* (98) expr ::= expr SLASH expr */
2215 -2, /* (99) expr ::= MINUS expr */
2216 -2, /* (100) expr ::= PLUS expr */
2217 -3, /* (101) expr ::= LP expr RP */
2218 -3, /* (102) expr ::= LP FILL|COLOR|THICKNESS RP */
2219 -1, /* (103) expr ::= NUMBER */
2220 -1, /* (104) expr ::= ID */
2221 -4, /* (105) expr ::= FUNC1 LP expr RP */
2222 -6, /* (106) expr ::= FUNC2 LP expr COMMA expr RP */
2223 -6, /* (107) expr ::= DIST LP position COMMA position RP */
2224 -3, /* (108) expr ::= place2 DOT_XY X */
2225 -3, /* (109) expr ::= place2 DOT_XY Y */
2226 -3, /* (110) expr ::= object DOT_L numproperty */
2227 -3, /* (111) expr ::= object DOT_L dashproperty */
2228 -3, /* (112) expr ::= object DOT_L colorproperty */
2229 -1, /* (113) lvalue ::= ID */
2230 -1, /* (114) lvalue ::= FILL */
2231 -1, /* (115) lvalue ::= COLOR */
2232 -1, /* (116) lvalue ::= THICKNESS */
2233 -1, /* (117) rvalue ::= expr */
2234 -1, /* (118) print ::= PRINT */
2235 -1, /* (119) prlist ::= pritem */
2236 -3, /* (120) prlist ::= prlist prsep pritem */
2237 -1, /* (121) direction ::= UP */
2238 -1, /* (122) direction ::= DOWN */
2239 -1, /* (123) direction ::= LEFT */
2240 -1, /* (124) direction ::= RIGHT */
2241 -1, /* (125) optrelexpr ::= relexpr */
2242 -1, /* (126) attribute_list ::= alist */
2243 0, /* (127) alist ::= */
2244 -2, /* (128) alist ::= alist attribute */
2245 -1, /* (129) attribute ::= boolproperty */
2246 -2, /* (130) attribute ::= WITH withclause */
2247 -1, /* (131) go ::= GO */
2248 0, /* (132) go ::= */
2249 -3, /* (133) even ::= UNTIL EVEN WITH */
2250 -2, /* (134) even ::= EVEN WITH */
2251 -1, /* (135) dashproperty ::= DOTTED */
2252 -1, /* (136) dashproperty ::= DASHED */
2253 -1, /* (137) colorproperty ::= FILL */
2254 -1, /* (138) colorproperty ::= COLOR */
2255 -1, /* (139) position ::= place */
2256 -2, /* (140) between ::= WAY BETWEEN */
2257 -1, /* (141) between ::= BETWEEN */
2258 -4, /* (142) between ::= OF THE WAY BETWEEN */
2259 -1, /* (143) place ::= place2 */
2260 -1, /* (144) edge ::= CENTER */
2261 -1, /* (145) edge ::= EDGEPT */
2262 -1, /* (146) edge ::= TOP */
2263 -1, /* (147) edge ::= BOTTOM */
2264 -1, /* (148) edge ::= START */
2265 -1, /* (149) edge ::= END */
2266 -1, /* (150) edge ::= RIGHT */
2267 -1, /* (151) edge ::= LEFT */
2268 -1, /* (152) object ::= objectname */
 
2269 };
2270
2271 static void yy_accept(yyParser*); /* Forward Declaration */
2272
2273 /*
@@ -2354,647 +2374,652 @@
2354 ** #line <lineno> <thisfile>
2355 ** break;
2356 */
2357 /********** Begin reduce actions **********************************************/
2358 YYMINORTYPE yylhsminor;
2359 case 0: /* document ::= element_list */
2360 #line 506 "pikchr.y"
2361 {pik_render(p,yymsp[0].minor.yy56);}
2362 #line 2387 "pikchr.c"
2363 break;
2364 case 1: /* element_list ::= element */
2365 #line 509 "pikchr.y"
2366 { yylhsminor.yy56 = pik_elist_append(p,0,yymsp[0].minor.yy226); }
2367 #line 2392 "pikchr.c"
2368 yymsp[0].minor.yy56 = yylhsminor.yy56;
2369 break;
2370 case 2: /* element_list ::= element_list EOL element */
2371 #line 511 "pikchr.y"
2372 { yylhsminor.yy56 = pik_elist_append(p,yymsp[-2].minor.yy56,yymsp[0].minor.yy226); }
2373 #line 2398 "pikchr.c"
2374 yymsp[-2].minor.yy56 = yylhsminor.yy56;
2375 break;
2376 case 3: /* element ::= */
2377 #line 514 "pikchr.y"
2378 { yymsp[1].minor.yy226 = 0; }
2379 #line 2404 "pikchr.c"
2380 break;
2381 case 4: /* element ::= direction */
2382 #line 515 "pikchr.y"
2383 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy226=0; }
2384 #line 2409 "pikchr.c"
2385 yymsp[0].minor.yy226 = yylhsminor.yy226;
2386 break;
2387 case 5: /* element ::= lvalue ASSIGN rvalue */
2388 #line 516 "pikchr.y"
2389 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy257,&yymsp[-1].minor.yy0); yylhsminor.yy226=0;}
2390 #line 2415 "pikchr.c"
2391 yymsp[-2].minor.yy226 = yylhsminor.yy226;
2392 break;
2393 case 6: /* element ::= PLACENAME COLON unnamed_element */
2394 #line 518 "pikchr.y"
2395 { yylhsminor.yy226 = yymsp[0].minor.yy226; pik_elem_setname(p,yymsp[0].minor.yy226,&yymsp[-2].minor.yy0); }
2396 #line 2421 "pikchr.c"
2397 yymsp[-2].minor.yy226 = yylhsminor.yy226;
2398 break;
2399 case 7: /* element ::= PLACENAME COLON position */
2400 #line 520 "pikchr.y"
2401 { yylhsminor.yy226 = pik_elem_new(p,0,0,0);
2402 if(yylhsminor.yy226){ yylhsminor.yy226->ptAt = yymsp[0].minor.yy175; pik_elem_setname(p,yylhsminor.yy226,&yymsp[-2].minor.yy0); }}
2403 #line 2428 "pikchr.c"
2404 yymsp[-2].minor.yy226 = yylhsminor.yy226;
2405 break;
2406 case 8: /* element ::= unnamed_element */
2407 #line 522 "pikchr.y"
2408 {yylhsminor.yy226 = yymsp[0].minor.yy226;}
2409 #line 2434 "pikchr.c"
2410 yymsp[0].minor.yy226 = yylhsminor.yy226;
2411 break;
2412 case 9: /* element ::= print prlist */
2413 #line 523 "pikchr.y"
2414 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy226=0;}
2415 #line 2440 "pikchr.c"
2416 break;
2417 case 10: /* element ::= ASSERT LP expr EQ expr RP */
2418 #line 528 "pikchr.y"
2419 {yymsp[-5].minor.yy226=pik_assert(p,yymsp[-3].minor.yy257,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy257);}
2420 #line 2445 "pikchr.c"
2421 break;
2422 case 11: /* element ::= ASSERT LP position EQ position RP */
2423 #line 530 "pikchr.y"
2424 {yymsp[-5].minor.yy226=pik_position_assert(p,&yymsp[-3].minor.yy175,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy175);}
2425 #line 2450 "pikchr.c"
2426 break;
2427 case 12: /* rvalue ::= PLACENAME */
2428 #line 541 "pikchr.y"
2429 {yylhsminor.yy257 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2430 #line 2455 "pikchr.c"
2431 yymsp[0].minor.yy257 = yylhsminor.yy257;
2432 break;
2433 case 13: /* pritem ::= FILL */
2434 case 14: /* pritem ::= COLOR */ yytestcase(yyruleno==14);
2435 case 15: /* pritem ::= THICKNESS */ yytestcase(yyruleno==15);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2436 #line 546 "pikchr.y"
 
 
 
 
 
 
 
 
 
 
 
 
 
2437 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2438 #line 2463 "pikchr.c"
2439 break;
2440 case 16: /* pritem ::= rvalue */
2441 #line 549 "pikchr.y"
2442 {pik_append_num(p,"",yymsp[0].minor.yy257);}
2443 #line 2468 "pikchr.c"
2444 break;
2445 case 17: /* pritem ::= STRING */
2446 #line 550 "pikchr.y"
2447 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2448 #line 2473 "pikchr.c"
2449 break;
2450 case 18: /* prsep ::= COMMA */
2451 #line 551 "pikchr.y"
2452 {pik_append(p, " ", 1);}
2453 #line 2478 "pikchr.c"
2454 break;
2455 case 19: /* unnamed_element ::= basetype attribute_list */
2456 #line 554 "pikchr.y"
2457 {yylhsminor.yy226 = yymsp[-1].minor.yy226; pik_after_adding_attributes(p,yylhsminor.yy226);}
2458 #line 2483 "pikchr.c"
2459 yymsp[-1].minor.yy226 = yylhsminor.yy226;
2460 break;
2461 case 20: /* basetype ::= CLASSNAME */
2462 #line 556 "pikchr.y"
2463 {yylhsminor.yy226 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2464 #line 2489 "pikchr.c"
2465 yymsp[0].minor.yy226 = yylhsminor.yy226;
2466 break;
2467 case 21: /* basetype ::= STRING textposition */
2468 #line 558 "pikchr.y"
2469 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy116; yylhsminor.yy226 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2470 #line 2495 "pikchr.c"
2471 yymsp[-1].minor.yy226 = yylhsminor.yy226;
2472 break;
2473 case 22: /* basetype ::= LB savelist element_list RB */
2474 #line 560 "pikchr.y"
2475 { p->list = yymsp[-2].minor.yy56; yymsp[-3].minor.yy226 = pik_elem_new(p,0,0,yymsp[-1].minor.yy56); if(yymsp[-3].minor.yy226) yymsp[-3].minor.yy226->errTok = yymsp[0].minor.yy0; }
2476 #line 2501 "pikchr.c"
2477 break;
2478 case 23: /* savelist ::= */
2479 #line 565 "pikchr.y"
2480 {yymsp[1].minor.yy56 = p->list; p->list = 0;}
2481 #line 2506 "pikchr.c"
2482 break;
2483 case 24: /* relexpr ::= expr */
2484 #line 572 "pikchr.y"
2485 {yylhsminor.yy164.rAbs = yymsp[0].minor.yy257; yylhsminor.yy164.rRel = 0;}
2486 #line 2511 "pikchr.c"
2487 yymsp[0].minor.yy164 = yylhsminor.yy164;
2488 break;
2489 case 25: /* relexpr ::= expr PERCENT */
2490 #line 573 "pikchr.y"
2491 {yylhsminor.yy164.rAbs = 0; yylhsminor.yy164.rRel = yymsp[-1].minor.yy257/100;}
2492 #line 2517 "pikchr.c"
2493 yymsp[-1].minor.yy164 = yylhsminor.yy164;
2494 break;
2495 case 26: /* optrelexpr ::= */
2496 #line 575 "pikchr.y"
2497 {yymsp[1].minor.yy164.rAbs = 0; yymsp[1].minor.yy164.rRel = 1.0;}
2498 #line 2523 "pikchr.c"
2499 break;
2500 case 27: /* attribute_list ::= relexpr alist */
2501 #line 577 "pikchr.y"
2502 {pik_add_direction(p,0,&yymsp[-1].minor.yy164);}
2503 #line 2528 "pikchr.c"
2504 break;
2505 case 28: /* attribute ::= numproperty relexpr */
2506 #line 581 "pikchr.y"
2507 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy164); }
2508 #line 2533 "pikchr.c"
2509 break;
2510 case 29: /* attribute ::= dashproperty expr */
2511 #line 582 "pikchr.y"
2512 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy257); }
2513 #line 2538 "pikchr.c"
2514 break;
2515 case 30: /* attribute ::= dashproperty */
2516 #line 583 "pikchr.y"
2517 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2518 #line 2543 "pikchr.c"
2519 break;
2520 case 31: /* attribute ::= colorproperty rvalue */
2521 #line 584 "pikchr.y"
2522 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy257); }
 
 
2523 #line 2548 "pikchr.c"
2524 break;
2525 case 32: /* attribute ::= go direction optrelexpr */
2526 #line 585 "pikchr.y"
2527 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy164);}
2528 #line 2553 "pikchr.c"
2529 break;
2530 case 33: /* attribute ::= go direction even position */
2531 #line 586 "pikchr.y"
2532 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy175);}
2533 #line 2558 "pikchr.c"
2534 break;
2535 case 34: /* attribute ::= CLOSE */
2536 #line 587 "pikchr.y"
2537 { pik_close_path(p,&yymsp[0].minor.yy0); }
2538 #line 2563 "pikchr.c"
2539 break;
2540 case 35: /* attribute ::= CHOP */
2541 #line 588 "pikchr.y"
2542 { p->cur->bChop = 1; }
2543 #line 2568 "pikchr.c"
2544 break;
2545 case 36: /* attribute ::= FROM position */
2546 #line 589 "pikchr.y"
2547 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy175); }
2548 #line 2573 "pikchr.c"
2549 break;
2550 case 37: /* attribute ::= TO position */
2551 #line 590 "pikchr.y"
2552 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy175); }
2553 #line 2578 "pikchr.c"
2554 break;
2555 case 38: /* attribute ::= THEN */
2556 #line 591 "pikchr.y"
2557 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2558 #line 2583 "pikchr.c"
2559 break;
2560 case 39: /* attribute ::= THEN optrelexpr HEADING expr */
2561 case 41: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==41);
2562 #line 593 "pikchr.y"
2563 {pik_move_hdg(p,&yymsp[-2].minor.yy164,&yymsp[-1].minor.yy0,yymsp[0].minor.yy257,0,&yymsp[-3].minor.yy0);}
2564 #line 2589 "pikchr.c"
2565 break;
2566 case 40: /* attribute ::= THEN optrelexpr EDGEPT */
2567 case 42: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==42);
2568 #line 594 "pikchr.y"
2569 {pik_move_hdg(p,&yymsp[-1].minor.yy164,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2570 #line 2595 "pikchr.c"
2571 break;
2572 case 43: /* attribute ::= AT position */
2573 #line 599 "pikchr.y"
2574 { pik_set_at(p,0,&yymsp[0].minor.yy175,&yymsp[-1].minor.yy0); }
2575 #line 2600 "pikchr.c"
2576 break;
2577 case 44: /* attribute ::= SAME */
2578 #line 601 "pikchr.y"
2579 {pik_same(p,0,&yymsp[0].minor.yy0);}
2580 #line 2605 "pikchr.c"
2581 break;
2582 case 45: /* attribute ::= SAME AS object */
2583 #line 602 "pikchr.y"
2584 {pik_same(p,yymsp[0].minor.yy226,&yymsp[-2].minor.yy0);}
2585 #line 2610 "pikchr.c"
2586 break;
2587 case 46: /* attribute ::= STRING textposition */
2588 #line 603 "pikchr.y"
2589 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy116);}
2590 #line 2615 "pikchr.c"
2591 break;
2592 case 47: /* attribute ::= FIT */
2593 #line 604 "pikchr.y"
2594 {pik_size_to_fit(p,&yymsp[0].minor.yy0); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2595 #line 2620 "pikchr.c"
2596 break;
2597 case 48: /* attribute ::= BEHIND object */
2598 #line 605 "pikchr.y"
2599 {pik_behind(p,yymsp[0].minor.yy226);}
2600 #line 2625 "pikchr.c"
2601 break;
2602 case 49: /* withclause ::= DOT_E edge AT position */
2603 case 50: /* withclause ::= edge AT position */ yytestcase(yyruleno==50);
2604 #line 613 "pikchr.y"
2605 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy175,&yymsp[-1].minor.yy0); }
2606 #line 2631 "pikchr.c"
2607 break;
2608 case 51: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2609 #line 617 "pikchr.y"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2610 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2611 #line 2636 "pikchr.c"
2612 yymsp[0].minor.yy0 = yylhsminor.yy0;
2613 break;
2614 case 52: /* boolproperty ::= CW */
2615 #line 628 "pikchr.y"
2616 {p->cur->cw = 1;}
2617 #line 2642 "pikchr.c"
2618 break;
2619 case 53: /* boolproperty ::= CCW */
2620 #line 629 "pikchr.y"
2621 {p->cur->cw = 0;}
2622 #line 2647 "pikchr.c"
2623 break;
2624 case 54: /* boolproperty ::= LARROW */
2625 #line 630 "pikchr.y"
2626 {p->cur->larrow=1; p->cur->rarrow=0; }
2627 #line 2652 "pikchr.c"
2628 break;
2629 case 55: /* boolproperty ::= RARROW */
2630 #line 631 "pikchr.y"
2631 {p->cur->larrow=0; p->cur->rarrow=1; }
2632 #line 2657 "pikchr.c"
2633 break;
2634 case 56: /* boolproperty ::= LRARROW */
2635 #line 632 "pikchr.y"
2636 {p->cur->larrow=1; p->cur->rarrow=1; }
2637 #line 2662 "pikchr.c"
2638 break;
2639 case 57: /* boolproperty ::= INVIS */
2640 #line 633 "pikchr.y"
2641 {p->cur->sw = 0.0;}
2642 #line 2667 "pikchr.c"
2643 break;
2644 case 58: /* boolproperty ::= THICK */
2645 #line 634 "pikchr.y"
2646 {p->cur->sw *= 1.5;}
2647 #line 2672 "pikchr.c"
2648 break;
2649 case 59: /* boolproperty ::= THIN */
2650 #line 635 "pikchr.y"
2651 {p->cur->sw *= 0.67;}
2652 #line 2677 "pikchr.c"
2653 break;
2654 case 60: /* textposition ::= */
2655 #line 637 "pikchr.y"
2656 {yymsp[1].minor.yy116 = 0;}
2657 #line 2682 "pikchr.c"
2658 break;
2659 case 61: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2660 #line 640 "pikchr.y"
2661 {yylhsminor.yy116 = pik_text_position(yymsp[-1].minor.yy116,&yymsp[0].minor.yy0);}
2662 #line 2687 "pikchr.c"
2663 yymsp[-1].minor.yy116 = yylhsminor.yy116;
2664 break;
2665 case 62: /* position ::= expr COMMA expr */
2666 #line 643 "pikchr.y"
2667 {yylhsminor.yy175.x=yymsp[-2].minor.yy257; yylhsminor.yy175.y=yymsp[0].minor.yy257;}
2668 #line 2693 "pikchr.c"
2669 yymsp[-2].minor.yy175 = yylhsminor.yy175;
2670 break;
2671 case 63: /* position ::= place PLUS expr COMMA expr */
2672 #line 645 "pikchr.y"
2673 {yylhsminor.yy175.x=yymsp[-4].minor.yy175.x+yymsp[-2].minor.yy257; yylhsminor.yy175.y=yymsp[-4].minor.yy175.y+yymsp[0].minor.yy257;}
2674 #line 2699 "pikchr.c"
2675 yymsp[-4].minor.yy175 = yylhsminor.yy175;
2676 break;
2677 case 64: /* position ::= place MINUS expr COMMA expr */
2678 #line 646 "pikchr.y"
2679 {yylhsminor.yy175.x=yymsp[-4].minor.yy175.x-yymsp[-2].minor.yy257; yylhsminor.yy175.y=yymsp[-4].minor.yy175.y-yymsp[0].minor.yy257;}
2680 #line 2705 "pikchr.c"
2681 yymsp[-4].minor.yy175 = yylhsminor.yy175;
2682 break;
2683 case 65: /* position ::= place PLUS LP expr COMMA expr RP */
2684 #line 648 "pikchr.y"
2685 {yylhsminor.yy175.x=yymsp[-6].minor.yy175.x+yymsp[-3].minor.yy257; yylhsminor.yy175.y=yymsp[-6].minor.yy175.y+yymsp[-1].minor.yy257;}
2686 #line 2711 "pikchr.c"
2687 yymsp[-6].minor.yy175 = yylhsminor.yy175;
2688 break;
2689 case 66: /* position ::= place MINUS LP expr COMMA expr RP */
2690 #line 650 "pikchr.y"
2691 {yylhsminor.yy175.x=yymsp[-6].minor.yy175.x-yymsp[-3].minor.yy257; yylhsminor.yy175.y=yymsp[-6].minor.yy175.y-yymsp[-1].minor.yy257;}
2692 #line 2717 "pikchr.c"
2693 yymsp[-6].minor.yy175 = yylhsminor.yy175;
2694 break;
2695 case 67: /* position ::= LP position COMMA position RP */
2696 #line 651 "pikchr.y"
2697 {yymsp[-4].minor.yy175.x=yymsp[-3].minor.yy175.x; yymsp[-4].minor.yy175.y=yymsp[-1].minor.yy175.y;}
2698 #line 2723 "pikchr.c"
2699 break;
2700 case 68: /* position ::= LP position RP */
2701 #line 652 "pikchr.y"
2702 {yymsp[-2].minor.yy175=yymsp[-1].minor.yy175;}
2703 #line 2728 "pikchr.c"
2704 break;
2705 case 69: /* position ::= expr between position AND position */
2706 #line 654 "pikchr.y"
2707 {yylhsminor.yy175 = pik_position_between(yymsp[-4].minor.yy257,yymsp[-2].minor.yy175,yymsp[0].minor.yy175);}
2708 #line 2733 "pikchr.c"
2709 yymsp[-4].minor.yy175 = yylhsminor.yy175;
2710 break;
2711 case 70: /* position ::= expr LT position COMMA position GT */
2712 #line 656 "pikchr.y"
2713 {yylhsminor.yy175 = pik_position_between(yymsp[-5].minor.yy257,yymsp[-3].minor.yy175,yymsp[-1].minor.yy175);}
2714 #line 2739 "pikchr.c"
2715 yymsp[-5].minor.yy175 = yylhsminor.yy175;
2716 break;
2717 case 71: /* position ::= expr ABOVE position */
2718 #line 657 "pikchr.y"
2719 {yylhsminor.yy175=yymsp[0].minor.yy175; yylhsminor.yy175.y += yymsp[-2].minor.yy257;}
2720 #line 2745 "pikchr.c"
2721 yymsp[-2].minor.yy175 = yylhsminor.yy175;
2722 break;
2723 case 72: /* position ::= expr BELOW position */
2724 #line 658 "pikchr.y"
2725 {yylhsminor.yy175=yymsp[0].minor.yy175; yylhsminor.yy175.y -= yymsp[-2].minor.yy257;}
2726 #line 2751 "pikchr.c"
2727 yymsp[-2].minor.yy175 = yylhsminor.yy175;
2728 break;
2729 case 73: /* position ::= expr LEFT OF position */
2730 #line 659 "pikchr.y"
2731 {yylhsminor.yy175=yymsp[0].minor.yy175; yylhsminor.yy175.x -= yymsp[-3].minor.yy257;}
2732 #line 2757 "pikchr.c"
2733 yymsp[-3].minor.yy175 = yylhsminor.yy175;
2734 break;
2735 case 74: /* position ::= expr RIGHT OF position */
2736 #line 660 "pikchr.y"
2737 {yylhsminor.yy175=yymsp[0].minor.yy175; yylhsminor.yy175.x += yymsp[-3].minor.yy257;}
2738 #line 2763 "pikchr.c"
2739 yymsp[-3].minor.yy175 = yylhsminor.yy175;
2740 break;
2741 case 75: /* position ::= expr ON HEADING EDGEPT OF position */
2742 #line 662 "pikchr.y"
2743 {yylhsminor.yy175 = pik_position_at_hdg(yymsp[-5].minor.yy257,&yymsp[-2].minor.yy0,yymsp[0].minor.yy175);}
2744 #line 2769 "pikchr.c"
2745 yymsp[-5].minor.yy175 = yylhsminor.yy175;
2746 break;
2747 case 76: /* position ::= expr HEADING EDGEPT OF position */
2748 #line 664 "pikchr.y"
2749 {yylhsminor.yy175 = pik_position_at_hdg(yymsp[-4].minor.yy257,&yymsp[-2].minor.yy0,yymsp[0].minor.yy175);}
2750 #line 2775 "pikchr.c"
2751 yymsp[-4].minor.yy175 = yylhsminor.yy175;
2752 break;
2753 case 77: /* position ::= expr EDGEPT OF position */
2754 #line 666 "pikchr.y"
2755 {yylhsminor.yy175 = pik_position_at_hdg(yymsp[-3].minor.yy257,&yymsp[-2].minor.yy0,yymsp[0].minor.yy175);}
2756 #line 2781 "pikchr.c"
2757 yymsp[-3].minor.yy175 = yylhsminor.yy175;
 
 
 
 
 
2758 break;
2759 case 78: /* position ::= expr ON HEADING expr FROM position */
2760 #line 668 "pikchr.y"
2761 {yylhsminor.yy175 = pik_position_at_angle(yymsp[-5].minor.yy257,yymsp[-2].minor.yy257,yymsp[0].minor.yy175);}
2762 #line 2787 "pikchr.c"
2763 yymsp[-5].minor.yy175 = yylhsminor.yy175;
2764 break;
2765 case 79: /* position ::= expr HEADING expr FROM position */
2766 #line 670 "pikchr.y"
2767 {yylhsminor.yy175 = pik_position_at_angle(yymsp[-4].minor.yy257,yymsp[-2].minor.yy257,yymsp[0].minor.yy175);}
2768 #line 2793 "pikchr.c"
2769 yymsp[-4].minor.yy175 = yylhsminor.yy175;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2770 break;
2771 case 80: /* place ::= edge OF object */
2772 #line 682 "pikchr.y"
2773 {yylhsminor.yy175 = pik_place_of_elem(p,yymsp[0].minor.yy226,&yymsp[-2].minor.yy0);}
2774 #line 2799 "pikchr.c"
2775 yymsp[-2].minor.yy175 = yylhsminor.yy175;
2776 break;
2777 case 81: /* place2 ::= object */
2778 #line 683 "pikchr.y"
2779 {yylhsminor.yy175 = pik_place_of_elem(p,yymsp[0].minor.yy226,0);}
2780 #line 2805 "pikchr.c"
2781 yymsp[0].minor.yy175 = yylhsminor.yy175;
2782 break;
2783 case 82: /* place2 ::= object DOT_E edge */
2784 #line 684 "pikchr.y"
2785 {yylhsminor.yy175 = pik_place_of_elem(p,yymsp[-2].minor.yy226,&yymsp[0].minor.yy0);}
2786 #line 2811 "pikchr.c"
2787 yymsp[-2].minor.yy175 = yylhsminor.yy175;
2788 break;
2789 case 83: /* place2 ::= NTH VERTEX OF object */
2790 #line 685 "pikchr.y"
2791 {yylhsminor.yy175 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy226);}
2792 #line 2817 "pikchr.c"
2793 yymsp[-3].minor.yy175 = yylhsminor.yy175;
2794 break;
2795 case 84: /* object ::= nth */
2796 #line 697 "pikchr.y"
2797 {yylhsminor.yy226 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2798 #line 2823 "pikchr.c"
2799 yymsp[0].minor.yy226 = yylhsminor.yy226;
2800 break;
2801 case 85: /* object ::= nth OF|IN object */
2802 #line 698 "pikchr.y"
2803 {yylhsminor.yy226 = pik_find_nth(p,yymsp[0].minor.yy226,&yymsp[-2].minor.yy0);}
2804 #line 2829 "pikchr.c"
2805 yymsp[-2].minor.yy226 = yylhsminor.yy226;
 
 
 
 
 
 
2806 break;
2807 case 86: /* objectname ::= PLACENAME */
2808 #line 700 "pikchr.y"
2809 {yylhsminor.yy226 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2810 #line 2835 "pikchr.c"
2811 yymsp[0].minor.yy226 = yylhsminor.yy226;
2812 break;
2813 case 87: /* objectname ::= objectname DOT_U PLACENAME */
2814 #line 702 "pikchr.y"
2815 {yylhsminor.yy226 = pik_find_byname(p,yymsp[-2].minor.yy226,&yymsp[0].minor.yy0);}
2816 #line 2841 "pikchr.c"
2817 yymsp[-2].minor.yy226 = yylhsminor.yy226;
2818 break;
2819 case 88: /* nth ::= NTH CLASSNAME */
2820 #line 704 "pikchr.y"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2821 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2822 #line 2847 "pikchr.c"
2823 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2824 break;
2825 case 89: /* nth ::= NTH LAST CLASSNAME */
2826 #line 705 "pikchr.y"
2827 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2828 #line 2853 "pikchr.c"
2829 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2830 break;
2831 case 90: /* nth ::= LAST CLASSNAME */
2832 #line 706 "pikchr.y"
2833 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2834 #line 2859 "pikchr.c"
2835 break;
2836 case 91: /* nth ::= LAST */
2837 #line 707 "pikchr.y"
2838 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2839 #line 2864 "pikchr.c"
2840 yymsp[0].minor.yy0 = yylhsminor.yy0;
2841 break;
2842 case 92: /* nth ::= NTH LB RB */
2843 #line 708 "pikchr.y"
2844 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2845 #line 2870 "pikchr.c"
2846 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2847 break;
2848 case 93: /* nth ::= NTH LAST LB RB */
2849 #line 709 "pikchr.y"
2850 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2851 #line 2876 "pikchr.c"
2852 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2853 break;
2854 case 94: /* nth ::= LAST LB RB */
2855 #line 710 "pikchr.y"
2856 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2857 #line 2882 "pikchr.c"
2858 break;
2859 case 95: /* expr ::= expr PLUS expr */
2860 #line 712 "pikchr.y"
2861 {yylhsminor.yy257=yymsp[-2].minor.yy257+yymsp[0].minor.yy257;}
2862 #line 2887 "pikchr.c"
2863 yymsp[-2].minor.yy257 = yylhsminor.yy257;
2864 break;
2865 case 96: /* expr ::= expr MINUS expr */
2866 #line 713 "pikchr.y"
2867 {yylhsminor.yy257=yymsp[-2].minor.yy257-yymsp[0].minor.yy257;}
2868 #line 2893 "pikchr.c"
2869 yymsp[-2].minor.yy257 = yylhsminor.yy257;
2870 break;
2871 case 97: /* expr ::= expr STAR expr */
2872 #line 714 "pikchr.y"
2873 {yylhsminor.yy257=yymsp[-2].minor.yy257*yymsp[0].minor.yy257;}
2874 #line 2899 "pikchr.c"
2875 yymsp[-2].minor.yy257 = yylhsminor.yy257;
2876 break;
2877 case 98: /* expr ::= expr SLASH expr */
2878 #line 715 "pikchr.y"
2879 {
2880 if( yymsp[0].minor.yy257==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy257 = 0.0; }
2881 else{ yylhsminor.yy257 = yymsp[-2].minor.yy257/yymsp[0].minor.yy257; }
2882 }
2883 #line 2908 "pikchr.c"
2884 yymsp[-2].minor.yy257 = yylhsminor.yy257;
2885 break;
2886 case 99: /* expr ::= MINUS expr */
2887 #line 719 "pikchr.y"
2888 {yymsp[-1].minor.yy257=-yymsp[0].minor.yy257;}
2889 #line 2914 "pikchr.c"
2890 break;
2891 case 100: /* expr ::= PLUS expr */
2892 #line 720 "pikchr.y"
2893 {yymsp[-1].minor.yy257=yymsp[0].minor.yy257;}
2894 #line 2919 "pikchr.c"
2895 break;
2896 case 101: /* expr ::= LP expr RP */
2897 #line 721 "pikchr.y"
2898 {yymsp[-2].minor.yy257=yymsp[-1].minor.yy257;}
2899 #line 2924 "pikchr.c"
2900 break;
2901 case 102: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2902 #line 722 "pikchr.y"
2903 {yymsp[-2].minor.yy257=pik_get_var(p,&yymsp[-1].minor.yy0);}
2904 #line 2929 "pikchr.c"
2905 break;
2906 case 103: /* expr ::= NUMBER */
2907 #line 723 "pikchr.y"
2908 {yylhsminor.yy257=pik_atof(&yymsp[0].minor.yy0);}
2909 #line 2934 "pikchr.c"
2910 yymsp[0].minor.yy257 = yylhsminor.yy257;
2911 break;
2912 case 104: /* expr ::= ID */
2913 #line 724 "pikchr.y"
2914 {yylhsminor.yy257=pik_get_var(p,&yymsp[0].minor.yy0);}
2915 #line 2940 "pikchr.c"
2916 yymsp[0].minor.yy257 = yylhsminor.yy257;
2917 break;
2918 case 105: /* expr ::= FUNC1 LP expr RP */
2919 #line 725 "pikchr.y"
2920 {yylhsminor.yy257 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy257,0.0);}
2921 #line 2946 "pikchr.c"
2922 yymsp[-3].minor.yy257 = yylhsminor.yy257;
2923 break;
2924 case 106: /* expr ::= FUNC2 LP expr COMMA expr RP */
2925 #line 726 "pikchr.y"
2926 {yylhsminor.yy257 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy257,yymsp[-1].minor.yy257);}
2927 #line 2952 "pikchr.c"
2928 yymsp[-5].minor.yy257 = yylhsminor.yy257;
2929 break;
2930 case 107: /* expr ::= DIST LP position COMMA position RP */
2931 #line 727 "pikchr.y"
2932 {yymsp[-5].minor.yy257 = pik_dist(&yymsp[-3].minor.yy175,&yymsp[-1].minor.yy175);}
2933 #line 2958 "pikchr.c"
2934 break;
2935 case 108: /* expr ::= place2 DOT_XY X */
2936 #line 728 "pikchr.y"
2937 {yylhsminor.yy257 = yymsp[-2].minor.yy175.x;}
2938 #line 2963 "pikchr.c"
2939 yymsp[-2].minor.yy257 = yylhsminor.yy257;
2940 break;
2941 case 109: /* expr ::= place2 DOT_XY Y */
2942 #line 729 "pikchr.y"
2943 {yylhsminor.yy257 = yymsp[-2].minor.yy175.y;}
2944 #line 2969 "pikchr.c"
2945 yymsp[-2].minor.yy257 = yylhsminor.yy257;
2946 break;
2947 case 110: /* expr ::= object DOT_L numproperty */
2948 case 111: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==111);
2949 case 112: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==112);
2950 #line 730 "pikchr.y"
2951 {yylhsminor.yy257=pik_property_of(yymsp[-2].minor.yy226,&yymsp[0].minor.yy0);}
2952 #line 2977 "pikchr.c"
2953 yymsp[-2].minor.yy257 = yylhsminor.yy257;
2954 break;
2955 default:
2956 /* (113) lvalue ::= ID */ yytestcase(yyruleno==113);
2957 /* (114) lvalue ::= FILL */ yytestcase(yyruleno==114);
2958 /* (115) lvalue ::= COLOR */ yytestcase(yyruleno==115);
2959 /* (116) lvalue ::= THICKNESS */ yytestcase(yyruleno==116);
2960 /* (117) rvalue ::= expr */ yytestcase(yyruleno==117);
2961 /* (118) print ::= PRINT */ yytestcase(yyruleno==118);
2962 /* (119) prlist ::= pritem (OPTIMIZED OUT) */ assert(yyruleno!=119);
2963 /* (120) prlist ::= prlist prsep pritem */ yytestcase(yyruleno==120);
2964 /* (121) direction ::= UP */ yytestcase(yyruleno==121);
2965 /* (122) direction ::= DOWN */ yytestcase(yyruleno==122);
2966 /* (123) direction ::= LEFT */ yytestcase(yyruleno==123);
2967 /* (124) direction ::= RIGHT */ yytestcase(yyruleno==124);
2968 /* (125) optrelexpr ::= relexpr (OPTIMIZED OUT) */ assert(yyruleno!=125);
2969 /* (126) attribute_list ::= alist */ yytestcase(yyruleno==126);
2970 /* (127) alist ::= */ yytestcase(yyruleno==127);
2971 /* (128) alist ::= alist attribute */ yytestcase(yyruleno==128);
2972 /* (129) attribute ::= boolproperty (OPTIMIZED OUT) */ assert(yyruleno!=129);
2973 /* (130) attribute ::= WITH withclause */ yytestcase(yyruleno==130);
2974 /* (131) go ::= GO */ yytestcase(yyruleno==131);
2975 /* (132) go ::= */ yytestcase(yyruleno==132);
2976 /* (133) even ::= UNTIL EVEN WITH */ yytestcase(yyruleno==133);
2977 /* (134) even ::= EVEN WITH */ yytestcase(yyruleno==134);
2978 /* (135) dashproperty ::= DOTTED */ yytestcase(yyruleno==135);
2979 /* (136) dashproperty ::= DASHED */ yytestcase(yyruleno==136);
2980 /* (137) colorproperty ::= FILL */ yytestcase(yyruleno==137);
2981 /* (138) colorproperty ::= COLOR */ yytestcase(yyruleno==138);
2982 /* (139) position ::= place */ yytestcase(yyruleno==139);
2983 /* (140) between ::= WAY BETWEEN */ yytestcase(yyruleno==140);
2984 /* (141) between ::= BETWEEN */ yytestcase(yyruleno==141);
2985 /* (142) between ::= OF THE WAY BETWEEN */ yytestcase(yyruleno==142);
2986 /* (143) place ::= place2 */ yytestcase(yyruleno==143);
2987 /* (144) edge ::= CENTER */ yytestcase(yyruleno==144);
2988 /* (145) edge ::= EDGEPT */ yytestcase(yyruleno==145);
2989 /* (146) edge ::= TOP */ yytestcase(yyruleno==146);
2990 /* (147) edge ::= BOTTOM */ yytestcase(yyruleno==147);
2991 /* (148) edge ::= START */ yytestcase(yyruleno==148);
2992 /* (149) edge ::= END */ yytestcase(yyruleno==149);
2993 /* (150) edge ::= RIGHT */ yytestcase(yyruleno==150);
2994 /* (151) edge ::= LEFT */ yytestcase(yyruleno==151);
2995 /* (152) object ::= objectname */ yytestcase(yyruleno==152);
2996 break;
2997 /********** End reduce actions ************************************************/
2998 };
2999 assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
3000 yygoto = yyRuleInfoLhs[yyruleno];
@@ -3050,19 +3075,19 @@
3050 ){
3051 pik_parserARG_FETCH
3052 pik_parserCTX_FETCH
3053 #define TOKEN yyminor
3054 /************ Begin %syntax_error code ****************************************/
3055 #line 494 "pikchr.y"
3056
3057 if( TOKEN.z && TOKEN.z[0] ){
3058 pik_error(p, &TOKEN, "syntax error");
3059 }else{
3060 pik_error(p, 0, "syntax error");
3061 }
3062 UNUSED_PARAMETER(yymajor);
3063 #line 3088 "pikchr.c"
3064 /************ End %syntax_error code ******************************************/
3065 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3066 pik_parserCTX_STORE
3067 }
3068
@@ -3291,11 +3316,11 @@
3291 #else
3292 (void)iToken;
3293 return 0;
3294 #endif
3295 }
3296 #line 735 "pikchr.y"
3297
3298
3299
3300 /* Chart of the 140 official HTML color names with their
3301 ** corresponding RGB value.
@@ -3497,13 +3522,13 @@
3497 { "thickness", 0.015 },
3498 };
3499
3500
3501 /* Methods for the "arc" class */
3502 static void arcInit(Pik *p, PElem *pElem){
3503 pElem->w = pik_value(p, "arcrad",6,0);
3504 pElem->h = pElem->w;
3505 }
3506 /* Hack: Arcs are here rendered as quadratic Bezier curves rather
3507 ** than true arcs. Multiple reasons: (1) the legacy-PIC parameters
3508 ** that control arcs are obscure and I could not figure out what they
3509 ** mean based on available documentation. (2) Arcs are rarely used,
@@ -3523,65 +3548,65 @@
3523 m.x += 0.5*rScale*dy;
3524 m.y -= 0.5*rScale*dx;
3525 }
3526 return m;
3527 }
3528 static void arcCheck(Pik *p, PElem *pElem){
3529 PPoint m;
3530 if( p->nTPath>2 ){
3531 pik_error(p, &pElem->errTok, "arc geometry error");
3532 return;
3533 }
3534 m = arcControlPoint(pElem->cw, p->aTPath[0], p->aTPath[1], 0.5);
3535 pik_bbox_add_xy(&pElem->bbox, m.x, m.y);
3536 }
3537 static void arcRender(Pik *p, PElem *pElem){
3538 PPoint f, m, t;
3539 if( pElem->nPath<2 ) return;
3540 if( pElem->sw<=0.0 ) return;
3541 f = pElem->aPath[0];
3542 t = pElem->aPath[1];
3543 m = arcControlPoint(pElem->cw,f,t,1.0);
3544 if( pElem->larrow ){
3545 pik_draw_arrowhead(p,&m,&f,pElem);
3546 }
3547 if( pElem->rarrow ){
3548 pik_draw_arrowhead(p,&m,&t,pElem);
3549 }
3550 pik_append_xy(p,"<path d=\"M", f.x, f.y);
3551 pik_append_xy(p,"Q", m.x, m.y);
3552 pik_append_xy(p," ", t.x, t.y);
3553 pik_append(p,"\" ",2);
3554 pik_append_style(p,pElem,0);
3555 pik_append(p,"\" />\n", -1);
3556
3557 pik_append_txt(p, pElem, 0);
3558 }
3559
3560
3561 /* Methods for the "arrow" class */
3562 static void arrowInit(Pik *p, PElem *pElem){
3563 pElem->w = pik_value(p, "linewid",7,0);
3564 pElem->h = pik_value(p, "lineht",6,0);
3565 pElem->rad = pik_value(p, "linerad",7,0);
3566 pElem->fill = -1.0;
3567 pElem->rarrow = 1;
3568 }
3569
3570 /* Methods for the "box" class */
3571 static void boxInit(Pik *p, PElem *pElem){
3572 pElem->w = pik_value(p, "boxwid",6,0);
3573 pElem->h = pik_value(p, "boxht",5,0);
3574 pElem->rad = pik_value(p, "boxrad",6,0);
3575 }
3576 /* Return offset from the center of the box to the compass point
3577 ** given by parameter cp */
3578 static PPoint boxOffset(Pik *p, PElem *pElem, int cp){
3579 PPoint pt = cZeroPoint;
3580 PNum w2 = 0.5*pElem->w;
3581 PNum h2 = 0.5*pElem->h;
3582 PNum rad = pElem->rad;
3583 PNum rx;
3584 if( rad<=0.0 ){
3585 rx = 0.0;
3586 }else{
3587 if( rad>w2 ) rad = w2;
@@ -3601,18 +3626,18 @@
3601 default: assert(0);
3602 }
3603 UNUSED_PARAMETER(p);
3604 return pt;
3605 }
3606 static PPoint boxChop(Pik *p, PElem *pElem, PPoint *pPt){
3607 PNum dx, dy;
3608 int cp = CP_C;
3609 PPoint chop = pElem->ptAt;
3610 if( pElem->w<=0.0 ) return chop;
3611 if( pElem->h<=0.0 ) return chop;
3612 dx = (pPt->x - pElem->ptAt.x)*pElem->h/pElem->w;
3613 dy = (pPt->y - pElem->ptAt.y);
3614 if( dx>0.0 ){
3615 if( dy>=2.414*dx ){
3616 cp = CP_N;
3617 }else if( dy>=0.414*dx ){
3618 cp = CP_NE;
@@ -3634,26 +3659,26 @@
3634 cp = CP_SW;
3635 }else{
3636 cp = CP_S;
3637 }
3638 }
3639 chop = pElem->type->xOffset(p,pElem,cp);
3640 chop.x += pElem->ptAt.x;
3641 chop.y += pElem->ptAt.y;
3642 return chop;
3643 }
3644 static void boxFit(Pik *p, PElem *pElem, PNum w, PNum h){
3645 if( w>0 ) pElem->w = w;
3646 if( h>0 ) pElem->h = h;
3647 UNUSED_PARAMETER(p);
3648 }
3649 static void boxRender(Pik *p, PElem *pElem){
3650 PNum w2 = 0.5*pElem->w;
3651 PNum h2 = 0.5*pElem->h;
3652 PNum rad = pElem->rad;
3653 PPoint pt = pElem->ptAt;
3654 if( pElem->sw>0.0 ){
3655 if( rad<=0.0 ){
3656 pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y-h2);
3657 pik_append_xy(p,"L", pt.x+w2,pt.y-h2);
3658 pik_append_xy(p,"L", pt.x+w2,pt.y+h2);
3659 pik_append_xy(p,"L", pt.x-w2,pt.y+h2);
@@ -3692,112 +3717,112 @@
3692 pik_append_arc(p, rad, rad, x0, y2);
3693 if( y2>y1 ) pik_append_xy(p, "L", x0, y1);
3694 pik_append_arc(p, rad, rad, x1, y0);
3695 pik_append(p,"Z\" ",-1);
3696 }
3697 pik_append_style(p,pElem,1);
3698 pik_append(p,"\" />\n", -1);
3699 }
3700 pik_append_txt(p, pElem, 0);
3701 }
3702
3703 /* Methods for the "circle" class */
3704 static void circleInit(Pik *p, PElem *pElem){
3705 pElem->w = pik_value(p, "circlerad",9,0)*2;
3706 pElem->h = pElem->w;
3707 pElem->rad = 0.5*pElem->w;
3708 }
3709 static void circleNumProp(Pik *p, PElem *pElem, PToken *pId){
3710 /* For a circle, the width must equal the height and both must
3711 ** be twice the radius. Enforce those constraints. */
3712 switch( pId->eType ){
3713 case T_RADIUS:
3714 pElem->w = pElem->h = 2.0*pElem->rad;
3715 break;
3716 case T_WIDTH:
3717 pElem->h = pElem->w;
3718 pElem->rad = 0.5*pElem->w;
3719 break;
3720 case T_HEIGHT:
3721 pElem->w = pElem->h;
3722 pElem->rad = 0.5*pElem->w;
3723 break;
3724 }
3725 UNUSED_PARAMETER(p);
3726 }
3727 static PPoint circleChop(Pik *p, PElem *pElem, PPoint *pPt){
3728 PPoint chop;
3729 PNum dx = pPt->x - pElem->ptAt.x;
3730 PNum dy = pPt->y - pElem->ptAt.y;
3731 PNum dist = hypot(dx,dy);
3732 if( dist<pElem->rad ) return pElem->ptAt;
3733 chop.x = pElem->ptAt.x + dx*pElem->rad/dist;
3734 chop.y = pElem->ptAt.y + dy*pElem->rad/dist;
3735 UNUSED_PARAMETER(p);
3736 return chop;
3737 }
3738 static void circleFit(Pik *p, PElem *pElem, PNum w, PNum h){
3739 PNum mx = 0.0;
3740 if( w>0 ) mx = w;
3741 if( h>mx ) mx = h;
3742 if( (w*w + h*h) > mx*mx ){
3743 mx = hypot(w,h);
3744 }
3745 if( mx>0.0 ){
3746 pElem->rad = 0.5*mx;
3747 pElem->w = pElem->h = mx;
3748 }
3749 UNUSED_PARAMETER(p);
3750 }
3751
3752 static void circleRender(Pik *p, PElem *pElem){
3753 PNum r = pElem->rad;
3754 PPoint pt = pElem->ptAt;
3755 if( pElem->sw>0.0 ){
3756 pik_append_x(p,"<circle cx=\"", pt.x, "\"");
3757 pik_append_y(p," cy=\"", pt.y, "\"");
3758 pik_append_dis(p," r=\"", r, "\" ");
3759 pik_append_style(p,pElem,1);
3760 pik_append(p,"\" />\n", -1);
3761 }
3762 pik_append_txt(p, pElem, 0);
3763 }
3764
3765 /* Methods for the "cylinder" class */
3766 static void cylinderInit(Pik *p, PElem *pElem){
3767 pElem->w = pik_value(p, "cylwid",6,0);
3768 pElem->h = pik_value(p, "cylht",5,0);
3769 pElem->rad = pik_value(p, "cylrad",6,0); /* Minor radius of ellipses */
3770 }
3771 static void cylinderFit(Pik *p, PElem *pElem, PNum w, PNum h){
3772 if( w>0 ) pElem->w = w;
3773 if( h>0 ) pElem->h = h + 4*pElem->rad + pElem->sw;
3774 UNUSED_PARAMETER(p);
3775 }
3776 static void cylinderRender(Pik *p, PElem *pElem){
3777 PNum w2 = 0.5*pElem->w;
3778 PNum h2 = 0.5*pElem->h;
3779 PNum rad = pElem->rad;
3780 PPoint pt = pElem->ptAt;
3781 if( pElem->sw>0.0 ){
3782 pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y+h2-rad);
3783 pik_append_xy(p,"L", pt.x-w2,pt.y-h2+rad);
3784 pik_append_arc(p,w2,rad,pt.x+w2,pt.y-h2+rad);
3785 pik_append_xy(p,"L", pt.x+w2,pt.y+h2-rad);
3786 pik_append_arc(p,w2,rad,pt.x-w2,pt.y+h2-rad);
3787 pik_append_arc(p,w2,rad,pt.x+w2,pt.y+h2-rad);
3788 pik_append(p,"\" ",-1);
3789 pik_append_style(p,pElem,1);
3790 pik_append(p,"\" />\n", -1);
3791 }
3792 pik_append_txt(p, pElem, 0);
3793 }
3794 static PPoint cylinderOffset(Pik *p, PElem *pElem, int cp){
3795 PPoint pt = cZeroPoint;
3796 PNum w2 = pElem->w*0.5;
3797 PNum h1 = pElem->h*0.5;
3798 PNum h2 = h1 - pElem->rad;
3799 switch( cp ){
3800 case CP_C: break;
3801 case CP_N: pt.x = 0.0; pt.y = h1; break;
3802 case CP_NE: pt.x = w2; pt.y = h2; break;
3803 case CP_E: pt.x = w2; pt.y = 0.0; break;
@@ -3811,79 +3836,79 @@
3811 UNUSED_PARAMETER(p);
3812 return pt;
3813 }
3814
3815 /* Methods for the "dot" class */
3816 static void dotInit(Pik *p, PElem *pElem){
3817 pElem->rad = pik_value(p, "dotrad",6,0);
3818 pElem->h = pElem->w = pElem->rad*6;
3819 pElem->fill = pElem->color;
3820 }
3821 static void dotNumProp(Pik *p, PElem *pElem, PToken *pId){
3822 switch( pId->eType ){
3823 case T_COLOR:
3824 pElem->fill = pElem->color;
3825 break;
3826 case T_FILL:
3827 pElem->color = pElem->fill;
3828 break;
3829 }
3830 UNUSED_PARAMETER(p);
3831 }
3832 static void dotCheck(Pik *p, PElem *pElem){
3833 pElem->w = pElem->h = 0;
3834 pik_bbox_addellipse(&pElem->bbox, pElem->ptAt.x, pElem->ptAt.y,
3835 pElem->rad, pElem->rad);
3836 UNUSED_PARAMETER(p);
3837 }
3838 static PPoint dotOffset(Pik *p, PElem *pElem, int cp){
3839 UNUSED_PARAMETER(p);
3840 UNUSED_PARAMETER(pElem);
3841 UNUSED_PARAMETER(cp);
3842 return cZeroPoint;
3843 }
3844 static void dotRender(Pik *p, PElem *pElem){
3845 PNum r = pElem->rad;
3846 PPoint pt = pElem->ptAt;
3847 if( pElem->sw>0.0 ){
3848 pik_append_x(p,"<circle cx=\"", pt.x, "\"");
3849 pik_append_y(p," cy=\"", pt.y, "\"");
3850 pik_append_dis(p," r=\"", r, "\"");
3851 pik_append_style(p,pElem,1);
3852 pik_append(p,"\" />\n", -1);
3853 }
3854 pik_append_txt(p, pElem, 0);
3855 }
3856
3857
3858
3859 /* Methods for the "ellipse" class */
3860 static void ellipseInit(Pik *p, PElem *pElem){
3861 pElem->w = pik_value(p, "ellipsewid",10,0);
3862 pElem->h = pik_value(p, "ellipseht",9,0);
3863 }
3864 static PPoint ellipseChop(Pik *p, PElem *pElem, PPoint *pPt){
3865 PPoint chop;
3866 PNum s, dq, dist;
3867 PNum dx = pPt->x - pElem->ptAt.x;
3868 PNum dy = pPt->y - pElem->ptAt.y;
3869 if( pElem->w<=0.0 ) return pElem->ptAt;
3870 if( pElem->h<=0.0 ) return pElem->ptAt;
3871 s = pElem->h/pElem->w;
3872 dq = dx*s;
3873 dist = hypot(dq,dy);
3874 if( dist<pElem->h ) return pElem->ptAt;
3875 chop.x = pElem->ptAt.x + 0.5*dq*pElem->h/(dist*s);
3876 chop.y = pElem->ptAt.y + 0.5*dy*pElem->h/dist;
3877 UNUSED_PARAMETER(p);
3878 return chop;
3879 }
3880 static PPoint ellipseOffset(Pik *p, PElem *pElem, int cp){
3881 PPoint pt = cZeroPoint;
3882 PNum w = pElem->w*0.5;
3883 PNum w2 = w*0.70710678118654747608;
3884 PNum h = pElem->h*0.5;
3885 PNum h2 = h*0.70710678118654747608;
3886 switch( cp ){
3887 case CP_C: break;
3888 case CP_N: pt.x = 0.0; pt.y = h; break;
3889 case CP_NE: pt.x = w2; pt.y = h2; break;
@@ -3896,38 +3921,38 @@
3896 default: assert(0);
3897 }
3898 UNUSED_PARAMETER(p);
3899 return pt;
3900 }
3901 static void ellipseRender(Pik *p, PElem *pElem){
3902 PNum w = pElem->w;
3903 PNum h = pElem->h;
3904 PPoint pt = pElem->ptAt;
3905 if( pElem->sw>0.0 ){
3906 pik_append_x(p,"<ellipse cx=\"", pt.x, "\"");
3907 pik_append_y(p," cy=\"", pt.y, "\"");
3908 pik_append_dis(p," rx=\"", w/2.0, "\"");
3909 pik_append_dis(p," ry=\"", h/2.0, "\" ");
3910 pik_append_style(p,pElem,1);
3911 pik_append(p,"\" />\n", -1);
3912 }
3913 pik_append_txt(p, pElem, 0);
3914 }
3915
3916 /* Methods for the "file" object */
3917 static void fileInit(Pik *p, PElem *pElem){
3918 pElem->w = pik_value(p, "filewid",7,0);
3919 pElem->h = pik_value(p, "fileht",6,0);
3920 pElem->rad = pik_value(p, "filerad",7,0);
3921 }
3922 /* Return offset from the center of the file to the compass point
3923 ** given by parameter cp */
3924 static PPoint fileOffset(Pik *p, PElem *pElem, int cp){
3925 PPoint pt = cZeroPoint;
3926 PNum w2 = 0.5*pElem->w;
3927 PNum h2 = 0.5*pElem->h;
3928 PNum rx = pElem->rad;
3929 PNum mn = w2<h2 ? w2 : h2;
3930 if( rx>mn ) rx = mn;
3931 if( rx<mn*0.25 ) rx = mn*0.25;
3932 pt.x = pt.y = 0.0;
3933 rx *= 0.5;
@@ -3944,132 +3969,133 @@
3944 default: assert(0);
3945 }
3946 UNUSED_PARAMETER(p);
3947 return pt;
3948 }
3949 static void fileFit(Pik *p, PElem *pElem, PNum w, PNum h){
3950 if( w>0 ) pElem->w = w;
3951 if( h>0 ) pElem->h = h + 2*pElem->rad;
3952 UNUSED_PARAMETER(p);
3953 }
3954 static void fileRender(Pik *p, PElem *pElem){
3955 PNum w2 = 0.5*pElem->w;
3956 PNum h2 = 0.5*pElem->h;
3957 PNum rad = pElem->rad;
3958 PPoint pt = pElem->ptAt;
3959 PNum mn = w2<h2 ? w2 : h2;
3960 if( rad>mn ) rad = mn;
3961 if( rad<mn*0.25 ) rad = mn*0.25;
3962 if( pElem->sw>0.0 ){
3963 pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y-h2);
3964 pik_append_xy(p,"L", pt.x+w2,pt.y-h2);
3965 pik_append_xy(p,"L", pt.x+w2,pt.y+(h2-rad));
3966 pik_append_xy(p,"L", pt.x+(w2-rad),pt.y+h2);
3967 pik_append_xy(p,"L", pt.x-w2,pt.y+h2);
3968 pik_append(p,"Z\" ",-1);
3969 pik_append_style(p,pElem,1);
3970 pik_append(p,"\" />\n",-1);
3971 pik_append_xy(p,"<path d=\"M", pt.x+(w2-rad), pt.y+h2);
3972 pik_append_xy(p,"L", pt.x+(w2-rad),pt.y+(h2-rad));
3973 pik_append_xy(p,"L", pt.x+w2, pt.y+(h2-rad));
3974 pik_append(p,"\" ",-1);
3975 pik_append_style(p,pElem,0);
3976 pik_append(p,"\" />\n",-1);
3977 }
3978 pik_append_txt(p, pElem, 0);
3979 }
3980
3981
3982 /* Methods for the "line" class */
3983 static void lineInit(Pik *p, PElem *pElem){
3984 pElem->w = pik_value(p, "linewid",7,0);
3985 pElem->h = pik_value(p, "lineht",6,0);
3986 pElem->rad = pik_value(p, "linerad",7,0);
3987 pElem->fill = -1.0;
3988 }
3989 static PPoint lineOffset(Pik *p, PElem *pElem, int cp){
3990 #if 0
3991 /* In legacy PIC, the .center of an unclosed line is half way between
3992 ** its .start and .end. */
3993 if( cp==CP_C && !pElem->bClose ){
3994 PPoint out;
3995 out.x = 0.5*(pElem->ptEnter.x + pElem->ptExit.x) - pElem->ptAt.x;
3996 out.y = 0.5*(pElem->ptEnter.x + pElem->ptExit.y) - pElem->ptAt.y;
3997 return out;
3998 }
3999 #endif
4000 return boxOffset(p,pElem,cp);
4001 }
4002 static void lineRender(Pik *p, PElem *pElem){
4003 int i;
4004 if( pElem->sw>0.0 ){
4005 const char *z = "<path d=\"M";
4006 int n = pElem->nPath;
4007 if( pElem->larrow ){
4008 pik_draw_arrowhead(p,&pElem->aPath[1],&pElem->aPath[0],pElem);
4009 }
4010 if( pElem->rarrow ){
4011 pik_draw_arrowhead(p,&pElem->aPath[n-2],&pElem->aPath[n-1],pElem);
4012 }
4013 for(i=0; i<pElem->nPath; i++){
4014 pik_append_xy(p,z,pElem->aPath[i].x,pElem->aPath[i].y);
4015 z = "L";
4016 }
4017 if( pElem->bClose ){
4018 pik_append(p,"Z",1);
4019 }else{
4020 pElem->fill = -1.0;
4021 }
4022 pik_append(p,"\" ",-1);
4023 pik_append_style(p,pElem,pElem->bClose);
4024 pik_append(p,"\" />\n", -1);
4025 }
4026 pik_append_txt(p, pElem, 0);
4027 }
4028
4029 /* Methods for the "move" class */
4030 static void moveInit(Pik *p, PElem *pElem){
4031 pElem->w = pik_value(p, "movewid",7,0);
4032 pElem->h = pElem->w;
4033 pElem->fill = -1.0;
4034 pElem->color = -1.0;
4035 pElem->sw = -1.0;
4036 }
4037 static void moveRender(Pik *p, PElem *pElem){
4038 /* No-op */
4039 UNUSED_PARAMETER(p);
4040 UNUSED_PARAMETER(pElem);
4041 }
4042
4043 /* Methods for the "oval" class */
4044 static void ovalInit(Pik *p, PElem *pElem){
4045 pElem->h = pik_value(p, "ovalht",6,0);
4046 pElem->w = pik_value(p, "ovalwid",7,0);
4047 pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
4048 }
4049 static void ovalNumProp(Pik *p, PElem *pElem, PToken *pId){
4050 UNUSED_PARAMETER(p);
4051 UNUSED_PARAMETER(pId);
4052 /* Always adjust the radius to be half of the smaller of
4053 ** the width and height. */
4054 pElem->rad = 0.5*(pElem->h<pElem->w?pElem->h:pElem->w);
4055 }
4056 static void ovalFit(Pik *p, PElem *pElem, PNum w, PNum h){
4057 UNUSED_PARAMETER(p);
4058 if( w>0 ) pElem->w = w;
4059 if( h>0 ) pElem->h = h;
4060 if( pElem->w<pElem->h ) pElem->w = pElem->h;
 
4061 }
4062
4063
4064
4065 /* Methods for the "spline" class */
4066 static void splineInit(Pik *p, PElem *pElem){
4067 pElem->w = pik_value(p, "linewid",7,0);
4068 pElem->h = pik_value(p, "lineht",6,0);
4069 pElem->rad = 1000;
4070 pElem->fill = -1.0; /* Disable fill by default */
4071 }
4072 /* Return a point along the path from "f" to "t" that is r units
4073 ** prior to reaching "t", except if the path is less than 2*r total,
4074 ** return the midpoint.
4075 */
@@ -4089,14 +4115,14 @@
4089 }
4090 m.x = t.x - r*dx;
4091 m.y = t.y - r*dy;
4092 return m;
4093 }
4094 static void radiusPath(Pik *p, PElem *pElem, PNum r){
4095 int i;
4096 int n = pElem->nPath;
4097 const PPoint *a = pElem->aPath;
4098 PPoint m;
4099 int isMid = 0;
4100
4101 pik_append_xy(p,"<path d=\"M", a[0].x, a[0].y);
4102 m = radiusMidpoint(a[0], a[1], r, &isMid);
@@ -4110,68 +4136,68 @@
4110 pik_append_xy(p," L ",m.x,m.y);
4111 }
4112 }
4113 pik_append_xy(p," L ",a[i].x,a[i].y);
4114 pik_append(p,"\" ",-1);
4115 pik_append_style(p,pElem,0);
4116 pik_append(p,"\" />\n", -1);
4117 }
4118 static void splineRender(Pik *p, PElem *pElem){
4119 if( pElem->sw>0.0 ){
4120 int n = pElem->nPath;
4121 PNum r = pElem->rad;
4122 if( n<3 || r<=0.0 ){
4123 lineRender(p,pElem);
4124 return;
4125 }
4126 if( pElem->larrow ){
4127 pik_draw_arrowhead(p,&pElem->aPath[1],&pElem->aPath[0],pElem);
4128 }
4129 if( pElem->rarrow ){
4130 pik_draw_arrowhead(p,&pElem->aPath[n-2],&pElem->aPath[n-1],pElem);
4131 }
4132 radiusPath(p,pElem,pElem->rad);
4133 }
4134 pik_append_txt(p, pElem, 0);
4135 }
4136
4137
4138 /* Methods for the "text" class */
4139 static void textInit(Pik *p, PElem *pElem){
4140 pik_value(p, "textwid",7,0);
4141 pik_value(p, "textht",6,0);
4142 pElem->sw = 0.0;
4143 }
4144 static PPoint textOffset(Pik *p, PElem *pElem, int cp){
4145 /* Automatically slim-down the width and height of text
4146 ** elements so that the bounding box tightly encloses the text,
4147 ** then get boxOffset() to do the offset computation.
4148 */
4149 pik_size_to_fit(p, &pElem->errTok);
4150 return boxOffset(p, pElem, cp);
4151 }
4152
4153 /* Methods for the "sublist" class */
4154 static void sublistInit(Pik *p, PElem *pElem){
4155 PEList *pList = pElem->pSublist;
4156 int i;
4157 UNUSED_PARAMETER(p);
4158 pik_bbox_init(&pElem->bbox);
4159 for(i=0; i<pList->n; i++){
4160 pik_bbox_addbox(&pElem->bbox, &pList->a[i]->bbox);
4161 }
4162 pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
4163 pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
4164 pElem->ptAt.x = 0.5*(pElem->bbox.ne.x + pElem->bbox.sw.x);
4165 pElem->ptAt.y = 0.5*(pElem->bbox.ne.y + pElem->bbox.sw.y);
4166 pElem->mCalc |= A_WIDTH|A_HEIGHT|A_RADIUS;
4167 }
4168
4169
4170 /*
4171 ** The following array holds all the different kinds of named
4172 ** elements. The special STRING and [] elements are separate.
4173 */
4174 static const PClass aClass[] = {
4175 { /* name */ "arc",
4176 /* isline */ 1,
4177 /* eJust */ 0,
@@ -4244,11 +4270,11 @@
4244 /* xInit */ ellipseInit,
4245 /* xNumProp */ 0,
4246 /* xCheck */ 0,
4247 /* xChop */ ellipseChop,
4248 /* xOffset */ ellipseOffset,
4249 /* xFit */ 0,
4250 /* xRender */ ellipseRender
4251 },
4252 { /* name */ "file",
4253 /* isline */ 0,
4254 /* eJust */ 1,
@@ -4363,20 +4389,20 @@
4363 /*
4364 ** Draw an arrowhead on the end of the line segment from pFrom to pTo.
4365 ** Also, shorten the line segment (by changing the value of pTo) so that
4366 ** the shaft of the arrow does not extend into the arrowhead.
4367 */
4368 static void pik_draw_arrowhead(Pik *p, PPoint *f, PPoint *t, PElem *pElem){
4369 PNum dx = t->x - f->x;
4370 PNum dy = t->y - f->y;
4371 PNum dist = hypot(dx,dy);
4372 PNum h = p->hArrow * pElem->sw;
4373 PNum w = p->wArrow * pElem->sw;
4374 PNum e1, ddx, ddy;
4375 PNum bx, by;
4376 if( pElem->color<0.0 ) return;
4377 if( pElem->sw<=0.0 ) return;
4378 if( dist<=0.0 ) return; /* Unable */
4379 dx /= dist;
4380 dy /= dist;
4381 e1 = dist - h;
4382 if( e1<0.0 ){
@@ -4388,20 +4414,20 @@
4388 bx = f->x + e1*dx;
4389 by = f->y + e1*dy;
4390 pik_append_xy(p,"<polygon points=\"", t->x, t->y);
4391 pik_append_xy(p," ",bx-ddx, by-ddy);
4392 pik_append_xy(p," ",bx+ddx, by+ddy);
4393 pik_append_clr(p,"\" style=\"fill:",pElem->color,"\"/>\n");
4394 pik_chop(f,t,h/2);
4395 }
4396
4397 /*
4398 ** Compute the relative offset to an edge location from the reference for a
4399 ** an element.
4400 */
4401 static PPoint pik_elem_offset(Pik *p, PElem *pElem, int cp){
4402 return pElem->type->xOffset(p, pElem, cp);
4403 }
4404
4405
4406 /*
4407 ** Append raw text to zOut
@@ -4544,49 +4570,49 @@
4544 }
4545
4546 /* Append a style="..." text. But, leave the quote unterminated, in case
4547 ** the caller wants to add some more.
4548 */
4549 static void pik_append_style(Pik *p, PElem *pElem, int bFill){
4550 pik_append(p, " style=\"", -1);
4551 if( pElem->fill>=0 && bFill ){
4552 pik_append_clr(p, "fill:", pElem->fill, ";");
4553 }else{
4554 pik_append(p,"fill:none;",-1);
4555 }
4556 if( pElem->sw>0.0 && pElem->color>=0.0 ){
4557 PNum sw = pElem->sw;
4558 pik_append_dis(p, "stroke-width:", sw, ";");
4559 if( pElem->nPath>2 && pElem->rad<=pElem->sw ){
4560 pik_append(p, "stroke-linejoin:round;", -1);
4561 }
4562 pik_append_clr(p, "stroke:",pElem->color,";");
4563 if( pElem->dotted>0.0 ){
4564 PNum v = pElem->dotted;
4565 if( sw<2.1/p->rScale ) sw = 2.1/p->rScale;
4566 pik_append_dis(p,"stroke-dasharray:",sw,"");
4567 pik_append_dis(p,",",v,";");
4568 }else if( pElem->dashed>0.0 ){
4569 PNum v = pElem->dashed;
4570 pik_append_dis(p,"stroke-dasharray:",v,"");
4571 pik_append_dis(p,",",v,";");
4572 }
4573 }
4574 }
4575
4576 /*
4577 ** Compute the vertical locations for all text items in the
4578 ** element pElem. In other words, set every pElem->aTxt[*].eCode
4579 ** value to contain exactly one of: TP_ABOVE2, TP_ABOVE, TP_CENTER,
4580 ** TP_BELOW, or TP_BELOW2 is set.
4581 */
4582 static void pik_txt_vertical_layout(PElem *pElem){
4583 int n, i;
4584 PToken *aTxt;
4585 n = pElem->nTxt;
4586 if( n==0 ) return;
4587 aTxt = pElem->aTxt;
4588 if( n==1 ){
4589 if( (aTxt[0].eCode & TP_VMASK)==0 ){
4590 aTxt[0].eCode |= TP_CENTER;
4591 }
4592 }else{
@@ -4649,22 +4675,22 @@
4649 }
4650 }
4651 }
4652 }
4653
4654 /* Append multiple <text> SVG element for the text fields of the PElem.
4655 ** Parameters:
4656 **
4657 ** p The Pik object into which we are rendering
4658 **
4659 ** pElem Object containing the text to be rendered
4660 **
4661 ** pBox If not NULL, do no rendering at all. Instead
4662 ** expand the box object so that it will include all
4663 ** of the text.
4664 */
4665 static void pik_append_txt(Pik *p, PElem *pElem, PBox *pBox){
4666 PNum dy; /* Half the height of a single line of text */
4667 PNum dy2; /* Extra vertical space around the center */
4668 PNum jw; /* Justification margin relative to center */
4669 int n, i, nz;
4670 PNum x, y, orig_y;
@@ -4671,35 +4697,35 @@
4671 const char *z;
4672 PToken *aTxt;
4673 int hasCenter = 0;
4674
4675 if( p->nErr ) return;
4676 if( pElem->nTxt==0 ) return;
4677 aTxt = pElem->aTxt;
4678 dy = 0.5*p->charHeight;
4679 n = pElem->nTxt;
4680 pik_txt_vertical_layout(pElem);
4681 x = pElem->ptAt.x;
4682 for(i=0; i<n; i++){
4683 if( (pElem->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
4684 }
4685 if( hasCenter ){
4686 dy2 = dy;
4687 }else if( pElem->type->isLine ){
4688 dy2 = pElem->sw;
4689 }else{
4690 dy2 = 0.0;
4691 }
4692 if( pElem->type->eJust==1 ){
4693 jw = 0.5*(pElem->w - 0.5*(p->charWidth + pElem->sw));
4694 }else{
4695 jw = 0.0;
4696 }
4697 for(i=0; i<n; i++){
4698 PToken *t = &aTxt[i];
4699 PNum xtraFontScale = 1.0;
4700 orig_y = pElem->ptAt.y;
4701 PNum nx = 0;
4702 y = 0;
4703 if( t->eCode & TP_ABOVE2 ) y += dy2 + 3*dy;
4704 if( t->eCode & TP_ABOVE ) y += dy2 + dy;
4705 if( t->eCode & TP_BELOW ) y -= dy2 + dy;
@@ -4713,11 +4739,11 @@
4713 if( pBox!=0 ){
4714 /* If pBox is not NULL, do not draw any <text>. Instead, just expand
4715 ** pBox to include the text */
4716 PNum cw = pik_text_length(t)*p->charWidth*xtraFontScale*0.01;
4717 PNum ch = p->charHeight*0.5*xtraFontScale;
4718 PNum x0, y0, x1, y1; /* Boundary of text relative to pElem->ptAt */
4719 if( t->eCode & TP_BOLD ) cw *= 1.1;
4720 if( t->eCode & TP_RJUST ){
4721 x0 = nx;
4722 y0 = y-ch;
4723 x1 = nx-cw;
@@ -4731,14 +4757,14 @@
4731 x0 = nx+cw/2;
4732 y0 = y+ch;
4733 x1 = nx-cw/2;
4734 y1 = y-ch;
4735 }
4736 if( (t->eCode & TP_ALIGN)!=0 && pElem->nPath>=2 ){
4737 int n = pElem->nPath;
4738 PNum dx = pElem->aPath[n-1].x - pElem->aPath[0].x;
4739 PNum dy = pElem->aPath[n-1].y - pElem->aPath[0].y;
4740 if( dx!=0 || dy!=0 ){
4741 PNum dist = hypot(dx,dy);
4742 PNum t;
4743 dx /= dist;
4744 dy /= dist;
@@ -4770,22 +4796,22 @@
4770 pik_append(p, " font-style=\"italic\"", -1);
4771 }
4772 if( t->eCode & TP_BOLD ){
4773 pik_append(p, " font-weight=\"bold\"", -1);
4774 }
4775 if( pElem->color>=0.0 ){
4776 pik_append_clr(p, " fill=\"", pElem->color, "\"");
4777 }
4778 xtraFontScale *= p->fontScale;
4779 if( xtraFontScale<=0.99 || xtraFontScale>=1.01 ){
4780 pik_append_num(p, " font-size=\"", xtraFontScale*100.0);
4781 pik_append(p, "%\"", 2);
4782 }
4783 if( (t->eCode & TP_ALIGN)!=0 && pElem->nPath>=2 ){
4784 int n = pElem->nPath;
4785 PNum dx = pElem->aPath[n-1].x - pElem->aPath[0].x;
4786 PNum dy = pElem->aPath[n-1].y - pElem->aPath[0].y;
4787 if( dx!=0 || dy!=0 ){
4788 PNum ang = atan2(dy,dx)*-180/M_PI;
4789 pik_append_num(p, " transform=\"rotate(", ang);
4790 pik_append_xy(p, " ", x, orig_y);
4791 pik_append(p,")\"",2);
@@ -4808,23 +4834,65 @@
4808 }
4809 pik_append(p, "</text>\n", -1);
4810 }
4811 }
4812
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4813
4814 /*
4815 ** Generate an error message for the output. pErr is the token at which
4816 ** the error should point. zMsg is the text of the error message. If
4817 ** either pErr or zMsg is NULL, generate an out-of-memory error message.
4818 **
4819 ** This routine is a no-op if there has already been an error reported.
4820 */
4821 static void pik_error(Pik *p, PToken *pErr, const char *zMsg){
4822 int i, j;
4823 int iCol;
4824 int nExtra;
4825 char c;
4826 if( p==0 ) return;
4827 if( p->nErr ) return;
4828 p->nErr++;
4829 if( zMsg==0 ){
4830 pik_append(p, "\n<div><p>Out of memory</p></div>\n", -1);
@@ -4833,29 +4901,26 @@
4833 if( pErr==0 ){
4834 pik_append(p, "\n", 1);
4835 pik_append_text(p, zMsg, -1, 0);
4836 return;
4837 }
4838 i = (int)(pErr->z - p->zIn);
4839 for(j=i; j>0 && p->zIn[j-1]!='\n'; j--){}
4840 iCol = i - j;
4841 for(nExtra=0; (c = p->zIn[i+nExtra])!=0 && c!='\n'; nExtra++){}
4842 pik_append(p, "<div><pre>\n", -1);
4843 pik_append_text(p, p->zIn, i+nExtra, 3);
4844 pik_append(p, "\n", 1);
4845 for(i=0; i<iCol; i++){ pik_append(p, " ", 1); }
4846 for(i=0; i<(int)pErr->n; i++) pik_append(p, "^", 1);
4847 pik_append(p, "\nERROR: ", -1);
4848 pik_append_text(p, zMsg, -1, 0);
4849 pik_append(p, "\n", 1);
4850 pik_append(p, "\n</pre></div>\n", -1);
 
 
 
 
4851 }
4852
4853 /*
4854 ** Process an "assert( e1 == e2 )" statement. Always return NULL.
4855 */
4856 static PElem *pik_assert(Pik *p, PNum e1, PToken *pEq, PNum e2){
4857 char zE1[100], zE2[100], zMsg[300];
4858
4859 /* Convert the numbers to strings using %g for comparison. This
4860 ** limits the precision of the comparison to account for rounding error. */
4861 snprintf(zE1, sizeof(zE1), "%g", e1); zE1[sizeof(zE1)-1] = 0;
@@ -4868,11 +4933,11 @@
4868 }
4869
4870 /*
4871 ** Process an "assert( place1 == place2 )" statement. Always return NULL.
4872 */
4873 static PElem *pik_position_assert(Pik *p, PPoint *e1, PToken *pEq, PPoint *e2){
4874 char zE1[100], zE2[100], zMsg[210];
4875
4876 /* Convert the numbers to strings using %g for comparison. This
4877 ** limits the precision of the comparison to account for rounding error. */
4878 snprintf(zE1, sizeof(zE1), "(%g,%g)", e1->x, e1->y); zE1[sizeof(zE1)-1] = 0;
@@ -4882,29 +4947,29 @@
4882 pik_error(p, pEq, zMsg);
4883 }
4884 return 0;
4885 }
4886
4887 /* Free a complete list of elements */
4888 static void pik_elist_free(Pik *p, PEList *pEList){
4889 int i;
4890 if( pEList==0 ) return;
4891 for(i=0; i<pEList->n; i++){
4892 pik_elem_free(p, pEList->a[i]);
4893 }
4894 free(pEList->a);
4895 free(pEList);
4896 return;
4897 }
4898
4899 /* Free a single element, and its substructure */
4900 static void pik_elem_free(Pik *p, PElem *pElem){
4901 if( pElem==0 ) return;
4902 free(pElem->zName);
4903 pik_elist_free(p, pElem->pSublist);
4904 free(pElem->aPath);
4905 free(pElem);
4906 }
4907
4908 /* Convert a numeric literal into a number. Return that number.
4909 ** There is no error handling because the tokenizer has already
4910 ** assured us that the numeric literal is valid.
@@ -5017,42 +5082,42 @@
5017 if( pA->ne.y<y+ry ) pA->ne.y = y+ry;
5018 }
5019
5020
5021
5022 /* Append a new element onto the end of an element_list. The
5023 ** element_list is created if it does not already exist. Return
5024 ** the new element list.
5025 */
5026 static PEList *pik_elist_append(Pik *p, PEList *pEList, PElem *pElem){
5027 if( pElem==0 ) return pEList;
5028 if( pEList==0 ){
5029 pEList = malloc(sizeof(*pEList));
5030 if( pEList==0 ){
5031 pik_error(p, 0, 0);
5032 pik_elem_free(p, pElem);
5033 return 0;
5034 }
5035 memset(pEList, 0, sizeof(*pEList));
5036 }
5037 if( pEList->n>=pEList->nAlloc ){
5038 int nNew = (pEList->n+5)*2;
5039 PElem **pNew = realloc(pEList->a, sizeof(PElem*)*nNew);
5040 if( pNew==0 ){
5041 pik_error(p, 0, 0);
5042 pik_elem_free(p, pElem);
5043 return pEList;
5044 }
5045 pEList->nAlloc = nNew;
5046 pEList->a = pNew;
5047 }
5048 pEList->a[pEList->n++] = pElem;
5049 p->list = pEList;
5050 return pEList;
5051 }
5052
5053 /* Convert an element class name into a PClass pointer
5054 */
5055 static const PClass *pik_find_class(PToken *pId){
5056 int first = 0;
5057 int last = count(aClass) - 1;
5058 do{
@@ -5069,19 +5134,19 @@
5069 }
5070 }while( first<=last );
5071 return 0;
5072 }
5073
5074 /* Allocate and return a new PElem object.
5075 **
5076 ** If pId!=0 then pId is an identifier that defines the element class.
5077 ** If pStr!=0 then it is a STRING literal that defines a text object.
5078 ** If pSublist!=0 then this is a [...] object. If all three parameters
5079 ** are NULL then this is a no-op object used to define a PLACENAME.
5080 */
5081 static PElem *pik_elem_new(Pik *p, PToken *pId, PToken *pStr,PEList *pSublist){
5082 PElem *pNew;
5083 int miss = 0;
5084
5085 if( p->nErr ) return 0;
5086 pNew = malloc( sizeof(*pNew) );
5087 if( pNew==0 ){
@@ -5095,11 +5160,11 @@
5095 p->thenFlag = 0;
5096 if( p->list==0 || p->list->n==0 ){
5097 pNew->ptAt.x = pNew->ptAt.y = 0.0;
5098 pNew->eWith = CP_C;
5099 }else{
5100 PElem *pPrior = p->list->a[p->list->n-1];
5101 pNew->ptAt = pPrior->ptExit;
5102 switch( p->eDir ){
5103 default: pNew->eWith = CP_W; break;
5104 case DIR_LEFT: pNew->eWith = CP_E; break;
5105 case DIR_UP: pNew->eWith = CP_S; break;
@@ -5138,32 +5203,72 @@
5138 pNew->fill = pik_value(p, "fill",4,0);
5139 pNew->color = pik_value(p, "color",5,0);
5140 pClass->xInit(p, pNew);
5141 return pNew;
5142 }
5143 pik_error(p, pId, "unknown element type");
5144 pik_elem_free(p, pNew);
5145 return 0;
5146 }
5147 pNew->type = &noopClass;
5148 pNew->ptExit = pNew->ptEnter = pNew->ptAt;
5149 return pNew;
5150 }
5151
5152 /*
5153 ** Set the output direction and exit point for an element.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5154 */
5155 static void pik_elem_set_exit(PElem *pElem, int eDir){
5156 assert( ValidDir(eDir) );
5157 pElem->outDir = eDir;
5158 if( !pElem->type->isLine || pElem->bClose ){
5159 pElem->ptExit = pElem->ptAt;
5160 switch( pElem->outDir ){
5161 default: pElem->ptExit.x += pElem->w*0.5; break;
5162 case DIR_LEFT: pElem->ptExit.x -= pElem->w*0.5; break;
5163 case DIR_UP: pElem->ptExit.y += pElem->h*0.5; break;
5164 case DIR_DOWN: pElem->ptExit.y -= pElem->h*0.5; break;
5165 }
5166 }
5167 }
5168
5169 /* Change the layout direction.
@@ -5188,34 +5293,34 @@
5188 if( p->list && p->list->n ){
5189 pik_elem_set_exit(p->list->a[p->list->n-1], eDir);
5190 }
5191 }
5192
5193 /* Move all coordinates contained within an element (and within its
5194 ** substructure) by dx, dy
5195 */
5196 static void pik_elem_move(PElem *pElem, PNum dx, PNum dy){
5197 int i;
5198 pElem->ptAt.x += dx;
5199 pElem->ptAt.y += dy;
5200 pElem->ptEnter.x += dx;
5201 pElem->ptEnter.y += dy;
5202 pElem->ptExit.x += dx;
5203 pElem->ptExit.y += dy;
5204 pElem->bbox.ne.x += dx;
5205 pElem->bbox.ne.y += dy;
5206 pElem->bbox.sw.x += dx;
5207 pElem->bbox.sw.y += dy;
5208 for(i=0; i<pElem->nPath; i++){
5209 pElem->aPath[i].x += dx;
5210 pElem->aPath[i].y += dy;
5211 }
5212 if( pElem->pSublist ){
5213 pik_elist_move(pElem->pSublist, dx, dy);
5214 }
5215 }
5216 static void pik_elist_move(PEList *pList, PNum dx, PNum dy){
5217 int i;
5218 for(i=0; i<pList->n; i++){
5219 pik_elem_move(pList->a[i], dx, dy);
5220 }
5221 }
@@ -5223,31 +5328,31 @@
5223 /*
5224 ** Check to see if it is ok to set the value of paraemeter mThis.
5225 ** Return 0 if it is ok. If it not ok, generate an appropriate
5226 ** error message and return non-zero.
5227 **
5228 ** Flags are set in pElem so that the same element or conflicting
5229 ** elements may not be set again.
5230 **
5231 ** To be ok, bit mThis must be clear and no more than one of
5232 ** the bits identified by mBlockers may be set.
5233 */
5234 static int pik_param_ok(
5235 Pik *p, /* For storing the error message (if any) */
5236 PElem *pElem, /* The element under construction */
5237 PToken *pId, /* Make the error point to this token */
5238 int mThis /* Value we are trying to set */
5239 ){
5240 if( pElem->mProp & mThis ){
5241 pik_error(p, pId, "value is already set");
5242 return 1;
5243 }
5244 if( pElem->mCalc & mThis ){
5245 pik_error(p, pId, "value already fixed by prior constraints");
5246 return 1;
5247 }
5248 pElem->mProp |= mThis;
5249 return 0;
5250 }
5251
5252
5253 /*
@@ -5255,56 +5360,56 @@
5255 **
5256 ** The rAbs term is an absolute value to add in. rRel is
5257 ** a relative value by which to change the current value.
5258 */
5259 void pik_set_numprop(Pik *p, PToken *pId, PRel *pVal){
5260 PElem *pElem = p->cur;
5261 switch( pId->eType ){
5262 case T_HEIGHT:
5263 if( pik_param_ok(p, pElem, pId, A_HEIGHT) ) return;
5264 pElem->h = pElem->h*pVal->rRel + pVal->rAbs;
5265 break;
5266 case T_WIDTH:
5267 if( pik_param_ok(p, pElem, pId, A_WIDTH) ) return;
5268 pElem->w = pElem->w*pVal->rRel + pVal->rAbs;
5269 break;
5270 case T_RADIUS:
5271 if( pik_param_ok(p, pElem, pId, A_RADIUS) ) return;
5272 pElem->rad = pElem->rad*pVal->rRel + pVal->rAbs;
5273 break;
5274 case T_DIAMETER:
5275 if( pik_param_ok(p, pElem, pId, A_RADIUS) ) return;
5276 pElem->rad = pElem->rad*pVal->rRel + 0.5*pVal->rAbs; /* diam it 2x rad */
5277 break;
5278 case T_THICKNESS:
5279 if( pik_param_ok(p, pElem, pId, A_THICKNESS) ) return;
5280 pElem->sw = pElem->sw*pVal->rRel + pVal->rAbs;
5281 break;
5282 }
5283 if( pElem->type->xNumProp ){
5284 pElem->type->xNumProp(p, pElem, pId);
5285 }
5286 return;
5287 }
5288
5289 /*
5290 ** Set a color property. The argument is an RGB value.
5291 */
5292 void pik_set_clrprop(Pik *p, PToken *pId, PNum rClr){
5293 PElem *pElem = p->cur;
5294 switch( pId->eType ){
5295 case T_FILL:
5296 if( pik_param_ok(p, pElem, pId, A_FILL) ) return;
5297 pElem->fill = rClr;
5298 break;
5299 case T_COLOR:
5300 if( pik_param_ok(p, pElem, pId, A_COLOR) ) return;
5301 pElem->color = rClr;
5302 break;
5303 }
5304 if( pElem->type->xNumProp ){
5305 pElem->type->xNumProp(p, pElem, pId);
5306 }
5307 return;
5308 }
5309
5310 /*
@@ -5312,23 +5417,23 @@
5312 **
5313 ** Use the value supplied by pVal if available. If pVal==0, use
5314 ** a default.
5315 */
5316 void pik_set_dashed(Pik *p, PToken *pId, PNum *pVal){
5317 PElem *pElem = p->cur;
5318 PNum v;
5319 switch( pId->eType ){
5320 case T_DOTTED: {
5321 v = pVal==0 ? pik_value(p,"dashwid",7,0) : *pVal;
5322 pElem->dotted = v;
5323 pElem->dashed = 0.0;
5324 break;
5325 }
5326 case T_DASHED: {
5327 v = pVal==0 ? pik_value(p,"dashwid",7,0) : *pVal;
5328 pElem->dashed = v;
5329 pElem->dotted = 0.0;
5330 break;
5331 }
5332 }
5333 }
5334
@@ -5346,18 +5451,18 @@
5346
5347 /* Add a new term to the path for a line-oriented object by transferring
5348 ** the information in the ptTo field over onto the path and into ptFrom
5349 ** resetting the ptTo.
5350 */
5351 static void pik_then(Pik *p, PToken *pToken, PElem *pElem){
5352 int n;
5353 if( !pElem->type->isLine ){
5354 pik_error(p, pToken, "use with line-oriented objects only");
5355 return;
5356 }
5357 n = p->nTPath - 1;
5358 if( n<1 && (pElem->mProp & A_FROM)==0 ){
5359 pik_error(p, pToken, "no prior path points");
5360 return;
5361 }
5362 p->thenFlag = 1;
5363 }
@@ -5375,22 +5480,22 @@
5375 p->aTPath[n] = p->aTPath[n-1];
5376 p->mTPath = 0;
5377 return n;
5378 }
5379
5380 /* Add a direction term to an element. "up 0.5", or "left 3", or "down"
5381 ** or "down 50%".
5382 */
5383 static void pik_add_direction(Pik *p, PToken *pDir, PRel *pVal){
5384 PElem *pElem = p->cur;
5385 int n;
5386 int dir;
5387 if( !pElem->type->isLine ){
5388 if( pDir ){
5389 pik_error(p, pDir, "use with line-oriented objects only");
5390 }else{
5391 PToken x = pik_next_semantic_token(&pElem->errTok);
5392 pik_error(p, &x, "syntax error");
5393 }
5394 return;
5395 }
5396 pik_reset_samepath(p);
@@ -5401,30 +5506,30 @@
5401 }
5402 dir = pDir ? pDir->eCode : p->eDir;
5403 switch( dir ){
5404 case DIR_UP:
5405 if( p->mTPath & 2 ) n = pik_next_rpath(p, pDir);
5406 p->aTPath[n].y += pVal->rAbs + pElem->h*pVal->rRel;
5407 p->mTPath |= 2;
5408 break;
5409 case DIR_DOWN:
5410 if( p->mTPath & 2 ) n = pik_next_rpath(p, pDir);
5411 p->aTPath[n].y -= pVal->rAbs + pElem->h*pVal->rRel;
5412 p->mTPath |= 2;
5413 break;
5414 case DIR_RIGHT:
5415 if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
5416 p->aTPath[n].x += pVal->rAbs + pElem->w*pVal->rRel;
5417 p->mTPath |= 1;
5418 break;
5419 case DIR_LEFT:
5420 if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
5421 p->aTPath[n].x -= pVal->rAbs + pElem->w*pVal->rRel;
5422 p->mTPath |= 1;
5423 break;
5424 }
5425 pElem->outDir = dir;
5426 }
5427
5428 /* Process a movement attribute of one of these forms:
5429 **
5430 ** pDist pHdgKW rHdg pEdgept
@@ -5437,14 +5542,14 @@
5437 PToken *pHeading, /* "heading" keyword if present */
5438 PNum rHdg, /* Angle argument to "heading" keyword */
5439 PToken *pEdgept, /* EDGEPT keyword "ne", "sw", etc... */
5440 PToken *pErr /* Token to use for error messages */
5441 ){
5442 PElem *pElem = p->cur;
5443 int n;
5444 PNum rDist = pDist->rAbs + pik_value(p,"linewid",7,0)*pDist->rRel;
5445 if( !pElem->type->isLine ){
5446 pik_error(p, pErr, "use with line-oriented objects only");
5447 return;
5448 }
5449 pik_reset_samepath(p);
5450 do{
@@ -5460,19 +5565,19 @@
5460 return;
5461 }else{
5462 rHdg = pik_hdg_angle[pEdgept->eEdge];
5463 }
5464 if( rHdg<=45.0 ){
5465 pElem->outDir = DIR_UP;
5466 }else if( rHdg<=135.0 ){
5467 pElem->outDir = DIR_RIGHT;
5468 }else if( rHdg<=225.0 ){
5469 pElem->outDir = DIR_DOWN;
5470 }else if( rHdg<=315.0 ){
5471 pElem->outDir = DIR_LEFT;
5472 }else{
5473 pElem->outDir = DIR_UP;
5474 }
5475 rHdg *= 0.017453292519943295769; /* degrees to radians */
5476 p->aTPath[n].x += rDist*sin(rHdg);
5477 p->aTPath[n].y += rDist*cos(rHdg);
5478 p->mTPath = 2;
@@ -5484,13 +5589,13 @@
5484 ** pDir is the first keyword, "right" or "left" or "up" or "down".
5485 ** The movement is in that direction until its closest approach to
5486 ** the point specified by pPoint.
5487 */
5488 static void pik_evenwith(Pik *p, PToken *pDir, PPoint *pPlace){
5489 PElem *pElem = p->cur;
5490 int n;
5491 if( !pElem->type->isLine ){
5492 pik_error(p, pDir, "use with line-oriented objects only");
5493 return;
5494 }
5495 pik_reset_samepath(p);
5496 n = p->nTPath - 1;
@@ -5510,25 +5615,25 @@
5510 if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
5511 p->aTPath[n].x = pPlace->x;
5512 p->mTPath |= 1;
5513 break;
5514 }
5515 pElem->outDir = pDir->eCode;
5516 }
5517
5518 /* Set the "from" of an element
5519 */
5520 static void pik_set_from(Pik *p, PElem *pElem, PToken *pTk, PPoint *pPt){
5521 if( !pElem->type->isLine ){
5522 pik_error(p, pTk, "use \"at\" to position this object");
5523 return;
5524 }
5525 if( pElem->mProp & A_FROM ){
5526 pik_error(p, pTk, "line start location already fixed");
5527 return;
5528 }
5529 if( pElem->bClose ){
5530 pik_error(p, pTk, "polygon is closed");
5531 return;
5532 }
5533 if( p->nTPath>1 ){
5534 PNum dx = pPt->x - p->aTPath[0].x;
@@ -5539,22 +5644,22 @@
5539 p->aTPath[i].y += dy;
5540 }
5541 }
5542 p->aTPath[0] = *pPt;
5543 p->mTPath = 3;
5544 pElem->mProp |= A_FROM;
5545 }
5546
5547 /* Set the "to" of an element
5548 */
5549 static void pik_add_to(Pik *p, PElem *pElem, PToken *pTk, PPoint *pPt){
5550 int n = p->nTPath-1;
5551 if( !pElem->type->isLine ){
5552 pik_error(p, pTk, "use \"at\" to position this object");
5553 return;
5554 }
5555 if( pElem->bClose ){
5556 pik_error(p, pTk, "polygon is closed");
5557 return;
5558 }
5559 if( n==0 || p->mTPath==3 || p->thenFlag ){
5560 n = pik_next_rpath(p, pTk);
@@ -5562,65 +5667,70 @@
5562 p->aTPath[n] = *pPt;
5563 p->mTPath = 3;
5564 }
5565
5566 static void pik_close_path(Pik *p, PToken *pErr){
5567 PElem *pElem = p->cur;
5568 if( p->nTPath<3 ){
5569 pik_error(p, pErr,
5570 "need at least 3 vertexes in order to close the polygon");
5571 return;
5572 }
5573 if( pElem->bClose ){
5574 pik_error(p, pErr, "polygon already closed");
5575 return;
5576 }
5577 pElem->bClose = 1;
5578 }
5579
5580 /* Lower the layer of the current element so that it is behind the
5581 ** given element.
5582 */
5583 static void pik_behind(Pik *p, PElem *pOther){
5584 PElem *pElem = p->cur;
5585 if( p->nErr==0 && pElem->iLayer>=pOther->iLayer ){
5586 pElem->iLayer = pOther->iLayer - 1;
5587 }
5588 }
5589
5590
5591 /* Set the "at" of an element
5592 */
5593 static void pik_set_at(Pik *p, PToken *pEdge, PPoint *pAt, PToken *pErrTok){
5594 PElem *pElem;
 
5595 if( p->nErr ) return;
5596 pElem = p->cur;
5597
5598 if( pElem->type->isLine ){
5599 pik_error(p, pErrTok, "use \"from\" and \"to\" to position this object");
5600 return;
5601 }
5602 if( pElem->mProp & A_AT ){
5603 pik_error(p, pErrTok, "location fixed by prior \"at\"");
5604 return;
5605 }
5606 pElem->mProp |= A_AT;
5607 pElem->eWith = pEdge ? pEdge->eEdge : CP_C;
5608 pElem->with = *pAt;
 
 
 
 
5609 }
5610
5611 /*
5612 ** Try to add a text attribute to an element
5613 */
5614 static void pik_add_txt(Pik *p, PToken *pTxt, int iPos){
5615 PElem *pElem = p->cur;
5616 PToken *pT;
5617 if( pElem->nTxt >= count(pElem->aTxt) ){
5618 pik_error(p, pTxt, "too many text terms");
5619 return;
5620 }
5621 pT = &pElem->aTxt[pElem->nTxt++];
5622 *pT = *pTxt;
5623 pT->eCode = iPos;
5624 }
5625
5626 /* Merge "text-position" flags
@@ -5813,29 +5923,36 @@
5813 ** underestimates the text size.
5814 ** (4) Previously set attributes will not be altered. In other words,
5815 ** "width 1in fit" might cause the height to change, but the
5816 ** width is now set.
5817 ** (5) This only works for attributes that have an xFit method.
 
 
 
 
 
 
5818 */
5819 static void pik_size_to_fit(Pik *p, PToken *pFit){
5820 PElem *pElem;
5821 PNum w, h;
5822 PBox bbox;
5823 if( p->nErr ) return;
5824 pElem = p->cur;
5825
5826 if( pElem->nTxt==0 ){
5827 pik_error(0, pFit, "no text to fit to");
5828 return;
5829 }
5830 if( pElem->type->xFit==0 ) return;
5831 pik_bbox_init(&bbox);
5832 pik_compute_layout_settings(p);
5833 pik_append_txt(p, pElem, &bbox);
5834 w = (bbox.ne.x - bbox.sw.x) + p->charWidth;
5835 h = (bbox.ne.y - bbox.sw.y) + 0.5*p->charHeight;
5836 pElem->type->xFit(p, pElem, w, h);
 
5837 }
5838
5839 /* Set a local variable name to "val".
5840 **
5841 ** The name might be a built-in variable or a color name. In either case,
@@ -5988,15 +6105,15 @@
5988 }
5989 if( i==0 && pik_token_eq(pNth,"first")==0 ) i = 1;
5990 return i;
5991 }
5992
5993 /* Search for the NTH element.
5994 **
5995 ** If pBasis is not NULL then it should be a [] element. Use the
5996 ** sublist of that [] element for the search. If pBasis is not a []
5997 ** element, then throw an error.
5998 **
5999 ** The pNth token describes the N-th search. The pNth->eCode value
6000 ** is one more than the number of items to skip. It is negative
6001 ** to search backwards. If pNth->eType==T_ID, then it is the name
6002 ** of a class to search for. If pNth->eType==T_LB, then
@@ -6003,12 +6120,12 @@
6003 ** search for a [] object. If pNth->eType==T_LAST, then search for
6004 ** any type.
6005 **
6006 ** Raise an error if the item is not found.
6007 */
6008 static PElem *pik_find_nth(Pik *p, PElem *pBasis, PToken *pNth){
6009 PEList *pList;
6010 int i, n;
6011 const PClass *pClass;
6012 if( pBasis==0 ){
6013 pList = p->list;
6014 }else{
@@ -6030,34 +6147,34 @@
6030 }
6031 }
6032 n = pNth->eCode;
6033 if( n<0 ){
6034 for(i=pList->n-1; i>=0; i--){
6035 PElem *pElem = pList->a[i];
6036 if( pClass && pElem->type!=pClass ) continue;
6037 n++;
6038 if( n==0 ){ return pElem; }
6039 }
6040 }else{
6041 for(i=0; i<pList->n; i++){
6042 PElem *pElem = pList->a[i];
6043 if( pClass && pElem->type!=pClass ) continue;
6044 n--;
6045 if( n==0 ){ return pElem; }
6046 }
6047 }
6048 pik_error(p, pNth, "no such object");
6049 return 0;
6050 }
6051
6052 /* Search for an element by name.
6053 **
6054 ** Search in pBasis->pSublist if pBasis is not NULL. If pBasis is NULL
6055 ** then search in p->list.
6056 */
6057 static PElem *pik_find_byname(Pik *p, PElem *pBasis, PToken *pName){
6058 PEList *pList;
6059 int i, j;
6060 if( pBasis==0 ){
6061 pList = p->list;
6062 }else{
6063 pList = pBasis->pSublist;
@@ -6066,49 +6183,49 @@
6066 pik_error(p, pName, "no such object");
6067 return 0;
6068 }
6069 /* First look explicitly tagged objects */
6070 for(i=pList->n-1; i>=0; i--){
6071 PElem *pElem = pList->a[i];
6072 if( pElem->zName && pik_token_eq(pName,pElem->zName)==0 ){
6073 return pElem;
6074 }
6075 }
6076 /* If not found, do a second pass looking for any object containing
6077 ** text which exactly matches pName */
6078 for(i=pList->n-1; i>=0; i--){
6079 PElem *pElem = pList->a[i];
6080 for(j=0; j<pElem->nTxt; j++){
6081 if( pElem->aTxt[j].n==pName->n+2
6082 && memcmp(pElem->aTxt[j].z+1,pName->z,pName->n)==0 ){
6083 return pElem;
6084 }
6085 }
6086 }
6087 pik_error(p, pName, "no such object");
6088 return 0;
6089 }
6090
6091 /* Change most of the settings for the current object to be the
6092 ** same as the pOther object, or the most recent element of the same
6093 ** type if pOther is NULL.
6094 */
6095 static void pik_same(Pik *p, PElem *pOther, PToken *pErrTok){
6096 PElem *pElem = p->cur;
6097 if( p->nErr ) return;
6098 if( pOther==0 ){
6099 int i;
6100 for(i=(p->list ? p->list->n : 0)-1; i>=0; i--){
6101 pOther = p->list->a[i];
6102 if( pOther->type==pElem->type ) break;
6103 }
6104 if( i<0 ){
6105 pik_error(p, pErrTok, "no prior objects of the same type");
6106 return;
6107 }
6108 }
6109 if( pOther->nPath && pElem->type->isLine ){
6110 PNum dx, dy;
6111 int i;
6112 dx = p->aTPath[0].x - pOther->aPath[0].x;
6113 dy = p->aTPath[0].y - pOther->aPath[0].y;
6114 for(i=1; i<pOther->nPath; i++){
@@ -6117,53 +6234,53 @@
6117 }
6118 p->nTPath = pOther->nPath;
6119 p->mTPath = 3;
6120 p->samePath = 1;
6121 }
6122 if( !pElem->type->isLine ){
6123 pElem->w = pOther->w;
6124 pElem->h = pOther->h;
6125 }
6126 pElem->rad = pOther->rad;
6127 pElem->sw = pOther->sw;
6128 pElem->dashed = pOther->dashed;
6129 pElem->dotted = pOther->dotted;
6130 pElem->fill = pOther->fill;
6131 pElem->color = pOther->color;
6132 pElem->cw = pOther->cw;
6133 pElem->larrow = pOther->larrow;
6134 pElem->rarrow = pOther->rarrow;
6135 pElem->bClose = pOther->bClose;
6136 pElem->bChop = pOther->bChop;
6137 pElem->inDir = pOther->inDir;
6138 pElem->outDir = pOther->outDir;
6139 pElem->iLayer = pOther->iLayer;
6140 }
6141
6142
6143 /* Return a "Place" associated with element pElem. If pEdge is NULL
6144 ** return the center of the object. Otherwise, return the corner
6145 ** described by pEdge.
6146 */
6147 static PPoint pik_place_of_elem(Pik *p, PElem *pElem, PToken *pEdge){
6148 PPoint pt = cZeroPoint;
6149 const PClass *pClass;
6150 if( pElem==0 ) return pt;
6151 if( pEdge==0 ){
6152 return pElem->ptAt;
6153 }
6154 pClass = pElem->type;
6155 if( pEdge->eType==T_EDGEPT || (pEdge->eEdge>0 && pEdge->eEdge<CP_END) ){
6156 pt = pClass->xOffset(p, pElem, pEdge->eEdge);
6157 pt.x += pElem->ptAt.x;
6158 pt.y += pElem->ptAt.y;
6159 return pt;
6160 }
6161 if( pEdge->eType==T_START ){
6162 return pElem->ptEnter;
6163 }else{
6164 return pElem->ptExit;
6165 }
6166 }
6167
6168 /* Do a linear interpolation of two positions.
6169 */
@@ -6192,11 +6309,11 @@
6192 return pik_position_at_angle(dist, pik_hdg_angle[pD->eEdge], pt);
6193 }
6194
6195 /* Return the coordinates for the n-th vertex of a line.
6196 */
6197 static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PElem *pObj){
6198 static const PPoint zero;
6199 int n;
6200 if( p->nErr || pObj==0 ) return p->aTPath[0];
6201 if( !pObj->type->isLine ){
6202 pik_error(p, pErr, "object is not a line");
@@ -6210,28 +6327,28 @@
6210 return pObj->aPath[n-1];
6211 }
6212
6213 /* Return the value of a property of an object.
6214 */
6215 static PNum pik_property_of(PElem *pElem, PToken *pProp){
6216 PNum v = 0.0;
6217 switch( pProp->eType ){
6218 case T_HEIGHT: v = pElem->h; break;
6219 case T_WIDTH: v = pElem->w; break;
6220 case T_RADIUS: v = pElem->rad; break;
6221 case T_DIAMETER: v = pElem->rad*2.0; break;
6222 case T_THICKNESS: v = pElem->sw; break;
6223 case T_DASHED: v = pElem->dashed; break;
6224 case T_DOTTED: v = pElem->dotted; break;
6225 case T_FILL: v = pElem->fill; break;
6226 case T_COLOR: v = pElem->color; break;
6227 case T_X: v = pElem->ptAt.x; break;
6228 case T_Y: v = pElem->ptAt.y; break;
6229 case T_TOP: v = pElem->bbox.ne.y; break;
6230 case T_BOTTOM: v = pElem->bbox.sw.y; break;
6231 case T_LEFT: v = pElem->bbox.sw.x; break;
6232 case T_RIGHT: v = pElem->bbox.ne.x; break;
6233 }
6234 return v;
6235 }
6236
6237 /* Compute one of the built-in functions
@@ -6256,43 +6373,43 @@
6256 default: v = 0.0;
6257 }
6258 return v;
6259 }
6260
6261 /* Attach a name to an element
6262 */
6263 static void pik_elem_setname(Pik *p, PElem *pElem, PToken *pName){
6264 if( pElem==0 ) return;
6265 if( pName==0 ) return;
6266 free(pElem->zName);
6267 pElem->zName = malloc(pName->n+1);
6268 if( pElem->zName==0 ){
6269 pik_error(p,0,0);
6270 }else{
6271 memcpy(pElem->zName,pName->z,pName->n);
6272 pElem->zName[pName->n] = 0;
6273 }
6274 return;
6275 }
6276
6277 /*
6278 ** Search for object located at *pCenter that has an xChop method.
6279 ** Return a pointer to the object, or NULL if not found.
6280 */
6281 static PElem *pik_find_chopper(PEList *pList, PPoint *pCenter){
6282 int i;
6283 if( pList==0 ) return 0;
6284 for(i=pList->n-1; i>=0; i--){
6285 PElem *pElem = pList->a[i];
6286 if( pElem->type->xChop!=0
6287 && pElem->ptAt.x==pCenter->x
6288 && pElem->ptAt.y==pCenter->y
6289 ){
6290 return pElem;
6291 }else if( pElem->pSublist ){
6292 pElem = pik_find_chopper(pElem->pSublist,pCenter);
6293 if( pElem ) return pElem;
6294 }
6295 }
6296 return 0;
6297 }
6298
@@ -6302,180 +6419,199 @@
6302 ** If point pTo is the exact enter of a choppable object,
6303 ** then adjust pTo by the appropriate amount in the direction
6304 ** of pFrom.
6305 */
6306 static void pik_autochop(Pik *p, PPoint *pFrom, PPoint *pTo){
6307 PElem *pElem = pik_find_chopper(p->list, pTo);
6308 if( pElem ){
6309 *pTo = pElem->type->xChop(p, pElem, pFrom);
6310 }
6311 }
6312
6313 /* This routine runs after all attributes have been received
6314 ** on an element.
6315 */
6316 static void pik_after_adding_attributes(Pik *p, PElem *pElem){
6317 int i;
6318 PPoint ofst;
6319 PNum dx, dy;
6320
6321 if( p->nErr ) return;
6322
6323 /* Position block elements */
6324 if( pElem->type->isLine==0 ){
6325 ofst = pik_elem_offset(p, pElem, pElem->eWith);
6326 dx = (pElem->with.x - ofst.x) - pElem->ptAt.x;
6327 dy = (pElem->with.y - ofst.y) - pElem->ptAt.y;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6328 if( dx!=0 || dy!=0 ){
6329 pik_elem_move(pElem, dx, dy);
6330 }
6331 }
6332
6333 /* For a line object with no movement specified, a single movement
6334 ** of the default length in the current direction
6335 */
6336 if( pElem->type->isLine && p->nTPath<2 ){
6337 pik_next_rpath(p, 0);
6338 assert( p->nTPath==2 );
6339 switch( pElem->inDir ){
6340 default: p->aTPath[1].x += pElem->w; break;
6341 case DIR_DOWN: p->aTPath[1].y -= pElem->h; break;
6342 case DIR_LEFT: p->aTPath[1].x -= pElem->w; break;
6343 case DIR_UP: p->aTPath[1].y += pElem->h; break;
6344 }
6345 if( pElem->type->xInit==arcInit ){
6346 p->eDir = pElem->outDir = (pElem->inDir + (pElem->cw ? 1 : 3))%4;
6347 switch( pElem->outDir ){
6348 default: p->aTPath[1].x += pElem->w; break;
6349 case DIR_DOWN: p->aTPath[1].y -= pElem->h; break;
6350 case DIR_LEFT: p->aTPath[1].x -= pElem->w; break;
6351 case DIR_UP: p->aTPath[1].y += pElem->h; break;
6352 }
6353 }
6354 }
6355
6356 /* Initialize the bounding box prior to running xCheck */
6357 pik_bbox_init(&pElem->bbox);
6358
6359 /* Run object-specific code */
6360 if( pElem->type->xCheck!=0 ){
6361 pElem->type->xCheck(p,pElem);
6362 if( p->nErr ) return;
6363 }
6364
6365 /* Compute final bounding box, entry and exit points, center
6366 ** point (ptAt) and path for the element
6367 */
6368 if( pElem->type->isLine ){
6369 pElem->aPath = malloc( sizeof(PPoint)*p->nTPath );
6370 if( pElem->aPath==0 ){
6371 pik_error(p, 0, 0);
6372 return;
6373 }else{
6374 pElem->nPath = p->nTPath;
6375 for(i=0; i<p->nTPath; i++){
6376 pElem->aPath[i] = p->aTPath[i];
6377 }
6378 }
6379
6380 /* "chop" processing:
6381 ** If the line goes to the center of an object with an
6382 ** xChop method, then use the xChop method to trim the line.
6383 */
6384 if( pElem->bChop && pElem->nPath>=2 ){
6385 int n = pElem->nPath;
6386 pik_autochop(p, &pElem->aPath[n-2], &pElem->aPath[n-1]);
6387 pik_autochop(p, &pElem->aPath[1], &pElem->aPath[0]);
6388 }
6389
6390 pElem->ptEnter = pElem->aPath[0];
6391 pElem->ptExit = pElem->aPath[pElem->nPath-1];
6392
6393 /* Compute the center of the line based on the bounding box over
6394 ** the vertexes. This is a difference from PIC. In Pikchr, the
6395 ** center of a line is the center of its bounding box. In PIC, the
6396 ** center of a line is halfway between its .start and .end. For
6397 ** straight lines, this is the same point, but for multi-segment
6398 ** lines the result is usually diferent */
6399 for(i=0; i<pElem->nPath; i++){
6400 pik_bbox_add_xy(&pElem->bbox, pElem->aPath[i].x, pElem->aPath[i].y);
6401 }
6402 pElem->ptAt.x = (pElem->bbox.ne.x + pElem->bbox.sw.x)/2.0;
6403 pElem->ptAt.y = (pElem->bbox.ne.y + pElem->bbox.sw.y)/2.0;
6404
6405 /* Reset the width and height of the object to be the width and height
6406 ** of the bounding box over vertexes */
6407 pElem->w = pElem->bbox.ne.x - pElem->bbox.sw.x;
6408 pElem->h = pElem->bbox.ne.y - pElem->bbox.sw.y;
6409
6410 /* If this is a polygon (if it has the "close" attribute), then
6411 ** adjust the exit point */
6412 if( pElem->bClose ){
6413 /* For "closed" lines, the .end is one of the .e, .s, .w, or .n
6414 ** points of the bounding box, as with block objects. */
6415 pik_elem_set_exit(pElem, pElem->inDir);
6416 }
6417 }else{
6418 PNum w2 = pElem->w/2.0;
6419 PNum h2 = pElem->h/2.0;
6420 pElem->ptEnter = pElem->ptAt;
6421 pElem->ptExit = pElem->ptAt;
6422 switch( pElem->inDir ){
6423 default: pElem->ptEnter.x -= w2; break;
6424 case DIR_LEFT: pElem->ptEnter.x += w2; break;
6425 case DIR_UP: pElem->ptEnter.y -= h2; break;
6426 case DIR_DOWN: pElem->ptEnter.y += h2; break;
6427 }
6428 switch( pElem->outDir ){
6429 default: pElem->ptExit.x += w2; break;
6430 case DIR_LEFT: pElem->ptExit.x -= w2; break;
6431 case DIR_UP: pElem->ptExit.y += h2; break;
6432 case DIR_DOWN: pElem->ptExit.y -= h2; break;
6433 }
6434 pik_bbox_add_xy(&pElem->bbox, pElem->ptAt.x - w2, pElem->ptAt.y - h2);
6435 pik_bbox_add_xy(&pElem->bbox, pElem->ptAt.x + w2, pElem->ptAt.y + h2);
6436 }
6437 p->eDir = pElem->outDir;
6438 }
6439
6440 /* Show basic information about each element as a comment in the
6441 ** generated HTML. Used for testing and debugging. Activated
6442 ** by the (undocumented) "debug = 1;"
6443 ** command.
6444 */
6445 static void pik_elem_render(Pik *p, PElem *pElem){
6446 char *zDir;
6447 if( pElem==0 ) return;
6448 pik_append(p,"<!-- ", -1);
6449 if( pElem->zName ){
6450 pik_append_text(p, pElem->zName, -1, 0);
6451 pik_append(p, ": ", 2);
6452 }
6453 pik_append_text(p, pElem->type->zName, -1, 0);
6454 if( pElem->nTxt ){
6455 pik_append(p, " \"", 2);
6456 pik_append_text(p, pElem->aTxt[0].z+1, pElem->aTxt[0].n-2, 1);
6457 pik_append(p, "\"", 1);
6458 }
6459 pik_append_num(p, " w=", pElem->w);
6460 pik_append_num(p, " h=", pElem->h);
6461 pik_append_point(p, " center=", &pElem->ptAt);
6462 pik_append_point(p, " enter=", &pElem->ptEnter);
6463 switch( pElem->outDir ){
6464 default: zDir = " right"; break;
6465 case DIR_LEFT: zDir = " left"; break;
6466 case DIR_UP: zDir = " up"; break;
6467 case DIR_DOWN: zDir = " down"; break;
6468 }
6469 pik_append_point(p, " exit=", &pElem->ptExit);
6470 pik_append(p, zDir, -1);
6471 pik_append(p, " -->\n", -1);
6472 }
6473
6474 /* Render a list of elements
6475 */
6476 void pik_elist_render(Pik *p, PEList *pEList){
6477 int i;
6478 int iNextLayer = 0;
6479 int iThisLayer;
6480 int bMoreToDo;
6481 int miss = 0;
@@ -6483,75 +6619,75 @@
6483 PNum colorLabel;
6484 do{
6485 bMoreToDo = 0;
6486 iThisLayer = iNextLayer;
6487 iNextLayer = 0x7fffffff;
6488 for(i=0; i<pEList->n; i++){
6489 PElem *pElem = pEList->a[i];
6490 if( pElem->iLayer>iThisLayer ){
6491 if( pElem->iLayer<iNextLayer ) iNextLayer = pElem->iLayer;
6492 bMoreToDo = 1;
6493 continue; /* Defer until another round */
6494 }else if( pElem->iLayer<iThisLayer ){
6495 continue;
6496 }
6497 void (*xRender)(Pik*,PElem*);
6498 if( mDebug & 1 ) pik_elem_render(p, pElem);
6499 xRender = pElem->type->xRender;
6500 if( xRender ){
6501 xRender(p, pElem);
6502 }
6503 if( pElem->pSublist ){
6504 pik_elist_render(p, pElem->pSublist);
6505 }
6506 }
6507 }while( bMoreToDo );
6508
6509 /* If the color_debug_label value is defined, then go through
6510 ** and paint a dot at every label location */
6511 colorLabel = pik_value(p, "debug_label_color", 17, &miss);
6512 if( miss==0 && colorLabel>=0.0 ){
6513 PElem dot;
6514 memset(&dot, 0, sizeof(dot));
6515 dot.type = &noopClass;
6516 dot.rad = 0.015;
6517 dot.sw = 0.015;
6518 dot.fill = colorLabel;
6519 dot.color = colorLabel;
6520 dot.nTxt = 1;
6521 dot.aTxt[0].eCode = TP_ABOVE;
6522 for(i=0; i<pEList->n; i++){
6523 PElem *pElem = pEList->a[i];
6524 if( pElem->zName==0 ) continue;
6525 dot.ptAt = pElem->ptAt;
6526 dot.aTxt[0].z = pElem->zName;
6527 dot.aTxt[0].n = (int)strlen(pElem->zName);
6528 dotRender(p, &dot);
6529 }
6530 }
6531 }
6532
6533 /* Add all elements of the list pEList to the bounding box
6534 */
6535 static void pik_bbox_add_elist(Pik *p, PEList *pEList, PNum wArrow){
6536 int i;
6537 for(i=0; i<pEList->n; i++){
6538 PElem *pElem = pEList->a[i];
6539 if( pElem->sw>0.0 ) pik_bbox_addbox(&p->bbox, &pElem->bbox);
6540 pik_append_txt(p, pElem, &p->bbox);
6541 if( pElem->pSublist ) pik_bbox_add_elist(p, pElem->pSublist, wArrow);
6542
6543
6544 /* Expand the bounding box to account for arrowheads on lines */
6545 if( pElem->type->isLine && pElem->nPath>0 ){
6546 if( pElem->larrow ){
6547 pik_bbox_addellipse(&p->bbox, pElem->aPath[0].x, pElem->aPath[0].y,
6548 wArrow, wArrow);
6549 }
6550 if( pElem->rarrow ){
6551 int j = pElem->nPath-1;
6552 pik_bbox_addellipse(&p->bbox, pElem->aPath[j].x, pElem->aPath[j].y,
6553 wArrow, wArrow);
6554 }
6555 }
6556 }
6557 }
@@ -6574,15 +6710,15 @@
6574 p->charWidth = pik_value(p,"charwid",7,0)*p->fontScale;
6575 p->charHeight = pik_value(p,"charht",6,0)*p->fontScale;
6576 p->bLayoutVars = 1;
6577 }
6578
6579 /* Render a list of elements. Write the SVG into p->zOut.
6580 ** Delete the input element_list before returnning.
6581 */
6582 static void pik_render(Pik *p, PEList *pEList){
6583 if( pEList==0 ) return;
6584 if( p->nErr==0 ){
6585 PNum thickness; /* Stroke width */
6586 PNum margin; /* Extra bounding box margin */
6587 PNum w, h; /* Drawing width and height */
6588 PNum wArrow;
@@ -6597,11 +6733,11 @@
6597 wArrow = p->wArrow*thickness;
6598
6599 /* Compute a bounding box over all objects so that we can know
6600 ** how big to declare the SVG canvas */
6601 pik_bbox_init(&p->bbox);
6602 pik_bbox_add_elist(p, pEList, wArrow);
6603
6604 /* Expand the bounding box slightly to account for line thickness
6605 ** and the optional "margin = EXPR" setting. */
6606 p->bbox.ne.x += margin + pik_value(p,"rightmargin",11,0);
6607 p->bbox.ne.y += margin + pik_value(p,"topmargin",9,0);
@@ -6627,17 +6763,17 @@
6627 pik_append_num(p, "\" height=\"", p->hSVG);
6628 pik_append(p, "\"", 1);
6629 }
6630 pik_append_dis(p, " viewBox=\"0 0 ",w,"");
6631 pik_append_dis(p, " ",h,"\">\n");
6632 pik_elist_render(p, pEList);
6633 pik_append(p,"</svg>\n", -1);
6634 }else{
6635 p->wSVG = -1;
6636 p->hSVG = -1;
6637 }
6638 pik_elist_free(p, pEList);
6639 }
6640
6641
6642
6643 /*
@@ -6676,10 +6812,11 @@
6676 { "close", 5, T_CLOSE, 0, 0 },
6677 { "color", 5, T_COLOR, 0, 0 },
6678 { "cos", 3, T_FUNC1, FN_COS, 0 },
6679 { "cw", 2, T_CW, 0, 0 },
6680 { "dashed", 6, T_DASHED, 0, 0 },
 
6681 { "diameter", 8, T_DIAMETER, 0, 0 },
6682 { "dist", 4, T_DIST, 0, 0 },
6683 { "dotted", 6, T_DOTTED, 0, 0 },
6684 { "down", 4, T_DOWN, DIR_DOWN, 0 },
6685 { "e", 1, T_EDGEPT, 0, CP_E },
@@ -6745,11 +6882,11 @@
6745 { "y", 1, T_Y, 0, 0 },
6746 };
6747
6748 /*
6749 ** Search a PikWordlist for the given keyword. Return a pointer to the
6750 ** element found. Or return 0 if not found.
6751 */
6752 static const PikWord *pik_find_word(
6753 const char *zIn, /* Word to search for */
6754 int n, /* Length of zIn */
6755 const PikWord *aList, /* List to search */
@@ -6787,11 +6924,11 @@
6787 /*
6788 ** Return the length of next token. The token starts on
6789 ** the pToken->z character. Fill in other fields of the
6790 ** pToken object as appropriate.
6791 */
6792 static int pik_token_length(PToken *pToken){
6793 const unsigned char *z = (const unsigned char*)pToken->z;
6794 int i;
6795 unsigned char c, c2;
6796 switch( z[0] ){
6797 case '\\': {
@@ -6921,10 +7058,35 @@
6921 }else{
6922 pToken->eType = T_LT;
6923 return 1;
6924 }
6925 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6926 default: {
6927 c = z[0];
6928 if( c=='.' ){
6929 unsigned char c1 = z[1];
6930 if( islower(c1) ){
@@ -6981,19 +7143,20 @@
6981 if( nDigit==0 ){
6982 pToken->eType = T_ERROR;
6983 return i;
6984 }
6985 if( c=='e' || c=='E' ){
 
6986 i++;
6987 c2 = z[i];
6988 if( c2=='+' || c2=='-' ){
6989 i++;
6990 c2 = z[i];
6991 }
6992 if( c2<'0' || c>'9' ){
6993 /* This is not an exp */
6994 i -= 2;
6995 }else{
6996 i++;
6997 isInt = 0;
6998 while( (c = z[i])>='0' && c<='9' ){ i++; }
6999 }
@@ -7018,11 +7181,11 @@
7018 ){
7019 i += 2;
7020 }
7021 pToken->eType = T_NUMBER;
7022 return i;
7023 }else if( islower(c) || c=='_' || c=='$' || c=='@' ){
7024 const PikWord *pFound;
7025 for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7026 pFound = pik_find_word((const char*)z, i,
7027 pik_keywords, count(pik_keywords));
7028 if( pFound ){
@@ -7040,10 +7203,18 @@
7040 return i;
7041 }else if( c>='A' && c<='Z' ){
7042 for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7043 pToken->eType = T_PLACENAME;
7044 return i;
 
 
 
 
 
 
 
 
7045 }else{
7046 pToken->eType = T_ERROR;
7047 return 1;
7048 }
7049 }
@@ -7060,18 +7231,147 @@
7060 int i = pThis->n;
7061 memset(&x, 0, sizeof(x));
7062 x.z = pThis->z;
7063 while(1){
7064 x.z = pThis->z + i;
7065 sz = pik_token_length(&x);
7066 if( x.eType!=T_WHITESPACE ){
7067 x.n = sz;
7068 return x;
7069 }
7070 i += sz;
7071 }
7072 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7073
7074 /*
7075 ** Parse the PIKCHR script contained in zText[]. Return a rendering. Or
7076 ** if an error is encountered, return the error text. The error message
7077 ** is HTML formatted. So regardless of what happens, the return text
@@ -7092,52 +7392,26 @@
7092 const char *zClass, /* Add class="%s" to <svg> markup */
7093 unsigned int mFlags, /* Flags used to influence rendering behavior */
7094 int *pnWidth, /* Write width of <svg> here, if not NULL */
7095 int *pnHeight /* Write height here, if not NULL */
7096 ){
7097 int i;
7098 int sz;
7099 PToken token;
7100 Pik s;
7101 yyParser sParse;
7102
7103 memset(&s, 0, sizeof(s));
7104 s.zIn = zText;
7105 s.nIn = (unsigned int)strlen(zText);
7106 s.eDir = DIR_RIGHT;
7107 s.zClass = zClass;
7108 s.mFlags = mFlags;
7109 pik_parserInit(&sParse, &s);
7110 #if 0
7111 pik_parserTrace(stdout, "parser: ");
7112 #endif
7113 for(i=0; zText[i] && s.nErr==0; i+=sz){
7114 token.eCode = 0;
7115 token.eEdge = 0;
7116 token.z = zText + i;
7117 sz = pik_token_length(&token);
7118 if( token.eType==T_WHITESPACE ){
7119 /* no-op */
7120 }else if( sz>1000 ){
7121 token.n = 1;
7122 pik_error(&s, &token, "token is too long - max length 1000 bytes");
7123 break;
7124 }else if( token.eType==T_ERROR ){
7125 token.n = (unsigned short)(sz & 0xffff);
7126 pik_error(&s, &token, "unrecognized token");
7127 break;
7128 }else{
7129 #if 0
7130 printf("******** Token %s (%d): \"%.*s\" **************\n",
7131 yyTokenName[token.eType], token.eType,
7132 isspace(token.z[0]) ? 0 : token.n, token.z);
7133 #endif
7134 token.n = (unsigned short)(sz & 0xffff);
7135 pik_parser(&sParse, token.eType, token);
7136 }
7137 }
7138 if( s.nErr==0 ){
 
7139 memset(&token,0,sizeof(token));
7140 token.z = zText;
7141 pik_parser(&sParse, 0, token);
7142 }
7143 pik_parserFinalize(&sParse);
@@ -7147,10 +7421,15 @@
7147 while( s.pVar ){
7148 PVar *pNext = s.pVar->pNext;
7149 free(s.pVar);
7150 s.pVar = pNext;
7151 }
 
 
 
 
 
7152 if( pnWidth ) *pnWidth = s.nErr ? -1 : s.wSVG;
7153 if( pnHeight ) *pnHeight = s.nErr ? -1 : s.hSVG;
7154 if( s.zOut ){
7155 s.zOut[s.nOut] = 0;
7156 s.zOut = realloc(s.zOut, s.nOut+1);
@@ -7317,6 +7596,6 @@
7317 }
7318 return 0;
7319 }
7320 #endif /* PIKCHR_SHELL */
7321
7322 #line 7347 "pikchr.c"
7323
--- src/pikchr.c
+++ src/pikchr.c
@@ -68,47 +68,47 @@
68 **
69 ** Each call to pikchr() uses a single instance of the Pik structure to
70 ** track its internal state. The Pik structure lives for the duration
71 ** of the pikchr() call.
72 **
73 ** The input is a sequence of objects or "statements". Each statement is
74 ** parsed into a PObj object. These are stored on an extensible array
75 ** called PList. All parameters to each PObj are computed as the
76 ** object is parsed. (Hence, the parameters to a PObj may only refer
77 ** to prior statements.) Once the PObj is completely assembled, it is
78 ** added to the end of a PList and never changes thereafter - except,
79 ** PObj objects that are part of a "[...]" block might have their
80 ** absolute position shifted when the outer [...] block is positioned.
81 ** But apart from this repositioning, PObj objects are unchanged once
82 ** they are added to the list. The order of statements on a PList does
83 ** not change.
84 **
85 ** After all input has been parsed, the top-level PList is walked to
86 ** generate output. Sub-lists resulting from [...] blocks are scanned
87 ** as they are encountered. All input must be collected and parsed ahead
88 ** of output generation because the size and position of statements must be
89 ** known in order to compute a bounding box on the output.
90 **
91 ** Each PObj is on a "layer". (The common case is that all PObj's are
92 ** on a single layer, but multiple layers are possible.) A separate pass
93 ** is made through the list for each layer.
94 **
95 ** After all output is generated, the Pik object and all the PList
96 ** and PObj objects are deallocated and the generated output string is
97 ** returned. Upon any error, the Pik.nErr flag is set, processing quickly
98 ** stops, and the stack unwinds. No attempt is made to continue reading
99 ** input after an error.
100 **
101 ** Most statements begin with a class name like "box" or "arrow" or "move".
102 ** There is a class named "text" which is used for statements that begin
103 ** with a string literal. You can also specify the "text" class.
104 ** A Sublist ("[...]") is a single object that contains a pointer to
105 ** its substatements, all gathered onto a separate PList object.
106 **
107 ** Variables go into PVar objects that form a linked list.
108 **
109 ** Each PObj has zero or one names. Input constructs that attempt
110 ** to assign a new name from an older name, for example:
111 **
112 ** Abc: Abc + (0.5cm, 0)
113 **
114 ** Statements like these generate a new "noop" object at the specified
@@ -131,18 +131,19 @@
131 ** compiler warnings with -Wextra */
132 #define UNUSED_PARAMETER(X) (void)(X)
133
134 typedef struct Pik Pik; /* Complete parsing context */
135 typedef struct PToken PToken; /* A single token */
136 typedef struct PObj PObj; /* A single diagram object */
137 typedef struct PList PList; /* A list of diagram objects */
138 typedef struct PClass PClass; /* Description of statements types */
139 typedef double PNum; /* Numeric value */
140 typedef struct PRel PRel; /* Absolute or percentage value */
141 typedef struct PPoint PPoint; /* A position in 2-D space */
142 typedef struct PVar PVar; /* script-defined variable */
143 typedef struct PBox PBox; /* A bounding box */
144 typedef struct PMacro PMacro; /* A "define" macro */
145
146 /* Compass points */
147 #define CP_N 1
148 #define CP_NE 2
149 #define CP_E 3
@@ -181,15 +182,15 @@
182 /* Text position and style flags. Stored in PToken.eCode so limited
183 ** to 15 bits. */
184 #define TP_LJUST 0x0001 /* left justify...... */
185 #define TP_RJUST 0x0002 /* ...Right justify */
186 #define TP_JMASK 0x0003 /* Mask for justification bits */
187 #define TP_ABOVE2 0x0004 /* Position text way above PObj.ptAt */
188 #define TP_ABOVE 0x0008 /* Position text above PObj.ptAt */
189 #define TP_CENTER 0x0010 /* On the line */
190 #define TP_BELOW 0x0020 /* Position text below PObj.ptAt */
191 #define TP_BELOW2 0x0040 /* Position text way below PObj.ptAt */
192 #define TP_VMASK 0x007c /* Mask for text positioning flags */
193 #define TP_BIG 0x0100 /* Larger font */
194 #define TP_SMALL 0x0200 /* Smaller font */
195 #define TP_XTRA 0x0400 /* Amplify TP_BIG or TP_SMALL */
196 #define TP_SZMASK 0x0700 /* Font size mask */
@@ -254,10 +255,11 @@
255 }
256
257 /* Extra token types not generated by LEMON but needed by the
258 ** tokenizer
259 */
260 #define T_PARAMETER 253 /* $1, $2, ..., $9 */
261 #define T_WHITESPACE 254 /* Whitespace of comments */
262 #define T_ERROR 255 /* Any text that is not a valid token */
263
264 /* Directions of movement */
265 #define DIR_RIGHT 0
@@ -266,12 +268,12 @@
268 #define DIR_UP 3
269 #define ValidDir(X) ((X)>=0 && (X)<=3)
270 #define IsUpDown(X) (((X)&1)==1)
271 #define IsLeftRight(X) (((X)&1)==0)
272
273 /* Bitmask for the various attributes for PObj. These bits are
274 ** collected in PObj.mProp and PObj.mCalc to check for constraint
275 ** errors. */
276 #define A_WIDTH 0x0001
277 #define A_HEIGHT 0x0002
278 #define A_RADIUS 0x0004
279 #define A_THICKNESS 0x0008
@@ -281,20 +283,21 @@
283 #define A_ARROW 0x0080
284 #define A_FROM 0x0100
285 #define A_CW 0x0200
286 #define A_AT 0x0400
287 #define A_TO 0x0800 /* one or more movement attributes */
288 #define A_FIT 0x1000
289
290
291 /* A single graphics object */
292 struct PObj {
293 const PClass *type; /* Object type or class */
294 PToken errTok; /* Reference token for error messages */
295 PPoint ptAt; /* Reference point for the object */
296 PPoint ptEnter, ptExit; /* Entry and exit points */
297 PList *pSublist; /* Substructure for [...] objects */
298 char *zName; /* Name assigned to this statement */
299 PNum w; /* "width" property */
300 PNum h; /* "height" property */
301 PNum rad; /* "radius" property */
302 PNum sw; /* "thickness" property. (Mnemonic: "stroke width")*/
303 PNum dotted; /* "dotted" property. <=0.0 for off */
@@ -317,33 +320,41 @@
320 int nPath; /* Number of path points */
321 PPoint *aPath; /* Array of path points */
322 PBox bbox; /* Bounding box */
323 };
324
325 /* A list of graphics objects */
326 struct PList {
327 int n; /* Number of statements in the list */
328 int nAlloc; /* Allocated slots in a[] */
329 PObj **a; /* Pointers to individual objects */
330 };
331
332 /* A macro definition */
333 struct PMacro {
334 PMacro *pNext; /* Next in the list */
335 PToken macroName; /* Name of the macro */
336 PToken macroBody; /* Body of the macro */
337 int inUse; /* Do not allow recursion */
338 };
339
340 /* Each call to the pikchr() subroutine uses an instance of the following
341 ** object to pass around context to all of its subroutines.
342 */
343 struct Pik {
344 unsigned nErr; /* Number of errors seen */
345 PToken sIn; /* Input Pikchr-language text */
 
346 char *zOut; /* Result accumulates here */
347 unsigned int nOut; /* Bytes written to zOut[] so far */
348 unsigned int nOutAlloc; /* Space allocated to zOut[] */
349 unsigned char eDir; /* Current direction */
350 unsigned int mFlags; /* Flags passed to pikchr() */
351 PObj *cur; /* Object under construction */
352 PList *list; /* Object list under construction */
353 PMacro *pMacros; /* List of all defined macros */
354 PVar *pVar; /* Application-defined variables */
355 PBox bbox; /* Bounding box around all statements */
356 /* Cache of layout values. <=0.0 for unknown... */
357 PNum rScale; /* Multiply to convert inches to pixels */
358 PNum fontScale; /* Scale fonts by this percent */
359 PNum charWidth; /* Character width */
360 PNum charHeight; /* Character height */
@@ -353,14 +364,17 @@
364 char thenFlag; /* True if "then" seen */
365 char samePath; /* aTPath copied by "same" */
366 const char *zClass; /* Class name for the <svg> */
367 int wSVG, hSVG; /* Width and height of the <svg> */
368 /* Paths for lines are constructed here first, then transferred into
369 ** the PObj object at the end: */
370 int nTPath; /* Number of entries on aTPath[] */
371 int mTPath; /* For last entry, 1: x set, 2: y set */
372 PPoint aTPath[1000]; /* Path under construction */
373 /* Error contexts */
374 unsigned int nCtx; /* Number of error contexts */
375 PToken aCtx[10]; /* Nested error contexts */
376 };
377
378
379 /*
380 ** The behavior of an object class is defined by an instance of
@@ -368,17 +382,17 @@
382 */
383 struct PClass {
384 const char *zName; /* Name of class */
385 char isLine; /* True if a line class */
386 char eJust; /* Use box-style text justification */
387 void (*xInit)(Pik*,PObj*); /* Initializer */
388 void (*xNumProp)(Pik*,PObj*,PToken*); /* Value change notification */
389 void (*xCheck)(Pik*,PObj*); /* Checks to do after parsing */
390 PPoint (*xChop)(Pik*,PObj*,PPoint*); /* Chopper */
391 PPoint (*xOffset)(Pik*,PObj*,int); /* Offset from .c to edge point */
392 void (*xFit)(Pik*,PObj*,PNum w,PNum h); /* Size to fit text */
393 void (*xRender)(Pik*,PObj*); /* Render */
394 };
395
396
397 /* Forward declarations */
398 static void pik_append(Pik*, const char*,int);
@@ -389,70 +403,71 @@
403 static void pik_append_y(Pik*,const char*,PNum,const char*);
404 static void pik_append_xy(Pik*,const char*,PNum,PNum);
405 static void pik_append_dis(Pik*,const char*,PNum,const char*);
406 static void pik_append_arc(Pik*,PNum,PNum,PNum,PNum);
407 static void pik_append_clr(Pik*,const char*,PNum,const char*);
408 static void pik_append_style(Pik*,PObj*,int);
409 static void pik_append_txt(Pik*,PObj*, PBox*);
410 static void pik_draw_arrowhead(Pik*,PPoint*pFrom,PPoint*pTo,PObj*);
411 static void pik_chop(PPoint*pFrom,PPoint*pTo,PNum);
412 static void pik_error(Pik*,PToken*,const char*);
413 static void pik_elist_free(Pik*,PList*);
414 static void pik_elem_free(Pik*,PObj*);
415 static void pik_render(Pik*,PList*);
416 static PList *pik_elist_append(Pik*,PList*,PObj*);
417 static PObj *pik_elem_new(Pik*,PToken*,PToken*,PList*);
418 static void pik_set_direction(Pik*,int);
419 static void pik_elem_setname(Pik*,PObj*,PToken*);
420 static void pik_set_var(Pik*,PToken*,PNum,PToken*);
421 static PNum pik_value(Pik*,const char*,int,int*);
422 static PNum pik_lookup_color(Pik*,PToken*);
423 static PNum pik_get_var(Pik*,PToken*);
424 static PNum pik_atof(PToken*);
425 static void pik_after_adding_attributes(Pik*,PObj*);
426 static void pik_elem_move(PObj*,PNum dx, PNum dy);
427 static void pik_elist_move(PList*,PNum dx, PNum dy);
428 static void pik_set_numprop(Pik*,PToken*,PRel*);
429 static void pik_set_clrprop(Pik*,PToken*,PNum);
430 static void pik_set_dashed(Pik*,PToken*,PNum*);
431 static void pik_then(Pik*,PToken*,PObj*);
432 static void pik_add_direction(Pik*,PToken*,PRel*);
433 static void pik_move_hdg(Pik*,PRel*,PToken*,PNum,PToken*,PToken*);
434 static void pik_evenwith(Pik*,PToken*,PPoint*);
435 static void pik_set_from(Pik*,PObj*,PToken*,PPoint*);
436 static void pik_add_to(Pik*,PObj*,PToken*,PPoint*);
437 static void pik_close_path(Pik*,PToken*);
438 static void pik_set_at(Pik*,PToken*,PPoint*,PToken*);
439 static short int pik_nth_value(Pik*,PToken*);
440 static PObj *pik_find_nth(Pik*,PObj*,PToken*);
441 static PObj *pik_find_byname(Pik*,PObj*,PToken*);
442 static PPoint pik_place_of_elem(Pik*,PObj*,PToken*);
443 static int pik_bbox_isempty(PBox*);
444 static void pik_bbox_init(PBox*);
445 static void pik_bbox_addbox(PBox*,PBox*);
446 static void pik_bbox_add_xy(PBox*,PNum,PNum);
447 static void pik_bbox_addellipse(PBox*,PNum x,PNum y,PNum rx,PNum ry);
448 static void pik_add_txt(Pik*,PToken*,int);
449 static int pik_text_length(const PToken *pToken);
450 static void pik_size_to_fit(Pik*,PToken*,int);
451 static int pik_text_position(int,PToken*);
452 static PNum pik_property_of(PObj*,PToken*);
453 static PNum pik_func(Pik*,PToken*,PNum,PNum);
454 static PPoint pik_position_between(PNum x, PPoint p1, PPoint p2);
455 static PPoint pik_position_at_angle(PNum dist, PNum r, PPoint pt);
456 static PPoint pik_position_at_hdg(PNum dist, PToken *pD, PPoint pt);
457 static void pik_same(Pik *p, PObj*, PToken*);
458 static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PObj *pObj);
459 static PToken pik_next_semantic_token(PToken *pThis);
460 static void pik_compute_layout_settings(Pik*);
461 static void pik_behind(Pik*,PObj*);
462 static PObj *pik_assert(Pik*,PNum,PToken*,PNum);
463 static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
464 static PNum pik_dist(PPoint*,PPoint*);
465 static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
466
467
468 #line 494 "pikchr.c"
469 /**************** End of %include directives **********************************/
470 /* These constants specify the various numeric values for terminal symbols.
471 ***************** Begin token definitions *************************************/
472 #ifndef T_ID
473 #define T_ID 1
@@ -470,87 +485,89 @@
485 #define T_COLON 13
486 #define T_ASSERT 14
487 #define T_LP 15
488 #define T_EQ 16
489 #define T_RP 17
490 #define T_DEFINE 18
491 #define T_CODEBLOCK 19
492 #define T_FILL 20
493 #define T_COLOR 21
494 #define T_THICKNESS 22
495 #define T_PRINT 23
496 #define T_STRING 24
497 #define T_COMMA 25
498 #define T_CLASSNAME 26
499 #define T_LB 27
500 #define T_RB 28
501 #define T_UP 29
502 #define T_DOWN 30
503 #define T_LEFT 31
504 #define T_RIGHT 32
505 #define T_CLOSE 33
506 #define T_CHOP 34
507 #define T_FROM 35
508 #define T_TO 36
509 #define T_THEN 37
510 #define T_HEADING 38
511 #define T_GO 39
512 #define T_AT 40
513 #define T_WITH 41
514 #define T_SAME 42
515 #define T_AS 43
516 #define T_FIT 44
517 #define T_BEHIND 45
518 #define T_UNTIL 46
519 #define T_EVEN 47
520 #define T_DOT_E 48
521 #define T_HEIGHT 49
522 #define T_WIDTH 50
523 #define T_RADIUS 51
524 #define T_DIAMETER 52
525 #define T_DOTTED 53
526 #define T_DASHED 54
527 #define T_CW 55
528 #define T_CCW 56
529 #define T_LARROW 57
530 #define T_RARROW 58
531 #define T_LRARROW 59
532 #define T_INVIS 60
533 #define T_THICK 61
534 #define T_THIN 62
535 #define T_CENTER 63
536 #define T_LJUST 64
537 #define T_RJUST 65
538 #define T_ABOVE 66
539 #define T_BELOW 67
540 #define T_ITALIC 68
541 #define T_BOLD 69
542 #define T_ALIGNED 70
543 #define T_BIG 71
544 #define T_SMALL 72
545 #define T_AND 73
546 #define T_LT 74
547 #define T_GT 75
548 #define T_ON 76
549 #define T_WAY 77
550 #define T_BETWEEN 78
551 #define T_THE 79
552 #define T_NTH 80
553 #define T_VERTEX 81
554 #define T_TOP 82
555 #define T_BOTTOM 83
556 #define T_START 84
557 #define T_END 85
558 #define T_IN 86
559 #define T_DOT_U 87
560 #define T_LAST 88
561 #define T_NUMBER 89
562 #define T_FUNC1 90
563 #define T_FUNC2 91
564 #define T_DIST 92
565 #define T_DOT_XY 93
566 #define T_X 94
567 #define T_Y 95
568 #define T_DOT_L 96
569 #endif
570 /**************** End token definitions ***************************************/
571
572 /* The next sections is a series of control #defines.
573 ** various aspects of the generated parser.
@@ -606,22 +623,22 @@
623 #ifndef INTERFACE
624 # define INTERFACE 1
625 #endif
626 /************* Begin control #defines *****************************************/
627 #define YYCODETYPE unsigned char
628 #define YYNOCODE 133
629 #define YYACTIONTYPE unsigned short int
630 #define pik_parserTOKENTYPE PToken
631 typedef union {
632 int yyinit;
633 pik_parserTOKENTYPE yy0;
634 int yy46;
635 PPoint yy47;
636 PNum yy121;
637 PRel yy134;
638 PObj* yy138;
639 PList* yy191;
640 } YYMINORTYPE;
641 #ifndef YYSTACKDEPTH
642 #define YYSTACKDEPTH 100
643 #endif
644 #define pik_parserARG_SDECL
@@ -633,22 +650,22 @@
650 #define pik_parserCTX_PDECL ,Pik *p
651 #define pik_parserCTX_PARAM ,p
652 #define pik_parserCTX_FETCH Pik *p=yypParser->p;
653 #define pik_parserCTX_STORE yypParser->p=p;
654 #define YYFALLBACK 1
655 #define YYNSTATE 164
656 #define YYNRULE 154
657 #define YYNRULE_WITH_ACTION 114
658 #define YYNTOKEN 97
659 #define YY_MAX_SHIFT 163
660 #define YY_MIN_SHIFTREDUCE 285
661 #define YY_MAX_SHIFTREDUCE 438
662 #define YY_ERROR_ACTION 439
663 #define YY_ACCEPT_ACTION 440
664 #define YY_NO_ACTION 441
665 #define YY_MIN_REDUCE 442
666 #define YY_MAX_REDUCE 595
667 /************* End control #defines *******************************************/
668 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
669
670 /* Define the yytestcase() macro to be a no-op if is not already defined
671 ** otherwise.
@@ -711,328 +728,324 @@
728 ** yy_reduce_ofst[] For each state, the offset into yy_action for
729 ** shifting non-terminals after a reduce.
730 ** yy_default[] Default action for each state.
731 **
732 *********** Begin parsing tables **********************************************/
733 #define YY_ACTTAB_COUNT (1223)
734 static const YYACTIONTYPE yy_action[] = {
735 /* 0 */ 569, 491, 161, 119, 25, 448, 29, 74, 129, 148,
736 /* 10 */ 569, 488, 161, 119, 449, 113, 120, 161, 119, 525,
737 /* 20 */ 423, 424, 337, 553, 81, 36, 554, 555, 569, 64,
738 /* 30 */ 63, 62, 61, 320, 321, 9, 8, 33, 149, 32,
739 /* 40 */ 7, 71, 127, 308, 333, 66, 523, 161, 119, 337,
740 /* 50 */ 337, 337, 337, 421, 422, 338, 339, 340, 341, 342,
741 /* 60 */ 343, 344, 345, 470, 64, 63, 62, 61, 311, 28,
742 /* 70 */ 73, 304, 148, 470, 528, 161, 119, 112, 113, 120,
743 /* 80 */ 161, 119, 128, 423, 424, 337, 354, 81, 526, 161,
744 /* 90 */ 119, 470, 374, 158, 13, 30, 320, 321, 9, 8,
745 /* 100 */ 33, 149, 32, 7, 71, 127, 372, 333, 66, 573,
746 /* 110 */ 328, 31, 337, 337, 337, 337, 421, 422, 338, 339,
747 /* 120 */ 340, 341, 342, 343, 344, 345, 390, 431, 326, 59,
748 /* 130 */ 60, 407, 408, 409, 410, 374, 158, 372, 35, 390,
749 /* 140 */ 2, 38, 59, 60, 48, 37, 46, 162, 442, 80,
750 /* 150 */ 372, 306, 79, 42, 118, 83, 437, 436, 36, 390,
751 /* 160 */ 431, 84, 59, 60, 47, 297, 571, 77, 571, 122,
752 /* 170 */ 372, 296, 390, 2, 108, 59, 60, 76, 156, 156,
753 /* 180 */ 156, 3, 117, 372, 132, 130, 42, 69, 430, 437,
754 /* 190 */ 436, 4, 390, 431, 67, 59, 60, 118, 64, 63,
755 /* 200 */ 62, 61, 5, 372, 6, 106, 2, 432, 433, 434,
756 /* 210 */ 435, 387, 1, 117, 389, 155, 154, 153, 106, 49,
757 /* 220 */ 420, 430, 437, 436, 107, 65, 117, 389, 155, 154,
758 /* 230 */ 153, 54, 51, 120, 161, 119, 419, 459, 106, 131,
759 /* 240 */ 432, 433, 434, 435, 78, 78, 117, 389, 155, 154,
760 /* 250 */ 153, 106, 393, 390, 430, 152, 59, 60, 11, 117,
761 /* 260 */ 389, 155, 154, 153, 102, 376, 157, 42, 394, 395,
762 /* 270 */ 69, 106, 353, 432, 433, 434, 435, 375, 159, 117,
763 /* 280 */ 389, 155, 154, 153, 142, 140, 64, 63, 62, 61,
764 /* 290 */ 12, 64, 63, 62, 61, 62, 61, 428, 45, 138,
765 /* 300 */ 139, 142, 140, 64, 63, 62, 61, 55, 64, 63,
766 /* 310 */ 62, 61, 426, 147, 146, 390, 387, 44, 59, 60,
767 /* 320 */ 43, 295, 15, 14, 55, 16, 102, 18, 19, 42,
768 /* 330 */ 147, 146, 106, 20, 299, 300, 301, 43, 303, 68,
769 /* 340 */ 117, 389, 155, 154, 153, 444, 450, 29, 22, 21,
770 /* 350 */ 114, 446, 356, 23, 26, 57, 24, 58, 145, 141,
771 /* 360 */ 427, 388, 163, 380, 373, 22, 21, 27, 160, 378,
772 /* 370 */ 70, 379, 39, 24, 441, 145, 141, 427, 142, 140,
773 /* 380 */ 64, 63, 62, 61, 347, 347, 347, 347, 347, 347,
774 /* 390 */ 347, 347, 347, 347, 106, 441, 441, 64, 63, 62,
775 /* 400 */ 61, 55, 117, 389, 155, 154, 153, 147, 146, 399,
776 /* 410 */ 387, 441, 441, 441, 43, 441, 441, 441, 52, 441,
777 /* 420 */ 133, 441, 126, 441, 441, 441, 123, 441, 400, 401,
778 /* 430 */ 402, 404, 80, 441, 306, 79, 441, 407, 408, 409,
779 /* 440 */ 410, 441, 22, 21, 390, 441, 441, 59, 60, 441,
780 /* 450 */ 24, 441, 145, 141, 427, 372, 441, 441, 42, 441,
781 /* 460 */ 441, 441, 441, 156, 156, 156, 390, 469, 441, 59,
782 /* 470 */ 60, 390, 143, 441, 59, 60, 441, 372, 441, 529,
783 /* 480 */ 42, 441, 372, 441, 441, 42, 441, 390, 144, 441,
784 /* 490 */ 59, 60, 441, 390, 441, 441, 59, 60, 372, 441,
785 /* 500 */ 441, 42, 441, 469, 372, 88, 390, 40, 441, 59,
786 /* 510 */ 60, 441, 441, 441, 120, 161, 119, 372, 529, 441,
787 /* 520 */ 41, 82, 441, 106, 529, 441, 441, 529, 462, 441,
788 /* 530 */ 34, 117, 389, 155, 154, 153, 152, 85, 64, 63,
789 /* 540 */ 62, 61, 441, 441, 441, 106, 120, 161, 119, 441,
790 /* 550 */ 106, 441, 441, 117, 389, 155, 154, 153, 117, 389,
791 /* 560 */ 155, 154, 153, 441, 441, 441, 106, 441, 152, 17,
792 /* 570 */ 441, 441, 106, 441, 117, 389, 155, 154, 153, 431,
793 /* 580 */ 117, 389, 155, 154, 153, 106, 441, 423, 424, 337,
794 /* 590 */ 441, 441, 86, 117, 389, 155, 154, 153, 441, 441,
795 /* 600 */ 441, 120, 161, 119, 121, 443, 450, 29, 437, 436,
796 /* 610 */ 441, 446, 64, 63, 62, 61, 337, 337, 337, 337,
797 /* 620 */ 421, 422, 163, 152, 441, 75, 440, 27, 109, 443,
798 /* 630 */ 450, 29, 441, 50, 74, 446, 148, 441, 441, 441,
799 /* 640 */ 430, 124, 113, 120, 161, 119, 163, 72, 441, 148,
800 /* 650 */ 441, 27, 431, 441, 125, 113, 120, 161, 119, 432,
801 /* 660 */ 433, 434, 435, 441, 74, 149, 148, 64, 63, 62,
802 /* 670 */ 61, 493, 113, 120, 161, 119, 441, 74, 149, 148,
803 /* 680 */ 352, 437, 436, 441, 492, 113, 120, 161, 119, 74,
804 /* 690 */ 441, 148, 441, 441, 98, 149, 486, 113, 120, 161,
805 /* 700 */ 119, 441, 441, 120, 161, 119, 441, 74, 149, 148,
806 /* 710 */ 441, 441, 441, 430, 480, 113, 120, 161, 119, 74,
807 /* 720 */ 149, 148, 441, 441, 441, 152, 479, 113, 120, 161,
808 /* 730 */ 119, 88, 432, 433, 434, 435, 441, 441, 149, 441,
809 /* 740 */ 120, 161, 119, 441, 74, 441, 148, 110, 110, 441,
810 /* 750 */ 149, 476, 113, 120, 161, 119, 74, 441, 148, 107,
811 /* 760 */ 441, 441, 152, 134, 113, 120, 161, 119, 120, 161,
812 /* 770 */ 119, 441, 459, 441, 74, 149, 148, 441, 441, 441,
813 /* 780 */ 563, 512, 113, 120, 161, 119, 74, 149, 148, 441,
814 /* 790 */ 152, 441, 441, 137, 113, 120, 161, 119, 441, 74,
815 /* 800 */ 441, 148, 441, 441, 441, 149, 520, 113, 120, 161,
816 /* 810 */ 119, 74, 441, 148, 441, 441, 88, 149, 522, 113,
817 /* 820 */ 120, 161, 119, 441, 441, 120, 161, 119, 441, 74,
818 /* 830 */ 149, 148, 111, 111, 441, 441, 519, 113, 120, 161,
819 /* 840 */ 119, 441, 149, 441, 441, 441, 74, 152, 148, 441,
820 /* 850 */ 441, 441, 88, 521, 113, 120, 161, 119, 441, 441,
821 /* 860 */ 149, 120, 161, 119, 441, 74, 441, 148, 471, 441,
822 /* 870 */ 441, 441, 518, 113, 120, 161, 119, 149, 74, 441,
823 /* 880 */ 148, 441, 441, 152, 441, 517, 113, 120, 161, 119,
824 /* 890 */ 74, 441, 148, 441, 441, 441, 149, 516, 113, 120,
825 /* 900 */ 161, 119, 441, 74, 441, 148, 441, 441, 441, 149,
826 /* 910 */ 515, 113, 120, 161, 119, 74, 441, 148, 89, 441,
827 /* 920 */ 441, 149, 514, 113, 120, 161, 119, 120, 161, 119,
828 /* 930 */ 441, 74, 441, 148, 149, 441, 441, 441, 150, 113,
829 /* 940 */ 120, 161, 119, 441, 441, 441, 149, 441, 74, 152,
830 /* 950 */ 148, 441, 441, 441, 90, 151, 113, 120, 161, 119,
831 /* 960 */ 441, 441, 149, 120, 161, 119, 441, 74, 441, 148,
832 /* 970 */ 64, 63, 62, 61, 136, 113, 120, 161, 119, 149,
833 /* 980 */ 74, 441, 148, 351, 441, 152, 441, 135, 113, 120,
834 /* 990 */ 161, 119, 88, 64, 63, 62, 61, 441, 149, 441,
835 /* 1000 */ 441, 120, 161, 119, 441, 107, 392, 10, 475, 475,
836 /* 1010 */ 441, 149, 441, 441, 120, 161, 119, 107, 474, 64,
837 /* 1020 */ 63, 62, 61, 152, 87, 441, 120, 161, 119, 99,
838 /* 1030 */ 447, 441, 391, 120, 161, 119, 152, 441, 120, 161,
839 /* 1040 */ 119, 100, 441, 441, 64, 63, 62, 61, 152, 441,
840 /* 1050 */ 120, 161, 119, 441, 441, 152, 101, 387, 441, 91,
841 /* 1060 */ 152, 441, 441, 441, 103, 120, 161, 119, 120, 161,
842 /* 1070 */ 119, 92, 152, 120, 161, 119, 441, 441, 441, 441,
843 /* 1080 */ 120, 161, 119, 441, 441, 441, 441, 152, 441, 93,
844 /* 1090 */ 152, 441, 441, 441, 104, 152, 441, 441, 120, 161,
845 /* 1100 */ 119, 441, 152, 120, 161, 119, 441, 94, 441, 441,
846 /* 1110 */ 441, 441, 441, 105, 441, 441, 120, 161, 119, 95,
847 /* 1120 */ 152, 441, 120, 161, 119, 152, 96, 441, 120, 161,
848 /* 1130 */ 119, 97, 441, 441, 441, 120, 161, 119, 152, 441,
849 /* 1140 */ 120, 161, 119, 543, 152, 441, 441, 441, 441, 441,
850 /* 1150 */ 152, 441, 120, 161, 119, 441, 441, 152, 542, 441,
851 /* 1160 */ 441, 541, 152, 441, 441, 441, 540, 120, 161, 119,
852 /* 1170 */ 120, 161, 119, 115, 152, 120, 161, 119, 64, 63,
853 /* 1180 */ 62, 61, 120, 161, 119, 64, 63, 62, 61, 152,
854 /* 1190 */ 441, 116, 152, 441, 441, 441, 441, 152, 441, 53,
855 /* 1200 */ 120, 161, 119, 441, 152, 441, 56, 441, 441, 441,
856 /* 1210 */ 441, 441, 441, 441, 441, 441, 441, 441, 441, 441,
857 /* 1220 */ 441, 441, 152,
 
 
858 };
859 static const YYCODETYPE yy_lookahead[] = {
860 /* 0 */ 0, 110, 111, 112, 131, 99, 100, 101, 103, 103,
861 /* 10 */ 10, 110, 111, 112, 108, 109, 110, 111, 112, 103,
862 /* 20 */ 20, 21, 22, 102, 24, 10, 105, 106, 28, 4,
863 /* 30 */ 5, 6, 7, 33, 34, 35, 36, 37, 132, 39,
864 /* 40 */ 40, 41, 42, 28, 44, 45, 110, 111, 112, 49,
865 /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
866 /* 60 */ 60, 61, 62, 0, 4, 5, 6, 7, 8, 104,
867 /* 70 */ 101, 25, 103, 10, 110, 111, 112, 108, 109, 110,
868 /* 80 */ 111, 112, 103, 20, 21, 22, 17, 24, 110, 111,
869 /* 90 */ 112, 28, 26, 27, 25, 123, 33, 34, 35, 36,
870 /* 100 */ 37, 132, 39, 40, 41, 42, 12, 44, 45, 130,
871 /* 110 */ 2, 125, 49, 50, 51, 52, 53, 54, 55, 56,
872 /* 120 */ 57, 58, 59, 60, 61, 62, 1, 2, 2, 4,
873 /* 130 */ 5, 29, 30, 31, 32, 26, 27, 12, 126, 1,
874 /* 140 */ 15, 102, 4, 5, 105, 106, 38, 81, 0, 24,
875 /* 150 */ 12, 26, 27, 15, 88, 113, 31, 32, 10, 1,
876 /* 160 */ 2, 113, 4, 5, 38, 19, 127, 128, 129, 1,
877 /* 170 */ 12, 17, 1, 15, 80, 4, 5, 48, 20, 21,
878 /* 180 */ 22, 16, 88, 12, 46, 47, 15, 3, 63, 31,
879 /* 190 */ 32, 15, 1, 2, 43, 4, 5, 88, 4, 5,
880 /* 200 */ 6, 7, 40, 12, 40, 80, 15, 82, 83, 84,
881 /* 210 */ 85, 17, 13, 88, 89, 90, 91, 92, 80, 25,
882 /* 220 */ 41, 63, 31, 32, 101, 96, 88, 89, 90, 91,
883 /* 230 */ 92, 4, 5, 110, 111, 112, 41, 114, 80, 47,
884 /* 240 */ 82, 83, 84, 85, 121, 122, 88, 89, 90, 91,
885 /* 250 */ 92, 80, 17, 1, 63, 132, 4, 5, 25, 88,
886 /* 260 */ 89, 90, 91, 92, 12, 26, 27, 15, 94, 95,
887 /* 270 */ 86, 80, 17, 82, 83, 84, 85, 26, 27, 88,
888 /* 280 */ 89, 90, 91, 92, 2, 3, 4, 5, 6, 7,
889 /* 290 */ 73, 4, 5, 6, 7, 6, 7, 78, 16, 77,
890 /* 300 */ 79, 2, 3, 4, 5, 6, 7, 25, 4, 5,
891 /* 310 */ 6, 7, 78, 31, 32, 1, 17, 38, 4, 5,
892 /* 320 */ 38, 17, 35, 3, 25, 3, 12, 3, 3, 15,
893 /* 330 */ 31, 32, 80, 3, 20, 21, 22, 38, 24, 3,
894 /* 340 */ 88, 89, 90, 91, 92, 98, 99, 100, 66, 67,
895 /* 350 */ 93, 104, 75, 25, 15, 15, 74, 15, 76, 77,
896 /* 360 */ 78, 17, 115, 28, 12, 66, 67, 120, 87, 28,
897 /* 370 */ 3, 28, 11, 74, 133, 76, 77, 78, 2, 3,
898 /* 380 */ 4, 5, 6, 7, 63, 64, 65, 66, 67, 68,
899 /* 390 */ 69, 70, 71, 72, 80, 133, 133, 4, 5, 6,
900 /* 400 */ 7, 25, 88, 89, 90, 91, 92, 31, 32, 1,
901 /* 410 */ 17, 133, 133, 133, 38, 133, 133, 133, 25, 133,
902 /* 420 */ 12, 133, 14, 133, 133, 133, 18, 133, 20, 21,
903 /* 430 */ 22, 23, 24, 133, 26, 27, 133, 29, 30, 31,
904 /* 440 */ 32, 133, 66, 67, 1, 133, 133, 4, 5, 133,
905 /* 450 */ 74, 133, 76, 77, 78, 12, 133, 133, 15, 133,
906 /* 460 */ 133, 133, 133, 20, 21, 22, 1, 2, 133, 4,
907 /* 470 */ 5, 1, 2, 133, 4, 5, 133, 12, 133, 48,
908 /* 480 */ 15, 133, 12, 133, 133, 15, 133, 1, 2, 133,
909 /* 490 */ 4, 5, 133, 1, 133, 133, 4, 5, 12, 133,
910 /* 500 */ 133, 15, 133, 38, 12, 101, 1, 15, 133, 4,
911 /* 510 */ 5, 133, 133, 133, 110, 111, 112, 12, 87, 133,
912 /* 520 */ 15, 117, 133, 80, 93, 133, 133, 96, 124, 133,
913 /* 530 */ 126, 88, 89, 90, 91, 92, 132, 101, 4, 5,
914 /* 540 */ 6, 7, 133, 133, 133, 80, 110, 111, 112, 133,
915 /* 550 */ 80, 133, 133, 88, 89, 90, 91, 92, 88, 89,
916 /* 560 */ 90, 91, 92, 133, 133, 133, 80, 133, 132, 35,
917 /* 570 */ 133, 133, 80, 133, 88, 89, 90, 91, 92, 2,
918 /* 580 */ 88, 89, 90, 91, 92, 80, 133, 20, 21, 22,
919 /* 590 */ 133, 133, 101, 88, 89, 90, 91, 92, 133, 133,
920 /* 600 */ 133, 110, 111, 112, 97, 98, 99, 100, 31, 32,
921 /* 610 */ 133, 104, 4, 5, 6, 7, 49, 50, 51, 52,
922 /* 620 */ 53, 54, 115, 132, 133, 48, 119, 120, 97, 98,
923 /* 630 */ 99, 100, 133, 25, 101, 104, 103, 133, 133, 133,
924 /* 640 */ 63, 108, 109, 110, 111, 112, 115, 101, 133, 103,
925 /* 650 */ 133, 120, 2, 133, 108, 109, 110, 111, 112, 82,
926 /* 660 */ 83, 84, 85, 133, 101, 132, 103, 4, 5, 6,
927 /* 670 */ 7, 108, 109, 110, 111, 112, 133, 101, 132, 103,
928 /* 680 */ 17, 31, 32, 133, 108, 109, 110, 111, 112, 101,
929 /* 690 */ 133, 103, 133, 133, 101, 132, 108, 109, 110, 111,
930 /* 700 */ 112, 133, 133, 110, 111, 112, 133, 101, 132, 103,
931 /* 710 */ 133, 133, 133, 63, 108, 109, 110, 111, 112, 101,
932 /* 720 */ 132, 103, 133, 133, 133, 132, 108, 109, 110, 111,
933 /* 730 */ 112, 101, 82, 83, 84, 85, 133, 133, 132, 133,
934 /* 740 */ 110, 111, 112, 133, 101, 133, 103, 117, 118, 133,
935 /* 750 */ 132, 108, 109, 110, 111, 112, 101, 133, 103, 101,
936 /* 760 */ 133, 133, 132, 108, 109, 110, 111, 112, 110, 111,
937 /* 770 */ 112, 133, 114, 133, 101, 132, 103, 133, 133, 133,
938 /* 780 */ 122, 108, 109, 110, 111, 112, 101, 132, 103, 133,
939 /* 790 */ 132, 133, 133, 108, 109, 110, 111, 112, 133, 101,
940 /* 800 */ 133, 103, 133, 133, 133, 132, 108, 109, 110, 111,
941 /* 810 */ 112, 101, 133, 103, 133, 133, 101, 132, 108, 109,
942 /* 820 */ 110, 111, 112, 133, 133, 110, 111, 112, 133, 101,
943 /* 830 */ 132, 103, 117, 118, 133, 133, 108, 109, 110, 111,
944 /* 840 */ 112, 133, 132, 133, 133, 133, 101, 132, 103, 133,
945 /* 850 */ 133, 133, 101, 108, 109, 110, 111, 112, 133, 133,
946 /* 860 */ 132, 110, 111, 112, 133, 101, 133, 103, 117, 133,
947 /* 870 */ 133, 133, 108, 109, 110, 111, 112, 132, 101, 133,
948 /* 880 */ 103, 133, 133, 132, 133, 108, 109, 110, 111, 112,
949 /* 890 */ 101, 133, 103, 133, 133, 133, 132, 108, 109, 110,
950 /* 900 */ 111, 112, 133, 101, 133, 103, 133, 133, 133, 132,
951 /* 910 */ 108, 109, 110, 111, 112, 101, 133, 103, 101, 133,
952 /* 920 */ 133, 132, 108, 109, 110, 111, 112, 110, 111, 112,
953 /* 930 */ 133, 101, 133, 103, 132, 133, 133, 133, 108, 109,
954 /* 940 */ 110, 111, 112, 133, 133, 133, 132, 133, 101, 132,
955 /* 950 */ 103, 133, 133, 133, 101, 108, 109, 110, 111, 112,
956 /* 960 */ 133, 133, 132, 110, 111, 112, 133, 101, 133, 103,
957 /* 970 */ 4, 5, 6, 7, 108, 109, 110, 111, 112, 132,
958 /* 980 */ 101, 133, 103, 17, 133, 132, 133, 108, 109, 110,
959 /* 990 */ 111, 112, 101, 4, 5, 6, 7, 133, 132, 133,
960 /* 1000 */ 133, 110, 111, 112, 133, 101, 17, 116, 117, 118,
961 /* 1010 */ 133, 132, 133, 133, 110, 111, 112, 101, 114, 4,
962 /* 1020 */ 5, 6, 7, 132, 101, 133, 110, 111, 112, 101,
963 /* 1030 */ 114, 133, 17, 110, 111, 112, 132, 133, 110, 111,
964 /* 1040 */ 112, 101, 133, 133, 4, 5, 6, 7, 132, 133,
965 /* 1050 */ 110, 111, 112, 133, 133, 132, 101, 17, 133, 101,
966 /* 1060 */ 132, 133, 133, 133, 101, 110, 111, 112, 110, 111,
967 /* 1070 */ 112, 101, 132, 110, 111, 112, 133, 133, 133, 133,
968 /* 1080 */ 110, 111, 112, 133, 133, 133, 133, 132, 133, 101,
969 /* 1090 */ 132, 133, 133, 133, 101, 132, 133, 133, 110, 111,
970 /* 1100 */ 112, 133, 132, 110, 111, 112, 133, 101, 133, 133,
971 /* 1110 */ 133, 133, 133, 101, 133, 133, 110, 111, 112, 101,
972 /* 1120 */ 132, 133, 110, 111, 112, 132, 101, 133, 110, 111,
973 /* 1130 */ 112, 101, 133, 133, 133, 110, 111, 112, 132, 133,
974 /* 1140 */ 110, 111, 112, 101, 132, 133, 133, 133, 133, 133,
975 /* 1150 */ 132, 133, 110, 111, 112, 133, 133, 132, 101, 133,
976 /* 1160 */ 133, 101, 132, 133, 133, 133, 101, 110, 111, 112,
977 /* 1170 */ 110, 111, 112, 101, 132, 110, 111, 112, 4, 5,
978 /* 1180 */ 6, 7, 110, 111, 112, 4, 5, 6, 7, 132,
979 /* 1190 */ 133, 101, 132, 133, 133, 133, 133, 132, 133, 25,
980 /* 1200 */ 110, 111, 112, 133, 132, 133, 25, 133, 133, 133,
981 /* 1210 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
982 /* 1220 */ 133, 133, 132, 133, 133, 133, 133, 133, 133, 133,
983 /* 1230 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
984 /* 1240 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
985 /* 1250 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
986 /* 1260 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
987 /* 1270 */ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
988 /* 1280 */ 133, 133, 133, 97, 97, 97, 97, 97, 97, 97,
989 /* 1290 */ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
990 /* 1300 */ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
991 /* 1310 */ 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
 
 
992 };
993 #define YY_SHIFT_COUNT (163)
994 #define YY_SHIFT_MIN (0)
995 #define YY_SHIFT_MAX (1181)
996 static const unsigned short int yy_shift_ofst[] = {
997 /* 0 */ 408, 125, 158, 191, 191, 191, 191, 191, 191, 191,
998 /* 10 */ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
999 /* 20 */ 191, 191, 191, 191, 191, 191, 191, 314, 138, 171,
1000 /* 30 */ 314, 408, 465, 465, 0, 63, 408, 252, 171, 252,
1001 /* 40 */ 443, 443, 443, 470, 486, 171, 171, 171, 171, 171,
1002 /* 50 */ 171, 492, 171, 171, 505, 171, 171, 171, 171, 171,
1003 /* 60 */ 171, 171, 171, 171, 171, 567, 94, 94, 94, 94,
1004 /* 70 */ 94, 577, 282, 299, 376, 650, 650, 102, 46, 1223,
1005 /* 80 */ 1223, 1223, 1223, 321, 321, 194, 393, 304, 60, 287,
1006 /* 90 */ 534, 663, 608, 966, 1174, 989, 1181, 1015, 1040, 25,
1007 /* 100 */ 25, 25, 431, 25, 25, 25, 66, 25, 109, 15,
1008 /* 110 */ 108, 126, 69, 227, 174, 289, 289, 239, 251, 184,
1009 /* 120 */ 129, 148, 146, 168, 154, 165, 176, 151, 162, 164,
1010 /* 130 */ 179, 195, 192, 199, 235, 233, 217, 255, 219, 222,
1011 /* 140 */ 221, 234, 320, 322, 324, 279, 325, 330, 336, 257,
1012 /* 150 */ 277, 328, 257, 339, 340, 342, 344, 335, 341, 343,
1013 /* 160 */ 352, 281, 367, 361,
1014 };
1015 #define YY_REDUCE_COUNT (82)
1016 #define YY_REDUCE_MIN (-127)
1017 #define YY_REDUCE_MAX (1090)
1018 static const short yy_reduce_ofst[] = {
1019 /* 0 */ 507, -94, -31, 533, 546, 563, 576, 588, 606, 618,
1020 /* 10 */ 643, 655, 673, 685, 698, 710, 728, 745, 764, 777,
1021 /* 20 */ 789, 802, 814, 830, 847, 866, 879, 123, 891, 404,
1022 /* 30 */ 658, 531, 630, 715, 39, 39, 247, 904, 751, 916,
1023 /* 40 */ 436, 491, 593, 817, 853, 923, 928, 940, 955, 958,
1024 /* 50 */ 963, 970, 988, 993, 1006, 1012, 1018, 1025, 1030, 1042,
1025 /* 60 */ 1057, 1060, 1065, 1072, 1090, -79, -109, -99, -64, -36,
1026 /* 70 */ -22, -21, -127, -127, -127, -95, -84, -35, -28, -14,
1027 /* 80 */ 42, 48, 12,
1028 };
1029 static const YYACTIONTYPE yy_default[] = {
1030 /* 0 */ 445, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1031 /* 10 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1032 /* 20 */ 439, 439, 439, 439, 439, 439, 439, 439, 469, 570,
1033 /* 30 */ 439, 445, 574, 481, 575, 575, 445, 439, 439, 439,
1034 /* 40 */ 439, 439, 439, 439, 439, 439, 439, 439, 473, 439,
1035 /* 50 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1036 /* 60 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1037 /* 70 */ 439, 439, 439, 439, 439, 439, 439, 439, 451, 466,
1038 /* 80 */ 503, 503, 570, 464, 489, 439, 439, 439, 467, 439,
1039 /* 90 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 484,
1040 /* 100 */ 482, 472, 455, 507, 506, 505, 439, 560, 439, 439,
1041 /* 110 */ 439, 439, 439, 582, 439, 539, 538, 534, 439, 527,
1042 /* 120 */ 524, 439, 439, 439, 439, 439, 439, 487, 439, 439,
1043 /* 130 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1044 /* 140 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 586,
1045 /* 150 */ 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
1046 /* 160 */ 439, 595, 439, 439,
1047 };
1048 /********** End of lemon-generated parsing tables *****************************/
1049
1050 /* The next table maps tokens (terminal symbols) into fallback tokens.
1051 ** If a construct like the following:
@@ -1066,10 +1079,12 @@
1079 0, /* COLON => nothing */
1080 0, /* ASSERT => nothing */
1081 0, /* LP => nothing */
1082 0, /* EQ => nothing */
1083 0, /* RP => nothing */
1084 0, /* DEFINE => nothing */
1085 0, /* CODEBLOCK => nothing */
1086 0, /* FILL => nothing */
1087 0, /* COLOR => nothing */
1088 0, /* THICKNESS => nothing */
1089 0, /* PRINT => nothing */
1090 0, /* STRING => nothing */
@@ -1249,283 +1264,286 @@
1264 /* 13 */ "COLON",
1265 /* 14 */ "ASSERT",
1266 /* 15 */ "LP",
1267 /* 16 */ "EQ",
1268 /* 17 */ "RP",
1269 /* 18 */ "DEFINE",
1270 /* 19 */ "CODEBLOCK",
1271 /* 20 */ "FILL",
1272 /* 21 */ "COLOR",
1273 /* 22 */ "THICKNESS",
1274 /* 23 */ "PRINT",
1275 /* 24 */ "STRING",
1276 /* 25 */ "COMMA",
1277 /* 26 */ "CLASSNAME",
1278 /* 27 */ "LB",
1279 /* 28 */ "RB",
1280 /* 29 */ "UP",
1281 /* 30 */ "DOWN",
1282 /* 31 */ "LEFT",
1283 /* 32 */ "RIGHT",
1284 /* 33 */ "CLOSE",
1285 /* 34 */ "CHOP",
1286 /* 35 */ "FROM",
1287 /* 36 */ "TO",
1288 /* 37 */ "THEN",
1289 /* 38 */ "HEADING",
1290 /* 39 */ "GO",
1291 /* 40 */ "AT",
1292 /* 41 */ "WITH",
1293 /* 42 */ "SAME",
1294 /* 43 */ "AS",
1295 /* 44 */ "FIT",
1296 /* 45 */ "BEHIND",
1297 /* 46 */ "UNTIL",
1298 /* 47 */ "EVEN",
1299 /* 48 */ "DOT_E",
1300 /* 49 */ "HEIGHT",
1301 /* 50 */ "WIDTH",
1302 /* 51 */ "RADIUS",
1303 /* 52 */ "DIAMETER",
1304 /* 53 */ "DOTTED",
1305 /* 54 */ "DASHED",
1306 /* 55 */ "CW",
1307 /* 56 */ "CCW",
1308 /* 57 */ "LARROW",
1309 /* 58 */ "RARROW",
1310 /* 59 */ "LRARROW",
1311 /* 60 */ "INVIS",
1312 /* 61 */ "THICK",
1313 /* 62 */ "THIN",
1314 /* 63 */ "CENTER",
1315 /* 64 */ "LJUST",
1316 /* 65 */ "RJUST",
1317 /* 66 */ "ABOVE",
1318 /* 67 */ "BELOW",
1319 /* 68 */ "ITALIC",
1320 /* 69 */ "BOLD",
1321 /* 70 */ "ALIGNED",
1322 /* 71 */ "BIG",
1323 /* 72 */ "SMALL",
1324 /* 73 */ "AND",
1325 /* 74 */ "LT",
1326 /* 75 */ "GT",
1327 /* 76 */ "ON",
1328 /* 77 */ "WAY",
1329 /* 78 */ "BETWEEN",
1330 /* 79 */ "THE",
1331 /* 80 */ "NTH",
1332 /* 81 */ "VERTEX",
1333 /* 82 */ "TOP",
1334 /* 83 */ "BOTTOM",
1335 /* 84 */ "START",
1336 /* 85 */ "END",
1337 /* 86 */ "IN",
1338 /* 87 */ "DOT_U",
1339 /* 88 */ "LAST",
1340 /* 89 */ "NUMBER",
1341 /* 90 */ "FUNC1",
1342 /* 91 */ "FUNC2",
1343 /* 92 */ "DIST",
1344 /* 93 */ "DOT_XY",
1345 /* 94 */ "X",
1346 /* 95 */ "Y",
1347 /* 96 */ "DOT_L",
1348 /* 97 */ "statement_list",
1349 /* 98 */ "statement",
1350 /* 99 */ "unnamed_statement",
1351 /* 100 */ "basetype",
1352 /* 101 */ "expr",
1353 /* 102 */ "numproperty",
1354 /* 103 */ "edge",
1355 /* 104 */ "direction",
1356 /* 105 */ "dashproperty",
1357 /* 106 */ "colorproperty",
1358 /* 107 */ "locproperty",
1359 /* 108 */ "position",
1360 /* 109 */ "place",
1361 /* 110 */ "object",
1362 /* 111 */ "objectname",
1363 /* 112 */ "nth",
1364 /* 113 */ "textposition",
1365 /* 114 */ "rvalue",
1366 /* 115 */ "lvalue",
1367 /* 116 */ "even",
1368 /* 117 */ "relexpr",
1369 /* 118 */ "optrelexpr",
1370 /* 119 */ "document",
1371 /* 120 */ "print",
1372 /* 121 */ "prlist",
1373 /* 122 */ "pritem",
1374 /* 123 */ "prsep",
1375 /* 124 */ "attribute_list",
1376 /* 125 */ "savelist",
1377 /* 126 */ "alist",
1378 /* 127 */ "attribute",
1379 /* 128 */ "go",
1380 /* 129 */ "boolproperty",
1381 /* 130 */ "withclause",
1382 /* 131 */ "between",
1383 /* 132 */ "place2",
1384 };
1385 #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
1386
1387 #ifndef NDEBUG
1388 /* For tracing reduce actions, the names of all rules are required.
1389 */
1390 static const char *const yyRuleName[] = {
1391 /* 0 */ "document ::= statement_list",
1392 /* 1 */ "statement_list ::= statement",
1393 /* 2 */ "statement_list ::= statement_list EOL statement",
1394 /* 3 */ "statement ::=",
1395 /* 4 */ "statement ::= direction",
1396 /* 5 */ "statement ::= lvalue ASSIGN rvalue",
1397 /* 6 */ "statement ::= PLACENAME COLON unnamed_statement",
1398 /* 7 */ "statement ::= PLACENAME COLON position",
1399 /* 8 */ "statement ::= unnamed_statement",
1400 /* 9 */ "statement ::= print prlist",
1401 /* 10 */ "statement ::= ASSERT LP expr EQ expr RP",
1402 /* 11 */ "statement ::= ASSERT LP position EQ position RP",
1403 /* 12 */ "statement ::= DEFINE ID CODEBLOCK",
1404 /* 13 */ "rvalue ::= PLACENAME",
1405 /* 14 */ "pritem ::= FILL",
1406 /* 15 */ "pritem ::= COLOR",
1407 /* 16 */ "pritem ::= THICKNESS",
1408 /* 17 */ "pritem ::= rvalue",
1409 /* 18 */ "pritem ::= STRING",
1410 /* 19 */ "prsep ::= COMMA",
1411 /* 20 */ "unnamed_statement ::= basetype attribute_list",
1412 /* 21 */ "basetype ::= CLASSNAME",
1413 /* 22 */ "basetype ::= STRING textposition",
1414 /* 23 */ "basetype ::= LB savelist statement_list RB",
1415 /* 24 */ "savelist ::=",
1416 /* 25 */ "relexpr ::= expr",
1417 /* 26 */ "relexpr ::= expr PERCENT",
1418 /* 27 */ "optrelexpr ::=",
1419 /* 28 */ "attribute_list ::= relexpr alist",
1420 /* 29 */ "attribute ::= numproperty relexpr",
1421 /* 30 */ "attribute ::= dashproperty expr",
1422 /* 31 */ "attribute ::= dashproperty",
1423 /* 32 */ "attribute ::= colorproperty rvalue",
1424 /* 33 */ "attribute ::= go direction optrelexpr",
1425 /* 34 */ "attribute ::= go direction even position",
1426 /* 35 */ "attribute ::= CLOSE",
1427 /* 36 */ "attribute ::= CHOP",
1428 /* 37 */ "attribute ::= FROM position",
1429 /* 38 */ "attribute ::= TO position",
1430 /* 39 */ "attribute ::= THEN",
1431 /* 40 */ "attribute ::= THEN optrelexpr HEADING expr",
1432 /* 41 */ "attribute ::= THEN optrelexpr EDGEPT",
1433 /* 42 */ "attribute ::= GO optrelexpr HEADING expr",
1434 /* 43 */ "attribute ::= GO optrelexpr EDGEPT",
1435 /* 44 */ "attribute ::= AT position",
1436 /* 45 */ "attribute ::= SAME",
1437 /* 46 */ "attribute ::= SAME AS object",
1438 /* 47 */ "attribute ::= STRING textposition",
1439 /* 48 */ "attribute ::= FIT",
1440 /* 49 */ "attribute ::= BEHIND object",
1441 /* 50 */ "withclause ::= DOT_E edge AT position",
1442 /* 51 */ "withclause ::= edge AT position",
1443 /* 52 */ "numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS",
1444 /* 53 */ "boolproperty ::= CW",
1445 /* 54 */ "boolproperty ::= CCW",
1446 /* 55 */ "boolproperty ::= LARROW",
1447 /* 56 */ "boolproperty ::= RARROW",
1448 /* 57 */ "boolproperty ::= LRARROW",
1449 /* 58 */ "boolproperty ::= INVIS",
1450 /* 59 */ "boolproperty ::= THICK",
1451 /* 60 */ "boolproperty ::= THIN",
1452 /* 61 */ "textposition ::=",
1453 /* 62 */ "textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL",
1454 /* 63 */ "position ::= expr COMMA expr",
1455 /* 64 */ "position ::= place PLUS expr COMMA expr",
1456 /* 65 */ "position ::= place MINUS expr COMMA expr",
1457 /* 66 */ "position ::= place PLUS LP expr COMMA expr RP",
1458 /* 67 */ "position ::= place MINUS LP expr COMMA expr RP",
1459 /* 68 */ "position ::= LP position COMMA position RP",
1460 /* 69 */ "position ::= LP position RP",
1461 /* 70 */ "position ::= expr between position AND position",
1462 /* 71 */ "position ::= expr LT position COMMA position GT",
1463 /* 72 */ "position ::= expr ABOVE position",
1464 /* 73 */ "position ::= expr BELOW position",
1465 /* 74 */ "position ::= expr LEFT OF position",
1466 /* 75 */ "position ::= expr RIGHT OF position",
1467 /* 76 */ "position ::= expr ON HEADING EDGEPT OF position",
1468 /* 77 */ "position ::= expr HEADING EDGEPT OF position",
1469 /* 78 */ "position ::= expr EDGEPT OF position",
1470 /* 79 */ "position ::= expr ON HEADING expr FROM position",
1471 /* 80 */ "position ::= expr HEADING expr FROM position",
1472 /* 81 */ "place ::= edge OF object",
1473 /* 82 */ "place2 ::= object",
1474 /* 83 */ "place2 ::= object DOT_E edge",
1475 /* 84 */ "place2 ::= NTH VERTEX OF object",
1476 /* 85 */ "object ::= nth",
1477 /* 86 */ "object ::= nth OF|IN object",
1478 /* 87 */ "objectname ::= PLACENAME",
1479 /* 88 */ "objectname ::= objectname DOT_U PLACENAME",
1480 /* 89 */ "nth ::= NTH CLASSNAME",
1481 /* 90 */ "nth ::= NTH LAST CLASSNAME",
1482 /* 91 */ "nth ::= LAST CLASSNAME",
1483 /* 92 */ "nth ::= LAST",
1484 /* 93 */ "nth ::= NTH LB RB",
1485 /* 94 */ "nth ::= NTH LAST LB RB",
1486 /* 95 */ "nth ::= LAST LB RB",
1487 /* 96 */ "expr ::= expr PLUS expr",
1488 /* 97 */ "expr ::= expr MINUS expr",
1489 /* 98 */ "expr ::= expr STAR expr",
1490 /* 99 */ "expr ::= expr SLASH expr",
1491 /* 100 */ "expr ::= MINUS expr",
1492 /* 101 */ "expr ::= PLUS expr",
1493 /* 102 */ "expr ::= LP expr RP",
1494 /* 103 */ "expr ::= LP FILL|COLOR|THICKNESS RP",
1495 /* 104 */ "expr ::= NUMBER",
1496 /* 105 */ "expr ::= ID",
1497 /* 106 */ "expr ::= FUNC1 LP expr RP",
1498 /* 107 */ "expr ::= FUNC2 LP expr COMMA expr RP",
1499 /* 108 */ "expr ::= DIST LP position COMMA position RP",
1500 /* 109 */ "expr ::= place2 DOT_XY X",
1501 /* 110 */ "expr ::= place2 DOT_XY Y",
1502 /* 111 */ "expr ::= object DOT_L numproperty",
1503 /* 112 */ "expr ::= object DOT_L dashproperty",
1504 /* 113 */ "expr ::= object DOT_L colorproperty",
1505 /* 114 */ "lvalue ::= ID",
1506 /* 115 */ "lvalue ::= FILL",
1507 /* 116 */ "lvalue ::= COLOR",
1508 /* 117 */ "lvalue ::= THICKNESS",
1509 /* 118 */ "rvalue ::= expr",
1510 /* 119 */ "print ::= PRINT",
1511 /* 120 */ "prlist ::= pritem",
1512 /* 121 */ "prlist ::= prlist prsep pritem",
1513 /* 122 */ "direction ::= UP",
1514 /* 123 */ "direction ::= DOWN",
1515 /* 124 */ "direction ::= LEFT",
1516 /* 125 */ "direction ::= RIGHT",
1517 /* 126 */ "optrelexpr ::= relexpr",
1518 /* 127 */ "attribute_list ::= alist",
1519 /* 128 */ "alist ::=",
1520 /* 129 */ "alist ::= alist attribute",
1521 /* 130 */ "attribute ::= boolproperty",
1522 /* 131 */ "attribute ::= WITH withclause",
1523 /* 132 */ "go ::= GO",
1524 /* 133 */ "go ::=",
1525 /* 134 */ "even ::= UNTIL EVEN WITH",
1526 /* 135 */ "even ::= EVEN WITH",
1527 /* 136 */ "dashproperty ::= DOTTED",
1528 /* 137 */ "dashproperty ::= DASHED",
1529 /* 138 */ "colorproperty ::= FILL",
1530 /* 139 */ "colorproperty ::= COLOR",
1531 /* 140 */ "position ::= place",
1532 /* 141 */ "between ::= WAY BETWEEN",
1533 /* 142 */ "between ::= BETWEEN",
1534 /* 143 */ "between ::= OF THE WAY BETWEEN",
1535 /* 144 */ "place ::= place2",
1536 /* 145 */ "edge ::= CENTER",
1537 /* 146 */ "edge ::= EDGEPT",
1538 /* 147 */ "edge ::= TOP",
1539 /* 148 */ "edge ::= BOTTOM",
1540 /* 149 */ "edge ::= START",
1541 /* 150 */ "edge ::= END",
1542 /* 151 */ "edge ::= RIGHT",
1543 /* 152 */ "edge ::= LEFT",
1544 /* 153 */ "object ::= objectname",
1545 };
1546 #endif /* NDEBUG */
1547
1548
1549 #if YYSTACKDEPTH<=0
@@ -1647,24 +1665,24 @@
1665 ** Note: during a reduce, the only symbols destroyed are those
1666 ** which appear on the RHS of the rule, but which are *not* used
1667 ** inside the C code.
1668 */
1669 /********* Begin destructor definitions ***************************************/
1670 case 97: /* statement_list */
1671 {
1672 #line 483 "pikchr.y"
1673 pik_elist_free(p,(yypminor->yy191));
1674 #line 1699 "pikchr.c"
1675 }
1676 break;
1677 case 98: /* statement */
1678 case 99: /* unnamed_statement */
1679 case 100: /* basetype */
1680 {
1681 #line 485 "pikchr.y"
1682 pik_elem_free(p,(yypminor->yy138));
1683 #line 1708 "pikchr.c"
1684 }
1685 break;
1686 /********* End destructor definitions *****************************************/
1687 default: break; /* If no destructor action specified: do nothing */
1688 }
@@ -1878,14 +1896,14 @@
1896 #endif
1897 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1898 /* Here code is inserted which will execute if the parser
1899 ** stack every overflows */
1900 /******** Begin %stack_overflow code ******************************************/
1901 #line 517 "pikchr.y"
1902
1903 pik_error(p, 0, "parser stack overflow");
1904 #line 1929 "pikchr.c"
1905 /******** End %stack_overflow code ********************************************/
1906 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1907 pik_parserCTX_STORE
1908 }
1909
@@ -1953,321 +1971,323 @@
1971 }
1972
1973 /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
1974 ** of that rule */
1975 static const YYCODETYPE yyRuleInfoLhs[] = {
1976 119, /* (0) document ::= statement_list */
1977 97, /* (1) statement_list ::= statement */
1978 97, /* (2) statement_list ::= statement_list EOL statement */
1979 98, /* (3) statement ::= */
1980 98, /* (4) statement ::= direction */
1981 98, /* (5) statement ::= lvalue ASSIGN rvalue */
1982 98, /* (6) statement ::= PLACENAME COLON unnamed_statement */
1983 98, /* (7) statement ::= PLACENAME COLON position */
1984 98, /* (8) statement ::= unnamed_statement */
1985 98, /* (9) statement ::= print prlist */
1986 98, /* (10) statement ::= ASSERT LP expr EQ expr RP */
1987 98, /* (11) statement ::= ASSERT LP position EQ position RP */
1988 98, /* (12) statement ::= DEFINE ID CODEBLOCK */
1989 114, /* (13) rvalue ::= PLACENAME */
1990 122, /* (14) pritem ::= FILL */
1991 122, /* (15) pritem ::= COLOR */
1992 122, /* (16) pritem ::= THICKNESS */
1993 122, /* (17) pritem ::= rvalue */
1994 122, /* (18) pritem ::= STRING */
1995 123, /* (19) prsep ::= COMMA */
1996 99, /* (20) unnamed_statement ::= basetype attribute_list */
1997 100, /* (21) basetype ::= CLASSNAME */
1998 100, /* (22) basetype ::= STRING textposition */
1999 100, /* (23) basetype ::= LB savelist statement_list RB */
2000 125, /* (24) savelist ::= */
2001 117, /* (25) relexpr ::= expr */
2002 117, /* (26) relexpr ::= expr PERCENT */
2003 118, /* (27) optrelexpr ::= */
2004 124, /* (28) attribute_list ::= relexpr alist */
2005 127, /* (29) attribute ::= numproperty relexpr */
2006 127, /* (30) attribute ::= dashproperty expr */
2007 127, /* (31) attribute ::= dashproperty */
2008 127, /* (32) attribute ::= colorproperty rvalue */
2009 127, /* (33) attribute ::= go direction optrelexpr */
2010 127, /* (34) attribute ::= go direction even position */
2011 127, /* (35) attribute ::= CLOSE */
2012 127, /* (36) attribute ::= CHOP */
2013 127, /* (37) attribute ::= FROM position */
2014 127, /* (38) attribute ::= TO position */
2015 127, /* (39) attribute ::= THEN */
2016 127, /* (40) attribute ::= THEN optrelexpr HEADING expr */
2017 127, /* (41) attribute ::= THEN optrelexpr EDGEPT */
2018 127, /* (42) attribute ::= GO optrelexpr HEADING expr */
2019 127, /* (43) attribute ::= GO optrelexpr EDGEPT */
2020 127, /* (44) attribute ::= AT position */
2021 127, /* (45) attribute ::= SAME */
2022 127, /* (46) attribute ::= SAME AS object */
2023 127, /* (47) attribute ::= STRING textposition */
2024 127, /* (48) attribute ::= FIT */
2025 127, /* (49) attribute ::= BEHIND object */
2026 130, /* (50) withclause ::= DOT_E edge AT position */
2027 130, /* (51) withclause ::= edge AT position */
2028 102, /* (52) numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2029 129, /* (53) boolproperty ::= CW */
2030 129, /* (54) boolproperty ::= CCW */
2031 129, /* (55) boolproperty ::= LARROW */
2032 129, /* (56) boolproperty ::= RARROW */
2033 129, /* (57) boolproperty ::= LRARROW */
2034 129, /* (58) boolproperty ::= INVIS */
2035 129, /* (59) boolproperty ::= THICK */
2036 129, /* (60) boolproperty ::= THIN */
2037 113, /* (61) textposition ::= */
2038 113, /* (62) textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2039 108, /* (63) position ::= expr COMMA expr */
2040 108, /* (64) position ::= place PLUS expr COMMA expr */
2041 108, /* (65) position ::= place MINUS expr COMMA expr */
2042 108, /* (66) position ::= place PLUS LP expr COMMA expr RP */
2043 108, /* (67) position ::= place MINUS LP expr COMMA expr RP */
2044 108, /* (68) position ::= LP position COMMA position RP */
2045 108, /* (69) position ::= LP position RP */
2046 108, /* (70) position ::= expr between position AND position */
2047 108, /* (71) position ::= expr LT position COMMA position GT */
2048 108, /* (72) position ::= expr ABOVE position */
2049 108, /* (73) position ::= expr BELOW position */
2050 108, /* (74) position ::= expr LEFT OF position */
2051 108, /* (75) position ::= expr RIGHT OF position */
2052 108, /* (76) position ::= expr ON HEADING EDGEPT OF position */
2053 108, /* (77) position ::= expr HEADING EDGEPT OF position */
2054 108, /* (78) position ::= expr EDGEPT OF position */
2055 108, /* (79) position ::= expr ON HEADING expr FROM position */
2056 108, /* (80) position ::= expr HEADING expr FROM position */
2057 109, /* (81) place ::= edge OF object */
2058 132, /* (82) place2 ::= object */
2059 132, /* (83) place2 ::= object DOT_E edge */
2060 132, /* (84) place2 ::= NTH VERTEX OF object */
2061 110, /* (85) object ::= nth */
2062 110, /* (86) object ::= nth OF|IN object */
2063 111, /* (87) objectname ::= PLACENAME */
2064 111, /* (88) objectname ::= objectname DOT_U PLACENAME */
2065 112, /* (89) nth ::= NTH CLASSNAME */
2066 112, /* (90) nth ::= NTH LAST CLASSNAME */
2067 112, /* (91) nth ::= LAST CLASSNAME */
2068 112, /* (92) nth ::= LAST */
2069 112, /* (93) nth ::= NTH LB RB */
2070 112, /* (94) nth ::= NTH LAST LB RB */
2071 112, /* (95) nth ::= LAST LB RB */
2072 101, /* (96) expr ::= expr PLUS expr */
2073 101, /* (97) expr ::= expr MINUS expr */
2074 101, /* (98) expr ::= expr STAR expr */
2075 101, /* (99) expr ::= expr SLASH expr */
2076 101, /* (100) expr ::= MINUS expr */
2077 101, /* (101) expr ::= PLUS expr */
2078 101, /* (102) expr ::= LP expr RP */
2079 101, /* (103) expr ::= LP FILL|COLOR|THICKNESS RP */
2080 101, /* (104) expr ::= NUMBER */
2081 101, /* (105) expr ::= ID */
2082 101, /* (106) expr ::= FUNC1 LP expr RP */
2083 101, /* (107) expr ::= FUNC2 LP expr COMMA expr RP */
2084 101, /* (108) expr ::= DIST LP position COMMA position RP */
2085 101, /* (109) expr ::= place2 DOT_XY X */
2086 101, /* (110) expr ::= place2 DOT_XY Y */
2087 101, /* (111) expr ::= object DOT_L numproperty */
2088 101, /* (112) expr ::= object DOT_L dashproperty */
2089 101, /* (113) expr ::= object DOT_L colorproperty */
2090 115, /* (114) lvalue ::= ID */
2091 115, /* (115) lvalue ::= FILL */
2092 115, /* (116) lvalue ::= COLOR */
2093 115, /* (117) lvalue ::= THICKNESS */
2094 114, /* (118) rvalue ::= expr */
2095 120, /* (119) print ::= PRINT */
2096 121, /* (120) prlist ::= pritem */
2097 121, /* (121) prlist ::= prlist prsep pritem */
2098 104, /* (122) direction ::= UP */
2099 104, /* (123) direction ::= DOWN */
2100 104, /* (124) direction ::= LEFT */
2101 104, /* (125) direction ::= RIGHT */
2102 118, /* (126) optrelexpr ::= relexpr */
2103 124, /* (127) attribute_list ::= alist */
2104 126, /* (128) alist ::= */
2105 126, /* (129) alist ::= alist attribute */
2106 127, /* (130) attribute ::= boolproperty */
2107 127, /* (131) attribute ::= WITH withclause */
2108 128, /* (132) go ::= GO */
2109 128, /* (133) go ::= */
2110 116, /* (134) even ::= UNTIL EVEN WITH */
2111 116, /* (135) even ::= EVEN WITH */
2112 105, /* (136) dashproperty ::= DOTTED */
2113 105, /* (137) dashproperty ::= DASHED */
2114 106, /* (138) colorproperty ::= FILL */
2115 106, /* (139) colorproperty ::= COLOR */
2116 108, /* (140) position ::= place */
2117 131, /* (141) between ::= WAY BETWEEN */
2118 131, /* (142) between ::= BETWEEN */
2119 131, /* (143) between ::= OF THE WAY BETWEEN */
2120 109, /* (144) place ::= place2 */
2121 103, /* (145) edge ::= CENTER */
2122 103, /* (146) edge ::= EDGEPT */
2123 103, /* (147) edge ::= TOP */
2124 103, /* (148) edge ::= BOTTOM */
2125 103, /* (149) edge ::= START */
2126 103, /* (150) edge ::= END */
2127 103, /* (151) edge ::= RIGHT */
2128 103, /* (152) edge ::= LEFT */
2129 110, /* (153) object ::= objectname */
2130 };
2131
2132 /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
2133 ** of symbols on the right-hand side of that rule. */
2134 static const signed char yyRuleInfoNRhs[] = {
2135 -1, /* (0) document ::= statement_list */
2136 -1, /* (1) statement_list ::= statement */
2137 -3, /* (2) statement_list ::= statement_list EOL statement */
2138 0, /* (3) statement ::= */
2139 -1, /* (4) statement ::= direction */
2140 -3, /* (5) statement ::= lvalue ASSIGN rvalue */
2141 -3, /* (6) statement ::= PLACENAME COLON unnamed_statement */
2142 -3, /* (7) statement ::= PLACENAME COLON position */
2143 -1, /* (8) statement ::= unnamed_statement */
2144 -2, /* (9) statement ::= print prlist */
2145 -6, /* (10) statement ::= ASSERT LP expr EQ expr RP */
2146 -6, /* (11) statement ::= ASSERT LP position EQ position RP */
2147 -3, /* (12) statement ::= DEFINE ID CODEBLOCK */
2148 -1, /* (13) rvalue ::= PLACENAME */
2149 -1, /* (14) pritem ::= FILL */
2150 -1, /* (15) pritem ::= COLOR */
2151 -1, /* (16) pritem ::= THICKNESS */
2152 -1, /* (17) pritem ::= rvalue */
2153 -1, /* (18) pritem ::= STRING */
2154 -1, /* (19) prsep ::= COMMA */
2155 -2, /* (20) unnamed_statement ::= basetype attribute_list */
2156 -1, /* (21) basetype ::= CLASSNAME */
2157 -2, /* (22) basetype ::= STRING textposition */
2158 -4, /* (23) basetype ::= LB savelist statement_list RB */
2159 0, /* (24) savelist ::= */
2160 -1, /* (25) relexpr ::= expr */
2161 -2, /* (26) relexpr ::= expr PERCENT */
2162 0, /* (27) optrelexpr ::= */
2163 -2, /* (28) attribute_list ::= relexpr alist */
2164 -2, /* (29) attribute ::= numproperty relexpr */
2165 -2, /* (30) attribute ::= dashproperty expr */
2166 -1, /* (31) attribute ::= dashproperty */
2167 -2, /* (32) attribute ::= colorproperty rvalue */
2168 -3, /* (33) attribute ::= go direction optrelexpr */
2169 -4, /* (34) attribute ::= go direction even position */
2170 -1, /* (35) attribute ::= CLOSE */
2171 -1, /* (36) attribute ::= CHOP */
2172 -2, /* (37) attribute ::= FROM position */
2173 -2, /* (38) attribute ::= TO position */
2174 -1, /* (39) attribute ::= THEN */
2175 -4, /* (40) attribute ::= THEN optrelexpr HEADING expr */
2176 -3, /* (41) attribute ::= THEN optrelexpr EDGEPT */
2177 -4, /* (42) attribute ::= GO optrelexpr HEADING expr */
2178 -3, /* (43) attribute ::= GO optrelexpr EDGEPT */
2179 -2, /* (44) attribute ::= AT position */
2180 -1, /* (45) attribute ::= SAME */
2181 -3, /* (46) attribute ::= SAME AS object */
2182 -2, /* (47) attribute ::= STRING textposition */
2183 -1, /* (48) attribute ::= FIT */
2184 -2, /* (49) attribute ::= BEHIND object */
2185 -4, /* (50) withclause ::= DOT_E edge AT position */
2186 -3, /* (51) withclause ::= edge AT position */
2187 -1, /* (52) numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2188 -1, /* (53) boolproperty ::= CW */
2189 -1, /* (54) boolproperty ::= CCW */
2190 -1, /* (55) boolproperty ::= LARROW */
2191 -1, /* (56) boolproperty ::= RARROW */
2192 -1, /* (57) boolproperty ::= LRARROW */
2193 -1, /* (58) boolproperty ::= INVIS */
2194 -1, /* (59) boolproperty ::= THICK */
2195 -1, /* (60) boolproperty ::= THIN */
2196 0, /* (61) textposition ::= */
2197 -2, /* (62) textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
2198 -3, /* (63) position ::= expr COMMA expr */
2199 -5, /* (64) position ::= place PLUS expr COMMA expr */
2200 -5, /* (65) position ::= place MINUS expr COMMA expr */
2201 -7, /* (66) position ::= place PLUS LP expr COMMA expr RP */
2202 -7, /* (67) position ::= place MINUS LP expr COMMA expr RP */
2203 -5, /* (68) position ::= LP position COMMA position RP */
2204 -3, /* (69) position ::= LP position RP */
2205 -5, /* (70) position ::= expr between position AND position */
2206 -6, /* (71) position ::= expr LT position COMMA position GT */
2207 -3, /* (72) position ::= expr ABOVE position */
2208 -3, /* (73) position ::= expr BELOW position */
2209 -4, /* (74) position ::= expr LEFT OF position */
2210 -4, /* (75) position ::= expr RIGHT OF position */
2211 -6, /* (76) position ::= expr ON HEADING EDGEPT OF position */
2212 -5, /* (77) position ::= expr HEADING EDGEPT OF position */
2213 -4, /* (78) position ::= expr EDGEPT OF position */
2214 -6, /* (79) position ::= expr ON HEADING expr FROM position */
2215 -5, /* (80) position ::= expr HEADING expr FROM position */
2216 -3, /* (81) place ::= edge OF object */
2217 -1, /* (82) place2 ::= object */
2218 -3, /* (83) place2 ::= object DOT_E edge */
2219 -4, /* (84) place2 ::= NTH VERTEX OF object */
2220 -1, /* (85) object ::= nth */
2221 -3, /* (86) object ::= nth OF|IN object */
2222 -1, /* (87) objectname ::= PLACENAME */
2223 -3, /* (88) objectname ::= objectname DOT_U PLACENAME */
2224 -2, /* (89) nth ::= NTH CLASSNAME */
2225 -3, /* (90) nth ::= NTH LAST CLASSNAME */
2226 -2, /* (91) nth ::= LAST CLASSNAME */
2227 -1, /* (92) nth ::= LAST */
2228 -3, /* (93) nth ::= NTH LB RB */
2229 -4, /* (94) nth ::= NTH LAST LB RB */
2230 -3, /* (95) nth ::= LAST LB RB */
2231 -3, /* (96) expr ::= expr PLUS expr */
2232 -3, /* (97) expr ::= expr MINUS expr */
2233 -3, /* (98) expr ::= expr STAR expr */
2234 -3, /* (99) expr ::= expr SLASH expr */
2235 -2, /* (100) expr ::= MINUS expr */
2236 -2, /* (101) expr ::= PLUS expr */
2237 -3, /* (102) expr ::= LP expr RP */
2238 -3, /* (103) expr ::= LP FILL|COLOR|THICKNESS RP */
2239 -1, /* (104) expr ::= NUMBER */
2240 -1, /* (105) expr ::= ID */
2241 -4, /* (106) expr ::= FUNC1 LP expr RP */
2242 -6, /* (107) expr ::= FUNC2 LP expr COMMA expr RP */
2243 -6, /* (108) expr ::= DIST LP position COMMA position RP */
2244 -3, /* (109) expr ::= place2 DOT_XY X */
2245 -3, /* (110) expr ::= place2 DOT_XY Y */
2246 -3, /* (111) expr ::= object DOT_L numproperty */
2247 -3, /* (112) expr ::= object DOT_L dashproperty */
2248 -3, /* (113) expr ::= object DOT_L colorproperty */
2249 -1, /* (114) lvalue ::= ID */
2250 -1, /* (115) lvalue ::= FILL */
2251 -1, /* (116) lvalue ::= COLOR */
2252 -1, /* (117) lvalue ::= THICKNESS */
2253 -1, /* (118) rvalue ::= expr */
2254 -1, /* (119) print ::= PRINT */
2255 -1, /* (120) prlist ::= pritem */
2256 -3, /* (121) prlist ::= prlist prsep pritem */
2257 -1, /* (122) direction ::= UP */
2258 -1, /* (123) direction ::= DOWN */
2259 -1, /* (124) direction ::= LEFT */
2260 -1, /* (125) direction ::= RIGHT */
2261 -1, /* (126) optrelexpr ::= relexpr */
2262 -1, /* (127) attribute_list ::= alist */
2263 0, /* (128) alist ::= */
2264 -2, /* (129) alist ::= alist attribute */
2265 -1, /* (130) attribute ::= boolproperty */
2266 -2, /* (131) attribute ::= WITH withclause */
2267 -1, /* (132) go ::= GO */
2268 0, /* (133) go ::= */
2269 -3, /* (134) even ::= UNTIL EVEN WITH */
2270 -2, /* (135) even ::= EVEN WITH */
2271 -1, /* (136) dashproperty ::= DOTTED */
2272 -1, /* (137) dashproperty ::= DASHED */
2273 -1, /* (138) colorproperty ::= FILL */
2274 -1, /* (139) colorproperty ::= COLOR */
2275 -1, /* (140) position ::= place */
2276 -2, /* (141) between ::= WAY BETWEEN */
2277 -1, /* (142) between ::= BETWEEN */
2278 -4, /* (143) between ::= OF THE WAY BETWEEN */
2279 -1, /* (144) place ::= place2 */
2280 -1, /* (145) edge ::= CENTER */
2281 -1, /* (146) edge ::= EDGEPT */
2282 -1, /* (147) edge ::= TOP */
2283 -1, /* (148) edge ::= BOTTOM */
2284 -1, /* (149) edge ::= START */
2285 -1, /* (150) edge ::= END */
2286 -1, /* (151) edge ::= RIGHT */
2287 -1, /* (152) edge ::= LEFT */
2288 -1, /* (153) object ::= objectname */
2289 };
2290
2291 static void yy_accept(yyParser*); /* Forward Declaration */
2292
2293 /*
@@ -2354,647 +2374,652 @@
2374 ** #line <lineno> <thisfile>
2375 ** break;
2376 */
2377 /********** Begin reduce actions **********************************************/
2378 YYMINORTYPE yylhsminor;
2379 case 0: /* document ::= statement_list */
2380 #line 521 "pikchr.y"
2381 {pik_render(p,yymsp[0].minor.yy191);}
2382 #line 2407 "pikchr.c"
2383 break;
2384 case 1: /* statement_list ::= statement */
2385 #line 524 "pikchr.y"
2386 { yylhsminor.yy191 = pik_elist_append(p,0,yymsp[0].minor.yy138); }
2387 #line 2412 "pikchr.c"
2388 yymsp[0].minor.yy191 = yylhsminor.yy191;
2389 break;
2390 case 2: /* statement_list ::= statement_list EOL statement */
2391 #line 526 "pikchr.y"
2392 { yylhsminor.yy191 = pik_elist_append(p,yymsp[-2].minor.yy191,yymsp[0].minor.yy138); }
2393 #line 2418 "pikchr.c"
2394 yymsp[-2].minor.yy191 = yylhsminor.yy191;
2395 break;
2396 case 3: /* statement ::= */
2397 #line 529 "pikchr.y"
2398 { yymsp[1].minor.yy138 = 0; }
2399 #line 2424 "pikchr.c"
2400 break;
2401 case 4: /* statement ::= direction */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2402 #line 530 "pikchr.y"
2403 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy138=0; }
2404 #line 2429 "pikchr.c"
2405 yymsp[0].minor.yy138 = yylhsminor.yy138;
2406 break;
2407 case 5: /* statement ::= lvalue ASSIGN rvalue */
2408 #line 531 "pikchr.y"
2409 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy121,&yymsp[-1].minor.yy0); yylhsminor.yy138=0;}
2410 #line 2435 "pikchr.c"
2411 yymsp[-2].minor.yy138 = yylhsminor.yy138;
2412 break;
2413 case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2414 #line 533 "pikchr.y"
2415 { yylhsminor.yy138 = yymsp[0].minor.yy138; pik_elem_setname(p,yymsp[0].minor.yy138,&yymsp[-2].minor.yy0); }
2416 #line 2441 "pikchr.c"
2417 yymsp[-2].minor.yy138 = yylhsminor.yy138;
2418 break;
2419 case 7: /* statement ::= PLACENAME COLON position */
2420 #line 535 "pikchr.y"
2421 { yylhsminor.yy138 = pik_elem_new(p,0,0,0);
2422 if(yylhsminor.yy138){ yylhsminor.yy138->ptAt = yymsp[0].minor.yy47; pik_elem_setname(p,yylhsminor.yy138,&yymsp[-2].minor.yy0); }}
2423 #line 2448 "pikchr.c"
2424 yymsp[-2].minor.yy138 = yylhsminor.yy138;
2425 break;
2426 case 8: /* statement ::= unnamed_statement */
2427 #line 537 "pikchr.y"
2428 {yylhsminor.yy138 = yymsp[0].minor.yy138;}
2429 #line 2454 "pikchr.c"
2430 yymsp[0].minor.yy138 = yylhsminor.yy138;
2431 break;
2432 case 9: /* statement ::= print prlist */
2433 #line 538 "pikchr.y"
2434 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy138=0;}
2435 #line 2460 "pikchr.c"
2436 break;
2437 case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2438 #line 543 "pikchr.y"
2439 {yymsp[-5].minor.yy138=pik_assert(p,yymsp[-3].minor.yy121,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy121);}
2440 #line 2465 "pikchr.c"
2441 break;
2442 case 11: /* statement ::= ASSERT LP position EQ position RP */
2443 #line 545 "pikchr.y"
2444 {yymsp[-5].minor.yy138=pik_position_assert(p,&yymsp[-3].minor.yy47,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy47);}
2445 #line 2470 "pikchr.c"
2446 break;
2447 case 12: /* statement ::= DEFINE ID CODEBLOCK */
2448 #line 546 "pikchr.y"
2449 {yymsp[-2].minor.yy138=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2450 #line 2475 "pikchr.c"
2451 break;
2452 case 13: /* rvalue ::= PLACENAME */
2453 #line 557 "pikchr.y"
2454 {yylhsminor.yy121 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2455 #line 2480 "pikchr.c"
2456 yymsp[0].minor.yy121 = yylhsminor.yy121;
2457 break;
2458 case 14: /* pritem ::= FILL */
2459 case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
2460 case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2461 #line 562 "pikchr.y"
2462 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2463 #line 2488 "pikchr.c"
2464 break;
2465 case 17: /* pritem ::= rvalue */
2466 #line 565 "pikchr.y"
2467 {pik_append_num(p,"",yymsp[0].minor.yy121);}
2468 #line 2493 "pikchr.c"
2469 break;
2470 case 18: /* pritem ::= STRING */
2471 #line 566 "pikchr.y"
2472 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2473 #line 2498 "pikchr.c"
2474 break;
2475 case 19: /* prsep ::= COMMA */
2476 #line 567 "pikchr.y"
2477 {pik_append(p, " ", 1);}
2478 #line 2503 "pikchr.c"
2479 break;
2480 case 20: /* unnamed_statement ::= basetype attribute_list */
2481 #line 570 "pikchr.y"
2482 {yylhsminor.yy138 = yymsp[-1].minor.yy138; pik_after_adding_attributes(p,yylhsminor.yy138);}
2483 #line 2508 "pikchr.c"
2484 yymsp[-1].minor.yy138 = yylhsminor.yy138;
2485 break;
2486 case 21: /* basetype ::= CLASSNAME */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2487 #line 572 "pikchr.y"
2488 {yylhsminor.yy138 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2489 #line 2514 "pikchr.c"
2490 yymsp[0].minor.yy138 = yylhsminor.yy138;
2491 break;
2492 case 22: /* basetype ::= STRING textposition */
2493 #line 574 "pikchr.y"
2494 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy46; yylhsminor.yy138 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2495 #line 2520 "pikchr.c"
2496 yymsp[-1].minor.yy138 = yylhsminor.yy138;
2497 break;
2498 case 23: /* basetype ::= LB savelist statement_list RB */
2499 #line 576 "pikchr.y"
2500 { p->list = yymsp[-2].minor.yy191; yymsp[-3].minor.yy138 = pik_elem_new(p,0,0,yymsp[-1].minor.yy191); if(yymsp[-3].minor.yy138) yymsp[-3].minor.yy138->errTok = yymsp[0].minor.yy0; }
2501 #line 2526 "pikchr.c"
2502 break;
2503 case 24: /* savelist ::= */
 
 
 
 
 
2504 #line 581 "pikchr.y"
2505 {yymsp[1].minor.yy191 = p->list; p->list = 0;}
2506 #line 2531 "pikchr.c"
2507 break;
2508 case 25: /* relexpr ::= expr */
2509 #line 588 "pikchr.y"
2510 {yylhsminor.yy134.rAbs = yymsp[0].minor.yy121; yylhsminor.yy134.rRel = 0;}
2511 #line 2536 "pikchr.c"
2512 yymsp[0].minor.yy134 = yylhsminor.yy134;
2513 break;
2514 case 26: /* relexpr ::= expr PERCENT */
2515 #line 589 "pikchr.y"
2516 {yylhsminor.yy134.rAbs = 0; yylhsminor.yy134.rRel = yymsp[-1].minor.yy121/100;}
2517 #line 2542 "pikchr.c"
2518 yymsp[-1].minor.yy134 = yylhsminor.yy134;
2519 break;
2520 case 27: /* optrelexpr ::= */
2521 #line 591 "pikchr.y"
2522 {yymsp[1].minor.yy134.rAbs = 0; yymsp[1].minor.yy134.rRel = 1.0;}
2523 #line 2548 "pikchr.c"
2524 break;
2525 case 28: /* attribute_list ::= relexpr alist */
2526 #line 593 "pikchr.y"
2527 {pik_add_direction(p,0,&yymsp[-1].minor.yy134);}
2528 #line 2553 "pikchr.c"
2529 break;
2530 case 29: /* attribute ::= numproperty relexpr */
2531 #line 597 "pikchr.y"
2532 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy134); }
2533 #line 2558 "pikchr.c"
2534 break;
2535 case 30: /* attribute ::= dashproperty expr */
2536 #line 598 "pikchr.y"
2537 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy121); }
2538 #line 2563 "pikchr.c"
2539 break;
2540 case 31: /* attribute ::= dashproperty */
2541 #line 599 "pikchr.y"
2542 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2543 #line 2568 "pikchr.c"
2544 break;
2545 case 32: /* attribute ::= colorproperty rvalue */
2546 #line 600 "pikchr.y"
2547 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy121); }
2548 #line 2573 "pikchr.c"
2549 break;
2550 case 33: /* attribute ::= go direction optrelexpr */
2551 #line 601 "pikchr.y"
2552 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy134);}
2553 #line 2578 "pikchr.c"
2554 break;
2555 case 34: /* attribute ::= go direction even position */
2556 #line 602 "pikchr.y"
2557 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy47);}
2558 #line 2583 "pikchr.c"
2559 break;
2560 case 35: /* attribute ::= CLOSE */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2561 #line 603 "pikchr.y"
2562 { pik_close_path(p,&yymsp[0].minor.yy0); }
2563 #line 2588 "pikchr.c"
2564 break;
2565 case 36: /* attribute ::= CHOP */
2566 #line 604 "pikchr.y"
2567 { p->cur->bChop = 1; }
2568 #line 2593 "pikchr.c"
2569 break;
2570 case 37: /* attribute ::= FROM position */
2571 #line 605 "pikchr.y"
2572 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy47); }
2573 #line 2598 "pikchr.c"
2574 break;
2575 case 38: /* attribute ::= TO position */
2576 #line 606 "pikchr.y"
2577 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy47); }
2578 #line 2603 "pikchr.c"
2579 break;
2580 case 39: /* attribute ::= THEN */
2581 #line 607 "pikchr.y"
2582 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2583 #line 2608 "pikchr.c"
2584 break;
2585 case 40: /* attribute ::= THEN optrelexpr HEADING expr */
2586 case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2587 #line 609 "pikchr.y"
2588 {pik_move_hdg(p,&yymsp[-2].minor.yy134,&yymsp[-1].minor.yy0,yymsp[0].minor.yy121,0,&yymsp[-3].minor.yy0);}
2589 #line 2614 "pikchr.c"
2590 break;
2591 case 41: /* attribute ::= THEN optrelexpr EDGEPT */
2592 case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2593 #line 610 "pikchr.y"
2594 {pik_move_hdg(p,&yymsp[-1].minor.yy134,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2595 #line 2620 "pikchr.c"
2596 break;
2597 case 44: /* attribute ::= AT position */
2598 #line 615 "pikchr.y"
2599 { pik_set_at(p,0,&yymsp[0].minor.yy47,&yymsp[-1].minor.yy0); }
2600 #line 2625 "pikchr.c"
2601 break;
2602 case 45: /* attribute ::= SAME */
 
 
 
 
 
 
2603 #line 617 "pikchr.y"
2604 {pik_same(p,0,&yymsp[0].minor.yy0);}
2605 #line 2630 "pikchr.c"
2606 break;
2607 case 46: /* attribute ::= SAME AS object */
2608 #line 618 "pikchr.y"
2609 {pik_same(p,yymsp[0].minor.yy138,&yymsp[-2].minor.yy0);}
2610 #line 2635 "pikchr.c"
2611 break;
2612 case 47: /* attribute ::= STRING textposition */
2613 #line 619 "pikchr.y"
2614 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy46);}
2615 #line 2640 "pikchr.c"
2616 break;
2617 case 48: /* attribute ::= FIT */
2618 #line 620 "pikchr.y"
2619 {pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2620 #line 2645 "pikchr.c"
2621 break;
2622 case 49: /* attribute ::= BEHIND object */
2623 #line 621 "pikchr.y"
2624 {pik_behind(p,yymsp[0].minor.yy138);}
2625 #line 2650 "pikchr.c"
2626 break;
2627 case 50: /* withclause ::= DOT_E edge AT position */
2628 case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2629 #line 629 "pikchr.y"
2630 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy47,&yymsp[-1].minor.yy0); }
2631 #line 2656 "pikchr.c"
2632 break;
2633 case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2634 #line 633 "pikchr.y"
2635 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2636 #line 2661 "pikchr.c"
2637 yymsp[0].minor.yy0 = yylhsminor.yy0;
2638 break;
2639 case 53: /* boolproperty ::= CW */
2640 #line 644 "pikchr.y"
2641 {p->cur->cw = 1;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2642 #line 2667 "pikchr.c"
2643 break;
2644 case 54: /* boolproperty ::= CCW */
2645 #line 645 "pikchr.y"
2646 {p->cur->cw = 0;}
2647 #line 2672 "pikchr.c"
2648 break;
2649 case 55: /* boolproperty ::= LARROW */
2650 #line 646 "pikchr.y"
2651 {p->cur->larrow=1; p->cur->rarrow=0; }
2652 #line 2677 "pikchr.c"
2653 break;
2654 case 56: /* boolproperty ::= RARROW */
2655 #line 647 "pikchr.y"
2656 {p->cur->larrow=0; p->cur->rarrow=1; }
2657 #line 2682 "pikchr.c"
2658 break;
2659 case 57: /* boolproperty ::= LRARROW */
2660 #line 648 "pikchr.y"
2661 {p->cur->larrow=1; p->cur->rarrow=1; }
2662 #line 2687 "pikchr.c"
2663 break;
2664 case 58: /* boolproperty ::= INVIS */
2665 #line 649 "pikchr.y"
2666 {p->cur->sw = 0.0;}
2667 #line 2692 "pikchr.c"
2668 break;
2669 case 59: /* boolproperty ::= THICK */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2670 #line 650 "pikchr.y"
2671 {p->cur->sw *= 1.5;}
2672 #line 2697 "pikchr.c"
 
2673 break;
2674 case 60: /* boolproperty ::= THIN */
2675 #line 651 "pikchr.y"
2676 {p->cur->sw *= 0.67;}
2677 #line 2702 "pikchr.c"
2678 break;
2679 case 61: /* textposition ::= */
2680 #line 653 "pikchr.y"
2681 {yymsp[1].minor.yy46 = 0;}
2682 #line 2707 "pikchr.c"
2683 break;
2684 case 62: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|ALIGNED|BIG|SMALL */
 
 
 
 
 
 
2685 #line 656 "pikchr.y"
2686 {yylhsminor.yy46 = pik_text_position(yymsp[-1].minor.yy46,&yymsp[0].minor.yy0);}
2687 #line 2712 "pikchr.c"
2688 yymsp[-1].minor.yy46 = yylhsminor.yy46;
2689 break;
2690 case 63: /* position ::= expr COMMA expr */
 
 
 
 
 
 
 
 
 
 
 
 
2691 #line 659 "pikchr.y"
2692 {yylhsminor.yy47.x=yymsp[-2].minor.yy121; yylhsminor.yy47.y=yymsp[0].minor.yy121;}
2693 #line 2718 "pikchr.c"
2694 yymsp[-2].minor.yy47 = yylhsminor.yy47;
2695 break;
2696 case 64: /* position ::= place PLUS expr COMMA expr */
2697 #line 661 "pikchr.y"
2698 {yylhsminor.yy47.x=yymsp[-4].minor.yy47.x+yymsp[-2].minor.yy121; yylhsminor.yy47.y=yymsp[-4].minor.yy47.y+yymsp[0].minor.yy121;}
2699 #line 2724 "pikchr.c"
2700 yymsp[-4].minor.yy47 = yylhsminor.yy47;
2701 break;
2702 case 65: /* position ::= place MINUS expr COMMA expr */
2703 #line 662 "pikchr.y"
2704 {yylhsminor.yy47.x=yymsp[-4].minor.yy47.x-yymsp[-2].minor.yy121; yylhsminor.yy47.y=yymsp[-4].minor.yy47.y-yymsp[0].minor.yy121;}
2705 #line 2730 "pikchr.c"
2706 yymsp[-4].minor.yy47 = yylhsminor.yy47;
2707 break;
2708 case 66: /* position ::= place PLUS LP expr COMMA expr RP */
2709 #line 664 "pikchr.y"
2710 {yylhsminor.yy47.x=yymsp[-6].minor.yy47.x+yymsp[-3].minor.yy121; yylhsminor.yy47.y=yymsp[-6].minor.yy47.y+yymsp[-1].minor.yy121;}
2711 #line 2736 "pikchr.c"
2712 yymsp[-6].minor.yy47 = yylhsminor.yy47;
2713 break;
2714 case 67: /* position ::= place MINUS LP expr COMMA expr RP */
2715 #line 666 "pikchr.y"
2716 {yylhsminor.yy47.x=yymsp[-6].minor.yy47.x-yymsp[-3].minor.yy121; yylhsminor.yy47.y=yymsp[-6].minor.yy47.y-yymsp[-1].minor.yy121;}
2717 #line 2742 "pikchr.c"
2718 yymsp[-6].minor.yy47 = yylhsminor.yy47;
2719 break;
2720 case 68: /* position ::= LP position COMMA position RP */
2721 #line 667 "pikchr.y"
2722 {yymsp[-4].minor.yy47.x=yymsp[-3].minor.yy47.x; yymsp[-4].minor.yy47.y=yymsp[-1].minor.yy47.y;}
2723 #line 2748 "pikchr.c"
2724 break;
2725 case 69: /* position ::= LP position RP */
2726 #line 668 "pikchr.y"
2727 {yymsp[-2].minor.yy47=yymsp[-1].minor.yy47;}
2728 #line 2753 "pikchr.c"
 
2729 break;
2730 case 70: /* position ::= expr between position AND position */
2731 #line 670 "pikchr.y"
2732 {yylhsminor.yy47 = pik_position_between(yymsp[-4].minor.yy121,yymsp[-2].minor.yy47,yymsp[0].minor.yy47);}
2733 #line 2758 "pikchr.c"
2734 yymsp[-4].minor.yy47 = yylhsminor.yy47;
2735 break;
2736 case 71: /* position ::= expr LT position COMMA position GT */
2737 #line 672 "pikchr.y"
2738 {yylhsminor.yy47 = pik_position_between(yymsp[-5].minor.yy121,yymsp[-3].minor.yy47,yymsp[-1].minor.yy47);}
2739 #line 2764 "pikchr.c"
2740 yymsp[-5].minor.yy47 = yylhsminor.yy47;
2741 break;
2742 case 72: /* position ::= expr ABOVE position */
2743 #line 673 "pikchr.y"
2744 {yylhsminor.yy47=yymsp[0].minor.yy47; yylhsminor.yy47.y += yymsp[-2].minor.yy121;}
2745 #line 2770 "pikchr.c"
2746 yymsp[-2].minor.yy47 = yylhsminor.yy47;
2747 break;
2748 case 73: /* position ::= expr BELOW position */
2749 #line 674 "pikchr.y"
2750 {yylhsminor.yy47=yymsp[0].minor.yy47; yylhsminor.yy47.y -= yymsp[-2].minor.yy121;}
2751 #line 2776 "pikchr.c"
2752 yymsp[-2].minor.yy47 = yylhsminor.yy47;
2753 break;
2754 case 74: /* position ::= expr LEFT OF position */
2755 #line 675 "pikchr.y"
2756 {yylhsminor.yy47=yymsp[0].minor.yy47; yylhsminor.yy47.x -= yymsp[-3].minor.yy121;}
2757 #line 2782 "pikchr.c"
2758 yymsp[-3].minor.yy47 = yylhsminor.yy47;
2759 break;
2760 case 75: /* position ::= expr RIGHT OF position */
2761 #line 676 "pikchr.y"
2762 {yylhsminor.yy47=yymsp[0].minor.yy47; yylhsminor.yy47.x += yymsp[-3].minor.yy121;}
2763 #line 2788 "pikchr.c"
2764 yymsp[-3].minor.yy47 = yylhsminor.yy47;
2765 break;
2766 case 76: /* position ::= expr ON HEADING EDGEPT OF position */
2767 #line 678 "pikchr.y"
2768 {yylhsminor.yy47 = pik_position_at_hdg(yymsp[-5].minor.yy121,&yymsp[-2].minor.yy0,yymsp[0].minor.yy47);}
2769 #line 2794 "pikchr.c"
2770 yymsp[-5].minor.yy47 = yylhsminor.yy47;
2771 break;
2772 case 77: /* position ::= expr HEADING EDGEPT OF position */
2773 #line 680 "pikchr.y"
2774 {yylhsminor.yy47 = pik_position_at_hdg(yymsp[-4].minor.yy121,&yymsp[-2].minor.yy0,yymsp[0].minor.yy47);}
2775 #line 2800 "pikchr.c"
2776 yymsp[-4].minor.yy47 = yylhsminor.yy47;
2777 break;
2778 case 78: /* position ::= expr EDGEPT OF position */
2779 #line 682 "pikchr.y"
2780 {yylhsminor.yy47 = pik_position_at_hdg(yymsp[-3].minor.yy121,&yymsp[-2].minor.yy0,yymsp[0].minor.yy47);}
2781 #line 2806 "pikchr.c"
2782 yymsp[-3].minor.yy47 = yylhsminor.yy47;
2783 break;
2784 case 79: /* position ::= expr ON HEADING expr FROM position */
 
 
 
 
 
 
2785 #line 684 "pikchr.y"
2786 {yylhsminor.yy47 = pik_position_at_angle(yymsp[-5].minor.yy121,yymsp[-2].minor.yy121,yymsp[0].minor.yy47);}
2787 #line 2812 "pikchr.c"
2788 yymsp[-5].minor.yy47 = yylhsminor.yy47;
2789 break;
2790 case 80: /* position ::= expr HEADING expr FROM position */
2791 #line 686 "pikchr.y"
2792 {yylhsminor.yy47 = pik_position_at_angle(yymsp[-4].minor.yy121,yymsp[-2].minor.yy121,yymsp[0].minor.yy47);}
2793 #line 2818 "pikchr.c"
2794 yymsp[-4].minor.yy47 = yylhsminor.yy47;
2795 break;
2796 case 81: /* place ::= edge OF object */
 
 
 
 
 
 
2797 #line 698 "pikchr.y"
2798 {yylhsminor.yy47 = pik_place_of_elem(p,yymsp[0].minor.yy138,&yymsp[-2].minor.yy0);}
2799 #line 2824 "pikchr.c"
2800 yymsp[-2].minor.yy47 = yylhsminor.yy47;
2801 break;
2802 case 82: /* place2 ::= object */
2803 #line 699 "pikchr.y"
2804 {yylhsminor.yy47 = pik_place_of_elem(p,yymsp[0].minor.yy138,0);}
2805 #line 2830 "pikchr.c"
2806 yymsp[0].minor.yy47 = yylhsminor.yy47;
2807 break;
2808 case 83: /* place2 ::= object DOT_E edge */
2809 #line 700 "pikchr.y"
2810 {yylhsminor.yy47 = pik_place_of_elem(p,yymsp[-2].minor.yy138,&yymsp[0].minor.yy0);}
2811 #line 2836 "pikchr.c"
2812 yymsp[-2].minor.yy47 = yylhsminor.yy47;
2813 break;
2814 case 84: /* place2 ::= NTH VERTEX OF object */
2815 #line 701 "pikchr.y"
2816 {yylhsminor.yy47 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy138);}
2817 #line 2842 "pikchr.c"
2818 yymsp[-3].minor.yy47 = yylhsminor.yy47;
2819 break;
2820 case 85: /* object ::= nth */
2821 #line 713 "pikchr.y"
2822 {yylhsminor.yy138 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2823 #line 2848 "pikchr.c"
2824 yymsp[0].minor.yy138 = yylhsminor.yy138;
2825 break;
2826 case 86: /* object ::= nth OF|IN object */
2827 #line 714 "pikchr.y"
2828 {yylhsminor.yy138 = pik_find_nth(p,yymsp[0].minor.yy138,&yymsp[-2].minor.yy0);}
2829 #line 2854 "pikchr.c"
2830 yymsp[-2].minor.yy138 = yylhsminor.yy138;
2831 break;
2832 case 87: /* objectname ::= PLACENAME */
2833 #line 716 "pikchr.y"
2834 {yylhsminor.yy138 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2835 #line 2860 "pikchr.c"
2836 yymsp[0].minor.yy138 = yylhsminor.yy138;
2837 break;
2838 case 88: /* objectname ::= objectname DOT_U PLACENAME */
2839 #line 718 "pikchr.y"
2840 {yylhsminor.yy138 = pik_find_byname(p,yymsp[-2].minor.yy138,&yymsp[0].minor.yy0);}
2841 #line 2866 "pikchr.c"
2842 yymsp[-2].minor.yy138 = yylhsminor.yy138;
2843 break;
2844 case 89: /* nth ::= NTH CLASSNAME */
2845 #line 720 "pikchr.y"
2846 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2847 #line 2872 "pikchr.c"
2848 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2849 break;
2850 case 90: /* nth ::= NTH LAST CLASSNAME */
2851 #line 721 "pikchr.y"
2852 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2853 #line 2878 "pikchr.c"
2854 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2855 break;
2856 case 91: /* nth ::= LAST CLASSNAME */
2857 #line 722 "pikchr.y"
2858 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2859 #line 2884 "pikchr.c"
2860 break;
2861 case 92: /* nth ::= LAST */
2862 #line 723 "pikchr.y"
2863 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2864 #line 2889 "pikchr.c"
2865 yymsp[0].minor.yy0 = yylhsminor.yy0;
2866 break;
2867 case 93: /* nth ::= NTH LB RB */
2868 #line 724 "pikchr.y"
2869 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2870 #line 2895 "pikchr.c"
2871 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2872 break;
2873 case 94: /* nth ::= NTH LAST LB RB */
2874 #line 725 "pikchr.y"
2875 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2876 #line 2901 "pikchr.c"
2877 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2878 break;
2879 case 95: /* nth ::= LAST LB RB */
2880 #line 726 "pikchr.y"
2881 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2882 #line 2907 "pikchr.c"
2883 break;
2884 case 96: /* expr ::= expr PLUS expr */
2885 #line 728 "pikchr.y"
2886 {yylhsminor.yy121=yymsp[-2].minor.yy121+yymsp[0].minor.yy121;}
2887 #line 2912 "pikchr.c"
2888 yymsp[-2].minor.yy121 = yylhsminor.yy121;
2889 break;
2890 case 97: /* expr ::= expr MINUS expr */
2891 #line 729 "pikchr.y"
2892 {yylhsminor.yy121=yymsp[-2].minor.yy121-yymsp[0].minor.yy121;}
2893 #line 2918 "pikchr.c"
2894 yymsp[-2].minor.yy121 = yylhsminor.yy121;
2895 break;
2896 case 98: /* expr ::= expr STAR expr */
2897 #line 730 "pikchr.y"
2898 {yylhsminor.yy121=yymsp[-2].minor.yy121*yymsp[0].minor.yy121;}
2899 #line 2924 "pikchr.c"
2900 yymsp[-2].minor.yy121 = yylhsminor.yy121;
2901 break;
2902 case 99: /* expr ::= expr SLASH expr */
2903 #line 731 "pikchr.y"
2904 {
2905 if( yymsp[0].minor.yy121==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy121 = 0.0; }
2906 else{ yylhsminor.yy121 = yymsp[-2].minor.yy121/yymsp[0].minor.yy121; }
2907 }
2908 #line 2933 "pikchr.c"
2909 yymsp[-2].minor.yy121 = yylhsminor.yy121;
2910 break;
2911 case 100: /* expr ::= MINUS expr */
2912 #line 735 "pikchr.y"
2913 {yymsp[-1].minor.yy121=-yymsp[0].minor.yy121;}
2914 #line 2939 "pikchr.c"
2915 break;
2916 case 101: /* expr ::= PLUS expr */
2917 #line 736 "pikchr.y"
2918 {yymsp[-1].minor.yy121=yymsp[0].minor.yy121;}
2919 #line 2944 "pikchr.c"
2920 break;
2921 case 102: /* expr ::= LP expr RP */
2922 #line 737 "pikchr.y"
2923 {yymsp[-2].minor.yy121=yymsp[-1].minor.yy121;}
2924 #line 2949 "pikchr.c"
2925 break;
2926 case 103: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2927 #line 738 "pikchr.y"
2928 {yymsp[-2].minor.yy121=pik_get_var(p,&yymsp[-1].minor.yy0);}
2929 #line 2954 "pikchr.c"
2930 break;
2931 case 104: /* expr ::= NUMBER */
2932 #line 739 "pikchr.y"
2933 {yylhsminor.yy121=pik_atof(&yymsp[0].minor.yy0);}
2934 #line 2959 "pikchr.c"
2935 yymsp[0].minor.yy121 = yylhsminor.yy121;
2936 break;
2937 case 105: /* expr ::= ID */
2938 #line 740 "pikchr.y"
2939 {yylhsminor.yy121=pik_get_var(p,&yymsp[0].minor.yy0);}
2940 #line 2965 "pikchr.c"
2941 yymsp[0].minor.yy121 = yylhsminor.yy121;
2942 break;
2943 case 106: /* expr ::= FUNC1 LP expr RP */
2944 #line 741 "pikchr.y"
2945 {yylhsminor.yy121 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy121,0.0);}
2946 #line 2971 "pikchr.c"
2947 yymsp[-3].minor.yy121 = yylhsminor.yy121;
2948 break;
2949 case 107: /* expr ::= FUNC2 LP expr COMMA expr RP */
2950 #line 742 "pikchr.y"
2951 {yylhsminor.yy121 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy121,yymsp[-1].minor.yy121);}
2952 #line 2977 "pikchr.c"
2953 yymsp[-5].minor.yy121 = yylhsminor.yy121;
2954 break;
2955 case 108: /* expr ::= DIST LP position COMMA position RP */
2956 #line 743 "pikchr.y"
2957 {yymsp[-5].minor.yy121 = pik_dist(&yymsp[-3].minor.yy47,&yymsp[-1].minor.yy47);}
2958 #line 2983 "pikchr.c"
2959 break;
2960 case 109: /* expr ::= place2 DOT_XY X */
2961 #line 744 "pikchr.y"
2962 {yylhsminor.yy121 = yymsp[-2].minor.yy47.x;}
2963 #line 2988 "pikchr.c"
2964 yymsp[-2].minor.yy121 = yylhsminor.yy121;
2965 break;
2966 case 110: /* expr ::= place2 DOT_XY Y */
2967 #line 745 "pikchr.y"
2968 {yylhsminor.yy121 = yymsp[-2].minor.yy47.y;}
2969 #line 2994 "pikchr.c"
2970 yymsp[-2].minor.yy121 = yylhsminor.yy121;
2971 break;
2972 case 111: /* expr ::= object DOT_L numproperty */
2973 case 112: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==112);
2974 case 113: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==113);
2975 #line 746 "pikchr.y"
2976 {yylhsminor.yy121=pik_property_of(yymsp[-2].minor.yy138,&yymsp[0].minor.yy0);}
2977 #line 3002 "pikchr.c"
2978 yymsp[-2].minor.yy121 = yylhsminor.yy121;
2979 break;
2980 default:
2981 /* (114) lvalue ::= ID */ yytestcase(yyruleno==114);
2982 /* (115) lvalue ::= FILL */ yytestcase(yyruleno==115);
2983 /* (116) lvalue ::= COLOR */ yytestcase(yyruleno==116);
2984 /* (117) lvalue ::= THICKNESS */ yytestcase(yyruleno==117);
2985 /* (118) rvalue ::= expr */ yytestcase(yyruleno==118);
2986 /* (119) print ::= PRINT */ yytestcase(yyruleno==119);
2987 /* (120) prlist ::= pritem (OPTIMIZED OUT) */ assert(yyruleno!=120);
2988 /* (121) prlist ::= prlist prsep pritem */ yytestcase(yyruleno==121);
2989 /* (122) direction ::= UP */ yytestcase(yyruleno==122);
2990 /* (123) direction ::= DOWN */ yytestcase(yyruleno==123);
2991 /* (124) direction ::= LEFT */ yytestcase(yyruleno==124);
2992 /* (125) direction ::= RIGHT */ yytestcase(yyruleno==125);
2993 /* (126) optrelexpr ::= relexpr (OPTIMIZED OUT) */ assert(yyruleno!=126);
2994 /* (127) attribute_list ::= alist */ yytestcase(yyruleno==127);
2995 /* (128) alist ::= */ yytestcase(yyruleno==128);
2996 /* (129) alist ::= alist attribute */ yytestcase(yyruleno==129);
2997 /* (130) attribute ::= boolproperty (OPTIMIZED OUT) */ assert(yyruleno!=130);
2998 /* (131) attribute ::= WITH withclause */ yytestcase(yyruleno==131);
2999 /* (132) go ::= GO */ yytestcase(yyruleno==132);
3000 /* (133) go ::= */ yytestcase(yyruleno==133);
3001 /* (134) even ::= UNTIL EVEN WITH */ yytestcase(yyruleno==134);
3002 /* (135) even ::= EVEN WITH */ yytestcase(yyruleno==135);
3003 /* (136) dashproperty ::= DOTTED */ yytestcase(yyruleno==136);
3004 /* (137) dashproperty ::= DASHED */ yytestcase(yyruleno==137);
3005 /* (138) colorproperty ::= FILL */ yytestcase(yyruleno==138);
3006 /* (139) colorproperty ::= COLOR */ yytestcase(yyruleno==139);
3007 /* (140) position ::= place */ yytestcase(yyruleno==140);
3008 /* (141) between ::= WAY BETWEEN */ yytestcase(yyruleno==141);
3009 /* (142) between ::= BETWEEN */ yytestcase(yyruleno==142);
3010 /* (143) between ::= OF THE WAY BETWEEN */ yytestcase(yyruleno==143);
3011 /* (144) place ::= place2 */ yytestcase(yyruleno==144);
3012 /* (145) edge ::= CENTER */ yytestcase(yyruleno==145);
3013 /* (146) edge ::= EDGEPT */ yytestcase(yyruleno==146);
3014 /* (147) edge ::= TOP */ yytestcase(yyruleno==147);
3015 /* (148) edge ::= BOTTOM */ yytestcase(yyruleno==148);
3016 /* (149) edge ::= START */ yytestcase(yyruleno==149);
3017 /* (150) edge ::= END */ yytestcase(yyruleno==150);
3018 /* (151) edge ::= RIGHT */ yytestcase(yyruleno==151);
3019 /* (152) edge ::= LEFT */ yytestcase(yyruleno==152);
3020 /* (153) object ::= objectname */ yytestcase(yyruleno==153);
3021 break;
3022 /********** End reduce actions ************************************************/
3023 };
3024 assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
3025 yygoto = yyRuleInfoLhs[yyruleno];
@@ -3050,19 +3075,19 @@
3075 ){
3076 pik_parserARG_FETCH
3077 pik_parserCTX_FETCH
3078 #define TOKEN yyminor
3079 /************ Begin %syntax_error code ****************************************/
3080 #line 509 "pikchr.y"
3081
3082 if( TOKEN.z && TOKEN.z[0] ){
3083 pik_error(p, &TOKEN, "syntax error");
3084 }else{
3085 pik_error(p, 0, "syntax error");
3086 }
3087 UNUSED_PARAMETER(yymajor);
3088 #line 3113 "pikchr.c"
3089 /************ End %syntax_error code ******************************************/
3090 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3091 pik_parserCTX_STORE
3092 }
3093
@@ -3291,11 +3316,11 @@
3316 #else
3317 (void)iToken;
3318 return 0;
3319 #endif
3320 }
3321 #line 751 "pikchr.y"
3322
3323
3324
3325 /* Chart of the 140 official HTML color names with their
3326 ** corresponding RGB value.
@@ -3497,13 +3522,13 @@
3522 { "thickness", 0.015 },
3523 };
3524
3525
3526 /* Methods for the "arc" class */
3527 static void arcInit(Pik *p, PObj *pObj){
3528 pObj->w = pik_value(p, "arcrad",6,0);
3529 pObj->h = pObj->w;
3530 }
3531 /* Hack: Arcs are here rendered as quadratic Bezier curves rather
3532 ** than true arcs. Multiple reasons: (1) the legacy-PIC parameters
3533 ** that control arcs are obscure and I could not figure out what they
3534 ** mean based on available documentation. (2) Arcs are rarely used,
@@ -3523,65 +3548,65 @@
3548 m.x += 0.5*rScale*dy;
3549 m.y -= 0.5*rScale*dx;
3550 }
3551 return m;
3552 }
3553 static void arcCheck(Pik *p, PObj *pObj){
3554 PPoint m;
3555 if( p->nTPath>2 ){
3556 pik_error(p, &pObj->errTok, "arc geometry error");
3557 return;
3558 }
3559 m = arcControlPoint(pObj->cw, p->aTPath[0], p->aTPath[1], 0.5);
3560 pik_bbox_add_xy(&pObj->bbox, m.x, m.y);
3561 }
3562 static void arcRender(Pik *p, PObj *pObj){
3563 PPoint f, m, t;
3564 if( pObj->nPath<2 ) return;
3565 if( pObj->sw<=0.0 ) return;
3566 f = pObj->aPath[0];
3567 t = pObj->aPath[1];
3568 m = arcControlPoint(pObj->cw,f,t,1.0);
3569 if( pObj->larrow ){
3570 pik_draw_arrowhead(p,&m,&f,pObj);
3571 }
3572 if( pObj->rarrow ){
3573 pik_draw_arrowhead(p,&m,&t,pObj);
3574 }
3575 pik_append_xy(p,"<path d=\"M", f.x, f.y);
3576 pik_append_xy(p,"Q", m.x, m.y);
3577 pik_append_xy(p," ", t.x, t.y);
3578 pik_append(p,"\" ",2);
3579 pik_append_style(p,pObj,0);
3580 pik_append(p,"\" />\n", -1);
3581
3582 pik_append_txt(p, pObj, 0);
3583 }
3584
3585
3586 /* Methods for the "arrow" class */
3587 static void arrowInit(Pik *p, PObj *pObj){
3588 pObj->w = pik_value(p, "linewid",7,0);
3589 pObj->h = pik_value(p, "lineht",6,0);
3590 pObj->rad = pik_value(p, "linerad",7,0);
3591 pObj->fill = -1.0;
3592 pObj->rarrow = 1;
3593 }
3594
3595 /* Methods for the "box" class */
3596 static void boxInit(Pik *p, PObj *pObj){
3597 pObj->w = pik_value(p, "boxwid",6,0);
3598 pObj->h = pik_value(p, "boxht",5,0);
3599 pObj->rad = pik_value(p, "boxrad",6,0);
3600 }
3601 /* Return offset from the center of the box to the compass point
3602 ** given by parameter cp */
3603 static PPoint boxOffset(Pik *p, PObj *pObj, int cp){
3604 PPoint pt = cZeroPoint;
3605 PNum w2 = 0.5*pObj->w;
3606 PNum h2 = 0.5*pObj->h;
3607 PNum rad = pObj->rad;
3608 PNum rx;
3609 if( rad<=0.0 ){
3610 rx = 0.0;
3611 }else{
3612 if( rad>w2 ) rad = w2;
@@ -3601,18 +3626,18 @@
3626 default: assert(0);
3627 }
3628 UNUSED_PARAMETER(p);
3629 return pt;
3630 }
3631 static PPoint boxChop(Pik *p, PObj *pObj, PPoint *pPt){
3632 PNum dx, dy;
3633 int cp = CP_C;
3634 PPoint chop = pObj->ptAt;
3635 if( pObj->w<=0.0 ) return chop;
3636 if( pObj->h<=0.0 ) return chop;
3637 dx = (pPt->x - pObj->ptAt.x)*pObj->h/pObj->w;
3638 dy = (pPt->y - pObj->ptAt.y);
3639 if( dx>0.0 ){
3640 if( dy>=2.414*dx ){
3641 cp = CP_N;
3642 }else if( dy>=0.414*dx ){
3643 cp = CP_NE;
@@ -3634,26 +3659,26 @@
3659 cp = CP_SW;
3660 }else{
3661 cp = CP_S;
3662 }
3663 }
3664 chop = pObj->type->xOffset(p,pObj,cp);
3665 chop.x += pObj->ptAt.x;
3666 chop.y += pObj->ptAt.y;
3667 return chop;
3668 }
3669 static void boxFit(Pik *p, PObj *pObj, PNum w, PNum h){
3670 if( w>0 ) pObj->w = w;
3671 if( h>0 ) pObj->h = h;
3672 UNUSED_PARAMETER(p);
3673 }
3674 static void boxRender(Pik *p, PObj *pObj){
3675 PNum w2 = 0.5*pObj->w;
3676 PNum h2 = 0.5*pObj->h;
3677 PNum rad = pObj->rad;
3678 PPoint pt = pObj->ptAt;
3679 if( pObj->sw>0.0 ){
3680 if( rad<=0.0 ){
3681 pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y-h2);
3682 pik_append_xy(p,"L", pt.x+w2,pt.y-h2);
3683 pik_append_xy(p,"L", pt.x+w2,pt.y+h2);
3684 pik_append_xy(p,"L", pt.x-w2,pt.y+h2);
@@ -3692,112 +3717,112 @@
3717 pik_append_arc(p, rad, rad, x0, y2);
3718 if( y2>y1 ) pik_append_xy(p, "L", x0, y1);
3719 pik_append_arc(p, rad, rad, x1, y0);
3720 pik_append(p,"Z\" ",-1);
3721 }
3722 pik_append_style(p,pObj,1);
3723 pik_append(p,"\" />\n", -1);
3724 }
3725 pik_append_txt(p, pObj, 0);
3726 }
3727
3728 /* Methods for the "circle" class */
3729 static void circleInit(Pik *p, PObj *pObj){
3730 pObj->w = pik_value(p, "circlerad",9,0)*2;
3731 pObj->h = pObj->w;
3732 pObj->rad = 0.5*pObj->w;
3733 }
3734 static void circleNumProp(Pik *p, PObj *pObj, PToken *pId){
3735 /* For a circle, the width must equal the height and both must
3736 ** be twice the radius. Enforce those constraints. */
3737 switch( pId->eType ){
3738 case T_RADIUS:
3739 pObj->w = pObj->h = 2.0*pObj->rad;
3740 break;
3741 case T_WIDTH:
3742 pObj->h = pObj->w;
3743 pObj->rad = 0.5*pObj->w;
3744 break;
3745 case T_HEIGHT:
3746 pObj->w = pObj->h;
3747 pObj->rad = 0.5*pObj->w;
3748 break;
3749 }
3750 UNUSED_PARAMETER(p);
3751 }
3752 static PPoint circleChop(Pik *p, PObj *pObj, PPoint *pPt){
3753 PPoint chop;
3754 PNum dx = pPt->x - pObj->ptAt.x;
3755 PNum dy = pPt->y - pObj->ptAt.y;
3756 PNum dist = hypot(dx,dy);
3757 if( dist<pObj->rad ) return pObj->ptAt;
3758 chop.x = pObj->ptAt.x + dx*pObj->rad/dist;
3759 chop.y = pObj->ptAt.y + dy*pObj->rad/dist;
3760 UNUSED_PARAMETER(p);
3761 return chop;
3762 }
3763 static void circleFit(Pik *p, PObj *pObj, PNum w, PNum h){
3764 PNum mx = 0.0;
3765 if( w>0 ) mx = w;
3766 if( h>mx ) mx = h;
3767 if( w*h>0 && (w*w + h*h) > mx*mx ){
3768 mx = hypot(w,h);
3769 }
3770 if( mx>0.0 ){
3771 pObj->rad = 0.5*mx;
3772 pObj->w = pObj->h = mx;
3773 }
3774 UNUSED_PARAMETER(p);
3775 }
3776
3777 static void circleRender(Pik *p, PObj *pObj){
3778 PNum r = pObj->rad;
3779 PPoint pt = pObj->ptAt;
3780 if( pObj->sw>0.0 ){
3781 pik_append_x(p,"<circle cx=\"", pt.x, "\"");
3782 pik_append_y(p," cy=\"", pt.y, "\"");
3783 pik_append_dis(p," r=\"", r, "\" ");
3784 pik_append_style(p,pObj,1);
3785 pik_append(p,"\" />\n", -1);
3786 }
3787 pik_append_txt(p, pObj, 0);
3788 }
3789
3790 /* Methods for the "cylinder" class */
3791 static void cylinderInit(Pik *p, PObj *pObj){
3792 pObj->w = pik_value(p, "cylwid",6,0);
3793 pObj->h = pik_value(p, "cylht",5,0);
3794 pObj->rad = pik_value(p, "cylrad",6,0); /* Minor radius of ellipses */
3795 }
3796 static void cylinderFit(Pik *p, PObj *pObj, PNum w, PNum h){
3797 if( w>0 ) pObj->w = w;
3798 if( h>0 ) pObj->h = h + 4*pObj->rad + pObj->sw;
3799 UNUSED_PARAMETER(p);
3800 }
3801 static void cylinderRender(Pik *p, PObj *pObj){
3802 PNum w2 = 0.5*pObj->w;
3803 PNum h2 = 0.5*pObj->h;
3804 PNum rad = pObj->rad;
3805 PPoint pt = pObj->ptAt;
3806 if( pObj->sw>0.0 ){
3807 pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y+h2-rad);
3808 pik_append_xy(p,"L", pt.x-w2,pt.y-h2+rad);
3809 pik_append_arc(p,w2,rad,pt.x+w2,pt.y-h2+rad);
3810 pik_append_xy(p,"L", pt.x+w2,pt.y+h2-rad);
3811 pik_append_arc(p,w2,rad,pt.x-w2,pt.y+h2-rad);
3812 pik_append_arc(p,w2,rad,pt.x+w2,pt.y+h2-rad);
3813 pik_append(p,"\" ",-1);
3814 pik_append_style(p,pObj,1);
3815 pik_append(p,"\" />\n", -1);
3816 }
3817 pik_append_txt(p, pObj, 0);
3818 }
3819 static PPoint cylinderOffset(Pik *p, PObj *pObj, int cp){
3820 PPoint pt = cZeroPoint;
3821 PNum w2 = pObj->w*0.5;
3822 PNum h1 = pObj->h*0.5;
3823 PNum h2 = h1 - pObj->rad;
3824 switch( cp ){
3825 case CP_C: break;
3826 case CP_N: pt.x = 0.0; pt.y = h1; break;
3827 case CP_NE: pt.x = w2; pt.y = h2; break;
3828 case CP_E: pt.x = w2; pt.y = 0.0; break;
@@ -3811,79 +3836,79 @@
3836 UNUSED_PARAMETER(p);
3837 return pt;
3838 }
3839
3840 /* Methods for the "dot" class */
3841 static void dotInit(Pik *p, PObj *pObj){
3842 pObj->rad = pik_value(p, "dotrad",6,0);
3843 pObj->h = pObj->w = pObj->rad*6;
3844 pObj->fill = pObj->color;
3845 }
3846 static void dotNumProp(Pik *p, PObj *pObj, PToken *pId){
3847 switch( pId->eType ){
3848 case T_COLOR:
3849 pObj->fill = pObj->color;
3850 break;
3851 case T_FILL:
3852 pObj->color = pObj->fill;
3853 break;
3854 }
3855 UNUSED_PARAMETER(p);
3856 }
3857 static void dotCheck(Pik *p, PObj *pObj){
3858 pObj->w = pObj->h = 0;
3859 pik_bbox_addellipse(&pObj->bbox, pObj->ptAt.x, pObj->ptAt.y,
3860 pObj->rad, pObj->rad);
3861 UNUSED_PARAMETER(p);
3862 }
3863 static PPoint dotOffset(Pik *p, PObj *pObj, int cp){
3864 UNUSED_PARAMETER(p);
3865 UNUSED_PARAMETER(pObj);
3866 UNUSED_PARAMETER(cp);
3867 return cZeroPoint;
3868 }
3869 static void dotRender(Pik *p, PObj *pObj){
3870 PNum r = pObj->rad;
3871 PPoint pt = pObj->ptAt;
3872 if( pObj->sw>0.0 ){
3873 pik_append_x(p,"<circle cx=\"", pt.x, "\"");
3874 pik_append_y(p," cy=\"", pt.y, "\"");
3875 pik_append_dis(p," r=\"", r, "\"");
3876 pik_append_style(p,pObj,1);
3877 pik_append(p,"\" />\n", -1);
3878 }
3879 pik_append_txt(p, pObj, 0);
3880 }
3881
3882
3883
3884 /* Methods for the "ellipse" class */
3885 static void ellipseInit(Pik *p, PObj *pObj){
3886 pObj->w = pik_value(p, "ellipsewid",10,0);
3887 pObj->h = pik_value(p, "ellipseht",9,0);
3888 }
3889 static PPoint ellipseChop(Pik *p, PObj *pObj, PPoint *pPt){
3890 PPoint chop;
3891 PNum s, dq, dist;
3892 PNum dx = pPt->x - pObj->ptAt.x;
3893 PNum dy = pPt->y - pObj->ptAt.y;
3894 if( pObj->w<=0.0 ) return pObj->ptAt;
3895 if( pObj->h<=0.0 ) return pObj->ptAt;
3896 s = pObj->h/pObj->w;
3897 dq = dx*s;
3898 dist = hypot(dq,dy);
3899 if( dist<pObj->h ) return pObj->ptAt;
3900 chop.x = pObj->ptAt.x + 0.5*dq*pObj->h/(dist*s);
3901 chop.y = pObj->ptAt.y + 0.5*dy*pObj->h/dist;
3902 UNUSED_PARAMETER(p);
3903 return chop;
3904 }
3905 static PPoint ellipseOffset(Pik *p, PObj *pObj, int cp){
3906 PPoint pt = cZeroPoint;
3907 PNum w = pObj->w*0.5;
3908 PNum w2 = w*0.70710678118654747608;
3909 PNum h = pObj->h*0.5;
3910 PNum h2 = h*0.70710678118654747608;
3911 switch( cp ){
3912 case CP_C: break;
3913 case CP_N: pt.x = 0.0; pt.y = h; break;
3914 case CP_NE: pt.x = w2; pt.y = h2; break;
@@ -3896,38 +3921,38 @@
3921 default: assert(0);
3922 }
3923 UNUSED_PARAMETER(p);
3924 return pt;
3925 }
3926 static void ellipseRender(Pik *p, PObj *pObj){
3927 PNum w = pObj->w;
3928 PNum h = pObj->h;
3929 PPoint pt = pObj->ptAt;
3930 if( pObj->sw>0.0 ){
3931 pik_append_x(p,"<ellipse cx=\"", pt.x, "\"");
3932 pik_append_y(p," cy=\"", pt.y, "\"");
3933 pik_append_dis(p," rx=\"", w/2.0, "\"");
3934 pik_append_dis(p," ry=\"", h/2.0, "\" ");
3935 pik_append_style(p,pObj,1);
3936 pik_append(p,"\" />\n", -1);
3937 }
3938 pik_append_txt(p, pObj, 0);
3939 }
3940
3941 /* Methods for the "file" object */
3942 static void fileInit(Pik *p, PObj *pObj){
3943 pObj->w = pik_value(p, "filewid",7,0);
3944 pObj->h = pik_value(p, "fileht",6,0);
3945 pObj->rad = pik_value(p, "filerad",7,0);
3946 }
3947 /* Return offset from the center of the file to the compass point
3948 ** given by parameter cp */
3949 static PPoint fileOffset(Pik *p, PObj *pObj, int cp){
3950 PPoint pt = cZeroPoint;
3951 PNum w2 = 0.5*pObj->w;
3952 PNum h2 = 0.5*pObj->h;
3953 PNum rx = pObj->rad;
3954 PNum mn = w2<h2 ? w2 : h2;
3955 if( rx>mn ) rx = mn;
3956 if( rx<mn*0.25 ) rx = mn*0.25;
3957 pt.x = pt.y = 0.0;
3958 rx *= 0.5;
@@ -3944,132 +3969,133 @@
3969 default: assert(0);
3970 }
3971 UNUSED_PARAMETER(p);
3972 return pt;
3973 }
3974 static void fileFit(Pik *p, PObj *pObj, PNum w, PNum h){
3975 if( w>0 ) pObj->w = w;
3976 if( h>0 ) pObj->h = h + 2*pObj->rad;
3977 UNUSED_PARAMETER(p);
3978 }
3979 static void fileRender(Pik *p, PObj *pObj){
3980 PNum w2 = 0.5*pObj->w;
3981 PNum h2 = 0.5*pObj->h;
3982 PNum rad = pObj->rad;
3983 PPoint pt = pObj->ptAt;
3984 PNum mn = w2<h2 ? w2 : h2;
3985 if( rad>mn ) rad = mn;
3986 if( rad<mn*0.25 ) rad = mn*0.25;
3987 if( pObj->sw>0.0 ){
3988 pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y-h2);
3989 pik_append_xy(p,"L", pt.x+w2,pt.y-h2);
3990 pik_append_xy(p,"L", pt.x+w2,pt.y+(h2-rad));
3991 pik_append_xy(p,"L", pt.x+(w2-rad),pt.y+h2);
3992 pik_append_xy(p,"L", pt.x-w2,pt.y+h2);
3993 pik_append(p,"Z\" ",-1);
3994 pik_append_style(p,pObj,1);
3995 pik_append(p,"\" />\n",-1);
3996 pik_append_xy(p,"<path d=\"M", pt.x+(w2-rad), pt.y+h2);
3997 pik_append_xy(p,"L", pt.x+(w2-rad),pt.y+(h2-rad));
3998 pik_append_xy(p,"L", pt.x+w2, pt.y+(h2-rad));
3999 pik_append(p,"\" ",-1);
4000 pik_append_style(p,pObj,0);
4001 pik_append(p,"\" />\n",-1);
4002 }
4003 pik_append_txt(p, pObj, 0);
4004 }
4005
4006
4007 /* Methods for the "line" class */
4008 static void lineInit(Pik *p, PObj *pObj){
4009 pObj->w = pik_value(p, "linewid",7,0);
4010 pObj->h = pik_value(p, "lineht",6,0);
4011 pObj->rad = pik_value(p, "linerad",7,0);
4012 pObj->fill = -1.0;
4013 }
4014 static PPoint lineOffset(Pik *p, PObj *pObj, int cp){
4015 #if 0
4016 /* In legacy PIC, the .center of an unclosed line is half way between
4017 ** its .start and .end. */
4018 if( cp==CP_C && !pObj->bClose ){
4019 PPoint out;
4020 out.x = 0.5*(pObj->ptEnter.x + pObj->ptExit.x) - pObj->ptAt.x;
4021 out.y = 0.5*(pObj->ptEnter.x + pObj->ptExit.y) - pObj->ptAt.y;
4022 return out;
4023 }
4024 #endif
4025 return boxOffset(p,pObj,cp);
4026 }
4027 static void lineRender(Pik *p, PObj *pObj){
4028 int i;
4029 if( pObj->sw>0.0 ){
4030 const char *z = "<path d=\"M";
4031 int n = pObj->nPath;
4032 if( pObj->larrow ){
4033 pik_draw_arrowhead(p,&pObj->aPath[1],&pObj->aPath[0],pObj);
4034 }
4035 if( pObj->rarrow ){
4036 pik_draw_arrowhead(p,&pObj->aPath[n-2],&pObj->aPath[n-1],pObj);
4037 }
4038 for(i=0; i<pObj->nPath; i++){
4039 pik_append_xy(p,z,pObj->aPath[i].x,pObj->aPath[i].y);
4040 z = "L";
4041 }
4042 if( pObj->bClose ){
4043 pik_append(p,"Z",1);
4044 }else{
4045 pObj->fill = -1.0;
4046 }
4047 pik_append(p,"\" ",-1);
4048 pik_append_style(p,pObj,pObj->bClose);
4049 pik_append(p,"\" />\n", -1);
4050 }
4051 pik_append_txt(p, pObj, 0);
4052 }
4053
4054 /* Methods for the "move" class */
4055 static void moveInit(Pik *p, PObj *pObj){
4056 pObj->w = pik_value(p, "movewid",7,0);
4057 pObj->h = pObj->w;
4058 pObj->fill = -1.0;
4059 pObj->color = -1.0;
4060 pObj->sw = -1.0;
4061 }
4062 static void moveRender(Pik *p, PObj *pObj){
4063 /* No-op */
4064 UNUSED_PARAMETER(p);
4065 UNUSED_PARAMETER(pObj);
4066 }
4067
4068 /* Methods for the "oval" class */
4069 static void ovalInit(Pik *p, PObj *pObj){
4070 pObj->h = pik_value(p, "ovalht",6,0);
4071 pObj->w = pik_value(p, "ovalwid",7,0);
4072 pObj->rad = 0.5*(pObj->h<pObj->w?pObj->h:pObj->w);
4073 }
4074 static void ovalNumProp(Pik *p, PObj *pObj, PToken *pId){
4075 UNUSED_PARAMETER(p);
4076 UNUSED_PARAMETER(pId);
4077 /* Always adjust the radius to be half of the smaller of
4078 ** the width and height. */
4079 pObj->rad = 0.5*(pObj->h<pObj->w?pObj->h:pObj->w);
4080 }
4081 static void ovalFit(Pik *p, PObj *pObj, PNum w, PNum h){
4082 UNUSED_PARAMETER(p);
4083 if( w>0 ) pObj->w = w;
4084 if( h>0 ) pObj->h = h;
4085 if( pObj->w<pObj->h ) pObj->w = pObj->h;
4086 pObj->rad = 0.5*(pObj->h<pObj->w?pObj->h:pObj->w);
4087 }
4088
4089
4090
4091 /* Methods for the "spline" class */
4092 static void splineInit(Pik *p, PObj *pObj){
4093 pObj->w = pik_value(p, "linewid",7,0);
4094 pObj->h = pik_value(p, "lineht",6,0);
4095 pObj->rad = 1000;
4096 pObj->fill = -1.0; /* Disable fill by default */
4097 }
4098 /* Return a point along the path from "f" to "t" that is r units
4099 ** prior to reaching "t", except if the path is less than 2*r total,
4100 ** return the midpoint.
4101 */
@@ -4089,14 +4115,14 @@
4115 }
4116 m.x = t.x - r*dx;
4117 m.y = t.y - r*dy;
4118 return m;
4119 }
4120 static void radiusPath(Pik *p, PObj *pObj, PNum r){
4121 int i;
4122 int n = pObj->nPath;
4123 const PPoint *a = pObj->aPath;
4124 PPoint m;
4125 int isMid = 0;
4126
4127 pik_append_xy(p,"<path d=\"M", a[0].x, a[0].y);
4128 m = radiusMidpoint(a[0], a[1], r, &isMid);
@@ -4110,68 +4136,68 @@
4136 pik_append_xy(p," L ",m.x,m.y);
4137 }
4138 }
4139 pik_append_xy(p," L ",a[i].x,a[i].y);
4140 pik_append(p,"\" ",-1);
4141 pik_append_style(p,pObj,0);
4142 pik_append(p,"\" />\n", -1);
4143 }
4144 static void splineRender(Pik *p, PObj *pObj){
4145 if( pObj->sw>0.0 ){
4146 int n = pObj->nPath;
4147 PNum r = pObj->rad;
4148 if( n<3 || r<=0.0 ){
4149 lineRender(p,pObj);
4150 return;
4151 }
4152 if( pObj->larrow ){
4153 pik_draw_arrowhead(p,&pObj->aPath[1],&pObj->aPath[0],pObj);
4154 }
4155 if( pObj->rarrow ){
4156 pik_draw_arrowhead(p,&pObj->aPath[n-2],&pObj->aPath[n-1],pObj);
4157 }
4158 radiusPath(p,pObj,pObj->rad);
4159 }
4160 pik_append_txt(p, pObj, 0);
4161 }
4162
4163
4164 /* Methods for the "text" class */
4165 static void textInit(Pik *p, PObj *pObj){
4166 pik_value(p, "textwid",7,0);
4167 pik_value(p, "textht",6,0);
4168 pObj->sw = 0.0;
4169 }
4170 static PPoint textOffset(Pik *p, PObj *pObj, int cp){
4171 /* Automatically slim-down the width and height of text
4172 ** statements so that the bounding box tightly encloses the text,
4173 ** then get boxOffset() to do the offset computation.
4174 */
4175 pik_size_to_fit(p, &pObj->errTok,3);
4176 return boxOffset(p, pObj, cp);
4177 }
4178
4179 /* Methods for the "sublist" class */
4180 static void sublistInit(Pik *p, PObj *pObj){
4181 PList *pList = pObj->pSublist;
4182 int i;
4183 UNUSED_PARAMETER(p);
4184 pik_bbox_init(&pObj->bbox);
4185 for(i=0; i<pList->n; i++){
4186 pik_bbox_addbox(&pObj->bbox, &pList->a[i]->bbox);
4187 }
4188 pObj->w = pObj->bbox.ne.x - pObj->bbox.sw.x;
4189 pObj->h = pObj->bbox.ne.y - pObj->bbox.sw.y;
4190 pObj->ptAt.x = 0.5*(pObj->bbox.ne.x + pObj->bbox.sw.x);
4191 pObj->ptAt.y = 0.5*(pObj->bbox.ne.y + pObj->bbox.sw.y);
4192 pObj->mCalc |= A_WIDTH|A_HEIGHT|A_RADIUS;
4193 }
4194
4195
4196 /*
4197 ** The following array holds all the different kinds of objects.
4198 ** The special [] object is separate.
4199 */
4200 static const PClass aClass[] = {
4201 { /* name */ "arc",
4202 /* isline */ 1,
4203 /* eJust */ 0,
@@ -4244,11 +4270,11 @@
4270 /* xInit */ ellipseInit,
4271 /* xNumProp */ 0,
4272 /* xCheck */ 0,
4273 /* xChop */ ellipseChop,
4274 /* xOffset */ ellipseOffset,
4275 /* xFit */ boxFit,
4276 /* xRender */ ellipseRender
4277 },
4278 { /* name */ "file",
4279 /* isline */ 0,
4280 /* eJust */ 1,
@@ -4363,20 +4389,20 @@
4389 /*
4390 ** Draw an arrowhead on the end of the line segment from pFrom to pTo.
4391 ** Also, shorten the line segment (by changing the value of pTo) so that
4392 ** the shaft of the arrow does not extend into the arrowhead.
4393 */
4394 static void pik_draw_arrowhead(Pik *p, PPoint *f, PPoint *t, PObj *pObj){
4395 PNum dx = t->x - f->x;
4396 PNum dy = t->y - f->y;
4397 PNum dist = hypot(dx,dy);
4398 PNum h = p->hArrow * pObj->sw;
4399 PNum w = p->wArrow * pObj->sw;
4400 PNum e1, ddx, ddy;
4401 PNum bx, by;
4402 if( pObj->color<0.0 ) return;
4403 if( pObj->sw<=0.0 ) return;
4404 if( dist<=0.0 ) return; /* Unable */
4405 dx /= dist;
4406 dy /= dist;
4407 e1 = dist - h;
4408 if( e1<0.0 ){
@@ -4388,20 +4414,20 @@
4414 bx = f->x + e1*dx;
4415 by = f->y + e1*dy;
4416 pik_append_xy(p,"<polygon points=\"", t->x, t->y);
4417 pik_append_xy(p," ",bx-ddx, by-ddy);
4418 pik_append_xy(p," ",bx+ddx, by+ddy);
4419 pik_append_clr(p,"\" style=\"fill:",pObj->color,"\"/>\n");
4420 pik_chop(f,t,h/2);
4421 }
4422
4423 /*
4424 ** Compute the relative offset to an edge location from the reference for a
4425 ** an statement.
4426 */
4427 static PPoint pik_elem_offset(Pik *p, PObj *pObj, int cp){
4428 return pObj->type->xOffset(p, pObj, cp);
4429 }
4430
4431
4432 /*
4433 ** Append raw text to zOut
@@ -4544,49 +4570,49 @@
4570 }
4571
4572 /* Append a style="..." text. But, leave the quote unterminated, in case
4573 ** the caller wants to add some more.
4574 */
4575 static void pik_append_style(Pik *p, PObj *pObj, int bFill){
4576 pik_append(p, " style=\"", -1);
4577 if( pObj->fill>=0 && bFill ){
4578 pik_append_clr(p, "fill:", pObj->fill, ";");
4579 }else{
4580 pik_append(p,"fill:none;",-1);
4581 }
4582 if( pObj->sw>0.0 && pObj->color>=0.0 ){
4583 PNum sw = pObj->sw;
4584 pik_append_dis(p, "stroke-width:", sw, ";");
4585 if( pObj->nPath>2 && pObj->rad<=pObj->sw ){
4586 pik_append(p, "stroke-linejoin:round;", -1);
4587 }
4588 pik_append_clr(p, "stroke:",pObj->color,";");
4589 if( pObj->dotted>0.0 ){
4590 PNum v = pObj->dotted;
4591 if( sw<2.1/p->rScale ) sw = 2.1/p->rScale;
4592 pik_append_dis(p,"stroke-dasharray:",sw,"");
4593 pik_append_dis(p,",",v,";");
4594 }else if( pObj->dashed>0.0 ){
4595 PNum v = pObj->dashed;
4596 pik_append_dis(p,"stroke-dasharray:",v,"");
4597 pik_append_dis(p,",",v,";");
4598 }
4599 }
4600 }
4601
4602 /*
4603 ** Compute the vertical locations for all text items in the
4604 ** object pObj. In other words, set every pObj->aTxt[*].eCode
4605 ** value to contain exactly one of: TP_ABOVE2, TP_ABOVE, TP_CENTER,
4606 ** TP_BELOW, or TP_BELOW2 is set.
4607 */
4608 static void pik_txt_vertical_layout(PObj *pObj){
4609 int n, i;
4610 PToken *aTxt;
4611 n = pObj->nTxt;
4612 if( n==0 ) return;
4613 aTxt = pObj->aTxt;
4614 if( n==1 ){
4615 if( (aTxt[0].eCode & TP_VMASK)==0 ){
4616 aTxt[0].eCode |= TP_CENTER;
4617 }
4618 }else{
@@ -4649,22 +4675,22 @@
4675 }
4676 }
4677 }
4678 }
4679
4680 /* Append multiple <text> SVG elements for the text fields of the PObj.
4681 ** Parameters:
4682 **
4683 ** p The Pik object into which we are rendering
4684 **
4685 ** pObj Object containing the text to be rendered
4686 **
4687 ** pBox If not NULL, do no rendering at all. Instead
4688 ** expand the box object so that it will include all
4689 ** of the text.
4690 */
4691 static void pik_append_txt(Pik *p, PObj *pObj, PBox *pBox){
4692 PNum dy; /* Half the height of a single line of text */
4693 PNum dy2; /* Extra vertical space around the center */
4694 PNum jw; /* Justification margin relative to center */
4695 int n, i, nz;
4696 PNum x, y, orig_y;
@@ -4671,35 +4697,35 @@
4697 const char *z;
4698 PToken *aTxt;
4699 int hasCenter = 0;
4700
4701 if( p->nErr ) return;
4702 if( pObj->nTxt==0 ) return;
4703 aTxt = pObj->aTxt;
4704 dy = 0.5*p->charHeight;
4705 n = pObj->nTxt;
4706 pik_txt_vertical_layout(pObj);
4707 x = pObj->ptAt.x;
4708 for(i=0; i<n; i++){
4709 if( (pObj->aTxt[i].eCode & TP_CENTER)!=0 ) hasCenter = 1;
4710 }
4711 if( hasCenter ){
4712 dy2 = dy;
4713 }else if( pObj->type->isLine ){
4714 dy2 = pObj->sw;
4715 }else{
4716 dy2 = 0.0;
4717 }
4718 if( pObj->type->eJust==1 ){
4719 jw = 0.5*(pObj->w - 0.5*(p->charWidth + pObj->sw));
4720 }else{
4721 jw = 0.0;
4722 }
4723 for(i=0; i<n; i++){
4724 PToken *t = &aTxt[i];
4725 PNum xtraFontScale = 1.0;
4726 orig_y = pObj->ptAt.y;
4727 PNum nx = 0;
4728 y = 0;
4729 if( t->eCode & TP_ABOVE2 ) y += dy2 + 3*dy;
4730 if( t->eCode & TP_ABOVE ) y += dy2 + dy;
4731 if( t->eCode & TP_BELOW ) y -= dy2 + dy;
@@ -4713,11 +4739,11 @@
4739 if( pBox!=0 ){
4740 /* If pBox is not NULL, do not draw any <text>. Instead, just expand
4741 ** pBox to include the text */
4742 PNum cw = pik_text_length(t)*p->charWidth*xtraFontScale*0.01;
4743 PNum ch = p->charHeight*0.5*xtraFontScale;
4744 PNum x0, y0, x1, y1; /* Boundary of text relative to pObj->ptAt */
4745 if( t->eCode & TP_BOLD ) cw *= 1.1;
4746 if( t->eCode & TP_RJUST ){
4747 x0 = nx;
4748 y0 = y-ch;
4749 x1 = nx-cw;
@@ -4731,14 +4757,14 @@
4757 x0 = nx+cw/2;
4758 y0 = y+ch;
4759 x1 = nx-cw/2;
4760 y1 = y-ch;
4761 }
4762 if( (t->eCode & TP_ALIGN)!=0 && pObj->nPath>=2 ){
4763 int n = pObj->nPath;
4764 PNum dx = pObj->aPath[n-1].x - pObj->aPath[0].x;
4765 PNum dy = pObj->aPath[n-1].y - pObj->aPath[0].y;
4766 if( dx!=0 || dy!=0 ){
4767 PNum dist = hypot(dx,dy);
4768 PNum t;
4769 dx /= dist;
4770 dy /= dist;
@@ -4770,22 +4796,22 @@
4796 pik_append(p, " font-style=\"italic\"", -1);
4797 }
4798 if( t->eCode & TP_BOLD ){
4799 pik_append(p, " font-weight=\"bold\"", -1);
4800 }
4801 if( pObj->color>=0.0 ){
4802 pik_append_clr(p, " fill=\"", pObj->color, "\"");
4803 }
4804 xtraFontScale *= p->fontScale;
4805 if( xtraFontScale<=0.99 || xtraFontScale>=1.01 ){
4806 pik_append_num(p, " font-size=\"", xtraFontScale*100.0);
4807 pik_append(p, "%\"", 2);
4808 }
4809 if( (t->eCode & TP_ALIGN)!=0 && pObj->nPath>=2 ){
4810 int n = pObj->nPath;
4811 PNum dx = pObj->aPath[n-1].x - pObj->aPath[0].x;
4812 PNum dy = pObj->aPath[n-1].y - pObj->aPath[0].y;
4813 if( dx!=0 || dy!=0 ){
4814 PNum ang = atan2(dy,dx)*-180/M_PI;
4815 pik_append_num(p, " transform=\"rotate(", ang);
4816 pik_append_xy(p, " ", x, orig_y);
4817 pik_append(p,")\"",2);
@@ -4808,23 +4834,65 @@
4834 }
4835 pik_append(p, "</text>\n", -1);
4836 }
4837 }
4838
4839 /*
4840 ** Append text (that will go inside of a <pre>...</pre>) that
4841 ** shows the context of an error token.
4842 */
4843 static void pik_error_context(Pik *p, PToken *pErr, int nContext){
4844 int iErrPt; /* Index of first byte of error from start of input */
4845 int iErrCol; /* Column of the error token on its line */
4846 int iStart; /* Start position of the error context */
4847 int iEnd; /* End position of the error context */
4848 int iLineno; /* Line number of the error */
4849 int iFirstLineno; /* Line number of start of error context */
4850 int i; /* Loop counter */
4851 char zLineno[20]; /* Buffer in which to generate line numbers */
4852
4853 iErrPt = (int)(pErr->z - p->sIn.z);
4854 iLineno = 1;
4855 for(i=0; i<iErrPt; i++){
4856 if( p->sIn.z[i]=='\n' ){
4857 iLineno++;
4858 }
4859 }
4860 iStart = 0;
4861 iFirstLineno = 1;
4862 while( iFirstLineno+nContext<iLineno ){
4863 while( p->sIn.z[iStart]!='\n' ){ iStart++; }
4864 iStart++;
4865 iFirstLineno++;
4866 }
4867 for(iEnd=iErrPt; p->sIn.z[iEnd]!=0 && p->sIn.z[iEnd]!='\n'; iEnd++){}
4868 i = iStart;
4869 while( iFirstLineno<=iLineno ){
4870 snprintf(zLineno,sizeof(zLineno)-1,"/* %4d */ ", iFirstLineno++);
4871 zLineno[sizeof(zLineno)-1] = 0;
4872 pik_append(p, zLineno, -1);
4873 for(i=iStart; p->sIn.z[i]!=0 && p->sIn.z[i]!='\n'; i++){}
4874 pik_append_text(p, p->sIn.z+iStart, i-iStart, 0);
4875 iStart = i+1;
4876 pik_append(p, "\n", 1);
4877 }
4878 for(iErrCol=0, i=iErrPt; i>0 && p->sIn.z[i]!='\n'; iErrCol++, i--){}
4879 for(i=0; i<iErrCol+11; i++){ pik_append(p, " ", 1); }
4880 for(i=0; i<(int)pErr->n; i++) pik_append(p, "^", 1);
4881 pik_append(p, "\n", 1);
4882 }
4883
4884
4885 /*
4886 ** Generate an error message for the output. pErr is the token at which
4887 ** the error should point. zMsg is the text of the error message. If
4888 ** either pErr or zMsg is NULL, generate an out-of-memory error message.
4889 **
4890 ** This routine is a no-op if there has already been an error reported.
4891 */
4892 static void pik_error(Pik *p, PToken *pErr, const char *zMsg){
4893 int i;
 
 
 
4894 if( p==0 ) return;
4895 if( p->nErr ) return;
4896 p->nErr++;
4897 if( zMsg==0 ){
4898 pik_append(p, "\n<div><p>Out of memory</p></div>\n", -1);
@@ -4833,29 +4901,26 @@
4901 if( pErr==0 ){
4902 pik_append(p, "\n", 1);
4903 pik_append_text(p, zMsg, -1, 0);
4904 return;
4905 }
 
 
 
 
4906 pik_append(p, "<div><pre>\n", -1);
4907 pik_error_context(p, pErr, 5);
4908 pik_append(p, "ERROR: ", -1);
 
 
 
4909 pik_append_text(p, zMsg, -1, 0);
4910 pik_append(p, "\n", 1);
4911 for(i=p->nCtx-1; i>=0; i--){
4912 pik_append(p, "Called from:\n", -1);
4913 pik_error_context(p, &p->aCtx[i], 0);
4914 }
4915 pik_append(p, "</pre></div>\n", -1);
4916 }
4917
4918 /*
4919 ** Process an "assert( e1 == e2 )" statement. Always return NULL.
4920 */
4921 static PObj *pik_assert(Pik *p, PNum e1, PToken *pEq, PNum e2){
4922 char zE1[100], zE2[100], zMsg[300];
4923
4924 /* Convert the numbers to strings using %g for comparison. This
4925 ** limits the precision of the comparison to account for rounding error. */
4926 snprintf(zE1, sizeof(zE1), "%g", e1); zE1[sizeof(zE1)-1] = 0;
@@ -4868,11 +4933,11 @@
4933 }
4934
4935 /*
4936 ** Process an "assert( place1 == place2 )" statement. Always return NULL.
4937 */
4938 static PObj *pik_position_assert(Pik *p, PPoint *e1, PToken *pEq, PPoint *e2){
4939 char zE1[100], zE2[100], zMsg[210];
4940
4941 /* Convert the numbers to strings using %g for comparison. This
4942 ** limits the precision of the comparison to account for rounding error. */
4943 snprintf(zE1, sizeof(zE1), "(%g,%g)", e1->x, e1->y); zE1[sizeof(zE1)-1] = 0;
@@ -4882,29 +4947,29 @@
4947 pik_error(p, pEq, zMsg);
4948 }
4949 return 0;
4950 }
4951
4952 /* Free a complete list of objects */
4953 static void pik_elist_free(Pik *p, PList *pList){
4954 int i;
4955 if( pList==0 ) return;
4956 for(i=0; i<pList->n; i++){
4957 pik_elem_free(p, pList->a[i]);
4958 }
4959 free(pList->a);
4960 free(pList);
4961 return;
4962 }
4963
4964 /* Free a single object, and its substructure */
4965 static void pik_elem_free(Pik *p, PObj *pObj){
4966 if( pObj==0 ) return;
4967 free(pObj->zName);
4968 pik_elist_free(p, pObj->pSublist);
4969 free(pObj->aPath);
4970 free(pObj);
4971 }
4972
4973 /* Convert a numeric literal into a number. Return that number.
4974 ** There is no error handling because the tokenizer has already
4975 ** assured us that the numeric literal is valid.
@@ -5017,42 +5082,42 @@
5082 if( pA->ne.y<y+ry ) pA->ne.y = y+ry;
5083 }
5084
5085
5086
5087 /* Append a new object onto the end of an object list. The
5088 ** object list is created if it does not already exist. Return
5089 ** the new object list.
5090 */
5091 static PList *pik_elist_append(Pik *p, PList *pList, PObj *pObj){
5092 if( pObj==0 ) return pList;
5093 if( pList==0 ){
5094 pList = malloc(sizeof(*pList));
5095 if( pList==0 ){
5096 pik_error(p, 0, 0);
5097 pik_elem_free(p, pObj);
5098 return 0;
5099 }
5100 memset(pList, 0, sizeof(*pList));
5101 }
5102 if( pList->n>=pList->nAlloc ){
5103 int nNew = (pList->n+5)*2;
5104 PObj **pNew = realloc(pList->a, sizeof(PObj*)*nNew);
5105 if( pNew==0 ){
5106 pik_error(p, 0, 0);
5107 pik_elem_free(p, pObj);
5108 return pList;
5109 }
5110 pList->nAlloc = nNew;
5111 pList->a = pNew;
5112 }
5113 pList->a[pList->n++] = pObj;
5114 p->list = pList;
5115 return pList;
5116 }
5117
5118 /* Convert an object class name into a PClass pointer
5119 */
5120 static const PClass *pik_find_class(PToken *pId){
5121 int first = 0;
5122 int last = count(aClass) - 1;
5123 do{
@@ -5069,19 +5134,19 @@
5134 }
5135 }while( first<=last );
5136 return 0;
5137 }
5138
5139 /* Allocate and return a new PObj object.
5140 **
5141 ** If pId!=0 then pId is an identifier that defines the object class.
5142 ** If pStr!=0 then it is a STRING literal that defines a text object.
5143 ** If pSublist!=0 then this is a [...] object. If all three parameters
5144 ** are NULL then this is a no-op object used to define a PLACENAME.
5145 */
5146 static PObj *pik_elem_new(Pik *p, PToken *pId, PToken *pStr,PList *pSublist){
5147 PObj *pNew;
5148 int miss = 0;
5149
5150 if( p->nErr ) return 0;
5151 pNew = malloc( sizeof(*pNew) );
5152 if( pNew==0 ){
@@ -5095,11 +5160,11 @@
5160 p->thenFlag = 0;
5161 if( p->list==0 || p->list->n==0 ){
5162 pNew->ptAt.x = pNew->ptAt.y = 0.0;
5163 pNew->eWith = CP_C;
5164 }else{
5165 PObj *pPrior = p->list->a[p->list->n-1];
5166 pNew->ptAt = pPrior->ptExit;
5167 switch( p->eDir ){
5168 default: pNew->eWith = CP_W; break;
5169 case DIR_LEFT: pNew->eWith = CP_E; break;
5170 case DIR_UP: pNew->eWith = CP_S; break;
@@ -5138,32 +5203,72 @@
5203 pNew->fill = pik_value(p, "fill",4,0);
5204 pNew->color = pik_value(p, "color",5,0);
5205 pClass->xInit(p, pNew);
5206 return pNew;
5207 }
5208 pik_error(p, pId, "unknown object type");
5209 pik_elem_free(p, pNew);
5210 return 0;
5211 }
5212 pNew->type = &noopClass;
5213 pNew->ptExit = pNew->ptEnter = pNew->ptAt;
5214 return pNew;
5215 }
5216
5217 /*
5218 ** If the ID token in the argument is the name of a macro, return
5219 ** the PMacro object for that macro
5220 */
5221 static PMacro *pik_find_macro(Pik *p, PToken *pId){
5222 PMacro *pMac;
5223 for(pMac = p->pMacros; pMac; pMac=pMac->pNext){
5224 if( pMac->macroName.n==pId->n
5225 && strncmp(pMac->macroName.z,pId->z,pId->n)==0
5226 ){
5227 return pMac;
5228 }
5229 }
5230 return 0;
5231 }
5232
5233 /* Add a new macro
5234 */
5235 static void pik_add_macro(
5236 Pik *p, /* Current Pikchr diagram */
5237 PToken *pId, /* The ID token that defines the macro name */
5238 PToken *pCode /* Macro body inside of {...} */
5239 ){
5240 PMacro *pNew = pik_find_macro(p, pId);
5241 if( pNew==0 ){
5242 pNew = malloc( sizeof(*pNew) );
5243 if( pNew==0 ){
5244 pik_error(p, 0, 0);
5245 return;
5246 }
5247 pNew->pNext = p->pMacros;
5248 p->pMacros = pNew;
5249 pNew->macroName = *pId;
5250 }
5251 pNew->macroBody.z = pCode->z+1;
5252 pNew->macroBody.n = pCode->n-2;
5253 pNew->inUse = 0;
5254 }
5255
5256
5257 /*
5258 ** Set the output direction and exit point for an object
5259 */
5260 static void pik_elem_set_exit(PObj *pObj, int eDir){
5261 assert( ValidDir(eDir) );
5262 pObj->outDir = eDir;
5263 if( !pObj->type->isLine || pObj->bClose ){
5264 pObj->ptExit = pObj->ptAt;
5265 switch( pObj->outDir ){
5266 default: pObj->ptExit.x += pObj->w*0.5; break;
5267 case DIR_LEFT: pObj->ptExit.x -= pObj->w*0.5; break;
5268 case DIR_UP: pObj->ptExit.y += pObj->h*0.5; break;
5269 case DIR_DOWN: pObj->ptExit.y -= pObj->h*0.5; break;
5270 }
5271 }
5272 }
5273
5274 /* Change the layout direction.
@@ -5188,34 +5293,34 @@
5293 if( p->list && p->list->n ){
5294 pik_elem_set_exit(p->list->a[p->list->n-1], eDir);
5295 }
5296 }
5297
5298 /* Move all coordinates contained within an object (and within its
5299 ** substructure) by dx, dy
5300 */
5301 static void pik_elem_move(PObj *pObj, PNum dx, PNum dy){
5302 int i;
5303 pObj->ptAt.x += dx;
5304 pObj->ptAt.y += dy;
5305 pObj->ptEnter.x += dx;
5306 pObj->ptEnter.y += dy;
5307 pObj->ptExit.x += dx;
5308 pObj->ptExit.y += dy;
5309 pObj->bbox.ne.x += dx;
5310 pObj->bbox.ne.y += dy;
5311 pObj->bbox.sw.x += dx;
5312 pObj->bbox.sw.y += dy;
5313 for(i=0; i<pObj->nPath; i++){
5314 pObj->aPath[i].x += dx;
5315 pObj->aPath[i].y += dy;
5316 }
5317 if( pObj->pSublist ){
5318 pik_elist_move(pObj->pSublist, dx, dy);
5319 }
5320 }
5321 static void pik_elist_move(PList *pList, PNum dx, PNum dy){
5322 int i;
5323 for(i=0; i<pList->n; i++){
5324 pik_elem_move(pList->a[i], dx, dy);
5325 }
5326 }
@@ -5223,31 +5328,31 @@
5328 /*
5329 ** Check to see if it is ok to set the value of paraemeter mThis.
5330 ** Return 0 if it is ok. If it not ok, generate an appropriate
5331 ** error message and return non-zero.
5332 **
5333 ** Flags are set in pObj so that the same object or conflicting
5334 ** objects may not be set again.
5335 **
5336 ** To be ok, bit mThis must be clear and no more than one of
5337 ** the bits identified by mBlockers may be set.
5338 */
5339 static int pik_param_ok(
5340 Pik *p, /* For storing the error message (if any) */
5341 PObj *pObj, /* The object under construction */
5342 PToken *pId, /* Make the error point to this token */
5343 int mThis /* Value we are trying to set */
5344 ){
5345 if( pObj->mProp & mThis ){
5346 pik_error(p, pId, "value is already set");
5347 return 1;
5348 }
5349 if( pObj->mCalc & mThis ){
5350 pik_error(p, pId, "value already fixed by prior constraints");
5351 return 1;
5352 }
5353 pObj->mProp |= mThis;
5354 return 0;
5355 }
5356
5357
5358 /*
@@ -5255,56 +5360,56 @@
5360 **
5361 ** The rAbs term is an absolute value to add in. rRel is
5362 ** a relative value by which to change the current value.
5363 */
5364 void pik_set_numprop(Pik *p, PToken *pId, PRel *pVal){
5365 PObj *pObj = p->cur;
5366 switch( pId->eType ){
5367 case T_HEIGHT:
5368 if( pik_param_ok(p, pObj, pId, A_HEIGHT) ) return;
5369 pObj->h = pObj->h*pVal->rRel + pVal->rAbs;
5370 break;
5371 case T_WIDTH:
5372 if( pik_param_ok(p, pObj, pId, A_WIDTH) ) return;
5373 pObj->w = pObj->w*pVal->rRel + pVal->rAbs;
5374 break;
5375 case T_RADIUS:
5376 if( pik_param_ok(p, pObj, pId, A_RADIUS) ) return;
5377 pObj->rad = pObj->rad*pVal->rRel + pVal->rAbs;
5378 break;
5379 case T_DIAMETER:
5380 if( pik_param_ok(p, pObj, pId, A_RADIUS) ) return;
5381 pObj->rad = pObj->rad*pVal->rRel + 0.5*pVal->rAbs; /* diam it 2x rad */
5382 break;
5383 case T_THICKNESS:
5384 if( pik_param_ok(p, pObj, pId, A_THICKNESS) ) return;
5385 pObj->sw = pObj->sw*pVal->rRel + pVal->rAbs;
5386 break;
5387 }
5388 if( pObj->type->xNumProp ){
5389 pObj->type->xNumProp(p, pObj, pId);
5390 }
5391 return;
5392 }
5393
5394 /*
5395 ** Set a color property. The argument is an RGB value.
5396 */
5397 void pik_set_clrprop(Pik *p, PToken *pId, PNum rClr){
5398 PObj *pObj = p->cur;
5399 switch( pId->eType ){
5400 case T_FILL:
5401 if( pik_param_ok(p, pObj, pId, A_FILL) ) return;
5402 pObj->fill = rClr;
5403 break;
5404 case T_COLOR:
5405 if( pik_param_ok(p, pObj, pId, A_COLOR) ) return;
5406 pObj->color = rClr;
5407 break;
5408 }
5409 if( pObj->type->xNumProp ){
5410 pObj->type->xNumProp(p, pObj, pId);
5411 }
5412 return;
5413 }
5414
5415 /*
@@ -5312,23 +5417,23 @@
5417 **
5418 ** Use the value supplied by pVal if available. If pVal==0, use
5419 ** a default.
5420 */
5421 void pik_set_dashed(Pik *p, PToken *pId, PNum *pVal){
5422 PObj *pObj = p->cur;
5423 PNum v;
5424 switch( pId->eType ){
5425 case T_DOTTED: {
5426 v = pVal==0 ? pik_value(p,"dashwid",7,0) : *pVal;
5427 pObj->dotted = v;
5428 pObj->dashed = 0.0;
5429 break;
5430 }
5431 case T_DASHED: {
5432 v = pVal==0 ? pik_value(p,"dashwid",7,0) : *pVal;
5433 pObj->dashed = v;
5434 pObj->dotted = 0.0;
5435 break;
5436 }
5437 }
5438 }
5439
@@ -5346,18 +5451,18 @@
5451
5452 /* Add a new term to the path for a line-oriented object by transferring
5453 ** the information in the ptTo field over onto the path and into ptFrom
5454 ** resetting the ptTo.
5455 */
5456 static void pik_then(Pik *p, PToken *pToken, PObj *pObj){
5457 int n;
5458 if( !pObj->type->isLine ){
5459 pik_error(p, pToken, "use with line-oriented objects only");
5460 return;
5461 }
5462 n = p->nTPath - 1;
5463 if( n<1 && (pObj->mProp & A_FROM)==0 ){
5464 pik_error(p, pToken, "no prior path points");
5465 return;
5466 }
5467 p->thenFlag = 1;
5468 }
@@ -5375,22 +5480,22 @@
5480 p->aTPath[n] = p->aTPath[n-1];
5481 p->mTPath = 0;
5482 return n;
5483 }
5484
5485 /* Add a direction term to an object. "up 0.5", or "left 3", or "down"
5486 ** or "down 50%".
5487 */
5488 static void pik_add_direction(Pik *p, PToken *pDir, PRel *pVal){
5489 PObj *pObj = p->cur;
5490 int n;
5491 int dir;
5492 if( !pObj->type->isLine ){
5493 if( pDir ){
5494 pik_error(p, pDir, "use with line-oriented objects only");
5495 }else{
5496 PToken x = pik_next_semantic_token(&pObj->errTok);
5497 pik_error(p, &x, "syntax error");
5498 }
5499 return;
5500 }
5501 pik_reset_samepath(p);
@@ -5401,30 +5506,30 @@
5506 }
5507 dir = pDir ? pDir->eCode : p->eDir;
5508 switch( dir ){
5509 case DIR_UP:
5510 if( p->mTPath & 2 ) n = pik_next_rpath(p, pDir);
5511 p->aTPath[n].y += pVal->rAbs + pObj->h*pVal->rRel;
5512 p->mTPath |= 2;
5513 break;
5514 case DIR_DOWN:
5515 if( p->mTPath & 2 ) n = pik_next_rpath(p, pDir);
5516 p->aTPath[n].y -= pVal->rAbs + pObj->h*pVal->rRel;
5517 p->mTPath |= 2;
5518 break;
5519 case DIR_RIGHT:
5520 if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
5521 p->aTPath[n].x += pVal->rAbs + pObj->w*pVal->rRel;
5522 p->mTPath |= 1;
5523 break;
5524 case DIR_LEFT:
5525 if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
5526 p->aTPath[n].x -= pVal->rAbs + pObj->w*pVal->rRel;
5527 p->mTPath |= 1;
5528 break;
5529 }
5530 pObj->outDir = dir;
5531 }
5532
5533 /* Process a movement attribute of one of these forms:
5534 **
5535 ** pDist pHdgKW rHdg pEdgept
@@ -5437,14 +5542,14 @@
5542 PToken *pHeading, /* "heading" keyword if present */
5543 PNum rHdg, /* Angle argument to "heading" keyword */
5544 PToken *pEdgept, /* EDGEPT keyword "ne", "sw", etc... */
5545 PToken *pErr /* Token to use for error messages */
5546 ){
5547 PObj *pObj = p->cur;
5548 int n;
5549 PNum rDist = pDist->rAbs + pik_value(p,"linewid",7,0)*pDist->rRel;
5550 if( !pObj->type->isLine ){
5551 pik_error(p, pErr, "use with line-oriented objects only");
5552 return;
5553 }
5554 pik_reset_samepath(p);
5555 do{
@@ -5460,19 +5565,19 @@
5565 return;
5566 }else{
5567 rHdg = pik_hdg_angle[pEdgept->eEdge];
5568 }
5569 if( rHdg<=45.0 ){
5570 pObj->outDir = DIR_UP;
5571 }else if( rHdg<=135.0 ){
5572 pObj->outDir = DIR_RIGHT;
5573 }else if( rHdg<=225.0 ){
5574 pObj->outDir = DIR_DOWN;
5575 }else if( rHdg<=315.0 ){
5576 pObj->outDir = DIR_LEFT;
5577 }else{
5578 pObj->outDir = DIR_UP;
5579 }
5580 rHdg *= 0.017453292519943295769; /* degrees to radians */
5581 p->aTPath[n].x += rDist*sin(rHdg);
5582 p->aTPath[n].y += rDist*cos(rHdg);
5583 p->mTPath = 2;
@@ -5484,13 +5589,13 @@
5589 ** pDir is the first keyword, "right" or "left" or "up" or "down".
5590 ** The movement is in that direction until its closest approach to
5591 ** the point specified by pPoint.
5592 */
5593 static void pik_evenwith(Pik *p, PToken *pDir, PPoint *pPlace){
5594 PObj *pObj = p->cur;
5595 int n;
5596 if( !pObj->type->isLine ){
5597 pik_error(p, pDir, "use with line-oriented objects only");
5598 return;
5599 }
5600 pik_reset_samepath(p);
5601 n = p->nTPath - 1;
@@ -5510,25 +5615,25 @@
5615 if( p->mTPath & 1 ) n = pik_next_rpath(p, pDir);
5616 p->aTPath[n].x = pPlace->x;
5617 p->mTPath |= 1;
5618 break;
5619 }
5620 pObj->outDir = pDir->eCode;
5621 }
5622
5623 /* Set the "from" of an object
5624 */
5625 static void pik_set_from(Pik *p, PObj *pObj, PToken *pTk, PPoint *pPt){
5626 if( !pObj->type->isLine ){
5627 pik_error(p, pTk, "use \"at\" to position this object");
5628 return;
5629 }
5630 if( pObj->mProp & A_FROM ){
5631 pik_error(p, pTk, "line start location already fixed");
5632 return;
5633 }
5634 if( pObj->bClose ){
5635 pik_error(p, pTk, "polygon is closed");
5636 return;
5637 }
5638 if( p->nTPath>1 ){
5639 PNum dx = pPt->x - p->aTPath[0].x;
@@ -5539,22 +5644,22 @@
5644 p->aTPath[i].y += dy;
5645 }
5646 }
5647 p->aTPath[0] = *pPt;
5648 p->mTPath = 3;
5649 pObj->mProp |= A_FROM;
5650 }
5651
5652 /* Set the "to" of an object
5653 */
5654 static void pik_add_to(Pik *p, PObj *pObj, PToken *pTk, PPoint *pPt){
5655 int n = p->nTPath-1;
5656 if( !pObj->type->isLine ){
5657 pik_error(p, pTk, "use \"at\" to position this object");
5658 return;
5659 }
5660 if( pObj->bClose ){
5661 pik_error(p, pTk, "polygon is closed");
5662 return;
5663 }
5664 if( n==0 || p->mTPath==3 || p->thenFlag ){
5665 n = pik_next_rpath(p, pTk);
@@ -5562,65 +5667,70 @@
5667 p->aTPath[n] = *pPt;
5668 p->mTPath = 3;
5669 }
5670
5671 static void pik_close_path(Pik *p, PToken *pErr){
5672 PObj *pObj = p->cur;
5673 if( p->nTPath<3 ){
5674 pik_error(p, pErr,
5675 "need at least 3 vertexes in order to close the polygon");
5676 return;
5677 }
5678 if( pObj->bClose ){
5679 pik_error(p, pErr, "polygon already closed");
5680 return;
5681 }
5682 pObj->bClose = 1;
5683 }
5684
5685 /* Lower the layer of the current object so that it is behind the
5686 ** given object.
5687 */
5688 static void pik_behind(Pik *p, PObj *pOther){
5689 PObj *pObj = p->cur;
5690 if( p->nErr==0 && pObj->iLayer>=pOther->iLayer ){
5691 pObj->iLayer = pOther->iLayer - 1;
5692 }
5693 }
5694
5695
5696 /* Set the "at" of an object
5697 */
5698 static void pik_set_at(Pik *p, PToken *pEdge, PPoint *pAt, PToken *pErrTok){
5699 PObj *pObj;
5700 static unsigned char eDirToCp[] = { CP_E, CP_S, CP_W, CP_N };
5701 if( p->nErr ) return;
5702 pObj = p->cur;
5703
5704 if( pObj->type->isLine ){
5705 pik_error(p, pErrTok, "use \"from\" and \"to\" to position this object");
5706 return;
5707 }
5708 if( pObj->mProp & A_AT ){
5709 pik_error(p, pErrTok, "location fixed by prior \"at\"");
5710 return;
5711 }
5712 pObj->mProp |= A_AT;
5713 pObj->eWith = pEdge ? pEdge->eEdge : CP_C;
5714 if( pObj->eWith>=CP_END ){
5715 int dir = pObj->eWith==CP_END ? pObj->outDir : pObj->inDir;
5716 pObj->eWith = eDirToCp[dir];
5717 }
5718 pObj->with = *pAt;
5719 }
5720
5721 /*
5722 ** Try to add a text attribute to an object
5723 */
5724 static void pik_add_txt(Pik *p, PToken *pTxt, int iPos){
5725 PObj *pObj = p->cur;
5726 PToken *pT;
5727 if( pObj->nTxt >= count(pObj->aTxt) ){
5728 pik_error(p, pTxt, "too many text terms");
5729 return;
5730 }
5731 pT = &pObj->aTxt[pObj->nTxt++];
5732 *pT = *pTxt;
5733 pT->eCode = iPos;
5734 }
5735
5736 /* Merge "text-position" flags
@@ -5813,29 +5923,36 @@
5923 ** underestimates the text size.
5924 ** (4) Previously set attributes will not be altered. In other words,
5925 ** "width 1in fit" might cause the height to change, but the
5926 ** width is now set.
5927 ** (5) This only works for attributes that have an xFit method.
5928 **
5929 ** The eWhich parameter is:
5930 **
5931 ** 1: Fit horizontally only
5932 ** 2: Fit vertically only
5933 ** 3: Fit both ways
5934 */
5935 static void pik_size_to_fit(Pik *p, PToken *pFit, int eWhich){
5936 PObj *pObj;
5937 PNum w, h;
5938 PBox bbox;
5939 if( p->nErr ) return;
5940 pObj = p->cur;
5941
5942 if( pObj->nTxt==0 ){
5943 pik_error(0, pFit, "no text to fit to");
5944 return;
5945 }
5946 if( pObj->type->xFit==0 ) return;
5947 pik_bbox_init(&bbox);
5948 pik_compute_layout_settings(p);
5949 pik_append_txt(p, pObj, &bbox);
5950 w = (eWhich & 1)!=0 ? (bbox.ne.x - bbox.sw.x) + p->charWidth : 0;
5951 h = (eWhich & 2)!=0 ? (bbox.ne.y - bbox.sw.y) + 0.5*p->charHeight : 0;
5952 pObj->type->xFit(p, pObj, w, h);
5953 pObj->mProp |= A_FIT;
5954 }
5955
5956 /* Set a local variable name to "val".
5957 **
5958 ** The name might be a built-in variable or a color name. In either case,
@@ -5988,15 +6105,15 @@
6105 }
6106 if( i==0 && pik_token_eq(pNth,"first")==0 ) i = 1;
6107 return i;
6108 }
6109
6110 /* Search for the NTH object.
6111 **
6112 ** If pBasis is not NULL then it should be a [] object. Use the
6113 ** sublist of that [] object for the search. If pBasis is not a []
6114 ** object, then throw an error.
6115 **
6116 ** The pNth token describes the N-th search. The pNth->eCode value
6117 ** is one more than the number of items to skip. It is negative
6118 ** to search backwards. If pNth->eType==T_ID, then it is the name
6119 ** of a class to search for. If pNth->eType==T_LB, then
@@ -6003,12 +6120,12 @@
6120 ** search for a [] object. If pNth->eType==T_LAST, then search for
6121 ** any type.
6122 **
6123 ** Raise an error if the item is not found.
6124 */
6125 static PObj *pik_find_nth(Pik *p, PObj *pBasis, PToken *pNth){
6126 PList *pList;
6127 int i, n;
6128 const PClass *pClass;
6129 if( pBasis==0 ){
6130 pList = p->list;
6131 }else{
@@ -6030,34 +6147,34 @@
6147 }
6148 }
6149 n = pNth->eCode;
6150 if( n<0 ){
6151 for(i=pList->n-1; i>=0; i--){
6152 PObj *pObj = pList->a[i];
6153 if( pClass && pObj->type!=pClass ) continue;
6154 n++;
6155 if( n==0 ){ return pObj; }
6156 }
6157 }else{
6158 for(i=0; i<pList->n; i++){
6159 PObj *pObj = pList->a[i];
6160 if( pClass && pObj->type!=pClass ) continue;
6161 n--;
6162 if( n==0 ){ return pObj; }
6163 }
6164 }
6165 pik_error(p, pNth, "no such object");
6166 return 0;
6167 }
6168
6169 /* Search for an object by name.
6170 **
6171 ** Search in pBasis->pSublist if pBasis is not NULL. If pBasis is NULL
6172 ** then search in p->list.
6173 */
6174 static PObj *pik_find_byname(Pik *p, PObj *pBasis, PToken *pName){
6175 PList *pList;
6176 int i, j;
6177 if( pBasis==0 ){
6178 pList = p->list;
6179 }else{
6180 pList = pBasis->pSublist;
@@ -6066,49 +6183,49 @@
6183 pik_error(p, pName, "no such object");
6184 return 0;
6185 }
6186 /* First look explicitly tagged objects */
6187 for(i=pList->n-1; i>=0; i--){
6188 PObj *pObj = pList->a[i];
6189 if( pObj->zName && pik_token_eq(pName,pObj->zName)==0 ){
6190 return pObj;
6191 }
6192 }
6193 /* If not found, do a second pass looking for any object containing
6194 ** text which exactly matches pName */
6195 for(i=pList->n-1; i>=0; i--){
6196 PObj *pObj = pList->a[i];
6197 for(j=0; j<pObj->nTxt; j++){
6198 if( pObj->aTxt[j].n==pName->n+2
6199 && memcmp(pObj->aTxt[j].z+1,pName->z,pName->n)==0 ){
6200 return pObj;
6201 }
6202 }
6203 }
6204 pik_error(p, pName, "no such object");
6205 return 0;
6206 }
6207
6208 /* Change most of the settings for the current object to be the
6209 ** same as the pOther object, or the most recent object of the same
6210 ** type if pOther is NULL.
6211 */
6212 static void pik_same(Pik *p, PObj *pOther, PToken *pErrTok){
6213 PObj *pObj = p->cur;
6214 if( p->nErr ) return;
6215 if( pOther==0 ){
6216 int i;
6217 for(i=(p->list ? p->list->n : 0)-1; i>=0; i--){
6218 pOther = p->list->a[i];
6219 if( pOther->type==pObj->type ) break;
6220 }
6221 if( i<0 ){
6222 pik_error(p, pErrTok, "no prior objects of the same type");
6223 return;
6224 }
6225 }
6226 if( pOther->nPath && pObj->type->isLine ){
6227 PNum dx, dy;
6228 int i;
6229 dx = p->aTPath[0].x - pOther->aPath[0].x;
6230 dy = p->aTPath[0].y - pOther->aPath[0].y;
6231 for(i=1; i<pOther->nPath; i++){
@@ -6117,53 +6234,53 @@
6234 }
6235 p->nTPath = pOther->nPath;
6236 p->mTPath = 3;
6237 p->samePath = 1;
6238 }
6239 if( !pObj->type->isLine ){
6240 pObj->w = pOther->w;
6241 pObj->h = pOther->h;
6242 }
6243 pObj->rad = pOther->rad;
6244 pObj->sw = pOther->sw;
6245 pObj->dashed = pOther->dashed;
6246 pObj->dotted = pOther->dotted;
6247 pObj->fill = pOther->fill;
6248 pObj->color = pOther->color;
6249 pObj->cw = pOther->cw;
6250 pObj->larrow = pOther->larrow;
6251 pObj->rarrow = pOther->rarrow;
6252 pObj->bClose = pOther->bClose;
6253 pObj->bChop = pOther->bChop;
6254 pObj->inDir = pOther->inDir;
6255 pObj->outDir = pOther->outDir;
6256 pObj->iLayer = pOther->iLayer;
6257 }
6258
6259
6260 /* Return a "Place" associated with object pObj. If pEdge is NULL
6261 ** return the center of the object. Otherwise, return the corner
6262 ** described by pEdge.
6263 */
6264 static PPoint pik_place_of_elem(Pik *p, PObj *pObj, PToken *pEdge){
6265 PPoint pt = cZeroPoint;
6266 const PClass *pClass;
6267 if( pObj==0 ) return pt;
6268 if( pEdge==0 ){
6269 return pObj->ptAt;
6270 }
6271 pClass = pObj->type;
6272 if( pEdge->eType==T_EDGEPT || (pEdge->eEdge>0 && pEdge->eEdge<CP_END) ){
6273 pt = pClass->xOffset(p, pObj, pEdge->eEdge);
6274 pt.x += pObj->ptAt.x;
6275 pt.y += pObj->ptAt.y;
6276 return pt;
6277 }
6278 if( pEdge->eType==T_START ){
6279 return pObj->ptEnter;
6280 }else{
6281 return pObj->ptExit;
6282 }
6283 }
6284
6285 /* Do a linear interpolation of two positions.
6286 */
@@ -6192,11 +6309,11 @@
6309 return pik_position_at_angle(dist, pik_hdg_angle[pD->eEdge], pt);
6310 }
6311
6312 /* Return the coordinates for the n-th vertex of a line.
6313 */
6314 static PPoint pik_nth_vertex(Pik *p, PToken *pNth, PToken *pErr, PObj *pObj){
6315 static const PPoint zero;
6316 int n;
6317 if( p->nErr || pObj==0 ) return p->aTPath[0];
6318 if( !pObj->type->isLine ){
6319 pik_error(p, pErr, "object is not a line");
@@ -6210,28 +6327,28 @@
6327 return pObj->aPath[n-1];
6328 }
6329
6330 /* Return the value of a property of an object.
6331 */
6332 static PNum pik_property_of(PObj *pObj, PToken *pProp){
6333 PNum v = 0.0;
6334 switch( pProp->eType ){
6335 case T_HEIGHT: v = pObj->h; break;
6336 case T_WIDTH: v = pObj->w; break;
6337 case T_RADIUS: v = pObj->rad; break;
6338 case T_DIAMETER: v = pObj->rad*2.0; break;
6339 case T_THICKNESS: v = pObj->sw; break;
6340 case T_DASHED: v = pObj->dashed; break;
6341 case T_DOTTED: v = pObj->dotted; break;
6342 case T_FILL: v = pObj->fill; break;
6343 case T_COLOR: v = pObj->color; break;
6344 case T_X: v = pObj->ptAt.x; break;
6345 case T_Y: v = pObj->ptAt.y; break;
6346 case T_TOP: v = pObj->bbox.ne.y; break;
6347 case T_BOTTOM: v = pObj->bbox.sw.y; break;
6348 case T_LEFT: v = pObj->bbox.sw.x; break;
6349 case T_RIGHT: v = pObj->bbox.ne.x; break;
6350 }
6351 return v;
6352 }
6353
6354 /* Compute one of the built-in functions
@@ -6256,43 +6373,43 @@
6373 default: v = 0.0;
6374 }
6375 return v;
6376 }
6377
6378 /* Attach a name to an object
6379 */
6380 static void pik_elem_setname(Pik *p, PObj *pObj, PToken *pName){
6381 if( pObj==0 ) return;
6382 if( pName==0 ) return;
6383 free(pObj->zName);
6384 pObj->zName = malloc(pName->n+1);
6385 if( pObj->zName==0 ){
6386 pik_error(p,0,0);
6387 }else{
6388 memcpy(pObj->zName,pName->z,pName->n);
6389 pObj->zName[pName->n] = 0;
6390 }
6391 return;
6392 }
6393
6394 /*
6395 ** Search for object located at *pCenter that has an xChop method.
6396 ** Return a pointer to the object, or NULL if not found.
6397 */
6398 static PObj *pik_find_chopper(PList *pList, PPoint *pCenter){
6399 int i;
6400 if( pList==0 ) return 0;
6401 for(i=pList->n-1; i>=0; i--){
6402 PObj *pObj = pList->a[i];
6403 if( pObj->type->xChop!=0
6404 && pObj->ptAt.x==pCenter->x
6405 && pObj->ptAt.y==pCenter->y
6406 ){
6407 return pObj;
6408 }else if( pObj->pSublist ){
6409 pObj = pik_find_chopper(pObj->pSublist,pCenter);
6410 if( pObj ) return pObj;
6411 }
6412 }
6413 return 0;
6414 }
6415
@@ -6302,180 +6419,199 @@
6419 ** If point pTo is the exact enter of a choppable object,
6420 ** then adjust pTo by the appropriate amount in the direction
6421 ** of pFrom.
6422 */
6423 static void pik_autochop(Pik *p, PPoint *pFrom, PPoint *pTo){
6424 PObj *pObj = pik_find_chopper(p->list, pTo);
6425 if( pObj ){
6426 *pTo = pObj->type->xChop(p, pObj, pFrom);
6427 }
6428 }
6429
6430 /* This routine runs after all attributes have been received
6431 ** on an object.
6432 */
6433 static void pik_after_adding_attributes(Pik *p, PObj *pObj){
6434 int i;
6435 PPoint ofst;
6436 PNum dx, dy;
6437
6438 if( p->nErr ) return;
6439
6440 /* Position block objects */
6441 if( pObj->type->isLine==0 ){
6442 /* A height or width less than or equal to zero means "autofit".
6443 ** Change the height or width to be big enough to contain the text,
6444 */
6445 if( pObj->h<=0.0 ){
6446 if( pObj->nTxt==0 ){
6447 pObj->h = 0.0;
6448 }else if( pObj->w<=0.0 ){
6449 pik_size_to_fit(p, &pObj->errTok, 3);
6450 }else{
6451 pik_size_to_fit(p, &pObj->errTok, 2);
6452 }
6453 }
6454 if( pObj->w<=0.0 ){
6455 if( pObj->nTxt==0 ){
6456 pObj->w = 0.0;
6457 }else{
6458 pik_size_to_fit(p, &pObj->errTok, 1);
6459 }
6460 }
6461 ofst = pik_elem_offset(p, pObj, pObj->eWith);
6462 dx = (pObj->with.x - ofst.x) - pObj->ptAt.x;
6463 dy = (pObj->with.y - ofst.y) - pObj->ptAt.y;
6464 if( dx!=0 || dy!=0 ){
6465 pik_elem_move(pObj, dx, dy);
6466 }
6467 }
6468
6469 /* For a line object with no movement specified, a single movement
6470 ** of the default length in the current direction
6471 */
6472 if( pObj->type->isLine && p->nTPath<2 ){
6473 pik_next_rpath(p, 0);
6474 assert( p->nTPath==2 );
6475 switch( pObj->inDir ){
6476 default: p->aTPath[1].x += pObj->w; break;
6477 case DIR_DOWN: p->aTPath[1].y -= pObj->h; break;
6478 case DIR_LEFT: p->aTPath[1].x -= pObj->w; break;
6479 case DIR_UP: p->aTPath[1].y += pObj->h; break;
6480 }
6481 if( pObj->type->xInit==arcInit ){
6482 p->eDir = pObj->outDir = (pObj->inDir + (pObj->cw ? 1 : 3))%4;
6483 switch( pObj->outDir ){
6484 default: p->aTPath[1].x += pObj->w; break;
6485 case DIR_DOWN: p->aTPath[1].y -= pObj->h; break;
6486 case DIR_LEFT: p->aTPath[1].x -= pObj->w; break;
6487 case DIR_UP: p->aTPath[1].y += pObj->h; break;
6488 }
6489 }
6490 }
6491
6492 /* Initialize the bounding box prior to running xCheck */
6493 pik_bbox_init(&pObj->bbox);
6494
6495 /* Run object-specific code */
6496 if( pObj->type->xCheck!=0 ){
6497 pObj->type->xCheck(p,pObj);
6498 if( p->nErr ) return;
6499 }
6500
6501 /* Compute final bounding box, entry and exit points, center
6502 ** point (ptAt) and path for the object
6503 */
6504 if( pObj->type->isLine ){
6505 pObj->aPath = malloc( sizeof(PPoint)*p->nTPath );
6506 if( pObj->aPath==0 ){
6507 pik_error(p, 0, 0);
6508 return;
6509 }else{
6510 pObj->nPath = p->nTPath;
6511 for(i=0; i<p->nTPath; i++){
6512 pObj->aPath[i] = p->aTPath[i];
6513 }
6514 }
6515
6516 /* "chop" processing:
6517 ** If the line goes to the center of an object with an
6518 ** xChop method, then use the xChop method to trim the line.
6519 */
6520 if( pObj->bChop && pObj->nPath>=2 ){
6521 int n = pObj->nPath;
6522 pik_autochop(p, &pObj->aPath[n-2], &pObj->aPath[n-1]);
6523 pik_autochop(p, &pObj->aPath[1], &pObj->aPath[0]);
6524 }
6525
6526 pObj->ptEnter = pObj->aPath[0];
6527 pObj->ptExit = pObj->aPath[pObj->nPath-1];
6528
6529 /* Compute the center of the line based on the bounding box over
6530 ** the vertexes. This is a difference from PIC. In Pikchr, the
6531 ** center of a line is the center of its bounding box. In PIC, the
6532 ** center of a line is halfway between its .start and .end. For
6533 ** straight lines, this is the same point, but for multi-segment
6534 ** lines the result is usually diferent */
6535 for(i=0; i<pObj->nPath; i++){
6536 pik_bbox_add_xy(&pObj->bbox, pObj->aPath[i].x, pObj->aPath[i].y);
6537 }
6538 pObj->ptAt.x = (pObj->bbox.ne.x + pObj->bbox.sw.x)/2.0;
6539 pObj->ptAt.y = (pObj->bbox.ne.y + pObj->bbox.sw.y)/2.0;
6540
6541 /* Reset the width and height of the object to be the width and height
6542 ** of the bounding box over vertexes */
6543 pObj->w = pObj->bbox.ne.x - pObj->bbox.sw.x;
6544 pObj->h = pObj->bbox.ne.y - pObj->bbox.sw.y;
6545
6546 /* If this is a polygon (if it has the "close" attribute), then
6547 ** adjust the exit point */
6548 if( pObj->bClose ){
6549 /* For "closed" lines, the .end is one of the .e, .s, .w, or .n
6550 ** points of the bounding box, as with block objects. */
6551 pik_elem_set_exit(pObj, pObj->inDir);
6552 }
6553 }else{
6554 PNum w2 = pObj->w/2.0;
6555 PNum h2 = pObj->h/2.0;
6556 pObj->ptEnter = pObj->ptAt;
6557 pObj->ptExit = pObj->ptAt;
6558 switch( pObj->inDir ){
6559 default: pObj->ptEnter.x -= w2; break;
6560 case DIR_LEFT: pObj->ptEnter.x += w2; break;
6561 case DIR_UP: pObj->ptEnter.y -= h2; break;
6562 case DIR_DOWN: pObj->ptEnter.y += h2; break;
6563 }
6564 switch( pObj->outDir ){
6565 default: pObj->ptExit.x += w2; break;
6566 case DIR_LEFT: pObj->ptExit.x -= w2; break;
6567 case DIR_UP: pObj->ptExit.y += h2; break;
6568 case DIR_DOWN: pObj->ptExit.y -= h2; break;
6569 }
6570 pik_bbox_add_xy(&pObj->bbox, pObj->ptAt.x - w2, pObj->ptAt.y - h2);
6571 pik_bbox_add_xy(&pObj->bbox, pObj->ptAt.x + w2, pObj->ptAt.y + h2);
6572 }
6573 p->eDir = pObj->outDir;
6574 }
6575
6576 /* Show basic information about each object as a comment in the
6577 ** generated HTML. Used for testing and debugging. Activated
6578 ** by the (undocumented) "debug = 1;"
6579 ** command.
6580 */
6581 static void pik_elem_render(Pik *p, PObj *pObj){
6582 char *zDir;
6583 if( pObj==0 ) return;
6584 pik_append(p,"<!-- ", -1);
6585 if( pObj->zName ){
6586 pik_append_text(p, pObj->zName, -1, 0);
6587 pik_append(p, ": ", 2);
6588 }
6589 pik_append_text(p, pObj->type->zName, -1, 0);
6590 if( pObj->nTxt ){
6591 pik_append(p, " \"", 2);
6592 pik_append_text(p, pObj->aTxt[0].z+1, pObj->aTxt[0].n-2, 1);
6593 pik_append(p, "\"", 1);
6594 }
6595 pik_append_num(p, " w=", pObj->w);
6596 pik_append_num(p, " h=", pObj->h);
6597 pik_append_point(p, " center=", &pObj->ptAt);
6598 pik_append_point(p, " enter=", &pObj->ptEnter);
6599 switch( pObj->outDir ){
6600 default: zDir = " right"; break;
6601 case DIR_LEFT: zDir = " left"; break;
6602 case DIR_UP: zDir = " up"; break;
6603 case DIR_DOWN: zDir = " down"; break;
6604 }
6605 pik_append_point(p, " exit=", &pObj->ptExit);
6606 pik_append(p, zDir, -1);
6607 pik_append(p, " -->\n", -1);
6608 }
6609
6610 /* Render a list of objects
6611 */
6612 void pik_elist_render(Pik *p, PList *pList){
6613 int i;
6614 int iNextLayer = 0;
6615 int iThisLayer;
6616 int bMoreToDo;
6617 int miss = 0;
@@ -6483,75 +6619,75 @@
6619 PNum colorLabel;
6620 do{
6621 bMoreToDo = 0;
6622 iThisLayer = iNextLayer;
6623 iNextLayer = 0x7fffffff;
6624 for(i=0; i<pList->n; i++){
6625 PObj *pObj = pList->a[i];
6626 if( pObj->iLayer>iThisLayer ){
6627 if( pObj->iLayer<iNextLayer ) iNextLayer = pObj->iLayer;
6628 bMoreToDo = 1;
6629 continue; /* Defer until another round */
6630 }else if( pObj->iLayer<iThisLayer ){
6631 continue;
6632 }
6633 void (*xRender)(Pik*,PObj*);
6634 if( mDebug & 1 ) pik_elem_render(p, pObj);
6635 xRender = pObj->type->xRender;
6636 if( xRender ){
6637 xRender(p, pObj);
6638 }
6639 if( pObj->pSublist ){
6640 pik_elist_render(p, pObj->pSublist);
6641 }
6642 }
6643 }while( bMoreToDo );
6644
6645 /* If the color_debug_label value is defined, then go through
6646 ** and paint a dot at every label location */
6647 colorLabel = pik_value(p, "debug_label_color", 17, &miss);
6648 if( miss==0 && colorLabel>=0.0 ){
6649 PObj dot;
6650 memset(&dot, 0, sizeof(dot));
6651 dot.type = &noopClass;
6652 dot.rad = 0.015;
6653 dot.sw = 0.015;
6654 dot.fill = colorLabel;
6655 dot.color = colorLabel;
6656 dot.nTxt = 1;
6657 dot.aTxt[0].eCode = TP_ABOVE;
6658 for(i=0; i<pList->n; i++){
6659 PObj *pObj = pList->a[i];
6660 if( pObj->zName==0 ) continue;
6661 dot.ptAt = pObj->ptAt;
6662 dot.aTxt[0].z = pObj->zName;
6663 dot.aTxt[0].n = (int)strlen(pObj->zName);
6664 dotRender(p, &dot);
6665 }
6666 }
6667 }
6668
6669 /* Add all objects of the list pList to the bounding box
6670 */
6671 static void pik_bbox_add_elist(Pik *p, PList *pList, PNum wArrow){
6672 int i;
6673 for(i=0; i<pList->n; i++){
6674 PObj *pObj = pList->a[i];
6675 if( pObj->sw>0.0 ) pik_bbox_addbox(&p->bbox, &pObj->bbox);
6676 pik_append_txt(p, pObj, &p->bbox);
6677 if( pObj->pSublist ) pik_bbox_add_elist(p, pObj->pSublist, wArrow);
6678
6679
6680 /* Expand the bounding box to account for arrowheads on lines */
6681 if( pObj->type->isLine && pObj->nPath>0 ){
6682 if( pObj->larrow ){
6683 pik_bbox_addellipse(&p->bbox, pObj->aPath[0].x, pObj->aPath[0].y,
6684 wArrow, wArrow);
6685 }
6686 if( pObj->rarrow ){
6687 int j = pObj->nPath-1;
6688 pik_bbox_addellipse(&p->bbox, pObj->aPath[j].x, pObj->aPath[j].y,
6689 wArrow, wArrow);
6690 }
6691 }
6692 }
6693 }
@@ -6574,15 +6710,15 @@
6710 p->charWidth = pik_value(p,"charwid",7,0)*p->fontScale;
6711 p->charHeight = pik_value(p,"charht",6,0)*p->fontScale;
6712 p->bLayoutVars = 1;
6713 }
6714
6715 /* Render a list of objects. Write the SVG into p->zOut.
6716 ** Delete the input object_list before returnning.
6717 */
6718 static void pik_render(Pik *p, PList *pList){
6719 if( pList==0 ) return;
6720 if( p->nErr==0 ){
6721 PNum thickness; /* Stroke width */
6722 PNum margin; /* Extra bounding box margin */
6723 PNum w, h; /* Drawing width and height */
6724 PNum wArrow;
@@ -6597,11 +6733,11 @@
6733 wArrow = p->wArrow*thickness;
6734
6735 /* Compute a bounding box over all objects so that we can know
6736 ** how big to declare the SVG canvas */
6737 pik_bbox_init(&p->bbox);
6738 pik_bbox_add_elist(p, pList, wArrow);
6739
6740 /* Expand the bounding box slightly to account for line thickness
6741 ** and the optional "margin = EXPR" setting. */
6742 p->bbox.ne.x += margin + pik_value(p,"rightmargin",11,0);
6743 p->bbox.ne.y += margin + pik_value(p,"topmargin",9,0);
@@ -6627,17 +6763,17 @@
6763 pik_append_num(p, "\" height=\"", p->hSVG);
6764 pik_append(p, "\"", 1);
6765 }
6766 pik_append_dis(p, " viewBox=\"0 0 ",w,"");
6767 pik_append_dis(p, " ",h,"\">\n");
6768 pik_elist_render(p, pList);
6769 pik_append(p,"</svg>\n", -1);
6770 }else{
6771 p->wSVG = -1;
6772 p->hSVG = -1;
6773 }
6774 pik_elist_free(p, pList);
6775 }
6776
6777
6778
6779 /*
@@ -6676,10 +6812,11 @@
6812 { "close", 5, T_CLOSE, 0, 0 },
6813 { "color", 5, T_COLOR, 0, 0 },
6814 { "cos", 3, T_FUNC1, FN_COS, 0 },
6815 { "cw", 2, T_CW, 0, 0 },
6816 { "dashed", 6, T_DASHED, 0, 0 },
6817 { "define", 6, T_DEFINE, 0, 0 },
6818 { "diameter", 8, T_DIAMETER, 0, 0 },
6819 { "dist", 4, T_DIST, 0, 0 },
6820 { "dotted", 6, T_DOTTED, 0, 0 },
6821 { "down", 4, T_DOWN, DIR_DOWN, 0 },
6822 { "e", 1, T_EDGEPT, 0, CP_E },
@@ -6745,11 +6882,11 @@
6882 { "y", 1, T_Y, 0, 0 },
6883 };
6884
6885 /*
6886 ** Search a PikWordlist for the given keyword. Return a pointer to the
6887 ** keyword entry found. Or return 0 if not found.
6888 */
6889 static const PikWord *pik_find_word(
6890 const char *zIn, /* Word to search for */
6891 int n, /* Length of zIn */
6892 const PikWord *aList, /* List to search */
@@ -6787,11 +6924,11 @@
6924 /*
6925 ** Return the length of next token. The token starts on
6926 ** the pToken->z character. Fill in other fields of the
6927 ** pToken object as appropriate.
6928 */
6929 static int pik_token_length(PToken *pToken, int bAllowCodeBlock){
6930 const unsigned char *z = (const unsigned char*)pToken->z;
6931 int i;
6932 unsigned char c, c2;
6933 switch( z[0] ){
6934 case '\\': {
@@ -6921,10 +7058,35 @@
7058 }else{
7059 pToken->eType = T_LT;
7060 return 1;
7061 }
7062 }
7063 case '{': {
7064 int len, depth;
7065 i = 1;
7066 if( bAllowCodeBlock ){
7067 depth = 1;
7068 while( z[i] && depth>0 ){
7069 PToken x;
7070 x.z = (char*)(z+i);
7071 len = pik_token_length(&x, 0);
7072 if( len==1 ){
7073 if( z[i]=='{' ) depth++;
7074 if( z[i]=='}' ) depth--;
7075 }
7076 i += len;
7077 }
7078 }else{
7079 depth = 0;
7080 }
7081 if( depth ){
7082 pToken->eType = T_ERROR;
7083 return 1;
7084 }
7085 pToken->eType = T_CODEBLOCK;
7086 return i;
7087 }
7088 default: {
7089 c = z[0];
7090 if( c=='.' ){
7091 unsigned char c1 = z[1];
7092 if( islower(c1) ){
@@ -6981,19 +7143,20 @@
7143 if( nDigit==0 ){
7144 pToken->eType = T_ERROR;
7145 return i;
7146 }
7147 if( c=='e' || c=='E' ){
7148 int iBefore = i;
7149 i++;
7150 c2 = z[i];
7151 if( c2=='+' || c2=='-' ){
7152 i++;
7153 c2 = z[i];
7154 }
7155 if( c2<'0' || c>'9' ){
7156 /* This is not an exp */
7157 i = iBefore;
7158 }else{
7159 i++;
7160 isInt = 0;
7161 while( (c = z[i])>='0' && c<='9' ){ i++; }
7162 }
@@ -7018,11 +7181,11 @@
7181 ){
7182 i += 2;
7183 }
7184 pToken->eType = T_NUMBER;
7185 return i;
7186 }else if( islower(c) ){
7187 const PikWord *pFound;
7188 for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7189 pFound = pik_find_word((const char*)z, i,
7190 pik_keywords, count(pik_keywords));
7191 if( pFound ){
@@ -7040,10 +7203,18 @@
7203 return i;
7204 }else if( c>='A' && c<='Z' ){
7205 for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7206 pToken->eType = T_PLACENAME;
7207 return i;
7208 }else if( c=='$' && z[1]>='1' && z[1]<='9' && !isdigit(z[2]) ){
7209 pToken->eType = T_PARAMETER;
7210 pToken->eCode = z[1] - '1';
7211 return 2;
7212 }else if( c=='_' || c=='$' || c=='@' ){
7213 for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7214 pToken->eType = T_ID;
7215 return i;
7216 }else{
7217 pToken->eType = T_ERROR;
7218 return 1;
7219 }
7220 }
@@ -7060,18 +7231,147 @@
7231 int i = pThis->n;
7232 memset(&x, 0, sizeof(x));
7233 x.z = pThis->z;
7234 while(1){
7235 x.z = pThis->z + i;
7236 sz = pik_token_length(&x, 1);
7237 if( x.eType!=T_WHITESPACE ){
7238 x.n = sz;
7239 return x;
7240 }
7241 i += sz;
7242 }
7243 }
7244
7245 /* Parser arguments to a macro invocation
7246 **
7247 ** (arg1, arg2, ...)
7248 **
7249 ** Arguments are comma-separated, except that commas within string
7250 ** literals or with (...), {...}, or [...] do not count. The argument
7251 ** list begins and ends with parentheses. There can be at most 9
7252 ** arguments.
7253 **
7254 ** Return the number of bytes in the argument list.
7255 */
7256 static unsigned int pik_parse_macro_args(
7257 Pik *p,
7258 const char *z, /* Start of the argument list */
7259 int n, /* Available bytes */
7260 PToken *args
7261 ){
7262 int nArg = 0;
7263 int i, sz;
7264 int iStart;
7265 int depth = 0;
7266 PToken x;
7267 if( z[0]!='(' ) return 0;
7268 args[0].z = z+1;
7269 iStart = 1;
7270 for(i=1; i<n && z[i]!=')'; i+=sz){
7271 x.z = z+i;
7272 sz = pik_token_length(&x, 0);
7273 if( sz!=1 ) continue;
7274 if( z[i]==',' && depth<=0 ){
7275 args[nArg].n = i - iStart;
7276 if( nArg==8 ){
7277 x.z = z;
7278 x.n = 1;
7279 pik_error(p, &x, "too many macro arguments - max 9");
7280 return 0;
7281 }
7282 nArg++;
7283 args[nArg].z = z+i+1;
7284 iStart = i+1;
7285 depth = 0;
7286 }else if( z[i]=='(' || z[i]=='{' || z[i]=='[' ){
7287 depth++;
7288 }else if( z[i]==')' || z[i]=='}' || z[i]==']' ){
7289 depth--;
7290 }
7291 }
7292 if( z[i]==')' ){
7293 args[nArg].n = i - iStart;
7294 return i+1;
7295 }
7296 x.z = z;
7297 x.n = 1;
7298 pik_error(p, &x, "unterminated macro argument list");
7299 return 0;
7300 }
7301
7302 /*
7303 ** Split up the content of a PToken into multiple tokens and
7304 ** send each to the parser.
7305 */
7306 void pik_tokenize(Pik *p, PToken *pIn, yyParser *pParser, PToken *aParam){
7307 unsigned int i;
7308 int sz = 0;
7309 PToken token;
7310 PMacro *pMac;
7311 for(i=0; i<pIn->n && pIn->z[i] && p->nErr==0; i+=sz){
7312 token.eCode = 0;
7313 token.eEdge = 0;
7314 token.z = pIn->z + i;
7315 sz = pik_token_length(&token, 1);
7316 if( token.eType==T_WHITESPACE ){
7317 /* no-op */
7318 }else if( sz>1000 ){
7319 token.n = 1;
7320 pik_error(p, &token, "token is too long - max length 1000 bytes");
7321 break;
7322 }else if( token.eType==T_ERROR ){
7323 token.n = (unsigned short)(sz & 0xffff);
7324 pik_error(p, &token, "unrecognized token");
7325 break;
7326 }else if( sz+i>pIn->n ){
7327 token.n = pIn->n - i;
7328 pik_error(p, &token, "syntax error");
7329 break;
7330 }else if( token.eType==T_PARAMETER ){
7331 /* Substitute a parameter into the input stream */
7332 if( aParam==0 || aParam[token.eCode].n==0 ){
7333 continue;
7334 }
7335 token.n = (unsigned short)(sz & 0xffff);
7336 if( p->nCtx>=count(p->aCtx) ){
7337 pik_error(p, &token, "macros nested too deep");
7338 }else{
7339 p->aCtx[p->nCtx++] = token;
7340 pik_tokenize(p, &aParam[token.eCode], pParser, 0);
7341 p->nCtx--;
7342 }
7343 }else if( token.eType==T_ID && (pMac = pik_find_macro(p,&token))!=0 ){
7344 PToken args[9];
7345 unsigned int j = i+sz;
7346 if( pMac->inUse ){
7347 pik_error(p, &pMac->macroName, "recursive macro definition");
7348 break;
7349 }
7350 token.n = (short int)(sz & 0xffff);
7351 if( p->nCtx>=count(p->aCtx) ){
7352 pik_error(p, &token, "macros nested too deep");
7353 break;
7354 }
7355 pMac->inUse = 1;
7356 memset(args, 0, sizeof(args));
7357 p->aCtx[p->nCtx++] = token;
7358 sz += pik_parse_macro_args(p, pIn->z+j, pIn->n-j, args);
7359 pik_tokenize(p, &pMac->macroBody, pParser, args);
7360 p->nCtx--;
7361 pMac->inUse = 0;
7362 }else{
7363 #if 0
7364 printf("******** Token %s (%d): \"%.*s\" **************\n",
7365 yyTokenName[token.eType], token.eType,
7366 (int)(isspace(token.z[0]) ? 0 : sz), token.z);
7367 #endif
7368 token.n = (unsigned short)(sz & 0xffff);
7369 pik_parser(pParser, token.eType, token);
7370 }
7371 }
7372 }
7373
7374 /*
7375 ** Parse the PIKCHR script contained in zText[]. Return a rendering. Or
7376 ** if an error is encountered, return the error text. The error message
7377 ** is HTML formatted. So regardless of what happens, the return text
@@ -7092,52 +7392,26 @@
7392 const char *zClass, /* Add class="%s" to <svg> markup */
7393 unsigned int mFlags, /* Flags used to influence rendering behavior */
7394 int *pnWidth, /* Write width of <svg> here, if not NULL */
7395 int *pnHeight /* Write height here, if not NULL */
7396 ){
 
 
 
7397 Pik s;
7398 yyParser sParse;
7399
7400 memset(&s, 0, sizeof(s));
7401 s.sIn.z = zText;
7402 s.sIn.n = (unsigned int)strlen(zText);
7403 s.eDir = DIR_RIGHT;
7404 s.zClass = zClass;
7405 s.mFlags = mFlags;
7406 pik_parserInit(&sParse, &s);
7407 #if 0
7408 pik_parserTrace(stdout, "parser: ");
7409 #endif
7410 pik_tokenize(&s, &s.sIn, &sParse, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7411 if( s.nErr==0 ){
7412 PToken token;
7413 memset(&token,0,sizeof(token));
7414 token.z = zText;
7415 pik_parser(&sParse, 0, token);
7416 }
7417 pik_parserFinalize(&sParse);
@@ -7147,10 +7421,15 @@
7421 while( s.pVar ){
7422 PVar *pNext = s.pVar->pNext;
7423 free(s.pVar);
7424 s.pVar = pNext;
7425 }
7426 while( s.pMacros ){
7427 PMacro *pNext = s.pMacros->pNext;
7428 free(s.pMacros);
7429 s.pMacros = pNext;
7430 }
7431 if( pnWidth ) *pnWidth = s.nErr ? -1 : s.wSVG;
7432 if( pnHeight ) *pnHeight = s.nErr ? -1 : s.hSVG;
7433 if( s.zOut ){
7434 s.zOut[s.nOut] = 0;
7435 s.zOut = realloc(s.zOut, s.nOut+1);
@@ -7317,6 +7596,6 @@
7596 }
7597 return 0;
7598 }
7599 #endif /* PIKCHR_SHELL */
7600
7601 #line 7626 "pikchr.c"
7602

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button