Fossil SCM

Sync up with trunk for latest improvements.

andybradford 2024-02-09 13:51 clone-resume merge
Commit 12390507b14a933a688c8c162e8fe385fef982e0ff1144f43afc9ccbc7b173f6
+386 -289
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -1,7 +1,8 @@
11
/* This file is automatically generated by Lemon from input grammar
2
-** source file "pikchr.y". */
2
+** source file "pikchr.y".
3
+*/
34
/*
45
** Zero-Clause BSD license:
56
**
67
** Copyright (C) 2020-09-01 by D. Richard Hipp <[email protected]>
78
**
@@ -319,10 +320,11 @@
319320
char cw; /* True for clockwise arc */
320321
char larrow; /* Arrow at beginning (<- or <->) */
321322
char rarrow; /* Arrow at end (-> or <->) */
322323
char bClose; /* True if "close" is seen */
323324
char bChop; /* True if "chop" is seen */
325
+ char bAltAutoFit; /* Always send both h and w into xFit() */
324326
unsigned char nTxt; /* Number of text values */
325327
unsigned mProp; /* Masks of properties set so far */
326328
unsigned mCalc; /* Values computed from other constraints */
327329
PToken aTxt[5]; /* Text with .eCode holding TP flags */
328330
int iLayer; /* Rendering order */
@@ -490,11 +492,11 @@
490492
static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
491493
static PNum pik_dist(PPoint*,PPoint*);
492494
static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
493495
494496
495
-#line 521 "pikchr.c"
497
+#line 523 "pikchr.c"
496498
/**************** End of %include directives **********************************/
497499
/* These constants specify the various numeric values for terminal symbols.
498500
***************** Begin token definitions *************************************/
499501
#ifndef T_ID
500502
#define T_ID 1
@@ -634,10 +636,13 @@
634636
** pik_parserARG_PDECL A parameter declaration for the %extra_argument
635637
** pik_parserARG_PARAM Code to pass %extra_argument as a subroutine parameter
636638
** pik_parserARG_STORE Code to store %extra_argument into yypParser
637639
** pik_parserARG_FETCH Code to extract %extra_argument from yypParser
638640
** pik_parserCTX_* As pik_parserARG_ except for %extra_context
641
+** YYREALLOC Name of the realloc() function to use
642
+** YYFREE Name of the free() function to use
643
+** YYDYNSTACK True if stack space should be extended on heap
639644
** YYERRORSYMBOL is the code number of the error symbol. If not
640645
** defined, then do no error processing.
641646
** YYNSTATE the combined number of states.
642647
** YYNRULE the number of rules in the grammar
643648
** YYNTOKEN Number of terminal symbols
@@ -647,10 +652,12 @@
647652
** YY_ERROR_ACTION The yy_action[] code for syntax error
648653
** YY_ACCEPT_ACTION The yy_action[] code for accept
649654
** YY_NO_ACTION The yy_action[] code for no-op
650655
** YY_MIN_REDUCE Minimum value for reduce actions
651656
** YY_MAX_REDUCE Maximum value for reduce actions
657
+** YY_MIN_DSTRCTR Minimum symbol value that has a destructor
658
+** YY_MAX_DSTRCTR Maximum symbol value that has a destructor
652659
*/
653660
#ifndef INTERFACE
654661
# define INTERFACE 1
655662
#endif
656663
/************* Begin control #defines *****************************************/
@@ -674,10 +681,13 @@
674681
#define pik_parserARG_SDECL
675682
#define pik_parserARG_PDECL
676683
#define pik_parserARG_PARAM
677684
#define pik_parserARG_FETCH
678685
#define pik_parserARG_STORE
686
+#define YYREALLOC realloc
687
+#define YYFREE free
688
+#define YYDYNSTACK 0
679689
#define pik_parserCTX_SDECL Pik *p;
680690
#define pik_parserCTX_PDECL ,Pik *p
681691
#define pik_parserCTX_PARAM ,p
682692
#define pik_parserCTX_FETCH Pik *p=yypParser->p;
683693
#define pik_parserCTX_STORE yypParser->p=p;
@@ -692,10 +702,12 @@
692702
#define YY_ERROR_ACTION 443
693703
#define YY_ACCEPT_ACTION 444
694704
#define YY_NO_ACTION 445
695705
#define YY_MIN_REDUCE 446
696706
#define YY_MAX_REDUCE 601
707
+#define YY_MIN_DSTRCTR 100
708
+#define YY_MAX_DSTRCTR 103
697709
/************* End control #defines *******************************************/
698710
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
699711
700712
/* Define the yytestcase() macro to be a no-op if is not already defined
701713
** otherwise.
@@ -706,10 +718,26 @@
706718
** for testing.
707719
*/
708720
#ifndef yytestcase
709721
# define yytestcase(X)
710722
#endif
723
+
724
+/* Macro to determine if stack space has the ability to grow using
725
+** heap memory.
726
+*/
727
+#if YYSTACKDEPTH<=0 || YYDYNSTACK
728
+# define YYGROWABLESTACK 1
729
+#else
730
+# define YYGROWABLESTACK 0
731
+#endif
732
+
733
+/* Guarantee a minimum number of initial stack slots.
734
+*/
735
+#if YYSTACKDEPTH<=0
736
+# undef YYSTACKDEPTH
737
+# define YYSTACKDEPTH 2 /* Need a minimum stack size */
738
+#endif
711739
712740
713741
/* Next are the tables used to determine what action to take based on the
714742
** current state and lookahead token. These tables are used to implement
715743
** functions that take a state number and lookahead value and return an
@@ -1250,18 +1278,13 @@
12501278
#ifndef YYNOERRORRECOVERY
12511279
int yyerrcnt; /* Shifts left before out of the error */
12521280
#endif
12531281
pik_parserARG_SDECL /* A place to hold %extra_argument */
12541282
pik_parserCTX_SDECL /* A place to hold %extra_context */
1255
-#if YYSTACKDEPTH<=0
1256
- int yystksz; /* Current side of the stack */
1257
- yyStackEntry *yystack; /* The parser's stack */
1258
- yyStackEntry yystk0; /* First stack entry */
1259
-#else
1260
- yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
1261
- yyStackEntry *yystackEnd; /* Last entry in the stack */
1262
-#endif
1283
+ yyStackEntry *yystackEnd; /* Last entry in the stack */
1284
+ yyStackEntry *yystack; /* The parser stack */
1285
+ yyStackEntry yystk0[YYSTACKDEPTH]; /* Initial stack space */
12631286
};
12641287
typedef struct yyParser yyParser;
12651288
12661289
#include <assert.h>
12671290
#ifndef NDEBUG
@@ -1601,41 +1624,49 @@
16011624
/* 155 */ "object ::= objectname",
16021625
};
16031626
#endif /* NDEBUG */
16041627
16051628
1606
-#if YYSTACKDEPTH<=0
1629
+#if YYGROWABLESTACK
16071630
/*
16081631
** Try to increase the size of the parser stack. Return the number
16091632
** of errors. Return 0 on success.
16101633
*/
16111634
static int yyGrowStack(yyParser *p){
1635
+ int oldSize = 1 + (int)(p->yystackEnd - p->yystack);
16121636
int newSize;
16131637
int idx;
16141638
yyStackEntry *pNew;
16151639
1616
- newSize = p->yystksz*2 + 100;
1617
- idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
1618
- if( p->yystack==&p->yystk0 ){
1619
- pNew = malloc(newSize*sizeof(pNew[0]));
1620
- if( pNew ) pNew[0] = p->yystk0;
1640
+ newSize = oldSize*2 + 100;
1641
+ idx = (int)(p->yytos - p->yystack);
1642
+ if( p->yystack==p->yystk0 ){
1643
+ pNew = YYREALLOC(0, newSize*sizeof(pNew[0]));
1644
+ if( pNew==0 ) return 1;
1645
+ memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
16211646
}else{
1622
- pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
1647
+ pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]));
1648
+ if( pNew==0 ) return 1;
16231649
}
1624
- if( pNew ){
1625
- p->yystack = pNew;
1626
- p->yytos = &p->yystack[idx];
1650
+ p->yystack = pNew;
1651
+ p->yytos = &p->yystack[idx];
16271652
#ifndef NDEBUG
1628
- if( yyTraceFILE ){
1629
- fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
1630
- yyTracePrompt, p->yystksz, newSize);
1631
- }
1653
+ if( yyTraceFILE ){
1654
+ fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
1655
+ yyTracePrompt, oldSize, newSize);
1656
+ }
16321657
#endif
1633
- p->yystksz = newSize;
1634
- }
1635
- return pNew==0;
1658
+ p->yystackEnd = &p->yystack[newSize-1];
1659
+ return 0;
16361660
}
1661
+#endif /* YYGROWABLESTACK */
1662
+
1663
+#if !YYGROWABLESTACK
1664
+/* For builds that do no have a growable stack, yyGrowStack always
1665
+** returns an error.
1666
+*/
1667
+# define yyGrowStack(X) 1
16371668
#endif
16381669
16391670
/* Datatype of the argument to the memory allocated passed as the
16401671
** second argument to pik_parserAlloc() below. This can be changed by
16411672
** putting an appropriate #define in the %include section of the input
@@ -1651,28 +1682,18 @@
16511682
yyParser *yypParser = (yyParser*)yypRawParser;
16521683
pik_parserCTX_STORE
16531684
#ifdef YYTRACKMAXSTACKDEPTH
16541685
yypParser->yyhwm = 0;
16551686
#endif
1656
-#if YYSTACKDEPTH<=0
1657
- yypParser->yytos = NULL;
1658
- yypParser->yystack = NULL;
1659
- yypParser->yystksz = 0;
1660
- if( yyGrowStack(yypParser) ){
1661
- yypParser->yystack = &yypParser->yystk0;
1662
- yypParser->yystksz = 1;
1663
- }
1664
-#endif
1687
+ yypParser->yystack = yypParser->yystk0;
1688
+ yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
16651689
#ifndef YYNOERRORRECOVERY
16661690
yypParser->yyerrcnt = -1;
16671691
#endif
16681692
yypParser->yytos = yypParser->yystack;
16691693
yypParser->yystack[0].stateno = 0;
16701694
yypParser->yystack[0].major = 0;
1671
-#if YYSTACKDEPTH>0
1672
- yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
1673
-#endif
16741695
}
16751696
16761697
#ifndef pik_parser_ENGINEALWAYSONSTACK
16771698
/*
16781699
** This function allocates a new parser.
@@ -1724,22 +1745,22 @@
17241745
** inside the C code.
17251746
*/
17261747
/********* Begin destructor definitions ***************************************/
17271748
case 100: /* statement_list */
17281749
{
1729
-#line 510 "pikchr.y"
1750
+#line 511 "pikchr.y"
17301751
pik_elist_free(p,(yypminor->yy235));
1731
-#line 1756 "pikchr.c"
1752
+#line 1777 "pikchr.c"
17321753
}
17331754
break;
17341755
case 101: /* statement */
17351756
case 102: /* unnamed_statement */
17361757
case 103: /* basetype */
17371758
{
1738
-#line 512 "pikchr.y"
1759
+#line 513 "pikchr.y"
17391760
pik_elem_free(p,(yypminor->yy162));
1740
-#line 1765 "pikchr.c"
1761
+#line 1786 "pikchr.c"
17411762
}
17421763
break;
17431764
/********* End destructor definitions *****************************************/
17441765
default: break; /* If no destructor action specified: do nothing */
17451766
}
@@ -1769,13 +1790,30 @@
17691790
/*
17701791
** Clear all secondary memory allocations from the parser
17711792
*/
17721793
void pik_parserFinalize(void *p){
17731794
yyParser *pParser = (yyParser*)p;
1774
- while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
1775
-#if YYSTACKDEPTH<=0
1776
- if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
1795
+
1796
+ /* In-lined version of calling yy_pop_parser_stack() for each
1797
+ ** element left in the stack */
1798
+ yyStackEntry *yytos = pParser->yytos;
1799
+ while( yytos>pParser->yystack ){
1800
+#ifndef NDEBUG
1801
+ if( yyTraceFILE ){
1802
+ fprintf(yyTraceFILE,"%sPopping %s\n",
1803
+ yyTracePrompt,
1804
+ yyTokenName[yytos->major]);
1805
+ }
1806
+#endif
1807
+ if( yytos->major>=YY_MIN_DSTRCTR ){
1808
+ yy_destructor(pParser, yytos->major, &yytos->minor);
1809
+ }
1810
+ yytos--;
1811
+ }
1812
+
1813
+#if YYGROWABLESTACK
1814
+ if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack);
17771815
#endif
17781816
}
17791817
17801818
#ifndef pik_parser_ENGINEALWAYSONSTACK
17811819
/*
@@ -1953,14 +1991,14 @@
19531991
#endif
19541992
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
19551993
/* Here code is inserted which will execute if the parser
19561994
** stack every overflows */
19571995
/******** Begin %stack_overflow code ******************************************/
1958
-#line 544 "pikchr.y"
1996
+#line 545 "pikchr.y"
19591997
19601998
pik_error(p, 0, "parser stack overflow");
1961
-#line 1986 "pikchr.c"
1999
+#line 2024 "pikchr.c"
19622000
/******** End %stack_overflow code ********************************************/
19632001
pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
19642002
pik_parserCTX_STORE
19652003
}
19662004
@@ -2000,29 +2038,23 @@
20002038
if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
20012039
yypParser->yyhwm++;
20022040
assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
20032041
}
20042042
#endif
2005
-#if YYSTACKDEPTH>0
2006
- if( yypParser->yytos>yypParser->yystackEnd ){
2007
- yypParser->yytos--;
2008
- yyStackOverflow(yypParser);
2009
- return;
2010
- }
2011
-#else
2012
- if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
2043
+ yytos = yypParser->yytos;
2044
+ if( yytos>yypParser->yystackEnd ){
20132045
if( yyGrowStack(yypParser) ){
20142046
yypParser->yytos--;
20152047
yyStackOverflow(yypParser);
20162048
return;
20172049
}
2050
+ yytos = yypParser->yytos;
2051
+ assert( yytos <= yypParser->yystackEnd );
20182052
}
2019
-#endif
20202053
if( yyNewState > YY_MAX_SHIFT ){
20212054
yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
20222055
}
2023
- yytos = yypParser->yytos;
20242056
yytos->stateno = yyNewState;
20252057
yytos->major = yyMajor;
20262058
yytos->minor.yy0 = yyMinor;
20272059
yyTraceShift(yypParser, yyNewState, "Shift");
20282060
}
@@ -2387,619 +2419,619 @@
23872419
** break;
23882420
*/
23892421
/********** Begin reduce actions **********************************************/
23902422
YYMINORTYPE yylhsminor;
23912423
case 0: /* document ::= statement_list */
2392
-#line 548 "pikchr.y"
2424
+#line 549 "pikchr.y"
23932425
{pik_render(p,yymsp[0].minor.yy235);}
2394
-#line 2419 "pikchr.c"
2426
+#line 2451 "pikchr.c"
23952427
break;
23962428
case 1: /* statement_list ::= statement */
2397
-#line 551 "pikchr.y"
2429
+#line 552 "pikchr.y"
23982430
{ yylhsminor.yy235 = pik_elist_append(p,0,yymsp[0].minor.yy162); }
2399
-#line 2424 "pikchr.c"
2431
+#line 2456 "pikchr.c"
24002432
yymsp[0].minor.yy235 = yylhsminor.yy235;
24012433
break;
24022434
case 2: /* statement_list ::= statement_list EOL statement */
2403
-#line 553 "pikchr.y"
2435
+#line 554 "pikchr.y"
24042436
{ yylhsminor.yy235 = pik_elist_append(p,yymsp[-2].minor.yy235,yymsp[0].minor.yy162); }
2405
-#line 2430 "pikchr.c"
2437
+#line 2462 "pikchr.c"
24062438
yymsp[-2].minor.yy235 = yylhsminor.yy235;
24072439
break;
24082440
case 3: /* statement ::= */
2409
-#line 556 "pikchr.y"
2441
+#line 557 "pikchr.y"
24102442
{ yymsp[1].minor.yy162 = 0; }
2411
-#line 2436 "pikchr.c"
2443
+#line 2468 "pikchr.c"
24122444
break;
24132445
case 4: /* statement ::= direction */
2414
-#line 557 "pikchr.y"
2446
+#line 558 "pikchr.y"
24152447
{ pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy162=0; }
2416
-#line 2441 "pikchr.c"
2448
+#line 2473 "pikchr.c"
24172449
yymsp[0].minor.yy162 = yylhsminor.yy162;
24182450
break;
24192451
case 5: /* statement ::= lvalue ASSIGN rvalue */
2420
-#line 558 "pikchr.y"
2452
+#line 559 "pikchr.y"
24212453
{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy21,&yymsp[-1].minor.yy0); yylhsminor.yy162=0;}
2422
-#line 2447 "pikchr.c"
2454
+#line 2479 "pikchr.c"
24232455
yymsp[-2].minor.yy162 = yylhsminor.yy162;
24242456
break;
24252457
case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2426
-#line 560 "pikchr.y"
2458
+#line 561 "pikchr.y"
24272459
{ yylhsminor.yy162 = yymsp[0].minor.yy162; pik_elem_setname(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0); }
2428
-#line 2453 "pikchr.c"
2460
+#line 2485 "pikchr.c"
24292461
yymsp[-2].minor.yy162 = yylhsminor.yy162;
24302462
break;
24312463
case 7: /* statement ::= PLACENAME COLON position */
2432
-#line 562 "pikchr.y"
2464
+#line 563 "pikchr.y"
24332465
{ yylhsminor.yy162 = pik_elem_new(p,0,0,0);
24342466
if(yylhsminor.yy162){ yylhsminor.yy162->ptAt = yymsp[0].minor.yy63; pik_elem_setname(p,yylhsminor.yy162,&yymsp[-2].minor.yy0); }}
2435
-#line 2460 "pikchr.c"
2467
+#line 2492 "pikchr.c"
24362468
yymsp[-2].minor.yy162 = yylhsminor.yy162;
24372469
break;
24382470
case 8: /* statement ::= unnamed_statement */
2439
-#line 564 "pikchr.y"
2471
+#line 565 "pikchr.y"
24402472
{yylhsminor.yy162 = yymsp[0].minor.yy162;}
2441
-#line 2466 "pikchr.c"
2473
+#line 2498 "pikchr.c"
24422474
yymsp[0].minor.yy162 = yylhsminor.yy162;
24432475
break;
24442476
case 9: /* statement ::= print prlist */
2445
-#line 565 "pikchr.y"
2477
+#line 566 "pikchr.y"
24462478
{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy162=0;}
2447
-#line 2472 "pikchr.c"
2479
+#line 2504 "pikchr.c"
24482480
break;
24492481
case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2450
-#line 570 "pikchr.y"
2482
+#line 571 "pikchr.y"
24512483
{yymsp[-5].minor.yy162=pik_assert(p,yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy21);}
2452
-#line 2477 "pikchr.c"
2484
+#line 2509 "pikchr.c"
24532485
break;
24542486
case 11: /* statement ::= ASSERT LP position EQ position RP */
2455
-#line 572 "pikchr.y"
2487
+#line 573 "pikchr.y"
24562488
{yymsp[-5].minor.yy162=pik_position_assert(p,&yymsp[-3].minor.yy63,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy63);}
2457
-#line 2482 "pikchr.c"
2489
+#line 2514 "pikchr.c"
24582490
break;
24592491
case 12: /* statement ::= DEFINE ID CODEBLOCK */
2460
-#line 573 "pikchr.y"
2492
+#line 574 "pikchr.y"
24612493
{yymsp[-2].minor.yy162=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2462
-#line 2487 "pikchr.c"
2494
+#line 2519 "pikchr.c"
24632495
break;
24642496
case 13: /* rvalue ::= PLACENAME */
2465
-#line 584 "pikchr.y"
2497
+#line 585 "pikchr.y"
24662498
{yylhsminor.yy21 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2467
-#line 2492 "pikchr.c"
2499
+#line 2524 "pikchr.c"
24682500
yymsp[0].minor.yy21 = yylhsminor.yy21;
24692501
break;
24702502
case 14: /* pritem ::= FILL */
24712503
case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
24722504
case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2473
-#line 589 "pikchr.y"
2505
+#line 590 "pikchr.y"
24742506
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2475
-#line 2500 "pikchr.c"
2507
+#line 2532 "pikchr.c"
24762508
break;
24772509
case 17: /* pritem ::= rvalue */
2478
-#line 592 "pikchr.y"
2510
+#line 593 "pikchr.y"
24792511
{pik_append_num(p,"",yymsp[0].minor.yy21);}
2480
-#line 2505 "pikchr.c"
2512
+#line 2537 "pikchr.c"
24812513
break;
24822514
case 18: /* pritem ::= STRING */
2483
-#line 593 "pikchr.y"
2515
+#line 594 "pikchr.y"
24842516
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2485
-#line 2510 "pikchr.c"
2517
+#line 2542 "pikchr.c"
24862518
break;
24872519
case 19: /* prsep ::= COMMA */
2488
-#line 594 "pikchr.y"
2520
+#line 595 "pikchr.y"
24892521
{pik_append(p, " ", 1);}
2490
-#line 2515 "pikchr.c"
2522
+#line 2547 "pikchr.c"
24912523
break;
24922524
case 20: /* unnamed_statement ::= basetype attribute_list */
2493
-#line 597 "pikchr.y"
2525
+#line 598 "pikchr.y"
24942526
{yylhsminor.yy162 = yymsp[-1].minor.yy162; pik_after_adding_attributes(p,yylhsminor.yy162);}
2495
-#line 2520 "pikchr.c"
2527
+#line 2552 "pikchr.c"
24962528
yymsp[-1].minor.yy162 = yylhsminor.yy162;
24972529
break;
24982530
case 21: /* basetype ::= CLASSNAME */
2499
-#line 599 "pikchr.y"
2531
+#line 600 "pikchr.y"
25002532
{yylhsminor.yy162 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2501
-#line 2526 "pikchr.c"
2533
+#line 2558 "pikchr.c"
25022534
yymsp[0].minor.yy162 = yylhsminor.yy162;
25032535
break;
25042536
case 22: /* basetype ::= STRING textposition */
2505
-#line 601 "pikchr.y"
2537
+#line 602 "pikchr.y"
25062538
{yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy188; yylhsminor.yy162 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2507
-#line 2532 "pikchr.c"
2539
+#line 2564 "pikchr.c"
25082540
yymsp[-1].minor.yy162 = yylhsminor.yy162;
25092541
break;
25102542
case 23: /* basetype ::= LB savelist statement_list RB */
2511
-#line 603 "pikchr.y"
2543
+#line 604 "pikchr.y"
25122544
{ p->list = yymsp[-2].minor.yy235; yymsp[-3].minor.yy162 = pik_elem_new(p,0,0,yymsp[-1].minor.yy235); if(yymsp[-3].minor.yy162) yymsp[-3].minor.yy162->errTok = yymsp[0].minor.yy0; }
2513
-#line 2538 "pikchr.c"
2545
+#line 2570 "pikchr.c"
25142546
break;
25152547
case 24: /* savelist ::= */
2516
-#line 608 "pikchr.y"
2548
+#line 609 "pikchr.y"
25172549
{yymsp[1].minor.yy235 = p->list; p->list = 0;}
2518
-#line 2543 "pikchr.c"
2550
+#line 2575 "pikchr.c"
25192551
break;
25202552
case 25: /* relexpr ::= expr */
2521
-#line 615 "pikchr.y"
2553
+#line 616 "pikchr.y"
25222554
{yylhsminor.yy72.rAbs = yymsp[0].minor.yy21; yylhsminor.yy72.rRel = 0;}
2523
-#line 2548 "pikchr.c"
2555
+#line 2580 "pikchr.c"
25242556
yymsp[0].minor.yy72 = yylhsminor.yy72;
25252557
break;
25262558
case 26: /* relexpr ::= expr PERCENT */
2527
-#line 616 "pikchr.y"
2559
+#line 617 "pikchr.y"
25282560
{yylhsminor.yy72.rAbs = 0; yylhsminor.yy72.rRel = yymsp[-1].minor.yy21/100;}
2529
-#line 2554 "pikchr.c"
2561
+#line 2586 "pikchr.c"
25302562
yymsp[-1].minor.yy72 = yylhsminor.yy72;
25312563
break;
25322564
case 27: /* optrelexpr ::= */
2533
-#line 618 "pikchr.y"
2565
+#line 619 "pikchr.y"
25342566
{yymsp[1].minor.yy72.rAbs = 0; yymsp[1].minor.yy72.rRel = 1.0;}
2535
-#line 2560 "pikchr.c"
2567
+#line 2592 "pikchr.c"
25362568
break;
25372569
case 28: /* attribute_list ::= relexpr alist */
2538
-#line 620 "pikchr.y"
2570
+#line 621 "pikchr.y"
25392571
{pik_add_direction(p,0,&yymsp[-1].minor.yy72);}
2540
-#line 2565 "pikchr.c"
2572
+#line 2597 "pikchr.c"
25412573
break;
25422574
case 29: /* attribute ::= numproperty relexpr */
2543
-#line 624 "pikchr.y"
2575
+#line 625 "pikchr.y"
25442576
{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72); }
2545
-#line 2570 "pikchr.c"
2577
+#line 2602 "pikchr.c"
25462578
break;
25472579
case 30: /* attribute ::= dashproperty expr */
2548
-#line 625 "pikchr.y"
2580
+#line 626 "pikchr.y"
25492581
{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy21); }
2550
-#line 2575 "pikchr.c"
2582
+#line 2607 "pikchr.c"
25512583
break;
25522584
case 31: /* attribute ::= dashproperty */
2553
-#line 626 "pikchr.y"
2585
+#line 627 "pikchr.y"
25542586
{ pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2555
-#line 2580 "pikchr.c"
2587
+#line 2612 "pikchr.c"
25562588
break;
25572589
case 32: /* attribute ::= colorproperty rvalue */
2558
-#line 627 "pikchr.y"
2590
+#line 628 "pikchr.y"
25592591
{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21); }
2560
-#line 2585 "pikchr.c"
2592
+#line 2617 "pikchr.c"
25612593
break;
25622594
case 33: /* attribute ::= go direction optrelexpr */
2563
-#line 628 "pikchr.y"
2595
+#line 629 "pikchr.y"
25642596
{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72);}
2565
-#line 2590 "pikchr.c"
2597
+#line 2622 "pikchr.c"
25662598
break;
25672599
case 34: /* attribute ::= go direction even position */
2568
-#line 629 "pikchr.y"
2600
+#line 630 "pikchr.y"
25692601
{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63);}
2570
-#line 2595 "pikchr.c"
2602
+#line 2627 "pikchr.c"
25712603
break;
25722604
case 35: /* attribute ::= CLOSE */
2573
-#line 630 "pikchr.y"
2605
+#line 631 "pikchr.y"
25742606
{ pik_close_path(p,&yymsp[0].minor.yy0); }
2575
-#line 2600 "pikchr.c"
2607
+#line 2632 "pikchr.c"
25762608
break;
25772609
case 36: /* attribute ::= CHOP */
2578
-#line 631 "pikchr.y"
2610
+#line 632 "pikchr.y"
25792611
{ p->cur->bChop = 1; }
2580
-#line 2605 "pikchr.c"
2612
+#line 2637 "pikchr.c"
25812613
break;
25822614
case 37: /* attribute ::= FROM position */
2583
-#line 632 "pikchr.y"
2615
+#line 633 "pikchr.y"
25842616
{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2585
-#line 2610 "pikchr.c"
2617
+#line 2642 "pikchr.c"
25862618
break;
25872619
case 38: /* attribute ::= TO position */
2588
-#line 633 "pikchr.y"
2620
+#line 634 "pikchr.y"
25892621
{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2590
-#line 2615 "pikchr.c"
2622
+#line 2647 "pikchr.c"
25912623
break;
25922624
case 39: /* attribute ::= THEN */
2593
-#line 634 "pikchr.y"
2625
+#line 635 "pikchr.y"
25942626
{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2595
-#line 2620 "pikchr.c"
2627
+#line 2652 "pikchr.c"
25962628
break;
25972629
case 40: /* attribute ::= THEN optrelexpr HEADING expr */
25982630
case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2599
-#line 636 "pikchr.y"
2631
+#line 637 "pikchr.y"
26002632
{pik_move_hdg(p,&yymsp[-2].minor.yy72,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21,0,&yymsp[-3].minor.yy0);}
2601
-#line 2626 "pikchr.c"
2633
+#line 2658 "pikchr.c"
26022634
break;
26032635
case 41: /* attribute ::= THEN optrelexpr EDGEPT */
26042636
case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2605
-#line 637 "pikchr.y"
2637
+#line 638 "pikchr.y"
26062638
{pik_move_hdg(p,&yymsp[-1].minor.yy72,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2607
-#line 2632 "pikchr.c"
2639
+#line 2664 "pikchr.c"
26082640
break;
26092641
case 44: /* attribute ::= AT position */
2610
-#line 642 "pikchr.y"
2642
+#line 643 "pikchr.y"
26112643
{ pik_set_at(p,0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2612
-#line 2637 "pikchr.c"
2644
+#line 2669 "pikchr.c"
26132645
break;
26142646
case 45: /* attribute ::= SAME */
2615
-#line 644 "pikchr.y"
2647
+#line 645 "pikchr.y"
26162648
{pik_same(p,0,&yymsp[0].minor.yy0);}
2617
-#line 2642 "pikchr.c"
2649
+#line 2674 "pikchr.c"
26182650
break;
26192651
case 46: /* attribute ::= SAME AS object */
2620
-#line 645 "pikchr.y"
2652
+#line 646 "pikchr.y"
26212653
{pik_same(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2622
-#line 2647 "pikchr.c"
2654
+#line 2679 "pikchr.c"
26232655
break;
26242656
case 47: /* attribute ::= STRING textposition */
2625
-#line 646 "pikchr.y"
2657
+#line 647 "pikchr.y"
26262658
{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy188);}
2627
-#line 2652 "pikchr.c"
2659
+#line 2684 "pikchr.c"
26282660
break;
26292661
case 48: /* attribute ::= FIT */
2630
-#line 647 "pikchr.y"
2662
+#line 648 "pikchr.y"
26312663
{pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2632
-#line 2657 "pikchr.c"
2664
+#line 2689 "pikchr.c"
26332665
break;
26342666
case 49: /* attribute ::= BEHIND object */
2635
-#line 648 "pikchr.y"
2667
+#line 649 "pikchr.y"
26362668
{pik_behind(p,yymsp[0].minor.yy162);}
2637
-#line 2662 "pikchr.c"
2669
+#line 2694 "pikchr.c"
26382670
break;
26392671
case 50: /* withclause ::= DOT_E edge AT position */
26402672
case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2641
-#line 656 "pikchr.y"
2673
+#line 657 "pikchr.y"
26422674
{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2643
-#line 2668 "pikchr.c"
2675
+#line 2700 "pikchr.c"
26442676
break;
26452677
case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2646
-#line 660 "pikchr.y"
2678
+#line 661 "pikchr.y"
26472679
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
2648
-#line 2673 "pikchr.c"
2680
+#line 2705 "pikchr.c"
26492681
yymsp[0].minor.yy0 = yylhsminor.yy0;
26502682
break;
26512683
case 53: /* boolproperty ::= CW */
2652
-#line 671 "pikchr.y"
2684
+#line 672 "pikchr.y"
26532685
{p->cur->cw = 1;}
2654
-#line 2679 "pikchr.c"
2686
+#line 2711 "pikchr.c"
26552687
break;
26562688
case 54: /* boolproperty ::= CCW */
2657
-#line 672 "pikchr.y"
2689
+#line 673 "pikchr.y"
26582690
{p->cur->cw = 0;}
2659
-#line 2684 "pikchr.c"
2691
+#line 2716 "pikchr.c"
26602692
break;
26612693
case 55: /* boolproperty ::= LARROW */
2662
-#line 673 "pikchr.y"
2694
+#line 674 "pikchr.y"
26632695
{p->cur->larrow=1; p->cur->rarrow=0; }
2664
-#line 2689 "pikchr.c"
2696
+#line 2721 "pikchr.c"
26652697
break;
26662698
case 56: /* boolproperty ::= RARROW */
2667
-#line 674 "pikchr.y"
2699
+#line 675 "pikchr.y"
26682700
{p->cur->larrow=0; p->cur->rarrow=1; }
2669
-#line 2694 "pikchr.c"
2701
+#line 2726 "pikchr.c"
26702702
break;
26712703
case 57: /* boolproperty ::= LRARROW */
2672
-#line 675 "pikchr.y"
2704
+#line 676 "pikchr.y"
26732705
{p->cur->larrow=1; p->cur->rarrow=1; }
2674
-#line 2699 "pikchr.c"
2706
+#line 2731 "pikchr.c"
26752707
break;
26762708
case 58: /* boolproperty ::= INVIS */
2677
-#line 676 "pikchr.y"
2709
+#line 677 "pikchr.y"
26782710
{p->cur->sw = -0.00001;}
2679
-#line 2704 "pikchr.c"
2711
+#line 2736 "pikchr.c"
26802712
break;
26812713
case 59: /* boolproperty ::= THICK */
2682
-#line 677 "pikchr.y"
2714
+#line 678 "pikchr.y"
26832715
{p->cur->sw *= 1.5;}
2684
-#line 2709 "pikchr.c"
2716
+#line 2741 "pikchr.c"
26852717
break;
26862718
case 60: /* boolproperty ::= THIN */
2687
-#line 678 "pikchr.y"
2719
+#line 679 "pikchr.y"
26882720
{p->cur->sw *= 0.67;}
2689
-#line 2714 "pikchr.c"
2721
+#line 2746 "pikchr.c"
26902722
break;
26912723
case 61: /* boolproperty ::= SOLID */
2692
-#line 679 "pikchr.y"
2724
+#line 680 "pikchr.y"
26932725
{p->cur->sw = pik_value(p,"thickness",9,0);
26942726
p->cur->dotted = p->cur->dashed = 0.0;}
2695
-#line 2720 "pikchr.c"
2727
+#line 2752 "pikchr.c"
26962728
break;
26972729
case 62: /* textposition ::= */
2698
-#line 682 "pikchr.y"
2730
+#line 683 "pikchr.y"
26992731
{yymsp[1].minor.yy188 = 0;}
2700
-#line 2725 "pikchr.c"
2732
+#line 2757 "pikchr.c"
27012733
break;
27022734
case 63: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|MONO|ALIGNED|BIG|SMALL */
2703
-#line 685 "pikchr.y"
2735
+#line 686 "pikchr.y"
27042736
{yylhsminor.yy188 = (short int)pik_text_position(yymsp[-1].minor.yy188,&yymsp[0].minor.yy0);}
2705
-#line 2730 "pikchr.c"
2737
+#line 2762 "pikchr.c"
27062738
yymsp[-1].minor.yy188 = yylhsminor.yy188;
27072739
break;
27082740
case 64: /* position ::= expr COMMA expr */
2709
-#line 688 "pikchr.y"
2741
+#line 689 "pikchr.y"
27102742
{yylhsminor.yy63.x=yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[0].minor.yy21;}
2711
-#line 2736 "pikchr.c"
2743
+#line 2768 "pikchr.c"
27122744
yymsp[-2].minor.yy63 = yylhsminor.yy63;
27132745
break;
27142746
case 65: /* position ::= place PLUS expr COMMA expr */
2715
-#line 690 "pikchr.y"
2747
+#line 691 "pikchr.y"
27162748
{yylhsminor.yy63.x=yymsp[-4].minor.yy63.x+yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[-4].minor.yy63.y+yymsp[0].minor.yy21;}
2717
-#line 2742 "pikchr.c"
2749
+#line 2774 "pikchr.c"
27182750
yymsp[-4].minor.yy63 = yylhsminor.yy63;
27192751
break;
27202752
case 66: /* position ::= place MINUS expr COMMA expr */
2721
-#line 691 "pikchr.y"
2753
+#line 692 "pikchr.y"
27222754
{yylhsminor.yy63.x=yymsp[-4].minor.yy63.x-yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[-4].minor.yy63.y-yymsp[0].minor.yy21;}
2723
-#line 2748 "pikchr.c"
2755
+#line 2780 "pikchr.c"
27242756
yymsp[-4].minor.yy63 = yylhsminor.yy63;
27252757
break;
27262758
case 67: /* position ::= place PLUS LP expr COMMA expr RP */
2727
-#line 693 "pikchr.y"
2759
+#line 694 "pikchr.y"
27282760
{yylhsminor.yy63.x=yymsp[-6].minor.yy63.x+yymsp[-3].minor.yy21; yylhsminor.yy63.y=yymsp[-6].minor.yy63.y+yymsp[-1].minor.yy21;}
2729
-#line 2754 "pikchr.c"
2761
+#line 2786 "pikchr.c"
27302762
yymsp[-6].minor.yy63 = yylhsminor.yy63;
27312763
break;
27322764
case 68: /* position ::= place MINUS LP expr COMMA expr RP */
2733
-#line 695 "pikchr.y"
2765
+#line 696 "pikchr.y"
27342766
{yylhsminor.yy63.x=yymsp[-6].minor.yy63.x-yymsp[-3].minor.yy21; yylhsminor.yy63.y=yymsp[-6].minor.yy63.y-yymsp[-1].minor.yy21;}
2735
-#line 2760 "pikchr.c"
2767
+#line 2792 "pikchr.c"
27362768
yymsp[-6].minor.yy63 = yylhsminor.yy63;
27372769
break;
27382770
case 69: /* position ::= LP position COMMA position RP */
2739
-#line 696 "pikchr.y"
2771
+#line 697 "pikchr.y"
27402772
{yymsp[-4].minor.yy63.x=yymsp[-3].minor.yy63.x; yymsp[-4].minor.yy63.y=yymsp[-1].minor.yy63.y;}
2741
-#line 2766 "pikchr.c"
2773
+#line 2798 "pikchr.c"
27422774
break;
27432775
case 70: /* position ::= LP position RP */
2744
-#line 697 "pikchr.y"
2776
+#line 698 "pikchr.y"
27452777
{yymsp[-2].minor.yy63=yymsp[-1].minor.yy63;}
2746
-#line 2771 "pikchr.c"
2778
+#line 2803 "pikchr.c"
27472779
break;
27482780
case 71: /* position ::= expr between position AND position */
2749
-#line 699 "pikchr.y"
2781
+#line 700 "pikchr.y"
27502782
{yylhsminor.yy63 = pik_position_between(yymsp[-4].minor.yy21,yymsp[-2].minor.yy63,yymsp[0].minor.yy63);}
2751
-#line 2776 "pikchr.c"
2783
+#line 2808 "pikchr.c"
27522784
yymsp[-4].minor.yy63 = yylhsminor.yy63;
27532785
break;
27542786
case 72: /* position ::= expr LT position COMMA position GT */
2755
-#line 701 "pikchr.y"
2787
+#line 702 "pikchr.y"
27562788
{yylhsminor.yy63 = pik_position_between(yymsp[-5].minor.yy21,yymsp[-3].minor.yy63,yymsp[-1].minor.yy63);}
2757
-#line 2782 "pikchr.c"
2789
+#line 2814 "pikchr.c"
27582790
yymsp[-5].minor.yy63 = yylhsminor.yy63;
27592791
break;
27602792
case 73: /* position ::= expr ABOVE position */
2761
-#line 702 "pikchr.y"
2793
+#line 703 "pikchr.y"
27622794
{yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y += yymsp[-2].minor.yy21;}
2763
-#line 2788 "pikchr.c"
2795
+#line 2820 "pikchr.c"
27642796
yymsp[-2].minor.yy63 = yylhsminor.yy63;
27652797
break;
27662798
case 74: /* position ::= expr BELOW position */
2767
-#line 703 "pikchr.y"
2799
+#line 704 "pikchr.y"
27682800
{yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y -= yymsp[-2].minor.yy21;}
2769
-#line 2794 "pikchr.c"
2801
+#line 2826 "pikchr.c"
27702802
yymsp[-2].minor.yy63 = yylhsminor.yy63;
27712803
break;
27722804
case 75: /* position ::= expr LEFT OF position */
2773
-#line 704 "pikchr.y"
2805
+#line 705 "pikchr.y"
27742806
{yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x -= yymsp[-3].minor.yy21;}
2775
-#line 2800 "pikchr.c"
2807
+#line 2832 "pikchr.c"
27762808
yymsp[-3].minor.yy63 = yylhsminor.yy63;
27772809
break;
27782810
case 76: /* position ::= expr RIGHT OF position */
2779
-#line 705 "pikchr.y"
2811
+#line 706 "pikchr.y"
27802812
{yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x += yymsp[-3].minor.yy21;}
2781
-#line 2806 "pikchr.c"
2813
+#line 2838 "pikchr.c"
27822814
yymsp[-3].minor.yy63 = yylhsminor.yy63;
27832815
break;
27842816
case 77: /* position ::= expr ON HEADING EDGEPT OF position */
2785
-#line 707 "pikchr.y"
2817
+#line 708 "pikchr.y"
27862818
{yylhsminor.yy63 = pik_position_at_hdg(yymsp[-5].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2787
-#line 2812 "pikchr.c"
2819
+#line 2844 "pikchr.c"
27882820
yymsp[-5].minor.yy63 = yylhsminor.yy63;
27892821
break;
27902822
case 78: /* position ::= expr HEADING EDGEPT OF position */
2791
-#line 709 "pikchr.y"
2823
+#line 710 "pikchr.y"
27922824
{yylhsminor.yy63 = pik_position_at_hdg(yymsp[-4].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2793
-#line 2818 "pikchr.c"
2825
+#line 2850 "pikchr.c"
27942826
yymsp[-4].minor.yy63 = yylhsminor.yy63;
27952827
break;
27962828
case 79: /* position ::= expr EDGEPT OF position */
2797
-#line 711 "pikchr.y"
2829
+#line 712 "pikchr.y"
27982830
{yylhsminor.yy63 = pik_position_at_hdg(yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2799
-#line 2824 "pikchr.c"
2831
+#line 2856 "pikchr.c"
28002832
yymsp[-3].minor.yy63 = yylhsminor.yy63;
28012833
break;
28022834
case 80: /* position ::= expr ON HEADING expr FROM position */
2803
-#line 713 "pikchr.y"
2835
+#line 714 "pikchr.y"
28042836
{yylhsminor.yy63 = pik_position_at_angle(yymsp[-5].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2805
-#line 2830 "pikchr.c"
2837
+#line 2862 "pikchr.c"
28062838
yymsp[-5].minor.yy63 = yylhsminor.yy63;
28072839
break;
28082840
case 81: /* position ::= expr HEADING expr FROM position */
2809
-#line 715 "pikchr.y"
2841
+#line 716 "pikchr.y"
28102842
{yylhsminor.yy63 = pik_position_at_angle(yymsp[-4].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2811
-#line 2836 "pikchr.c"
2843
+#line 2868 "pikchr.c"
28122844
yymsp[-4].minor.yy63 = yylhsminor.yy63;
28132845
break;
28142846
case 82: /* place ::= edge OF object */
2815
-#line 727 "pikchr.y"
2847
+#line 728 "pikchr.y"
28162848
{yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2817
-#line 2842 "pikchr.c"
2849
+#line 2874 "pikchr.c"
28182850
yymsp[-2].minor.yy63 = yylhsminor.yy63;
28192851
break;
28202852
case 83: /* place2 ::= object */
2821
-#line 728 "pikchr.y"
2853
+#line 729 "pikchr.y"
28222854
{yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,0);}
2823
-#line 2848 "pikchr.c"
2855
+#line 2880 "pikchr.c"
28242856
yymsp[0].minor.yy63 = yylhsminor.yy63;
28252857
break;
28262858
case 84: /* place2 ::= object DOT_E edge */
2827
-#line 729 "pikchr.y"
2859
+#line 730 "pikchr.y"
28282860
{yylhsminor.yy63 = pik_place_of_elem(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2829
-#line 2854 "pikchr.c"
2861
+#line 2886 "pikchr.c"
28302862
yymsp[-2].minor.yy63 = yylhsminor.yy63;
28312863
break;
28322864
case 85: /* place2 ::= NTH VERTEX OF object */
2833
-#line 730 "pikchr.y"
2865
+#line 731 "pikchr.y"
28342866
{yylhsminor.yy63 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy162);}
2835
-#line 2860 "pikchr.c"
2867
+#line 2892 "pikchr.c"
28362868
yymsp[-3].minor.yy63 = yylhsminor.yy63;
28372869
break;
28382870
case 86: /* object ::= nth */
2839
-#line 742 "pikchr.y"
2871
+#line 743 "pikchr.y"
28402872
{yylhsminor.yy162 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2841
-#line 2866 "pikchr.c"
2873
+#line 2898 "pikchr.c"
28422874
yymsp[0].minor.yy162 = yylhsminor.yy162;
28432875
break;
28442876
case 87: /* object ::= nth OF|IN object */
2845
-#line 743 "pikchr.y"
2877
+#line 744 "pikchr.y"
28462878
{yylhsminor.yy162 = pik_find_nth(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2847
-#line 2872 "pikchr.c"
2879
+#line 2904 "pikchr.c"
28482880
yymsp[-2].minor.yy162 = yylhsminor.yy162;
28492881
break;
28502882
case 88: /* objectname ::= THIS */
2851
-#line 745 "pikchr.y"
2883
+#line 746 "pikchr.y"
28522884
{yymsp[0].minor.yy162 = p->cur;}
2853
-#line 2878 "pikchr.c"
2885
+#line 2910 "pikchr.c"
28542886
break;
28552887
case 89: /* objectname ::= PLACENAME */
2856
-#line 746 "pikchr.y"
2888
+#line 747 "pikchr.y"
28572889
{yylhsminor.yy162 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2858
-#line 2883 "pikchr.c"
2890
+#line 2915 "pikchr.c"
28592891
yymsp[0].minor.yy162 = yylhsminor.yy162;
28602892
break;
28612893
case 90: /* objectname ::= objectname DOT_U PLACENAME */
2862
-#line 748 "pikchr.y"
2894
+#line 749 "pikchr.y"
28632895
{yylhsminor.yy162 = pik_find_byname(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2864
-#line 2889 "pikchr.c"
2896
+#line 2921 "pikchr.c"
28652897
yymsp[-2].minor.yy162 = yylhsminor.yy162;
28662898
break;
28672899
case 91: /* nth ::= NTH CLASSNAME */
2868
-#line 750 "pikchr.y"
2900
+#line 751 "pikchr.y"
28692901
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2870
-#line 2895 "pikchr.c"
2902
+#line 2927 "pikchr.c"
28712903
yymsp[-1].minor.yy0 = yylhsminor.yy0;
28722904
break;
28732905
case 92: /* nth ::= NTH LAST CLASSNAME */
2874
-#line 751 "pikchr.y"
2906
+#line 752 "pikchr.y"
28752907
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2876
-#line 2901 "pikchr.c"
2908
+#line 2933 "pikchr.c"
28772909
yymsp[-2].minor.yy0 = yylhsminor.yy0;
28782910
break;
28792911
case 93: /* nth ::= LAST CLASSNAME */
2880
-#line 752 "pikchr.y"
2912
+#line 753 "pikchr.y"
28812913
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2882
-#line 2907 "pikchr.c"
2914
+#line 2939 "pikchr.c"
28832915
break;
28842916
case 94: /* nth ::= LAST */
2885
-#line 753 "pikchr.y"
2917
+#line 754 "pikchr.y"
28862918
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2887
-#line 2912 "pikchr.c"
2919
+#line 2944 "pikchr.c"
28882920
yymsp[0].minor.yy0 = yylhsminor.yy0;
28892921
break;
28902922
case 95: /* nth ::= NTH LB RB */
2891
-#line 754 "pikchr.y"
2923
+#line 755 "pikchr.y"
28922924
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2893
-#line 2918 "pikchr.c"
2925
+#line 2950 "pikchr.c"
28942926
yymsp[-2].minor.yy0 = yylhsminor.yy0;
28952927
break;
28962928
case 96: /* nth ::= NTH LAST LB RB */
2897
-#line 755 "pikchr.y"
2929
+#line 756 "pikchr.y"
28982930
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2899
-#line 2924 "pikchr.c"
2931
+#line 2956 "pikchr.c"
29002932
yymsp[-3].minor.yy0 = yylhsminor.yy0;
29012933
break;
29022934
case 97: /* nth ::= LAST LB RB */
2903
-#line 756 "pikchr.y"
2935
+#line 757 "pikchr.y"
29042936
{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2905
-#line 2930 "pikchr.c"
2937
+#line 2962 "pikchr.c"
29062938
break;
29072939
case 98: /* expr ::= expr PLUS expr */
2908
-#line 758 "pikchr.y"
2940
+#line 759 "pikchr.y"
29092941
{yylhsminor.yy21=yymsp[-2].minor.yy21+yymsp[0].minor.yy21;}
2910
-#line 2935 "pikchr.c"
2942
+#line 2967 "pikchr.c"
29112943
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29122944
break;
29132945
case 99: /* expr ::= expr MINUS expr */
2914
-#line 759 "pikchr.y"
2946
+#line 760 "pikchr.y"
29152947
{yylhsminor.yy21=yymsp[-2].minor.yy21-yymsp[0].minor.yy21;}
2916
-#line 2941 "pikchr.c"
2948
+#line 2973 "pikchr.c"
29172949
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29182950
break;
29192951
case 100: /* expr ::= expr STAR expr */
2920
-#line 760 "pikchr.y"
2952
+#line 761 "pikchr.y"
29212953
{yylhsminor.yy21=yymsp[-2].minor.yy21*yymsp[0].minor.yy21;}
2922
-#line 2947 "pikchr.c"
2954
+#line 2979 "pikchr.c"
29232955
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29242956
break;
29252957
case 101: /* expr ::= expr SLASH expr */
2926
-#line 761 "pikchr.y"
2958
+#line 762 "pikchr.y"
29272959
{
29282960
if( yymsp[0].minor.yy21==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy21 = 0.0; }
29292961
else{ yylhsminor.yy21 = yymsp[-2].minor.yy21/yymsp[0].minor.yy21; }
29302962
}
2931
-#line 2956 "pikchr.c"
2963
+#line 2988 "pikchr.c"
29322964
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29332965
break;
29342966
case 102: /* expr ::= MINUS expr */
2935
-#line 765 "pikchr.y"
2967
+#line 766 "pikchr.y"
29362968
{yymsp[-1].minor.yy21=-yymsp[0].minor.yy21;}
2937
-#line 2962 "pikchr.c"
2969
+#line 2994 "pikchr.c"
29382970
break;
29392971
case 103: /* expr ::= PLUS expr */
2940
-#line 766 "pikchr.y"
2972
+#line 767 "pikchr.y"
29412973
{yymsp[-1].minor.yy21=yymsp[0].minor.yy21;}
2942
-#line 2967 "pikchr.c"
2974
+#line 2999 "pikchr.c"
29432975
break;
29442976
case 104: /* expr ::= LP expr RP */
2945
-#line 767 "pikchr.y"
2977
+#line 768 "pikchr.y"
29462978
{yymsp[-2].minor.yy21=yymsp[-1].minor.yy21;}
2947
-#line 2972 "pikchr.c"
2979
+#line 3004 "pikchr.c"
29482980
break;
29492981
case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2950
-#line 768 "pikchr.y"
2982
+#line 769 "pikchr.y"
29512983
{yymsp[-2].minor.yy21=pik_get_var(p,&yymsp[-1].minor.yy0);}
2952
-#line 2977 "pikchr.c"
2984
+#line 3009 "pikchr.c"
29532985
break;
29542986
case 106: /* expr ::= NUMBER */
2955
-#line 769 "pikchr.y"
2987
+#line 770 "pikchr.y"
29562988
{yylhsminor.yy21=pik_atof(&yymsp[0].minor.yy0);}
2957
-#line 2982 "pikchr.c"
2989
+#line 3014 "pikchr.c"
29582990
yymsp[0].minor.yy21 = yylhsminor.yy21;
29592991
break;
29602992
case 107: /* expr ::= ID */
2961
-#line 770 "pikchr.y"
2993
+#line 771 "pikchr.y"
29622994
{yylhsminor.yy21=pik_get_var(p,&yymsp[0].minor.yy0);}
2963
-#line 2988 "pikchr.c"
2995
+#line 3020 "pikchr.c"
29642996
yymsp[0].minor.yy21 = yylhsminor.yy21;
29652997
break;
29662998
case 108: /* expr ::= FUNC1 LP expr RP */
2967
-#line 771 "pikchr.y"
2999
+#line 772 "pikchr.y"
29683000
{yylhsminor.yy21 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy21,0.0);}
2969
-#line 2994 "pikchr.c"
3001
+#line 3026 "pikchr.c"
29703002
yymsp[-3].minor.yy21 = yylhsminor.yy21;
29713003
break;
29723004
case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */
2973
-#line 772 "pikchr.y"
3005
+#line 773 "pikchr.y"
29743006
{yylhsminor.yy21 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy21,yymsp[-1].minor.yy21);}
2975
-#line 3000 "pikchr.c"
3007
+#line 3032 "pikchr.c"
29763008
yymsp[-5].minor.yy21 = yylhsminor.yy21;
29773009
break;
29783010
case 110: /* expr ::= DIST LP position COMMA position RP */
2979
-#line 773 "pikchr.y"
3011
+#line 774 "pikchr.y"
29803012
{yymsp[-5].minor.yy21 = pik_dist(&yymsp[-3].minor.yy63,&yymsp[-1].minor.yy63);}
2981
-#line 3006 "pikchr.c"
3013
+#line 3038 "pikchr.c"
29823014
break;
29833015
case 111: /* expr ::= place2 DOT_XY X */
2984
-#line 774 "pikchr.y"
3016
+#line 775 "pikchr.y"
29853017
{yylhsminor.yy21 = yymsp[-2].minor.yy63.x;}
2986
-#line 3011 "pikchr.c"
3018
+#line 3043 "pikchr.c"
29873019
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29883020
break;
29893021
case 112: /* expr ::= place2 DOT_XY Y */
2990
-#line 775 "pikchr.y"
3022
+#line 776 "pikchr.y"
29913023
{yylhsminor.yy21 = yymsp[-2].minor.yy63.y;}
2992
-#line 3017 "pikchr.c"
3024
+#line 3049 "pikchr.c"
29933025
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29943026
break;
29953027
case 113: /* expr ::= object DOT_L numproperty */
29963028
case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114);
29973029
case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115);
2998
-#line 776 "pikchr.y"
3030
+#line 777 "pikchr.y"
29993031
{yylhsminor.yy21=pik_property_of(yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
3000
-#line 3025 "pikchr.c"
3032
+#line 3057 "pikchr.c"
30013033
yymsp[-2].minor.yy21 = yylhsminor.yy21;
30023034
break;
30033035
default:
30043036
/* (116) lvalue ::= ID */ yytestcase(yyruleno==116);
30053037
/* (117) lvalue ::= FILL */ yytestcase(yyruleno==117);
@@ -3098,19 +3130,19 @@
30983130
){
30993131
pik_parserARG_FETCH
31003132
pik_parserCTX_FETCH
31013133
#define TOKEN yyminor
31023134
/************ Begin %syntax_error code ****************************************/
3103
-#line 536 "pikchr.y"
3135
+#line 537 "pikchr.y"
31043136
31053137
if( TOKEN.z && TOKEN.z[0] ){
31063138
pik_error(p, &TOKEN, "syntax error");
31073139
}else{
31083140
pik_error(p, 0, "syntax error");
31093141
}
31103142
UNUSED_PARAMETER(yymajor);
3111
-#line 3136 "pikchr.c"
3143
+#line 3168 "pikchr.c"
31123144
/************ End %syntax_error code ******************************************/
31133145
pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
31143146
pik_parserCTX_STORE
31153147
}
31163148
@@ -3227,23 +3259,16 @@
32273259
yypParser->yyhwm++;
32283260
assert( yypParser->yyhwm ==
32293261
(int)(yypParser->yytos - yypParser->yystack));
32303262
}
32313263
#endif
3232
-#if YYSTACKDEPTH>0
32333264
if( yypParser->yytos>=yypParser->yystackEnd ){
3234
- yyStackOverflow(yypParser);
3235
- break;
3236
- }
3237
-#else
3238
- if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
32393265
if( yyGrowStack(yypParser) ){
32403266
yyStackOverflow(yypParser);
32413267
break;
32423268
}
32433269
}
3244
-#endif
32453270
}
32463271
yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor pik_parserCTX_PARAM);
32473272
}else if( yyact <= YY_MAX_SHIFTREDUCE ){
32483273
yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
32493274
#ifndef YYNOERRORRECOVERY
@@ -3382,11 +3407,11 @@
33823407
#else
33833408
(void)iToken;
33843409
return 0;
33853410
#endif
33863411
}
3387
-#line 781 "pikchr.y"
3412
+#line 782 "pikchr.y"
33883413
33893414
33903415
33913416
/* Chart of the 148 official CSS color names with their
33923417
** corresponding RGB values thru Color Module Level 4:
@@ -3577,10 +3602,12 @@
35773602
{ "color", 0.0 },
35783603
{ "cylht", 0.5 },
35793604
{ "cylrad", 0.075 },
35803605
{ "cylwid", 0.75 },
35813606
{ "dashwid", 0.05 },
3607
+ { "diamondht", 0.75 },
3608
+ { "diamondwid", 1.0 },
35823609
{ "dotrad", 0.015 },
35833610
{ "ellipseht", 0.5 },
35843611
{ "ellipsewid", 0.75 },
35853612
{ "fileht", 0.75 },
35863613
{ "filerad", 0.15 },
@@ -3957,10 +3984,65 @@
39573984
pik_append(p,"\" />\n", -1);
39583985
}
39593986
pik_append_txt(p, pObj, 0);
39603987
}
39613988
3989
+/* Methods for the "diamond" class */
3990
+static void diamondInit(Pik *p, PObj *pObj){
3991
+ pObj->w = pik_value(p, "diamondwid",10,0);
3992
+ pObj->h = pik_value(p, "diamondht",9,0);
3993
+ pObj->bAltAutoFit = 1;
3994
+}
3995
+/* Return offset from the center of the box to the compass point
3996
+** given by parameter cp */
3997
+static PPoint diamondOffset(Pik *p, PObj *pObj, int cp){
3998
+ PPoint pt = cZeroPoint;
3999
+ PNum w2 = 0.5*pObj->w;
4000
+ PNum w4 = 0.25*pObj->w;
4001
+ PNum h2 = 0.5*pObj->h;
4002
+ PNum h4 = 0.25*pObj->h;
4003
+ switch( cp ){
4004
+ case CP_C: break;
4005
+ case CP_N: pt.x = 0.0; pt.y = h2; break;
4006
+ case CP_NE: pt.x = w4; pt.y = h4; break;
4007
+ case CP_E: pt.x = w2; pt.y = 0.0; break;
4008
+ case CP_SE: pt.x = w4; pt.y = -h4; break;
4009
+ case CP_S: pt.x = 0.0; pt.y = -h2; break;
4010
+ case CP_SW: pt.x = -w4; pt.y = -h4; break;
4011
+ case CP_W: pt.x = -w2; pt.y = 0.0; break;
4012
+ case CP_NW: pt.x = -w4; pt.y = h4; break;
4013
+ default: assert(0);
4014
+ }
4015
+ UNUSED_PARAMETER(p);
4016
+ return pt;
4017
+}
4018
+static void diamondFit(Pik *p, PObj *pObj, PNum w, PNum h){
4019
+ if( pObj->w<=0 ) pObj->w = w*1.5;
4020
+ if( pObj->h<=0 ) pObj->h = h*1.5;
4021
+ if( pObj->w>0 && pObj->h>0 ){
4022
+ PNum x = pObj->w*h/pObj->h + w;
4023
+ PNum y = pObj->h*x/pObj->w;
4024
+ pObj->w = x;
4025
+ pObj->h = y;
4026
+ }
4027
+ UNUSED_PARAMETER(p);
4028
+}
4029
+static void diamondRender(Pik *p, PObj *pObj){
4030
+ PNum w2 = 0.5*pObj->w;
4031
+ PNum h2 = 0.5*pObj->h;
4032
+ PPoint pt = pObj->ptAt;
4033
+ if( pObj->sw>=0.0 ){
4034
+ pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y);
4035
+ pik_append_xy(p,"L", pt.x,pt.y-h2);
4036
+ pik_append_xy(p,"L", pt.x+w2,pt.y);
4037
+ pik_append_xy(p,"L", pt.x,pt.y+h2);
4038
+ pik_append(p,"Z\" ",-1);
4039
+ pik_append_style(p,pObj,3);
4040
+ pik_append(p,"\" />\n", -1);
4041
+ }
4042
+ pik_append_txt(p, pObj, 0);
4043
+}
39624044
39634045
39644046
/* Methods for the "ellipse" class */
39654047
static void ellipseInit(Pik *p, PObj *pObj){
39664048
pObj->w = pik_value(p, "ellipsewid",10,0);
@@ -4341,10 +4423,21 @@
43414423
/* xChop */ boxChop,
43424424
/* xOffset */ cylinderOffset,
43434425
/* xFit */ cylinderFit,
43444426
/* xRender */ cylinderRender
43454427
},
4428
+ { /* name */ "diamond",
4429
+ /* isline */ 0,
4430
+ /* eJust */ 0,
4431
+ /* xInit */ diamondInit,
4432
+ /* xNumProp */ 0,
4433
+ /* xCheck */ 0,
4434
+ /* xChop */ boxChop,
4435
+ /* xOffset */ diamondOffset,
4436
+ /* xFit */ diamondFit,
4437
+ /* xRender */ diamondRender
4438
+ },
43464439
{ /* name */ "dot",
43474440
/* isline */ 0,
43484441
/* eJust */ 0,
43494442
/* xInit */ dotInit,
43504443
/* xNumProp */ dotNumProp,
@@ -6269,12 +6362,16 @@
62696362
}
62706363
if( pObj->type->xFit==0 ) return;
62716364
pik_bbox_init(&bbox);
62726365
pik_compute_layout_settings(p);
62736366
pik_append_txt(p, pObj, &bbox);
6274
- w = (eWhich & 1)!=0 ? (bbox.ne.x - bbox.sw.x) + p->charWidth : 0;
6275
- if( eWhich & 2 ){
6367
+ if( (eWhich & 1)!=0 || pObj->bAltAutoFit ){
6368
+ w = (bbox.ne.x - bbox.sw.x) + p->charWidth;
6369
+ }else{
6370
+ w = 0;
6371
+ }
6372
+ if( (eWhich & 2)!=0 || pObj->bAltAutoFit ){
62766373
PNum h1, h2;
62776374
h1 = (bbox.ne.y - pObj->ptAt.y);
62786375
h2 = (pObj->ptAt.y - bbox.sw.y);
62796376
h = 2.0*( h1<h2 ? h2 : h1 ) + 0.5*p->charHeight;
62806377
}else{
@@ -8143,6 +8240,6 @@
81438240
81448241
81458242
#endif /* PIKCHR_TCL */
81468243
81478244
8148
-#line 8173 "pikchr.c"
8245
+#line 8270 "pikchr.c"
81498246
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -1,7 +1,8 @@
1 /* This file is automatically generated by Lemon from input grammar
2 ** source file "pikchr.y". */
 
3 /*
4 ** Zero-Clause BSD license:
5 **
6 ** Copyright (C) 2020-09-01 by D. Richard Hipp <[email protected]>
7 **
@@ -319,10 +320,11 @@
319 char cw; /* True for clockwise arc */
320 char larrow; /* Arrow at beginning (<- or <->) */
321 char rarrow; /* Arrow at end (-> or <->) */
322 char bClose; /* True if "close" is seen */
323 char bChop; /* True if "chop" is seen */
 
324 unsigned char nTxt; /* Number of text values */
325 unsigned mProp; /* Masks of properties set so far */
326 unsigned mCalc; /* Values computed from other constraints */
327 PToken aTxt[5]; /* Text with .eCode holding TP flags */
328 int iLayer; /* Rendering order */
@@ -490,11 +492,11 @@
490 static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
491 static PNum pik_dist(PPoint*,PPoint*);
492 static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
493
494
495 #line 521 "pikchr.c"
496 /**************** End of %include directives **********************************/
497 /* These constants specify the various numeric values for terminal symbols.
498 ***************** Begin token definitions *************************************/
499 #ifndef T_ID
500 #define T_ID 1
@@ -634,10 +636,13 @@
634 ** pik_parserARG_PDECL A parameter declaration for the %extra_argument
635 ** pik_parserARG_PARAM Code to pass %extra_argument as a subroutine parameter
636 ** pik_parserARG_STORE Code to store %extra_argument into yypParser
637 ** pik_parserARG_FETCH Code to extract %extra_argument from yypParser
638 ** pik_parserCTX_* As pik_parserARG_ except for %extra_context
 
 
 
639 ** YYERRORSYMBOL is the code number of the error symbol. If not
640 ** defined, then do no error processing.
641 ** YYNSTATE the combined number of states.
642 ** YYNRULE the number of rules in the grammar
643 ** YYNTOKEN Number of terminal symbols
@@ -647,10 +652,12 @@
647 ** YY_ERROR_ACTION The yy_action[] code for syntax error
648 ** YY_ACCEPT_ACTION The yy_action[] code for accept
649 ** YY_NO_ACTION The yy_action[] code for no-op
650 ** YY_MIN_REDUCE Minimum value for reduce actions
651 ** YY_MAX_REDUCE Maximum value for reduce actions
 
 
652 */
653 #ifndef INTERFACE
654 # define INTERFACE 1
655 #endif
656 /************* Begin control #defines *****************************************/
@@ -674,10 +681,13 @@
674 #define pik_parserARG_SDECL
675 #define pik_parserARG_PDECL
676 #define pik_parserARG_PARAM
677 #define pik_parserARG_FETCH
678 #define pik_parserARG_STORE
 
 
 
679 #define pik_parserCTX_SDECL Pik *p;
680 #define pik_parserCTX_PDECL ,Pik *p
681 #define pik_parserCTX_PARAM ,p
682 #define pik_parserCTX_FETCH Pik *p=yypParser->p;
683 #define pik_parserCTX_STORE yypParser->p=p;
@@ -692,10 +702,12 @@
692 #define YY_ERROR_ACTION 443
693 #define YY_ACCEPT_ACTION 444
694 #define YY_NO_ACTION 445
695 #define YY_MIN_REDUCE 446
696 #define YY_MAX_REDUCE 601
 
 
697 /************* End control #defines *******************************************/
698 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
699
700 /* Define the yytestcase() macro to be a no-op if is not already defined
701 ** otherwise.
@@ -706,10 +718,26 @@
706 ** for testing.
707 */
708 #ifndef yytestcase
709 # define yytestcase(X)
710 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
711
712
713 /* Next are the tables used to determine what action to take based on the
714 ** current state and lookahead token. These tables are used to implement
715 ** functions that take a state number and lookahead value and return an
@@ -1250,18 +1278,13 @@
1250 #ifndef YYNOERRORRECOVERY
1251 int yyerrcnt; /* Shifts left before out of the error */
1252 #endif
1253 pik_parserARG_SDECL /* A place to hold %extra_argument */
1254 pik_parserCTX_SDECL /* A place to hold %extra_context */
1255 #if YYSTACKDEPTH<=0
1256 int yystksz; /* Current side of the stack */
1257 yyStackEntry *yystack; /* The parser's stack */
1258 yyStackEntry yystk0; /* First stack entry */
1259 #else
1260 yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
1261 yyStackEntry *yystackEnd; /* Last entry in the stack */
1262 #endif
1263 };
1264 typedef struct yyParser yyParser;
1265
1266 #include <assert.h>
1267 #ifndef NDEBUG
@@ -1601,41 +1624,49 @@
1601 /* 155 */ "object ::= objectname",
1602 };
1603 #endif /* NDEBUG */
1604
1605
1606 #if YYSTACKDEPTH<=0
1607 /*
1608 ** Try to increase the size of the parser stack. Return the number
1609 ** of errors. Return 0 on success.
1610 */
1611 static int yyGrowStack(yyParser *p){
 
1612 int newSize;
1613 int idx;
1614 yyStackEntry *pNew;
1615
1616 newSize = p->yystksz*2 + 100;
1617 idx = p->yytos ? (int)(p->yytos - p->yystack) : 0;
1618 if( p->yystack==&p->yystk0 ){
1619 pNew = malloc(newSize*sizeof(pNew[0]));
1620 if( pNew ) pNew[0] = p->yystk0;
 
1621 }else{
1622 pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
 
1623 }
1624 if( pNew ){
1625 p->yystack = pNew;
1626 p->yytos = &p->yystack[idx];
1627 #ifndef NDEBUG
1628 if( yyTraceFILE ){
1629 fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
1630 yyTracePrompt, p->yystksz, newSize);
1631 }
1632 #endif
1633 p->yystksz = newSize;
1634 }
1635 return pNew==0;
1636 }
 
 
 
 
 
 
 
1637 #endif
1638
1639 /* Datatype of the argument to the memory allocated passed as the
1640 ** second argument to pik_parserAlloc() below. This can be changed by
1641 ** putting an appropriate #define in the %include section of the input
@@ -1651,28 +1682,18 @@
1651 yyParser *yypParser = (yyParser*)yypRawParser;
1652 pik_parserCTX_STORE
1653 #ifdef YYTRACKMAXSTACKDEPTH
1654 yypParser->yyhwm = 0;
1655 #endif
1656 #if YYSTACKDEPTH<=0
1657 yypParser->yytos = NULL;
1658 yypParser->yystack = NULL;
1659 yypParser->yystksz = 0;
1660 if( yyGrowStack(yypParser) ){
1661 yypParser->yystack = &yypParser->yystk0;
1662 yypParser->yystksz = 1;
1663 }
1664 #endif
1665 #ifndef YYNOERRORRECOVERY
1666 yypParser->yyerrcnt = -1;
1667 #endif
1668 yypParser->yytos = yypParser->yystack;
1669 yypParser->yystack[0].stateno = 0;
1670 yypParser->yystack[0].major = 0;
1671 #if YYSTACKDEPTH>0
1672 yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
1673 #endif
1674 }
1675
1676 #ifndef pik_parser_ENGINEALWAYSONSTACK
1677 /*
1678 ** This function allocates a new parser.
@@ -1724,22 +1745,22 @@
1724 ** inside the C code.
1725 */
1726 /********* Begin destructor definitions ***************************************/
1727 case 100: /* statement_list */
1728 {
1729 #line 510 "pikchr.y"
1730 pik_elist_free(p,(yypminor->yy235));
1731 #line 1756 "pikchr.c"
1732 }
1733 break;
1734 case 101: /* statement */
1735 case 102: /* unnamed_statement */
1736 case 103: /* basetype */
1737 {
1738 #line 512 "pikchr.y"
1739 pik_elem_free(p,(yypminor->yy162));
1740 #line 1765 "pikchr.c"
1741 }
1742 break;
1743 /********* End destructor definitions *****************************************/
1744 default: break; /* If no destructor action specified: do nothing */
1745 }
@@ -1769,13 +1790,30 @@
1769 /*
1770 ** Clear all secondary memory allocations from the parser
1771 */
1772 void pik_parserFinalize(void *p){
1773 yyParser *pParser = (yyParser*)p;
1774 while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
1775 #if YYSTACKDEPTH<=0
1776 if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1777 #endif
1778 }
1779
1780 #ifndef pik_parser_ENGINEALWAYSONSTACK
1781 /*
@@ -1953,14 +1991,14 @@
1953 #endif
1954 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1955 /* Here code is inserted which will execute if the parser
1956 ** stack every overflows */
1957 /******** Begin %stack_overflow code ******************************************/
1958 #line 544 "pikchr.y"
1959
1960 pik_error(p, 0, "parser stack overflow");
1961 #line 1986 "pikchr.c"
1962 /******** End %stack_overflow code ********************************************/
1963 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
1964 pik_parserCTX_STORE
1965 }
1966
@@ -2000,29 +2038,23 @@
2000 if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
2001 yypParser->yyhwm++;
2002 assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
2003 }
2004 #endif
2005 #if YYSTACKDEPTH>0
2006 if( yypParser->yytos>yypParser->yystackEnd ){
2007 yypParser->yytos--;
2008 yyStackOverflow(yypParser);
2009 return;
2010 }
2011 #else
2012 if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
2013 if( yyGrowStack(yypParser) ){
2014 yypParser->yytos--;
2015 yyStackOverflow(yypParser);
2016 return;
2017 }
 
 
2018 }
2019 #endif
2020 if( yyNewState > YY_MAX_SHIFT ){
2021 yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
2022 }
2023 yytos = yypParser->yytos;
2024 yytos->stateno = yyNewState;
2025 yytos->major = yyMajor;
2026 yytos->minor.yy0 = yyMinor;
2027 yyTraceShift(yypParser, yyNewState, "Shift");
2028 }
@@ -2387,619 +2419,619 @@
2387 ** break;
2388 */
2389 /********** Begin reduce actions **********************************************/
2390 YYMINORTYPE yylhsminor;
2391 case 0: /* document ::= statement_list */
2392 #line 548 "pikchr.y"
2393 {pik_render(p,yymsp[0].minor.yy235);}
2394 #line 2419 "pikchr.c"
2395 break;
2396 case 1: /* statement_list ::= statement */
2397 #line 551 "pikchr.y"
2398 { yylhsminor.yy235 = pik_elist_append(p,0,yymsp[0].minor.yy162); }
2399 #line 2424 "pikchr.c"
2400 yymsp[0].minor.yy235 = yylhsminor.yy235;
2401 break;
2402 case 2: /* statement_list ::= statement_list EOL statement */
2403 #line 553 "pikchr.y"
2404 { yylhsminor.yy235 = pik_elist_append(p,yymsp[-2].minor.yy235,yymsp[0].minor.yy162); }
2405 #line 2430 "pikchr.c"
2406 yymsp[-2].minor.yy235 = yylhsminor.yy235;
2407 break;
2408 case 3: /* statement ::= */
2409 #line 556 "pikchr.y"
2410 { yymsp[1].minor.yy162 = 0; }
2411 #line 2436 "pikchr.c"
2412 break;
2413 case 4: /* statement ::= direction */
2414 #line 557 "pikchr.y"
2415 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy162=0; }
2416 #line 2441 "pikchr.c"
2417 yymsp[0].minor.yy162 = yylhsminor.yy162;
2418 break;
2419 case 5: /* statement ::= lvalue ASSIGN rvalue */
2420 #line 558 "pikchr.y"
2421 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy21,&yymsp[-1].minor.yy0); yylhsminor.yy162=0;}
2422 #line 2447 "pikchr.c"
2423 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2424 break;
2425 case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2426 #line 560 "pikchr.y"
2427 { yylhsminor.yy162 = yymsp[0].minor.yy162; pik_elem_setname(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0); }
2428 #line 2453 "pikchr.c"
2429 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2430 break;
2431 case 7: /* statement ::= PLACENAME COLON position */
2432 #line 562 "pikchr.y"
2433 { yylhsminor.yy162 = pik_elem_new(p,0,0,0);
2434 if(yylhsminor.yy162){ yylhsminor.yy162->ptAt = yymsp[0].minor.yy63; pik_elem_setname(p,yylhsminor.yy162,&yymsp[-2].minor.yy0); }}
2435 #line 2460 "pikchr.c"
2436 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2437 break;
2438 case 8: /* statement ::= unnamed_statement */
2439 #line 564 "pikchr.y"
2440 {yylhsminor.yy162 = yymsp[0].minor.yy162;}
2441 #line 2466 "pikchr.c"
2442 yymsp[0].minor.yy162 = yylhsminor.yy162;
2443 break;
2444 case 9: /* statement ::= print prlist */
2445 #line 565 "pikchr.y"
2446 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy162=0;}
2447 #line 2472 "pikchr.c"
2448 break;
2449 case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2450 #line 570 "pikchr.y"
2451 {yymsp[-5].minor.yy162=pik_assert(p,yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy21);}
2452 #line 2477 "pikchr.c"
2453 break;
2454 case 11: /* statement ::= ASSERT LP position EQ position RP */
2455 #line 572 "pikchr.y"
2456 {yymsp[-5].minor.yy162=pik_position_assert(p,&yymsp[-3].minor.yy63,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy63);}
2457 #line 2482 "pikchr.c"
2458 break;
2459 case 12: /* statement ::= DEFINE ID CODEBLOCK */
2460 #line 573 "pikchr.y"
2461 {yymsp[-2].minor.yy162=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2462 #line 2487 "pikchr.c"
2463 break;
2464 case 13: /* rvalue ::= PLACENAME */
2465 #line 584 "pikchr.y"
2466 {yylhsminor.yy21 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2467 #line 2492 "pikchr.c"
2468 yymsp[0].minor.yy21 = yylhsminor.yy21;
2469 break;
2470 case 14: /* pritem ::= FILL */
2471 case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
2472 case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2473 #line 589 "pikchr.y"
2474 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2475 #line 2500 "pikchr.c"
2476 break;
2477 case 17: /* pritem ::= rvalue */
2478 #line 592 "pikchr.y"
2479 {pik_append_num(p,"",yymsp[0].minor.yy21);}
2480 #line 2505 "pikchr.c"
2481 break;
2482 case 18: /* pritem ::= STRING */
2483 #line 593 "pikchr.y"
2484 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2485 #line 2510 "pikchr.c"
2486 break;
2487 case 19: /* prsep ::= COMMA */
2488 #line 594 "pikchr.y"
2489 {pik_append(p, " ", 1);}
2490 #line 2515 "pikchr.c"
2491 break;
2492 case 20: /* unnamed_statement ::= basetype attribute_list */
2493 #line 597 "pikchr.y"
2494 {yylhsminor.yy162 = yymsp[-1].minor.yy162; pik_after_adding_attributes(p,yylhsminor.yy162);}
2495 #line 2520 "pikchr.c"
2496 yymsp[-1].minor.yy162 = yylhsminor.yy162;
2497 break;
2498 case 21: /* basetype ::= CLASSNAME */
2499 #line 599 "pikchr.y"
2500 {yylhsminor.yy162 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2501 #line 2526 "pikchr.c"
2502 yymsp[0].minor.yy162 = yylhsminor.yy162;
2503 break;
2504 case 22: /* basetype ::= STRING textposition */
2505 #line 601 "pikchr.y"
2506 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy188; yylhsminor.yy162 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2507 #line 2532 "pikchr.c"
2508 yymsp[-1].minor.yy162 = yylhsminor.yy162;
2509 break;
2510 case 23: /* basetype ::= LB savelist statement_list RB */
2511 #line 603 "pikchr.y"
2512 { p->list = yymsp[-2].minor.yy235; yymsp[-3].minor.yy162 = pik_elem_new(p,0,0,yymsp[-1].minor.yy235); if(yymsp[-3].minor.yy162) yymsp[-3].minor.yy162->errTok = yymsp[0].minor.yy0; }
2513 #line 2538 "pikchr.c"
2514 break;
2515 case 24: /* savelist ::= */
2516 #line 608 "pikchr.y"
2517 {yymsp[1].minor.yy235 = p->list; p->list = 0;}
2518 #line 2543 "pikchr.c"
2519 break;
2520 case 25: /* relexpr ::= expr */
2521 #line 615 "pikchr.y"
2522 {yylhsminor.yy72.rAbs = yymsp[0].minor.yy21; yylhsminor.yy72.rRel = 0;}
2523 #line 2548 "pikchr.c"
2524 yymsp[0].minor.yy72 = yylhsminor.yy72;
2525 break;
2526 case 26: /* relexpr ::= expr PERCENT */
2527 #line 616 "pikchr.y"
2528 {yylhsminor.yy72.rAbs = 0; yylhsminor.yy72.rRel = yymsp[-1].minor.yy21/100;}
2529 #line 2554 "pikchr.c"
2530 yymsp[-1].minor.yy72 = yylhsminor.yy72;
2531 break;
2532 case 27: /* optrelexpr ::= */
2533 #line 618 "pikchr.y"
2534 {yymsp[1].minor.yy72.rAbs = 0; yymsp[1].minor.yy72.rRel = 1.0;}
2535 #line 2560 "pikchr.c"
2536 break;
2537 case 28: /* attribute_list ::= relexpr alist */
2538 #line 620 "pikchr.y"
2539 {pik_add_direction(p,0,&yymsp[-1].minor.yy72);}
2540 #line 2565 "pikchr.c"
2541 break;
2542 case 29: /* attribute ::= numproperty relexpr */
2543 #line 624 "pikchr.y"
2544 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72); }
2545 #line 2570 "pikchr.c"
2546 break;
2547 case 30: /* attribute ::= dashproperty expr */
2548 #line 625 "pikchr.y"
2549 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy21); }
2550 #line 2575 "pikchr.c"
2551 break;
2552 case 31: /* attribute ::= dashproperty */
2553 #line 626 "pikchr.y"
2554 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2555 #line 2580 "pikchr.c"
2556 break;
2557 case 32: /* attribute ::= colorproperty rvalue */
2558 #line 627 "pikchr.y"
2559 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21); }
2560 #line 2585 "pikchr.c"
2561 break;
2562 case 33: /* attribute ::= go direction optrelexpr */
2563 #line 628 "pikchr.y"
2564 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72);}
2565 #line 2590 "pikchr.c"
2566 break;
2567 case 34: /* attribute ::= go direction even position */
2568 #line 629 "pikchr.y"
2569 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63);}
2570 #line 2595 "pikchr.c"
2571 break;
2572 case 35: /* attribute ::= CLOSE */
2573 #line 630 "pikchr.y"
2574 { pik_close_path(p,&yymsp[0].minor.yy0); }
2575 #line 2600 "pikchr.c"
2576 break;
2577 case 36: /* attribute ::= CHOP */
2578 #line 631 "pikchr.y"
2579 { p->cur->bChop = 1; }
2580 #line 2605 "pikchr.c"
2581 break;
2582 case 37: /* attribute ::= FROM position */
2583 #line 632 "pikchr.y"
2584 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2585 #line 2610 "pikchr.c"
2586 break;
2587 case 38: /* attribute ::= TO position */
2588 #line 633 "pikchr.y"
2589 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2590 #line 2615 "pikchr.c"
2591 break;
2592 case 39: /* attribute ::= THEN */
2593 #line 634 "pikchr.y"
2594 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2595 #line 2620 "pikchr.c"
2596 break;
2597 case 40: /* attribute ::= THEN optrelexpr HEADING expr */
2598 case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2599 #line 636 "pikchr.y"
2600 {pik_move_hdg(p,&yymsp[-2].minor.yy72,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21,0,&yymsp[-3].minor.yy0);}
2601 #line 2626 "pikchr.c"
2602 break;
2603 case 41: /* attribute ::= THEN optrelexpr EDGEPT */
2604 case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2605 #line 637 "pikchr.y"
2606 {pik_move_hdg(p,&yymsp[-1].minor.yy72,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2607 #line 2632 "pikchr.c"
2608 break;
2609 case 44: /* attribute ::= AT position */
2610 #line 642 "pikchr.y"
2611 { pik_set_at(p,0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2612 #line 2637 "pikchr.c"
2613 break;
2614 case 45: /* attribute ::= SAME */
2615 #line 644 "pikchr.y"
2616 {pik_same(p,0,&yymsp[0].minor.yy0);}
2617 #line 2642 "pikchr.c"
2618 break;
2619 case 46: /* attribute ::= SAME AS object */
2620 #line 645 "pikchr.y"
2621 {pik_same(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2622 #line 2647 "pikchr.c"
2623 break;
2624 case 47: /* attribute ::= STRING textposition */
2625 #line 646 "pikchr.y"
2626 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy188);}
2627 #line 2652 "pikchr.c"
2628 break;
2629 case 48: /* attribute ::= FIT */
2630 #line 647 "pikchr.y"
2631 {pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2632 #line 2657 "pikchr.c"
2633 break;
2634 case 49: /* attribute ::= BEHIND object */
2635 #line 648 "pikchr.y"
2636 {pik_behind(p,yymsp[0].minor.yy162);}
2637 #line 2662 "pikchr.c"
2638 break;
2639 case 50: /* withclause ::= DOT_E edge AT position */
2640 case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2641 #line 656 "pikchr.y"
2642 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2643 #line 2668 "pikchr.c"
2644 break;
2645 case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2646 #line 660 "pikchr.y"
2647 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2648 #line 2673 "pikchr.c"
2649 yymsp[0].minor.yy0 = yylhsminor.yy0;
2650 break;
2651 case 53: /* boolproperty ::= CW */
2652 #line 671 "pikchr.y"
2653 {p->cur->cw = 1;}
2654 #line 2679 "pikchr.c"
2655 break;
2656 case 54: /* boolproperty ::= CCW */
2657 #line 672 "pikchr.y"
2658 {p->cur->cw = 0;}
2659 #line 2684 "pikchr.c"
2660 break;
2661 case 55: /* boolproperty ::= LARROW */
2662 #line 673 "pikchr.y"
2663 {p->cur->larrow=1; p->cur->rarrow=0; }
2664 #line 2689 "pikchr.c"
2665 break;
2666 case 56: /* boolproperty ::= RARROW */
2667 #line 674 "pikchr.y"
2668 {p->cur->larrow=0; p->cur->rarrow=1; }
2669 #line 2694 "pikchr.c"
2670 break;
2671 case 57: /* boolproperty ::= LRARROW */
2672 #line 675 "pikchr.y"
2673 {p->cur->larrow=1; p->cur->rarrow=1; }
2674 #line 2699 "pikchr.c"
2675 break;
2676 case 58: /* boolproperty ::= INVIS */
2677 #line 676 "pikchr.y"
2678 {p->cur->sw = -0.00001;}
2679 #line 2704 "pikchr.c"
2680 break;
2681 case 59: /* boolproperty ::= THICK */
2682 #line 677 "pikchr.y"
2683 {p->cur->sw *= 1.5;}
2684 #line 2709 "pikchr.c"
2685 break;
2686 case 60: /* boolproperty ::= THIN */
2687 #line 678 "pikchr.y"
2688 {p->cur->sw *= 0.67;}
2689 #line 2714 "pikchr.c"
2690 break;
2691 case 61: /* boolproperty ::= SOLID */
2692 #line 679 "pikchr.y"
2693 {p->cur->sw = pik_value(p,"thickness",9,0);
2694 p->cur->dotted = p->cur->dashed = 0.0;}
2695 #line 2720 "pikchr.c"
2696 break;
2697 case 62: /* textposition ::= */
2698 #line 682 "pikchr.y"
2699 {yymsp[1].minor.yy188 = 0;}
2700 #line 2725 "pikchr.c"
2701 break;
2702 case 63: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|MONO|ALIGNED|BIG|SMALL */
2703 #line 685 "pikchr.y"
2704 {yylhsminor.yy188 = (short int)pik_text_position(yymsp[-1].minor.yy188,&yymsp[0].minor.yy0);}
2705 #line 2730 "pikchr.c"
2706 yymsp[-1].minor.yy188 = yylhsminor.yy188;
2707 break;
2708 case 64: /* position ::= expr COMMA expr */
2709 #line 688 "pikchr.y"
2710 {yylhsminor.yy63.x=yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[0].minor.yy21;}
2711 #line 2736 "pikchr.c"
2712 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2713 break;
2714 case 65: /* position ::= place PLUS expr COMMA expr */
2715 #line 690 "pikchr.y"
2716 {yylhsminor.yy63.x=yymsp[-4].minor.yy63.x+yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[-4].minor.yy63.y+yymsp[0].minor.yy21;}
2717 #line 2742 "pikchr.c"
2718 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2719 break;
2720 case 66: /* position ::= place MINUS expr COMMA expr */
2721 #line 691 "pikchr.y"
2722 {yylhsminor.yy63.x=yymsp[-4].minor.yy63.x-yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[-4].minor.yy63.y-yymsp[0].minor.yy21;}
2723 #line 2748 "pikchr.c"
2724 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2725 break;
2726 case 67: /* position ::= place PLUS LP expr COMMA expr RP */
2727 #line 693 "pikchr.y"
2728 {yylhsminor.yy63.x=yymsp[-6].minor.yy63.x+yymsp[-3].minor.yy21; yylhsminor.yy63.y=yymsp[-6].minor.yy63.y+yymsp[-1].minor.yy21;}
2729 #line 2754 "pikchr.c"
2730 yymsp[-6].minor.yy63 = yylhsminor.yy63;
2731 break;
2732 case 68: /* position ::= place MINUS LP expr COMMA expr RP */
2733 #line 695 "pikchr.y"
2734 {yylhsminor.yy63.x=yymsp[-6].minor.yy63.x-yymsp[-3].minor.yy21; yylhsminor.yy63.y=yymsp[-6].minor.yy63.y-yymsp[-1].minor.yy21;}
2735 #line 2760 "pikchr.c"
2736 yymsp[-6].minor.yy63 = yylhsminor.yy63;
2737 break;
2738 case 69: /* position ::= LP position COMMA position RP */
2739 #line 696 "pikchr.y"
2740 {yymsp[-4].minor.yy63.x=yymsp[-3].minor.yy63.x; yymsp[-4].minor.yy63.y=yymsp[-1].minor.yy63.y;}
2741 #line 2766 "pikchr.c"
2742 break;
2743 case 70: /* position ::= LP position RP */
2744 #line 697 "pikchr.y"
2745 {yymsp[-2].minor.yy63=yymsp[-1].minor.yy63;}
2746 #line 2771 "pikchr.c"
2747 break;
2748 case 71: /* position ::= expr between position AND position */
2749 #line 699 "pikchr.y"
2750 {yylhsminor.yy63 = pik_position_between(yymsp[-4].minor.yy21,yymsp[-2].minor.yy63,yymsp[0].minor.yy63);}
2751 #line 2776 "pikchr.c"
2752 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2753 break;
2754 case 72: /* position ::= expr LT position COMMA position GT */
2755 #line 701 "pikchr.y"
2756 {yylhsminor.yy63 = pik_position_between(yymsp[-5].minor.yy21,yymsp[-3].minor.yy63,yymsp[-1].minor.yy63);}
2757 #line 2782 "pikchr.c"
2758 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2759 break;
2760 case 73: /* position ::= expr ABOVE position */
2761 #line 702 "pikchr.y"
2762 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y += yymsp[-2].minor.yy21;}
2763 #line 2788 "pikchr.c"
2764 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2765 break;
2766 case 74: /* position ::= expr BELOW position */
2767 #line 703 "pikchr.y"
2768 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y -= yymsp[-2].minor.yy21;}
2769 #line 2794 "pikchr.c"
2770 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2771 break;
2772 case 75: /* position ::= expr LEFT OF position */
2773 #line 704 "pikchr.y"
2774 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x -= yymsp[-3].minor.yy21;}
2775 #line 2800 "pikchr.c"
2776 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2777 break;
2778 case 76: /* position ::= expr RIGHT OF position */
2779 #line 705 "pikchr.y"
2780 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x += yymsp[-3].minor.yy21;}
2781 #line 2806 "pikchr.c"
2782 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2783 break;
2784 case 77: /* position ::= expr ON HEADING EDGEPT OF position */
2785 #line 707 "pikchr.y"
2786 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-5].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2787 #line 2812 "pikchr.c"
2788 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2789 break;
2790 case 78: /* position ::= expr HEADING EDGEPT OF position */
2791 #line 709 "pikchr.y"
2792 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-4].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2793 #line 2818 "pikchr.c"
2794 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2795 break;
2796 case 79: /* position ::= expr EDGEPT OF position */
2797 #line 711 "pikchr.y"
2798 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2799 #line 2824 "pikchr.c"
2800 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2801 break;
2802 case 80: /* position ::= expr ON HEADING expr FROM position */
2803 #line 713 "pikchr.y"
2804 {yylhsminor.yy63 = pik_position_at_angle(yymsp[-5].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2805 #line 2830 "pikchr.c"
2806 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2807 break;
2808 case 81: /* position ::= expr HEADING expr FROM position */
2809 #line 715 "pikchr.y"
2810 {yylhsminor.yy63 = pik_position_at_angle(yymsp[-4].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2811 #line 2836 "pikchr.c"
2812 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2813 break;
2814 case 82: /* place ::= edge OF object */
2815 #line 727 "pikchr.y"
2816 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2817 #line 2842 "pikchr.c"
2818 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2819 break;
2820 case 83: /* place2 ::= object */
2821 #line 728 "pikchr.y"
2822 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,0);}
2823 #line 2848 "pikchr.c"
2824 yymsp[0].minor.yy63 = yylhsminor.yy63;
2825 break;
2826 case 84: /* place2 ::= object DOT_E edge */
2827 #line 729 "pikchr.y"
2828 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2829 #line 2854 "pikchr.c"
2830 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2831 break;
2832 case 85: /* place2 ::= NTH VERTEX OF object */
2833 #line 730 "pikchr.y"
2834 {yylhsminor.yy63 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy162);}
2835 #line 2860 "pikchr.c"
2836 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2837 break;
2838 case 86: /* object ::= nth */
2839 #line 742 "pikchr.y"
2840 {yylhsminor.yy162 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2841 #line 2866 "pikchr.c"
2842 yymsp[0].minor.yy162 = yylhsminor.yy162;
2843 break;
2844 case 87: /* object ::= nth OF|IN object */
2845 #line 743 "pikchr.y"
2846 {yylhsminor.yy162 = pik_find_nth(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2847 #line 2872 "pikchr.c"
2848 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2849 break;
2850 case 88: /* objectname ::= THIS */
2851 #line 745 "pikchr.y"
2852 {yymsp[0].minor.yy162 = p->cur;}
2853 #line 2878 "pikchr.c"
2854 break;
2855 case 89: /* objectname ::= PLACENAME */
2856 #line 746 "pikchr.y"
2857 {yylhsminor.yy162 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2858 #line 2883 "pikchr.c"
2859 yymsp[0].minor.yy162 = yylhsminor.yy162;
2860 break;
2861 case 90: /* objectname ::= objectname DOT_U PLACENAME */
2862 #line 748 "pikchr.y"
2863 {yylhsminor.yy162 = pik_find_byname(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2864 #line 2889 "pikchr.c"
2865 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2866 break;
2867 case 91: /* nth ::= NTH CLASSNAME */
2868 #line 750 "pikchr.y"
2869 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2870 #line 2895 "pikchr.c"
2871 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2872 break;
2873 case 92: /* nth ::= NTH LAST CLASSNAME */
2874 #line 751 "pikchr.y"
2875 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2876 #line 2901 "pikchr.c"
2877 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2878 break;
2879 case 93: /* nth ::= LAST CLASSNAME */
2880 #line 752 "pikchr.y"
2881 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2882 #line 2907 "pikchr.c"
2883 break;
2884 case 94: /* nth ::= LAST */
2885 #line 753 "pikchr.y"
2886 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2887 #line 2912 "pikchr.c"
2888 yymsp[0].minor.yy0 = yylhsminor.yy0;
2889 break;
2890 case 95: /* nth ::= NTH LB RB */
2891 #line 754 "pikchr.y"
2892 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2893 #line 2918 "pikchr.c"
2894 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2895 break;
2896 case 96: /* nth ::= NTH LAST LB RB */
2897 #line 755 "pikchr.y"
2898 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2899 #line 2924 "pikchr.c"
2900 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2901 break;
2902 case 97: /* nth ::= LAST LB RB */
2903 #line 756 "pikchr.y"
2904 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2905 #line 2930 "pikchr.c"
2906 break;
2907 case 98: /* expr ::= expr PLUS expr */
2908 #line 758 "pikchr.y"
2909 {yylhsminor.yy21=yymsp[-2].minor.yy21+yymsp[0].minor.yy21;}
2910 #line 2935 "pikchr.c"
2911 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2912 break;
2913 case 99: /* expr ::= expr MINUS expr */
2914 #line 759 "pikchr.y"
2915 {yylhsminor.yy21=yymsp[-2].minor.yy21-yymsp[0].minor.yy21;}
2916 #line 2941 "pikchr.c"
2917 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2918 break;
2919 case 100: /* expr ::= expr STAR expr */
2920 #line 760 "pikchr.y"
2921 {yylhsminor.yy21=yymsp[-2].minor.yy21*yymsp[0].minor.yy21;}
2922 #line 2947 "pikchr.c"
2923 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2924 break;
2925 case 101: /* expr ::= expr SLASH expr */
2926 #line 761 "pikchr.y"
2927 {
2928 if( yymsp[0].minor.yy21==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy21 = 0.0; }
2929 else{ yylhsminor.yy21 = yymsp[-2].minor.yy21/yymsp[0].minor.yy21; }
2930 }
2931 #line 2956 "pikchr.c"
2932 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2933 break;
2934 case 102: /* expr ::= MINUS expr */
2935 #line 765 "pikchr.y"
2936 {yymsp[-1].minor.yy21=-yymsp[0].minor.yy21;}
2937 #line 2962 "pikchr.c"
2938 break;
2939 case 103: /* expr ::= PLUS expr */
2940 #line 766 "pikchr.y"
2941 {yymsp[-1].minor.yy21=yymsp[0].minor.yy21;}
2942 #line 2967 "pikchr.c"
2943 break;
2944 case 104: /* expr ::= LP expr RP */
2945 #line 767 "pikchr.y"
2946 {yymsp[-2].minor.yy21=yymsp[-1].minor.yy21;}
2947 #line 2972 "pikchr.c"
2948 break;
2949 case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2950 #line 768 "pikchr.y"
2951 {yymsp[-2].minor.yy21=pik_get_var(p,&yymsp[-1].minor.yy0);}
2952 #line 2977 "pikchr.c"
2953 break;
2954 case 106: /* expr ::= NUMBER */
2955 #line 769 "pikchr.y"
2956 {yylhsminor.yy21=pik_atof(&yymsp[0].minor.yy0);}
2957 #line 2982 "pikchr.c"
2958 yymsp[0].minor.yy21 = yylhsminor.yy21;
2959 break;
2960 case 107: /* expr ::= ID */
2961 #line 770 "pikchr.y"
2962 {yylhsminor.yy21=pik_get_var(p,&yymsp[0].minor.yy0);}
2963 #line 2988 "pikchr.c"
2964 yymsp[0].minor.yy21 = yylhsminor.yy21;
2965 break;
2966 case 108: /* expr ::= FUNC1 LP expr RP */
2967 #line 771 "pikchr.y"
2968 {yylhsminor.yy21 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy21,0.0);}
2969 #line 2994 "pikchr.c"
2970 yymsp[-3].minor.yy21 = yylhsminor.yy21;
2971 break;
2972 case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */
2973 #line 772 "pikchr.y"
2974 {yylhsminor.yy21 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy21,yymsp[-1].minor.yy21);}
2975 #line 3000 "pikchr.c"
2976 yymsp[-5].minor.yy21 = yylhsminor.yy21;
2977 break;
2978 case 110: /* expr ::= DIST LP position COMMA position RP */
2979 #line 773 "pikchr.y"
2980 {yymsp[-5].minor.yy21 = pik_dist(&yymsp[-3].minor.yy63,&yymsp[-1].minor.yy63);}
2981 #line 3006 "pikchr.c"
2982 break;
2983 case 111: /* expr ::= place2 DOT_XY X */
2984 #line 774 "pikchr.y"
2985 {yylhsminor.yy21 = yymsp[-2].minor.yy63.x;}
2986 #line 3011 "pikchr.c"
2987 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2988 break;
2989 case 112: /* expr ::= place2 DOT_XY Y */
2990 #line 775 "pikchr.y"
2991 {yylhsminor.yy21 = yymsp[-2].minor.yy63.y;}
2992 #line 3017 "pikchr.c"
2993 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2994 break;
2995 case 113: /* expr ::= object DOT_L numproperty */
2996 case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114);
2997 case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115);
2998 #line 776 "pikchr.y"
2999 {yylhsminor.yy21=pik_property_of(yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
3000 #line 3025 "pikchr.c"
3001 yymsp[-2].minor.yy21 = yylhsminor.yy21;
3002 break;
3003 default:
3004 /* (116) lvalue ::= ID */ yytestcase(yyruleno==116);
3005 /* (117) lvalue ::= FILL */ yytestcase(yyruleno==117);
@@ -3098,19 +3130,19 @@
3098 ){
3099 pik_parserARG_FETCH
3100 pik_parserCTX_FETCH
3101 #define TOKEN yyminor
3102 /************ Begin %syntax_error code ****************************************/
3103 #line 536 "pikchr.y"
3104
3105 if( TOKEN.z && TOKEN.z[0] ){
3106 pik_error(p, &TOKEN, "syntax error");
3107 }else{
3108 pik_error(p, 0, "syntax error");
3109 }
3110 UNUSED_PARAMETER(yymajor);
3111 #line 3136 "pikchr.c"
3112 /************ End %syntax_error code ******************************************/
3113 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3114 pik_parserCTX_STORE
3115 }
3116
@@ -3227,23 +3259,16 @@
3227 yypParser->yyhwm++;
3228 assert( yypParser->yyhwm ==
3229 (int)(yypParser->yytos - yypParser->yystack));
3230 }
3231 #endif
3232 #if YYSTACKDEPTH>0
3233 if( yypParser->yytos>=yypParser->yystackEnd ){
3234 yyStackOverflow(yypParser);
3235 break;
3236 }
3237 #else
3238 if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
3239 if( yyGrowStack(yypParser) ){
3240 yyStackOverflow(yypParser);
3241 break;
3242 }
3243 }
3244 #endif
3245 }
3246 yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor pik_parserCTX_PARAM);
3247 }else if( yyact <= YY_MAX_SHIFTREDUCE ){
3248 yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
3249 #ifndef YYNOERRORRECOVERY
@@ -3382,11 +3407,11 @@
3382 #else
3383 (void)iToken;
3384 return 0;
3385 #endif
3386 }
3387 #line 781 "pikchr.y"
3388
3389
3390
3391 /* Chart of the 148 official CSS color names with their
3392 ** corresponding RGB values thru Color Module Level 4:
@@ -3577,10 +3602,12 @@
3577 { "color", 0.0 },
3578 { "cylht", 0.5 },
3579 { "cylrad", 0.075 },
3580 { "cylwid", 0.75 },
3581 { "dashwid", 0.05 },
 
 
3582 { "dotrad", 0.015 },
3583 { "ellipseht", 0.5 },
3584 { "ellipsewid", 0.75 },
3585 { "fileht", 0.75 },
3586 { "filerad", 0.15 },
@@ -3957,10 +3984,65 @@
3957 pik_append(p,"\" />\n", -1);
3958 }
3959 pik_append_txt(p, pObj, 0);
3960 }
3961
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3962
3963
3964 /* Methods for the "ellipse" class */
3965 static void ellipseInit(Pik *p, PObj *pObj){
3966 pObj->w = pik_value(p, "ellipsewid",10,0);
@@ -4341,10 +4423,21 @@
4341 /* xChop */ boxChop,
4342 /* xOffset */ cylinderOffset,
4343 /* xFit */ cylinderFit,
4344 /* xRender */ cylinderRender
4345 },
 
 
 
 
 
 
 
 
 
 
 
4346 { /* name */ "dot",
4347 /* isline */ 0,
4348 /* eJust */ 0,
4349 /* xInit */ dotInit,
4350 /* xNumProp */ dotNumProp,
@@ -6269,12 +6362,16 @@
6269 }
6270 if( pObj->type->xFit==0 ) return;
6271 pik_bbox_init(&bbox);
6272 pik_compute_layout_settings(p);
6273 pik_append_txt(p, pObj, &bbox);
6274 w = (eWhich & 1)!=0 ? (bbox.ne.x - bbox.sw.x) + p->charWidth : 0;
6275 if( eWhich & 2 ){
 
 
 
 
6276 PNum h1, h2;
6277 h1 = (bbox.ne.y - pObj->ptAt.y);
6278 h2 = (pObj->ptAt.y - bbox.sw.y);
6279 h = 2.0*( h1<h2 ? h2 : h1 ) + 0.5*p->charHeight;
6280 }else{
@@ -8143,6 +8240,6 @@
8143
8144
8145 #endif /* PIKCHR_TCL */
8146
8147
8148 #line 8173 "pikchr.c"
8149
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -1,7 +1,8 @@
1 /* This file is automatically generated by Lemon from input grammar
2 ** source file "pikchr.y".
3 */
4 /*
5 ** Zero-Clause BSD license:
6 **
7 ** Copyright (C) 2020-09-01 by D. Richard Hipp <[email protected]>
8 **
@@ -319,10 +320,11 @@
320 char cw; /* True for clockwise arc */
321 char larrow; /* Arrow at beginning (<- or <->) */
322 char rarrow; /* Arrow at end (-> or <->) */
323 char bClose; /* True if "close" is seen */
324 char bChop; /* True if "chop" is seen */
325 char bAltAutoFit; /* Always send both h and w into xFit() */
326 unsigned char nTxt; /* Number of text values */
327 unsigned mProp; /* Masks of properties set so far */
328 unsigned mCalc; /* Values computed from other constraints */
329 PToken aTxt[5]; /* Text with .eCode holding TP flags */
330 int iLayer; /* Rendering order */
@@ -490,11 +492,11 @@
492 static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
493 static PNum pik_dist(PPoint*,PPoint*);
494 static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
495
496
497 #line 523 "pikchr.c"
498 /**************** End of %include directives **********************************/
499 /* These constants specify the various numeric values for terminal symbols.
500 ***************** Begin token definitions *************************************/
501 #ifndef T_ID
502 #define T_ID 1
@@ -634,10 +636,13 @@
636 ** pik_parserARG_PDECL A parameter declaration for the %extra_argument
637 ** pik_parserARG_PARAM Code to pass %extra_argument as a subroutine parameter
638 ** pik_parserARG_STORE Code to store %extra_argument into yypParser
639 ** pik_parserARG_FETCH Code to extract %extra_argument from yypParser
640 ** pik_parserCTX_* As pik_parserARG_ except for %extra_context
641 ** YYREALLOC Name of the realloc() function to use
642 ** YYFREE Name of the free() function to use
643 ** YYDYNSTACK True if stack space should be extended on heap
644 ** YYERRORSYMBOL is the code number of the error symbol. If not
645 ** defined, then do no error processing.
646 ** YYNSTATE the combined number of states.
647 ** YYNRULE the number of rules in the grammar
648 ** YYNTOKEN Number of terminal symbols
@@ -647,10 +652,12 @@
652 ** YY_ERROR_ACTION The yy_action[] code for syntax error
653 ** YY_ACCEPT_ACTION The yy_action[] code for accept
654 ** YY_NO_ACTION The yy_action[] code for no-op
655 ** YY_MIN_REDUCE Minimum value for reduce actions
656 ** YY_MAX_REDUCE Maximum value for reduce actions
657 ** YY_MIN_DSTRCTR Minimum symbol value that has a destructor
658 ** YY_MAX_DSTRCTR Maximum symbol value that has a destructor
659 */
660 #ifndef INTERFACE
661 # define INTERFACE 1
662 #endif
663 /************* Begin control #defines *****************************************/
@@ -674,10 +681,13 @@
681 #define pik_parserARG_SDECL
682 #define pik_parserARG_PDECL
683 #define pik_parserARG_PARAM
684 #define pik_parserARG_FETCH
685 #define pik_parserARG_STORE
686 #define YYREALLOC realloc
687 #define YYFREE free
688 #define YYDYNSTACK 0
689 #define pik_parserCTX_SDECL Pik *p;
690 #define pik_parserCTX_PDECL ,Pik *p
691 #define pik_parserCTX_PARAM ,p
692 #define pik_parserCTX_FETCH Pik *p=yypParser->p;
693 #define pik_parserCTX_STORE yypParser->p=p;
@@ -692,10 +702,12 @@
702 #define YY_ERROR_ACTION 443
703 #define YY_ACCEPT_ACTION 444
704 #define YY_NO_ACTION 445
705 #define YY_MIN_REDUCE 446
706 #define YY_MAX_REDUCE 601
707 #define YY_MIN_DSTRCTR 100
708 #define YY_MAX_DSTRCTR 103
709 /************* End control #defines *******************************************/
710 #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))
711
712 /* Define the yytestcase() macro to be a no-op if is not already defined
713 ** otherwise.
@@ -706,10 +718,26 @@
718 ** for testing.
719 */
720 #ifndef yytestcase
721 # define yytestcase(X)
722 #endif
723
724 /* Macro to determine if stack space has the ability to grow using
725 ** heap memory.
726 */
727 #if YYSTACKDEPTH<=0 || YYDYNSTACK
728 # define YYGROWABLESTACK 1
729 #else
730 # define YYGROWABLESTACK 0
731 #endif
732
733 /* Guarantee a minimum number of initial stack slots.
734 */
735 #if YYSTACKDEPTH<=0
736 # undef YYSTACKDEPTH
737 # define YYSTACKDEPTH 2 /* Need a minimum stack size */
738 #endif
739
740
741 /* Next are the tables used to determine what action to take based on the
742 ** current state and lookahead token. These tables are used to implement
743 ** functions that take a state number and lookahead value and return an
@@ -1250,18 +1278,13 @@
1278 #ifndef YYNOERRORRECOVERY
1279 int yyerrcnt; /* Shifts left before out of the error */
1280 #endif
1281 pik_parserARG_SDECL /* A place to hold %extra_argument */
1282 pik_parserCTX_SDECL /* A place to hold %extra_context */
1283 yyStackEntry *yystackEnd; /* Last entry in the stack */
1284 yyStackEntry *yystack; /* The parser stack */
1285 yyStackEntry yystk0[YYSTACKDEPTH]; /* Initial stack space */
 
 
 
 
 
1286 };
1287 typedef struct yyParser yyParser;
1288
1289 #include <assert.h>
1290 #ifndef NDEBUG
@@ -1601,41 +1624,49 @@
1624 /* 155 */ "object ::= objectname",
1625 };
1626 #endif /* NDEBUG */
1627
1628
1629 #if YYGROWABLESTACK
1630 /*
1631 ** Try to increase the size of the parser stack. Return the number
1632 ** of errors. Return 0 on success.
1633 */
1634 static int yyGrowStack(yyParser *p){
1635 int oldSize = 1 + (int)(p->yystackEnd - p->yystack);
1636 int newSize;
1637 int idx;
1638 yyStackEntry *pNew;
1639
1640 newSize = oldSize*2 + 100;
1641 idx = (int)(p->yytos - p->yystack);
1642 if( p->yystack==p->yystk0 ){
1643 pNew = YYREALLOC(0, newSize*sizeof(pNew[0]));
1644 if( pNew==0 ) return 1;
1645 memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
1646 }else{
1647 pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]));
1648 if( pNew==0 ) return 1;
1649 }
1650 p->yystack = pNew;
1651 p->yytos = &p->yystack[idx];
 
1652 #ifndef NDEBUG
1653 if( yyTraceFILE ){
1654 fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
1655 yyTracePrompt, oldSize, newSize);
1656 }
1657 #endif
1658 p->yystackEnd = &p->yystack[newSize-1];
1659 return 0;
 
1660 }
1661 #endif /* YYGROWABLESTACK */
1662
1663 #if !YYGROWABLESTACK
1664 /* For builds that do no have a growable stack, yyGrowStack always
1665 ** returns an error.
1666 */
1667 # define yyGrowStack(X) 1
1668 #endif
1669
1670 /* Datatype of the argument to the memory allocated passed as the
1671 ** second argument to pik_parserAlloc() below. This can be changed by
1672 ** putting an appropriate #define in the %include section of the input
@@ -1651,28 +1682,18 @@
1682 yyParser *yypParser = (yyParser*)yypRawParser;
1683 pik_parserCTX_STORE
1684 #ifdef YYTRACKMAXSTACKDEPTH
1685 yypParser->yyhwm = 0;
1686 #endif
1687 yypParser->yystack = yypParser->yystk0;
1688 yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1];
 
 
 
 
 
 
 
1689 #ifndef YYNOERRORRECOVERY
1690 yypParser->yyerrcnt = -1;
1691 #endif
1692 yypParser->yytos = yypParser->yystack;
1693 yypParser->yystack[0].stateno = 0;
1694 yypParser->yystack[0].major = 0;
 
 
 
1695 }
1696
1697 #ifndef pik_parser_ENGINEALWAYSONSTACK
1698 /*
1699 ** This function allocates a new parser.
@@ -1724,22 +1745,22 @@
1745 ** inside the C code.
1746 */
1747 /********* Begin destructor definitions ***************************************/
1748 case 100: /* statement_list */
1749 {
1750 #line 511 "pikchr.y"
1751 pik_elist_free(p,(yypminor->yy235));
1752 #line 1777 "pikchr.c"
1753 }
1754 break;
1755 case 101: /* statement */
1756 case 102: /* unnamed_statement */
1757 case 103: /* basetype */
1758 {
1759 #line 513 "pikchr.y"
1760 pik_elem_free(p,(yypminor->yy162));
1761 #line 1786 "pikchr.c"
1762 }
1763 break;
1764 /********* End destructor definitions *****************************************/
1765 default: break; /* If no destructor action specified: do nothing */
1766 }
@@ -1769,13 +1790,30 @@
1790 /*
1791 ** Clear all secondary memory allocations from the parser
1792 */
1793 void pik_parserFinalize(void *p){
1794 yyParser *pParser = (yyParser*)p;
1795
1796 /* In-lined version of calling yy_pop_parser_stack() for each
1797 ** element left in the stack */
1798 yyStackEntry *yytos = pParser->yytos;
1799 while( yytos>pParser->yystack ){
1800 #ifndef NDEBUG
1801 if( yyTraceFILE ){
1802 fprintf(yyTraceFILE,"%sPopping %s\n",
1803 yyTracePrompt,
1804 yyTokenName[yytos->major]);
1805 }
1806 #endif
1807 if( yytos->major>=YY_MIN_DSTRCTR ){
1808 yy_destructor(pParser, yytos->major, &yytos->minor);
1809 }
1810 yytos--;
1811 }
1812
1813 #if YYGROWABLESTACK
1814 if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack);
1815 #endif
1816 }
1817
1818 #ifndef pik_parser_ENGINEALWAYSONSTACK
1819 /*
@@ -1953,14 +1991,14 @@
1991 #endif
1992 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
1993 /* Here code is inserted which will execute if the parser
1994 ** stack every overflows */
1995 /******** Begin %stack_overflow code ******************************************/
1996 #line 545 "pikchr.y"
1997
1998 pik_error(p, 0, "parser stack overflow");
1999 #line 2024 "pikchr.c"
2000 /******** End %stack_overflow code ********************************************/
2001 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
2002 pik_parserCTX_STORE
2003 }
2004
@@ -2000,29 +2038,23 @@
2038 if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
2039 yypParser->yyhwm++;
2040 assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) );
2041 }
2042 #endif
2043 yytos = yypParser->yytos;
2044 if( yytos>yypParser->yystackEnd ){
 
 
 
 
 
 
2045 if( yyGrowStack(yypParser) ){
2046 yypParser->yytos--;
2047 yyStackOverflow(yypParser);
2048 return;
2049 }
2050 yytos = yypParser->yytos;
2051 assert( yytos <= yypParser->yystackEnd );
2052 }
 
2053 if( yyNewState > YY_MAX_SHIFT ){
2054 yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
2055 }
 
2056 yytos->stateno = yyNewState;
2057 yytos->major = yyMajor;
2058 yytos->minor.yy0 = yyMinor;
2059 yyTraceShift(yypParser, yyNewState, "Shift");
2060 }
@@ -2387,619 +2419,619 @@
2419 ** break;
2420 */
2421 /********** Begin reduce actions **********************************************/
2422 YYMINORTYPE yylhsminor;
2423 case 0: /* document ::= statement_list */
2424 #line 549 "pikchr.y"
2425 {pik_render(p,yymsp[0].minor.yy235);}
2426 #line 2451 "pikchr.c"
2427 break;
2428 case 1: /* statement_list ::= statement */
2429 #line 552 "pikchr.y"
2430 { yylhsminor.yy235 = pik_elist_append(p,0,yymsp[0].minor.yy162); }
2431 #line 2456 "pikchr.c"
2432 yymsp[0].minor.yy235 = yylhsminor.yy235;
2433 break;
2434 case 2: /* statement_list ::= statement_list EOL statement */
2435 #line 554 "pikchr.y"
2436 { yylhsminor.yy235 = pik_elist_append(p,yymsp[-2].minor.yy235,yymsp[0].minor.yy162); }
2437 #line 2462 "pikchr.c"
2438 yymsp[-2].minor.yy235 = yylhsminor.yy235;
2439 break;
2440 case 3: /* statement ::= */
2441 #line 557 "pikchr.y"
2442 { yymsp[1].minor.yy162 = 0; }
2443 #line 2468 "pikchr.c"
2444 break;
2445 case 4: /* statement ::= direction */
2446 #line 558 "pikchr.y"
2447 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy162=0; }
2448 #line 2473 "pikchr.c"
2449 yymsp[0].minor.yy162 = yylhsminor.yy162;
2450 break;
2451 case 5: /* statement ::= lvalue ASSIGN rvalue */
2452 #line 559 "pikchr.y"
2453 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy21,&yymsp[-1].minor.yy0); yylhsminor.yy162=0;}
2454 #line 2479 "pikchr.c"
2455 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2456 break;
2457 case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2458 #line 561 "pikchr.y"
2459 { yylhsminor.yy162 = yymsp[0].minor.yy162; pik_elem_setname(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0); }
2460 #line 2485 "pikchr.c"
2461 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2462 break;
2463 case 7: /* statement ::= PLACENAME COLON position */
2464 #line 563 "pikchr.y"
2465 { yylhsminor.yy162 = pik_elem_new(p,0,0,0);
2466 if(yylhsminor.yy162){ yylhsminor.yy162->ptAt = yymsp[0].minor.yy63; pik_elem_setname(p,yylhsminor.yy162,&yymsp[-2].minor.yy0); }}
2467 #line 2492 "pikchr.c"
2468 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2469 break;
2470 case 8: /* statement ::= unnamed_statement */
2471 #line 565 "pikchr.y"
2472 {yylhsminor.yy162 = yymsp[0].minor.yy162;}
2473 #line 2498 "pikchr.c"
2474 yymsp[0].minor.yy162 = yylhsminor.yy162;
2475 break;
2476 case 9: /* statement ::= print prlist */
2477 #line 566 "pikchr.y"
2478 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy162=0;}
2479 #line 2504 "pikchr.c"
2480 break;
2481 case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2482 #line 571 "pikchr.y"
2483 {yymsp[-5].minor.yy162=pik_assert(p,yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy21);}
2484 #line 2509 "pikchr.c"
2485 break;
2486 case 11: /* statement ::= ASSERT LP position EQ position RP */
2487 #line 573 "pikchr.y"
2488 {yymsp[-5].minor.yy162=pik_position_assert(p,&yymsp[-3].minor.yy63,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy63);}
2489 #line 2514 "pikchr.c"
2490 break;
2491 case 12: /* statement ::= DEFINE ID CODEBLOCK */
2492 #line 574 "pikchr.y"
2493 {yymsp[-2].minor.yy162=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2494 #line 2519 "pikchr.c"
2495 break;
2496 case 13: /* rvalue ::= PLACENAME */
2497 #line 585 "pikchr.y"
2498 {yylhsminor.yy21 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2499 #line 2524 "pikchr.c"
2500 yymsp[0].minor.yy21 = yylhsminor.yy21;
2501 break;
2502 case 14: /* pritem ::= FILL */
2503 case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
2504 case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2505 #line 590 "pikchr.y"
2506 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2507 #line 2532 "pikchr.c"
2508 break;
2509 case 17: /* pritem ::= rvalue */
2510 #line 593 "pikchr.y"
2511 {pik_append_num(p,"",yymsp[0].minor.yy21);}
2512 #line 2537 "pikchr.c"
2513 break;
2514 case 18: /* pritem ::= STRING */
2515 #line 594 "pikchr.y"
2516 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2517 #line 2542 "pikchr.c"
2518 break;
2519 case 19: /* prsep ::= COMMA */
2520 #line 595 "pikchr.y"
2521 {pik_append(p, " ", 1);}
2522 #line 2547 "pikchr.c"
2523 break;
2524 case 20: /* unnamed_statement ::= basetype attribute_list */
2525 #line 598 "pikchr.y"
2526 {yylhsminor.yy162 = yymsp[-1].minor.yy162; pik_after_adding_attributes(p,yylhsminor.yy162);}
2527 #line 2552 "pikchr.c"
2528 yymsp[-1].minor.yy162 = yylhsminor.yy162;
2529 break;
2530 case 21: /* basetype ::= CLASSNAME */
2531 #line 600 "pikchr.y"
2532 {yylhsminor.yy162 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2533 #line 2558 "pikchr.c"
2534 yymsp[0].minor.yy162 = yylhsminor.yy162;
2535 break;
2536 case 22: /* basetype ::= STRING textposition */
2537 #line 602 "pikchr.y"
2538 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy188; yylhsminor.yy162 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2539 #line 2564 "pikchr.c"
2540 yymsp[-1].minor.yy162 = yylhsminor.yy162;
2541 break;
2542 case 23: /* basetype ::= LB savelist statement_list RB */
2543 #line 604 "pikchr.y"
2544 { p->list = yymsp[-2].minor.yy235; yymsp[-3].minor.yy162 = pik_elem_new(p,0,0,yymsp[-1].minor.yy235); if(yymsp[-3].minor.yy162) yymsp[-3].minor.yy162->errTok = yymsp[0].minor.yy0; }
2545 #line 2570 "pikchr.c"
2546 break;
2547 case 24: /* savelist ::= */
2548 #line 609 "pikchr.y"
2549 {yymsp[1].minor.yy235 = p->list; p->list = 0;}
2550 #line 2575 "pikchr.c"
2551 break;
2552 case 25: /* relexpr ::= expr */
2553 #line 616 "pikchr.y"
2554 {yylhsminor.yy72.rAbs = yymsp[0].minor.yy21; yylhsminor.yy72.rRel = 0;}
2555 #line 2580 "pikchr.c"
2556 yymsp[0].minor.yy72 = yylhsminor.yy72;
2557 break;
2558 case 26: /* relexpr ::= expr PERCENT */
2559 #line 617 "pikchr.y"
2560 {yylhsminor.yy72.rAbs = 0; yylhsminor.yy72.rRel = yymsp[-1].minor.yy21/100;}
2561 #line 2586 "pikchr.c"
2562 yymsp[-1].minor.yy72 = yylhsminor.yy72;
2563 break;
2564 case 27: /* optrelexpr ::= */
2565 #line 619 "pikchr.y"
2566 {yymsp[1].minor.yy72.rAbs = 0; yymsp[1].minor.yy72.rRel = 1.0;}
2567 #line 2592 "pikchr.c"
2568 break;
2569 case 28: /* attribute_list ::= relexpr alist */
2570 #line 621 "pikchr.y"
2571 {pik_add_direction(p,0,&yymsp[-1].minor.yy72);}
2572 #line 2597 "pikchr.c"
2573 break;
2574 case 29: /* attribute ::= numproperty relexpr */
2575 #line 625 "pikchr.y"
2576 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72); }
2577 #line 2602 "pikchr.c"
2578 break;
2579 case 30: /* attribute ::= dashproperty expr */
2580 #line 626 "pikchr.y"
2581 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy21); }
2582 #line 2607 "pikchr.c"
2583 break;
2584 case 31: /* attribute ::= dashproperty */
2585 #line 627 "pikchr.y"
2586 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2587 #line 2612 "pikchr.c"
2588 break;
2589 case 32: /* attribute ::= colorproperty rvalue */
2590 #line 628 "pikchr.y"
2591 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21); }
2592 #line 2617 "pikchr.c"
2593 break;
2594 case 33: /* attribute ::= go direction optrelexpr */
2595 #line 629 "pikchr.y"
2596 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72);}
2597 #line 2622 "pikchr.c"
2598 break;
2599 case 34: /* attribute ::= go direction even position */
2600 #line 630 "pikchr.y"
2601 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63);}
2602 #line 2627 "pikchr.c"
2603 break;
2604 case 35: /* attribute ::= CLOSE */
2605 #line 631 "pikchr.y"
2606 { pik_close_path(p,&yymsp[0].minor.yy0); }
2607 #line 2632 "pikchr.c"
2608 break;
2609 case 36: /* attribute ::= CHOP */
2610 #line 632 "pikchr.y"
2611 { p->cur->bChop = 1; }
2612 #line 2637 "pikchr.c"
2613 break;
2614 case 37: /* attribute ::= FROM position */
2615 #line 633 "pikchr.y"
2616 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2617 #line 2642 "pikchr.c"
2618 break;
2619 case 38: /* attribute ::= TO position */
2620 #line 634 "pikchr.y"
2621 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2622 #line 2647 "pikchr.c"
2623 break;
2624 case 39: /* attribute ::= THEN */
2625 #line 635 "pikchr.y"
2626 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2627 #line 2652 "pikchr.c"
2628 break;
2629 case 40: /* attribute ::= THEN optrelexpr HEADING expr */
2630 case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2631 #line 637 "pikchr.y"
2632 {pik_move_hdg(p,&yymsp[-2].minor.yy72,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21,0,&yymsp[-3].minor.yy0);}
2633 #line 2658 "pikchr.c"
2634 break;
2635 case 41: /* attribute ::= THEN optrelexpr EDGEPT */
2636 case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2637 #line 638 "pikchr.y"
2638 {pik_move_hdg(p,&yymsp[-1].minor.yy72,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2639 #line 2664 "pikchr.c"
2640 break;
2641 case 44: /* attribute ::= AT position */
2642 #line 643 "pikchr.y"
2643 { pik_set_at(p,0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2644 #line 2669 "pikchr.c"
2645 break;
2646 case 45: /* attribute ::= SAME */
2647 #line 645 "pikchr.y"
2648 {pik_same(p,0,&yymsp[0].minor.yy0);}
2649 #line 2674 "pikchr.c"
2650 break;
2651 case 46: /* attribute ::= SAME AS object */
2652 #line 646 "pikchr.y"
2653 {pik_same(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2654 #line 2679 "pikchr.c"
2655 break;
2656 case 47: /* attribute ::= STRING textposition */
2657 #line 647 "pikchr.y"
2658 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy188);}
2659 #line 2684 "pikchr.c"
2660 break;
2661 case 48: /* attribute ::= FIT */
2662 #line 648 "pikchr.y"
2663 {pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2664 #line 2689 "pikchr.c"
2665 break;
2666 case 49: /* attribute ::= BEHIND object */
2667 #line 649 "pikchr.y"
2668 {pik_behind(p,yymsp[0].minor.yy162);}
2669 #line 2694 "pikchr.c"
2670 break;
2671 case 50: /* withclause ::= DOT_E edge AT position */
2672 case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2673 #line 657 "pikchr.y"
2674 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2675 #line 2700 "pikchr.c"
2676 break;
2677 case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2678 #line 661 "pikchr.y"
2679 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2680 #line 2705 "pikchr.c"
2681 yymsp[0].minor.yy0 = yylhsminor.yy0;
2682 break;
2683 case 53: /* boolproperty ::= CW */
2684 #line 672 "pikchr.y"
2685 {p->cur->cw = 1;}
2686 #line 2711 "pikchr.c"
2687 break;
2688 case 54: /* boolproperty ::= CCW */
2689 #line 673 "pikchr.y"
2690 {p->cur->cw = 0;}
2691 #line 2716 "pikchr.c"
2692 break;
2693 case 55: /* boolproperty ::= LARROW */
2694 #line 674 "pikchr.y"
2695 {p->cur->larrow=1; p->cur->rarrow=0; }
2696 #line 2721 "pikchr.c"
2697 break;
2698 case 56: /* boolproperty ::= RARROW */
2699 #line 675 "pikchr.y"
2700 {p->cur->larrow=0; p->cur->rarrow=1; }
2701 #line 2726 "pikchr.c"
2702 break;
2703 case 57: /* boolproperty ::= LRARROW */
2704 #line 676 "pikchr.y"
2705 {p->cur->larrow=1; p->cur->rarrow=1; }
2706 #line 2731 "pikchr.c"
2707 break;
2708 case 58: /* boolproperty ::= INVIS */
2709 #line 677 "pikchr.y"
2710 {p->cur->sw = -0.00001;}
2711 #line 2736 "pikchr.c"
2712 break;
2713 case 59: /* boolproperty ::= THICK */
2714 #line 678 "pikchr.y"
2715 {p->cur->sw *= 1.5;}
2716 #line 2741 "pikchr.c"
2717 break;
2718 case 60: /* boolproperty ::= THIN */
2719 #line 679 "pikchr.y"
2720 {p->cur->sw *= 0.67;}
2721 #line 2746 "pikchr.c"
2722 break;
2723 case 61: /* boolproperty ::= SOLID */
2724 #line 680 "pikchr.y"
2725 {p->cur->sw = pik_value(p,"thickness",9,0);
2726 p->cur->dotted = p->cur->dashed = 0.0;}
2727 #line 2752 "pikchr.c"
2728 break;
2729 case 62: /* textposition ::= */
2730 #line 683 "pikchr.y"
2731 {yymsp[1].minor.yy188 = 0;}
2732 #line 2757 "pikchr.c"
2733 break;
2734 case 63: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|MONO|ALIGNED|BIG|SMALL */
2735 #line 686 "pikchr.y"
2736 {yylhsminor.yy188 = (short int)pik_text_position(yymsp[-1].minor.yy188,&yymsp[0].minor.yy0);}
2737 #line 2762 "pikchr.c"
2738 yymsp[-1].minor.yy188 = yylhsminor.yy188;
2739 break;
2740 case 64: /* position ::= expr COMMA expr */
2741 #line 689 "pikchr.y"
2742 {yylhsminor.yy63.x=yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[0].minor.yy21;}
2743 #line 2768 "pikchr.c"
2744 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2745 break;
2746 case 65: /* position ::= place PLUS expr COMMA expr */
2747 #line 691 "pikchr.y"
2748 {yylhsminor.yy63.x=yymsp[-4].minor.yy63.x+yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[-4].minor.yy63.y+yymsp[0].minor.yy21;}
2749 #line 2774 "pikchr.c"
2750 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2751 break;
2752 case 66: /* position ::= place MINUS expr COMMA expr */
2753 #line 692 "pikchr.y"
2754 {yylhsminor.yy63.x=yymsp[-4].minor.yy63.x-yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[-4].minor.yy63.y-yymsp[0].minor.yy21;}
2755 #line 2780 "pikchr.c"
2756 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2757 break;
2758 case 67: /* position ::= place PLUS LP expr COMMA expr RP */
2759 #line 694 "pikchr.y"
2760 {yylhsminor.yy63.x=yymsp[-6].minor.yy63.x+yymsp[-3].minor.yy21; yylhsminor.yy63.y=yymsp[-6].minor.yy63.y+yymsp[-1].minor.yy21;}
2761 #line 2786 "pikchr.c"
2762 yymsp[-6].minor.yy63 = yylhsminor.yy63;
2763 break;
2764 case 68: /* position ::= place MINUS LP expr COMMA expr RP */
2765 #line 696 "pikchr.y"
2766 {yylhsminor.yy63.x=yymsp[-6].minor.yy63.x-yymsp[-3].minor.yy21; yylhsminor.yy63.y=yymsp[-6].minor.yy63.y-yymsp[-1].minor.yy21;}
2767 #line 2792 "pikchr.c"
2768 yymsp[-6].minor.yy63 = yylhsminor.yy63;
2769 break;
2770 case 69: /* position ::= LP position COMMA position RP */
2771 #line 697 "pikchr.y"
2772 {yymsp[-4].minor.yy63.x=yymsp[-3].minor.yy63.x; yymsp[-4].minor.yy63.y=yymsp[-1].minor.yy63.y;}
2773 #line 2798 "pikchr.c"
2774 break;
2775 case 70: /* position ::= LP position RP */
2776 #line 698 "pikchr.y"
2777 {yymsp[-2].minor.yy63=yymsp[-1].minor.yy63;}
2778 #line 2803 "pikchr.c"
2779 break;
2780 case 71: /* position ::= expr between position AND position */
2781 #line 700 "pikchr.y"
2782 {yylhsminor.yy63 = pik_position_between(yymsp[-4].minor.yy21,yymsp[-2].minor.yy63,yymsp[0].minor.yy63);}
2783 #line 2808 "pikchr.c"
2784 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2785 break;
2786 case 72: /* position ::= expr LT position COMMA position GT */
2787 #line 702 "pikchr.y"
2788 {yylhsminor.yy63 = pik_position_between(yymsp[-5].minor.yy21,yymsp[-3].minor.yy63,yymsp[-1].minor.yy63);}
2789 #line 2814 "pikchr.c"
2790 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2791 break;
2792 case 73: /* position ::= expr ABOVE position */
2793 #line 703 "pikchr.y"
2794 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y += yymsp[-2].minor.yy21;}
2795 #line 2820 "pikchr.c"
2796 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2797 break;
2798 case 74: /* position ::= expr BELOW position */
2799 #line 704 "pikchr.y"
2800 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y -= yymsp[-2].minor.yy21;}
2801 #line 2826 "pikchr.c"
2802 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2803 break;
2804 case 75: /* position ::= expr LEFT OF position */
2805 #line 705 "pikchr.y"
2806 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x -= yymsp[-3].minor.yy21;}
2807 #line 2832 "pikchr.c"
2808 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2809 break;
2810 case 76: /* position ::= expr RIGHT OF position */
2811 #line 706 "pikchr.y"
2812 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x += yymsp[-3].minor.yy21;}
2813 #line 2838 "pikchr.c"
2814 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2815 break;
2816 case 77: /* position ::= expr ON HEADING EDGEPT OF position */
2817 #line 708 "pikchr.y"
2818 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-5].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2819 #line 2844 "pikchr.c"
2820 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2821 break;
2822 case 78: /* position ::= expr HEADING EDGEPT OF position */
2823 #line 710 "pikchr.y"
2824 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-4].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2825 #line 2850 "pikchr.c"
2826 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2827 break;
2828 case 79: /* position ::= expr EDGEPT OF position */
2829 #line 712 "pikchr.y"
2830 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2831 #line 2856 "pikchr.c"
2832 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2833 break;
2834 case 80: /* position ::= expr ON HEADING expr FROM position */
2835 #line 714 "pikchr.y"
2836 {yylhsminor.yy63 = pik_position_at_angle(yymsp[-5].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2837 #line 2862 "pikchr.c"
2838 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2839 break;
2840 case 81: /* position ::= expr HEADING expr FROM position */
2841 #line 716 "pikchr.y"
2842 {yylhsminor.yy63 = pik_position_at_angle(yymsp[-4].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2843 #line 2868 "pikchr.c"
2844 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2845 break;
2846 case 82: /* place ::= edge OF object */
2847 #line 728 "pikchr.y"
2848 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2849 #line 2874 "pikchr.c"
2850 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2851 break;
2852 case 83: /* place2 ::= object */
2853 #line 729 "pikchr.y"
2854 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,0);}
2855 #line 2880 "pikchr.c"
2856 yymsp[0].minor.yy63 = yylhsminor.yy63;
2857 break;
2858 case 84: /* place2 ::= object DOT_E edge */
2859 #line 730 "pikchr.y"
2860 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2861 #line 2886 "pikchr.c"
2862 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2863 break;
2864 case 85: /* place2 ::= NTH VERTEX OF object */
2865 #line 731 "pikchr.y"
2866 {yylhsminor.yy63 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy162);}
2867 #line 2892 "pikchr.c"
2868 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2869 break;
2870 case 86: /* object ::= nth */
2871 #line 743 "pikchr.y"
2872 {yylhsminor.yy162 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2873 #line 2898 "pikchr.c"
2874 yymsp[0].minor.yy162 = yylhsminor.yy162;
2875 break;
2876 case 87: /* object ::= nth OF|IN object */
2877 #line 744 "pikchr.y"
2878 {yylhsminor.yy162 = pik_find_nth(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2879 #line 2904 "pikchr.c"
2880 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2881 break;
2882 case 88: /* objectname ::= THIS */
2883 #line 746 "pikchr.y"
2884 {yymsp[0].minor.yy162 = p->cur;}
2885 #line 2910 "pikchr.c"
2886 break;
2887 case 89: /* objectname ::= PLACENAME */
2888 #line 747 "pikchr.y"
2889 {yylhsminor.yy162 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2890 #line 2915 "pikchr.c"
2891 yymsp[0].minor.yy162 = yylhsminor.yy162;
2892 break;
2893 case 90: /* objectname ::= objectname DOT_U PLACENAME */
2894 #line 749 "pikchr.y"
2895 {yylhsminor.yy162 = pik_find_byname(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2896 #line 2921 "pikchr.c"
2897 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2898 break;
2899 case 91: /* nth ::= NTH CLASSNAME */
2900 #line 751 "pikchr.y"
2901 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2902 #line 2927 "pikchr.c"
2903 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2904 break;
2905 case 92: /* nth ::= NTH LAST CLASSNAME */
2906 #line 752 "pikchr.y"
2907 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2908 #line 2933 "pikchr.c"
2909 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2910 break;
2911 case 93: /* nth ::= LAST CLASSNAME */
2912 #line 753 "pikchr.y"
2913 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2914 #line 2939 "pikchr.c"
2915 break;
2916 case 94: /* nth ::= LAST */
2917 #line 754 "pikchr.y"
2918 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2919 #line 2944 "pikchr.c"
2920 yymsp[0].minor.yy0 = yylhsminor.yy0;
2921 break;
2922 case 95: /* nth ::= NTH LB RB */
2923 #line 755 "pikchr.y"
2924 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2925 #line 2950 "pikchr.c"
2926 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2927 break;
2928 case 96: /* nth ::= NTH LAST LB RB */
2929 #line 756 "pikchr.y"
2930 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2931 #line 2956 "pikchr.c"
2932 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2933 break;
2934 case 97: /* nth ::= LAST LB RB */
2935 #line 757 "pikchr.y"
2936 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2937 #line 2962 "pikchr.c"
2938 break;
2939 case 98: /* expr ::= expr PLUS expr */
2940 #line 759 "pikchr.y"
2941 {yylhsminor.yy21=yymsp[-2].minor.yy21+yymsp[0].minor.yy21;}
2942 #line 2967 "pikchr.c"
2943 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2944 break;
2945 case 99: /* expr ::= expr MINUS expr */
2946 #line 760 "pikchr.y"
2947 {yylhsminor.yy21=yymsp[-2].minor.yy21-yymsp[0].minor.yy21;}
2948 #line 2973 "pikchr.c"
2949 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2950 break;
2951 case 100: /* expr ::= expr STAR expr */
2952 #line 761 "pikchr.y"
2953 {yylhsminor.yy21=yymsp[-2].minor.yy21*yymsp[0].minor.yy21;}
2954 #line 2979 "pikchr.c"
2955 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2956 break;
2957 case 101: /* expr ::= expr SLASH expr */
2958 #line 762 "pikchr.y"
2959 {
2960 if( yymsp[0].minor.yy21==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy21 = 0.0; }
2961 else{ yylhsminor.yy21 = yymsp[-2].minor.yy21/yymsp[0].minor.yy21; }
2962 }
2963 #line 2988 "pikchr.c"
2964 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2965 break;
2966 case 102: /* expr ::= MINUS expr */
2967 #line 766 "pikchr.y"
2968 {yymsp[-1].minor.yy21=-yymsp[0].minor.yy21;}
2969 #line 2994 "pikchr.c"
2970 break;
2971 case 103: /* expr ::= PLUS expr */
2972 #line 767 "pikchr.y"
2973 {yymsp[-1].minor.yy21=yymsp[0].minor.yy21;}
2974 #line 2999 "pikchr.c"
2975 break;
2976 case 104: /* expr ::= LP expr RP */
2977 #line 768 "pikchr.y"
2978 {yymsp[-2].minor.yy21=yymsp[-1].minor.yy21;}
2979 #line 3004 "pikchr.c"
2980 break;
2981 case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2982 #line 769 "pikchr.y"
2983 {yymsp[-2].minor.yy21=pik_get_var(p,&yymsp[-1].minor.yy0);}
2984 #line 3009 "pikchr.c"
2985 break;
2986 case 106: /* expr ::= NUMBER */
2987 #line 770 "pikchr.y"
2988 {yylhsminor.yy21=pik_atof(&yymsp[0].minor.yy0);}
2989 #line 3014 "pikchr.c"
2990 yymsp[0].minor.yy21 = yylhsminor.yy21;
2991 break;
2992 case 107: /* expr ::= ID */
2993 #line 771 "pikchr.y"
2994 {yylhsminor.yy21=pik_get_var(p,&yymsp[0].minor.yy0);}
2995 #line 3020 "pikchr.c"
2996 yymsp[0].minor.yy21 = yylhsminor.yy21;
2997 break;
2998 case 108: /* expr ::= FUNC1 LP expr RP */
2999 #line 772 "pikchr.y"
3000 {yylhsminor.yy21 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy21,0.0);}
3001 #line 3026 "pikchr.c"
3002 yymsp[-3].minor.yy21 = yylhsminor.yy21;
3003 break;
3004 case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */
3005 #line 773 "pikchr.y"
3006 {yylhsminor.yy21 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy21,yymsp[-1].minor.yy21);}
3007 #line 3032 "pikchr.c"
3008 yymsp[-5].minor.yy21 = yylhsminor.yy21;
3009 break;
3010 case 110: /* expr ::= DIST LP position COMMA position RP */
3011 #line 774 "pikchr.y"
3012 {yymsp[-5].minor.yy21 = pik_dist(&yymsp[-3].minor.yy63,&yymsp[-1].minor.yy63);}
3013 #line 3038 "pikchr.c"
3014 break;
3015 case 111: /* expr ::= place2 DOT_XY X */
3016 #line 775 "pikchr.y"
3017 {yylhsminor.yy21 = yymsp[-2].minor.yy63.x;}
3018 #line 3043 "pikchr.c"
3019 yymsp[-2].minor.yy21 = yylhsminor.yy21;
3020 break;
3021 case 112: /* expr ::= place2 DOT_XY Y */
3022 #line 776 "pikchr.y"
3023 {yylhsminor.yy21 = yymsp[-2].minor.yy63.y;}
3024 #line 3049 "pikchr.c"
3025 yymsp[-2].minor.yy21 = yylhsminor.yy21;
3026 break;
3027 case 113: /* expr ::= object DOT_L numproperty */
3028 case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114);
3029 case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115);
3030 #line 777 "pikchr.y"
3031 {yylhsminor.yy21=pik_property_of(yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
3032 #line 3057 "pikchr.c"
3033 yymsp[-2].minor.yy21 = yylhsminor.yy21;
3034 break;
3035 default:
3036 /* (116) lvalue ::= ID */ yytestcase(yyruleno==116);
3037 /* (117) lvalue ::= FILL */ yytestcase(yyruleno==117);
@@ -3098,19 +3130,19 @@
3130 ){
3131 pik_parserARG_FETCH
3132 pik_parserCTX_FETCH
3133 #define TOKEN yyminor
3134 /************ Begin %syntax_error code ****************************************/
3135 #line 537 "pikchr.y"
3136
3137 if( TOKEN.z && TOKEN.z[0] ){
3138 pik_error(p, &TOKEN, "syntax error");
3139 }else{
3140 pik_error(p, 0, "syntax error");
3141 }
3142 UNUSED_PARAMETER(yymajor);
3143 #line 3168 "pikchr.c"
3144 /************ End %syntax_error code ******************************************/
3145 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3146 pik_parserCTX_STORE
3147 }
3148
@@ -3227,23 +3259,16 @@
3259 yypParser->yyhwm++;
3260 assert( yypParser->yyhwm ==
3261 (int)(yypParser->yytos - yypParser->yystack));
3262 }
3263 #endif
 
3264 if( yypParser->yytos>=yypParser->yystackEnd ){
 
 
 
 
 
3265 if( yyGrowStack(yypParser) ){
3266 yyStackOverflow(yypParser);
3267 break;
3268 }
3269 }
 
3270 }
3271 yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor pik_parserCTX_PARAM);
3272 }else if( yyact <= YY_MAX_SHIFTREDUCE ){
3273 yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
3274 #ifndef YYNOERRORRECOVERY
@@ -3382,11 +3407,11 @@
3407 #else
3408 (void)iToken;
3409 return 0;
3410 #endif
3411 }
3412 #line 782 "pikchr.y"
3413
3414
3415
3416 /* Chart of the 148 official CSS color names with their
3417 ** corresponding RGB values thru Color Module Level 4:
@@ -3577,10 +3602,12 @@
3602 { "color", 0.0 },
3603 { "cylht", 0.5 },
3604 { "cylrad", 0.075 },
3605 { "cylwid", 0.75 },
3606 { "dashwid", 0.05 },
3607 { "diamondht", 0.75 },
3608 { "diamondwid", 1.0 },
3609 { "dotrad", 0.015 },
3610 { "ellipseht", 0.5 },
3611 { "ellipsewid", 0.75 },
3612 { "fileht", 0.75 },
3613 { "filerad", 0.15 },
@@ -3957,10 +3984,65 @@
3984 pik_append(p,"\" />\n", -1);
3985 }
3986 pik_append_txt(p, pObj, 0);
3987 }
3988
3989 /* Methods for the "diamond" class */
3990 static void diamondInit(Pik *p, PObj *pObj){
3991 pObj->w = pik_value(p, "diamondwid",10,0);
3992 pObj->h = pik_value(p, "diamondht",9,0);
3993 pObj->bAltAutoFit = 1;
3994 }
3995 /* Return offset from the center of the box to the compass point
3996 ** given by parameter cp */
3997 static PPoint diamondOffset(Pik *p, PObj *pObj, int cp){
3998 PPoint pt = cZeroPoint;
3999 PNum w2 = 0.5*pObj->w;
4000 PNum w4 = 0.25*pObj->w;
4001 PNum h2 = 0.5*pObj->h;
4002 PNum h4 = 0.25*pObj->h;
4003 switch( cp ){
4004 case CP_C: break;
4005 case CP_N: pt.x = 0.0; pt.y = h2; break;
4006 case CP_NE: pt.x = w4; pt.y = h4; break;
4007 case CP_E: pt.x = w2; pt.y = 0.0; break;
4008 case CP_SE: pt.x = w4; pt.y = -h4; break;
4009 case CP_S: pt.x = 0.0; pt.y = -h2; break;
4010 case CP_SW: pt.x = -w4; pt.y = -h4; break;
4011 case CP_W: pt.x = -w2; pt.y = 0.0; break;
4012 case CP_NW: pt.x = -w4; pt.y = h4; break;
4013 default: assert(0);
4014 }
4015 UNUSED_PARAMETER(p);
4016 return pt;
4017 }
4018 static void diamondFit(Pik *p, PObj *pObj, PNum w, PNum h){
4019 if( pObj->w<=0 ) pObj->w = w*1.5;
4020 if( pObj->h<=0 ) pObj->h = h*1.5;
4021 if( pObj->w>0 && pObj->h>0 ){
4022 PNum x = pObj->w*h/pObj->h + w;
4023 PNum y = pObj->h*x/pObj->w;
4024 pObj->w = x;
4025 pObj->h = y;
4026 }
4027 UNUSED_PARAMETER(p);
4028 }
4029 static void diamondRender(Pik *p, PObj *pObj){
4030 PNum w2 = 0.5*pObj->w;
4031 PNum h2 = 0.5*pObj->h;
4032 PPoint pt = pObj->ptAt;
4033 if( pObj->sw>=0.0 ){
4034 pik_append_xy(p,"<path d=\"M", pt.x-w2,pt.y);
4035 pik_append_xy(p,"L", pt.x,pt.y-h2);
4036 pik_append_xy(p,"L", pt.x+w2,pt.y);
4037 pik_append_xy(p,"L", pt.x,pt.y+h2);
4038 pik_append(p,"Z\" ",-1);
4039 pik_append_style(p,pObj,3);
4040 pik_append(p,"\" />\n", -1);
4041 }
4042 pik_append_txt(p, pObj, 0);
4043 }
4044
4045
4046 /* Methods for the "ellipse" class */
4047 static void ellipseInit(Pik *p, PObj *pObj){
4048 pObj->w = pik_value(p, "ellipsewid",10,0);
@@ -4341,10 +4423,21 @@
4423 /* xChop */ boxChop,
4424 /* xOffset */ cylinderOffset,
4425 /* xFit */ cylinderFit,
4426 /* xRender */ cylinderRender
4427 },
4428 { /* name */ "diamond",
4429 /* isline */ 0,
4430 /* eJust */ 0,
4431 /* xInit */ diamondInit,
4432 /* xNumProp */ 0,
4433 /* xCheck */ 0,
4434 /* xChop */ boxChop,
4435 /* xOffset */ diamondOffset,
4436 /* xFit */ diamondFit,
4437 /* xRender */ diamondRender
4438 },
4439 { /* name */ "dot",
4440 /* isline */ 0,
4441 /* eJust */ 0,
4442 /* xInit */ dotInit,
4443 /* xNumProp */ dotNumProp,
@@ -6269,12 +6362,16 @@
6362 }
6363 if( pObj->type->xFit==0 ) return;
6364 pik_bbox_init(&bbox);
6365 pik_compute_layout_settings(p);
6366 pik_append_txt(p, pObj, &bbox);
6367 if( (eWhich & 1)!=0 || pObj->bAltAutoFit ){
6368 w = (bbox.ne.x - bbox.sw.x) + p->charWidth;
6369 }else{
6370 w = 0;
6371 }
6372 if( (eWhich & 2)!=0 || pObj->bAltAutoFit ){
6373 PNum h1, h2;
6374 h1 = (bbox.ne.y - pObj->ptAt.y);
6375 h2 = (pObj->ptAt.y - bbox.sw.y);
6376 h = 2.0*( h1<h2 ? h2 : h1 ) + 0.5*p->charHeight;
6377 }else{
@@ -8143,6 +8240,6 @@
8240
8241
8242 #endif /* PIKCHR_TCL */
8243
8244
8245 #line 8270 "pikchr.c"
8246
+378 -377
--- extsrc/pikchr.js
+++ extsrc/pikchr.js
@@ -1,18 +1,17 @@
11
22
var initPikchrModule = (() => {
33
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
44
55
return (
6
-function(config) {
7
- var initPikchrModule = config || {};
6
+function(moduleArg = {}) {
87
9
-var Module = typeof initPikchrModule != "undefined" ? initPikchrModule : {};
8
+var Module = moduleArg;
109
1110
var readyPromiseResolve, readyPromiseReject;
1211
13
-Module["ready"] = new Promise(function(resolve, reject) {
12
+Module["ready"] = new Promise((resolve, reject) => {
1413
readyPromiseResolve = resolve;
1514
readyPromiseReject = reject;
1615
});
1716
1817
var moduleOverrides = Object.assign({}, Module);
@@ -36,11 +35,11 @@
3635
return Module["locateFile"](path, scriptDirectory);
3736
}
3837
return scriptDirectory + path;
3938
}
4039
41
-var read_, readAsync, readBinary, setWindowTitle;
40
+var read_, readAsync, readBinary;
4241
4342
if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
4443
if (ENVIRONMENT_IS_WORKER) {
4544
scriptDirectory = self.location.href;
4645
} else if (typeof document != "undefined" && document.currentScript) {
@@ -47,52 +46,51 @@
4746
scriptDirectory = document.currentScript.src;
4847
}
4948
if (_scriptDir) {
5049
scriptDirectory = _scriptDir;
5150
}
52
- if (scriptDirectory.indexOf("blob:") !== 0) {
53
- scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1);
51
+ if (scriptDirectory.startsWith("blob:")) {
52
+ scriptDirectory = "";
5453
} else {
55
- scriptDirectory = "";
54
+ scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1);
5655
}
5756
{
5857
read_ = url => {
59
- var xhr = new XMLHttpRequest();
58
+ var xhr = new XMLHttpRequest;
6059
xhr.open("GET", url, false);
6160
xhr.send(null);
6261
return xhr.responseText;
6362
};
6463
if (ENVIRONMENT_IS_WORKER) {
6564
readBinary = url => {
66
- var xhr = new XMLHttpRequest();
65
+ var xhr = new XMLHttpRequest;
6766
xhr.open("GET", url, false);
6867
xhr.responseType = "arraybuffer";
6968
xhr.send(null);
70
- return new Uint8Array(xhr.response);
69
+ return new Uint8Array(/** @type{!ArrayBuffer} */ (xhr.response));
7170
};
7271
}
7372
readAsync = (url, onload, onerror) => {
74
- var xhr = new XMLHttpRequest();
73
+ var xhr = new XMLHttpRequest;
7574
xhr.open("GET", url, true);
7675
xhr.responseType = "arraybuffer";
7776
xhr.onload = () => {
78
- if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
77
+ if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) {
7978
onload(xhr.response);
8079
return;
8180
}
8281
onerror();
8382
};
8483
xhr.onerror = onerror;
8584
xhr.send(null);
8685
};
8786
}
88
- setWindowTitle = title => document.title = title;
8987
} else {}
9088
9189
var out = Module["print"] || console.log.bind(console);
9290
93
-var err = Module["printErr"] || console.warn.bind(console);
91
+var err = Module["printErr"] || console.error.bind(console);
9492
9593
Object.assign(Module, moduleOverrides);
9694
9795
moduleOverrides = null;
9896
@@ -104,12 +102,10 @@
104102
105103
var wasmBinary;
106104
107105
if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"];
108106
109
-var noExitRuntime = Module["noExitRuntime"] || true;
110
-
111107
if (typeof WebAssembly != "object") {
112108
abort("no native wasm support detected");
113109
}
114110
115111
var wasmMemory;
@@ -116,119 +112,32 @@
116112
117113
var ABORT = false;
118114
119115
var EXITSTATUS;
120116
121
-var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined;
122
-
123
-function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) {
124
- var endIdx = idx + maxBytesToRead;
125
- var endPtr = idx;
126
- while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
127
- if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
128
- return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
129
- }
130
- var str = "";
131
- while (idx < endPtr) {
132
- var u0 = heapOrArray[idx++];
133
- if (!(u0 & 128)) {
134
- str += String.fromCharCode(u0);
135
- continue;
136
- }
137
- var u1 = heapOrArray[idx++] & 63;
138
- if ((u0 & 224) == 192) {
139
- str += String.fromCharCode((u0 & 31) << 6 | u1);
140
- continue;
141
- }
142
- var u2 = heapOrArray[idx++] & 63;
143
- if ((u0 & 240) == 224) {
144
- u0 = (u0 & 15) << 12 | u1 << 6 | u2;
145
- } else {
146
- u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heapOrArray[idx++] & 63;
147
- }
148
- if (u0 < 65536) {
149
- str += String.fromCharCode(u0);
150
- } else {
151
- var ch = u0 - 65536;
152
- str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
153
- }
154
- }
155
- return str;
156
-}
157
-
158
-function UTF8ToString(ptr, maxBytesToRead) {
159
- return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
160
-}
161
-
162
-function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
163
- if (!(maxBytesToWrite > 0)) return 0;
164
- var startIdx = outIdx;
165
- var endIdx = outIdx + maxBytesToWrite - 1;
166
- for (var i = 0; i < str.length; ++i) {
167
- var u = str.charCodeAt(i);
168
- if (u >= 55296 && u <= 57343) {
169
- var u1 = str.charCodeAt(++i);
170
- u = 65536 + ((u & 1023) << 10) | u1 & 1023;
171
- }
172
- if (u <= 127) {
173
- if (outIdx >= endIdx) break;
174
- heap[outIdx++] = u;
175
- } else if (u <= 2047) {
176
- if (outIdx + 1 >= endIdx) break;
177
- heap[outIdx++] = 192 | u >> 6;
178
- heap[outIdx++] = 128 | u & 63;
179
- } else if (u <= 65535) {
180
- if (outIdx + 2 >= endIdx) break;
181
- heap[outIdx++] = 224 | u >> 12;
182
- heap[outIdx++] = 128 | u >> 6 & 63;
183
- heap[outIdx++] = 128 | u & 63;
184
- } else {
185
- if (outIdx + 3 >= endIdx) break;
186
- heap[outIdx++] = 240 | u >> 18;
187
- heap[outIdx++] = 128 | u >> 12 & 63;
188
- heap[outIdx++] = 128 | u >> 6 & 63;
189
- heap[outIdx++] = 128 | u & 63;
190
- }
191
- }
192
- heap[outIdx] = 0;
193
- return outIdx - startIdx;
194
-}
195
-
196
-function stringToUTF8(str, outPtr, maxBytesToWrite) {
197
- return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
198
-}
199
-
200
-var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
117
+var /** @type {!Int8Array} */ HEAP8, /** @type {!Uint8Array} */ HEAPU8, /** @type {!Int16Array} */ HEAP16, /** @type {!Uint16Array} */ HEAPU16, /** @type {!Int32Array} */ HEAP32, /** @type {!Uint32Array} */ HEAPU32, /** @type {!Float32Array} */ HEAPF32, /** @type {!Float64Array} */ HEAPF64;
201118
202119
function updateMemoryViews() {
203120
var b = wasmMemory.buffer;
204121
Module["HEAP8"] = HEAP8 = new Int8Array(b);
205122
Module["HEAP16"] = HEAP16 = new Int16Array(b);
206
- Module["HEAP32"] = HEAP32 = new Int32Array(b);
207123
Module["HEAPU8"] = HEAPU8 = new Uint8Array(b);
208124
Module["HEAPU16"] = HEAPU16 = new Uint16Array(b);
125
+ Module["HEAP32"] = HEAP32 = new Int32Array(b);
209126
Module["HEAPU32"] = HEAPU32 = new Uint32Array(b);
210127
Module["HEAPF32"] = HEAPF32 = new Float32Array(b);
211128
Module["HEAPF64"] = HEAPF64 = new Float64Array(b);
212129
}
213130
214
-var INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 16777216;
215
-
216
-var wasmTable;
217
-
218131
var __ATPRERUN__ = [];
219132
220133
var __ATINIT__ = [];
221134
222135
var __ATPOSTRUN__ = [];
223136
224137
var runtimeInitialized = false;
225138
226
-function keepRuntimeAlive() {
227
- return noExitRuntime;
228
-}
229
-
230139
function preRun() {
231140
if (Module["preRun"]) {
232141
if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
233142
while (Module["preRun"].length) {
234143
addOnPreRun(Module["preRun"].shift());
@@ -270,20 +179,16 @@
270179
271180
var dependenciesFulfilled = null;
272181
273182
function addRunDependency(id) {
274183
runDependencies++;
275
- if (Module["monitorRunDependencies"]) {
276
- Module["monitorRunDependencies"](runDependencies);
277
- }
184
+ Module["monitorRunDependencies"]?.(runDependencies);
278185
}
279186
280187
function removeRunDependency(id) {
281188
runDependencies--;
282
- if (Module["monitorRunDependencies"]) {
283
- Module["monitorRunDependencies"](runDependencies);
284
- }
189
+ Module["monitorRunDependencies"]?.(runDependencies);
285190
if (runDependencies == 0) {
286191
if (runDependencyWatcher !== null) {
287192
clearInterval(runDependencyWatcher);
288193
runDependencyWatcher = null;
289194
}
@@ -293,278 +198,382 @@
293198
callback();
294199
}
295200
}
296201
}
297202
298
-function abort(what) {
299
- if (Module["onAbort"]) {
300
- Module["onAbort"](what);
301
- }
203
+/** @param {string|number=} what */ function abort(what) {
204
+ Module["onAbort"]?.(what);
302205
what = "Aborted(" + what + ")";
303206
err(what);
304207
ABORT = true;
305208
EXITSTATUS = 1;
306209
what += ". Build with -sASSERTIONS for more info.";
307
- var e = new WebAssembly.RuntimeError(what);
210
+ /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what);
308211
readyPromiseReject(e);
309212
throw e;
310213
}
311214
312215
var dataURIPrefix = "data:application/octet-stream;base64,";
313216
314
-function isDataURI(filename) {
315
- return filename.startsWith(dataURIPrefix);
316
-}
217
+/**
218
+ * Indicates whether filename is a base64 data URI.
219
+ * @noinline
220
+ */ var isDataURI = filename => filename.startsWith(dataURIPrefix);
317221
318222
var wasmBinaryFile;
319223
320224
wasmBinaryFile = "pikchr.wasm";
321225
322226
if (!isDataURI(wasmBinaryFile)) {
323227
wasmBinaryFile = locateFile(wasmBinaryFile);
324228
}
325229
326
-function getBinary(file) {
327
- try {
328
- if (file == wasmBinaryFile && wasmBinary) {
329
- return new Uint8Array(wasmBinary);
330
- }
331
- if (readBinary) {
332
- return readBinary(file);
333
- }
334
- throw "both async and sync fetching of the wasm failed";
335
- } catch (err) {
336
- abort(err);
337
- }
338
-}
339
-
340
-function getBinaryPromise() {
230
+function getBinarySync(file) {
231
+ if (file == wasmBinaryFile && wasmBinary) {
232
+ return new Uint8Array(wasmBinary);
233
+ }
234
+ if (readBinary) {
235
+ return readBinary(file);
236
+ }
237
+ throw "both async and sync fetching of the wasm failed";
238
+}
239
+
240
+function getBinaryPromise(binaryFile) {
341241
if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
342242
if (typeof fetch == "function") {
343
- return fetch(wasmBinaryFile, {
243
+ return fetch(binaryFile, {
344244
credentials: "same-origin"
345
- }).then(function(response) {
245
+ }).then(response => {
346246
if (!response["ok"]) {
347
- throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
247
+ throw `failed to load wasm binary file at '${binaryFile}'`;
348248
}
349249
return response["arrayBuffer"]();
350
- }).catch(function() {
351
- return getBinary(wasmBinaryFile);
352
- });
353
- }
354
- }
355
- return Promise.resolve().then(function() {
356
- return getBinary(wasmBinaryFile);
357
- });
250
+ }).catch(() => getBinarySync(binaryFile));
251
+ }
252
+ }
253
+ return Promise.resolve().then(() => getBinarySync(binaryFile));
254
+}
255
+
256
+function instantiateArrayBuffer(binaryFile, imports, receiver) {
257
+ return getBinaryPromise(binaryFile).then(binary => WebAssembly.instantiate(binary, imports)).then(instance => instance).then(receiver, reason => {
258
+ err(`failed to asynchronously prepare wasm: ${reason}`);
259
+ abort(reason);
260
+ });
261
+}
262
+
263
+function instantiateAsync(binary, binaryFile, imports, callback) {
264
+ if (!binary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(binaryFile) && typeof fetch == "function") {
265
+ return fetch(binaryFile, {
266
+ credentials: "same-origin"
267
+ }).then(response => {
268
+ /** @suppress {checkTypes} */ var result = WebAssembly.instantiateStreaming(response, imports);
269
+ return result.then(callback, function(reason) {
270
+ err(`wasm streaming compile failed: ${reason}`);
271
+ err("falling back to ArrayBuffer instantiation");
272
+ return instantiateArrayBuffer(binaryFile, imports, callback);
273
+ });
274
+ });
275
+ }
276
+ return instantiateArrayBuffer(binaryFile, imports, callback);
358277
}
359278
360279
function createWasm() {
361280
var info = {
362
- "a": asmLibraryArg
281
+ "a": wasmImports
363282
};
364
- function receiveInstance(instance, module) {
365
- var exports = instance.exports;
366
- Module["asm"] = exports;
367
- wasmMemory = Module["asm"]["d"];
283
+ /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) {
284
+ wasmExports = instance.exports;
285
+ wasmMemory = wasmExports["d"];
368286
updateMemoryViews();
369
- wasmTable = Module["asm"]["g"];
370
- addOnInit(Module["asm"]["e"]);
287
+ addOnInit(wasmExports["e"]);
371288
removeRunDependency("wasm-instantiate");
289
+ return wasmExports;
372290
}
373291
addRunDependency("wasm-instantiate");
374292
function receiveInstantiationResult(result) {
375293
receiveInstance(result["instance"]);
376294
}
377
- function instantiateArrayBuffer(receiver) {
378
- return getBinaryPromise().then(function(binary) {
379
- return WebAssembly.instantiate(binary, info);
380
- }).then(function(instance) {
381
- return instance;
382
- }).then(receiver, function(reason) {
383
- err("failed to asynchronously prepare wasm: " + reason);
384
- abort(reason);
385
- });
386
- }
387
- function instantiateAsync() {
388
- if (!wasmBinary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(wasmBinaryFile) && typeof fetch == "function") {
389
- return fetch(wasmBinaryFile, {
390
- credentials: "same-origin"
391
- }).then(function(response) {
392
- var result = WebAssembly.instantiateStreaming(response, info);
393
- return result.then(receiveInstantiationResult, function(reason) {
394
- err("wasm streaming compile failed: " + reason);
395
- err("falling back to ArrayBuffer instantiation");
396
- return instantiateArrayBuffer(receiveInstantiationResult);
397
- });
398
- });
399
- } else {
400
- return instantiateArrayBuffer(receiveInstantiationResult);
401
- }
402
- }
403
- if (Module["instantiateWasm"]) {
404
- try {
405
- var exports = Module["instantiateWasm"](info, receiveInstance);
406
- return exports;
407
- } catch (e) {
408
- err("Module.instantiateWasm callback failed with error: " + e);
409
- readyPromiseReject(e);
410
- }
411
- }
412
- instantiateAsync().catch(readyPromiseReject);
413
- return {};
414
-}
415
-
416
-var tempDouble;
417
-
418
-var tempI64;
419
-
420
-function ExitStatus(status) {
421
- this.name = "ExitStatus";
422
- this.message = "Program terminated with exit(" + status + ")";
423
- this.status = status;
424
-}
425
-
426
-function callRuntimeCallbacks(callbacks) {
427
- while (callbacks.length > 0) {
428
- callbacks.shift()(Module);
429
- }
430
-}
431
-
432
-function getValue(ptr, type = "i8") {
433
- if (type.endsWith("*")) type = "*";
434
- switch (type) {
435
- case "i1":
436
- return HEAP8[ptr >> 0];
437
-
438
- case "i8":
439
- return HEAP8[ptr >> 0];
440
-
441
- case "i16":
442
- return HEAP16[ptr >> 1];
443
-
444
- case "i32":
445
- return HEAP32[ptr >> 2];
446
-
447
- case "i64":
448
- return HEAP32[ptr >> 2];
449
-
450
- case "float":
451
- return HEAPF32[ptr >> 2];
452
-
453
- case "double":
454
- return HEAPF64[ptr >> 3];
455
-
456
- case "*":
457
- return HEAPU32[ptr >> 2];
458
-
459
- default:
460
- abort("invalid type for getValue: " + type);
461
- }
462
- return null;
463
-}
464
-
465
-function setValue(ptr, value, type = "i8") {
466
- if (type.endsWith("*")) type = "*";
467
- switch (type) {
468
- case "i1":
469
- HEAP8[ptr >> 0] = value;
470
- break;
471
-
472
- case "i8":
473
- HEAP8[ptr >> 0] = value;
474
- break;
475
-
476
- case "i16":
477
- HEAP16[ptr >> 1] = value;
478
- break;
479
-
480
- case "i32":
481
- HEAP32[ptr >> 2] = value;
482
- break;
483
-
484
- case "i64":
485
- tempI64 = [ value >>> 0, (tempDouble = value, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ],
486
- HEAP32[ptr >> 2] = tempI64[0], HEAP32[ptr + 4 >> 2] = tempI64[1];
487
- break;
488
-
489
- case "float":
490
- HEAPF32[ptr >> 2] = value;
491
- break;
492
-
493
- case "double":
494
- HEAPF64[ptr >> 3] = value;
495
- break;
496
-
497
- case "*":
498
- HEAPU32[ptr >> 2] = value;
499
- break;
500
-
501
- default:
502
- abort("invalid type for setValue: " + type);
503
- }
504
-}
505
-
506
-function ___assert_fail(condition, filename, line, func) {
507
- abort("Assertion failed: " + UTF8ToString(condition) + ", at: " + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
508
-}
509
-
510
-function abortOnCannotGrowMemory(requestedSize) {
511
- abort("OOM");
512
-}
513
-
514
-function _emscripten_resize_heap(requestedSize) {
515
- var oldSize = HEAPU8.length;
516
- requestedSize = requestedSize >>> 0;
517
- abortOnCannotGrowMemory(requestedSize);
518
-}
519
-
520
-var SYSCALLS = {
521
- varargs: undefined,
522
- get: function() {
523
- SYSCALLS.varargs += 4;
524
- var ret = HEAP32[SYSCALLS.varargs - 4 >> 2];
525
- return ret;
526
- },
527
- getStr: function(ptr) {
528
- var ret = UTF8ToString(ptr);
529
- return ret;
530
- }
531
-};
532
-
533
-function _proc_exit(code) {
534
- EXITSTATUS = code;
535
- if (!keepRuntimeAlive()) {
536
- if (Module["onExit"]) Module["onExit"](code);
537
- ABORT = true;
538
- }
539
- quit_(code, new ExitStatus(code));
540
-}
541
-
542
-function exitJS(status, implicit) {
543
- EXITSTATUS = status;
544
- _proc_exit(status);
545
-}
546
-
547
-var _exit = exitJS;
548
-
549
-function getCFunc(ident) {
550
- var func = Module["_" + ident];
551
- return func;
552
-}
553
-
554
-function writeArrayToMemory(array, buffer) {
555
- HEAP8.set(array, buffer);
556
-}
557
-
558
-function ccall(ident, returnType, argTypes, args, opts) {
295
+ if (Module["instantiateWasm"]) {
296
+ try {
297
+ return Module["instantiateWasm"](info, receiveInstance);
298
+ } catch (e) {
299
+ err(`Module.instantiateWasm callback failed with error: ${e}`);
300
+ readyPromiseReject(e);
301
+ }
302
+ }
303
+ instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult).catch(readyPromiseReject);
304
+ return {};
305
+}
306
+
307
+/** @constructor */ function ExitStatus(status) {
308
+ this.name = "ExitStatus";
309
+ this.message = `Program terminated with exit(${status})`;
310
+ this.status = status;
311
+}
312
+
313
+var callRuntimeCallbacks = callbacks => {
314
+ while (callbacks.length > 0) {
315
+ callbacks.shift()(Module);
316
+ }
317
+};
318
+
319
+/**
320
+ * @param {number} ptr
321
+ * @param {string} type
322
+ */ function getValue(ptr, type = "i8") {
323
+ if (type.endsWith("*")) type = "*";
324
+ switch (type) {
325
+ case "i1":
326
+ return HEAP8[((ptr) >> 0)];
327
+
328
+ case "i8":
329
+ return HEAP8[((ptr) >> 0)];
330
+
331
+ case "i16":
332
+ return HEAP16[((ptr) >> 1)];
333
+
334
+ case "i32":
335
+ return HEAP32[((ptr) >> 2)];
336
+
337
+ case "i64":
338
+ abort("to do getValue(i64) use WASM_BIGINT");
339
+
340
+ case "float":
341
+ return HEAPF32[((ptr) >> 2)];
342
+
343
+ case "double":
344
+ return HEAPF64[((ptr) >> 3)];
345
+
346
+ case "*":
347
+ return HEAPU32[((ptr) >> 2)];
348
+
349
+ default:
350
+ abort(`invalid type for getValue: ${type}`);
351
+ }
352
+}
353
+
354
+var noExitRuntime = Module["noExitRuntime"] || true;
355
+
356
+/**
357
+ * @param {number} ptr
358
+ * @param {number} value
359
+ * @param {string} type
360
+ */ function setValue(ptr, value, type = "i8") {
361
+ if (type.endsWith("*")) type = "*";
362
+ switch (type) {
363
+ case "i1":
364
+ HEAP8[((ptr) >> 0)] = value;
365
+ break;
366
+
367
+ case "i8":
368
+ HEAP8[((ptr) >> 0)] = value;
369
+ break;
370
+
371
+ case "i16":
372
+ HEAP16[((ptr) >> 1)] = value;
373
+ break;
374
+
375
+ case "i32":
376
+ HEAP32[((ptr) >> 2)] = value;
377
+ break;
378
+
379
+ case "i64":
380
+ abort("to do setValue(i64) use WASM_BIGINT");
381
+
382
+ case "float":
383
+ HEAPF32[((ptr) >> 2)] = value;
384
+ break;
385
+
386
+ case "double":
387
+ HEAPF64[((ptr) >> 3)] = value;
388
+ break;
389
+
390
+ case "*":
391
+ HEAPU32[((ptr) >> 2)] = value;
392
+ break;
393
+
394
+ default:
395
+ abort(`invalid type for setValue: ${type}`);
396
+ }
397
+}
398
+
399
+var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined;
400
+
401
+/**
402
+ * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
403
+ * array that contains uint8 values, returns a copy of that string as a
404
+ * Javascript String object.
405
+ * heapOrArray is either a regular array, or a JavaScript typed array view.
406
+ * @param {number} idx
407
+ * @param {number=} maxBytesToRead
408
+ * @return {string}
409
+ */ var UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => {
410
+ var endIdx = idx + maxBytesToRead;
411
+ var endPtr = idx;
412
+ while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
413
+ if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
414
+ return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
415
+ }
416
+ var str = "";
417
+ while (idx < endPtr) {
418
+ var u0 = heapOrArray[idx++];
419
+ if (!(u0 & 128)) {
420
+ str += String.fromCharCode(u0);
421
+ continue;
422
+ }
423
+ var u1 = heapOrArray[idx++] & 63;
424
+ if ((u0 & 224) == 192) {
425
+ str += String.fromCharCode(((u0 & 31) << 6) | u1);
426
+ continue;
427
+ }
428
+ var u2 = heapOrArray[idx++] & 63;
429
+ if ((u0 & 240) == 224) {
430
+ u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
431
+ } else {
432
+ u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
433
+ }
434
+ if (u0 < 65536) {
435
+ str += String.fromCharCode(u0);
436
+ } else {
437
+ var ch = u0 - 65536;
438
+ str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
439
+ }
440
+ }
441
+ return str;
442
+};
443
+
444
+/**
445
+ * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
446
+ * emscripten HEAP, returns a copy of that string as a Javascript String object.
447
+ *
448
+ * @param {number} ptr
449
+ * @param {number=} maxBytesToRead - An optional length that specifies the
450
+ * maximum number of bytes to read. You can omit this parameter to scan the
451
+ * string until the first 0 byte. If maxBytesToRead is passed, and the string
452
+ * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
453
+ * string will cut short at that byte index (i.e. maxBytesToRead will not
454
+ * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
455
+ * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
456
+ * JS JIT optimizations off, so it is worth to consider consistently using one
457
+ * @return {string}
458
+ */ var UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
459
+
460
+var ___assert_fail = (condition, filename, line, func) => {
461
+ abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
462
+};
463
+
464
+var abortOnCannotGrowMemory = requestedSize => {
465
+ abort("OOM");
466
+};
467
+
468
+var _emscripten_resize_heap = requestedSize => {
469
+ var oldSize = HEAPU8.length;
470
+ requestedSize >>>= 0;
471
+ abortOnCannotGrowMemory(requestedSize);
472
+};
473
+
474
+var runtimeKeepaliveCounter = 0;
475
+
476
+var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
477
+
478
+var _proc_exit = code => {
479
+ EXITSTATUS = code;
480
+ if (!keepRuntimeAlive()) {
481
+ Module["onExit"]?.(code);
482
+ ABORT = true;
483
+ }
484
+ quit_(code, new ExitStatus(code));
485
+};
486
+
487
+/** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => {
488
+ EXITSTATUS = status;
489
+ _proc_exit(status);
490
+};
491
+
492
+var _exit = exitJS;
493
+
494
+var getCFunc = ident => {
495
+ var func = Module["_" + ident];
496
+ return func;
497
+};
498
+
499
+var writeArrayToMemory = (array, buffer) => {
500
+ HEAP8.set(array, buffer);
501
+};
502
+
503
+var lengthBytesUTF8 = str => {
504
+ var len = 0;
505
+ for (var i = 0; i < str.length; ++i) {
506
+ var c = str.charCodeAt(i);
507
+ if (c <= 127) {
508
+ len++;
509
+ } else if (c <= 2047) {
510
+ len += 2;
511
+ } else if (c >= 55296 && c <= 57343) {
512
+ len += 4;
513
+ ++i;
514
+ } else {
515
+ len += 3;
516
+ }
517
+ }
518
+ return len;
519
+};
520
+
521
+var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
522
+ if (!(maxBytesToWrite > 0)) return 0;
523
+ var startIdx = outIdx;
524
+ var endIdx = outIdx + maxBytesToWrite - 1;
525
+ for (var i = 0; i < str.length; ++i) {
526
+ var u = str.charCodeAt(i);
527
+ if (u >= 55296 && u <= 57343) {
528
+ var u1 = str.charCodeAt(++i);
529
+ u = 65536 + ((u & 1023) << 10) | (u1 & 1023);
530
+ }
531
+ if (u <= 127) {
532
+ if (outIdx >= endIdx) break;
533
+ heap[outIdx++] = u;
534
+ } else if (u <= 2047) {
535
+ if (outIdx + 1 >= endIdx) break;
536
+ heap[outIdx++] = 192 | (u >> 6);
537
+ heap[outIdx++] = 128 | (u & 63);
538
+ } else if (u <= 65535) {
539
+ if (outIdx + 2 >= endIdx) break;
540
+ heap[outIdx++] = 224 | (u >> 12);
541
+ heap[outIdx++] = 128 | ((u >> 6) & 63);
542
+ heap[outIdx++] = 128 | (u & 63);
543
+ } else {
544
+ if (outIdx + 3 >= endIdx) break;
545
+ heap[outIdx++] = 240 | (u >> 18);
546
+ heap[outIdx++] = 128 | ((u >> 12) & 63);
547
+ heap[outIdx++] = 128 | ((u >> 6) & 63);
548
+ heap[outIdx++] = 128 | (u & 63);
549
+ }
550
+ }
551
+ heap[outIdx] = 0;
552
+ return outIdx - startIdx;
553
+};
554
+
555
+var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
556
+
557
+var stringToUTF8OnStack = str => {
558
+ var size = lengthBytesUTF8(str) + 1;
559
+ var ret = stackAlloc(size);
560
+ stringToUTF8(str, ret, size);
561
+ return ret;
562
+};
563
+
564
+/**
565
+ * @param {string|null=} returnType
566
+ * @param {Array=} argTypes
567
+ * @param {Arguments|Array=} args
568
+ * @param {Object=} opts
569
+ */ var ccall = (ident, returnType, argTypes, args, opts) => {
559570
var toC = {
560571
"string": str => {
561572
var ret = 0;
562573
if (str !== null && str !== undefined && str !== 0) {
563
- var len = (str.length << 2) + 1;
564
- ret = stackAlloc(len);
565
- stringToUTF8(str, ret, len);
574
+ ret = stringToUTF8OnStack(str);
566575
}
567576
return ret;
568577
},
569578
"array": arr => {
570579
var ret = stackAlloc(arr.length);
@@ -598,51 +607,46 @@
598607
if (stack !== 0) stackRestore(stack);
599608
return convertReturnValue(ret);
600609
}
601610
ret = onDone(ret);
602611
return ret;
603
-}
612
+};
604613
605
-function cwrap(ident, returnType, argTypes, opts) {
606
- argTypes = argTypes || [];
607
- var numericArgs = argTypes.every(type => type === "number" || type === "boolean");
614
+/**
615
+ * @param {string=} returnType
616
+ * @param {Array=} argTypes
617
+ * @param {Object=} opts
618
+ */ var cwrap = (ident, returnType, argTypes, opts) => {
619
+ var numericArgs = !argTypes || argTypes.every(type => type === "number" || type === "boolean");
608620
var numericRet = returnType !== "string";
609621
if (numericRet && numericArgs && !opts) {
610622
return getCFunc(ident);
611623
}
612624
return function() {
613625
return ccall(ident, returnType, argTypes, arguments, opts);
614626
};
615
-}
616
-
617
-var asmLibraryArg = {
618
- "a": ___assert_fail,
619
- "b": _emscripten_resize_heap,
620
- "c": _exit
621
-};
622
-
623
-var asm = createWasm();
624
-
625
-var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
626
- return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["e"]).apply(null, arguments);
627
-};
628
-
629
-var _pikchr = Module["_pikchr"] = function() {
630
- return (_pikchr = Module["_pikchr"] = Module["asm"]["f"]).apply(null, arguments);
631
-};
632
-
633
-var stackSave = Module["stackSave"] = function() {
634
- return (stackSave = Module["stackSave"] = Module["asm"]["h"]).apply(null, arguments);
635
-};
636
-
637
-var stackRestore = Module["stackRestore"] = function() {
638
- return (stackRestore = Module["stackRestore"] = Module["asm"]["i"]).apply(null, arguments);
639
-};
640
-
641
-var stackAlloc = Module["stackAlloc"] = function() {
642
- return (stackAlloc = Module["stackAlloc"] = Module["asm"]["j"]).apply(null, arguments);
643
-};
627
+};
628
+
629
+var wasmImports = {
630
+ /** @export */ a: ___assert_fail,
631
+ /** @export */ b: _emscripten_resize_heap,
632
+ /** @export */ c: _exit
633
+};
634
+
635
+var wasmExports = createWasm();
636
+
637
+var ___wasm_call_ctors = () => (___wasm_call_ctors = wasmExports["e"])();
638
+
639
+var _pikchr = Module["_pikchr"] = (a0, a1, a2, a3, a4) => (_pikchr = Module["_pikchr"] = wasmExports["f"])(a0, a1, a2, a3, a4);
640
+
641
+var stackSave = () => (stackSave = wasmExports["h"])();
642
+
643
+var stackRestore = a0 => (stackRestore = wasmExports["i"])(a0);
644
+
645
+var stackAlloc = a0 => (stackAlloc = wasmExports["j"])(a0);
646
+
647
+Module["stackAlloc"] = stackAlloc;
644648
645649
Module["stackSave"] = stackSave;
646650
647651
Module["stackRestore"] = stackRestore;
648652
@@ -657,12 +661,11 @@
657661
dependenciesFulfilled = function runCaller() {
658662
if (!calledRun) run();
659663
if (!calledRun) dependenciesFulfilled = runCaller;
660664
};
661665
662
-function run(args) {
663
- args = args || arguments_;
666
+function run() {
664667
if (runDependencies > 0) {
665668
return;
666669
}
667670
preRun();
668671
if (runDependencies > 0) {
@@ -699,15 +702,13 @@
699702
}
700703
701704
run();
702705
703706
704
- return initPikchrModule.ready
707
+ return moduleArg.ready
705708
}
706709
);
707710
})();
708711
if (typeof exports === 'object' && typeof module === 'object')
709712
module.exports = initPikchrModule;
710713
else if (typeof define === 'function' && define['amd'])
711
- define([], function() { return initPikchrModule; });
712
-else if (typeof exports === 'object')
713
- exports["initPikchrModule"] = initPikchrModule;
714
+ define([], () => initPikchrModule);
714715
--- extsrc/pikchr.js
+++ extsrc/pikchr.js
@@ -1,18 +1,17 @@
1
2 var initPikchrModule = (() => {
3 var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
4
5 return (
6 function(config) {
7 var initPikchrModule = config || {};
8
9 var Module = typeof initPikchrModule != "undefined" ? initPikchrModule : {};
10
11 var readyPromiseResolve, readyPromiseReject;
12
13 Module["ready"] = new Promise(function(resolve, reject) {
14 readyPromiseResolve = resolve;
15 readyPromiseReject = reject;
16 });
17
18 var moduleOverrides = Object.assign({}, Module);
@@ -36,11 +35,11 @@
36 return Module["locateFile"](path, scriptDirectory);
37 }
38 return scriptDirectory + path;
39 }
40
41 var read_, readAsync, readBinary, setWindowTitle;
42
43 if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
44 if (ENVIRONMENT_IS_WORKER) {
45 scriptDirectory = self.location.href;
46 } else if (typeof document != "undefined" && document.currentScript) {
@@ -47,52 +46,51 @@
47 scriptDirectory = document.currentScript.src;
48 }
49 if (_scriptDir) {
50 scriptDirectory = _scriptDir;
51 }
52 if (scriptDirectory.indexOf("blob:") !== 0) {
53 scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1);
54 } else {
55 scriptDirectory = "";
56 }
57 {
58 read_ = url => {
59 var xhr = new XMLHttpRequest();
60 xhr.open("GET", url, false);
61 xhr.send(null);
62 return xhr.responseText;
63 };
64 if (ENVIRONMENT_IS_WORKER) {
65 readBinary = url => {
66 var xhr = new XMLHttpRequest();
67 xhr.open("GET", url, false);
68 xhr.responseType = "arraybuffer";
69 xhr.send(null);
70 return new Uint8Array(xhr.response);
71 };
72 }
73 readAsync = (url, onload, onerror) => {
74 var xhr = new XMLHttpRequest();
75 xhr.open("GET", url, true);
76 xhr.responseType = "arraybuffer";
77 xhr.onload = () => {
78 if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
79 onload(xhr.response);
80 return;
81 }
82 onerror();
83 };
84 xhr.onerror = onerror;
85 xhr.send(null);
86 };
87 }
88 setWindowTitle = title => document.title = title;
89 } else {}
90
91 var out = Module["print"] || console.log.bind(console);
92
93 var err = Module["printErr"] || console.warn.bind(console);
94
95 Object.assign(Module, moduleOverrides);
96
97 moduleOverrides = null;
98
@@ -104,12 +102,10 @@
104
105 var wasmBinary;
106
107 if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"];
108
109 var noExitRuntime = Module["noExitRuntime"] || true;
110
111 if (typeof WebAssembly != "object") {
112 abort("no native wasm support detected");
113 }
114
115 var wasmMemory;
@@ -116,119 +112,32 @@
116
117 var ABORT = false;
118
119 var EXITSTATUS;
120
121 var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined;
122
123 function UTF8ArrayToString(heapOrArray, idx, maxBytesToRead) {
124 var endIdx = idx + maxBytesToRead;
125 var endPtr = idx;
126 while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
127 if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
128 return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
129 }
130 var str = "";
131 while (idx < endPtr) {
132 var u0 = heapOrArray[idx++];
133 if (!(u0 & 128)) {
134 str += String.fromCharCode(u0);
135 continue;
136 }
137 var u1 = heapOrArray[idx++] & 63;
138 if ((u0 & 224) == 192) {
139 str += String.fromCharCode((u0 & 31) << 6 | u1);
140 continue;
141 }
142 var u2 = heapOrArray[idx++] & 63;
143 if ((u0 & 240) == 224) {
144 u0 = (u0 & 15) << 12 | u1 << 6 | u2;
145 } else {
146 u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | heapOrArray[idx++] & 63;
147 }
148 if (u0 < 65536) {
149 str += String.fromCharCode(u0);
150 } else {
151 var ch = u0 - 65536;
152 str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);
153 }
154 }
155 return str;
156 }
157
158 function UTF8ToString(ptr, maxBytesToRead) {
159 return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
160 }
161
162 function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
163 if (!(maxBytesToWrite > 0)) return 0;
164 var startIdx = outIdx;
165 var endIdx = outIdx + maxBytesToWrite - 1;
166 for (var i = 0; i < str.length; ++i) {
167 var u = str.charCodeAt(i);
168 if (u >= 55296 && u <= 57343) {
169 var u1 = str.charCodeAt(++i);
170 u = 65536 + ((u & 1023) << 10) | u1 & 1023;
171 }
172 if (u <= 127) {
173 if (outIdx >= endIdx) break;
174 heap[outIdx++] = u;
175 } else if (u <= 2047) {
176 if (outIdx + 1 >= endIdx) break;
177 heap[outIdx++] = 192 | u >> 6;
178 heap[outIdx++] = 128 | u & 63;
179 } else if (u <= 65535) {
180 if (outIdx + 2 >= endIdx) break;
181 heap[outIdx++] = 224 | u >> 12;
182 heap[outIdx++] = 128 | u >> 6 & 63;
183 heap[outIdx++] = 128 | u & 63;
184 } else {
185 if (outIdx + 3 >= endIdx) break;
186 heap[outIdx++] = 240 | u >> 18;
187 heap[outIdx++] = 128 | u >> 12 & 63;
188 heap[outIdx++] = 128 | u >> 6 & 63;
189 heap[outIdx++] = 128 | u & 63;
190 }
191 }
192 heap[outIdx] = 0;
193 return outIdx - startIdx;
194 }
195
196 function stringToUTF8(str, outPtr, maxBytesToWrite) {
197 return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
198 }
199
200 var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
201
202 function updateMemoryViews() {
203 var b = wasmMemory.buffer;
204 Module["HEAP8"] = HEAP8 = new Int8Array(b);
205 Module["HEAP16"] = HEAP16 = new Int16Array(b);
206 Module["HEAP32"] = HEAP32 = new Int32Array(b);
207 Module["HEAPU8"] = HEAPU8 = new Uint8Array(b);
208 Module["HEAPU16"] = HEAPU16 = new Uint16Array(b);
 
209 Module["HEAPU32"] = HEAPU32 = new Uint32Array(b);
210 Module["HEAPF32"] = HEAPF32 = new Float32Array(b);
211 Module["HEAPF64"] = HEAPF64 = new Float64Array(b);
212 }
213
214 var INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 16777216;
215
216 var wasmTable;
217
218 var __ATPRERUN__ = [];
219
220 var __ATINIT__ = [];
221
222 var __ATPOSTRUN__ = [];
223
224 var runtimeInitialized = false;
225
226 function keepRuntimeAlive() {
227 return noExitRuntime;
228 }
229
230 function preRun() {
231 if (Module["preRun"]) {
232 if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
233 while (Module["preRun"].length) {
234 addOnPreRun(Module["preRun"].shift());
@@ -270,20 +179,16 @@
270
271 var dependenciesFulfilled = null;
272
273 function addRunDependency(id) {
274 runDependencies++;
275 if (Module["monitorRunDependencies"]) {
276 Module["monitorRunDependencies"](runDependencies);
277 }
278 }
279
280 function removeRunDependency(id) {
281 runDependencies--;
282 if (Module["monitorRunDependencies"]) {
283 Module["monitorRunDependencies"](runDependencies);
284 }
285 if (runDependencies == 0) {
286 if (runDependencyWatcher !== null) {
287 clearInterval(runDependencyWatcher);
288 runDependencyWatcher = null;
289 }
@@ -293,278 +198,382 @@
293 callback();
294 }
295 }
296 }
297
298 function abort(what) {
299 if (Module["onAbort"]) {
300 Module["onAbort"](what);
301 }
302 what = "Aborted(" + what + ")";
303 err(what);
304 ABORT = true;
305 EXITSTATUS = 1;
306 what += ". Build with -sASSERTIONS for more info.";
307 var e = new WebAssembly.RuntimeError(what);
308 readyPromiseReject(e);
309 throw e;
310 }
311
312 var dataURIPrefix = "data:application/octet-stream;base64,";
313
314 function isDataURI(filename) {
315 return filename.startsWith(dataURIPrefix);
316 }
 
317
318 var wasmBinaryFile;
319
320 wasmBinaryFile = "pikchr.wasm";
321
322 if (!isDataURI(wasmBinaryFile)) {
323 wasmBinaryFile = locateFile(wasmBinaryFile);
324 }
325
326 function getBinary(file) {
327 try {
328 if (file == wasmBinaryFile && wasmBinary) {
329 return new Uint8Array(wasmBinary);
330 }
331 if (readBinary) {
332 return readBinary(file);
333 }
334 throw "both async and sync fetching of the wasm failed";
335 } catch (err) {
336 abort(err);
337 }
338 }
339
340 function getBinaryPromise() {
341 if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
342 if (typeof fetch == "function") {
343 return fetch(wasmBinaryFile, {
344 credentials: "same-origin"
345 }).then(function(response) {
346 if (!response["ok"]) {
347 throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
348 }
349 return response["arrayBuffer"]();
350 }).catch(function() {
351 return getBinary(wasmBinaryFile);
352 });
353 }
354 }
355 return Promise.resolve().then(function() {
356 return getBinary(wasmBinaryFile);
357 });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358 }
359
360 function createWasm() {
361 var info = {
362 "a": asmLibraryArg
363 };
364 function receiveInstance(instance, module) {
365 var exports = instance.exports;
366 Module["asm"] = exports;
367 wasmMemory = Module["asm"]["d"];
368 updateMemoryViews();
369 wasmTable = Module["asm"]["g"];
370 addOnInit(Module["asm"]["e"]);
371 removeRunDependency("wasm-instantiate");
 
372 }
373 addRunDependency("wasm-instantiate");
374 function receiveInstantiationResult(result) {
375 receiveInstance(result["instance"]);
376 }
377 function instantiateArrayBuffer(receiver) {
378 return getBinaryPromise().then(function(binary) {
379 return WebAssembly.instantiate(binary, info);
380 }).then(function(instance) {
381 return instance;
382 }).then(receiver, function(reason) {
383 err("failed to asynchronously prepare wasm: " + reason);
384 abort(reason);
385 });
386 }
387 function instantiateAsync() {
388 if (!wasmBinary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(wasmBinaryFile) && typeof fetch == "function") {
389 return fetch(wasmBinaryFile, {
390 credentials: "same-origin"
391 }).then(function(response) {
392 var result = WebAssembly.instantiateStreaming(response, info);
393 return result.then(receiveInstantiationResult, function(reason) {
394 err("wasm streaming compile failed: " + reason);
395 err("falling back to ArrayBuffer instantiation");
396 return instantiateArrayBuffer(receiveInstantiationResult);
397 });
398 });
399 } else {
400 return instantiateArrayBuffer(receiveInstantiationResult);
401 }
402 }
403 if (Module["instantiateWasm"]) {
404 try {
405 var exports = Module["instantiateWasm"](info, receiveInstance);
406 return exports;
407 } catch (e) {
408 err("Module.instantiateWasm callback failed with error: " + e);
409 readyPromiseReject(e);
410 }
411 }
412 instantiateAsync().catch(readyPromiseReject);
413 return {};
414 }
415
416 var tempDouble;
417
418 var tempI64;
419
420 function ExitStatus(status) {
421 this.name = "ExitStatus";
422 this.message = "Program terminated with exit(" + status + ")";
423 this.status = status;
424 }
425
426 function callRuntimeCallbacks(callbacks) {
427 while (callbacks.length > 0) {
428 callbacks.shift()(Module);
429 }
430 }
431
432 function getValue(ptr, type = "i8") {
433 if (type.endsWith("*")) type = "*";
434 switch (type) {
435 case "i1":
436 return HEAP8[ptr >> 0];
437
438 case "i8":
439 return HEAP8[ptr >> 0];
440
441 case "i16":
442 return HEAP16[ptr >> 1];
443
444 case "i32":
445 return HEAP32[ptr >> 2];
446
447 case "i64":
448 return HEAP32[ptr >> 2];
449
450 case "float":
451 return HEAPF32[ptr >> 2];
452
453 case "double":
454 return HEAPF64[ptr >> 3];
455
456 case "*":
457 return HEAPU32[ptr >> 2];
458
459 default:
460 abort("invalid type for getValue: " + type);
461 }
462 return null;
463 }
464
465 function setValue(ptr, value, type = "i8") {
466 if (type.endsWith("*")) type = "*";
467 switch (type) {
468 case "i1":
469 HEAP8[ptr >> 0] = value;
470 break;
471
472 case "i8":
473 HEAP8[ptr >> 0] = value;
474 break;
475
476 case "i16":
477 HEAP16[ptr >> 1] = value;
478 break;
479
480 case "i32":
481 HEAP32[ptr >> 2] = value;
482 break;
483
484 case "i64":
485 tempI64 = [ value >>> 0, (tempDouble = value, +Math.abs(tempDouble) >= 1 ? tempDouble > 0 ? (Math.min(+Math.floor(tempDouble / 4294967296), 4294967295) | 0) >>> 0 : ~~+Math.ceil((tempDouble - +(~~tempDouble >>> 0)) / 4294967296) >>> 0 : 0) ],
486 HEAP32[ptr >> 2] = tempI64[0], HEAP32[ptr + 4 >> 2] = tempI64[1];
487 break;
488
489 case "float":
490 HEAPF32[ptr >> 2] = value;
491 break;
492
493 case "double":
494 HEAPF64[ptr >> 3] = value;
495 break;
496
497 case "*":
498 HEAPU32[ptr >> 2] = value;
499 break;
500
501 default:
502 abort("invalid type for setValue: " + type);
503 }
504 }
505
506 function ___assert_fail(condition, filename, line, func) {
507 abort("Assertion failed: " + UTF8ToString(condition) + ", at: " + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
508 }
509
510 function abortOnCannotGrowMemory(requestedSize) {
511 abort("OOM");
512 }
513
514 function _emscripten_resize_heap(requestedSize) {
515 var oldSize = HEAPU8.length;
516 requestedSize = requestedSize >>> 0;
517 abortOnCannotGrowMemory(requestedSize);
518 }
519
520 var SYSCALLS = {
521 varargs: undefined,
522 get: function() {
523 SYSCALLS.varargs += 4;
524 var ret = HEAP32[SYSCALLS.varargs - 4 >> 2];
525 return ret;
526 },
527 getStr: function(ptr) {
528 var ret = UTF8ToString(ptr);
529 return ret;
530 }
531 };
532
533 function _proc_exit(code) {
534 EXITSTATUS = code;
535 if (!keepRuntimeAlive()) {
536 if (Module["onExit"]) Module["onExit"](code);
537 ABORT = true;
538 }
539 quit_(code, new ExitStatus(code));
540 }
541
542 function exitJS(status, implicit) {
543 EXITSTATUS = status;
544 _proc_exit(status);
545 }
546
547 var _exit = exitJS;
548
549 function getCFunc(ident) {
550 var func = Module["_" + ident];
551 return func;
552 }
553
554 function writeArrayToMemory(array, buffer) {
555 HEAP8.set(array, buffer);
556 }
557
558 function ccall(ident, returnType, argTypes, args, opts) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559 var toC = {
560 "string": str => {
561 var ret = 0;
562 if (str !== null && str !== undefined && str !== 0) {
563 var len = (str.length << 2) + 1;
564 ret = stackAlloc(len);
565 stringToUTF8(str, ret, len);
566 }
567 return ret;
568 },
569 "array": arr => {
570 var ret = stackAlloc(arr.length);
@@ -598,51 +607,46 @@
598 if (stack !== 0) stackRestore(stack);
599 return convertReturnValue(ret);
600 }
601 ret = onDone(ret);
602 return ret;
603 }
604
605 function cwrap(ident, returnType, argTypes, opts) {
606 argTypes = argTypes || [];
607 var numericArgs = argTypes.every(type => type === "number" || type === "boolean");
 
 
 
608 var numericRet = returnType !== "string";
609 if (numericRet && numericArgs && !opts) {
610 return getCFunc(ident);
611 }
612 return function() {
613 return ccall(ident, returnType, argTypes, arguments, opts);
614 };
615 }
616
617 var asmLibraryArg = {
618 "a": ___assert_fail,
619 "b": _emscripten_resize_heap,
620 "c": _exit
621 };
622
623 var asm = createWasm();
624
625 var ___wasm_call_ctors = Module["___wasm_call_ctors"] = function() {
626 return (___wasm_call_ctors = Module["___wasm_call_ctors"] = Module["asm"]["e"]).apply(null, arguments);
627 };
628
629 var _pikchr = Module["_pikchr"] = function() {
630 return (_pikchr = Module["_pikchr"] = Module["asm"]["f"]).apply(null, arguments);
631 };
632
633 var stackSave = Module["stackSave"] = function() {
634 return (stackSave = Module["stackSave"] = Module["asm"]["h"]).apply(null, arguments);
635 };
636
637 var stackRestore = Module["stackRestore"] = function() {
638 return (stackRestore = Module["stackRestore"] = Module["asm"]["i"]).apply(null, arguments);
639 };
640
641 var stackAlloc = Module["stackAlloc"] = function() {
642 return (stackAlloc = Module["stackAlloc"] = Module["asm"]["j"]).apply(null, arguments);
643 };
644
645 Module["stackSave"] = stackSave;
646
647 Module["stackRestore"] = stackRestore;
648
@@ -657,12 +661,11 @@
657 dependenciesFulfilled = function runCaller() {
658 if (!calledRun) run();
659 if (!calledRun) dependenciesFulfilled = runCaller;
660 };
661
662 function run(args) {
663 args = args || arguments_;
664 if (runDependencies > 0) {
665 return;
666 }
667 preRun();
668 if (runDependencies > 0) {
@@ -699,15 +702,13 @@
699 }
700
701 run();
702
703
704 return initPikchrModule.ready
705 }
706 );
707 })();
708 if (typeof exports === 'object' && typeof module === 'object')
709 module.exports = initPikchrModule;
710 else if (typeof define === 'function' && define['amd'])
711 define([], function() { return initPikchrModule; });
712 else if (typeof exports === 'object')
713 exports["initPikchrModule"] = initPikchrModule;
714
--- extsrc/pikchr.js
+++ extsrc/pikchr.js
@@ -1,18 +1,17 @@
1
2 var initPikchrModule = (() => {
3 var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
4
5 return (
6 function(moduleArg = {}) {
 
7
8 var Module = moduleArg;
9
10 var readyPromiseResolve, readyPromiseReject;
11
12 Module["ready"] = new Promise((resolve, reject) => {
13 readyPromiseResolve = resolve;
14 readyPromiseReject = reject;
15 });
16
17 var moduleOverrides = Object.assign({}, Module);
@@ -36,11 +35,11 @@
35 return Module["locateFile"](path, scriptDirectory);
36 }
37 return scriptDirectory + path;
38 }
39
40 var read_, readAsync, readBinary;
41
42 if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
43 if (ENVIRONMENT_IS_WORKER) {
44 scriptDirectory = self.location.href;
45 } else if (typeof document != "undefined" && document.currentScript) {
@@ -47,52 +46,51 @@
46 scriptDirectory = document.currentScript.src;
47 }
48 if (_scriptDir) {
49 scriptDirectory = _scriptDir;
50 }
51 if (scriptDirectory.startsWith("blob:")) {
52 scriptDirectory = "";
53 } else {
54 scriptDirectory = scriptDirectory.substr(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1);
55 }
56 {
57 read_ = url => {
58 var xhr = new XMLHttpRequest;
59 xhr.open("GET", url, false);
60 xhr.send(null);
61 return xhr.responseText;
62 };
63 if (ENVIRONMENT_IS_WORKER) {
64 readBinary = url => {
65 var xhr = new XMLHttpRequest;
66 xhr.open("GET", url, false);
67 xhr.responseType = "arraybuffer";
68 xhr.send(null);
69 return new Uint8Array(/** @type{!ArrayBuffer} */ (xhr.response));
70 };
71 }
72 readAsync = (url, onload, onerror) => {
73 var xhr = new XMLHttpRequest;
74 xhr.open("GET", url, true);
75 xhr.responseType = "arraybuffer";
76 xhr.onload = () => {
77 if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) {
78 onload(xhr.response);
79 return;
80 }
81 onerror();
82 };
83 xhr.onerror = onerror;
84 xhr.send(null);
85 };
86 }
 
87 } else {}
88
89 var out = Module["print"] || console.log.bind(console);
90
91 var err = Module["printErr"] || console.error.bind(console);
92
93 Object.assign(Module, moduleOverrides);
94
95 moduleOverrides = null;
96
@@ -104,12 +102,10 @@
102
103 var wasmBinary;
104
105 if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"];
106
 
 
107 if (typeof WebAssembly != "object") {
108 abort("no native wasm support detected");
109 }
110
111 var wasmMemory;
@@ -116,119 +112,32 @@
112
113 var ABORT = false;
114
115 var EXITSTATUS;
116
117 var /** @type {!Int8Array} */ HEAP8, /** @type {!Uint8Array} */ HEAPU8, /** @type {!Int16Array} */ HEAP16, /** @type {!Uint16Array} */ HEAPU16, /** @type {!Int32Array} */ HEAP32, /** @type {!Uint32Array} */ HEAPU32, /** @type {!Float32Array} */ HEAPF32, /** @type {!Float64Array} */ HEAPF64;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
119 function updateMemoryViews() {
120 var b = wasmMemory.buffer;
121 Module["HEAP8"] = HEAP8 = new Int8Array(b);
122 Module["HEAP16"] = HEAP16 = new Int16Array(b);
 
123 Module["HEAPU8"] = HEAPU8 = new Uint8Array(b);
124 Module["HEAPU16"] = HEAPU16 = new Uint16Array(b);
125 Module["HEAP32"] = HEAP32 = new Int32Array(b);
126 Module["HEAPU32"] = HEAPU32 = new Uint32Array(b);
127 Module["HEAPF32"] = HEAPF32 = new Float32Array(b);
128 Module["HEAPF64"] = HEAPF64 = new Float64Array(b);
129 }
130
 
 
 
 
131 var __ATPRERUN__ = [];
132
133 var __ATINIT__ = [];
134
135 var __ATPOSTRUN__ = [];
136
137 var runtimeInitialized = false;
138
 
 
 
 
139 function preRun() {
140 if (Module["preRun"]) {
141 if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
142 while (Module["preRun"].length) {
143 addOnPreRun(Module["preRun"].shift());
@@ -270,20 +179,16 @@
179
180 var dependenciesFulfilled = null;
181
182 function addRunDependency(id) {
183 runDependencies++;
184 Module["monitorRunDependencies"]?.(runDependencies);
 
 
185 }
186
187 function removeRunDependency(id) {
188 runDependencies--;
189 Module["monitorRunDependencies"]?.(runDependencies);
 
 
190 if (runDependencies == 0) {
191 if (runDependencyWatcher !== null) {
192 clearInterval(runDependencyWatcher);
193 runDependencyWatcher = null;
194 }
@@ -293,278 +198,382 @@
198 callback();
199 }
200 }
201 }
202
203 /** @param {string|number=} what */ function abort(what) {
204 Module["onAbort"]?.(what);
 
 
205 what = "Aborted(" + what + ")";
206 err(what);
207 ABORT = true;
208 EXITSTATUS = 1;
209 what += ". Build with -sASSERTIONS for more info.";
210 /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what);
211 readyPromiseReject(e);
212 throw e;
213 }
214
215 var dataURIPrefix = "data:application/octet-stream;base64,";
216
217 /**
218 * Indicates whether filename is a base64 data URI.
219 * @noinline
220 */ var isDataURI = filename => filename.startsWith(dataURIPrefix);
221
222 var wasmBinaryFile;
223
224 wasmBinaryFile = "pikchr.wasm";
225
226 if (!isDataURI(wasmBinaryFile)) {
227 wasmBinaryFile = locateFile(wasmBinaryFile);
228 }
229
230 function getBinarySync(file) {
231 if (file == wasmBinaryFile && wasmBinary) {
232 return new Uint8Array(wasmBinary);
233 }
234 if (readBinary) {
235 return readBinary(file);
236 }
237 throw "both async and sync fetching of the wasm failed";
238 }
239
240 function getBinaryPromise(binaryFile) {
 
 
 
 
241 if (!wasmBinary && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER)) {
242 if (typeof fetch == "function") {
243 return fetch(binaryFile, {
244 credentials: "same-origin"
245 }).then(response => {
246 if (!response["ok"]) {
247 throw `failed to load wasm binary file at '${binaryFile}'`;
248 }
249 return response["arrayBuffer"]();
250 }).catch(() => getBinarySync(binaryFile));
251 }
252 }
253 return Promise.resolve().then(() => getBinarySync(binaryFile));
254 }
255
256 function instantiateArrayBuffer(binaryFile, imports, receiver) {
257 return getBinaryPromise(binaryFile).then(binary => WebAssembly.instantiate(binary, imports)).then(instance => instance).then(receiver, reason => {
258 err(`failed to asynchronously prepare wasm: ${reason}`);
259 abort(reason);
260 });
261 }
262
263 function instantiateAsync(binary, binaryFile, imports, callback) {
264 if (!binary && typeof WebAssembly.instantiateStreaming == "function" && !isDataURI(binaryFile) && typeof fetch == "function") {
265 return fetch(binaryFile, {
266 credentials: "same-origin"
267 }).then(response => {
268 /** @suppress {checkTypes} */ var result = WebAssembly.instantiateStreaming(response, imports);
269 return result.then(callback, function(reason) {
270 err(`wasm streaming compile failed: ${reason}`);
271 err("falling back to ArrayBuffer instantiation");
272 return instantiateArrayBuffer(binaryFile, imports, callback);
273 });
274 });
275 }
276 return instantiateArrayBuffer(binaryFile, imports, callback);
277 }
278
279 function createWasm() {
280 var info = {
281 "a": wasmImports
282 };
283 /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) {
284 wasmExports = instance.exports;
285 wasmMemory = wasmExports["d"];
 
286 updateMemoryViews();
287 addOnInit(wasmExports["e"]);
 
288 removeRunDependency("wasm-instantiate");
289 return wasmExports;
290 }
291 addRunDependency("wasm-instantiate");
292 function receiveInstantiationResult(result) {
293 receiveInstance(result["instance"]);
294 }
295 if (Module["instantiateWasm"]) {
296 try {
297 return Module["instantiateWasm"](info, receiveInstance);
298 } catch (e) {
299 err(`Module.instantiateWasm callback failed with error: ${e}`);
300 readyPromiseReject(e);
301 }
302 }
303 instantiateAsync(wasmBinary, wasmBinaryFile, info, receiveInstantiationResult).catch(readyPromiseReject);
304 return {};
305 }
306
307 /** @constructor */ function ExitStatus(status) {
308 this.name = "ExitStatus";
309 this.message = `Program terminated with exit(${status})`;
310 this.status = status;
311 }
312
313 var callRuntimeCallbacks = callbacks => {
314 while (callbacks.length > 0) {
315 callbacks.shift()(Module);
316 }
317 };
318
319 /**
320 * @param {number} ptr
321 * @param {string} type
322 */ function getValue(ptr, type = "i8") {
323 if (type.endsWith("*")) type = "*";
324 switch (type) {
325 case "i1":
326 return HEAP8[((ptr) >> 0)];
327
328 case "i8":
329 return HEAP8[((ptr) >> 0)];
330
331 case "i16":
332 return HEAP16[((ptr) >> 1)];
333
334 case "i32":
335 return HEAP32[((ptr) >> 2)];
336
337 case "i64":
338 abort("to do getValue(i64) use WASM_BIGINT");
339
340 case "float":
341 return HEAPF32[((ptr) >> 2)];
342
343 case "double":
344 return HEAPF64[((ptr) >> 3)];
345
346 case "*":
347 return HEAPU32[((ptr) >> 2)];
348
349 default:
350 abort(`invalid type for getValue: ${type}`);
351 }
352 }
353
354 var noExitRuntime = Module["noExitRuntime"] || true;
355
356 /**
357 * @param {number} ptr
358 * @param {number} value
359 * @param {string} type
360 */ function setValue(ptr, value, type = "i8") {
361 if (type.endsWith("*")) type = "*";
362 switch (type) {
363 case "i1":
364 HEAP8[((ptr) >> 0)] = value;
365 break;
366
367 case "i8":
368 HEAP8[((ptr) >> 0)] = value;
369 break;
370
371 case "i16":
372 HEAP16[((ptr) >> 1)] = value;
373 break;
374
375 case "i32":
376 HEAP32[((ptr) >> 2)] = value;
377 break;
378
379 case "i64":
380 abort("to do setValue(i64) use WASM_BIGINT");
381
382 case "float":
383 HEAPF32[((ptr) >> 2)] = value;
384 break;
385
386 case "double":
387 HEAPF64[((ptr) >> 3)] = value;
388 break;
389
390 case "*":
391 HEAPU32[((ptr) >> 2)] = value;
392 break;
393
394 default:
395 abort(`invalid type for setValue: ${type}`);
396 }
397 }
398
399 var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder("utf8") : undefined;
400
401 /**
402 * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
403 * array that contains uint8 values, returns a copy of that string as a
404 * Javascript String object.
405 * heapOrArray is either a regular array, or a JavaScript typed array view.
406 * @param {number} idx
407 * @param {number=} maxBytesToRead
408 * @return {string}
409 */ var UTF8ArrayToString = (heapOrArray, idx, maxBytesToRead) => {
410 var endIdx = idx + maxBytesToRead;
411 var endPtr = idx;
412 while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
413 if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
414 return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
415 }
416 var str = "";
417 while (idx < endPtr) {
418 var u0 = heapOrArray[idx++];
419 if (!(u0 & 128)) {
420 str += String.fromCharCode(u0);
421 continue;
422 }
423 var u1 = heapOrArray[idx++] & 63;
424 if ((u0 & 224) == 192) {
425 str += String.fromCharCode(((u0 & 31) << 6) | u1);
426 continue;
427 }
428 var u2 = heapOrArray[idx++] & 63;
429 if ((u0 & 240) == 224) {
430 u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
431 } else {
432 u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
433 }
434 if (u0 < 65536) {
435 str += String.fromCharCode(u0);
436 } else {
437 var ch = u0 - 65536;
438 str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
439 }
440 }
441 return str;
442 };
443
444 /**
445 * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
446 * emscripten HEAP, returns a copy of that string as a Javascript String object.
447 *
448 * @param {number} ptr
449 * @param {number=} maxBytesToRead - An optional length that specifies the
450 * maximum number of bytes to read. You can omit this parameter to scan the
451 * string until the first 0 byte. If maxBytesToRead is passed, and the string
452 * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
453 * string will cut short at that byte index (i.e. maxBytesToRead will not
454 * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
455 * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
456 * JS JIT optimizations off, so it is worth to consider consistently using one
457 * @return {string}
458 */ var UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
459
460 var ___assert_fail = (condition, filename, line, func) => {
461 abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
462 };
463
464 var abortOnCannotGrowMemory = requestedSize => {
465 abort("OOM");
466 };
467
468 var _emscripten_resize_heap = requestedSize => {
469 var oldSize = HEAPU8.length;
470 requestedSize >>>= 0;
471 abortOnCannotGrowMemory(requestedSize);
472 };
473
474 var runtimeKeepaliveCounter = 0;
475
476 var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
477
478 var _proc_exit = code => {
479 EXITSTATUS = code;
480 if (!keepRuntimeAlive()) {
481 Module["onExit"]?.(code);
482 ABORT = true;
483 }
484 quit_(code, new ExitStatus(code));
485 };
486
487 /** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => {
488 EXITSTATUS = status;
489 _proc_exit(status);
490 };
491
492 var _exit = exitJS;
493
494 var getCFunc = ident => {
495 var func = Module["_" + ident];
496 return func;
497 };
498
499 var writeArrayToMemory = (array, buffer) => {
500 HEAP8.set(array, buffer);
501 };
502
503 var lengthBytesUTF8 = str => {
504 var len = 0;
505 for (var i = 0; i < str.length; ++i) {
506 var c = str.charCodeAt(i);
507 if (c <= 127) {
508 len++;
509 } else if (c <= 2047) {
510 len += 2;
511 } else if (c >= 55296 && c <= 57343) {
512 len += 4;
513 ++i;
514 } else {
515 len += 3;
516 }
517 }
518 return len;
519 };
520
521 var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
522 if (!(maxBytesToWrite > 0)) return 0;
523 var startIdx = outIdx;
524 var endIdx = outIdx + maxBytesToWrite - 1;
525 for (var i = 0; i < str.length; ++i) {
526 var u = str.charCodeAt(i);
527 if (u >= 55296 && u <= 57343) {
528 var u1 = str.charCodeAt(++i);
529 u = 65536 + ((u & 1023) << 10) | (u1 & 1023);
530 }
531 if (u <= 127) {
532 if (outIdx >= endIdx) break;
533 heap[outIdx++] = u;
534 } else if (u <= 2047) {
535 if (outIdx + 1 >= endIdx) break;
536 heap[outIdx++] = 192 | (u >> 6);
537 heap[outIdx++] = 128 | (u & 63);
538 } else if (u <= 65535) {
539 if (outIdx + 2 >= endIdx) break;
540 heap[outIdx++] = 224 | (u >> 12);
541 heap[outIdx++] = 128 | ((u >> 6) & 63);
542 heap[outIdx++] = 128 | (u & 63);
543 } else {
544 if (outIdx + 3 >= endIdx) break;
545 heap[outIdx++] = 240 | (u >> 18);
546 heap[outIdx++] = 128 | ((u >> 12) & 63);
547 heap[outIdx++] = 128 | ((u >> 6) & 63);
548 heap[outIdx++] = 128 | (u & 63);
549 }
550 }
551 heap[outIdx] = 0;
552 return outIdx - startIdx;
553 };
554
555 var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
556
557 var stringToUTF8OnStack = str => {
558 var size = lengthBytesUTF8(str) + 1;
559 var ret = stackAlloc(size);
560 stringToUTF8(str, ret, size);
561 return ret;
562 };
563
564 /**
565 * @param {string|null=} returnType
566 * @param {Array=} argTypes
567 * @param {Arguments|Array=} args
568 * @param {Object=} opts
569 */ var ccall = (ident, returnType, argTypes, args, opts) => {
570 var toC = {
571 "string": str => {
572 var ret = 0;
573 if (str !== null && str !== undefined && str !== 0) {
574 ret = stringToUTF8OnStack(str);
 
 
575 }
576 return ret;
577 },
578 "array": arr => {
579 var ret = stackAlloc(arr.length);
@@ -598,51 +607,46 @@
607 if (stack !== 0) stackRestore(stack);
608 return convertReturnValue(ret);
609 }
610 ret = onDone(ret);
611 return ret;
612 };
613
614 /**
615 * @param {string=} returnType
616 * @param {Array=} argTypes
617 * @param {Object=} opts
618 */ var cwrap = (ident, returnType, argTypes, opts) => {
619 var numericArgs = !argTypes || argTypes.every(type => type === "number" || type === "boolean");
620 var numericRet = returnType !== "string";
621 if (numericRet && numericArgs && !opts) {
622 return getCFunc(ident);
623 }
624 return function() {
625 return ccall(ident, returnType, argTypes, arguments, opts);
626 };
627 };
628
629 var wasmImports = {
630 /** @export */ a: ___assert_fail,
631 /** @export */ b: _emscripten_resize_heap,
632 /** @export */ c: _exit
633 };
634
635 var wasmExports = createWasm();
636
637 var ___wasm_call_ctors = () => (___wasm_call_ctors = wasmExports["e"])();
638
639 var _pikchr = Module["_pikchr"] = (a0, a1, a2, a3, a4) => (_pikchr = Module["_pikchr"] = wasmExports["f"])(a0, a1, a2, a3, a4);
640
641 var stackSave = () => (stackSave = wasmExports["h"])();
642
643 var stackRestore = a0 => (stackRestore = wasmExports["i"])(a0);
644
645 var stackAlloc = a0 => (stackAlloc = wasmExports["j"])(a0);
646
647 Module["stackAlloc"] = stackAlloc;
 
 
 
 
 
 
 
 
648
649 Module["stackSave"] = stackSave;
650
651 Module["stackRestore"] = stackRestore;
652
@@ -657,12 +661,11 @@
661 dependenciesFulfilled = function runCaller() {
662 if (!calledRun) run();
663 if (!calledRun) dependenciesFulfilled = runCaller;
664 };
665
666 function run() {
 
667 if (runDependencies > 0) {
668 return;
669 }
670 preRun();
671 if (runDependencies > 0) {
@@ -699,15 +702,13 @@
702 }
703
704 run();
705
706
707 return moduleArg.ready
708 }
709 );
710 })();
711 if (typeof exports === 'object' && typeof module === 'object')
712 module.exports = initPikchrModule;
713 else if (typeof define === 'function' && define['amd'])
714 define([], () => initPikchrModule);
 
 
715
--- extsrc/pikchr.wasm
+++ extsrc/pikchr.wasm
cannot compute difference between binary files
11
--- extsrc/pikchr.wasm
+++ extsrc/pikchr.wasm
0 annot compute difference between binary files
1
--- extsrc/pikchr.wasm
+++ extsrc/pikchr.wasm
0 annot compute difference between binary files
1
+5 -2
--- src/http.c
+++ src/http.c
@@ -312,27 +312,30 @@
312312
** change the value.
313313
**
314314
** With no arguments, show all hosts for which ssh-needs-path is true.
315315
*/
316316
void test_ssh_needs_path(void){
317
- db_find_and_open_repository(0,0);
317
+ db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
318
+ db_open_config(0,0);
318319
if( g.argc>=3 ){
319320
const char *zHost = g.argv[2];
320321
int a = -1;
321322
int rc;
322323
if( g.argc>=4 ) a = is_truth(g.argv[3]);
323324
rc = ssh_needs_path_argument(zHost, a);
324325
fossil_print("%-20s %s\n", zHost, rc ? "yes" : "no");
325326
}else{
326327
Stmt s;
327
- db_prepare(&s, "SELECT substr(name,18) FROM config"
328
+ db_swap_connections();
329
+ db_prepare(&s, "SELECT substr(name,18) FROM global_config"
328330
" WHERE name GLOB 'use-path-for-ssh:*'");
329331
while( db_step(&s)==SQLITE_ROW ){
330332
const char *zHost = db_column_text(&s,0);
331333
fossil_print("%-20s yes\n", zHost);
332334
}
333335
db_finalize(&s);
336
+ db_swap_connections();
334337
}
335338
}
336339
337340
/* Add an approprate PATH= argument to the SSH command under construction
338341
** in pCmd.
339342
--- src/http.c
+++ src/http.c
@@ -312,27 +312,30 @@
312 ** change the value.
313 **
314 ** With no arguments, show all hosts for which ssh-needs-path is true.
315 */
316 void test_ssh_needs_path(void){
317 db_find_and_open_repository(0,0);
 
318 if( g.argc>=3 ){
319 const char *zHost = g.argv[2];
320 int a = -1;
321 int rc;
322 if( g.argc>=4 ) a = is_truth(g.argv[3]);
323 rc = ssh_needs_path_argument(zHost, a);
324 fossil_print("%-20s %s\n", zHost, rc ? "yes" : "no");
325 }else{
326 Stmt s;
327 db_prepare(&s, "SELECT substr(name,18) FROM config"
 
328 " WHERE name GLOB 'use-path-for-ssh:*'");
329 while( db_step(&s)==SQLITE_ROW ){
330 const char *zHost = db_column_text(&s,0);
331 fossil_print("%-20s yes\n", zHost);
332 }
333 db_finalize(&s);
 
334 }
335 }
336
337 /* Add an approprate PATH= argument to the SSH command under construction
338 ** in pCmd.
339
--- src/http.c
+++ src/http.c
@@ -312,27 +312,30 @@
312 ** change the value.
313 **
314 ** With no arguments, show all hosts for which ssh-needs-path is true.
315 */
316 void test_ssh_needs_path(void){
317 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
318 db_open_config(0,0);
319 if( g.argc>=3 ){
320 const char *zHost = g.argv[2];
321 int a = -1;
322 int rc;
323 if( g.argc>=4 ) a = is_truth(g.argv[3]);
324 rc = ssh_needs_path_argument(zHost, a);
325 fossil_print("%-20s %s\n", zHost, rc ? "yes" : "no");
326 }else{
327 Stmt s;
328 db_swap_connections();
329 db_prepare(&s, "SELECT substr(name,18) FROM global_config"
330 " WHERE name GLOB 'use-path-for-ssh:*'");
331 while( db_step(&s)==SQLITE_ROW ){
332 const char *zHost = db_column_text(&s,0);
333 fossil_print("%-20s yes\n", zHost);
334 }
335 db_finalize(&s);
336 db_swap_connections();
337 }
338 }
339
340 /* Add an approprate PATH= argument to the SSH command under construction
341 ** in pCmd.
342
+5 -4
--- src/main.c
+++ src/main.c
@@ -3065,14 +3065,15 @@
30653065
**
30663066
** If REPOSITORY begins with a "HOST:" or "USER@HOST:" prefix, then
30673067
** the command is run on the remote host specified and the results are
30683068
** tunneled back to the local machine via SSH. This feature only works for
30693069
** the "fossil ui" command, not the "fossil server" command. The name of the
3070
-** fossil executable on the remote host is specified by the --fossilcmd option,
3071
-** or if there is no --fossilcmd, it first tries "$HOME/bin/fossil" and if
3072
-** not found there it searches for any executable named "fossil" on the
3073
-** default $PATH set by SSH on the remote.
3070
+** fossil executable on the remote host is specified by the --fossilcmd
3071
+** option, or if there is no --fossilcmd, it first tries "fossil" and if it
3072
+** is not found in the default $PATH set by SSH on the remote, it then adds
3073
+** "$HOME/bin:/usr/local/bin:/opt/homebrew/bin" to the PATH and tries again to
3074
+** run "fossil".
30743075
**
30753076
** REPOSITORY may also be a directory (aka folder) that contains one or
30763077
** more repositories with names ending in ".fossil". In this case, a
30773078
** prefix of the URL pathname is used to search the directory for an
30783079
** appropriate repository. To thwart mischief, the pathname in the URL must
30793080
--- src/main.c
+++ src/main.c
@@ -3065,14 +3065,15 @@
3065 **
3066 ** If REPOSITORY begins with a "HOST:" or "USER@HOST:" prefix, then
3067 ** the command is run on the remote host specified and the results are
3068 ** tunneled back to the local machine via SSH. This feature only works for
3069 ** the "fossil ui" command, not the "fossil server" command. The name of the
3070 ** fossil executable on the remote host is specified by the --fossilcmd option,
3071 ** or if there is no --fossilcmd, it first tries "$HOME/bin/fossil" and if
3072 ** not found there it searches for any executable named "fossil" on the
3073 ** default $PATH set by SSH on the remote.
 
3074 **
3075 ** REPOSITORY may also be a directory (aka folder) that contains one or
3076 ** more repositories with names ending in ".fossil". In this case, a
3077 ** prefix of the URL pathname is used to search the directory for an
3078 ** appropriate repository. To thwart mischief, the pathname in the URL must
3079
--- src/main.c
+++ src/main.c
@@ -3065,14 +3065,15 @@
3065 **
3066 ** If REPOSITORY begins with a "HOST:" or "USER@HOST:" prefix, then
3067 ** the command is run on the remote host specified and the results are
3068 ** tunneled back to the local machine via SSH. This feature only works for
3069 ** the "fossil ui" command, not the "fossil server" command. The name of the
3070 ** fossil executable on the remote host is specified by the --fossilcmd
3071 ** option, or if there is no --fossilcmd, it first tries "fossil" and if it
3072 ** is not found in the default $PATH set by SSH on the remote, it then adds
3073 ** "$HOME/bin:/usr/local/bin:/opt/homebrew/bin" to the PATH and tries again to
3074 ** run "fossil".
3075 **
3076 ** REPOSITORY may also be a directory (aka folder) that contains one or
3077 ** more repositories with names ending in ".fossil". In this case, a
3078 ** prefix of the URL pathname is used to search the directory for an
3079 ** appropriate repository. To thwart mischief, the pathname in the URL must
3080
+1 -1
--- src/main.mk
+++ src/main.mk
@@ -2115,11 +2115,11 @@
21152115
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
21162116
$(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
21172117
21182118
$(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
21192119
$(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
2120
- -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore \
2120
+ -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore,stackAlloc \
21212121
-sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \
21222122
-sENVIRONMENT=web \
21232123
-sMODULARIZE \
21242124
-sEXPORT_NAME=initPikchrModule \
21252125
--minify 0
21262126
--- src/main.mk
+++ src/main.mk
@@ -2115,11 +2115,11 @@
2115 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
2116 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
2117
2118 $(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
2119 $(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
2120 -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore \
2121 -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \
2122 -sENVIRONMENT=web \
2123 -sMODULARIZE \
2124 -sEXPORT_NAME=initPikchrModule \
2125 --minify 0
2126
--- src/main.mk
+++ src/main.mk
@@ -2115,11 +2115,11 @@
2115 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
2116 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
2117
2118 $(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
2119 $(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
2120 -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore,stackAlloc \
2121 -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \
2122 -sENVIRONMENT=web \
2123 -sMODULARIZE \
2124 -sEXPORT_NAME=initPikchrModule \
2125 --minify 0
2126
+1 -1
--- src/name.c
+++ src/name.c
@@ -210,11 +210,11 @@
210210
**
211211
** Return 0 if there are no matches.
212212
**
213213
** This is a tricky query to do efficiently.
214214
** If the tag is very common (ex: "trunk") then
215
-** we want to use the query identified below as Q1 - which searching
215
+** we want to use the query identified below as Q1 - which searches
216216
** the most recent EVENT table entries for the most recent with the tag.
217217
** But if the tag is relatively scarce (anything other than "trunk", basically)
218218
** then we want to do the indexed search show below as Q2.
219219
*/
220220
static int most_recent_event_with_tag(const char *zTag, const char *zType){
221221
--- src/name.c
+++ src/name.c
@@ -210,11 +210,11 @@
210 **
211 ** Return 0 if there are no matches.
212 **
213 ** This is a tricky query to do efficiently.
214 ** If the tag is very common (ex: "trunk") then
215 ** we want to use the query identified below as Q1 - which searching
216 ** the most recent EVENT table entries for the most recent with the tag.
217 ** But if the tag is relatively scarce (anything other than "trunk", basically)
218 ** then we want to do the indexed search show below as Q2.
219 */
220 static int most_recent_event_with_tag(const char *zTag, const char *zType){
221
--- src/name.c
+++ src/name.c
@@ -210,11 +210,11 @@
210 **
211 ** Return 0 if there are no matches.
212 **
213 ** This is a tricky query to do efficiently.
214 ** If the tag is very common (ex: "trunk") then
215 ** we want to use the query identified below as Q1 - which searches
216 ** the most recent EVENT table entries for the most recent with the tag.
217 ** But if the tag is relatively scarce (anything other than "trunk", basically)
218 ** then we want to do the indexed search show below as Q2.
219 */
220 static int most_recent_event_with_tag(const char *zTag, const char *zType){
221
+3 -10
--- src/popen.c
+++ src/popen.c
@@ -129,18 +129,19 @@
129129
FILE **ppOut, /* Write to child using this file descriptor */
130130
int *pChildPid, /* PID of the child process */
131131
int bDirect /* 0: run zCmd as a shell cmd. 1: run directly */
132132
){
133133
#ifdef _WIN32
134
- HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr;
134
+ HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr, hStderr;
135135
SECURITY_ATTRIBUTES saAttr;
136136
DWORD childPid = 0;
137137
int fd;
138138
139139
saAttr.nLength = sizeof(saAttr);
140140
saAttr.bInheritHandle = TRUE;
141141
saAttr.lpSecurityDescriptor = NULL;
142
+ hStderr = GetStdHandle(STD_ERROR_HANDLE);
142143
if( !CreatePipe(&hStdoutRd, &hStdoutWr, &saAttr, 4096) ){
143144
win32_fatal_error("cannot create pipe for stdout");
144145
}
145146
SetHandleInformation( hStdoutRd, HANDLE_FLAG_INHERIT, FALSE);
146147
@@ -148,16 +149,11 @@
148149
win32_fatal_error("cannot create pipe for stdin");
149150
}
150151
SetHandleInformation( hStdinWr, HANDLE_FLAG_INHERIT, FALSE);
151152
152153
win32_create_child_process(fossil_utf8_to_unicode(zCmd),
153
- hStdinRd,hStdoutWr,hStdoutWr,&childPid);
154
- /* ^^^^^^^^^ ^^^^^^^^^
155
- ** Send both stdout and stderr to to *ppOut.
156
- ** See check-in 857495ec92a521bb (2024-02-06) and earlier for
157
- ** an example of how to leave stderr going to console */
158
-
154
+ hStdinRd, hStdoutWr, hStderr,&childPid);
159155
*pChildPid = childPid;
160156
*pfdIn = _open_osfhandle(PTR_TO_INT(hStdoutRd), 0);
161157
fd = _open_osfhandle(PTR_TO_INT(hStdinWr), 0);
162158
*ppOut = _fdopen(fd, "w");
163159
CloseHandle(hStdinRd);
@@ -198,13 +194,10 @@
198194
close(1);
199195
fd = dup(pin[1]);
200196
if( fd!=1 ) fossil_panic("popen() failed to open file descriptor 1");
201197
close(pin[0]);
202198
close(pin[1]);
203
- close(2);
204
- fd = dup(1);
205
- if( fd!=2 ) fossil_panic("popen() failed to redirect stderr into stdout");
206199
if( bDirect ){
207200
execl(zCmd, zCmd, (char*)0);
208201
}else{
209202
execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
210203
}
211204
--- src/popen.c
+++ src/popen.c
@@ -129,18 +129,19 @@
129 FILE **ppOut, /* Write to child using this file descriptor */
130 int *pChildPid, /* PID of the child process */
131 int bDirect /* 0: run zCmd as a shell cmd. 1: run directly */
132 ){
133 #ifdef _WIN32
134 HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr;
135 SECURITY_ATTRIBUTES saAttr;
136 DWORD childPid = 0;
137 int fd;
138
139 saAttr.nLength = sizeof(saAttr);
140 saAttr.bInheritHandle = TRUE;
141 saAttr.lpSecurityDescriptor = NULL;
 
142 if( !CreatePipe(&hStdoutRd, &hStdoutWr, &saAttr, 4096) ){
143 win32_fatal_error("cannot create pipe for stdout");
144 }
145 SetHandleInformation( hStdoutRd, HANDLE_FLAG_INHERIT, FALSE);
146
@@ -148,16 +149,11 @@
148 win32_fatal_error("cannot create pipe for stdin");
149 }
150 SetHandleInformation( hStdinWr, HANDLE_FLAG_INHERIT, FALSE);
151
152 win32_create_child_process(fossil_utf8_to_unicode(zCmd),
153 hStdinRd,hStdoutWr,hStdoutWr,&childPid);
154 /* ^^^^^^^^^ ^^^^^^^^^
155 ** Send both stdout and stderr to to *ppOut.
156 ** See check-in 857495ec92a521bb (2024-02-06) and earlier for
157 ** an example of how to leave stderr going to console */
158
159 *pChildPid = childPid;
160 *pfdIn = _open_osfhandle(PTR_TO_INT(hStdoutRd), 0);
161 fd = _open_osfhandle(PTR_TO_INT(hStdinWr), 0);
162 *ppOut = _fdopen(fd, "w");
163 CloseHandle(hStdinRd);
@@ -198,13 +194,10 @@
198 close(1);
199 fd = dup(pin[1]);
200 if( fd!=1 ) fossil_panic("popen() failed to open file descriptor 1");
201 close(pin[0]);
202 close(pin[1]);
203 close(2);
204 fd = dup(1);
205 if( fd!=2 ) fossil_panic("popen() failed to redirect stderr into stdout");
206 if( bDirect ){
207 execl(zCmd, zCmd, (char*)0);
208 }else{
209 execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
210 }
211
--- src/popen.c
+++ src/popen.c
@@ -129,18 +129,19 @@
129 FILE **ppOut, /* Write to child using this file descriptor */
130 int *pChildPid, /* PID of the child process */
131 int bDirect /* 0: run zCmd as a shell cmd. 1: run directly */
132 ){
133 #ifdef _WIN32
134 HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr, hStderr;
135 SECURITY_ATTRIBUTES saAttr;
136 DWORD childPid = 0;
137 int fd;
138
139 saAttr.nLength = sizeof(saAttr);
140 saAttr.bInheritHandle = TRUE;
141 saAttr.lpSecurityDescriptor = NULL;
142 hStderr = GetStdHandle(STD_ERROR_HANDLE);
143 if( !CreatePipe(&hStdoutRd, &hStdoutWr, &saAttr, 4096) ){
144 win32_fatal_error("cannot create pipe for stdout");
145 }
146 SetHandleInformation( hStdoutRd, HANDLE_FLAG_INHERIT, FALSE);
147
@@ -148,16 +149,11 @@
149 win32_fatal_error("cannot create pipe for stdin");
150 }
151 SetHandleInformation( hStdinWr, HANDLE_FLAG_INHERIT, FALSE);
152
153 win32_create_child_process(fossil_utf8_to_unicode(zCmd),
154 hStdinRd, hStdoutWr, hStderr,&childPid);
 
 
 
 
 
155 *pChildPid = childPid;
156 *pfdIn = _open_osfhandle(PTR_TO_INT(hStdoutRd), 0);
157 fd = _open_osfhandle(PTR_TO_INT(hStdinWr), 0);
158 *ppOut = _fdopen(fd, "w");
159 CloseHandle(hStdinRd);
@@ -198,13 +194,10 @@
194 close(1);
195 fd = dup(pin[1]);
196 if( fd!=1 ) fossil_panic("popen() failed to open file descriptor 1");
197 close(pin[0]);
198 close(pin[1]);
 
 
 
199 if( bDirect ){
200 execl(zCmd, zCmd, (char*)0);
201 }else{
202 execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
203 }
204
+2 -6
--- src/pqueue.c
+++ src/pqueue.c
@@ -42,11 +42,10 @@
4242
struct PQueue {
4343
int cnt; /* Number of entries in the queue */
4444
int sz; /* Number of slots in a[] */
4545
struct QueueElement {
4646
int id; /* ID of the element */
47
- void *p; /* Content pointer */
4847
double value; /* Value of element. Kept in ascending order */
4948
} *a;
5049
};
5150
#endif
5251
@@ -74,11 +73,11 @@
7473
}
7574
7675
/*
7776
** Insert element e into the queue.
7877
*/
79
-void pqueuex_insert(PQueue *p, int e, double v, void *pData){
78
+void pqueuex_insert(PQueue *p, int e, double v){
8079
int i, j;
8180
if( p->cnt+1>p->sz ){
8281
pqueuex_resize(p, p->cnt+5);
8382
}
8483
for(i=0; i<p->cnt; i++){
@@ -88,29 +87,26 @@
8887
}
8988
break;
9089
}
9190
}
9291
p->a[i].id = e;
93
- p->a[i].p = pData;
9492
p->a[i].value = v;
9593
p->cnt++;
9694
}
9795
9896
/*
9997
** Extract the first element from the queue (the element with
10098
** the smallest value) and return its ID. Return 0 if the queue
10199
** is empty.
102100
*/
103
-int pqueuex_extract(PQueue *p, void **pp){
101
+int pqueuex_extract(PQueue *p){
104102
int e, i;
105103
if( p->cnt==0 ){
106
- if( pp ) *pp = 0;
107104
return 0;
108105
}
109106
e = p->a[0].id;
110
- if( pp ) *pp = p->a[0].p;
111107
for(i=0; i<p->cnt-1; i++){
112108
p->a[i] = p->a[i+1];
113109
}
114110
p->cnt--;
115111
return e;
116112
}
117113
--- src/pqueue.c
+++ src/pqueue.c
@@ -42,11 +42,10 @@
42 struct PQueue {
43 int cnt; /* Number of entries in the queue */
44 int sz; /* Number of slots in a[] */
45 struct QueueElement {
46 int id; /* ID of the element */
47 void *p; /* Content pointer */
48 double value; /* Value of element. Kept in ascending order */
49 } *a;
50 };
51 #endif
52
@@ -74,11 +73,11 @@
74 }
75
76 /*
77 ** Insert element e into the queue.
78 */
79 void pqueuex_insert(PQueue *p, int e, double v, void *pData){
80 int i, j;
81 if( p->cnt+1>p->sz ){
82 pqueuex_resize(p, p->cnt+5);
83 }
84 for(i=0; i<p->cnt; i++){
@@ -88,29 +87,26 @@
88 }
89 break;
90 }
91 }
92 p->a[i].id = e;
93 p->a[i].p = pData;
94 p->a[i].value = v;
95 p->cnt++;
96 }
97
98 /*
99 ** Extract the first element from the queue (the element with
100 ** the smallest value) and return its ID. Return 0 if the queue
101 ** is empty.
102 */
103 int pqueuex_extract(PQueue *p, void **pp){
104 int e, i;
105 if( p->cnt==0 ){
106 if( pp ) *pp = 0;
107 return 0;
108 }
109 e = p->a[0].id;
110 if( pp ) *pp = p->a[0].p;
111 for(i=0; i<p->cnt-1; i++){
112 p->a[i] = p->a[i+1];
113 }
114 p->cnt--;
115 return e;
116 }
117
--- src/pqueue.c
+++ src/pqueue.c
@@ -42,11 +42,10 @@
42 struct PQueue {
43 int cnt; /* Number of entries in the queue */
44 int sz; /* Number of slots in a[] */
45 struct QueueElement {
46 int id; /* ID of the element */
 
47 double value; /* Value of element. Kept in ascending order */
48 } *a;
49 };
50 #endif
51
@@ -74,11 +73,11 @@
73 }
74
75 /*
76 ** Insert element e into the queue.
77 */
78 void pqueuex_insert(PQueue *p, int e, double v){
79 int i, j;
80 if( p->cnt+1>p->sz ){
81 pqueuex_resize(p, p->cnt+5);
82 }
83 for(i=0; i<p->cnt; i++){
@@ -88,29 +87,26 @@
87 }
88 break;
89 }
90 }
91 p->a[i].id = e;
 
92 p->a[i].value = v;
93 p->cnt++;
94 }
95
96 /*
97 ** Extract the first element from the queue (the element with
98 ** the smallest value) and return its ID. Return 0 if the queue
99 ** is empty.
100 */
101 int pqueuex_extract(PQueue *p){
102 int e, i;
103 if( p->cnt==0 ){
 
104 return 0;
105 }
106 e = p->a[0].id;
 
107 for(i=0; i<p->cnt-1; i++){
108 p->a[i] = p->a[i+1];
109 }
110 p->cnt--;
111 return e;
112 }
113
+3 -3
--- src/tag.c
+++ src/tag.c
@@ -44,11 +44,11 @@
4444
Stmt ins; /* INSERT INTO tagxref */
4545
Stmt eventupdate; /* UPDATE event */
4646
4747
assert( tagType==0 || tagType==2 );
4848
pqueuex_init(&queue);
49
- pqueuex_insert(&queue, pid, 0.0, 0);
49
+ pqueuex_insert(&queue, pid, 0.0);
5050
5151
/* Query for children of :pid to which to propagate the tag.
5252
** Three returns: (1) rid of the child. (2) timestamp of child.
5353
** (3) True to propagate or false to block.
5454
*/
@@ -79,18 +79,18 @@
7979
if( tagid==TAG_BGCOLOR ){
8080
db_prepare(&eventupdate,
8181
"UPDATE event SET bgcolor=%Q WHERE objid=:rid", zValue
8282
);
8383
}
84
- while( (pid = pqueuex_extract(&queue, 0))!=0 ){
84
+ while( (pid = pqueuex_extract(&queue))!=0 ){
8585
db_bind_int(&s, ":pid", pid);
8686
while( db_step(&s)==SQLITE_ROW ){
8787
int doit = db_column_int(&s, 2);
8888
if( doit ){
8989
int cid = db_column_int(&s, 0);
9090
double mtime = db_column_double(&s, 1);
91
- pqueuex_insert(&queue, cid, mtime, 0);
91
+ pqueuex_insert(&queue, cid, mtime);
9292
db_bind_int(&ins, ":rid", cid);
9393
db_step(&ins);
9494
db_reset(&ins);
9595
if( tagid==TAG_BGCOLOR ){
9696
db_bind_int(&eventupdate, ":rid", cid);
9797
--- src/tag.c
+++ src/tag.c
@@ -44,11 +44,11 @@
44 Stmt ins; /* INSERT INTO tagxref */
45 Stmt eventupdate; /* UPDATE event */
46
47 assert( tagType==0 || tagType==2 );
48 pqueuex_init(&queue);
49 pqueuex_insert(&queue, pid, 0.0, 0);
50
51 /* Query for children of :pid to which to propagate the tag.
52 ** Three returns: (1) rid of the child. (2) timestamp of child.
53 ** (3) True to propagate or false to block.
54 */
@@ -79,18 +79,18 @@
79 if( tagid==TAG_BGCOLOR ){
80 db_prepare(&eventupdate,
81 "UPDATE event SET bgcolor=%Q WHERE objid=:rid", zValue
82 );
83 }
84 while( (pid = pqueuex_extract(&queue, 0))!=0 ){
85 db_bind_int(&s, ":pid", pid);
86 while( db_step(&s)==SQLITE_ROW ){
87 int doit = db_column_int(&s, 2);
88 if( doit ){
89 int cid = db_column_int(&s, 0);
90 double mtime = db_column_double(&s, 1);
91 pqueuex_insert(&queue, cid, mtime, 0);
92 db_bind_int(&ins, ":rid", cid);
93 db_step(&ins);
94 db_reset(&ins);
95 if( tagid==TAG_BGCOLOR ){
96 db_bind_int(&eventupdate, ":rid", cid);
97
--- src/tag.c
+++ src/tag.c
@@ -44,11 +44,11 @@
44 Stmt ins; /* INSERT INTO tagxref */
45 Stmt eventupdate; /* UPDATE event */
46
47 assert( tagType==0 || tagType==2 );
48 pqueuex_init(&queue);
49 pqueuex_insert(&queue, pid, 0.0);
50
51 /* Query for children of :pid to which to propagate the tag.
52 ** Three returns: (1) rid of the child. (2) timestamp of child.
53 ** (3) True to propagate or false to block.
54 */
@@ -79,18 +79,18 @@
79 if( tagid==TAG_BGCOLOR ){
80 db_prepare(&eventupdate,
81 "UPDATE event SET bgcolor=%Q WHERE objid=:rid", zValue
82 );
83 }
84 while( (pid = pqueuex_extract(&queue))!=0 ){
85 db_bind_int(&s, ":pid", pid);
86 while( db_step(&s)==SQLITE_ROW ){
87 int doit = db_column_int(&s, 2);
88 if( doit ){
89 int cid = db_column_int(&s, 0);
90 double mtime = db_column_double(&s, 1);
91 pqueuex_insert(&queue, cid, mtime);
92 db_bind_int(&ins, ":rid", cid);
93 db_step(&ins);
94 db_reset(&ins);
95 if( tagid==TAG_BGCOLOR ){
96 db_bind_int(&eventupdate, ":rid", cid);
97
+187 -13
--- src/timeline.c
+++ src/timeline.c
@@ -1568,10 +1568,134 @@
15681568
15691569
/* It looks like this may be a date. Return it with punctuation added. */
15701570
return zEDate;
15711571
}
15721572
1573
+/*
1574
+** Find the first check-in encountered with a particular tag
1575
+** when moving either forwards are backwards in time from a
1576
+** particular starting point (iFrom). Return the rid of that
1577
+** first check-in. If there are no check-ins in the decendent
1578
+** or ancestor set of check-in iFrom that match the tag, then
1579
+** return 0.
1580
+*/
1581
+static int timeline_endpoint(
1582
+ int iFrom, /* Starting point */
1583
+ const char *zEnd, /* Tag we are searching for */
1584
+ int bForward /* 1: forwards in time (descendents) 0: backwards */
1585
+){
1586
+ int tagId;
1587
+ int endId = 0;
1588
+ Stmt q;
1589
+ int ans = 0;
1590
+
1591
+ tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
1592
+ if( tagId==0 ){
1593
+ endId = symbolic_name_to_rid(zEnd, "ci");
1594
+ if( endId==0 ) return 0;
1595
+ }
1596
+ if( bForward ){
1597
+ if( tagId ){
1598
+ db_prepare(&q,
1599
+ "WITH RECURSIVE dx(id,mtime) AS ("
1600
+ " SELECT %d, event.mtime FROM event WHERE objid=%d"
1601
+ " UNION"
1602
+ " SELECT plink.cid, plink.mtime"
1603
+ " FROM dx, plink"
1604
+ " WHERE plink.pid=dx.id"
1605
+ " AND plink.mtime<=(SELECT max(event.mtime) FROM tagxref, event"
1606
+ " WHERE tagxref.tagid=%d AND tagxref.tagtype>0"
1607
+ " AND event.objid=tagxref.rid)"
1608
+ " ORDER BY plink.mtime)"
1609
+ "SELECT id FROM dx, tagxref"
1610
+ " WHERE tagid=%d AND tagtype>0 AND rid=id LIMIT 1",
1611
+ iFrom, iFrom, tagId, tagId
1612
+ );
1613
+ }else{
1614
+ db_prepare(&q,
1615
+ "WITH RECURSIVE dx(id,mtime) AS ("
1616
+ " SELECT %d, event.mtime FROM event WHERE objid=%d"
1617
+ " UNION"
1618
+ " SELECT plink.cid, plink.mtime"
1619
+ " FROM dx, plink"
1620
+ " WHERE plink.pid=dx.id"
1621
+ " AND plink.mtime<=(SELECT mtime FROM event WHERE objid=%d)"
1622
+ " ORDER BY plink.mtime)"
1623
+ "SELECT id FROM dx WHERE id=%d",
1624
+ iFrom, iFrom, endId, endId
1625
+ );
1626
+ }
1627
+ }else{
1628
+ if( tagId ){
1629
+ db_prepare(&q,
1630
+ "WITH RECURSIVE dx(id,mtime) AS ("
1631
+ " SELECT %d, event.mtime FROM event WHERE objid=%d"
1632
+ " UNION"
1633
+ " SELECT plink.pid, event.mtime"
1634
+ " FROM dx, plink, event"
1635
+ " WHERE plink.cid=dx.id AND event.objid=plink.pid"
1636
+ " AND event.mtime>=(SELECT min(event.mtime) FROM tagxref, event"
1637
+ " WHERE tagxref.tagid=%d AND tagxref.tagtype>0"
1638
+ " AND event.objid=tagxref.rid)"
1639
+ " ORDER BY event.mtime DESC)"
1640
+ "SELECT id FROM dx, tagxref"
1641
+ " WHERE tagid=%d AND tagtype>0 AND rid=id LIMIT 1",
1642
+ iFrom, iFrom, tagId, tagId
1643
+ );
1644
+ }else{
1645
+ db_prepare(&q,
1646
+ "WITH RECURSIVE dx(id,mtime) AS ("
1647
+ " SELECT %d, event.mtime FROM event WHERE objid=%d"
1648
+ " UNION"
1649
+ " SELECT plink.pid, event.mtime"
1650
+ " FROM dx, plink, event"
1651
+ " WHERE plink.cid=dx.id AND event.objid=plink.pid"
1652
+ " AND event.mtime>=(SELECT mtime FROM event WHERE objid=%d)"
1653
+ " ORDER BY event.mtime DESC)"
1654
+ "SELECT id FROM dx WHERE id=%d",
1655
+ iFrom, iFrom, endId, endId
1656
+ );
1657
+ }
1658
+ }
1659
+ if( db_step(&q)==SQLITE_ROW ){
1660
+ ans = db_column_int(&q, 0);
1661
+ }
1662
+ db_finalize(&q);
1663
+ return ans;
1664
+}
1665
+
1666
+/*
1667
+** COMMAND: test-endpoint
1668
+**
1669
+** Usage: fossil test-endpoint BASE TAG ?OPTIONS?
1670
+**
1671
+** Show the first check-in with TAG that is a descendent or ancestor
1672
+** of BASE. The first descendent checkin is shown by default. Use
1673
+** the --backto to see the first ancestor checkin.
1674
+**
1675
+** Options:
1676
+**
1677
+** --backto Show ancestor. Others defaults to descendents.
1678
+*/
1679
+void timeline_test_endpoint(void){
1680
+ int bForward = find_option("backto",0,0)==0;
1681
+ int from_rid;
1682
+ int ans;
1683
+ db_find_and_open_repository(0, 0);
1684
+ verify_all_options();
1685
+ if( g.argc!=4 ){
1686
+ usage("BASE-CHECKIN TAG ?--backto?");
1687
+ }
1688
+ from_rid = symbolic_name_to_rid(g.argv[2],"ci");
1689
+ ans = timeline_endpoint(from_rid, g.argv[3], bForward);
1690
+ if( ans ){
1691
+ fossil_print("Result: %d (%S)\n", ans, rid_to_uuid(ans));
1692
+ }else{
1693
+ fossil_print("No path found\n");
1694
+ }
1695
+}
1696
+
15731697
15741698
/*
15751699
** WEBPAGE: timeline
15761700
**
15771701
** Query parameters:
@@ -1598,14 +1722,16 @@
15981722
** bt=PRIOR ... going back to PRIOR
15991723
** d=CHECKIN Children and descendants of CHECKIN
16001724
** ft=DESCENDANT ... going forward to DESCENDANT
16011725
** dp=CHECKIN Same as 'd=CHECKIN&p=CHECKIN'
16021726
** df=CHECKIN Same as 'd=CHECKIN&n1=all&nd'. Mnemonic: "Derived From"
1603
-** bt=CHECKIN In conjunction with p=CX, this means show all
1604
-** ancestors of CX going back to the time of CHECKIN.
1605
-** All qualifying check-ins are shown unless there
1606
-** is also an n= or n1= query parameter.
1727
+** bt=CHECKIN "Back To". Show ancenstors going back to CHECKIN
1728
+** p=CX ... from CX back to time of CHECKIN
1729
+** from=CX ... shortest path from CX back to CHECKIN
1730
+** ft=CHECKIN "Forward To": Show decendents forward to CHECKIN
1731
+** d=CX ... from CX up to the time of CHECKIN
1732
+** from=CX ... shortest path from CX up to CHECKIN
16071733
** t=TAG Show only check-ins with the given TAG
16081734
** r=TAG Show check-ins related to TAG, equivalent to t=TAG&rel
16091735
** tl=TAGLIST Shorthand for t=TAGLIST&ms=brlist
16101736
** rl=TAGLIST Shorthand for r=TAGLIST&ms=brlist
16111737
** rel Show related check-ins as well as those matching t=TAG
@@ -1627,10 +1753,12 @@
16271753
** f=CHECKIN Show family (immediate parents and children) of CHECKIN
16281754
** from=CHECKIN Path from...
16291755
** to=CHECKIN ... to this
16301756
** shortest ... show only the shortest path
16311757
** rel ... also show related checkins
1758
+** bt=PRIOR ... path from CHECKIN back to PRIOR
1759
+** ft=LATER ... path from CHECKIN forward to LATER
16321760
** uf=FILE_HASH Show only check-ins that contain the given file version
16331761
** All qualifying check-ins are shown unless there is
16341762
** also an n= or n1= query parameter.
16351763
** chng=GLOBLIST Show only check-ins that involve changes to a file whose
16361764
** name matches one of the comma-separate GLOBLIST
@@ -1727,10 +1855,11 @@
17271855
int disableY = 0; /* Disable type selector on submenu */
17281856
int advancedMenu = 0; /* Use the advanced menu design */
17291857
char *zPlural; /* Ending for plural forms */
17301858
int showCherrypicks = 1; /* True to show cherrypick merges */
17311859
int haveParameterN; /* True if n= query parameter present */
1860
+ int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
17321861
17331862
url_initialize(&url, "timeline");
17341863
cgi_query_parameters_to_url(&url);
17351864
17361865
(void)P_NoBot("ss")
@@ -2043,10 +2172,30 @@
20432172
blob_append_sql(&sql,
20442173
" AND NOT EXISTS(SELECT 1 FROM tagxref"
20452174
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n",
20462175
TAG_HIDDEN
20472176
);
2177
+ }
2178
+ if( from_rid && !to_rid && (P("ft")!=0 || P("bt")!=0) ){
2179
+ const char *zTo = P("ft");
2180
+ if( zTo ){
2181
+ from_to_mode = 1;
2182
+ to_rid = timeline_endpoint(from_rid, zTo, 1);
2183
+ }else{
2184
+ from_to_mode = 2;
2185
+ zTo = P("bt");
2186
+ to_rid = timeline_endpoint(from_rid, zTo, 0);
2187
+ }
2188
+ if( to_rid ){
2189
+ cgi_replace_parameter("to", zTo);
2190
+ if( selectedRid==0 ) selectedRid = from_rid;
2191
+ if( secondaryRid==0 ) secondaryRid = to_rid;
2192
+ }else{
2193
+ to_rid = from_rid;
2194
+ blob_appendf(&desc, "There is no path from %h %s to %h.<br>Instead: ",
2195
+ P("from"), from_to_mode==1 ? "forward" : "back", zTo);
2196
+ }
20482197
}
20492198
if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
20502199
/* If from= and to= are present, display all nodes on a path connecting
20512200
** the two */
20522201
PathNode *p = 0;
@@ -2054,11 +2203,17 @@
20542203
const char *zTo = 0;
20552204
Blob ins;
20562205
int nNodeOnPath = 0;
20572206
20582207
if( from_rid && to_rid ){
2059
- p = path_shortest(from_rid, to_rid, noMerge, 0, 0);
2208
+ if( from_to_mode==0 ){
2209
+ p = path_shortest(from_rid, to_rid, noMerge, 0, 0);
2210
+ }else if( from_to_mode==1 ){
2211
+ p = path_shortest(from_rid, to_rid, 0, 1, 0);
2212
+ }else{
2213
+ p = path_shortest(to_rid, from_rid, 0, 1, 0);
2214
+ }
20602215
zFrom = P("from");
20612216
zTo = P("to");
20622217
}else{
20632218
if( path_common_ancestor(me_rid, you_rid) ){
20642219
p = path_first();
@@ -2122,19 +2277,37 @@
21222277
db_multi_exec("%s", blob_sql_text(&sql));
21232278
if( advancedMenu ){
21242279
style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
21252280
}
21262281
nNodeOnPath = db_int(0, "SELECT count(*) FROM temp.pathnode");
2127
- blob_appendf(&desc, "%d check-ins going from ", nNodeOnPath);
2282
+ if( nNodeOnPath==1 && from_to_mode>0 ){
2283
+ blob_appendf(&desc,"Check-in ");
2284
+ }else if( from_to_mode>0 ){
2285
+ blob_appendf(&desc, "%d check-ins on the shorted path from ",nNodeOnPath);
2286
+ }else{
2287
+ blob_appendf(&desc, "%d check-ins going from ", nNodeOnPath);
2288
+ }
2289
+ if( from_rid==selectedRid ){
2290
+ blob_appendf(&desc, "<span class='timelineSelected'>");
2291
+ }
21282292
blob_appendf(&desc, "%z%h</a>", href("%R/info/%h", zFrom), zFrom);
2129
- blob_append(&desc, " to ", -1);
2130
- blob_appendf(&desc, "%z%h</a>", href("%R/info/%h",zTo), zTo);
2131
- if( related ){
2132
- int nRelated = db_int(0, "SELECT count(*) FROM timeline") - nNodeOnPath;
2133
- if( nRelated>0 ){
2134
- blob_appendf(&desc, " and %d related check-in%s", nRelated,
2135
- nRelated>1 ? "s" : "");
2293
+ if( from_rid==selectedRid ) blob_appendf(&desc, "</span>");
2294
+ if( nNodeOnPath==1 && from_to_mode>0 ){
2295
+ blob_appendf(&desc, " only");
2296
+ }else{
2297
+ blob_append(&desc, " to ", -1);
2298
+ if( to_rid==secondaryRid ){
2299
+ blob_appendf(&desc,"<span class='timelineSelected timelineSecondary'>");
2300
+ }
2301
+ blob_appendf(&desc, "%z%h</a>", href("%R/info/%h",zTo), zTo);
2302
+ if( to_rid==secondaryRid ) blob_appendf(&desc, "</span>");
2303
+ if( related ){
2304
+ int nRelated = db_int(0, "SELECT count(*) FROM timeline") - nNodeOnPath;
2305
+ if( nRelated>0 ){
2306
+ blob_appendf(&desc, " and %d related check-in%s", nRelated,
2307
+ nRelated>1 ? "s" : "");
2308
+ }
21362309
}
21372310
}
21382311
addFileGlobDescription(zChng, &desc);
21392312
}else if( (p_rid || d_rid) && g.perm.Read && zTagSql==0 ){
21402313
/* If p= or d= is present, ignore all other parameters other than n= */
@@ -2680,10 +2853,11 @@
26802853
@ <pre>%h(blob_sql_text(&sql2))</pre>
26812854
}
26822855
db_multi_exec("%s", blob_sql_text(&sql2));
26832856
if( nEntry>0 ){
26842857
nEntry -= db_int(0,"select count(*) from timeline");
2858
+ if( nEntry<=0 ) nEntry = 1;
26852859
}
26862860
blob_reset(&sql2);
26872861
blob_append_sql(&sql,
26882862
" AND event.mtime<=%f ORDER BY event.mtime DESC",
26892863
rCirca
26902864
--- src/timeline.c
+++ src/timeline.c
@@ -1568,10 +1568,134 @@
1568
1569 /* It looks like this may be a date. Return it with punctuation added. */
1570 return zEDate;
1571 }
1572
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1573
1574 /*
1575 ** WEBPAGE: timeline
1576 **
1577 ** Query parameters:
@@ -1598,14 +1722,16 @@
1598 ** bt=PRIOR ... going back to PRIOR
1599 ** d=CHECKIN Children and descendants of CHECKIN
1600 ** ft=DESCENDANT ... going forward to DESCENDANT
1601 ** dp=CHECKIN Same as 'd=CHECKIN&p=CHECKIN'
1602 ** df=CHECKIN Same as 'd=CHECKIN&n1=all&nd'. Mnemonic: "Derived From"
1603 ** bt=CHECKIN In conjunction with p=CX, this means show all
1604 ** ancestors of CX going back to the time of CHECKIN.
1605 ** All qualifying check-ins are shown unless there
1606 ** is also an n= or n1= query parameter.
 
 
1607 ** t=TAG Show only check-ins with the given TAG
1608 ** r=TAG Show check-ins related to TAG, equivalent to t=TAG&rel
1609 ** tl=TAGLIST Shorthand for t=TAGLIST&ms=brlist
1610 ** rl=TAGLIST Shorthand for r=TAGLIST&ms=brlist
1611 ** rel Show related check-ins as well as those matching t=TAG
@@ -1627,10 +1753,12 @@
1627 ** f=CHECKIN Show family (immediate parents and children) of CHECKIN
1628 ** from=CHECKIN Path from...
1629 ** to=CHECKIN ... to this
1630 ** shortest ... show only the shortest path
1631 ** rel ... also show related checkins
 
 
1632 ** uf=FILE_HASH Show only check-ins that contain the given file version
1633 ** All qualifying check-ins are shown unless there is
1634 ** also an n= or n1= query parameter.
1635 ** chng=GLOBLIST Show only check-ins that involve changes to a file whose
1636 ** name matches one of the comma-separate GLOBLIST
@@ -1727,10 +1855,11 @@
1727 int disableY = 0; /* Disable type selector on submenu */
1728 int advancedMenu = 0; /* Use the advanced menu design */
1729 char *zPlural; /* Ending for plural forms */
1730 int showCherrypicks = 1; /* True to show cherrypick merges */
1731 int haveParameterN; /* True if n= query parameter present */
 
1732
1733 url_initialize(&url, "timeline");
1734 cgi_query_parameters_to_url(&url);
1735
1736 (void)P_NoBot("ss")
@@ -2043,10 +2172,30 @@
2043 blob_append_sql(&sql,
2044 " AND NOT EXISTS(SELECT 1 FROM tagxref"
2045 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n",
2046 TAG_HIDDEN
2047 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2048 }
2049 if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
2050 /* If from= and to= are present, display all nodes on a path connecting
2051 ** the two */
2052 PathNode *p = 0;
@@ -2054,11 +2203,17 @@
2054 const char *zTo = 0;
2055 Blob ins;
2056 int nNodeOnPath = 0;
2057
2058 if( from_rid && to_rid ){
2059 p = path_shortest(from_rid, to_rid, noMerge, 0, 0);
 
 
 
 
 
 
2060 zFrom = P("from");
2061 zTo = P("to");
2062 }else{
2063 if( path_common_ancestor(me_rid, you_rid) ){
2064 p = path_first();
@@ -2122,19 +2277,37 @@
2122 db_multi_exec("%s", blob_sql_text(&sql));
2123 if( advancedMenu ){
2124 style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
2125 }
2126 nNodeOnPath = db_int(0, "SELECT count(*) FROM temp.pathnode");
2127 blob_appendf(&desc, "%d check-ins going from ", nNodeOnPath);
 
 
 
 
 
 
 
 
 
2128 blob_appendf(&desc, "%z%h</a>", href("%R/info/%h", zFrom), zFrom);
2129 blob_append(&desc, " to ", -1);
2130 blob_appendf(&desc, "%z%h</a>", href("%R/info/%h",zTo), zTo);
2131 if( related ){
2132 int nRelated = db_int(0, "SELECT count(*) FROM timeline") - nNodeOnPath;
2133 if( nRelated>0 ){
2134 blob_appendf(&desc, " and %d related check-in%s", nRelated,
2135 nRelated>1 ? "s" : "");
 
 
 
 
 
 
 
 
 
2136 }
2137 }
2138 addFileGlobDescription(zChng, &desc);
2139 }else if( (p_rid || d_rid) && g.perm.Read && zTagSql==0 ){
2140 /* If p= or d= is present, ignore all other parameters other than n= */
@@ -2680,10 +2853,11 @@
2680 @ <pre>%h(blob_sql_text(&sql2))</pre>
2681 }
2682 db_multi_exec("%s", blob_sql_text(&sql2));
2683 if( nEntry>0 ){
2684 nEntry -= db_int(0,"select count(*) from timeline");
 
2685 }
2686 blob_reset(&sql2);
2687 blob_append_sql(&sql,
2688 " AND event.mtime<=%f ORDER BY event.mtime DESC",
2689 rCirca
2690
--- src/timeline.c
+++ src/timeline.c
@@ -1568,10 +1568,134 @@
1568
1569 /* It looks like this may be a date. Return it with punctuation added. */
1570 return zEDate;
1571 }
1572
1573 /*
1574 ** Find the first check-in encountered with a particular tag
1575 ** when moving either forwards are backwards in time from a
1576 ** particular starting point (iFrom). Return the rid of that
1577 ** first check-in. If there are no check-ins in the decendent
1578 ** or ancestor set of check-in iFrom that match the tag, then
1579 ** return 0.
1580 */
1581 static int timeline_endpoint(
1582 int iFrom, /* Starting point */
1583 const char *zEnd, /* Tag we are searching for */
1584 int bForward /* 1: forwards in time (descendents) 0: backwards */
1585 ){
1586 int tagId;
1587 int endId = 0;
1588 Stmt q;
1589 int ans = 0;
1590
1591 tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
1592 if( tagId==0 ){
1593 endId = symbolic_name_to_rid(zEnd, "ci");
1594 if( endId==0 ) return 0;
1595 }
1596 if( bForward ){
1597 if( tagId ){
1598 db_prepare(&q,
1599 "WITH RECURSIVE dx(id,mtime) AS ("
1600 " SELECT %d, event.mtime FROM event WHERE objid=%d"
1601 " UNION"
1602 " SELECT plink.cid, plink.mtime"
1603 " FROM dx, plink"
1604 " WHERE plink.pid=dx.id"
1605 " AND plink.mtime<=(SELECT max(event.mtime) FROM tagxref, event"
1606 " WHERE tagxref.tagid=%d AND tagxref.tagtype>0"
1607 " AND event.objid=tagxref.rid)"
1608 " ORDER BY plink.mtime)"
1609 "SELECT id FROM dx, tagxref"
1610 " WHERE tagid=%d AND tagtype>0 AND rid=id LIMIT 1",
1611 iFrom, iFrom, tagId, tagId
1612 );
1613 }else{
1614 db_prepare(&q,
1615 "WITH RECURSIVE dx(id,mtime) AS ("
1616 " SELECT %d, event.mtime FROM event WHERE objid=%d"
1617 " UNION"
1618 " SELECT plink.cid, plink.mtime"
1619 " FROM dx, plink"
1620 " WHERE plink.pid=dx.id"
1621 " AND plink.mtime<=(SELECT mtime FROM event WHERE objid=%d)"
1622 " ORDER BY plink.mtime)"
1623 "SELECT id FROM dx WHERE id=%d",
1624 iFrom, iFrom, endId, endId
1625 );
1626 }
1627 }else{
1628 if( tagId ){
1629 db_prepare(&q,
1630 "WITH RECURSIVE dx(id,mtime) AS ("
1631 " SELECT %d, event.mtime FROM event WHERE objid=%d"
1632 " UNION"
1633 " SELECT plink.pid, event.mtime"
1634 " FROM dx, plink, event"
1635 " WHERE plink.cid=dx.id AND event.objid=plink.pid"
1636 " AND event.mtime>=(SELECT min(event.mtime) FROM tagxref, event"
1637 " WHERE tagxref.tagid=%d AND tagxref.tagtype>0"
1638 " AND event.objid=tagxref.rid)"
1639 " ORDER BY event.mtime DESC)"
1640 "SELECT id FROM dx, tagxref"
1641 " WHERE tagid=%d AND tagtype>0 AND rid=id LIMIT 1",
1642 iFrom, iFrom, tagId, tagId
1643 );
1644 }else{
1645 db_prepare(&q,
1646 "WITH RECURSIVE dx(id,mtime) AS ("
1647 " SELECT %d, event.mtime FROM event WHERE objid=%d"
1648 " UNION"
1649 " SELECT plink.pid, event.mtime"
1650 " FROM dx, plink, event"
1651 " WHERE plink.cid=dx.id AND event.objid=plink.pid"
1652 " AND event.mtime>=(SELECT mtime FROM event WHERE objid=%d)"
1653 " ORDER BY event.mtime DESC)"
1654 "SELECT id FROM dx WHERE id=%d",
1655 iFrom, iFrom, endId, endId
1656 );
1657 }
1658 }
1659 if( db_step(&q)==SQLITE_ROW ){
1660 ans = db_column_int(&q, 0);
1661 }
1662 db_finalize(&q);
1663 return ans;
1664 }
1665
1666 /*
1667 ** COMMAND: test-endpoint
1668 **
1669 ** Usage: fossil test-endpoint BASE TAG ?OPTIONS?
1670 **
1671 ** Show the first check-in with TAG that is a descendent or ancestor
1672 ** of BASE. The first descendent checkin is shown by default. Use
1673 ** the --backto to see the first ancestor checkin.
1674 **
1675 ** Options:
1676 **
1677 ** --backto Show ancestor. Others defaults to descendents.
1678 */
1679 void timeline_test_endpoint(void){
1680 int bForward = find_option("backto",0,0)==0;
1681 int from_rid;
1682 int ans;
1683 db_find_and_open_repository(0, 0);
1684 verify_all_options();
1685 if( g.argc!=4 ){
1686 usage("BASE-CHECKIN TAG ?--backto?");
1687 }
1688 from_rid = symbolic_name_to_rid(g.argv[2],"ci");
1689 ans = timeline_endpoint(from_rid, g.argv[3], bForward);
1690 if( ans ){
1691 fossil_print("Result: %d (%S)\n", ans, rid_to_uuid(ans));
1692 }else{
1693 fossil_print("No path found\n");
1694 }
1695 }
1696
1697
1698 /*
1699 ** WEBPAGE: timeline
1700 **
1701 ** Query parameters:
@@ -1598,14 +1722,16 @@
1722 ** bt=PRIOR ... going back to PRIOR
1723 ** d=CHECKIN Children and descendants of CHECKIN
1724 ** ft=DESCENDANT ... going forward to DESCENDANT
1725 ** dp=CHECKIN Same as 'd=CHECKIN&p=CHECKIN'
1726 ** df=CHECKIN Same as 'd=CHECKIN&n1=all&nd'. Mnemonic: "Derived From"
1727 ** bt=CHECKIN "Back To". Show ancenstors going back to CHECKIN
1728 ** p=CX ... from CX back to time of CHECKIN
1729 ** from=CX ... shortest path from CX back to CHECKIN
1730 ** ft=CHECKIN "Forward To": Show decendents forward to CHECKIN
1731 ** d=CX ... from CX up to the time of CHECKIN
1732 ** from=CX ... shortest path from CX up to CHECKIN
1733 ** t=TAG Show only check-ins with the given TAG
1734 ** r=TAG Show check-ins related to TAG, equivalent to t=TAG&rel
1735 ** tl=TAGLIST Shorthand for t=TAGLIST&ms=brlist
1736 ** rl=TAGLIST Shorthand for r=TAGLIST&ms=brlist
1737 ** rel Show related check-ins as well as those matching t=TAG
@@ -1627,10 +1753,12 @@
1753 ** f=CHECKIN Show family (immediate parents and children) of CHECKIN
1754 ** from=CHECKIN Path from...
1755 ** to=CHECKIN ... to this
1756 ** shortest ... show only the shortest path
1757 ** rel ... also show related checkins
1758 ** bt=PRIOR ... path from CHECKIN back to PRIOR
1759 ** ft=LATER ... path from CHECKIN forward to LATER
1760 ** uf=FILE_HASH Show only check-ins that contain the given file version
1761 ** All qualifying check-ins are shown unless there is
1762 ** also an n= or n1= query parameter.
1763 ** chng=GLOBLIST Show only check-ins that involve changes to a file whose
1764 ** name matches one of the comma-separate GLOBLIST
@@ -1727,10 +1855,11 @@
1855 int disableY = 0; /* Disable type selector on submenu */
1856 int advancedMenu = 0; /* Use the advanced menu design */
1857 char *zPlural; /* Ending for plural forms */
1858 int showCherrypicks = 1; /* True to show cherrypick merges */
1859 int haveParameterN; /* True if n= query parameter present */
1860 int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
1861
1862 url_initialize(&url, "timeline");
1863 cgi_query_parameters_to_url(&url);
1864
1865 (void)P_NoBot("ss")
@@ -2043,10 +2172,30 @@
2172 blob_append_sql(&sql,
2173 " AND NOT EXISTS(SELECT 1 FROM tagxref"
2174 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n",
2175 TAG_HIDDEN
2176 );
2177 }
2178 if( from_rid && !to_rid && (P("ft")!=0 || P("bt")!=0) ){
2179 const char *zTo = P("ft");
2180 if( zTo ){
2181 from_to_mode = 1;
2182 to_rid = timeline_endpoint(from_rid, zTo, 1);
2183 }else{
2184 from_to_mode = 2;
2185 zTo = P("bt");
2186 to_rid = timeline_endpoint(from_rid, zTo, 0);
2187 }
2188 if( to_rid ){
2189 cgi_replace_parameter("to", zTo);
2190 if( selectedRid==0 ) selectedRid = from_rid;
2191 if( secondaryRid==0 ) secondaryRid = to_rid;
2192 }else{
2193 to_rid = from_rid;
2194 blob_appendf(&desc, "There is no path from %h %s to %h.<br>Instead: ",
2195 P("from"), from_to_mode==1 ? "forward" : "back", zTo);
2196 }
2197 }
2198 if( ((from_rid && to_rid) || (me_rid && you_rid)) && g.perm.Read ){
2199 /* If from= and to= are present, display all nodes on a path connecting
2200 ** the two */
2201 PathNode *p = 0;
@@ -2054,11 +2203,17 @@
2203 const char *zTo = 0;
2204 Blob ins;
2205 int nNodeOnPath = 0;
2206
2207 if( from_rid && to_rid ){
2208 if( from_to_mode==0 ){
2209 p = path_shortest(from_rid, to_rid, noMerge, 0, 0);
2210 }else if( from_to_mode==1 ){
2211 p = path_shortest(from_rid, to_rid, 0, 1, 0);
2212 }else{
2213 p = path_shortest(to_rid, from_rid, 0, 1, 0);
2214 }
2215 zFrom = P("from");
2216 zTo = P("to");
2217 }else{
2218 if( path_common_ancestor(me_rid, you_rid) ){
2219 p = path_first();
@@ -2122,19 +2277,37 @@
2277 db_multi_exec("%s", blob_sql_text(&sql));
2278 if( advancedMenu ){
2279 style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
2280 }
2281 nNodeOnPath = db_int(0, "SELECT count(*) FROM temp.pathnode");
2282 if( nNodeOnPath==1 && from_to_mode>0 ){
2283 blob_appendf(&desc,"Check-in ");
2284 }else if( from_to_mode>0 ){
2285 blob_appendf(&desc, "%d check-ins on the shorted path from ",nNodeOnPath);
2286 }else{
2287 blob_appendf(&desc, "%d check-ins going from ", nNodeOnPath);
2288 }
2289 if( from_rid==selectedRid ){
2290 blob_appendf(&desc, "<span class='timelineSelected'>");
2291 }
2292 blob_appendf(&desc, "%z%h</a>", href("%R/info/%h", zFrom), zFrom);
2293 if( from_rid==selectedRid ) blob_appendf(&desc, "</span>");
2294 if( nNodeOnPath==1 && from_to_mode>0 ){
2295 blob_appendf(&desc, " only");
2296 }else{
2297 blob_append(&desc, " to ", -1);
2298 if( to_rid==secondaryRid ){
2299 blob_appendf(&desc,"<span class='timelineSelected timelineSecondary'>");
2300 }
2301 blob_appendf(&desc, "%z%h</a>", href("%R/info/%h",zTo), zTo);
2302 if( to_rid==secondaryRid ) blob_appendf(&desc, "</span>");
2303 if( related ){
2304 int nRelated = db_int(0, "SELECT count(*) FROM timeline") - nNodeOnPath;
2305 if( nRelated>0 ){
2306 blob_appendf(&desc, " and %d related check-in%s", nRelated,
2307 nRelated>1 ? "s" : "");
2308 }
2309 }
2310 }
2311 addFileGlobDescription(zChng, &desc);
2312 }else if( (p_rid || d_rid) && g.perm.Read && zTagSql==0 ){
2313 /* If p= or d= is present, ignore all other parameters other than n= */
@@ -2680,10 +2853,11 @@
2853 @ <pre>%h(blob_sql_text(&sql2))</pre>
2854 }
2855 db_multi_exec("%s", blob_sql_text(&sql2));
2856 if( nEntry>0 ){
2857 nEntry -= db_int(0,"select count(*) from timeline");
2858 if( nEntry<=0 ) nEntry = 1;
2859 }
2860 blob_reset(&sql2);
2861 blob_append_sql(&sql,
2862 " AND event.mtime<=%f ORDER BY event.mtime DESC",
2863 rCirca
2864

Keyboard Shortcuts

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