Fossil SCM

Merge from trunk.

brickviking 2025-03-02 20:36 bv-infotool merge
Commit b591622016a515c46be58151abf92c093f781c85b911bca71d479d1113d37d71
+38 -16
--- auto.def
+++ auto.def
@@ -337,12 +337,12 @@
337337
}
338338
339339
# Check for libraries that need to be sorted out early
340340
cc-check-function-in-lib iconv iconv
341341
342
-cc-check-function-in-lib sin m ;# must come before ssl check:
343
- # https://fossil-scm.org/forum/forumpost/afcd42b7fd
342
+cc-check-function-in-lib sin m
343
+cc-check-function-in-lib dlopen dl
344344
345345
# Helper for OpenSSL checking
346346
proc check-for-openssl {msg {cflags {}} {libs {-lssl -lcrypto -lpthread}}} {
347347
msg-checking "Checking for $msg..."
348348
set rc 0
@@ -507,10 +507,12 @@
507507
set ssllibs "$dir/libssl.a $dir/libcrypto.a -lpthread"
508508
if {[check-for-openssl $msg "$cflags $ldflags" $ssllibs]} {
509509
incr found
510510
break
511511
}
512
+ # This test should arguably fail here if --with-openssl=X
513
+ # points to an invalid X.
512514
}
513515
}
514516
}
515517
}
516518
if {$found} {
@@ -862,24 +864,10 @@
862864
# We need to link with libubsan if we're compiling under
863865
# GCC with -fsanitize=undefined.
864866
cc-check-function-in-lib __ubsan_handle_add_overflow ubsan
865867
}
866868
}
867
-
868
-# Finally, append libraries that must be last. This matters more on some
869
-# OSes than others, but is most broadly required for static linking.
870
-if {[check-function-in-lib dlopen dl]} {
871
- # Some platforms (*BSD) have the dl functions already in libc and no libdl.
872
- # In such case we can link directly without -ldl.
873
- define-append LIBS [get-define lib_dlopen]
874
-}
875
-if {[opt-bool static]} {
876
- # Linux can only infer the dependency on pthread from OpenSSL when
877
- # doing dynamic linkage.
878
- define-append LIBS -lpthread
879
-}
880
-
881869
882870
########################################################################
883871
# @proj-check-emsdk
884872
#
885873
# Emscripten is used for doing in-tree builds of web-based WASM stuff,
@@ -958,10 +946,44 @@
958946
define EMCC_OPT ""
959947
catch {exec rm -f tools/emcc.sh}
960948
}
961949
962950
handle-with-openssl
951
+
952
+# Finally, append libraries that must be last. This matters more on some
953
+# OSes than others, but is most broadly required for static linking.
954
+if {[opt-bool static]} {
955
+ # Linux can only infer the dependency on pthread from OpenSSL when
956
+ # doing dynamic linkage.
957
+ define-append LIBS -lpthread
958
+}
959
+
960
+apply {{} {
961
+ # This started out as a workaround for getting the ordering of -ldl
962
+ # correct in conjunction with openssl in some environments. Then it
963
+ # evolved into a more generic preemptive portability workaround to
964
+ # ensure that certain libraries are always appended to the global
965
+ # LIBS list if they exist on the system. Based on a /chat discussion
966
+ # on 2025-02-27 in the context of check-in [8d3b9bf4d4].
967
+ #
968
+ # Note that [move-lib-to-end] and [lib-actually-exists] are in
969
+ # autosetup/local.tcl.
970
+ set libs [get-define LIBS]
971
+ #puts "**** 1 LIBS: $libs"
972
+ foreach ll {-ldl -lpthread -lm} {
973
+ if {![move-lib-to-end $ll $libs libs]} {
974
+ # $ll was not in the list
975
+ if {[lib-actually-exists $ll]} {
976
+ # Add it to the list "just in case." This will be a no-op on
977
+ # systems where the lib is not actually used.
978
+ lappend libs $ll
979
+ }
980
+ }
981
+ }
982
+ #puts "**** 2 LIBS: $libs"
983
+ define LIBS [join $libs " "]
984
+}}
963985
964986
# Tag container builds with a prefix of the checkin ID of the version
965987
# of Fossil each one contains. This not only allows multiple images
966988
# to coexist and multiple containers to be created unamgiguosly from
967989
# them, it also changes the URL we fetch the source tarball from, so
968990
--- auto.def
+++ auto.def
@@ -337,12 +337,12 @@
337 }
338
339 # Check for libraries that need to be sorted out early
340 cc-check-function-in-lib iconv iconv
341
342 cc-check-function-in-lib sin m ;# must come before ssl check:
343 # https://fossil-scm.org/forum/forumpost/afcd42b7fd
344
345 # Helper for OpenSSL checking
346 proc check-for-openssl {msg {cflags {}} {libs {-lssl -lcrypto -lpthread}}} {
347 msg-checking "Checking for $msg..."
348 set rc 0
@@ -507,10 +507,12 @@
507 set ssllibs "$dir/libssl.a $dir/libcrypto.a -lpthread"
508 if {[check-for-openssl $msg "$cflags $ldflags" $ssllibs]} {
509 incr found
510 break
511 }
 
 
512 }
513 }
514 }
515 }
516 if {$found} {
@@ -862,24 +864,10 @@
862 # We need to link with libubsan if we're compiling under
863 # GCC with -fsanitize=undefined.
864 cc-check-function-in-lib __ubsan_handle_add_overflow ubsan
865 }
866 }
867
868 # Finally, append libraries that must be last. This matters more on some
869 # OSes than others, but is most broadly required for static linking.
870 if {[check-function-in-lib dlopen dl]} {
871 # Some platforms (*BSD) have the dl functions already in libc and no libdl.
872 # In such case we can link directly without -ldl.
873 define-append LIBS [get-define lib_dlopen]
874 }
875 if {[opt-bool static]} {
876 # Linux can only infer the dependency on pthread from OpenSSL when
877 # doing dynamic linkage.
878 define-append LIBS -lpthread
879 }
880
881
882 ########################################################################
883 # @proj-check-emsdk
884 #
885 # Emscripten is used for doing in-tree builds of web-based WASM stuff,
@@ -958,10 +946,44 @@
958 define EMCC_OPT ""
959 catch {exec rm -f tools/emcc.sh}
960 }
961
962 handle-with-openssl
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
963
964 # Tag container builds with a prefix of the checkin ID of the version
965 # of Fossil each one contains. This not only allows multiple images
966 # to coexist and multiple containers to be created unamgiguosly from
967 # them, it also changes the URL we fetch the source tarball from, so
968
--- auto.def
+++ auto.def
@@ -337,12 +337,12 @@
337 }
338
339 # Check for libraries that need to be sorted out early
340 cc-check-function-in-lib iconv iconv
341
342 cc-check-function-in-lib sin m
343 cc-check-function-in-lib dlopen dl
344
345 # Helper for OpenSSL checking
346 proc check-for-openssl {msg {cflags {}} {libs {-lssl -lcrypto -lpthread}}} {
347 msg-checking "Checking for $msg..."
348 set rc 0
@@ -507,10 +507,12 @@
507 set ssllibs "$dir/libssl.a $dir/libcrypto.a -lpthread"
508 if {[check-for-openssl $msg "$cflags $ldflags" $ssllibs]} {
509 incr found
510 break
511 }
512 # This test should arguably fail here if --with-openssl=X
513 # points to an invalid X.
514 }
515 }
516 }
517 }
518 if {$found} {
@@ -862,24 +864,10 @@
864 # We need to link with libubsan if we're compiling under
865 # GCC with -fsanitize=undefined.
866 cc-check-function-in-lib __ubsan_handle_add_overflow ubsan
867 }
868 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
869
870 ########################################################################
871 # @proj-check-emsdk
872 #
873 # Emscripten is used for doing in-tree builds of web-based WASM stuff,
@@ -958,10 +946,44 @@
946 define EMCC_OPT ""
947 catch {exec rm -f tools/emcc.sh}
948 }
949
950 handle-with-openssl
951
952 # Finally, append libraries that must be last. This matters more on some
953 # OSes than others, but is most broadly required for static linking.
954 if {[opt-bool static]} {
955 # Linux can only infer the dependency on pthread from OpenSSL when
956 # doing dynamic linkage.
957 define-append LIBS -lpthread
958 }
959
960 apply {{} {
961 # This started out as a workaround for getting the ordering of -ldl
962 # correct in conjunction with openssl in some environments. Then it
963 # evolved into a more generic preemptive portability workaround to
964 # ensure that certain libraries are always appended to the global
965 # LIBS list if they exist on the system. Based on a /chat discussion
966 # on 2025-02-27 in the context of check-in [8d3b9bf4d4].
967 #
968 # Note that [move-lib-to-end] and [lib-actually-exists] are in
969 # autosetup/local.tcl.
970 set libs [get-define LIBS]
971 #puts "**** 1 LIBS: $libs"
972 foreach ll {-ldl -lpthread -lm} {
973 if {![move-lib-to-end $ll $libs libs]} {
974 # $ll was not in the list
975 if {[lib-actually-exists $ll]} {
976 # Add it to the list "just in case." This will be a no-op on
977 # systems where the lib is not actually used.
978 lappend libs $ll
979 }
980 }
981 }
982 #puts "**** 2 LIBS: $libs"
983 define LIBS [join $libs " "]
984 }}
985
986 # Tag container builds with a prefix of the checkin ID of the version
987 # of Fossil each one contains. This not only allows multiple images
988 # to coexist and multiple containers to be created unamgiguosly from
989 # them, it also changes the URL we fetch the source tarball from, so
990
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -27,5 +27,35 @@
2727
set tclconfig($name) [string trim $value ']
2828
}
2929
}
3030
return [array get tclconfig]
3131
}
32
+
33
+#
34
+# Given a library link flag, e.g. -lfoo, returns 1 if that library can
35
+# actually be linked to, else returns 0.
36
+proc lib-actually-exists {linkFlag} {
37
+ cctest -link 1 -code "void libActuallyExists(void){}" -libs $linkFlag
38
+}
39
+
40
+#
41
+# Given a library flag, e.g. -lfoo, a list of libs, e.g. {-lfoo -lbar
42
+# -lbaz}, and a target variable name, this function appends all
43
+# entries of $libList which do not match $flag to $tgtVar, then
44
+# appends $flag to the end of $tgtVar. Returns the number of matches
45
+# found.
46
+proc move-lib-to-end {flag libList tgtVar} {
47
+ upvar $tgtVar tgt
48
+ set tgt {}
49
+ set found 0
50
+ foreach e $libList {
51
+ if {$flag eq $e} {
52
+ incr found
53
+ } else {
54
+ lappend tgt $e
55
+ }
56
+ }
57
+ if {$found} {
58
+ lappend tgt $flag
59
+ }
60
+ return $found
61
+}
3262
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -27,5 +27,35 @@
27 set tclconfig($name) [string trim $value ']
28 }
29 }
30 return [array get tclconfig]
31 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
--- autosetup/local.tcl
+++ autosetup/local.tcl
@@ -27,5 +27,35 @@
27 set tclconfig($name) [string trim $value ']
28 }
29 }
30 return [array get tclconfig]
31 }
32
33 #
34 # Given a library link flag, e.g. -lfoo, returns 1 if that library can
35 # actually be linked to, else returns 0.
36 proc lib-actually-exists {linkFlag} {
37 cctest -link 1 -code "void libActuallyExists(void){}" -libs $linkFlag
38 }
39
40 #
41 # Given a library flag, e.g. -lfoo, a list of libs, e.g. {-lfoo -lbar
42 # -lbaz}, and a target variable name, this function appends all
43 # entries of $libList which do not match $flag to $tgtVar, then
44 # appends $flag to the end of $tgtVar. Returns the number of matches
45 # found.
46 proc move-lib-to-end {flag libList tgtVar} {
47 upvar $tgtVar tgt
48 set tgt {}
49 set found 0
50 foreach e $libList {
51 if {$flag eq $e} {
52 incr found
53 } else {
54 lappend tgt $e
55 }
56 }
57 if {$found} {
58 lappend tgt $flag
59 }
60 return $found
61 }
62
--- extsrc/pikchr-worker.js
+++ extsrc/pikchr-worker.js
@@ -36,11 +36,11 @@
3636
pikchr: source code for the pikchr,
3737
darkMode: boolean true to adjust colors for a dark color scheme,
3838
cssClass: CSS class name to add to the SVG
3939
}
4040
41
- Workers-to-Main types
41
+ Workers-to-Main message types:
4242
4343
- stdout, stderr: indicate stdout/stderr output from the wasm
4444
layer. The data property is the string of the output, noting
4545
that the emscripten binding emits these one line at a time. Thus,
4646
if a C-side puts() emits multiple lines in a single call, the JS
@@ -50,21 +50,21 @@
5050
5151
- module: Status text. This is intended to alert the main thread
5252
about module loading status so that, e.g., the main thread can
5353
update a progress widget and DTRT when the module is finished
5454
loading and available for work. Status messages come in the form
55
-
55
+
5656
{type:'module', data:{
5757
type:'status',
5858
data: {text:string|null, step:1-based-integer}
5959
}
6060
6161
with an incrementing step value for each subsequent message. When
6262
the module loading is complete, a message with a text value of
6363
null is posted.
6464
65
- - pikchr:
65
+ - pikchr:
6666
6767
{type: 'pikchr',
6868
data:{
6969
pikchr: input text,
7070
result: rendered result (SVG on success, HTML on error),
@@ -162,11 +162,11 @@
162162
}
163163
return;
164164
};
165165
console.warn("Unknown pikchr-worker message type:",ev);
166166
};
167
-
167
+
168168
/**
169169
emscripten module for use with build mode -sMODULARIZE.
170170
*/
171171
const pikchrModule = {
172172
print: function(){wMsg('stdout', Array.prototype.slice.call(arguments));},
173173
--- extsrc/pikchr-worker.js
+++ extsrc/pikchr-worker.js
@@ -36,11 +36,11 @@
36 pikchr: source code for the pikchr,
37 darkMode: boolean true to adjust colors for a dark color scheme,
38 cssClass: CSS class name to add to the SVG
39 }
40
41 Workers-to-Main types
42
43 - stdout, stderr: indicate stdout/stderr output from the wasm
44 layer. The data property is the string of the output, noting
45 that the emscripten binding emits these one line at a time. Thus,
46 if a C-side puts() emits multiple lines in a single call, the JS
@@ -50,21 +50,21 @@
50
51 - module: Status text. This is intended to alert the main thread
52 about module loading status so that, e.g., the main thread can
53 update a progress widget and DTRT when the module is finished
54 loading and available for work. Status messages come in the form
55
56 {type:'module', data:{
57 type:'status',
58 data: {text:string|null, step:1-based-integer}
59 }
60
61 with an incrementing step value for each subsequent message. When
62 the module loading is complete, a message with a text value of
63 null is posted.
64
65 - pikchr:
66
67 {type: 'pikchr',
68 data:{
69 pikchr: input text,
70 result: rendered result (SVG on success, HTML on error),
@@ -162,11 +162,11 @@
162 }
163 return;
164 };
165 console.warn("Unknown pikchr-worker message type:",ev);
166 };
167
168 /**
169 emscripten module for use with build mode -sMODULARIZE.
170 */
171 const pikchrModule = {
172 print: function(){wMsg('stdout', Array.prototype.slice.call(arguments));},
173
--- extsrc/pikchr-worker.js
+++ extsrc/pikchr-worker.js
@@ -36,11 +36,11 @@
36 pikchr: source code for the pikchr,
37 darkMode: boolean true to adjust colors for a dark color scheme,
38 cssClass: CSS class name to add to the SVG
39 }
40
41 Workers-to-Main message types:
42
43 - stdout, stderr: indicate stdout/stderr output from the wasm
44 layer. The data property is the string of the output, noting
45 that the emscripten binding emits these one line at a time. Thus,
46 if a C-side puts() emits multiple lines in a single call, the JS
@@ -50,21 +50,21 @@
50
51 - module: Status text. This is intended to alert the main thread
52 about module loading status so that, e.g., the main thread can
53 update a progress widget and DTRT when the module is finished
54 loading and available for work. Status messages come in the form
55
56 {type:'module', data:{
57 type:'status',
58 data: {text:string|null, step:1-based-integer}
59 }
60
61 with an incrementing step value for each subsequent message. When
62 the module loading is complete, a message with a text value of
63 null is posted.
64
65 - pikchr:
66
67 {type: 'pikchr',
68 data:{
69 pikchr: input text,
70 result: rendered result (SVG on success, HTML on error),
@@ -162,11 +162,11 @@
162 }
163 return;
164 };
165 console.warn("Unknown pikchr-worker message type:",ev);
166 };
167
168 /**
169 emscripten module for use with build mode -sMODULARIZE.
170 */
171 const pikchrModule = {
172 print: function(){wMsg('stdout', Array.prototype.slice.call(arguments));},
173
+256 -244
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -125,10 +125,22 @@
125125
#include <assert.h>
126126
#define count(X) (sizeof(X)/sizeof(X[0]))
127127
#ifndef M_PI
128128
# define M_PI 3.1415926535897932385
129129
#endif
130
+
131
+/*
132
+** Typesafe version of ctype.h macros. Cygwin requires this, I'm told.
133
+*/
134
+#define IsUpper(X) isupper((unsigned char)(X))
135
+#define IsLower(X) islower((unsigned char)(X))
136
+#define ToLower(X) tolower((unsigned char)(X))
137
+#define IsDigit(X) isdigit((unsigned char)(X))
138
+#define IsXDigit(X) isxdigit((unsigned char)(X))
139
+#define IsSpace(X) isspace((unsigned char)(X))
140
+#define IsAlnum(X) isalnum((unsigned char)(X))
141
+
130142
131143
/* Limit the number of tokens in a single script to avoid run-away
132144
** macro expansion attacks. See forum post
133145
** https://pikchr.org/home/forumpost/ef8684c6955a411a
134146
*/
@@ -492,11 +504,11 @@
492504
static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
493505
static PNum pik_dist(PPoint*,PPoint*);
494506
static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
495507
496508
497
-#line 523 "pikchr.c"
509
+#line 535 "pikchr.c"
498510
/**************** End of %include directives **********************************/
499511
/* These constants specify the various numeric values for terminal symbols.
500512
***************** Begin token definitions *************************************/
501513
#ifndef T_ID
502514
#define T_ID 1
@@ -1745,22 +1757,22 @@
17451757
** inside the C code.
17461758
*/
17471759
/********* Begin destructor definitions ***************************************/
17481760
case 100: /* statement_list */
17491761
{
1750
-#line 511 "pikchr.y"
1762
+#line 523 "pikchr.y"
17511763
pik_elist_free(p,(yypminor->yy235));
1752
-#line 1777 "pikchr.c"
1764
+#line 1789 "pikchr.c"
17531765
}
17541766
break;
17551767
case 101: /* statement */
17561768
case 102: /* unnamed_statement */
17571769
case 103: /* basetype */
17581770
{
1759
-#line 513 "pikchr.y"
1771
+#line 525 "pikchr.y"
17601772
pik_elem_free(p,(yypminor->yy162));
1761
-#line 1786 "pikchr.c"
1773
+#line 1798 "pikchr.c"
17621774
}
17631775
break;
17641776
/********* End destructor definitions *****************************************/
17651777
default: break; /* If no destructor action specified: do nothing */
17661778
}
@@ -1991,14 +2003,14 @@
19912003
#endif
19922004
while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
19932005
/* Here code is inserted which will execute if the parser
19942006
** stack every overflows */
19952007
/******** Begin %stack_overflow code ******************************************/
1996
-#line 545 "pikchr.y"
2008
+#line 557 "pikchr.y"
19972009
19982010
pik_error(p, 0, "parser stack overflow");
1999
-#line 2024 "pikchr.c"
2011
+#line 2036 "pikchr.c"
20002012
/******** End %stack_overflow code ********************************************/
20012013
pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
20022014
pik_parserCTX_STORE
20032015
}
20042016
@@ -2419,619 +2431,619 @@
24192431
** break;
24202432
*/
24212433
/********** Begin reduce actions **********************************************/
24222434
YYMINORTYPE yylhsminor;
24232435
case 0: /* document ::= statement_list */
2424
-#line 549 "pikchr.y"
2436
+#line 561 "pikchr.y"
24252437
{pik_render(p,yymsp[0].minor.yy235);}
2426
-#line 2451 "pikchr.c"
2438
+#line 2463 "pikchr.c"
24272439
break;
24282440
case 1: /* statement_list ::= statement */
2429
-#line 552 "pikchr.y"
2441
+#line 564 "pikchr.y"
24302442
{ yylhsminor.yy235 = pik_elist_append(p,0,yymsp[0].minor.yy162); }
2431
-#line 2456 "pikchr.c"
2443
+#line 2468 "pikchr.c"
24322444
yymsp[0].minor.yy235 = yylhsminor.yy235;
24332445
break;
24342446
case 2: /* statement_list ::= statement_list EOL statement */
2435
-#line 554 "pikchr.y"
2447
+#line 566 "pikchr.y"
24362448
{ yylhsminor.yy235 = pik_elist_append(p,yymsp[-2].minor.yy235,yymsp[0].minor.yy162); }
2437
-#line 2462 "pikchr.c"
2449
+#line 2474 "pikchr.c"
24382450
yymsp[-2].minor.yy235 = yylhsminor.yy235;
24392451
break;
24402452
case 3: /* statement ::= */
2441
-#line 557 "pikchr.y"
2453
+#line 569 "pikchr.y"
24422454
{ yymsp[1].minor.yy162 = 0; }
2443
-#line 2468 "pikchr.c"
2455
+#line 2480 "pikchr.c"
24442456
break;
24452457
case 4: /* statement ::= direction */
2446
-#line 558 "pikchr.y"
2458
+#line 570 "pikchr.y"
24472459
{ pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy162=0; }
2448
-#line 2473 "pikchr.c"
2460
+#line 2485 "pikchr.c"
24492461
yymsp[0].minor.yy162 = yylhsminor.yy162;
24502462
break;
24512463
case 5: /* statement ::= lvalue ASSIGN rvalue */
2452
-#line 559 "pikchr.y"
2464
+#line 571 "pikchr.y"
24532465
{pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy21,&yymsp[-1].minor.yy0); yylhsminor.yy162=0;}
2454
-#line 2479 "pikchr.c"
2466
+#line 2491 "pikchr.c"
24552467
yymsp[-2].minor.yy162 = yylhsminor.yy162;
24562468
break;
24572469
case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2458
-#line 561 "pikchr.y"
2470
+#line 573 "pikchr.y"
24592471
{ yylhsminor.yy162 = yymsp[0].minor.yy162; pik_elem_setname(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0); }
2460
-#line 2485 "pikchr.c"
2472
+#line 2497 "pikchr.c"
24612473
yymsp[-2].minor.yy162 = yylhsminor.yy162;
24622474
break;
24632475
case 7: /* statement ::= PLACENAME COLON position */
2464
-#line 563 "pikchr.y"
2476
+#line 575 "pikchr.y"
24652477
{ yylhsminor.yy162 = pik_elem_new(p,0,0,0);
24662478
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"
2479
+#line 2504 "pikchr.c"
24682480
yymsp[-2].minor.yy162 = yylhsminor.yy162;
24692481
break;
24702482
case 8: /* statement ::= unnamed_statement */
2471
-#line 565 "pikchr.y"
2483
+#line 577 "pikchr.y"
24722484
{yylhsminor.yy162 = yymsp[0].minor.yy162;}
2473
-#line 2498 "pikchr.c"
2485
+#line 2510 "pikchr.c"
24742486
yymsp[0].minor.yy162 = yylhsminor.yy162;
24752487
break;
24762488
case 9: /* statement ::= print prlist */
2477
-#line 566 "pikchr.y"
2489
+#line 578 "pikchr.y"
24782490
{pik_append(p,"<br>\n",5); yymsp[-1].minor.yy162=0;}
2479
-#line 2504 "pikchr.c"
2491
+#line 2516 "pikchr.c"
24802492
break;
24812493
case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2482
-#line 571 "pikchr.y"
2494
+#line 583 "pikchr.y"
24832495
{yymsp[-5].minor.yy162=pik_assert(p,yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy21);}
2484
-#line 2509 "pikchr.c"
2496
+#line 2521 "pikchr.c"
24852497
break;
24862498
case 11: /* statement ::= ASSERT LP position EQ position RP */
2487
-#line 573 "pikchr.y"
2499
+#line 585 "pikchr.y"
24882500
{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"
2501
+#line 2526 "pikchr.c"
24902502
break;
24912503
case 12: /* statement ::= DEFINE ID CODEBLOCK */
2492
-#line 574 "pikchr.y"
2504
+#line 586 "pikchr.y"
24932505
{yymsp[-2].minor.yy162=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2494
-#line 2519 "pikchr.c"
2506
+#line 2531 "pikchr.c"
24952507
break;
24962508
case 13: /* rvalue ::= PLACENAME */
2497
-#line 585 "pikchr.y"
2509
+#line 597 "pikchr.y"
24982510
{yylhsminor.yy21 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2499
-#line 2524 "pikchr.c"
2511
+#line 2536 "pikchr.c"
25002512
yymsp[0].minor.yy21 = yylhsminor.yy21;
25012513
break;
25022514
case 14: /* pritem ::= FILL */
25032515
case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
25042516
case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2505
-#line 590 "pikchr.y"
2517
+#line 602 "pikchr.y"
25062518
{pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2507
-#line 2532 "pikchr.c"
2519
+#line 2544 "pikchr.c"
25082520
break;
25092521
case 17: /* pritem ::= rvalue */
2510
-#line 593 "pikchr.y"
2522
+#line 605 "pikchr.y"
25112523
{pik_append_num(p,"",yymsp[0].minor.yy21);}
2512
-#line 2537 "pikchr.c"
2524
+#line 2549 "pikchr.c"
25132525
break;
25142526
case 18: /* pritem ::= STRING */
2515
-#line 594 "pikchr.y"
2527
+#line 606 "pikchr.y"
25162528
{pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2517
-#line 2542 "pikchr.c"
2529
+#line 2554 "pikchr.c"
25182530
break;
25192531
case 19: /* prsep ::= COMMA */
2520
-#line 595 "pikchr.y"
2532
+#line 607 "pikchr.y"
25212533
{pik_append(p, " ", 1);}
2522
-#line 2547 "pikchr.c"
2534
+#line 2559 "pikchr.c"
25232535
break;
25242536
case 20: /* unnamed_statement ::= basetype attribute_list */
2525
-#line 598 "pikchr.y"
2537
+#line 610 "pikchr.y"
25262538
{yylhsminor.yy162 = yymsp[-1].minor.yy162; pik_after_adding_attributes(p,yylhsminor.yy162);}
2527
-#line 2552 "pikchr.c"
2539
+#line 2564 "pikchr.c"
25282540
yymsp[-1].minor.yy162 = yylhsminor.yy162;
25292541
break;
25302542
case 21: /* basetype ::= CLASSNAME */
2531
-#line 600 "pikchr.y"
2543
+#line 612 "pikchr.y"
25322544
{yylhsminor.yy162 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2533
-#line 2558 "pikchr.c"
2545
+#line 2570 "pikchr.c"
25342546
yymsp[0].minor.yy162 = yylhsminor.yy162;
25352547
break;
25362548
case 22: /* basetype ::= STRING textposition */
2537
-#line 602 "pikchr.y"
2549
+#line 614 "pikchr.y"
25382550
{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"
2551
+#line 2576 "pikchr.c"
25402552
yymsp[-1].minor.yy162 = yylhsminor.yy162;
25412553
break;
25422554
case 23: /* basetype ::= LB savelist statement_list RB */
2543
-#line 604 "pikchr.y"
2555
+#line 616 "pikchr.y"
25442556
{ 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"
2557
+#line 2582 "pikchr.c"
25462558
break;
25472559
case 24: /* savelist ::= */
2548
-#line 609 "pikchr.y"
2560
+#line 621 "pikchr.y"
25492561
{yymsp[1].minor.yy235 = p->list; p->list = 0;}
2550
-#line 2575 "pikchr.c"
2562
+#line 2587 "pikchr.c"
25512563
break;
25522564
case 25: /* relexpr ::= expr */
2553
-#line 616 "pikchr.y"
2565
+#line 628 "pikchr.y"
25542566
{yylhsminor.yy72.rAbs = yymsp[0].minor.yy21; yylhsminor.yy72.rRel = 0;}
2555
-#line 2580 "pikchr.c"
2567
+#line 2592 "pikchr.c"
25562568
yymsp[0].minor.yy72 = yylhsminor.yy72;
25572569
break;
25582570
case 26: /* relexpr ::= expr PERCENT */
2559
-#line 617 "pikchr.y"
2571
+#line 629 "pikchr.y"
25602572
{yylhsminor.yy72.rAbs = 0; yylhsminor.yy72.rRel = yymsp[-1].minor.yy21/100;}
2561
-#line 2586 "pikchr.c"
2573
+#line 2598 "pikchr.c"
25622574
yymsp[-1].minor.yy72 = yylhsminor.yy72;
25632575
break;
25642576
case 27: /* optrelexpr ::= */
2565
-#line 619 "pikchr.y"
2577
+#line 631 "pikchr.y"
25662578
{yymsp[1].minor.yy72.rAbs = 0; yymsp[1].minor.yy72.rRel = 1.0;}
2567
-#line 2592 "pikchr.c"
2579
+#line 2604 "pikchr.c"
25682580
break;
25692581
case 28: /* attribute_list ::= relexpr alist */
2570
-#line 621 "pikchr.y"
2582
+#line 633 "pikchr.y"
25712583
{pik_add_direction(p,0,&yymsp[-1].minor.yy72);}
2572
-#line 2597 "pikchr.c"
2584
+#line 2609 "pikchr.c"
25732585
break;
25742586
case 29: /* attribute ::= numproperty relexpr */
2575
-#line 625 "pikchr.y"
2587
+#line 637 "pikchr.y"
25762588
{ pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72); }
2577
-#line 2602 "pikchr.c"
2589
+#line 2614 "pikchr.c"
25782590
break;
25792591
case 30: /* attribute ::= dashproperty expr */
2580
-#line 626 "pikchr.y"
2592
+#line 638 "pikchr.y"
25812593
{ pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy21); }
2582
-#line 2607 "pikchr.c"
2594
+#line 2619 "pikchr.c"
25832595
break;
25842596
case 31: /* attribute ::= dashproperty */
2585
-#line 627 "pikchr.y"
2597
+#line 639 "pikchr.y"
25862598
{ pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2587
-#line 2612 "pikchr.c"
2599
+#line 2624 "pikchr.c"
25882600
break;
25892601
case 32: /* attribute ::= colorproperty rvalue */
2590
-#line 628 "pikchr.y"
2602
+#line 640 "pikchr.y"
25912603
{ pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21); }
2592
-#line 2617 "pikchr.c"
2604
+#line 2629 "pikchr.c"
25932605
break;
25942606
case 33: /* attribute ::= go direction optrelexpr */
2595
-#line 629 "pikchr.y"
2607
+#line 641 "pikchr.y"
25962608
{ pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72);}
2597
-#line 2622 "pikchr.c"
2609
+#line 2634 "pikchr.c"
25982610
break;
25992611
case 34: /* attribute ::= go direction even position */
2600
-#line 630 "pikchr.y"
2612
+#line 642 "pikchr.y"
26012613
{pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63);}
2602
-#line 2627 "pikchr.c"
2614
+#line 2639 "pikchr.c"
26032615
break;
26042616
case 35: /* attribute ::= CLOSE */
2605
-#line 631 "pikchr.y"
2617
+#line 643 "pikchr.y"
26062618
{ pik_close_path(p,&yymsp[0].minor.yy0); }
2607
-#line 2632 "pikchr.c"
2619
+#line 2644 "pikchr.c"
26082620
break;
26092621
case 36: /* attribute ::= CHOP */
2610
-#line 632 "pikchr.y"
2622
+#line 644 "pikchr.y"
26112623
{ p->cur->bChop = 1; }
2612
-#line 2637 "pikchr.c"
2624
+#line 2649 "pikchr.c"
26132625
break;
26142626
case 37: /* attribute ::= FROM position */
2615
-#line 633 "pikchr.y"
2627
+#line 645 "pikchr.y"
26162628
{ pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2617
-#line 2642 "pikchr.c"
2629
+#line 2654 "pikchr.c"
26182630
break;
26192631
case 38: /* attribute ::= TO position */
2620
-#line 634 "pikchr.y"
2632
+#line 646 "pikchr.y"
26212633
{ pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2622
-#line 2647 "pikchr.c"
2634
+#line 2659 "pikchr.c"
26232635
break;
26242636
case 39: /* attribute ::= THEN */
2625
-#line 635 "pikchr.y"
2637
+#line 647 "pikchr.y"
26262638
{ pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2627
-#line 2652 "pikchr.c"
2639
+#line 2664 "pikchr.c"
26282640
break;
26292641
case 40: /* attribute ::= THEN optrelexpr HEADING expr */
26302642
case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2631
-#line 637 "pikchr.y"
2643
+#line 649 "pikchr.y"
26322644
{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"
2645
+#line 2670 "pikchr.c"
26342646
break;
26352647
case 41: /* attribute ::= THEN optrelexpr EDGEPT */
26362648
case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2637
-#line 638 "pikchr.y"
2649
+#line 650 "pikchr.y"
26382650
{pik_move_hdg(p,&yymsp[-1].minor.yy72,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2639
-#line 2664 "pikchr.c"
2651
+#line 2676 "pikchr.c"
26402652
break;
26412653
case 44: /* attribute ::= AT position */
2642
-#line 643 "pikchr.y"
2654
+#line 655 "pikchr.y"
26432655
{ pik_set_at(p,0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2644
-#line 2669 "pikchr.c"
2656
+#line 2681 "pikchr.c"
26452657
break;
26462658
case 45: /* attribute ::= SAME */
2647
-#line 645 "pikchr.y"
2659
+#line 657 "pikchr.y"
26482660
{pik_same(p,0,&yymsp[0].minor.yy0);}
2649
-#line 2674 "pikchr.c"
2661
+#line 2686 "pikchr.c"
26502662
break;
26512663
case 46: /* attribute ::= SAME AS object */
2652
-#line 646 "pikchr.y"
2664
+#line 658 "pikchr.y"
26532665
{pik_same(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2654
-#line 2679 "pikchr.c"
2666
+#line 2691 "pikchr.c"
26552667
break;
26562668
case 47: /* attribute ::= STRING textposition */
2657
-#line 647 "pikchr.y"
2669
+#line 659 "pikchr.y"
26582670
{pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy188);}
2659
-#line 2684 "pikchr.c"
2671
+#line 2696 "pikchr.c"
26602672
break;
26612673
case 48: /* attribute ::= FIT */
2662
-#line 648 "pikchr.y"
2674
+#line 660 "pikchr.y"
26632675
{pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2664
-#line 2689 "pikchr.c"
2676
+#line 2701 "pikchr.c"
26652677
break;
26662678
case 49: /* attribute ::= BEHIND object */
2667
-#line 649 "pikchr.y"
2679
+#line 661 "pikchr.y"
26682680
{pik_behind(p,yymsp[0].minor.yy162);}
2669
-#line 2694 "pikchr.c"
2681
+#line 2706 "pikchr.c"
26702682
break;
26712683
case 50: /* withclause ::= DOT_E edge AT position */
26722684
case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2673
-#line 657 "pikchr.y"
2685
+#line 669 "pikchr.y"
26742686
{ pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2675
-#line 2700 "pikchr.c"
2687
+#line 2712 "pikchr.c"
26762688
break;
26772689
case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2678
-#line 661 "pikchr.y"
2690
+#line 673 "pikchr.y"
26792691
{yylhsminor.yy0 = yymsp[0].minor.yy0;}
2680
-#line 2705 "pikchr.c"
2692
+#line 2717 "pikchr.c"
26812693
yymsp[0].minor.yy0 = yylhsminor.yy0;
26822694
break;
26832695
case 53: /* boolproperty ::= CW */
2684
-#line 672 "pikchr.y"
2696
+#line 684 "pikchr.y"
26852697
{p->cur->cw = 1;}
2686
-#line 2711 "pikchr.c"
2698
+#line 2723 "pikchr.c"
26872699
break;
26882700
case 54: /* boolproperty ::= CCW */
2689
-#line 673 "pikchr.y"
2701
+#line 685 "pikchr.y"
26902702
{p->cur->cw = 0;}
2691
-#line 2716 "pikchr.c"
2703
+#line 2728 "pikchr.c"
26922704
break;
26932705
case 55: /* boolproperty ::= LARROW */
2694
-#line 674 "pikchr.y"
2706
+#line 686 "pikchr.y"
26952707
{p->cur->larrow=1; p->cur->rarrow=0; }
2696
-#line 2721 "pikchr.c"
2708
+#line 2733 "pikchr.c"
26972709
break;
26982710
case 56: /* boolproperty ::= RARROW */
2699
-#line 675 "pikchr.y"
2711
+#line 687 "pikchr.y"
27002712
{p->cur->larrow=0; p->cur->rarrow=1; }
2701
-#line 2726 "pikchr.c"
2713
+#line 2738 "pikchr.c"
27022714
break;
27032715
case 57: /* boolproperty ::= LRARROW */
2704
-#line 676 "pikchr.y"
2716
+#line 688 "pikchr.y"
27052717
{p->cur->larrow=1; p->cur->rarrow=1; }
2706
-#line 2731 "pikchr.c"
2718
+#line 2743 "pikchr.c"
27072719
break;
27082720
case 58: /* boolproperty ::= INVIS */
2709
-#line 677 "pikchr.y"
2721
+#line 689 "pikchr.y"
27102722
{p->cur->sw = -0.00001;}
2711
-#line 2736 "pikchr.c"
2723
+#line 2748 "pikchr.c"
27122724
break;
27132725
case 59: /* boolproperty ::= THICK */
2714
-#line 678 "pikchr.y"
2726
+#line 690 "pikchr.y"
27152727
{p->cur->sw *= 1.5;}
2716
-#line 2741 "pikchr.c"
2728
+#line 2753 "pikchr.c"
27172729
break;
27182730
case 60: /* boolproperty ::= THIN */
2719
-#line 679 "pikchr.y"
2731
+#line 691 "pikchr.y"
27202732
{p->cur->sw *= 0.67;}
2721
-#line 2746 "pikchr.c"
2733
+#line 2758 "pikchr.c"
27222734
break;
27232735
case 61: /* boolproperty ::= SOLID */
2724
-#line 680 "pikchr.y"
2736
+#line 692 "pikchr.y"
27252737
{p->cur->sw = pik_value(p,"thickness",9,0);
27262738
p->cur->dotted = p->cur->dashed = 0.0;}
2727
-#line 2752 "pikchr.c"
2739
+#line 2764 "pikchr.c"
27282740
break;
27292741
case 62: /* textposition ::= */
2730
-#line 683 "pikchr.y"
2742
+#line 695 "pikchr.y"
27312743
{yymsp[1].minor.yy188 = 0;}
2732
-#line 2757 "pikchr.c"
2744
+#line 2769 "pikchr.c"
27332745
break;
27342746
case 63: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|MONO|ALIGNED|BIG|SMALL */
2735
-#line 686 "pikchr.y"
2747
+#line 698 "pikchr.y"
27362748
{yylhsminor.yy188 = (short int)pik_text_position(yymsp[-1].minor.yy188,&yymsp[0].minor.yy0);}
2737
-#line 2762 "pikchr.c"
2749
+#line 2774 "pikchr.c"
27382750
yymsp[-1].minor.yy188 = yylhsminor.yy188;
27392751
break;
27402752
case 64: /* position ::= expr COMMA expr */
2741
-#line 689 "pikchr.y"
2753
+#line 701 "pikchr.y"
27422754
{yylhsminor.yy63.x=yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[0].minor.yy21;}
2743
-#line 2768 "pikchr.c"
2755
+#line 2780 "pikchr.c"
27442756
yymsp[-2].minor.yy63 = yylhsminor.yy63;
27452757
break;
27462758
case 65: /* position ::= place PLUS expr COMMA expr */
2747
-#line 691 "pikchr.y"
2759
+#line 703 "pikchr.y"
27482760
{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"
2761
+#line 2786 "pikchr.c"
27502762
yymsp[-4].minor.yy63 = yylhsminor.yy63;
27512763
break;
27522764
case 66: /* position ::= place MINUS expr COMMA expr */
2753
-#line 692 "pikchr.y"
2765
+#line 704 "pikchr.y"
27542766
{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"
2767
+#line 2792 "pikchr.c"
27562768
yymsp[-4].minor.yy63 = yylhsminor.yy63;
27572769
break;
27582770
case 67: /* position ::= place PLUS LP expr COMMA expr RP */
2759
-#line 694 "pikchr.y"
2771
+#line 706 "pikchr.y"
27602772
{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"
2773
+#line 2798 "pikchr.c"
27622774
yymsp[-6].minor.yy63 = yylhsminor.yy63;
27632775
break;
27642776
case 68: /* position ::= place MINUS LP expr COMMA expr RP */
2765
-#line 696 "pikchr.y"
2777
+#line 708 "pikchr.y"
27662778
{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"
2779
+#line 2804 "pikchr.c"
27682780
yymsp[-6].minor.yy63 = yylhsminor.yy63;
27692781
break;
27702782
case 69: /* position ::= LP position COMMA position RP */
2771
-#line 697 "pikchr.y"
2783
+#line 709 "pikchr.y"
27722784
{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"
2785
+#line 2810 "pikchr.c"
27742786
break;
27752787
case 70: /* position ::= LP position RP */
2776
-#line 698 "pikchr.y"
2788
+#line 710 "pikchr.y"
27772789
{yymsp[-2].minor.yy63=yymsp[-1].minor.yy63;}
2778
-#line 2803 "pikchr.c"
2790
+#line 2815 "pikchr.c"
27792791
break;
27802792
case 71: /* position ::= expr between position AND position */
2781
-#line 700 "pikchr.y"
2793
+#line 712 "pikchr.y"
27822794
{yylhsminor.yy63 = pik_position_between(yymsp[-4].minor.yy21,yymsp[-2].minor.yy63,yymsp[0].minor.yy63);}
2783
-#line 2808 "pikchr.c"
2795
+#line 2820 "pikchr.c"
27842796
yymsp[-4].minor.yy63 = yylhsminor.yy63;
27852797
break;
27862798
case 72: /* position ::= expr LT position COMMA position GT */
2787
-#line 702 "pikchr.y"
2799
+#line 714 "pikchr.y"
27882800
{yylhsminor.yy63 = pik_position_between(yymsp[-5].minor.yy21,yymsp[-3].minor.yy63,yymsp[-1].minor.yy63);}
2789
-#line 2814 "pikchr.c"
2801
+#line 2826 "pikchr.c"
27902802
yymsp[-5].minor.yy63 = yylhsminor.yy63;
27912803
break;
27922804
case 73: /* position ::= expr ABOVE position */
2793
-#line 703 "pikchr.y"
2805
+#line 715 "pikchr.y"
27942806
{yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y += yymsp[-2].minor.yy21;}
2795
-#line 2820 "pikchr.c"
2807
+#line 2832 "pikchr.c"
27962808
yymsp[-2].minor.yy63 = yylhsminor.yy63;
27972809
break;
27982810
case 74: /* position ::= expr BELOW position */
2799
-#line 704 "pikchr.y"
2811
+#line 716 "pikchr.y"
28002812
{yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y -= yymsp[-2].minor.yy21;}
2801
-#line 2826 "pikchr.c"
2813
+#line 2838 "pikchr.c"
28022814
yymsp[-2].minor.yy63 = yylhsminor.yy63;
28032815
break;
28042816
case 75: /* position ::= expr LEFT OF position */
2805
-#line 705 "pikchr.y"
2817
+#line 717 "pikchr.y"
28062818
{yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x -= yymsp[-3].minor.yy21;}
2807
-#line 2832 "pikchr.c"
2819
+#line 2844 "pikchr.c"
28082820
yymsp[-3].minor.yy63 = yylhsminor.yy63;
28092821
break;
28102822
case 76: /* position ::= expr RIGHT OF position */
2811
-#line 706 "pikchr.y"
2823
+#line 718 "pikchr.y"
28122824
{yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x += yymsp[-3].minor.yy21;}
2813
-#line 2838 "pikchr.c"
2825
+#line 2850 "pikchr.c"
28142826
yymsp[-3].minor.yy63 = yylhsminor.yy63;
28152827
break;
28162828
case 77: /* position ::= expr ON HEADING EDGEPT OF position */
2817
-#line 708 "pikchr.y"
2829
+#line 720 "pikchr.y"
28182830
{yylhsminor.yy63 = pik_position_at_hdg(yymsp[-5].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2819
-#line 2844 "pikchr.c"
2831
+#line 2856 "pikchr.c"
28202832
yymsp[-5].minor.yy63 = yylhsminor.yy63;
28212833
break;
28222834
case 78: /* position ::= expr HEADING EDGEPT OF position */
2823
-#line 710 "pikchr.y"
2835
+#line 722 "pikchr.y"
28242836
{yylhsminor.yy63 = pik_position_at_hdg(yymsp[-4].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2825
-#line 2850 "pikchr.c"
2837
+#line 2862 "pikchr.c"
28262838
yymsp[-4].minor.yy63 = yylhsminor.yy63;
28272839
break;
28282840
case 79: /* position ::= expr EDGEPT OF position */
2829
-#line 712 "pikchr.y"
2841
+#line 724 "pikchr.y"
28302842
{yylhsminor.yy63 = pik_position_at_hdg(yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2831
-#line 2856 "pikchr.c"
2843
+#line 2868 "pikchr.c"
28322844
yymsp[-3].minor.yy63 = yylhsminor.yy63;
28332845
break;
28342846
case 80: /* position ::= expr ON HEADING expr FROM position */
2835
-#line 714 "pikchr.y"
2847
+#line 726 "pikchr.y"
28362848
{yylhsminor.yy63 = pik_position_at_angle(yymsp[-5].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2837
-#line 2862 "pikchr.c"
2849
+#line 2874 "pikchr.c"
28382850
yymsp[-5].minor.yy63 = yylhsminor.yy63;
28392851
break;
28402852
case 81: /* position ::= expr HEADING expr FROM position */
2841
-#line 716 "pikchr.y"
2853
+#line 728 "pikchr.y"
28422854
{yylhsminor.yy63 = pik_position_at_angle(yymsp[-4].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2843
-#line 2868 "pikchr.c"
2855
+#line 2880 "pikchr.c"
28442856
yymsp[-4].minor.yy63 = yylhsminor.yy63;
28452857
break;
28462858
case 82: /* place ::= edge OF object */
2847
-#line 728 "pikchr.y"
2859
+#line 740 "pikchr.y"
28482860
{yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2849
-#line 2874 "pikchr.c"
2861
+#line 2886 "pikchr.c"
28502862
yymsp[-2].minor.yy63 = yylhsminor.yy63;
28512863
break;
28522864
case 83: /* place2 ::= object */
2853
-#line 729 "pikchr.y"
2865
+#line 741 "pikchr.y"
28542866
{yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,0);}
2855
-#line 2880 "pikchr.c"
2867
+#line 2892 "pikchr.c"
28562868
yymsp[0].minor.yy63 = yylhsminor.yy63;
28572869
break;
28582870
case 84: /* place2 ::= object DOT_E edge */
2859
-#line 730 "pikchr.y"
2871
+#line 742 "pikchr.y"
28602872
{yylhsminor.yy63 = pik_place_of_elem(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2861
-#line 2886 "pikchr.c"
2873
+#line 2898 "pikchr.c"
28622874
yymsp[-2].minor.yy63 = yylhsminor.yy63;
28632875
break;
28642876
case 85: /* place2 ::= NTH VERTEX OF object */
2865
-#line 731 "pikchr.y"
2877
+#line 743 "pikchr.y"
28662878
{yylhsminor.yy63 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy162);}
2867
-#line 2892 "pikchr.c"
2879
+#line 2904 "pikchr.c"
28682880
yymsp[-3].minor.yy63 = yylhsminor.yy63;
28692881
break;
28702882
case 86: /* object ::= nth */
2871
-#line 743 "pikchr.y"
2883
+#line 755 "pikchr.y"
28722884
{yylhsminor.yy162 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2873
-#line 2898 "pikchr.c"
2885
+#line 2910 "pikchr.c"
28742886
yymsp[0].minor.yy162 = yylhsminor.yy162;
28752887
break;
28762888
case 87: /* object ::= nth OF|IN object */
2877
-#line 744 "pikchr.y"
2889
+#line 756 "pikchr.y"
28782890
{yylhsminor.yy162 = pik_find_nth(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2879
-#line 2904 "pikchr.c"
2891
+#line 2916 "pikchr.c"
28802892
yymsp[-2].minor.yy162 = yylhsminor.yy162;
28812893
break;
28822894
case 88: /* objectname ::= THIS */
2883
-#line 746 "pikchr.y"
2895
+#line 758 "pikchr.y"
28842896
{yymsp[0].minor.yy162 = p->cur;}
2885
-#line 2910 "pikchr.c"
2897
+#line 2922 "pikchr.c"
28862898
break;
28872899
case 89: /* objectname ::= PLACENAME */
2888
-#line 747 "pikchr.y"
2900
+#line 759 "pikchr.y"
28892901
{yylhsminor.yy162 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2890
-#line 2915 "pikchr.c"
2902
+#line 2927 "pikchr.c"
28912903
yymsp[0].minor.yy162 = yylhsminor.yy162;
28922904
break;
28932905
case 90: /* objectname ::= objectname DOT_U PLACENAME */
2894
-#line 749 "pikchr.y"
2906
+#line 761 "pikchr.y"
28952907
{yylhsminor.yy162 = pik_find_byname(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2896
-#line 2921 "pikchr.c"
2908
+#line 2933 "pikchr.c"
28972909
yymsp[-2].minor.yy162 = yylhsminor.yy162;
28982910
break;
28992911
case 91: /* nth ::= NTH CLASSNAME */
2900
-#line 751 "pikchr.y"
2912
+#line 763 "pikchr.y"
29012913
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2902
-#line 2927 "pikchr.c"
2914
+#line 2939 "pikchr.c"
29032915
yymsp[-1].minor.yy0 = yylhsminor.yy0;
29042916
break;
29052917
case 92: /* nth ::= NTH LAST CLASSNAME */
2906
-#line 752 "pikchr.y"
2918
+#line 764 "pikchr.y"
29072919
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2908
-#line 2933 "pikchr.c"
2920
+#line 2945 "pikchr.c"
29092921
yymsp[-2].minor.yy0 = yylhsminor.yy0;
29102922
break;
29112923
case 93: /* nth ::= LAST CLASSNAME */
2912
-#line 753 "pikchr.y"
2924
+#line 765 "pikchr.y"
29132925
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2914
-#line 2939 "pikchr.c"
2926
+#line 2951 "pikchr.c"
29152927
break;
29162928
case 94: /* nth ::= LAST */
2917
-#line 754 "pikchr.y"
2929
+#line 766 "pikchr.y"
29182930
{yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2919
-#line 2944 "pikchr.c"
2931
+#line 2956 "pikchr.c"
29202932
yymsp[0].minor.yy0 = yylhsminor.yy0;
29212933
break;
29222934
case 95: /* nth ::= NTH LB RB */
2923
-#line 755 "pikchr.y"
2935
+#line 767 "pikchr.y"
29242936
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2925
-#line 2950 "pikchr.c"
2937
+#line 2962 "pikchr.c"
29262938
yymsp[-2].minor.yy0 = yylhsminor.yy0;
29272939
break;
29282940
case 96: /* nth ::= NTH LAST LB RB */
2929
-#line 756 "pikchr.y"
2941
+#line 768 "pikchr.y"
29302942
{yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2931
-#line 2956 "pikchr.c"
2943
+#line 2968 "pikchr.c"
29322944
yymsp[-3].minor.yy0 = yylhsminor.yy0;
29332945
break;
29342946
case 97: /* nth ::= LAST LB RB */
2935
-#line 757 "pikchr.y"
2947
+#line 769 "pikchr.y"
29362948
{yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2937
-#line 2962 "pikchr.c"
2949
+#line 2974 "pikchr.c"
29382950
break;
29392951
case 98: /* expr ::= expr PLUS expr */
2940
-#line 759 "pikchr.y"
2952
+#line 771 "pikchr.y"
29412953
{yylhsminor.yy21=yymsp[-2].minor.yy21+yymsp[0].minor.yy21;}
2942
-#line 2967 "pikchr.c"
2954
+#line 2979 "pikchr.c"
29432955
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29442956
break;
29452957
case 99: /* expr ::= expr MINUS expr */
2946
-#line 760 "pikchr.y"
2958
+#line 772 "pikchr.y"
29472959
{yylhsminor.yy21=yymsp[-2].minor.yy21-yymsp[0].minor.yy21;}
2948
-#line 2973 "pikchr.c"
2960
+#line 2985 "pikchr.c"
29492961
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29502962
break;
29512963
case 100: /* expr ::= expr STAR expr */
2952
-#line 761 "pikchr.y"
2964
+#line 773 "pikchr.y"
29532965
{yylhsminor.yy21=yymsp[-2].minor.yy21*yymsp[0].minor.yy21;}
2954
-#line 2979 "pikchr.c"
2966
+#line 2991 "pikchr.c"
29552967
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29562968
break;
29572969
case 101: /* expr ::= expr SLASH expr */
2958
-#line 762 "pikchr.y"
2970
+#line 774 "pikchr.y"
29592971
{
29602972
if( yymsp[0].minor.yy21==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy21 = 0.0; }
29612973
else{ yylhsminor.yy21 = yymsp[-2].minor.yy21/yymsp[0].minor.yy21; }
29622974
}
2963
-#line 2988 "pikchr.c"
2975
+#line 3000 "pikchr.c"
29642976
yymsp[-2].minor.yy21 = yylhsminor.yy21;
29652977
break;
29662978
case 102: /* expr ::= MINUS expr */
2967
-#line 766 "pikchr.y"
2979
+#line 778 "pikchr.y"
29682980
{yymsp[-1].minor.yy21=-yymsp[0].minor.yy21;}
2969
-#line 2994 "pikchr.c"
2981
+#line 3006 "pikchr.c"
29702982
break;
29712983
case 103: /* expr ::= PLUS expr */
2972
-#line 767 "pikchr.y"
2984
+#line 779 "pikchr.y"
29732985
{yymsp[-1].minor.yy21=yymsp[0].minor.yy21;}
2974
-#line 2999 "pikchr.c"
2986
+#line 3011 "pikchr.c"
29752987
break;
29762988
case 104: /* expr ::= LP expr RP */
2977
-#line 768 "pikchr.y"
2989
+#line 780 "pikchr.y"
29782990
{yymsp[-2].minor.yy21=yymsp[-1].minor.yy21;}
2979
-#line 3004 "pikchr.c"
2991
+#line 3016 "pikchr.c"
29802992
break;
29812993
case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2982
-#line 769 "pikchr.y"
2994
+#line 781 "pikchr.y"
29832995
{yymsp[-2].minor.yy21=pik_get_var(p,&yymsp[-1].minor.yy0);}
2984
-#line 3009 "pikchr.c"
2996
+#line 3021 "pikchr.c"
29852997
break;
29862998
case 106: /* expr ::= NUMBER */
2987
-#line 770 "pikchr.y"
2999
+#line 782 "pikchr.y"
29883000
{yylhsminor.yy21=pik_atof(&yymsp[0].minor.yy0);}
2989
-#line 3014 "pikchr.c"
3001
+#line 3026 "pikchr.c"
29903002
yymsp[0].minor.yy21 = yylhsminor.yy21;
29913003
break;
29923004
case 107: /* expr ::= ID */
2993
-#line 771 "pikchr.y"
3005
+#line 783 "pikchr.y"
29943006
{yylhsminor.yy21=pik_get_var(p,&yymsp[0].minor.yy0);}
2995
-#line 3020 "pikchr.c"
3007
+#line 3032 "pikchr.c"
29963008
yymsp[0].minor.yy21 = yylhsminor.yy21;
29973009
break;
29983010
case 108: /* expr ::= FUNC1 LP expr RP */
2999
-#line 772 "pikchr.y"
3011
+#line 784 "pikchr.y"
30003012
{yylhsminor.yy21 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy21,0.0);}
3001
-#line 3026 "pikchr.c"
3013
+#line 3038 "pikchr.c"
30023014
yymsp[-3].minor.yy21 = yylhsminor.yy21;
30033015
break;
30043016
case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */
3005
-#line 773 "pikchr.y"
3017
+#line 785 "pikchr.y"
30063018
{yylhsminor.yy21 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy21,yymsp[-1].minor.yy21);}
3007
-#line 3032 "pikchr.c"
3019
+#line 3044 "pikchr.c"
30083020
yymsp[-5].minor.yy21 = yylhsminor.yy21;
30093021
break;
30103022
case 110: /* expr ::= DIST LP position COMMA position RP */
3011
-#line 774 "pikchr.y"
3023
+#line 786 "pikchr.y"
30123024
{yymsp[-5].minor.yy21 = pik_dist(&yymsp[-3].minor.yy63,&yymsp[-1].minor.yy63);}
3013
-#line 3038 "pikchr.c"
3025
+#line 3050 "pikchr.c"
30143026
break;
30153027
case 111: /* expr ::= place2 DOT_XY X */
3016
-#line 775 "pikchr.y"
3028
+#line 787 "pikchr.y"
30173029
{yylhsminor.yy21 = yymsp[-2].minor.yy63.x;}
3018
-#line 3043 "pikchr.c"
3030
+#line 3055 "pikchr.c"
30193031
yymsp[-2].minor.yy21 = yylhsminor.yy21;
30203032
break;
30213033
case 112: /* expr ::= place2 DOT_XY Y */
3022
-#line 776 "pikchr.y"
3034
+#line 788 "pikchr.y"
30233035
{yylhsminor.yy21 = yymsp[-2].minor.yy63.y;}
3024
-#line 3049 "pikchr.c"
3036
+#line 3061 "pikchr.c"
30253037
yymsp[-2].minor.yy21 = yylhsminor.yy21;
30263038
break;
30273039
case 113: /* expr ::= object DOT_L numproperty */
30283040
case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114);
30293041
case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115);
3030
-#line 777 "pikchr.y"
3042
+#line 789 "pikchr.y"
30313043
{yylhsminor.yy21=pik_property_of(yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
3032
-#line 3057 "pikchr.c"
3044
+#line 3069 "pikchr.c"
30333045
yymsp[-2].minor.yy21 = yylhsminor.yy21;
30343046
break;
30353047
default:
30363048
/* (116) lvalue ::= ID */ yytestcase(yyruleno==116);
30373049
/* (117) lvalue ::= FILL */ yytestcase(yyruleno==117);
@@ -3130,19 +3142,19 @@
31303142
){
31313143
pik_parserARG_FETCH
31323144
pik_parserCTX_FETCH
31333145
#define TOKEN yyminor
31343146
/************ Begin %syntax_error code ****************************************/
3135
-#line 537 "pikchr.y"
3147
+#line 549 "pikchr.y"
31363148
31373149
if( TOKEN.z && TOKEN.z[0] ){
31383150
pik_error(p, &TOKEN, "syntax error");
31393151
}else{
31403152
pik_error(p, 0, "syntax error");
31413153
}
31423154
UNUSED_PARAMETER(yymajor);
3143
-#line 3168 "pikchr.c"
3155
+#line 3180 "pikchr.c"
31443156
/************ End %syntax_error code ******************************************/
31453157
pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
31463158
pik_parserCTX_STORE
31473159
}
31483160
@@ -3407,11 +3419,11 @@
34073419
#else
34083420
(void)iToken;
34093421
return 0;
34103422
#endif
34113423
}
3412
-#line 782 "pikchr.y"
3424
+#line 794 "pikchr.y"
34133425
34143426
34153427
34163428
/* Chart of the 148 official CSS color names with their
34173429
** corresponding RGB values thru Color Module Level 4:
@@ -6495,13 +6507,13 @@
64956507
unsigned int i;
64966508
mid = (first+last)/2;
64976509
zClr = aColor[mid].zName;
64986510
for(i=0; i<pId->n; i++){
64996511
c1 = zClr[i]&0x7f;
6500
- if( isupper(c1) ) c1 = tolower(c1);
6512
+ if( IsUpper(c1) ) c1 = ToLower(c1);
65016513
c2 = pId->z[i]&0x7f;
6502
- if( isupper(c2) ) c2 = tolower(c2);
6514
+ if( IsUpper(c2) ) c2 = ToLower(c2);
65036515
c = c2 - c1;
65046516
if( c ) break;
65056517
}
65066518
if( c==0 && aColor[mid].zName[pId->n] ) c = -1;
65076519
if( c==0 ) return (double)aColor[mid].val;
@@ -7605,11 +7617,11 @@
76057617
}
76067618
default: {
76077619
c = z[0];
76087620
if( c=='.' ){
76097621
unsigned char c1 = z[1];
7610
- if( islower(c1) ){
7622
+ if( IsLower(c1) ){
76117623
const PikWord *pFound;
76127624
for(i=2; (c = z[i])>='a' && c<='z'; i++){}
76137625
pFound = pik_find_word((const char*)z+1, i-1,
76147626
pik_keywords, count(pik_keywords));
76157627
if( pFound && (pFound->eEdge>0 ||
@@ -7625,15 +7637,15 @@
76257637
}else{
76267638
/* Any other "dot" */
76277639
pToken->eType = T_DOT_L;
76287640
}
76297641
return 1;
7630
- }else if( isdigit(c1) ){
7642
+ }else if( IsDigit(c1) ){
76317643
i = 0;
76327644
/* no-op. Fall through to number handling */
7633
- }else if( isupper(c1) ){
7634
- for(i=2; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7645
+ }else if( IsUpper(c1) ){
7646
+ for(i=2; (c = z[i])!=0 && (IsAlnum(c) || c=='_'); i++){}
76357647
pToken->eType = T_DOT_U;
76367648
return 1;
76377649
}else{
76387650
pToken->eType = T_ERROR;
76397651
return 1;
@@ -7644,11 +7656,11 @@
76447656
int isInt = 1;
76457657
if( c!='.' ){
76467658
nDigit = 1;
76477659
for(i=1; (c = z[i])>='0' && c<='9'; i++){ nDigit++; }
76487660
if( i==1 && (c=='x' || c=='X') ){
7649
- for(i=2; (c = z[i])!=0 && isxdigit(c); i++){}
7661
+ for(i=2; (c = z[i])!=0 && IsXDigit(c); i++){}
76507662
pToken->eType = T_NUMBER;
76517663
return i;
76527664
}
76537665
}else{
76547666
isInt = 0;
@@ -7700,13 +7712,13 @@
77007712
){
77017713
i += 2;
77027714
}
77037715
pToken->eType = T_NUMBER;
77047716
return i;
7705
- }else if( islower(c) ){
7717
+ }else if( IsLower(c) ){
77067718
const PikWord *pFound;
7707
- for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7719
+ for(i=1; (c = z[i])!=0 && (IsAlnum(c) || c=='_'); i++){}
77087720
pFound = pik_find_word((const char*)z, i,
77097721
pik_keywords, count(pik_keywords));
77107722
if( pFound ){
77117723
pToken->eType = pFound->eType;
77127724
pToken->eCode = pFound->eCode;
@@ -7719,19 +7731,19 @@
77197731
}else{
77207732
pToken->eType = T_ID;
77217733
}
77227734
return i;
77237735
}else if( c>='A' && c<='Z' ){
7724
- for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7736
+ for(i=1; (c = z[i])!=0 && (IsAlnum(c) || c=='_'); i++){}
77257737
pToken->eType = T_PLACENAME;
77267738
return i;
7727
- }else if( c=='$' && z[1]>='1' && z[1]<='9' && !isdigit(z[2]) ){
7739
+ }else if( c=='$' && z[1]>='1' && z[1]<='9' && !IsDigit(z[2]) ){
77287740
pToken->eType = T_PARAMETER;
77297741
pToken->eCode = z[1] - '1';
77307742
return 2;
77317743
}else if( c=='_' || c=='$' || c=='@' ){
7732
- for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7744
+ for(i=1; (c = z[i])!=0 && (IsAlnum(c) || c=='_'); i++){}
77337745
pToken->eType = T_ID;
77347746
return i;
77357747
}else{
77367748
pToken->eType = T_ERROR;
77377749
return 1;
@@ -7814,12 +7826,12 @@
78147826
/* Remove leading and trailing whitespace from each argument.
78157827
** If what remains is one of $1, $2, ... $9 then transfer the
78167828
** corresponding argument from the outer context */
78177829
for(j=0; j<=nArg; j++){
78187830
PToken *t = &args[j];
7819
- while( t->n>0 && isspace(t->z[0]) ){ t->n--; t->z++; }
7820
- while( t->n>0 && isspace(t->z[t->n-1]) ){ t->n--; }
7831
+ while( t->n>0 && IsSpace(t->z[0]) ){ t->n--; t->z++; }
7832
+ while( t->n>0 && IsSpace(t->z[t->n-1]) ){ t->n--; }
78217833
if( t->n==2 && t->z[0]=='$' && t->z[1]>='1' && t->z[1]<='9' ){
78227834
if( pOuter ) *t = pOuter[t->z[1]-'1'];
78237835
else t->n = 0;
78247836
}
78257837
}
@@ -7896,11 +7908,11 @@
78967908
pMac->inUse = 0;
78977909
}else{
78987910
#if 0
78997911
printf("******** Token %s (%d): \"%.*s\" **************\n",
79007912
yyTokenName[token.eType], token.eType,
7901
- (int)(isspace(token.z[0]) ? 0 : sz), token.z);
7913
+ (int)(IsSpace(token.z[0]) ? 0 : sz), token.z);
79027914
#endif
79037915
token.n = (unsigned short)(sz & 0xffff);
79047916
if( p->nToken++ > PIKCHR_TOKEN_LIMIT ){
79057917
pik_error(p, &token, "script is too complex");
79067918
break;
@@ -8242,6 +8254,6 @@
82428254
82438255
82448256
#endif /* PIKCHR_TCL */
82458257
82468258
8247
-#line 8272 "pikchr.c"
8259
+#line 8284 "pikchr.c"
82488260
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -125,10 +125,22 @@
125 #include <assert.h>
126 #define count(X) (sizeof(X)/sizeof(X[0]))
127 #ifndef M_PI
128 # define M_PI 3.1415926535897932385
129 #endif
 
 
 
 
 
 
 
 
 
 
 
 
130
131 /* Limit the number of tokens in a single script to avoid run-away
132 ** macro expansion attacks. See forum post
133 ** https://pikchr.org/home/forumpost/ef8684c6955a411a
134 */
@@ -492,11 +504,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
@@ -1745,22 +1757,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 }
@@ -1991,14 +2003,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
@@ -2419,619 +2431,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);
@@ -3130,19 +3142,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
@@ -3407,11 +3419,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:
@@ -6495,13 +6507,13 @@
6495 unsigned int i;
6496 mid = (first+last)/2;
6497 zClr = aColor[mid].zName;
6498 for(i=0; i<pId->n; i++){
6499 c1 = zClr[i]&0x7f;
6500 if( isupper(c1) ) c1 = tolower(c1);
6501 c2 = pId->z[i]&0x7f;
6502 if( isupper(c2) ) c2 = tolower(c2);
6503 c = c2 - c1;
6504 if( c ) break;
6505 }
6506 if( c==0 && aColor[mid].zName[pId->n] ) c = -1;
6507 if( c==0 ) return (double)aColor[mid].val;
@@ -7605,11 +7617,11 @@
7605 }
7606 default: {
7607 c = z[0];
7608 if( c=='.' ){
7609 unsigned char c1 = z[1];
7610 if( islower(c1) ){
7611 const PikWord *pFound;
7612 for(i=2; (c = z[i])>='a' && c<='z'; i++){}
7613 pFound = pik_find_word((const char*)z+1, i-1,
7614 pik_keywords, count(pik_keywords));
7615 if( pFound && (pFound->eEdge>0 ||
@@ -7625,15 +7637,15 @@
7625 }else{
7626 /* Any other "dot" */
7627 pToken->eType = T_DOT_L;
7628 }
7629 return 1;
7630 }else if( isdigit(c1) ){
7631 i = 0;
7632 /* no-op. Fall through to number handling */
7633 }else if( isupper(c1) ){
7634 for(i=2; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7635 pToken->eType = T_DOT_U;
7636 return 1;
7637 }else{
7638 pToken->eType = T_ERROR;
7639 return 1;
@@ -7644,11 +7656,11 @@
7644 int isInt = 1;
7645 if( c!='.' ){
7646 nDigit = 1;
7647 for(i=1; (c = z[i])>='0' && c<='9'; i++){ nDigit++; }
7648 if( i==1 && (c=='x' || c=='X') ){
7649 for(i=2; (c = z[i])!=0 && isxdigit(c); i++){}
7650 pToken->eType = T_NUMBER;
7651 return i;
7652 }
7653 }else{
7654 isInt = 0;
@@ -7700,13 +7712,13 @@
7700 ){
7701 i += 2;
7702 }
7703 pToken->eType = T_NUMBER;
7704 return i;
7705 }else if( islower(c) ){
7706 const PikWord *pFound;
7707 for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7708 pFound = pik_find_word((const char*)z, i,
7709 pik_keywords, count(pik_keywords));
7710 if( pFound ){
7711 pToken->eType = pFound->eType;
7712 pToken->eCode = pFound->eCode;
@@ -7719,19 +7731,19 @@
7719 }else{
7720 pToken->eType = T_ID;
7721 }
7722 return i;
7723 }else if( c>='A' && c<='Z' ){
7724 for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7725 pToken->eType = T_PLACENAME;
7726 return i;
7727 }else if( c=='$' && z[1]>='1' && z[1]<='9' && !isdigit(z[2]) ){
7728 pToken->eType = T_PARAMETER;
7729 pToken->eCode = z[1] - '1';
7730 return 2;
7731 }else if( c=='_' || c=='$' || c=='@' ){
7732 for(i=1; (c = z[i])!=0 && (isalnum(c) || c=='_'); i++){}
7733 pToken->eType = T_ID;
7734 return i;
7735 }else{
7736 pToken->eType = T_ERROR;
7737 return 1;
@@ -7814,12 +7826,12 @@
7814 /* Remove leading and trailing whitespace from each argument.
7815 ** If what remains is one of $1, $2, ... $9 then transfer the
7816 ** corresponding argument from the outer context */
7817 for(j=0; j<=nArg; j++){
7818 PToken *t = &args[j];
7819 while( t->n>0 && isspace(t->z[0]) ){ t->n--; t->z++; }
7820 while( t->n>0 && isspace(t->z[t->n-1]) ){ t->n--; }
7821 if( t->n==2 && t->z[0]=='$' && t->z[1]>='1' && t->z[1]<='9' ){
7822 if( pOuter ) *t = pOuter[t->z[1]-'1'];
7823 else t->n = 0;
7824 }
7825 }
@@ -7896,11 +7908,11 @@
7896 pMac->inUse = 0;
7897 }else{
7898 #if 0
7899 printf("******** Token %s (%d): \"%.*s\" **************\n",
7900 yyTokenName[token.eType], token.eType,
7901 (int)(isspace(token.z[0]) ? 0 : sz), token.z);
7902 #endif
7903 token.n = (unsigned short)(sz & 0xffff);
7904 if( p->nToken++ > PIKCHR_TOKEN_LIMIT ){
7905 pik_error(p, &token, "script is too complex");
7906 break;
@@ -8242,6 +8254,6 @@
8242
8243
8244 #endif /* PIKCHR_TCL */
8245
8246
8247 #line 8272 "pikchr.c"
8248
--- extsrc/pikchr.c
+++ extsrc/pikchr.c
@@ -125,10 +125,22 @@
125 #include <assert.h>
126 #define count(X) (sizeof(X)/sizeof(X[0]))
127 #ifndef M_PI
128 # define M_PI 3.1415926535897932385
129 #endif
130
131 /*
132 ** Typesafe version of ctype.h macros. Cygwin requires this, I'm told.
133 */
134 #define IsUpper(X) isupper((unsigned char)(X))
135 #define IsLower(X) islower((unsigned char)(X))
136 #define ToLower(X) tolower((unsigned char)(X))
137 #define IsDigit(X) isdigit((unsigned char)(X))
138 #define IsXDigit(X) isxdigit((unsigned char)(X))
139 #define IsSpace(X) isspace((unsigned char)(X))
140 #define IsAlnum(X) isalnum((unsigned char)(X))
141
142
143 /* Limit the number of tokens in a single script to avoid run-away
144 ** macro expansion attacks. See forum post
145 ** https://pikchr.org/home/forumpost/ef8684c6955a411a
146 */
@@ -492,11 +504,11 @@
504 static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*);
505 static PNum pik_dist(PPoint*,PPoint*);
506 static void pik_add_macro(Pik*,PToken *pId,PToken *pCode);
507
508
509 #line 535 "pikchr.c"
510 /**************** End of %include directives **********************************/
511 /* These constants specify the various numeric values for terminal symbols.
512 ***************** Begin token definitions *************************************/
513 #ifndef T_ID
514 #define T_ID 1
@@ -1745,22 +1757,22 @@
1757 ** inside the C code.
1758 */
1759 /********* Begin destructor definitions ***************************************/
1760 case 100: /* statement_list */
1761 {
1762 #line 523 "pikchr.y"
1763 pik_elist_free(p,(yypminor->yy235));
1764 #line 1789 "pikchr.c"
1765 }
1766 break;
1767 case 101: /* statement */
1768 case 102: /* unnamed_statement */
1769 case 103: /* basetype */
1770 {
1771 #line 525 "pikchr.y"
1772 pik_elem_free(p,(yypminor->yy162));
1773 #line 1798 "pikchr.c"
1774 }
1775 break;
1776 /********* End destructor definitions *****************************************/
1777 default: break; /* If no destructor action specified: do nothing */
1778 }
@@ -1991,14 +2003,14 @@
2003 #endif
2004 while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser);
2005 /* Here code is inserted which will execute if the parser
2006 ** stack every overflows */
2007 /******** Begin %stack_overflow code ******************************************/
2008 #line 557 "pikchr.y"
2009
2010 pik_error(p, 0, "parser stack overflow");
2011 #line 2036 "pikchr.c"
2012 /******** End %stack_overflow code ********************************************/
2013 pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */
2014 pik_parserCTX_STORE
2015 }
2016
@@ -2419,619 +2431,619 @@
2431 ** break;
2432 */
2433 /********** Begin reduce actions **********************************************/
2434 YYMINORTYPE yylhsminor;
2435 case 0: /* document ::= statement_list */
2436 #line 561 "pikchr.y"
2437 {pik_render(p,yymsp[0].minor.yy235);}
2438 #line 2463 "pikchr.c"
2439 break;
2440 case 1: /* statement_list ::= statement */
2441 #line 564 "pikchr.y"
2442 { yylhsminor.yy235 = pik_elist_append(p,0,yymsp[0].minor.yy162); }
2443 #line 2468 "pikchr.c"
2444 yymsp[0].minor.yy235 = yylhsminor.yy235;
2445 break;
2446 case 2: /* statement_list ::= statement_list EOL statement */
2447 #line 566 "pikchr.y"
2448 { yylhsminor.yy235 = pik_elist_append(p,yymsp[-2].minor.yy235,yymsp[0].minor.yy162); }
2449 #line 2474 "pikchr.c"
2450 yymsp[-2].minor.yy235 = yylhsminor.yy235;
2451 break;
2452 case 3: /* statement ::= */
2453 #line 569 "pikchr.y"
2454 { yymsp[1].minor.yy162 = 0; }
2455 #line 2480 "pikchr.c"
2456 break;
2457 case 4: /* statement ::= direction */
2458 #line 570 "pikchr.y"
2459 { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy162=0; }
2460 #line 2485 "pikchr.c"
2461 yymsp[0].minor.yy162 = yylhsminor.yy162;
2462 break;
2463 case 5: /* statement ::= lvalue ASSIGN rvalue */
2464 #line 571 "pikchr.y"
2465 {pik_set_var(p,&yymsp[-2].minor.yy0,yymsp[0].minor.yy21,&yymsp[-1].minor.yy0); yylhsminor.yy162=0;}
2466 #line 2491 "pikchr.c"
2467 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2468 break;
2469 case 6: /* statement ::= PLACENAME COLON unnamed_statement */
2470 #line 573 "pikchr.y"
2471 { yylhsminor.yy162 = yymsp[0].minor.yy162; pik_elem_setname(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0); }
2472 #line 2497 "pikchr.c"
2473 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2474 break;
2475 case 7: /* statement ::= PLACENAME COLON position */
2476 #line 575 "pikchr.y"
2477 { yylhsminor.yy162 = pik_elem_new(p,0,0,0);
2478 if(yylhsminor.yy162){ yylhsminor.yy162->ptAt = yymsp[0].minor.yy63; pik_elem_setname(p,yylhsminor.yy162,&yymsp[-2].minor.yy0); }}
2479 #line 2504 "pikchr.c"
2480 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2481 break;
2482 case 8: /* statement ::= unnamed_statement */
2483 #line 577 "pikchr.y"
2484 {yylhsminor.yy162 = yymsp[0].minor.yy162;}
2485 #line 2510 "pikchr.c"
2486 yymsp[0].minor.yy162 = yylhsminor.yy162;
2487 break;
2488 case 9: /* statement ::= print prlist */
2489 #line 578 "pikchr.y"
2490 {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy162=0;}
2491 #line 2516 "pikchr.c"
2492 break;
2493 case 10: /* statement ::= ASSERT LP expr EQ expr RP */
2494 #line 583 "pikchr.y"
2495 {yymsp[-5].minor.yy162=pik_assert(p,yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy21);}
2496 #line 2521 "pikchr.c"
2497 break;
2498 case 11: /* statement ::= ASSERT LP position EQ position RP */
2499 #line 585 "pikchr.y"
2500 {yymsp[-5].minor.yy162=pik_position_assert(p,&yymsp[-3].minor.yy63,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy63);}
2501 #line 2526 "pikchr.c"
2502 break;
2503 case 12: /* statement ::= DEFINE ID CODEBLOCK */
2504 #line 586 "pikchr.y"
2505 {yymsp[-2].minor.yy162=0; pik_add_macro(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
2506 #line 2531 "pikchr.c"
2507 break;
2508 case 13: /* rvalue ::= PLACENAME */
2509 #line 597 "pikchr.y"
2510 {yylhsminor.yy21 = pik_lookup_color(p,&yymsp[0].minor.yy0);}
2511 #line 2536 "pikchr.c"
2512 yymsp[0].minor.yy21 = yylhsminor.yy21;
2513 break;
2514 case 14: /* pritem ::= FILL */
2515 case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15);
2516 case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16);
2517 #line 602 "pikchr.y"
2518 {pik_append_num(p,"",pik_value(p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.n,0));}
2519 #line 2544 "pikchr.c"
2520 break;
2521 case 17: /* pritem ::= rvalue */
2522 #line 605 "pikchr.y"
2523 {pik_append_num(p,"",yymsp[0].minor.yy21);}
2524 #line 2549 "pikchr.c"
2525 break;
2526 case 18: /* pritem ::= STRING */
2527 #line 606 "pikchr.y"
2528 {pik_append_text(p,yymsp[0].minor.yy0.z+1,yymsp[0].minor.yy0.n-2,0);}
2529 #line 2554 "pikchr.c"
2530 break;
2531 case 19: /* prsep ::= COMMA */
2532 #line 607 "pikchr.y"
2533 {pik_append(p, " ", 1);}
2534 #line 2559 "pikchr.c"
2535 break;
2536 case 20: /* unnamed_statement ::= basetype attribute_list */
2537 #line 610 "pikchr.y"
2538 {yylhsminor.yy162 = yymsp[-1].minor.yy162; pik_after_adding_attributes(p,yylhsminor.yy162);}
2539 #line 2564 "pikchr.c"
2540 yymsp[-1].minor.yy162 = yylhsminor.yy162;
2541 break;
2542 case 21: /* basetype ::= CLASSNAME */
2543 #line 612 "pikchr.y"
2544 {yylhsminor.yy162 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); }
2545 #line 2570 "pikchr.c"
2546 yymsp[0].minor.yy162 = yylhsminor.yy162;
2547 break;
2548 case 22: /* basetype ::= STRING textposition */
2549 #line 614 "pikchr.y"
2550 {yymsp[-1].minor.yy0.eCode = yymsp[0].minor.yy188; yylhsminor.yy162 = pik_elem_new(p,0,&yymsp[-1].minor.yy0,0); }
2551 #line 2576 "pikchr.c"
2552 yymsp[-1].minor.yy162 = yylhsminor.yy162;
2553 break;
2554 case 23: /* basetype ::= LB savelist statement_list RB */
2555 #line 616 "pikchr.y"
2556 { 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; }
2557 #line 2582 "pikchr.c"
2558 break;
2559 case 24: /* savelist ::= */
2560 #line 621 "pikchr.y"
2561 {yymsp[1].minor.yy235 = p->list; p->list = 0;}
2562 #line 2587 "pikchr.c"
2563 break;
2564 case 25: /* relexpr ::= expr */
2565 #line 628 "pikchr.y"
2566 {yylhsminor.yy72.rAbs = yymsp[0].minor.yy21; yylhsminor.yy72.rRel = 0;}
2567 #line 2592 "pikchr.c"
2568 yymsp[0].minor.yy72 = yylhsminor.yy72;
2569 break;
2570 case 26: /* relexpr ::= expr PERCENT */
2571 #line 629 "pikchr.y"
2572 {yylhsminor.yy72.rAbs = 0; yylhsminor.yy72.rRel = yymsp[-1].minor.yy21/100;}
2573 #line 2598 "pikchr.c"
2574 yymsp[-1].minor.yy72 = yylhsminor.yy72;
2575 break;
2576 case 27: /* optrelexpr ::= */
2577 #line 631 "pikchr.y"
2578 {yymsp[1].minor.yy72.rAbs = 0; yymsp[1].minor.yy72.rRel = 1.0;}
2579 #line 2604 "pikchr.c"
2580 break;
2581 case 28: /* attribute_list ::= relexpr alist */
2582 #line 633 "pikchr.y"
2583 {pik_add_direction(p,0,&yymsp[-1].minor.yy72);}
2584 #line 2609 "pikchr.c"
2585 break;
2586 case 29: /* attribute ::= numproperty relexpr */
2587 #line 637 "pikchr.y"
2588 { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72); }
2589 #line 2614 "pikchr.c"
2590 break;
2591 case 30: /* attribute ::= dashproperty expr */
2592 #line 638 "pikchr.y"
2593 { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy21); }
2594 #line 2619 "pikchr.c"
2595 break;
2596 case 31: /* attribute ::= dashproperty */
2597 #line 639 "pikchr.y"
2598 { pik_set_dashed(p,&yymsp[0].minor.yy0,0); }
2599 #line 2624 "pikchr.c"
2600 break;
2601 case 32: /* attribute ::= colorproperty rvalue */
2602 #line 640 "pikchr.y"
2603 { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21); }
2604 #line 2629 "pikchr.c"
2605 break;
2606 case 33: /* attribute ::= go direction optrelexpr */
2607 #line 641 "pikchr.y"
2608 { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72);}
2609 #line 2634 "pikchr.c"
2610 break;
2611 case 34: /* attribute ::= go direction even position */
2612 #line 642 "pikchr.y"
2613 {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63);}
2614 #line 2639 "pikchr.c"
2615 break;
2616 case 35: /* attribute ::= CLOSE */
2617 #line 643 "pikchr.y"
2618 { pik_close_path(p,&yymsp[0].minor.yy0); }
2619 #line 2644 "pikchr.c"
2620 break;
2621 case 36: /* attribute ::= CHOP */
2622 #line 644 "pikchr.y"
2623 { p->cur->bChop = 1; }
2624 #line 2649 "pikchr.c"
2625 break;
2626 case 37: /* attribute ::= FROM position */
2627 #line 645 "pikchr.y"
2628 { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2629 #line 2654 "pikchr.c"
2630 break;
2631 case 38: /* attribute ::= TO position */
2632 #line 646 "pikchr.y"
2633 { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); }
2634 #line 2659 "pikchr.c"
2635 break;
2636 case 39: /* attribute ::= THEN */
2637 #line 647 "pikchr.y"
2638 { pik_then(p, &yymsp[0].minor.yy0, p->cur); }
2639 #line 2664 "pikchr.c"
2640 break;
2641 case 40: /* attribute ::= THEN optrelexpr HEADING expr */
2642 case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42);
2643 #line 649 "pikchr.y"
2644 {pik_move_hdg(p,&yymsp[-2].minor.yy72,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21,0,&yymsp[-3].minor.yy0);}
2645 #line 2670 "pikchr.c"
2646 break;
2647 case 41: /* attribute ::= THEN optrelexpr EDGEPT */
2648 case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43);
2649 #line 650 "pikchr.y"
2650 {pik_move_hdg(p,&yymsp[-1].minor.yy72,0,0,&yymsp[0].minor.yy0,&yymsp[-2].minor.yy0);}
2651 #line 2676 "pikchr.c"
2652 break;
2653 case 44: /* attribute ::= AT position */
2654 #line 655 "pikchr.y"
2655 { pik_set_at(p,0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2656 #line 2681 "pikchr.c"
2657 break;
2658 case 45: /* attribute ::= SAME */
2659 #line 657 "pikchr.y"
2660 {pik_same(p,0,&yymsp[0].minor.yy0);}
2661 #line 2686 "pikchr.c"
2662 break;
2663 case 46: /* attribute ::= SAME AS object */
2664 #line 658 "pikchr.y"
2665 {pik_same(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2666 #line 2691 "pikchr.c"
2667 break;
2668 case 47: /* attribute ::= STRING textposition */
2669 #line 659 "pikchr.y"
2670 {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy188);}
2671 #line 2696 "pikchr.c"
2672 break;
2673 case 48: /* attribute ::= FIT */
2674 #line 660 "pikchr.y"
2675 {pik_size_to_fit(p,&yymsp[0].minor.yy0,3); }
2676 #line 2701 "pikchr.c"
2677 break;
2678 case 49: /* attribute ::= BEHIND object */
2679 #line 661 "pikchr.y"
2680 {pik_behind(p,yymsp[0].minor.yy162);}
2681 #line 2706 "pikchr.c"
2682 break;
2683 case 50: /* withclause ::= DOT_E edge AT position */
2684 case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51);
2685 #line 669 "pikchr.y"
2686 { pik_set_at(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); }
2687 #line 2712 "pikchr.c"
2688 break;
2689 case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */
2690 #line 673 "pikchr.y"
2691 {yylhsminor.yy0 = yymsp[0].minor.yy0;}
2692 #line 2717 "pikchr.c"
2693 yymsp[0].minor.yy0 = yylhsminor.yy0;
2694 break;
2695 case 53: /* boolproperty ::= CW */
2696 #line 684 "pikchr.y"
2697 {p->cur->cw = 1;}
2698 #line 2723 "pikchr.c"
2699 break;
2700 case 54: /* boolproperty ::= CCW */
2701 #line 685 "pikchr.y"
2702 {p->cur->cw = 0;}
2703 #line 2728 "pikchr.c"
2704 break;
2705 case 55: /* boolproperty ::= LARROW */
2706 #line 686 "pikchr.y"
2707 {p->cur->larrow=1; p->cur->rarrow=0; }
2708 #line 2733 "pikchr.c"
2709 break;
2710 case 56: /* boolproperty ::= RARROW */
2711 #line 687 "pikchr.y"
2712 {p->cur->larrow=0; p->cur->rarrow=1; }
2713 #line 2738 "pikchr.c"
2714 break;
2715 case 57: /* boolproperty ::= LRARROW */
2716 #line 688 "pikchr.y"
2717 {p->cur->larrow=1; p->cur->rarrow=1; }
2718 #line 2743 "pikchr.c"
2719 break;
2720 case 58: /* boolproperty ::= INVIS */
2721 #line 689 "pikchr.y"
2722 {p->cur->sw = -0.00001;}
2723 #line 2748 "pikchr.c"
2724 break;
2725 case 59: /* boolproperty ::= THICK */
2726 #line 690 "pikchr.y"
2727 {p->cur->sw *= 1.5;}
2728 #line 2753 "pikchr.c"
2729 break;
2730 case 60: /* boolproperty ::= THIN */
2731 #line 691 "pikchr.y"
2732 {p->cur->sw *= 0.67;}
2733 #line 2758 "pikchr.c"
2734 break;
2735 case 61: /* boolproperty ::= SOLID */
2736 #line 692 "pikchr.y"
2737 {p->cur->sw = pik_value(p,"thickness",9,0);
2738 p->cur->dotted = p->cur->dashed = 0.0;}
2739 #line 2764 "pikchr.c"
2740 break;
2741 case 62: /* textposition ::= */
2742 #line 695 "pikchr.y"
2743 {yymsp[1].minor.yy188 = 0;}
2744 #line 2769 "pikchr.c"
2745 break;
2746 case 63: /* textposition ::= textposition CENTER|LJUST|RJUST|ABOVE|BELOW|ITALIC|BOLD|MONO|ALIGNED|BIG|SMALL */
2747 #line 698 "pikchr.y"
2748 {yylhsminor.yy188 = (short int)pik_text_position(yymsp[-1].minor.yy188,&yymsp[0].minor.yy0);}
2749 #line 2774 "pikchr.c"
2750 yymsp[-1].minor.yy188 = yylhsminor.yy188;
2751 break;
2752 case 64: /* position ::= expr COMMA expr */
2753 #line 701 "pikchr.y"
2754 {yylhsminor.yy63.x=yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[0].minor.yy21;}
2755 #line 2780 "pikchr.c"
2756 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2757 break;
2758 case 65: /* position ::= place PLUS expr COMMA expr */
2759 #line 703 "pikchr.y"
2760 {yylhsminor.yy63.x=yymsp[-4].minor.yy63.x+yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[-4].minor.yy63.y+yymsp[0].minor.yy21;}
2761 #line 2786 "pikchr.c"
2762 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2763 break;
2764 case 66: /* position ::= place MINUS expr COMMA expr */
2765 #line 704 "pikchr.y"
2766 {yylhsminor.yy63.x=yymsp[-4].minor.yy63.x-yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[-4].minor.yy63.y-yymsp[0].minor.yy21;}
2767 #line 2792 "pikchr.c"
2768 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2769 break;
2770 case 67: /* position ::= place PLUS LP expr COMMA expr RP */
2771 #line 706 "pikchr.y"
2772 {yylhsminor.yy63.x=yymsp[-6].minor.yy63.x+yymsp[-3].minor.yy21; yylhsminor.yy63.y=yymsp[-6].minor.yy63.y+yymsp[-1].minor.yy21;}
2773 #line 2798 "pikchr.c"
2774 yymsp[-6].minor.yy63 = yylhsminor.yy63;
2775 break;
2776 case 68: /* position ::= place MINUS LP expr COMMA expr RP */
2777 #line 708 "pikchr.y"
2778 {yylhsminor.yy63.x=yymsp[-6].minor.yy63.x-yymsp[-3].minor.yy21; yylhsminor.yy63.y=yymsp[-6].minor.yy63.y-yymsp[-1].minor.yy21;}
2779 #line 2804 "pikchr.c"
2780 yymsp[-6].minor.yy63 = yylhsminor.yy63;
2781 break;
2782 case 69: /* position ::= LP position COMMA position RP */
2783 #line 709 "pikchr.y"
2784 {yymsp[-4].minor.yy63.x=yymsp[-3].minor.yy63.x; yymsp[-4].minor.yy63.y=yymsp[-1].minor.yy63.y;}
2785 #line 2810 "pikchr.c"
2786 break;
2787 case 70: /* position ::= LP position RP */
2788 #line 710 "pikchr.y"
2789 {yymsp[-2].minor.yy63=yymsp[-1].minor.yy63;}
2790 #line 2815 "pikchr.c"
2791 break;
2792 case 71: /* position ::= expr between position AND position */
2793 #line 712 "pikchr.y"
2794 {yylhsminor.yy63 = pik_position_between(yymsp[-4].minor.yy21,yymsp[-2].minor.yy63,yymsp[0].minor.yy63);}
2795 #line 2820 "pikchr.c"
2796 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2797 break;
2798 case 72: /* position ::= expr LT position COMMA position GT */
2799 #line 714 "pikchr.y"
2800 {yylhsminor.yy63 = pik_position_between(yymsp[-5].minor.yy21,yymsp[-3].minor.yy63,yymsp[-1].minor.yy63);}
2801 #line 2826 "pikchr.c"
2802 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2803 break;
2804 case 73: /* position ::= expr ABOVE position */
2805 #line 715 "pikchr.y"
2806 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y += yymsp[-2].minor.yy21;}
2807 #line 2832 "pikchr.c"
2808 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2809 break;
2810 case 74: /* position ::= expr BELOW position */
2811 #line 716 "pikchr.y"
2812 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y -= yymsp[-2].minor.yy21;}
2813 #line 2838 "pikchr.c"
2814 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2815 break;
2816 case 75: /* position ::= expr LEFT OF position */
2817 #line 717 "pikchr.y"
2818 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x -= yymsp[-3].minor.yy21;}
2819 #line 2844 "pikchr.c"
2820 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2821 break;
2822 case 76: /* position ::= expr RIGHT OF position */
2823 #line 718 "pikchr.y"
2824 {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x += yymsp[-3].minor.yy21;}
2825 #line 2850 "pikchr.c"
2826 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2827 break;
2828 case 77: /* position ::= expr ON HEADING EDGEPT OF position */
2829 #line 720 "pikchr.y"
2830 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-5].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2831 #line 2856 "pikchr.c"
2832 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2833 break;
2834 case 78: /* position ::= expr HEADING EDGEPT OF position */
2835 #line 722 "pikchr.y"
2836 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-4].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2837 #line 2862 "pikchr.c"
2838 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2839 break;
2840 case 79: /* position ::= expr EDGEPT OF position */
2841 #line 724 "pikchr.y"
2842 {yylhsminor.yy63 = pik_position_at_hdg(yymsp[-3].minor.yy21,&yymsp[-2].minor.yy0,yymsp[0].minor.yy63);}
2843 #line 2868 "pikchr.c"
2844 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2845 break;
2846 case 80: /* position ::= expr ON HEADING expr FROM position */
2847 #line 726 "pikchr.y"
2848 {yylhsminor.yy63 = pik_position_at_angle(yymsp[-5].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2849 #line 2874 "pikchr.c"
2850 yymsp[-5].minor.yy63 = yylhsminor.yy63;
2851 break;
2852 case 81: /* position ::= expr HEADING expr FROM position */
2853 #line 728 "pikchr.y"
2854 {yylhsminor.yy63 = pik_position_at_angle(yymsp[-4].minor.yy21,yymsp[-2].minor.yy21,yymsp[0].minor.yy63);}
2855 #line 2880 "pikchr.c"
2856 yymsp[-4].minor.yy63 = yylhsminor.yy63;
2857 break;
2858 case 82: /* place ::= edge OF object */
2859 #line 740 "pikchr.y"
2860 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2861 #line 2886 "pikchr.c"
2862 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2863 break;
2864 case 83: /* place2 ::= object */
2865 #line 741 "pikchr.y"
2866 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,0);}
2867 #line 2892 "pikchr.c"
2868 yymsp[0].minor.yy63 = yylhsminor.yy63;
2869 break;
2870 case 84: /* place2 ::= object DOT_E edge */
2871 #line 742 "pikchr.y"
2872 {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2873 #line 2898 "pikchr.c"
2874 yymsp[-2].minor.yy63 = yylhsminor.yy63;
2875 break;
2876 case 85: /* place2 ::= NTH VERTEX OF object */
2877 #line 743 "pikchr.y"
2878 {yylhsminor.yy63 = pik_nth_vertex(p,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,yymsp[0].minor.yy162);}
2879 #line 2904 "pikchr.c"
2880 yymsp[-3].minor.yy63 = yylhsminor.yy63;
2881 break;
2882 case 86: /* object ::= nth */
2883 #line 755 "pikchr.y"
2884 {yylhsminor.yy162 = pik_find_nth(p,0,&yymsp[0].minor.yy0);}
2885 #line 2910 "pikchr.c"
2886 yymsp[0].minor.yy162 = yylhsminor.yy162;
2887 break;
2888 case 87: /* object ::= nth OF|IN object */
2889 #line 756 "pikchr.y"
2890 {yylhsminor.yy162 = pik_find_nth(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);}
2891 #line 2916 "pikchr.c"
2892 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2893 break;
2894 case 88: /* objectname ::= THIS */
2895 #line 758 "pikchr.y"
2896 {yymsp[0].minor.yy162 = p->cur;}
2897 #line 2922 "pikchr.c"
2898 break;
2899 case 89: /* objectname ::= PLACENAME */
2900 #line 759 "pikchr.y"
2901 {yylhsminor.yy162 = pik_find_byname(p,0,&yymsp[0].minor.yy0);}
2902 #line 2927 "pikchr.c"
2903 yymsp[0].minor.yy162 = yylhsminor.yy162;
2904 break;
2905 case 90: /* objectname ::= objectname DOT_U PLACENAME */
2906 #line 761 "pikchr.y"
2907 {yylhsminor.yy162 = pik_find_byname(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
2908 #line 2933 "pikchr.c"
2909 yymsp[-2].minor.yy162 = yylhsminor.yy162;
2910 break;
2911 case 91: /* nth ::= NTH CLASSNAME */
2912 #line 763 "pikchr.y"
2913 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-1].minor.yy0); }
2914 #line 2939 "pikchr.c"
2915 yymsp[-1].minor.yy0 = yylhsminor.yy0;
2916 break;
2917 case 92: /* nth ::= NTH LAST CLASSNAME */
2918 #line 764 "pikchr.y"
2919 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-2].minor.yy0); }
2920 #line 2945 "pikchr.c"
2921 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2922 break;
2923 case 93: /* nth ::= LAST CLASSNAME */
2924 #line 765 "pikchr.y"
2925 {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;}
2926 #line 2951 "pikchr.c"
2927 break;
2928 case 94: /* nth ::= LAST */
2929 #line 766 "pikchr.y"
2930 {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;}
2931 #line 2956 "pikchr.c"
2932 yymsp[0].minor.yy0 = yylhsminor.yy0;
2933 break;
2934 case 95: /* nth ::= NTH LB RB */
2935 #line 767 "pikchr.y"
2936 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = pik_nth_value(p,&yymsp[-2].minor.yy0);}
2937 #line 2962 "pikchr.c"
2938 yymsp[-2].minor.yy0 = yylhsminor.yy0;
2939 break;
2940 case 96: /* nth ::= NTH LAST LB RB */
2941 #line 768 "pikchr.y"
2942 {yylhsminor.yy0=yymsp[-1].minor.yy0; yylhsminor.yy0.eCode = -pik_nth_value(p,&yymsp[-3].minor.yy0);}
2943 #line 2968 "pikchr.c"
2944 yymsp[-3].minor.yy0 = yylhsminor.yy0;
2945 break;
2946 case 97: /* nth ::= LAST LB RB */
2947 #line 769 "pikchr.y"
2948 {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; }
2949 #line 2974 "pikchr.c"
2950 break;
2951 case 98: /* expr ::= expr PLUS expr */
2952 #line 771 "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 99: /* expr ::= expr MINUS expr */
2958 #line 772 "pikchr.y"
2959 {yylhsminor.yy21=yymsp[-2].minor.yy21-yymsp[0].minor.yy21;}
2960 #line 2985 "pikchr.c"
2961 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2962 break;
2963 case 100: /* expr ::= expr STAR expr */
2964 #line 773 "pikchr.y"
2965 {yylhsminor.yy21=yymsp[-2].minor.yy21*yymsp[0].minor.yy21;}
2966 #line 2991 "pikchr.c"
2967 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2968 break;
2969 case 101: /* expr ::= expr SLASH expr */
2970 #line 774 "pikchr.y"
2971 {
2972 if( yymsp[0].minor.yy21==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy21 = 0.0; }
2973 else{ yylhsminor.yy21 = yymsp[-2].minor.yy21/yymsp[0].minor.yy21; }
2974 }
2975 #line 3000 "pikchr.c"
2976 yymsp[-2].minor.yy21 = yylhsminor.yy21;
2977 break;
2978 case 102: /* expr ::= MINUS expr */
2979 #line 778 "pikchr.y"
2980 {yymsp[-1].minor.yy21=-yymsp[0].minor.yy21;}
2981 #line 3006 "pikchr.c"
2982 break;
2983 case 103: /* expr ::= PLUS expr */
2984 #line 779 "pikchr.y"
2985 {yymsp[-1].minor.yy21=yymsp[0].minor.yy21;}
2986 #line 3011 "pikchr.c"
2987 break;
2988 case 104: /* expr ::= LP expr RP */
2989 #line 780 "pikchr.y"
2990 {yymsp[-2].minor.yy21=yymsp[-1].minor.yy21;}
2991 #line 3016 "pikchr.c"
2992 break;
2993 case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */
2994 #line 781 "pikchr.y"
2995 {yymsp[-2].minor.yy21=pik_get_var(p,&yymsp[-1].minor.yy0);}
2996 #line 3021 "pikchr.c"
2997 break;
2998 case 106: /* expr ::= NUMBER */
2999 #line 782 "pikchr.y"
3000 {yylhsminor.yy21=pik_atof(&yymsp[0].minor.yy0);}
3001 #line 3026 "pikchr.c"
3002 yymsp[0].minor.yy21 = yylhsminor.yy21;
3003 break;
3004 case 107: /* expr ::= ID */
3005 #line 783 "pikchr.y"
3006 {yylhsminor.yy21=pik_get_var(p,&yymsp[0].minor.yy0);}
3007 #line 3032 "pikchr.c"
3008 yymsp[0].minor.yy21 = yylhsminor.yy21;
3009 break;
3010 case 108: /* expr ::= FUNC1 LP expr RP */
3011 #line 784 "pikchr.y"
3012 {yylhsminor.yy21 = pik_func(p,&yymsp[-3].minor.yy0,yymsp[-1].minor.yy21,0.0);}
3013 #line 3038 "pikchr.c"
3014 yymsp[-3].minor.yy21 = yylhsminor.yy21;
3015 break;
3016 case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */
3017 #line 785 "pikchr.y"
3018 {yylhsminor.yy21 = pik_func(p,&yymsp[-5].minor.yy0,yymsp[-3].minor.yy21,yymsp[-1].minor.yy21);}
3019 #line 3044 "pikchr.c"
3020 yymsp[-5].minor.yy21 = yylhsminor.yy21;
3021 break;
3022 case 110: /* expr ::= DIST LP position COMMA position RP */
3023 #line 786 "pikchr.y"
3024 {yymsp[-5].minor.yy21 = pik_dist(&yymsp[-3].minor.yy63,&yymsp[-1].minor.yy63);}
3025 #line 3050 "pikchr.c"
3026 break;
3027 case 111: /* expr ::= place2 DOT_XY X */
3028 #line 787 "pikchr.y"
3029 {yylhsminor.yy21 = yymsp[-2].minor.yy63.x;}
3030 #line 3055 "pikchr.c"
3031 yymsp[-2].minor.yy21 = yylhsminor.yy21;
3032 break;
3033 case 112: /* expr ::= place2 DOT_XY Y */
3034 #line 788 "pikchr.y"
3035 {yylhsminor.yy21 = yymsp[-2].minor.yy63.y;}
3036 #line 3061 "pikchr.c"
3037 yymsp[-2].minor.yy21 = yylhsminor.yy21;
3038 break;
3039 case 113: /* expr ::= object DOT_L numproperty */
3040 case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114);
3041 case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115);
3042 #line 789 "pikchr.y"
3043 {yylhsminor.yy21=pik_property_of(yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);}
3044 #line 3069 "pikchr.c"
3045 yymsp[-2].minor.yy21 = yylhsminor.yy21;
3046 break;
3047 default:
3048 /* (116) lvalue ::= ID */ yytestcase(yyruleno==116);
3049 /* (117) lvalue ::= FILL */ yytestcase(yyruleno==117);
@@ -3130,19 +3142,19 @@
3142 ){
3143 pik_parserARG_FETCH
3144 pik_parserCTX_FETCH
3145 #define TOKEN yyminor
3146 /************ Begin %syntax_error code ****************************************/
3147 #line 549 "pikchr.y"
3148
3149 if( TOKEN.z && TOKEN.z[0] ){
3150 pik_error(p, &TOKEN, "syntax error");
3151 }else{
3152 pik_error(p, 0, "syntax error");
3153 }
3154 UNUSED_PARAMETER(yymajor);
3155 #line 3180 "pikchr.c"
3156 /************ End %syntax_error code ******************************************/
3157 pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */
3158 pik_parserCTX_STORE
3159 }
3160
@@ -3407,11 +3419,11 @@
3419 #else
3420 (void)iToken;
3421 return 0;
3422 #endif
3423 }
3424 #line 794 "pikchr.y"
3425
3426
3427
3428 /* Chart of the 148 official CSS color names with their
3429 ** corresponding RGB values thru Color Module Level 4:
@@ -6495,13 +6507,13 @@
6507 unsigned int i;
6508 mid = (first+last)/2;
6509 zClr = aColor[mid].zName;
6510 for(i=0; i<pId->n; i++){
6511 c1 = zClr[i]&0x7f;
6512 if( IsUpper(c1) ) c1 = ToLower(c1);
6513 c2 = pId->z[i]&0x7f;
6514 if( IsUpper(c2) ) c2 = ToLower(c2);
6515 c = c2 - c1;
6516 if( c ) break;
6517 }
6518 if( c==0 && aColor[mid].zName[pId->n] ) c = -1;
6519 if( c==0 ) return (double)aColor[mid].val;
@@ -7605,11 +7617,11 @@
7617 }
7618 default: {
7619 c = z[0];
7620 if( c=='.' ){
7621 unsigned char c1 = z[1];
7622 if( IsLower(c1) ){
7623 const PikWord *pFound;
7624 for(i=2; (c = z[i])>='a' && c<='z'; i++){}
7625 pFound = pik_find_word((const char*)z+1, i-1,
7626 pik_keywords, count(pik_keywords));
7627 if( pFound && (pFound->eEdge>0 ||
@@ -7625,15 +7637,15 @@
7637 }else{
7638 /* Any other "dot" */
7639 pToken->eType = T_DOT_L;
7640 }
7641 return 1;
7642 }else if( IsDigit(c1) ){
7643 i = 0;
7644 /* no-op. Fall through to number handling */
7645 }else if( IsUpper(c1) ){
7646 for(i=2; (c = z[i])!=0 && (IsAlnum(c) || c=='_'); i++){}
7647 pToken->eType = T_DOT_U;
7648 return 1;
7649 }else{
7650 pToken->eType = T_ERROR;
7651 return 1;
@@ -7644,11 +7656,11 @@
7656 int isInt = 1;
7657 if( c!='.' ){
7658 nDigit = 1;
7659 for(i=1; (c = z[i])>='0' && c<='9'; i++){ nDigit++; }
7660 if( i==1 && (c=='x' || c=='X') ){
7661 for(i=2; (c = z[i])!=0 && IsXDigit(c); i++){}
7662 pToken->eType = T_NUMBER;
7663 return i;
7664 }
7665 }else{
7666 isInt = 0;
@@ -7700,13 +7712,13 @@
7712 ){
7713 i += 2;
7714 }
7715 pToken->eType = T_NUMBER;
7716 return i;
7717 }else if( IsLower(c) ){
7718 const PikWord *pFound;
7719 for(i=1; (c = z[i])!=0 && (IsAlnum(c) || c=='_'); i++){}
7720 pFound = pik_find_word((const char*)z, i,
7721 pik_keywords, count(pik_keywords));
7722 if( pFound ){
7723 pToken->eType = pFound->eType;
7724 pToken->eCode = pFound->eCode;
@@ -7719,19 +7731,19 @@
7731 }else{
7732 pToken->eType = T_ID;
7733 }
7734 return i;
7735 }else if( c>='A' && c<='Z' ){
7736 for(i=1; (c = z[i])!=0 && (IsAlnum(c) || c=='_'); i++){}
7737 pToken->eType = T_PLACENAME;
7738 return i;
7739 }else if( c=='$' && z[1]>='1' && z[1]<='9' && !IsDigit(z[2]) ){
7740 pToken->eType = T_PARAMETER;
7741 pToken->eCode = z[1] - '1';
7742 return 2;
7743 }else if( c=='_' || c=='$' || c=='@' ){
7744 for(i=1; (c = z[i])!=0 && (IsAlnum(c) || c=='_'); i++){}
7745 pToken->eType = T_ID;
7746 return i;
7747 }else{
7748 pToken->eType = T_ERROR;
7749 return 1;
@@ -7814,12 +7826,12 @@
7826 /* Remove leading and trailing whitespace from each argument.
7827 ** If what remains is one of $1, $2, ... $9 then transfer the
7828 ** corresponding argument from the outer context */
7829 for(j=0; j<=nArg; j++){
7830 PToken *t = &args[j];
7831 while( t->n>0 && IsSpace(t->z[0]) ){ t->n--; t->z++; }
7832 while( t->n>0 && IsSpace(t->z[t->n-1]) ){ t->n--; }
7833 if( t->n==2 && t->z[0]=='$' && t->z[1]>='1' && t->z[1]<='9' ){
7834 if( pOuter ) *t = pOuter[t->z[1]-'1'];
7835 else t->n = 0;
7836 }
7837 }
@@ -7896,11 +7908,11 @@
7908 pMac->inUse = 0;
7909 }else{
7910 #if 0
7911 printf("******** Token %s (%d): \"%.*s\" **************\n",
7912 yyTokenName[token.eType], token.eType,
7913 (int)(IsSpace(token.z[0]) ? 0 : sz), token.z);
7914 #endif
7915 token.n = (unsigned short)(sz & 0xffff);
7916 if( p->nToken++ > PIKCHR_TOKEN_LIMIT ){
7917 pik_error(p, &token, "script is too complex");
7918 break;
@@ -8242,6 +8254,6 @@
8254
8255
8256 #endif /* PIKCHR_TCL */
8257
8258
8259 #line 8284 "pikchr.c"
8260
+751 -617
--- extsrc/pikchr.js
+++ extsrc/pikchr.js
@@ -1,713 +1,847 @@
1
-
21
var initPikchrModule = (() => {
3
- var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
2
+ var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
43
54
return (
6
-function(config) {
7
- var initPikchrModule = config || {};
5
+async function(moduleArg = {}) {
6
+ var moduleRtn;
87
9
-var Module = typeof initPikchrModule != "undefined" ? initPikchrModule : {};
8
+// include: shell.js
9
+// The Module object: Our interface to the outside world. We import
10
+// and export values on it. There are various ways Module can be used:
11
+// 1. Not defined. We create it here
12
+// 2. A function parameter, function(moduleArg) => Promise<Module>
13
+// 3. pre-run appended it, var Module = {}; ..generated code..
14
+// 4. External script tag defines var Module.
15
+// We need to check if Module already exists (e.g. case 3 above).
16
+// Substitution will be replaced with actual code on later stage of the build,
17
+// this way Closure Compiler will not mangle it (e.g. case 4. above).
18
+// Note that if you want to run closure, and also to use Module
19
+// after the generated code, you will need to define var Module = {};
20
+// before the code. Then that object will be used in the code, and you
21
+// can continue to use Module afterwards as well.
22
+var Module = moduleArg;
1023
24
+// Set up the promise that indicates the Module is initialized
1125
var readyPromiseResolve, readyPromiseReject;
1226
13
-Module["ready"] = new Promise(function(resolve, reject) {
14
- readyPromiseResolve = resolve;
15
- readyPromiseReject = reject;
27
+var readyPromise = new Promise((resolve, reject) => {
28
+ readyPromiseResolve = resolve;
29
+ readyPromiseReject = reject;
1630
});
1731
32
+// Determine the runtime environment we are in. You can customize this by
33
+// setting the ENVIRONMENT setting at compile time (see settings.js).
34
+var ENVIRONMENT_IS_WEB = true;
35
+
36
+var ENVIRONMENT_IS_WORKER = false;
37
+
38
+// --pre-jses are emitted after the Module integration code, so that they can
39
+// refer to Module (if they choose; they can also define Module)
40
+// Sometimes an existing Module object exists with properties
41
+// meant to overwrite the default module functionality. Here
42
+// we collect those properties and reapply _after_ we configure
43
+// the current environment's defaults to avoid having to be so
44
+// defensive during initialization.
1845
var moduleOverrides = Object.assign({}, Module);
1946
2047
var arguments_ = [];
2148
2249
var thisProgram = "./this.program";
2350
2451
var quit_ = (status, toThrow) => {
25
- throw toThrow;
52
+ throw toThrow;
2653
};
2754
28
-var ENVIRONMENT_IS_WEB = true;
29
-
30
-var ENVIRONMENT_IS_WORKER = false;
31
-
55
+// `/` should be present at the end if `scriptDirectory` is not empty
3256
var scriptDirectory = "";
3357
3458
function locateFile(path) {
35
- if (Module["locateFile"]) {
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
- 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;
59
+ if (Module["locateFile"]) {
60
+ return Module["locateFile"](path, scriptDirectory);
61
+ }
62
+ return scriptDirectory + path;
63
+}
64
+
65
+// Hooks that are implemented differently in different runtime environments.
66
+var readAsync, readBinary;
67
+
68
+// Note that this includes Node.js workers when relevant (pthreads is enabled).
69
+// Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
70
+// ENVIRONMENT_IS_NODE.
71
+if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
72
+ if (ENVIRONMENT_IS_WORKER) {
73
+ // Check worker, not web, since window could be polyfilled
74
+ scriptDirectory = self.location.href;
75
+ } else if (typeof document != "undefined" && document.currentScript) {
76
+ // web
77
+ scriptDirectory = document.currentScript.src;
78
+ }
79
+ // When MODULARIZE, this JS may be executed later, after document.currentScript
80
+ // is gone, so we saved it, and we use it here instead of any other info.
81
+ if (_scriptName) {
82
+ scriptDirectory = _scriptName;
83
+ }
84
+ // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
85
+ // otherwise, slice off the final part of the url to find the script directory.
86
+ // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
87
+ // and scriptDirectory will correctly be replaced with an empty string.
88
+ // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
89
+ // they are removed because they could contain a slash.
90
+ if (scriptDirectory.startsWith("blob:")) {
91
+ scriptDirectory = "";
92
+ } else {
93
+ scriptDirectory = scriptDirectory.slice(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1);
94
+ }
95
+ {
96
+ // include: web_or_worker_shell_read.js
97
+ readAsync = async url => {
98
+ var response = await fetch(url, {
99
+ credentials: "same-origin"
100
+ });
101
+ if (response.ok) {
102
+ return response.arrayBuffer();
103
+ }
104
+ throw new Error(response.status + " : " + response.url);
105
+ };
106
+ }
89107
} else {}
90108
91109
var out = Module["print"] || console.log.bind(console);
92110
93
-var err = Module["printErr"] || console.warn.bind(console);
111
+var err = Module["printErr"] || console.error.bind(console);
94112
113
+// Merge back in the overrides
95114
Object.assign(Module, moduleOverrides);
96115
116
+// Free the object hierarchy contained in the overrides, this lets the GC
117
+// reclaim data used.
97118
moduleOverrides = null;
98119
120
+// Emit code to handle expected values on the Module object. This applies Module.x
121
+// to the proper local x. This has two benefits: first, we only emit it if it is
122
+// expected to arrive, and second, by using a local everywhere else that can be
123
+// minified.
99124
if (Module["arguments"]) arguments_ = Module["arguments"];
100125
101126
if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
102127
103
-if (Module["quit"]) quit_ = Module["quit"];
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
-
128
+// perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
129
+// end include: shell.js
130
+// include: preamble.js
131
+// === Preamble library stuff ===
132
+// Documentation for the public APIs defined in this file must be updated in:
133
+// site/source/docs/api_reference/preamble.js.rst
134
+// A prebuilt local version of the documentation is available at:
135
+// site/build/text/docs/api_reference/preamble.js.txt
136
+// You can also build docs locally as HTML or other formats in site/
137
+// An online HTML version (which may be of a different version of Emscripten)
138
+// is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
139
+var wasmBinary = Module["wasmBinary"];
140
+
141
+// Wasm globals
115142
var wasmMemory;
116143
144
+//========================================
145
+// Runtime essentials
146
+//========================================
147
+// whether we are quitting the application. no code should run after this.
148
+// set in exit() and abort()
117149
var ABORT = false;
118150
151
+// set by exit() and abort(). Passed to 'onExit' handler.
152
+// NOTE: This is also used as the process return code code in shell environments
153
+// but only when noExitRuntime is false.
119154
var EXITSTATUS;
120155
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__ = [];
156
+// Memory management
157
+var /** @type {!Int8Array} */ HEAP8, /** @type {!Uint8Array} */ HEAPU8, /** @type {!Int16Array} */ HEAP16, /** @type {!Uint16Array} */ HEAPU16, /** @type {!Int32Array} */ HEAP32, /** @type {!Uint32Array} */ HEAPU32, /** @type {!Float32Array} */ HEAPF32, /* BigInt64Array type is not correctly defined in closure
158
+/** not-@type {!BigInt64Array} */ HEAP64, /* BigUint64Array type is not correctly defined in closure
159
+/** not-t@type {!BigUint64Array} */ HEAPU64, /** @type {!Float64Array} */ HEAPF64;
223160
224161
var runtimeInitialized = false;
225162
226
-function keepRuntimeAlive() {
227
- return noExitRuntime;
163
+// include: runtime_shared.js
164
+// include: runtime_stack_check.js
165
+// end include: runtime_stack_check.js
166
+// include: runtime_exceptions.js
167
+// end include: runtime_exceptions.js
168
+// include: runtime_debug.js
169
+// end include: runtime_debug.js
170
+// include: memoryprofiler.js
171
+// end include: memoryprofiler.js
172
+function updateMemoryViews() {
173
+ var b = wasmMemory.buffer;
174
+ Module["HEAP8"] = HEAP8 = new Int8Array(b);
175
+ Module["HEAP16"] = HEAP16 = new Int16Array(b);
176
+ Module["HEAPU8"] = HEAPU8 = new Uint8Array(b);
177
+ Module["HEAPU16"] = HEAPU16 = new Uint16Array(b);
178
+ Module["HEAP32"] = HEAP32 = new Int32Array(b);
179
+ Module["HEAPU32"] = HEAPU32 = new Uint32Array(b);
180
+ Module["HEAPF32"] = HEAPF32 = new Float32Array(b);
181
+ Module["HEAPF64"] = HEAPF64 = new Float64Array(b);
182
+ Module["HEAP64"] = HEAP64 = new BigInt64Array(b);
183
+ Module["HEAPU64"] = HEAPU64 = new BigUint64Array(b);
228184
}
229185
186
+// end include: runtime_shared.js
230187
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());
188
+ if (Module["preRun"]) {
189
+ if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
190
+ while (Module["preRun"].length) {
191
+ addOnPreRun(Module["preRun"].shift());
192
+ }
235193
}
236
- }
237
- callRuntimeCallbacks(__ATPRERUN__);
194
+ callRuntimeCallbacks(onPreRuns);
238195
}
239196
240197
function initRuntime() {
241
- runtimeInitialized = true;
242
- callRuntimeCallbacks(__ATINIT__);
198
+ runtimeInitialized = true;
199
+ wasmExports["e"]();
243200
}
244201
245202
function postRun() {
246
- if (Module["postRun"]) {
247
- if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ];
248
- while (Module["postRun"].length) {
249
- addOnPostRun(Module["postRun"].shift());
250
- }
251
- }
252
- callRuntimeCallbacks(__ATPOSTRUN__);
253
-}
254
-
255
-function addOnPreRun(cb) {
256
- __ATPRERUN__.unshift(cb);
257
-}
258
-
259
-function addOnInit(cb) {
260
- __ATINIT__.unshift(cb);
261
-}
262
-
263
-function addOnPostRun(cb) {
264
- __ATPOSTRUN__.unshift(cb);
265
-}
266
-
267
-var runDependencies = 0;
268
-
269
-var runDependencyWatcher = null;
203
+ if (Module["postRun"]) {
204
+ if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ];
205
+ while (Module["postRun"].length) {
206
+ addOnPostRun(Module["postRun"].shift());
207
+ }
208
+ }
209
+ callRuntimeCallbacks(onPostRuns);
210
+}
211
+
212
+// A counter of dependencies for calling run(). If we need to
213
+// do asynchronous work before running, increment this and
214
+// decrement it. Incrementing must happen in a place like
215
+// Module.preRun (used by emcc to add file preloading).
216
+// Note that you can add dependencies in preRun, even though
217
+// it happens right before run - run will be postponed until
218
+// the dependencies are met.
219
+var runDependencies = 0;
270220
271221
var dependenciesFulfilled = null;
272222
273223
function addRunDependency(id) {
274
- runDependencies++;
275
- if (Module["monitorRunDependencies"]) {
276
- Module["monitorRunDependencies"](runDependencies);
277
- }
224
+ runDependencies++;
225
+ Module["monitorRunDependencies"]?.(runDependencies);
278226
}
279227
280228
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
- }
290
- if (dependenciesFulfilled) {
291
- var callback = dependenciesFulfilled;
292
- dependenciesFulfilled = null;
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);
229
+ runDependencies--;
230
+ Module["monitorRunDependencies"]?.(runDependencies);
231
+ if (runDependencies == 0) {
232
+ if (dependenciesFulfilled) {
233
+ var callback = dependenciesFulfilled;
234
+ dependenciesFulfilled = null;
235
+ callback();
236
+ }
237
+ }
238
+}
239
+
240
+/** @param {string|number=} what */ function abort(what) {
241
+ Module["onAbort"]?.(what);
242
+ what = "Aborted(" + what + ")";
243
+ // TODO(sbc): Should we remove printing and leave it up to whoever
244
+ // catches the exception?
245
+ err(what);
246
+ ABORT = true;
247
+ what += ". Build with -sASSERTIONS for more info.";
248
+ // Use a wasm runtime error, because a JS error might be seen as a foreign
249
+ // exception, which means we'd run destructors on it. We need the error to
250
+ // simply make the program stop.
251
+ // FIXME This approach does not work in Wasm EH because it currently does not assume
252
+ // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
253
+ // a trap or not based on a hidden field within the object. So at the moment
254
+ // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
255
+ // allows this in the wasm spec.
256
+ // Suppress closure compiler warning here. Closure compiler's builtin extern
257
+ // definition for WebAssembly.RuntimeError claims it takes no arguments even
258
+ // though it can.
259
+ // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
260
+ /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what);
261
+ readyPromiseReject(e);
262
+ // Throw the error whether or not MODULARIZE is set because abort is used
263
+ // in code paths apart from instantiation where an exception is expected
264
+ // to be thrown when abort is called.
265
+ throw e;
316266
}
317267
318268
var wasmBinaryFile;
319269
320
-wasmBinaryFile = "pikchr.wasm";
321
-
322
-if (!isDataURI(wasmBinaryFile)) {
323
- wasmBinaryFile = locateFile(wasmBinaryFile);
270
+function findWasmBinary() {
271
+ return locateFile("pikchr.wasm");
324272
}
325273
326
-function getBinary(file) {
327
- try {
274
+function getBinarySync(file) {
328275
if (file == wasmBinaryFile && wasmBinary) {
329
- return new Uint8Array(wasmBinary);
276
+ return new Uint8Array(wasmBinary);
330277
}
331278
if (readBinary) {
332
- return readBinary(file);
279
+ return readBinary(file);
333280
}
334281
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
-}
282
+}
283
+
284
+async function getWasmBinary(binaryFile) {
285
+ // If we don't have the binary yet, load it asynchronously using readAsync.
286
+ if (!wasmBinary) {
287
+ // Fetch the binary using readAsync
288
+ try {
289
+ var response = await readAsync(binaryFile);
290
+ return new Uint8Array(response);
291
+ } catch {}
292
+ }
293
+ // Otherwise, getBinarySync should be able to get it synchronously
294
+ return getBinarySync(binaryFile);
295
+}
296
+
297
+async function instantiateArrayBuffer(binaryFile, imports) {
298
+ try {
299
+ var binary = await getWasmBinary(binaryFile);
300
+ var instance = await WebAssembly.instantiate(binary, imports);
301
+ return instance;
302
+ } catch (reason) {
303
+ err(`failed to asynchronously prepare wasm: ${reason}`);
304
+ abort(reason);
305
+ }
306
+}
307
+
308
+async function instantiateAsync(binary, binaryFile, imports) {
309
+ if (!binary && typeof WebAssembly.instantiateStreaming == "function") {
310
+ try {
311
+ var response = fetch(binaryFile, {
312
+ credentials: "same-origin"
313
+ });
314
+ var instantiationResult = await WebAssembly.instantiateStreaming(response, imports);
315
+ return instantiationResult;
316
+ } catch (reason) {
317
+ // We expect the most common failure cause to be a bad MIME type for the binary,
318
+ // in which case falling back to ArrayBuffer instantiation should work.
319
+ err(`wasm streaming compile failed: ${reason}`);
320
+ err("falling back to ArrayBuffer instantiation");
321
+ }
322
+ }
323
+ return instantiateArrayBuffer(binaryFile, imports);
324
+}
325
+
326
+function getWasmImports() {
327
+ // prepare imports
328
+ return {
329
+ "a": wasmImports
330
+ };
331
+}
332
+
333
+// Create the wasm instance.
334
+// Receives the wasm imports, returns the exports.
335
+async function createWasm() {
336
+ // Load the wasm module and create an instance of using native support in the JS engine.
337
+ // handle a generated wasm instance, receiving its exports and
338
+ // performing other necessary setup
339
+ /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) {
340
+ wasmExports = instance.exports;
341
+ wasmMemory = wasmExports["d"];
342
+ updateMemoryViews();
343
+ removeRunDependency("wasm-instantiate");
344
+ return wasmExports;
345
+ }
346
+ // wait for the pthread pool (if any)
347
+ addRunDependency("wasm-instantiate");
348
+ // Prefer streaming instantiation if available.
349
+ function receiveInstantiationResult(result) {
350
+ // 'result' is a ResultObject object which has both the module and instance.
351
+ // receiveInstance() will swap in the exports (to Module.asm) so they can be called
352
+ // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
353
+ // When the regression is fixed, can restore the above PTHREADS-enabled path.
354
+ return receiveInstance(result["instance"]);
355
+ }
356
+ var info = getWasmImports();
357
+ // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
358
+ // to manually instantiate the Wasm module themselves. This allows pages to
359
+ // run the instantiation parallel to any other async startup actions they are
360
+ // performing.
361
+ // Also pthreads and wasm workers initialize the wasm instance through this
362
+ // path.
363
+ if (Module["instantiateWasm"]) {
364
+ return new Promise((resolve, reject) => {
365
+ Module["instantiateWasm"](info, (mod, inst) => {
366
+ receiveInstance(mod, inst);
367
+ resolve(mod.exports);
368
+ });
369
+ });
370
+ }
371
+ wasmBinaryFile ??= findWasmBinary();
372
+ try {
373
+ var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
374
+ var exports = receiveInstantiationResult(result);
375
+ return exports;
376
+ } catch (e) {
377
+ // If instantiation fails, reject the module ready promise.
378
+ readyPromiseReject(e);
379
+ return Promise.reject(e);
380
+ }
381
+}
382
+
383
+// === Body ===
384
+// end include: preamble.js
385
+class ExitStatus {
386
+ name="ExitStatus";
387
+ constructor(status) {
388
+ this.message = `Program terminated with exit(${status})`;
389
+ this.status = status;
390
+ }
391
+}
392
+
393
+var callRuntimeCallbacks = callbacks => {
394
+ while (callbacks.length > 0) {
395
+ // Pass the module as the first argument.
396
+ callbacks.shift()(Module);
397
+ }
398
+};
399
+
400
+var onPostRuns = [];
401
+
402
+var addOnPostRun = cb => onPostRuns.unshift(cb);
403
+
404
+var onPreRuns = [];
405
+
406
+var addOnPreRun = cb => onPreRuns.unshift(cb);
407
+
408
+/**
409
+ * @param {number} ptr
410
+ * @param {string} type
411
+ */ function getValue(ptr, type = "i8") {
412
+ if (type.endsWith("*")) type = "*";
413
+ switch (type) {
414
+ case "i1":
415
+ return HEAP8[ptr];
416
+
417
+ case "i8":
418
+ return HEAP8[ptr];
419
+
420
+ case "i16":
421
+ return HEAP16[((ptr) >> 1)];
422
+
423
+ case "i32":
424
+ return HEAP32[((ptr) >> 2)];
425
+
426
+ case "i64":
427
+ return HEAP64[((ptr) >> 3)];
428
+
429
+ case "float":
430
+ return HEAPF32[((ptr) >> 2)];
431
+
432
+ case "double":
433
+ return HEAPF64[((ptr) >> 3)];
434
+
435
+ case "*":
436
+ return HEAPU32[((ptr) >> 2)];
437
+
438
+ default:
439
+ abort(`invalid type for getValue: ${type}`);
440
+ }
441
+}
442
+
443
+var noExitRuntime = Module["noExitRuntime"] || true;
444
+
445
+/**
446
+ * @param {number} ptr
447
+ * @param {number} value
448
+ * @param {string} type
449
+ */ function setValue(ptr, value, type = "i8") {
450
+ if (type.endsWith("*")) type = "*";
451
+ switch (type) {
452
+ case "i1":
453
+ HEAP8[ptr] = value;
454
+ break;
455
+
456
+ case "i8":
457
+ HEAP8[ptr] = value;
458
+ break;
459
+
460
+ case "i16":
461
+ HEAP16[((ptr) >> 1)] = value;
462
+ break;
463
+
464
+ case "i32":
465
+ HEAP32[((ptr) >> 2)] = value;
466
+ break;
467
+
468
+ case "i64":
469
+ HEAP64[((ptr) >> 3)] = BigInt(value);
470
+ break;
471
+
472
+ case "float":
473
+ HEAPF32[((ptr) >> 2)] = value;
474
+ break;
475
+
476
+ case "double":
477
+ HEAPF64[((ptr) >> 3)] = value;
478
+ break;
479
+
480
+ case "*":
481
+ HEAPU32[((ptr) >> 2)] = value;
482
+ break;
483
+
484
+ default:
485
+ abort(`invalid type for setValue: ${type}`);
486
+ }
487
+}
488
+
489
+var stackRestore = val => __emscripten_stack_restore(val);
490
+
491
+var stackSave = () => _emscripten_stack_get_current();
492
+
493
+var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder : undefined;
494
+
495
+/**
496
+ * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
497
+ * array that contains uint8 values, returns a copy of that string as a
498
+ * Javascript String object.
499
+ * heapOrArray is either a regular array, or a JavaScript typed array view.
500
+ * @param {number=} idx
501
+ * @param {number=} maxBytesToRead
502
+ * @return {string}
503
+ */ var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => {
504
+ var endIdx = idx + maxBytesToRead;
505
+ var endPtr = idx;
506
+ // TextDecoder needs to know the byte length in advance, it doesn't stop on
507
+ // null terminator by itself. Also, use the length info to avoid running tiny
508
+ // strings through TextDecoder, since .subarray() allocates garbage.
509
+ // (As a tiny code save trick, compare endPtr against endIdx using a negation,
510
+ // so that undefined/NaN means Infinity)
511
+ while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
512
+ if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
513
+ return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
514
+ }
515
+ var str = "";
516
+ // If building with TextDecoder, we have already computed the string length
517
+ // above, so test loop end condition against that
518
+ while (idx < endPtr) {
519
+ // For UTF8 byte structure, see:
520
+ // http://en.wikipedia.org/wiki/UTF-8#Description
521
+ // https://www.ietf.org/rfc/rfc2279.txt
522
+ // https://tools.ietf.org/html/rfc3629
523
+ var u0 = heapOrArray[idx++];
524
+ if (!(u0 & 128)) {
525
+ str += String.fromCharCode(u0);
526
+ continue;
527
+ }
528
+ var u1 = heapOrArray[idx++] & 63;
529
+ if ((u0 & 224) == 192) {
530
+ str += String.fromCharCode(((u0 & 31) << 6) | u1);
531
+ continue;
532
+ }
533
+ var u2 = heapOrArray[idx++] & 63;
534
+ if ((u0 & 240) == 224) {
535
+ u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
536
+ } else {
537
+ u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
538
+ }
539
+ if (u0 < 65536) {
540
+ str += String.fromCharCode(u0);
541
+ } else {
542
+ var ch = u0 - 65536;
543
+ str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
544
+ }
545
+ }
546
+ return str;
547
+};
548
+
549
+/**
550
+ * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
551
+ * emscripten HEAP, returns a copy of that string as a Javascript String object.
552
+ *
553
+ * @param {number} ptr
554
+ * @param {number=} maxBytesToRead - An optional length that specifies the
555
+ * maximum number of bytes to read. You can omit this parameter to scan the
556
+ * string until the first 0 byte. If maxBytesToRead is passed, and the string
557
+ * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
558
+ * string will cut short at that byte index (i.e. maxBytesToRead will not
559
+ * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
560
+ * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
561
+ * JS JIT optimizations off, so it is worth to consider consistently using one
562
+ * @return {string}
563
+ */ var UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
564
+
565
+var ___assert_fail = (condition, filename, line, func) => abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
566
+
567
+var abortOnCannotGrowMemory = requestedSize => {
568
+ abort("OOM");
569
+};
570
+
571
+var _emscripten_resize_heap = requestedSize => {
572
+ var oldSize = HEAPU8.length;
573
+ // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
574
+ requestedSize >>>= 0;
575
+ abortOnCannotGrowMemory(requestedSize);
576
+};
577
+
578
+var runtimeKeepaliveCounter = 0;
579
+
580
+var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
581
+
582
+var _proc_exit = code => {
583
+ EXITSTATUS = code;
584
+ if (!keepRuntimeAlive()) {
585
+ Module["onExit"]?.(code);
586
+ ABORT = true;
587
+ }
588
+ quit_(code, new ExitStatus(code));
589
+};
590
+
591
+/** @suppress {duplicate } */ /** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => {
592
+ EXITSTATUS = status;
593
+ _proc_exit(status);
594
+};
546595
547596
var _exit = exitJS;
548597
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);
571
- writeArrayToMemory(arr, ret);
572
- return ret;
573
- }
574
- };
575
- function convertReturnValue(ret) {
576
- if (returnType === "string") {
577
- return UTF8ToString(ret);
578
- }
579
- if (returnType === "boolean") return Boolean(ret);
580
- return ret;
581
- }
582
- var func = getCFunc(ident);
583
- var cArgs = [];
584
- var stack = 0;
585
- if (args) {
586
- for (var i = 0; i < args.length; i++) {
587
- var converter = toC[argTypes[i]];
588
- if (converter) {
589
- if (stack === 0) stack = stackSave();
590
- cArgs[i] = converter(args[i]);
591
- } else {
592
- cArgs[i] = args[i];
593
- }
594
- }
595
- }
596
- var ret = func.apply(null, cArgs);
597
- function onDone(ret) {
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
-
598
+var getCFunc = ident => {
599
+ var func = Module["_" + ident];
600
+ // closure exported function
601
+ return func;
602
+};
603
+
604
+var writeArrayToMemory = (array, buffer) => {
605
+ HEAP8.set(array, buffer);
606
+};
607
+
608
+var lengthBytesUTF8 = str => {
609
+ var len = 0;
610
+ for (var i = 0; i < str.length; ++i) {
611
+ // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
612
+ // unit, not a Unicode code point of the character! So decode
613
+ // UTF16->UTF32->UTF8.
614
+ // See http://unicode.org/faq/utf_bom.html#utf16-3
615
+ var c = str.charCodeAt(i);
616
+ // possibly a lead surrogate
617
+ if (c <= 127) {
618
+ len++;
619
+ } else if (c <= 2047) {
620
+ len += 2;
621
+ } else if (c >= 55296 && c <= 57343) {
622
+ len += 4;
623
+ ++i;
624
+ } else {
625
+ len += 3;
626
+ }
627
+ }
628
+ return len;
629
+};
630
+
631
+var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
632
+ // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
633
+ // undefined and false each don't write out any bytes.
634
+ if (!(maxBytesToWrite > 0)) return 0;
635
+ var startIdx = outIdx;
636
+ var endIdx = outIdx + maxBytesToWrite - 1;
637
+ // -1 for string null terminator.
638
+ for (var i = 0; i < str.length; ++i) {
639
+ // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
640
+ // unit, not a Unicode code point of the character! So decode
641
+ // UTF16->UTF32->UTF8.
642
+ // See http://unicode.org/faq/utf_bom.html#utf16-3
643
+ // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
644
+ // and https://www.ietf.org/rfc/rfc2279.txt
645
+ // and https://tools.ietf.org/html/rfc3629
646
+ var u = str.charCodeAt(i);
647
+ // possibly a lead surrogate
648
+ if (u >= 55296 && u <= 57343) {
649
+ var u1 = str.charCodeAt(++i);
650
+ u = 65536 + ((u & 1023) << 10) | (u1 & 1023);
651
+ }
652
+ if (u <= 127) {
653
+ if (outIdx >= endIdx) break;
654
+ heap[outIdx++] = u;
655
+ } else if (u <= 2047) {
656
+ if (outIdx + 1 >= endIdx) break;
657
+ heap[outIdx++] = 192 | (u >> 6);
658
+ heap[outIdx++] = 128 | (u & 63);
659
+ } else if (u <= 65535) {
660
+ if (outIdx + 2 >= endIdx) break;
661
+ heap[outIdx++] = 224 | (u >> 12);
662
+ heap[outIdx++] = 128 | ((u >> 6) & 63);
663
+ heap[outIdx++] = 128 | (u & 63);
664
+ } else {
665
+ if (outIdx + 3 >= endIdx) break;
666
+ heap[outIdx++] = 240 | (u >> 18);
667
+ heap[outIdx++] = 128 | ((u >> 12) & 63);
668
+ heap[outIdx++] = 128 | ((u >> 6) & 63);
669
+ heap[outIdx++] = 128 | (u & 63);
670
+ }
671
+ }
672
+ // Null-terminate the pointer to the buffer.
673
+ heap[outIdx] = 0;
674
+ return outIdx - startIdx;
675
+};
676
+
677
+var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
678
+
679
+var stackAlloc = sz => __emscripten_stack_alloc(sz);
680
+
681
+var stringToUTF8OnStack = str => {
682
+ var size = lengthBytesUTF8(str) + 1;
683
+ var ret = stackAlloc(size);
684
+ stringToUTF8(str, ret, size);
685
+ return ret;
686
+};
687
+
688
+/**
689
+ * @param {string|null=} returnType
690
+ * @param {Array=} argTypes
691
+ * @param {Arguments|Array=} args
692
+ * @param {Object=} opts
693
+ */ var ccall = (ident, returnType, argTypes, args, opts) => {
694
+ // For fast lookup of conversion functions
695
+ var toC = {
696
+ "string": str => {
697
+ var ret = 0;
698
+ if (str !== null && str !== undefined && str !== 0) {
699
+ // null string
700
+ ret = stringToUTF8OnStack(str);
701
+ }
702
+ return ret;
703
+ },
704
+ "array": arr => {
705
+ var ret = stackAlloc(arr.length);
706
+ writeArrayToMemory(arr, ret);
707
+ return ret;
708
+ }
709
+ };
710
+ function convertReturnValue(ret) {
711
+ if (returnType === "string") {
712
+ return UTF8ToString(ret);
713
+ }
714
+ if (returnType === "boolean") return Boolean(ret);
715
+ return ret;
716
+ }
717
+ var func = getCFunc(ident);
718
+ var cArgs = [];
719
+ var stack = 0;
720
+ if (args) {
721
+ for (var i = 0; i < args.length; i++) {
722
+ var converter = toC[argTypes[i]];
723
+ if (converter) {
724
+ if (stack === 0) stack = stackSave();
725
+ cArgs[i] = converter(args[i]);
726
+ } else {
727
+ cArgs[i] = args[i];
728
+ }
729
+ }
730
+ }
731
+ var ret = func(...cArgs);
732
+ function onDone(ret) {
733
+ if (stack !== 0) stackRestore(stack);
734
+ return convertReturnValue(ret);
735
+ }
736
+ ret = onDone(ret);
737
+ return ret;
738
+};
739
+
740
+/**
741
+ * @param {string=} returnType
742
+ * @param {Array=} argTypes
743
+ * @param {Object=} opts
744
+ */ var cwrap = (ident, returnType, argTypes, opts) => {
745
+ // When the function takes numbers and returns a number, we can just return
746
+ // the original function
747
+ var numericArgs = !argTypes || argTypes.every(type => type === "number" || type === "boolean");
748
+ var numericRet = returnType !== "string";
749
+ if (numericRet && numericArgs && !opts) {
750
+ return getCFunc(ident);
751
+ }
752
+ return (...args) => ccall(ident, returnType, argTypes, args, opts);
753
+};
754
+
755
+var wasmImports = {
756
+ /** @export */ a: ___assert_fail,
757
+ /** @export */ b: _emscripten_resize_heap,
758
+ /** @export */ c: _exit
759
+};
760
+
761
+var wasmExports = await createWasm();
762
+
763
+var ___wasm_call_ctors = wasmExports["e"];
764
+
765
+var _pikchr = Module["_pikchr"] = wasmExports["g"];
766
+
767
+var __emscripten_stack_restore = wasmExports["h"];
768
+
769
+var __emscripten_stack_alloc = wasmExports["i"];
770
+
771
+var _emscripten_stack_get_current = wasmExports["j"];
772
+
773
+// include: postamble.js
774
+// === Auto-generated postamble setup entry stuff ===
645775
Module["stackSave"] = stackSave;
646776
647777
Module["stackRestore"] = stackRestore;
778
+
779
+Module["stackAlloc"] = stackAlloc;
648780
649781
Module["cwrap"] = cwrap;
650782
651783
Module["setValue"] = setValue;
652784
653785
Module["getValue"] = getValue;
654786
655
-var calledRun;
656
-
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) {
669
- return;
670
- }
671
- function doRun() {
672
- if (calledRun) return;
673
- calledRun = true;
674
- Module["calledRun"] = true;
675
- if (ABORT) return;
676
- initRuntime();
677
- readyPromiseResolve(Module);
678
- if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"]();
679
- postRun();
680
- }
681
- if (Module["setStatus"]) {
682
- Module["setStatus"]("Running...");
683
- setTimeout(function() {
684
- setTimeout(function() {
685
- Module["setStatus"]("");
686
- }, 1);
687
- doRun();
688
- }, 1);
689
- } else {
690
- doRun();
691
- }
787
+function run() {
788
+ if (runDependencies > 0) {
789
+ dependenciesFulfilled = run;
790
+ return;
791
+ }
792
+ preRun();
793
+ // a preRun added a dependency, run will be called later
794
+ if (runDependencies > 0) {
795
+ dependenciesFulfilled = run;
796
+ return;
797
+ }
798
+ function doRun() {
799
+ // run may have just been called through dependencies being fulfilled just in this very frame,
800
+ // or while the async setStatus time below was happening
801
+ Module["calledRun"] = true;
802
+ if (ABORT) return;
803
+ initRuntime();
804
+ readyPromiseResolve(Module);
805
+ Module["onRuntimeInitialized"]?.();
806
+ postRun();
807
+ }
808
+ if (Module["setStatus"]) {
809
+ Module["setStatus"]("Running...");
810
+ setTimeout(() => {
811
+ setTimeout(() => Module["setStatus"](""), 1);
812
+ doRun();
813
+ }, 1);
814
+ } else {
815
+ doRun();
816
+ }
692817
}
693818
694819
if (Module["preInit"]) {
695
- if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ];
696
- while (Module["preInit"].length > 0) {
697
- Module["preInit"].pop()();
698
- }
820
+ if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ];
821
+ while (Module["preInit"].length > 0) {
822
+ Module["preInit"].pop()();
823
+ }
699824
}
700825
701826
run();
702827
828
+// end include: postamble.js
829
+// include: postamble_modularize.js
830
+// In MODULARIZE mode we wrap the generated code in a factory function
831
+// and return either the Module itself, or a promise of the module.
832
+// We assign to the `moduleRtn` global here and configure closure to see
833
+// this as and extern so it won't get minified.
834
+moduleRtn = readyPromise;
835
+
703836
704
- return initPikchrModule.ready
837
+ return moduleRtn;
705838
}
706839
);
707840
})();
708
-if (typeof exports === 'object' && typeof module === 'object')
841
+if (typeof exports === 'object' && typeof module === 'object') {
709842
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;
843
+ // This default export looks redundant, but it allows TS to import this
844
+ // commonjs style module.
845
+ module.exports.default = initPikchrModule;
846
+} else if (typeof define === 'function' && define['amd'])
847
+ define([], () => initPikchrModule);
714848
--- extsrc/pikchr.js
+++ extsrc/pikchr.js
@@ -1,713 +1,847 @@
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);
19
20 var arguments_ = [];
21
22 var thisProgram = "./this.program";
23
24 var quit_ = (status, toThrow) => {
25 throw toThrow;
26 };
27
28 var ENVIRONMENT_IS_WEB = true;
29
30 var ENVIRONMENT_IS_WORKER = false;
31
32 var scriptDirectory = "";
33
34 function locateFile(path) {
35 if (Module["locateFile"]) {
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 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
 
 
 
 
99 if (Module["arguments"]) arguments_ = Module["arguments"];
100
101 if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
102
103 if (Module["quit"]) quit_ = Module["quit"];
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
 
 
 
 
 
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());
 
235 }
236 }
237 callRuntimeCallbacks(__ATPRERUN__);
238 }
239
240 function initRuntime() {
241 runtimeInitialized = true;
242 callRuntimeCallbacks(__ATINIT__);
243 }
244
245 function postRun() {
246 if (Module["postRun"]) {
247 if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ];
248 while (Module["postRun"].length) {
249 addOnPostRun(Module["postRun"].shift());
250 }
251 }
252 callRuntimeCallbacks(__ATPOSTRUN__);
253 }
254
255 function addOnPreRun(cb) {
256 __ATPRERUN__.unshift(cb);
257 }
258
259 function addOnInit(cb) {
260 __ATINIT__.unshift(cb);
261 }
262
263 function addOnPostRun(cb) {
264 __ATPOSTRUN__.unshift(cb);
265 }
266
267 var runDependencies = 0;
268
269 var runDependencyWatcher = null;
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 }
290 if (dependenciesFulfilled) {
291 var callback = dependenciesFulfilled;
292 dependenciesFulfilled = null;
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);
571 writeArrayToMemory(arr, ret);
572 return ret;
573 }
574 };
575 function convertReturnValue(ret) {
576 if (returnType === "string") {
577 return UTF8ToString(ret);
578 }
579 if (returnType === "boolean") return Boolean(ret);
580 return ret;
581 }
582 var func = getCFunc(ident);
583 var cArgs = [];
584 var stack = 0;
585 if (args) {
586 for (var i = 0; i < args.length; i++) {
587 var converter = toC[argTypes[i]];
588 if (converter) {
589 if (stack === 0) stack = stackSave();
590 cArgs[i] = converter(args[i]);
591 } else {
592 cArgs[i] = args[i];
593 }
594 }
595 }
596 var ret = func.apply(null, cArgs);
597 function onDone(ret) {
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
649 Module["cwrap"] = cwrap;
650
651 Module["setValue"] = setValue;
652
653 Module["getValue"] = getValue;
654
655 var calledRun;
656
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) {
669 return;
670 }
671 function doRun() {
672 if (calledRun) return;
673 calledRun = true;
674 Module["calledRun"] = true;
675 if (ABORT) return;
676 initRuntime();
677 readyPromiseResolve(Module);
678 if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"]();
679 postRun();
680 }
681 if (Module["setStatus"]) {
682 Module["setStatus"]("Running...");
683 setTimeout(function() {
684 setTimeout(function() {
685 Module["setStatus"]("");
686 }, 1);
687 doRun();
688 }, 1);
689 } else {
690 doRun();
691 }
692 }
693
694 if (Module["preInit"]) {
695 if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ];
696 while (Module["preInit"].length > 0) {
697 Module["preInit"].pop()();
698 }
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,713 +1,847 @@
 
1 var initPikchrModule = (() => {
2 var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
3
4 return (
5 async function(moduleArg = {}) {
6 var moduleRtn;
7
8 // include: shell.js
9 // The Module object: Our interface to the outside world. We import
10 // and export values on it. There are various ways Module can be used:
11 // 1. Not defined. We create it here
12 // 2. A function parameter, function(moduleArg) => Promise<Module>
13 // 3. pre-run appended it, var Module = {}; ..generated code..
14 // 4. External script tag defines var Module.
15 // We need to check if Module already exists (e.g. case 3 above).
16 // Substitution will be replaced with actual code on later stage of the build,
17 // this way Closure Compiler will not mangle it (e.g. case 4. above).
18 // Note that if you want to run closure, and also to use Module
19 // after the generated code, you will need to define var Module = {};
20 // before the code. Then that object will be used in the code, and you
21 // can continue to use Module afterwards as well.
22 var Module = moduleArg;
23
24 // Set up the promise that indicates the Module is initialized
25 var readyPromiseResolve, readyPromiseReject;
26
27 var readyPromise = new Promise((resolve, reject) => {
28 readyPromiseResolve = resolve;
29 readyPromiseReject = reject;
30 });
31
32 // Determine the runtime environment we are in. You can customize this by
33 // setting the ENVIRONMENT setting at compile time (see settings.js).
34 var ENVIRONMENT_IS_WEB = true;
35
36 var ENVIRONMENT_IS_WORKER = false;
37
38 // --pre-jses are emitted after the Module integration code, so that they can
39 // refer to Module (if they choose; they can also define Module)
40 // Sometimes an existing Module object exists with properties
41 // meant to overwrite the default module functionality. Here
42 // we collect those properties and reapply _after_ we configure
43 // the current environment's defaults to avoid having to be so
44 // defensive during initialization.
45 var moduleOverrides = Object.assign({}, Module);
46
47 var arguments_ = [];
48
49 var thisProgram = "./this.program";
50
51 var quit_ = (status, toThrow) => {
52 throw toThrow;
53 };
54
55 // `/` should be present at the end if `scriptDirectory` is not empty
 
 
 
56 var scriptDirectory = "";
57
58 function locateFile(path) {
59 if (Module["locateFile"]) {
60 return Module["locateFile"](path, scriptDirectory);
61 }
62 return scriptDirectory + path;
63 }
64
65 // Hooks that are implemented differently in different runtime environments.
66 var readAsync, readBinary;
67
68 // Note that this includes Node.js workers when relevant (pthreads is enabled).
69 // Node.js workers are detected as a combination of ENVIRONMENT_IS_WORKER and
70 // ENVIRONMENT_IS_NODE.
71 if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
72 if (ENVIRONMENT_IS_WORKER) {
73 // Check worker, not web, since window could be polyfilled
74 scriptDirectory = self.location.href;
75 } else if (typeof document != "undefined" && document.currentScript) {
76 // web
77 scriptDirectory = document.currentScript.src;
78 }
79 // When MODULARIZE, this JS may be executed later, after document.currentScript
80 // is gone, so we saved it, and we use it here instead of any other info.
81 if (_scriptName) {
82 scriptDirectory = _scriptName;
83 }
84 // blob urls look like blob:http://site.com/etc/etc and we cannot infer anything from them.
85 // otherwise, slice off the final part of the url to find the script directory.
86 // if scriptDirectory does not contain a slash, lastIndexOf will return -1,
87 // and scriptDirectory will correctly be replaced with an empty string.
88 // If scriptDirectory contains a query (starting with ?) or a fragment (starting with #),
89 // they are removed because they could contain a slash.
90 if (scriptDirectory.startsWith("blob:")) {
91 scriptDirectory = "";
92 } else {
93 scriptDirectory = scriptDirectory.slice(0, scriptDirectory.replace(/[?#].*/, "").lastIndexOf("/") + 1);
94 }
95 {
96 // include: web_or_worker_shell_read.js
97 readAsync = async url => {
98 var response = await fetch(url, {
99 credentials: "same-origin"
100 });
101 if (response.ok) {
102 return response.arrayBuffer();
103 }
104 throw new Error(response.status + " : " + response.url);
105 };
106 }
 
 
 
 
 
 
107 } else {}
108
109 var out = Module["print"] || console.log.bind(console);
110
111 var err = Module["printErr"] || console.error.bind(console);
112
113 // Merge back in the overrides
114 Object.assign(Module, moduleOverrides);
115
116 // Free the object hierarchy contained in the overrides, this lets the GC
117 // reclaim data used.
118 moduleOverrides = null;
119
120 // Emit code to handle expected values on the Module object. This applies Module.x
121 // to the proper local x. This has two benefits: first, we only emit it if it is
122 // expected to arrive, and second, by using a local everywhere else that can be
123 // minified.
124 if (Module["arguments"]) arguments_ = Module["arguments"];
125
126 if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
127
128 // perform assertions in shell.js after we set up out() and err(), as otherwise if an assertion fails it cannot print the message
129 // end include: shell.js
130 // include: preamble.js
131 // === Preamble library stuff ===
132 // Documentation for the public APIs defined in this file must be updated in:
133 // site/source/docs/api_reference/preamble.js.rst
134 // A prebuilt local version of the documentation is available at:
135 // site/build/text/docs/api_reference/preamble.js.txt
136 // You can also build docs locally as HTML or other formats in site/
137 // An online HTML version (which may be of a different version of Emscripten)
138 // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
139 var wasmBinary = Module["wasmBinary"];
140
141 // Wasm globals
142 var wasmMemory;
143
144 //========================================
145 // Runtime essentials
146 //========================================
147 // whether we are quitting the application. no code should run after this.
148 // set in exit() and abort()
149 var ABORT = false;
150
151 // set by exit() and abort(). Passed to 'onExit' handler.
152 // NOTE: This is also used as the process return code code in shell environments
153 // but only when noExitRuntime is false.
154 var EXITSTATUS;
155
156 // Memory management
157 var /** @type {!Int8Array} */ HEAP8, /** @type {!Uint8Array} */ HEAPU8, /** @type {!Int16Array} */ HEAP16, /** @type {!Uint16Array} */ HEAPU16, /** @type {!Int32Array} */ HEAP32, /** @type {!Uint32Array} */ HEAPU32, /** @type {!Float32Array} */ HEAPF32, /* BigInt64Array type is not correctly defined in closure
158 /** not-@type {!BigInt64Array} */ HEAP64, /* BigUint64Array type is not correctly defined in closure
159 /** not-t@type {!BigUint64Array} */ HEAPU64, /** @type {!Float64Array} */ HEAPF64;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
161 var runtimeInitialized = false;
162
163 // include: runtime_shared.js
164 // include: runtime_stack_check.js
165 // end include: runtime_stack_check.js
166 // include: runtime_exceptions.js
167 // end include: runtime_exceptions.js
168 // include: runtime_debug.js
169 // end include: runtime_debug.js
170 // include: memoryprofiler.js
171 // end include: memoryprofiler.js
172 function updateMemoryViews() {
173 var b = wasmMemory.buffer;
174 Module["HEAP8"] = HEAP8 = new Int8Array(b);
175 Module["HEAP16"] = HEAP16 = new Int16Array(b);
176 Module["HEAPU8"] = HEAPU8 = new Uint8Array(b);
177 Module["HEAPU16"] = HEAPU16 = new Uint16Array(b);
178 Module["HEAP32"] = HEAP32 = new Int32Array(b);
179 Module["HEAPU32"] = HEAPU32 = new Uint32Array(b);
180 Module["HEAPF32"] = HEAPF32 = new Float32Array(b);
181 Module["HEAPF64"] = HEAPF64 = new Float64Array(b);
182 Module["HEAP64"] = HEAP64 = new BigInt64Array(b);
183 Module["HEAPU64"] = HEAPU64 = new BigUint64Array(b);
184 }
185
186 // end include: runtime_shared.js
187 function preRun() {
188 if (Module["preRun"]) {
189 if (typeof Module["preRun"] == "function") Module["preRun"] = [ Module["preRun"] ];
190 while (Module["preRun"].length) {
191 addOnPreRun(Module["preRun"].shift());
192 }
193 }
194 callRuntimeCallbacks(onPreRuns);
 
195 }
196
197 function initRuntime() {
198 runtimeInitialized = true;
199 wasmExports["e"]();
200 }
201
202 function postRun() {
203 if (Module["postRun"]) {
204 if (typeof Module["postRun"] == "function") Module["postRun"] = [ Module["postRun"] ];
205 while (Module["postRun"].length) {
206 addOnPostRun(Module["postRun"].shift());
207 }
208 }
209 callRuntimeCallbacks(onPostRuns);
210 }
211
212 // A counter of dependencies for calling run(). If we need to
213 // do asynchronous work before running, increment this and
214 // decrement it. Incrementing must happen in a place like
215 // Module.preRun (used by emcc to add file preloading).
216 // Note that you can add dependencies in preRun, even though
217 // it happens right before run - run will be postponed until
218 // the dependencies are met.
219 var runDependencies = 0;
 
 
 
 
 
 
 
220
221 var dependenciesFulfilled = null;
222
223 function addRunDependency(id) {
224 runDependencies++;
225 Module["monitorRunDependencies"]?.(runDependencies);
 
 
226 }
227
228 function removeRunDependency(id) {
229 runDependencies--;
230 Module["monitorRunDependencies"]?.(runDependencies);
231 if (runDependencies == 0) {
232 if (dependenciesFulfilled) {
233 var callback = dependenciesFulfilled;
234 dependenciesFulfilled = null;
235 callback();
236 }
237 }
238 }
239
240 /** @param {string|number=} what */ function abort(what) {
241 Module["onAbort"]?.(what);
242 what = "Aborted(" + what + ")";
243 // TODO(sbc): Should we remove printing and leave it up to whoever
244 // catches the exception?
245 err(what);
246 ABORT = true;
247 what += ". Build with -sASSERTIONS for more info.";
248 // Use a wasm runtime error, because a JS error might be seen as a foreign
249 // exception, which means we'd run destructors on it. We need the error to
250 // simply make the program stop.
251 // FIXME This approach does not work in Wasm EH because it currently does not assume
252 // all RuntimeErrors are from traps; it decides whether a RuntimeError is from
253 // a trap or not based on a hidden field within the object. So at the moment
254 // we don't have a way of throwing a wasm trap from JS. TODO Make a JS API that
255 // allows this in the wasm spec.
256 // Suppress closure compiler warning here. Closure compiler's builtin extern
257 // definition for WebAssembly.RuntimeError claims it takes no arguments even
258 // though it can.
259 // TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
260 /** @suppress {checkTypes} */ var e = new WebAssembly.RuntimeError(what);
261 readyPromiseReject(e);
262 // Throw the error whether or not MODULARIZE is set because abort is used
263 // in code paths apart from instantiation where an exception is expected
264 // to be thrown when abort is called.
265 throw e;
266 }
267
268 var wasmBinaryFile;
269
270 function findWasmBinary() {
271 return locateFile("pikchr.wasm");
 
 
272 }
273
274 function getBinarySync(file) {
 
275 if (file == wasmBinaryFile && wasmBinary) {
276 return new Uint8Array(wasmBinary);
277 }
278 if (readBinary) {
279 return readBinary(file);
280 }
281 throw "both async and sync fetching of the wasm failed";
282 }
283
284 async function getWasmBinary(binaryFile) {
285 // If we don't have the binary yet, load it asynchronously using readAsync.
286 if (!wasmBinary) {
287 // Fetch the binary using readAsync
288 try {
289 var response = await readAsync(binaryFile);
290 return new Uint8Array(response);
291 } catch {}
292 }
293 // Otherwise, getBinarySync should be able to get it synchronously
294 return getBinarySync(binaryFile);
295 }
296
297 async function instantiateArrayBuffer(binaryFile, imports) {
298 try {
299 var binary = await getWasmBinary(binaryFile);
300 var instance = await WebAssembly.instantiate(binary, imports);
301 return instance;
302 } catch (reason) {
303 err(`failed to asynchronously prepare wasm: ${reason}`);
304 abort(reason);
305 }
306 }
307
308 async function instantiateAsync(binary, binaryFile, imports) {
309 if (!binary && typeof WebAssembly.instantiateStreaming == "function") {
310 try {
311 var response = fetch(binaryFile, {
312 credentials: "same-origin"
313 });
314 var instantiationResult = await WebAssembly.instantiateStreaming(response, imports);
315 return instantiationResult;
316 } catch (reason) {
317 // We expect the most common failure cause to be a bad MIME type for the binary,
318 // in which case falling back to ArrayBuffer instantiation should work.
319 err(`wasm streaming compile failed: ${reason}`);
320 err("falling back to ArrayBuffer instantiation");
321 }
322 }
323 return instantiateArrayBuffer(binaryFile, imports);
324 }
325
326 function getWasmImports() {
327 // prepare imports
328 return {
329 "a": wasmImports
330 };
331 }
332
333 // Create the wasm instance.
334 // Receives the wasm imports, returns the exports.
335 async function createWasm() {
336 // Load the wasm module and create an instance of using native support in the JS engine.
337 // handle a generated wasm instance, receiving its exports and
338 // performing other necessary setup
339 /** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) {
340 wasmExports = instance.exports;
341 wasmMemory = wasmExports["d"];
342 updateMemoryViews();
343 removeRunDependency("wasm-instantiate");
344 return wasmExports;
345 }
346 // wait for the pthread pool (if any)
347 addRunDependency("wasm-instantiate");
348 // Prefer streaming instantiation if available.
349 function receiveInstantiationResult(result) {
350 // 'result' is a ResultObject object which has both the module and instance.
351 // receiveInstance() will swap in the exports (to Module.asm) so they can be called
352 // TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
353 // When the regression is fixed, can restore the above PTHREADS-enabled path.
354 return receiveInstance(result["instance"]);
355 }
356 var info = getWasmImports();
357 // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
358 // to manually instantiate the Wasm module themselves. This allows pages to
359 // run the instantiation parallel to any other async startup actions they are
360 // performing.
361 // Also pthreads and wasm workers initialize the wasm instance through this
362 // path.
363 if (Module["instantiateWasm"]) {
364 return new Promise((resolve, reject) => {
365 Module["instantiateWasm"](info, (mod, inst) => {
366 receiveInstance(mod, inst);
367 resolve(mod.exports);
368 });
369 });
370 }
371 wasmBinaryFile ??= findWasmBinary();
372 try {
373 var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
374 var exports = receiveInstantiationResult(result);
375 return exports;
376 } catch (e) {
377 // If instantiation fails, reject the module ready promise.
378 readyPromiseReject(e);
379 return Promise.reject(e);
380 }
381 }
382
383 // === Body ===
384 // end include: preamble.js
385 class ExitStatus {
386 name="ExitStatus";
387 constructor(status) {
388 this.message = `Program terminated with exit(${status})`;
389 this.status = status;
390 }
391 }
392
393 var callRuntimeCallbacks = callbacks => {
394 while (callbacks.length > 0) {
395 // Pass the module as the first argument.
396 callbacks.shift()(Module);
397 }
398 };
399
400 var onPostRuns = [];
401
402 var addOnPostRun = cb => onPostRuns.unshift(cb);
403
404 var onPreRuns = [];
405
406 var addOnPreRun = cb => onPreRuns.unshift(cb);
407
408 /**
409 * @param {number} ptr
410 * @param {string} type
411 */ function getValue(ptr, type = "i8") {
412 if (type.endsWith("*")) type = "*";
413 switch (type) {
414 case "i1":
415 return HEAP8[ptr];
416
417 case "i8":
418 return HEAP8[ptr];
419
420 case "i16":
421 return HEAP16[((ptr) >> 1)];
422
423 case "i32":
424 return HEAP32[((ptr) >> 2)];
425
426 case "i64":
427 return HEAP64[((ptr) >> 3)];
428
429 case "float":
430 return HEAPF32[((ptr) >> 2)];
431
432 case "double":
433 return HEAPF64[((ptr) >> 3)];
434
435 case "*":
436 return HEAPU32[((ptr) >> 2)];
437
438 default:
439 abort(`invalid type for getValue: ${type}`);
440 }
441 }
442
443 var noExitRuntime = Module["noExitRuntime"] || true;
444
445 /**
446 * @param {number} ptr
447 * @param {number} value
448 * @param {string} type
449 */ function setValue(ptr, value, type = "i8") {
450 if (type.endsWith("*")) type = "*";
451 switch (type) {
452 case "i1":
453 HEAP8[ptr] = value;
454 break;
455
456 case "i8":
457 HEAP8[ptr] = value;
458 break;
459
460 case "i16":
461 HEAP16[((ptr) >> 1)] = value;
462 break;
463
464 case "i32":
465 HEAP32[((ptr) >> 2)] = value;
466 break;
467
468 case "i64":
469 HEAP64[((ptr) >> 3)] = BigInt(value);
470 break;
471
472 case "float":
473 HEAPF32[((ptr) >> 2)] = value;
474 break;
475
476 case "double":
477 HEAPF64[((ptr) >> 3)] = value;
478 break;
479
480 case "*":
481 HEAPU32[((ptr) >> 2)] = value;
482 break;
483
484 default:
485 abort(`invalid type for setValue: ${type}`);
486 }
487 }
488
489 var stackRestore = val => __emscripten_stack_restore(val);
490
491 var stackSave = () => _emscripten_stack_get_current();
492
493 var UTF8Decoder = typeof TextDecoder != "undefined" ? new TextDecoder : undefined;
494
495 /**
496 * Given a pointer 'idx' to a null-terminated UTF8-encoded string in the given
497 * array that contains uint8 values, returns a copy of that string as a
498 * Javascript String object.
499 * heapOrArray is either a regular array, or a JavaScript typed array view.
500 * @param {number=} idx
501 * @param {number=} maxBytesToRead
502 * @return {string}
503 */ var UTF8ArrayToString = (heapOrArray, idx = 0, maxBytesToRead = NaN) => {
504 var endIdx = idx + maxBytesToRead;
505 var endPtr = idx;
506 // TextDecoder needs to know the byte length in advance, it doesn't stop on
507 // null terminator by itself. Also, use the length info to avoid running tiny
508 // strings through TextDecoder, since .subarray() allocates garbage.
509 // (As a tiny code save trick, compare endPtr against endIdx using a negation,
510 // so that undefined/NaN means Infinity)
511 while (heapOrArray[endPtr] && !(endPtr >= endIdx)) ++endPtr;
512 if (endPtr - idx > 16 && heapOrArray.buffer && UTF8Decoder) {
513 return UTF8Decoder.decode(heapOrArray.subarray(idx, endPtr));
514 }
515 var str = "";
516 // If building with TextDecoder, we have already computed the string length
517 // above, so test loop end condition against that
518 while (idx < endPtr) {
519 // For UTF8 byte structure, see:
520 // http://en.wikipedia.org/wiki/UTF-8#Description
521 // https://www.ietf.org/rfc/rfc2279.txt
522 // https://tools.ietf.org/html/rfc3629
523 var u0 = heapOrArray[idx++];
524 if (!(u0 & 128)) {
525 str += String.fromCharCode(u0);
526 continue;
527 }
528 var u1 = heapOrArray[idx++] & 63;
529 if ((u0 & 224) == 192) {
530 str += String.fromCharCode(((u0 & 31) << 6) | u1);
531 continue;
532 }
533 var u2 = heapOrArray[idx++] & 63;
534 if ((u0 & 240) == 224) {
535 u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
536 } else {
537 u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heapOrArray[idx++] & 63);
538 }
539 if (u0 < 65536) {
540 str += String.fromCharCode(u0);
541 } else {
542 var ch = u0 - 65536;
543 str += String.fromCharCode(55296 | (ch >> 10), 56320 | (ch & 1023));
544 }
545 }
546 return str;
547 };
548
549 /**
550 * Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the
551 * emscripten HEAP, returns a copy of that string as a Javascript String object.
552 *
553 * @param {number} ptr
554 * @param {number=} maxBytesToRead - An optional length that specifies the
555 * maximum number of bytes to read. You can omit this parameter to scan the
556 * string until the first 0 byte. If maxBytesToRead is passed, and the string
557 * at [ptr, ptr+maxBytesToReadr[ contains a null byte in the middle, then the
558 * string will cut short at that byte index (i.e. maxBytesToRead will not
559 * produce a string of exact length [ptr, ptr+maxBytesToRead[) N.B. mixing
560 * frequent uses of UTF8ToString() with and without maxBytesToRead may throw
561 * JS JIT optimizations off, so it is worth to consider consistently using one
562 * @return {string}
563 */ var UTF8ToString = (ptr, maxBytesToRead) => ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
564
565 var ___assert_fail = (condition, filename, line, func) => abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [ filename ? UTF8ToString(filename) : "unknown filename", line, func ? UTF8ToString(func) : "unknown function" ]);
566
567 var abortOnCannotGrowMemory = requestedSize => {
568 abort("OOM");
569 };
570
571 var _emscripten_resize_heap = requestedSize => {
572 var oldSize = HEAPU8.length;
573 // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
574 requestedSize >>>= 0;
575 abortOnCannotGrowMemory(requestedSize);
576 };
577
578 var runtimeKeepaliveCounter = 0;
579
580 var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
581
582 var _proc_exit = code => {
583 EXITSTATUS = code;
584 if (!keepRuntimeAlive()) {
585 Module["onExit"]?.(code);
586 ABORT = true;
587 }
588 quit_(code, new ExitStatus(code));
589 };
590
591 /** @suppress {duplicate } */ /** @param {boolean|number=} implicit */ var exitJS = (status, implicit) => {
592 EXITSTATUS = status;
593 _proc_exit(status);
594 };
595
596 var _exit = exitJS;
597
598 var getCFunc = ident => {
599 var func = Module["_" + ident];
600 // closure exported function
601 return func;
602 };
603
604 var writeArrayToMemory = (array, buffer) => {
605 HEAP8.set(array, buffer);
606 };
607
608 var lengthBytesUTF8 = str => {
609 var len = 0;
610 for (var i = 0; i < str.length; ++i) {
611 // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
612 // unit, not a Unicode code point of the character! So decode
613 // UTF16->UTF32->UTF8.
614 // See http://unicode.org/faq/utf_bom.html#utf16-3
615 var c = str.charCodeAt(i);
616 // possibly a lead surrogate
617 if (c <= 127) {
618 len++;
619 } else if (c <= 2047) {
620 len += 2;
621 } else if (c >= 55296 && c <= 57343) {
622 len += 4;
623 ++i;
624 } else {
625 len += 3;
626 }
627 }
628 return len;
629 };
630
631 var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
632 // Parameter maxBytesToWrite is not optional. Negative values, 0, null,
633 // undefined and false each don't write out any bytes.
634 if (!(maxBytesToWrite > 0)) return 0;
635 var startIdx = outIdx;
636 var endIdx = outIdx + maxBytesToWrite - 1;
637 // -1 for string null terminator.
638 for (var i = 0; i < str.length; ++i) {
639 // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code
640 // unit, not a Unicode code point of the character! So decode
641 // UTF16->UTF32->UTF8.
642 // See http://unicode.org/faq/utf_bom.html#utf16-3
643 // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description
644 // and https://www.ietf.org/rfc/rfc2279.txt
645 // and https://tools.ietf.org/html/rfc3629
646 var u = str.charCodeAt(i);
647 // possibly a lead surrogate
648 if (u >= 55296 && u <= 57343) {
649 var u1 = str.charCodeAt(++i);
650 u = 65536 + ((u & 1023) << 10) | (u1 & 1023);
651 }
652 if (u <= 127) {
653 if (outIdx >= endIdx) break;
654 heap[outIdx++] = u;
655 } else if (u <= 2047) {
656 if (outIdx + 1 >= endIdx) break;
657 heap[outIdx++] = 192 | (u >> 6);
658 heap[outIdx++] = 128 | (u & 63);
659 } else if (u <= 65535) {
660 if (outIdx + 2 >= endIdx) break;
661 heap[outIdx++] = 224 | (u >> 12);
662 heap[outIdx++] = 128 | ((u >> 6) & 63);
663 heap[outIdx++] = 128 | (u & 63);
664 } else {
665 if (outIdx + 3 >= endIdx) break;
666 heap[outIdx++] = 240 | (u >> 18);
667 heap[outIdx++] = 128 | ((u >> 12) & 63);
668 heap[outIdx++] = 128 | ((u >> 6) & 63);
669 heap[outIdx++] = 128 | (u & 63);
670 }
671 }
672 // Null-terminate the pointer to the buffer.
673 heap[outIdx] = 0;
674 return outIdx - startIdx;
675 };
676
677 var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
678
679 var stackAlloc = sz => __emscripten_stack_alloc(sz);
680
681 var stringToUTF8OnStack = str => {
682 var size = lengthBytesUTF8(str) + 1;
683 var ret = stackAlloc(size);
684 stringToUTF8(str, ret, size);
685 return ret;
686 };
687
688 /**
689 * @param {string|null=} returnType
690 * @param {Array=} argTypes
691 * @param {Arguments|Array=} args
692 * @param {Object=} opts
693 */ var ccall = (ident, returnType, argTypes, args, opts) => {
694 // For fast lookup of conversion functions
695 var toC = {
696 "string": str => {
697 var ret = 0;
698 if (str !== null && str !== undefined && str !== 0) {
699 // null string
700 ret = stringToUTF8OnStack(str);
701 }
702 return ret;
703 },
704 "array": arr => {
705 var ret = stackAlloc(arr.length);
706 writeArrayToMemory(arr, ret);
707 return ret;
708 }
709 };
710 function convertReturnValue(ret) {
711 if (returnType === "string") {
712 return UTF8ToString(ret);
713 }
714 if (returnType === "boolean") return Boolean(ret);
715 return ret;
716 }
717 var func = getCFunc(ident);
718 var cArgs = [];
719 var stack = 0;
720 if (args) {
721 for (var i = 0; i < args.length; i++) {
722 var converter = toC[argTypes[i]];
723 if (converter) {
724 if (stack === 0) stack = stackSave();
725 cArgs[i] = converter(args[i]);
726 } else {
727 cArgs[i] = args[i];
728 }
729 }
730 }
731 var ret = func(...cArgs);
732 function onDone(ret) {
733 if (stack !== 0) stackRestore(stack);
734 return convertReturnValue(ret);
735 }
736 ret = onDone(ret);
737 return ret;
738 };
739
740 /**
741 * @param {string=} returnType
742 * @param {Array=} argTypes
743 * @param {Object=} opts
744 */ var cwrap = (ident, returnType, argTypes, opts) => {
745 // When the function takes numbers and returns a number, we can just return
746 // the original function
747 var numericArgs = !argTypes || argTypes.every(type => type === "number" || type === "boolean");
748 var numericRet = returnType !== "string";
749 if (numericRet && numericArgs && !opts) {
750 return getCFunc(ident);
751 }
752 return (...args) => ccall(ident, returnType, argTypes, args, opts);
753 };
754
755 var wasmImports = {
756 /** @export */ a: ___assert_fail,
757 /** @export */ b: _emscripten_resize_heap,
758 /** @export */ c: _exit
759 };
760
761 var wasmExports = await createWasm();
762
763 var ___wasm_call_ctors = wasmExports["e"];
764
765 var _pikchr = Module["_pikchr"] = wasmExports["g"];
766
767 var __emscripten_stack_restore = wasmExports["h"];
768
769 var __emscripten_stack_alloc = wasmExports["i"];
770
771 var _emscripten_stack_get_current = wasmExports["j"];
772
773 // include: postamble.js
774 // === Auto-generated postamble setup entry stuff ===
775 Module["stackSave"] = stackSave;
776
777 Module["stackRestore"] = stackRestore;
778
779 Module["stackAlloc"] = stackAlloc;
780
781 Module["cwrap"] = cwrap;
782
783 Module["setValue"] = setValue;
784
785 Module["getValue"] = getValue;
786
787 function run() {
788 if (runDependencies > 0) {
789 dependenciesFulfilled = run;
790 return;
791 }
792 preRun();
793 // a preRun added a dependency, run will be called later
794 if (runDependencies > 0) {
795 dependenciesFulfilled = run;
796 return;
797 }
798 function doRun() {
799 // run may have just been called through dependencies being fulfilled just in this very frame,
800 // or while the async setStatus time below was happening
801 Module["calledRun"] = true;
802 if (ABORT) return;
803 initRuntime();
804 readyPromiseResolve(Module);
805 Module["onRuntimeInitialized"]?.();
806 postRun();
807 }
808 if (Module["setStatus"]) {
809 Module["setStatus"]("Running...");
810 setTimeout(() => {
811 setTimeout(() => Module["setStatus"](""), 1);
812 doRun();
813 }, 1);
814 } else {
815 doRun();
816 }
 
 
 
 
 
 
 
817 }
818
819 if (Module["preInit"]) {
820 if (typeof Module["preInit"] == "function") Module["preInit"] = [ Module["preInit"] ];
821 while (Module["preInit"].length > 0) {
822 Module["preInit"].pop()();
823 }
824 }
825
826 run();
827
828 // end include: postamble.js
829 // include: postamble_modularize.js
830 // In MODULARIZE mode we wrap the generated code in a factory function
831 // and return either the Module itself, or a promise of the module.
832 // We assign to the `moduleRtn` global here and configure closure to see
833 // this as and extern so it won't get minified.
834 moduleRtn = readyPromise;
835
836
837 return moduleRtn;
838 }
839 );
840 })();
841 if (typeof exports === 'object' && typeof module === 'object') {
842 module.exports = initPikchrModule;
843 // This default export looks redundant, but it allows TS to import this
844 // commonjs style module.
845 module.exports.default = initPikchrModule;
846 } else if (typeof define === 'function' && define['amd'])
847 define([], () => initPikchrModule);
848
--- 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
+1 -1
--- src/alerts.c
+++ src/alerts.c
@@ -1133,11 +1133,11 @@
11331133
** designated host and port and all times.
11341134
*/
11351135
11361136
11371137
/*
1138
-** COMMAND: alerts*
1138
+** COMMAND: alerts* abbreviated-subcommands
11391139
**
11401140
** Usage: %fossil alerts SUBCOMMAND ARGS...
11411141
**
11421142
** Subcommands:
11431143
**
11441144
--- src/alerts.c
+++ src/alerts.c
@@ -1133,11 +1133,11 @@
1133 ** designated host and port and all times.
1134 */
1135
1136
1137 /*
1138 ** COMMAND: alerts*
1139 **
1140 ** Usage: %fossil alerts SUBCOMMAND ARGS...
1141 **
1142 ** Subcommands:
1143 **
1144
--- src/alerts.c
+++ src/alerts.c
@@ -1133,11 +1133,11 @@
1133 ** designated host and port and all times.
1134 */
1135
1136
1137 /*
1138 ** COMMAND: alerts* abbreviated-subcommands
1139 **
1140 ** Usage: %fossil alerts SUBCOMMAND ARGS...
1141 **
1142 ** Subcommands:
1143 **
1144
+1 -1
--- src/allrepo.c
+++ src/allrepo.c
@@ -51,11 +51,11 @@
5151
blob_appendf(pExtra, " %s", g.argv[i]);
5252
}
5353
}
5454
5555
/*
56
-** COMMAND: all
56
+** COMMAND: all abbreviated-subcommands
5757
**
5858
** Usage: %fossil all SUBCOMMAND ...
5959
**
6060
** The ~/.fossil file records the location of all repositories for a
6161
** user. This command performs certain operations on all repositories
6262
--- src/allrepo.c
+++ src/allrepo.c
@@ -51,11 +51,11 @@
51 blob_appendf(pExtra, " %s", g.argv[i]);
52 }
53 }
54
55 /*
56 ** COMMAND: all
57 **
58 ** Usage: %fossil all SUBCOMMAND ...
59 **
60 ** The ~/.fossil file records the location of all repositories for a
61 ** user. This command performs certain operations on all repositories
62
--- src/allrepo.c
+++ src/allrepo.c
@@ -51,11 +51,11 @@
51 blob_appendf(pExtra, " %s", g.argv[i]);
52 }
53 }
54
55 /*
56 ** COMMAND: all abbreviated-subcommands
57 **
58 ** Usage: %fossil all SUBCOMMAND ...
59 **
60 ** The ~/.fossil file records the location of all repositories for a
61 ** user. This command performs certain operations on all repositories
62
+1 -1
--- src/blob.c
+++ src/blob.c
@@ -1994,11 +1994,11 @@
19941994
zUtf8 = blob_str(pBlob) + bomSize;
19951995
zUtf8 = fossil_unicode_to_utf8(zUtf8);
19961996
blob_reset(pBlob);
19971997
blob_set_dynamic(pBlob, zUtf8);
19981998
}else if( useMbcs && invalid_utf8(pBlob) ){
1999
-#if defined(_WIN32) || defined(__CYGWIN__)
1999
+#if defined(_WIN32)
20002000
zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob));
20012001
blob_reset(pBlob);
20022002
blob_append(pBlob, zUtf8, -1);
20032003
fossil_mbcs_free(zUtf8);
20042004
#else
20052005
--- src/blob.c
+++ src/blob.c
@@ -1994,11 +1994,11 @@
1994 zUtf8 = blob_str(pBlob) + bomSize;
1995 zUtf8 = fossil_unicode_to_utf8(zUtf8);
1996 blob_reset(pBlob);
1997 blob_set_dynamic(pBlob, zUtf8);
1998 }else if( useMbcs && invalid_utf8(pBlob) ){
1999 #if defined(_WIN32) || defined(__CYGWIN__)
2000 zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob));
2001 blob_reset(pBlob);
2002 blob_append(pBlob, zUtf8, -1);
2003 fossil_mbcs_free(zUtf8);
2004 #else
2005
--- src/blob.c
+++ src/blob.c
@@ -1994,11 +1994,11 @@
1994 zUtf8 = blob_str(pBlob) + bomSize;
1995 zUtf8 = fossil_unicode_to_utf8(zUtf8);
1996 blob_reset(pBlob);
1997 blob_set_dynamic(pBlob, zUtf8);
1998 }else if( useMbcs && invalid_utf8(pBlob) ){
1999 #if defined(_WIN32)
2000 zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob));
2001 blob_reset(pBlob);
2002 blob_append(pBlob, zUtf8, -1);
2003 fossil_mbcs_free(zUtf8);
2004 #else
2005
+7 -7
--- src/branch.c
+++ src/branch.c
@@ -598,11 +598,11 @@
598598
** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS?
599599
**
600600
** Run various subcommands to manage branches of the open repository or
601601
** of the repository identified by the -R or --repository option.
602602
**
603
-** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
603
+** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
604604
**
605605
** Adds or cancels the "closed" tag to one or more branches.
606606
** It accepts arbitrary unambiguous symbolic names but
607607
** will only resolve check-in names and skips any which resolve
608608
** to non-leaf check-ins.
@@ -612,26 +612,26 @@
612612
** to stdout
613613
** -v|--verbose Output more information
614614
** --date-override DATE DATE to use instead of 'now'
615615
** --user-override USER USER to use instead of the current default
616616
**
617
-** > fossil branch current
617
+** > fossil branch current
618618
**
619619
** Print the name of the branch for the current check-out
620620
**
621
-** > fossil branch hide|unhide ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
621
+** > fossil branch hide|unhide ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
622622
**
623623
** Adds or cancels the "hidden" tag for the specified branches or
624624
** or check-in IDs. Accepts the same options as the close
625625
** subcommand.
626626
**
627
-** > fossil branch info BRANCH-NAME
627
+** > fossil branch info BRANCH-NAME
628628
**
629629
** Print information about a branch
630630
**
631
-** > fossil branch list|ls ?OPTIONS? ?GLOB?
632
-** > fossil branch lsh ?OPTIONS? ?LIMIT?
631
+** > fossil branch list|ls ?OPTIONS? ?GLOB?
632
+** > fossil branch lsh ?OPTIONS? ?LIMIT?
633633
**
634634
** List all branches.
635635
**
636636
** Options:
637637
** -a|--all List all branches. Default show only open branches
@@ -653,11 +653,11 @@
653653
** The "lsh" variant of this subcommand shows recently changed branches,
654654
** and accepts an optional LIMIT argument (defaults to 5) to cap output,
655655
** but no GLOB argument. All other options are supported, with -t being
656656
** an implied no-op.
657657
**
658
-** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
658
+** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
659659
**
660660
** Create a new branch BRANCH-NAME off of check-in BASIS.
661661
**
662662
** Options:
663663
** --private Branch is private (i.e., remains local)
664664
--- src/branch.c
+++ src/branch.c
@@ -598,11 +598,11 @@
598 ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS?
599 **
600 ** Run various subcommands to manage branches of the open repository or
601 ** of the repository identified by the -R or --repository option.
602 **
603 ** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
604 **
605 ** Adds or cancels the "closed" tag to one or more branches.
606 ** It accepts arbitrary unambiguous symbolic names but
607 ** will only resolve check-in names and skips any which resolve
608 ** to non-leaf check-ins.
@@ -612,26 +612,26 @@
612 ** to stdout
613 ** -v|--verbose Output more information
614 ** --date-override DATE DATE to use instead of 'now'
615 ** --user-override USER USER to use instead of the current default
616 **
617 ** > fossil branch current
618 **
619 ** Print the name of the branch for the current check-out
620 **
621 ** > fossil branch hide|unhide ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
622 **
623 ** Adds or cancels the "hidden" tag for the specified branches or
624 ** or check-in IDs. Accepts the same options as the close
625 ** subcommand.
626 **
627 ** > fossil branch info BRANCH-NAME
628 **
629 ** Print information about a branch
630 **
631 ** > fossil branch list|ls ?OPTIONS? ?GLOB?
632 ** > fossil branch lsh ?OPTIONS? ?LIMIT?
633 **
634 ** List all branches.
635 **
636 ** Options:
637 ** -a|--all List all branches. Default show only open branches
@@ -653,11 +653,11 @@
653 ** The "lsh" variant of this subcommand shows recently changed branches,
654 ** and accepts an optional LIMIT argument (defaults to 5) to cap output,
655 ** but no GLOB argument. All other options are supported, with -t being
656 ** an implied no-op.
657 **
658 ** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
659 **
660 ** Create a new branch BRANCH-NAME off of check-in BASIS.
661 **
662 ** Options:
663 ** --private Branch is private (i.e., remains local)
664
--- src/branch.c
+++ src/branch.c
@@ -598,11 +598,11 @@
598 ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS?
599 **
600 ** Run various subcommands to manage branches of the open repository or
601 ** of the repository identified by the -R or --repository option.
602 **
603 ** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
604 **
605 ** Adds or cancels the "closed" tag to one or more branches.
606 ** It accepts arbitrary unambiguous symbolic names but
607 ** will only resolve check-in names and skips any which resolve
608 ** to non-leaf check-ins.
@@ -612,26 +612,26 @@
612 ** to stdout
613 ** -v|--verbose Output more information
614 ** --date-override DATE DATE to use instead of 'now'
615 ** --user-override USER USER to use instead of the current default
616 **
617 ** > fossil branch current
618 **
619 ** Print the name of the branch for the current check-out
620 **
621 ** > fossil branch hide|unhide ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
622 **
623 ** Adds or cancels the "hidden" tag for the specified branches or
624 ** or check-in IDs. Accepts the same options as the close
625 ** subcommand.
626 **
627 ** > fossil branch info BRANCH-NAME
628 **
629 ** Print information about a branch
630 **
631 ** > fossil branch list|ls ?OPTIONS? ?GLOB?
632 ** > fossil branch lsh ?OPTIONS? ?LIMIT?
633 **
634 ** List all branches.
635 **
636 ** Options:
637 ** -a|--all List all branches. Default show only open branches
@@ -653,11 +653,11 @@
653 ** The "lsh" variant of this subcommand shows recently changed branches,
654 ** and accepts an optional LIMIT argument (defaults to 5) to cap output,
655 ** but no GLOB argument. All other options are supported, with -t being
656 ** an implied no-op.
657 **
658 ** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
659 **
660 ** Create a new branch BRANCH-NAME off of check-in BASIS.
661 **
662 ** Options:
663 ** --private Branch is private (i.e., remains local)
664
+1 -1
--- src/cache.c
+++ src/cache.c
@@ -255,11 +255,11 @@
255255
void cache_initialize(void){
256256
sqlite3_close(cacheOpen(1));
257257
}
258258
259259
/*
260
-** COMMAND: cache*
260
+** COMMAND: cache* abbreviated-subcommands
261261
**
262262
** Usage: %fossil cache SUBCOMMAND
263263
**
264264
** Manage the cache used for potentially expensive web pages such as
265265
** /zip and /tarball. SUBCOMMAND can be:
266266
--- src/cache.c
+++ src/cache.c
@@ -255,11 +255,11 @@
255 void cache_initialize(void){
256 sqlite3_close(cacheOpen(1));
257 }
258
259 /*
260 ** COMMAND: cache*
261 **
262 ** Usage: %fossil cache SUBCOMMAND
263 **
264 ** Manage the cache used for potentially expensive web pages such as
265 ** /zip and /tarball. SUBCOMMAND can be:
266
--- src/cache.c
+++ src/cache.c
@@ -255,11 +255,11 @@
255 void cache_initialize(void){
256 sqlite3_close(cacheOpen(1));
257 }
258
259 /*
260 ** COMMAND: cache* abbreviated-subcommands
261 **
262 ** Usage: %fossil cache SUBCOMMAND
263 **
264 ** Manage the cache used for potentially expensive web pages such as
265 ** /zip and /tarball. SUBCOMMAND can be:
266
+7 -4
--- src/comformat.c
+++ src/comformat.c
@@ -220,10 +220,11 @@
220220
int maxChars, /* [in] Optimization hint to abort before space found. */
221221
int *sumWidth /* [out] Summated width of all characters to next space. */
222222
){
223223
int cchUTF8, utf32, wcwidth = 0;
224224
int nextIndex = index;
225
+ if( zLine[index]==0 ) return index;
225226
for(;;){
226227
char_info_utf8(&zLine[nextIndex],&cchUTF8,&utf32);
227228
nextIndex += cchUTF8;
228229
wcwidth += cli_wcwidth(utf32);
229230
if( zLine[nextIndex]==0 || fossil_isspace(zLine[nextIndex]) ||
@@ -263,14 +264,16 @@
263264
int maxUTF8 = 1; /* Expected sequence length. */
264265
char c = z[i++];
265266
if( c==0x1b && z[i]=='[' ){
266267
do{
267268
i++;
268
- }while( fossil_isdigit(z[i]) || z[i]==';' );
269
- *pCchUTF8 = i+1;
270
- *pUtf32 = 0x301; /* A zero-width character */
271
- return;
269
+ }while( i<fossil_isdigit(z[i]) || z[i]==';' );
270
+ if( fossil_isalpha(z[i]) ){
271
+ *pCchUTF8 = i+1;
272
+ *pUtf32 = 0x301; /* A zero-width character */
273
+ return;
274
+ }
272275
}
273276
if( (c&0x80)==0x00 ){ /* 7-bit ASCII character. */
274277
*pCchUTF8 = 1;
275278
*pUtf32 = (int)z[0];
276279
return;
277280
--- src/comformat.c
+++ src/comformat.c
@@ -220,10 +220,11 @@
220 int maxChars, /* [in] Optimization hint to abort before space found. */
221 int *sumWidth /* [out] Summated width of all characters to next space. */
222 ){
223 int cchUTF8, utf32, wcwidth = 0;
224 int nextIndex = index;
 
225 for(;;){
226 char_info_utf8(&zLine[nextIndex],&cchUTF8,&utf32);
227 nextIndex += cchUTF8;
228 wcwidth += cli_wcwidth(utf32);
229 if( zLine[nextIndex]==0 || fossil_isspace(zLine[nextIndex]) ||
@@ -263,14 +264,16 @@
263 int maxUTF8 = 1; /* Expected sequence length. */
264 char c = z[i++];
265 if( c==0x1b && z[i]=='[' ){
266 do{
267 i++;
268 }while( fossil_isdigit(z[i]) || z[i]==';' );
269 *pCchUTF8 = i+1;
270 *pUtf32 = 0x301; /* A zero-width character */
271 return;
 
 
272 }
273 if( (c&0x80)==0x00 ){ /* 7-bit ASCII character. */
274 *pCchUTF8 = 1;
275 *pUtf32 = (int)z[0];
276 return;
277
--- src/comformat.c
+++ src/comformat.c
@@ -220,10 +220,11 @@
220 int maxChars, /* [in] Optimization hint to abort before space found. */
221 int *sumWidth /* [out] Summated width of all characters to next space. */
222 ){
223 int cchUTF8, utf32, wcwidth = 0;
224 int nextIndex = index;
225 if( zLine[index]==0 ) return index;
226 for(;;){
227 char_info_utf8(&zLine[nextIndex],&cchUTF8,&utf32);
228 nextIndex += cchUTF8;
229 wcwidth += cli_wcwidth(utf32);
230 if( zLine[nextIndex]==0 || fossil_isspace(zLine[nextIndex]) ||
@@ -263,14 +264,16 @@
264 int maxUTF8 = 1; /* Expected sequence length. */
265 char c = z[i++];
266 if( c==0x1b && z[i]=='[' ){
267 do{
268 i++;
269 }while( i<fossil_isdigit(z[i]) || z[i]==';' );
270 if( fossil_isalpha(z[i]) ){
271 *pCchUTF8 = i+1;
272 *pUtf32 = 0x301; /* A zero-width character */
273 return;
274 }
275 }
276 if( (c&0x80)==0x00 ){ /* 7-bit ASCII character. */
277 *pCchUTF8 = 1;
278 *pUtf32 = (int)z[0];
279 return;
280
+314 -36
--- src/dispatch.c
+++ src/dispatch.c
@@ -54,10 +54,11 @@
5454
/* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
5555
#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
5656
#define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
5757
#define CMDFLAG_ALIAS 0x2000 /* Command aliases */
5858
#define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
59
+#define CMDFLAG_ABBREVSUBCMD 0x8000 /* Help text abbreviates subcommands */
5960
/**************************************************************************/
6061
6162
/* Values for the 2nd parameter to dispatch_name_search() */
6263
#define CMDFLAG_ANY 0x0038 /* Match anything */
6364
#define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -522,13 +523,21 @@
522523
}
523524
524525
/*
525526
** Format help text for TTY display.
526527
*/
527
-static void help_to_text(const char *zHelp, Blob *pText){
528
+static void help_to_text(const char *zHelp, Blob *pText, int bUsage){
528529
int i, x;
529530
char c;
531
+ if( zHelp[0]=='>' ){
532
+ if( !bUsage ){
533
+ blob_appendf(pText, "Usage:");
534
+ }else{
535
+ blob_append_char(pText, ' ');
536
+ }
537
+ zHelp++;
538
+ }
530539
for(i=0; (c = zHelp[i])!=0; i++){
531540
if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){
532541
if( i>0 ) blob_append(pText, zHelp, i);
533542
blob_append(pText, "fossil", 6);
534543
zHelp += i+7;
@@ -603,11 +612,11 @@
603612
fossil_print("# %s\n", aCommand[bktHelp[aCommand[i].iHelp][j]].zName);
604613
fossil_print("%s\n\n", aCommand[i].zHelp);
605614
}else{
606615
Blob txt;
607616
blob_init(&txt, 0, 0);
608
- help_to_text(aCommand[i].zHelp, &txt);
617
+ help_to_text(aCommand[i].zHelp, &txt, 0);
609618
for(j=0; j<occHelp[aCommand[i].iHelp]; j++){
610619
fossil_print("# %s%s\n",
611620
aCommand[bktHelp[aCommand[i].iHelp][j]].zName,
612621
(aCommand[i].eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ?
613622
" (versionable)" : "");
@@ -855,11 +864,11 @@
855864
if( pCmd->zHelp[0]==0 ){
856865
@ No help available for "%h(pCmd->zName)"
857866
}else if( P("plaintext") ){
858867
Blob txt;
859868
blob_init(&txt, 0, 0);
860
- help_to_text(pCmd->zHelp, &txt);
869
+ help_to_text(pCmd->zHelp, &txt, 0);
861870
@ <pre class="helpPage">
862871
@ %h(blob_str(&txt))
863872
@ </pre>
864873
blob_reset(&txt);
865874
}else if( P("raw") ){
@@ -1059,10 +1068,229 @@
10591068
}
10601069
@ </dl>
10611070
blob_reset(&buf);
10621071
style_finish_page();
10631072
}
1073
+
1074
+/*
1075
+** Analyze p and return one of three values:
1076
+**
1077
+** 0 p is the continuation of a prior subcommand.
1078
+**
1079
+** 1 p is text past the end of a prior subcommand.
1080
+**
1081
+** 2 p is the start of a new subcommand.
1082
+*/
1083
+static int is_subcommand(Blob *p, int bAbbrevSubcmd){
1084
+ int i, sz;
1085
+ const unsigned char *z = (const unsigned char*)blob_buffer(p);
1086
+ sz = blob_size(p);
1087
+ if( sz>6 ) sz = 6;
1088
+ for(i=0; i<sz && fossil_isspace(z[i]); i++){}
1089
+ if( i>=sz ) return 0;
1090
+
1091
+ if( bAbbrevSubcmd==0 ){
1092
+ if( i>1 ) return 0;
1093
+ return z[0]=='>' ? 2 : 1;
1094
+ }else{
1095
+ return (i==3 && fossil_isalpha(z[3])) ? 2 : 1;
1096
+ }
1097
+}
1098
+
1099
+/*
1100
+** Input z[] is help text for zTopic. If zTopic has sub-command zSub,
1101
+** then cut out all portions of the original help text that do not
1102
+** directly pertain to zSub and write the zSub-relevant parts into
1103
+** pOut.
1104
+**
1105
+** Return the number of lines of z[] written into pOut. A return of
1106
+** zero means no simplification occurred.
1107
+*/
1108
+static int simplify_to_subtopic(
1109
+ const char *z, /* Full original help text */
1110
+ Blob *pOut, /* Write simplified help text here */
1111
+ const char *zTopic, /* TOPIC */
1112
+ const char *zSubtopic, /* SUBTOPIC */
1113
+ int bAbbrevSubcmd /* True if z[] contains abbreviated subcommands */
1114
+){
1115
+ Blob in, line; //, subsection;
1116
+ int n = 0;
1117
+ char *zQTop = re_quote(zTopic);
1118
+ char *zQSub = re_quote(zSubtopic);
1119
+ char *zPattern;
1120
+ ReCompiled *pRe = 0;
1121
+
1122
+ if( bAbbrevSubcmd ){
1123
+ zPattern = mprintf(" ([a-z]+ ?\\| ?)*%s\\b", zQSub);
1124
+ }else{
1125
+ zPattern = mprintf("> ?fossil [-a-z]+ .*\\b%s\\b", zQSub);
1126
+ }
1127
+ fossil_free(zQTop);
1128
+ fossil_free(zQSub);
1129
+ re_compile(&pRe, zPattern, 0);
1130
+ fossil_free(zPattern);
1131
+ blob_init(&in, z, -1);
1132
+ while( blob_line(&in, &line) ){
1133
+ if( re_match(pRe, (unsigned char*)blob_buffer(&line), blob_size(&line)) ){
1134
+ int atStart = 1;
1135
+ blob_appendb(pOut, &line);
1136
+ n++;
1137
+ while( blob_line(&in, &line) ){
1138
+ if( re_match(pRe,(unsigned char*)blob_buffer(&line),blob_size(&line)) ){
1139
+ blob_appendb(pOut, &line);
1140
+ n++;
1141
+ atStart = 1;
1142
+ }else{
1143
+ int x = is_subcommand(&line,bAbbrevSubcmd);
1144
+ if( x==2 ){
1145
+ if( atStart ){
1146
+ blob_appendb(pOut, &line);
1147
+ n++;
1148
+ }else{
1149
+ break;
1150
+ }
1151
+ }else if( x==1 ){
1152
+ break;
1153
+ }else{
1154
+ blob_appendb(pOut, &line);
1155
+ n++;
1156
+ atStart = 0;
1157
+ }
1158
+ }
1159
+ }
1160
+ }
1161
+ }
1162
+ blob_reset(&line);
1163
+ re_free(pRe);
1164
+ if( n ){
1165
+ blob_trim(pOut);
1166
+ blob_reset(&in);
1167
+ }
1168
+ return n;
1169
+}
1170
+
1171
+/*
1172
+** Input p is a "Usage:" line or a subcommand line. Simplify this line
1173
+** for the --usage option and write it into pOut.
1174
+*/
1175
+static void simplify_usage_line(
1176
+ Blob *p,
1177
+ Blob *pOut,
1178
+ int bAbbrevSubcmd,
1179
+ const char *zCmd
1180
+){
1181
+ const char *z = blob_buffer(p);
1182
+ int sz = blob_size(p);
1183
+ int i = 0;
1184
+ if( sz>6 && z[0]=='U' ){
1185
+ for(i=1; i<sz && !fossil_isspace(z[i]); i++){}
1186
+ }else if( sz>0 && z[0]=='>' ){
1187
+ i = 1;
1188
+ }else if( sz>4 && bAbbrevSubcmd
1189
+ && memcmp(z," ",3)==0 && !fossil_isspace(z[3]) ){
1190
+ int j;
1191
+ for(j=3; j<sz-1 && (z[j]!=' ' || z[j+1]!=' '); j++){}
1192
+ blob_appendf(pOut, "fossil %s %.*s\n", zCmd, j-3, &z[3]);
1193
+ return;
1194
+ }else{
1195
+ while( i<sz && fossil_isspace(z[i]) ) i++;
1196
+ if( i+2<sz && (z[i]=='o' || z[i]=='O') && z[i+1]=='r' ){
1197
+ while( i<sz && !fossil_isspace(z[i]) ) i++;
1198
+ }
1199
+ }
1200
+ while( i<sz && fossil_isspace(z[i]) ) i++;
1201
+ blob_append(pOut, &z[i], sz-i);
1202
+}
1203
+
1204
+/*
1205
+** Input z[] is help text for a command zTopic. Write into pOut all lines of
1206
+** z[] that show the command-line syntax for that command. Lines written
1207
+** to pOut are lines that begin with out of:
1208
+**
1209
+** Usage:
1210
+** or:
1211
+** > fossil TOPIC
1212
+**
1213
+** Return the number of lines written into pOut.
1214
+*/
1215
+static int simplify_to_usage(
1216
+ const char *z, /* Full original help text */
1217
+ Blob *pOut, /* Write simplified help text here */
1218
+ const char *zTopic, /* The command for which z[] is full help text */
1219
+ int bAbbrevSubcmd /* z[] uses abbreviated subcommands */
1220
+){
1221
+ ReCompiled *pRe = 0;
1222
+ Blob in, line;
1223
+ int n = 0;
1224
+
1225
+ if( bAbbrevSubcmd ){
1226
+ re_compile(&pRe, "^(Usage: | [a-z][-a-z|]+ .*)", 0);
1227
+ }else{
1228
+ re_compile(&pRe, "^(Usage: | *[Oo]r: +%fossi |> ?fossil )", 0);
1229
+ }
1230
+ blob_init(&in, z, -1);
1231
+ while( blob_line(&in, &line) ){
1232
+ if( re_match(pRe, (unsigned char*)blob_buffer(&line), blob_strlen(&line)) ){
1233
+ simplify_usage_line(&line, pOut, bAbbrevSubcmd, zTopic);
1234
+ n++;
1235
+ }
1236
+ }
1237
+ re_free(pRe);
1238
+ if( n ) blob_trim(pOut);
1239
+ return n;
1240
+}
1241
+
1242
+/*
1243
+** Input z[] is help text. Write into pOut all lines of z[] that show
1244
+** command-line options. Return the number of lines written.
1245
+*/
1246
+static int simplify_to_options(
1247
+ const char *z, /* Full original help text */
1248
+ Blob *pOut, /* Write simplified help text here */
1249
+ int bAbbrevSubcmd, /* z[] uses abbreviated subcommands */
1250
+ const char *zCmd /* Name of the command that z[] describes */
1251
+){
1252
+ ReCompiled *pRe = 0;
1253
+ Blob txt, line, subsection;
1254
+ int n = 0;
1255
+ int bSubsectionSeen = 0;
1256
+
1257
+ blob_init(&txt, z, -1);
1258
+ blob_init(&subsection, 0, 0);
1259
+ re_compile(&pRe, "^ +-.* ", 0);
1260
+ while( blob_line(&txt, &line) ){
1261
+ int len = blob_size(&line);
1262
+ unsigned char *zLine = (unsigned char *)blob_buffer(&line);
1263
+ if( re_match(pRe, zLine, len) ){
1264
+ if( blob_size(&subsection) ){
1265
+ simplify_usage_line(&subsection, pOut, bAbbrevSubcmd, zCmd);
1266
+ blob_reset(&subsection);
1267
+ }
1268
+ blob_appendb(pOut, &line);
1269
+ }else if( len>7 && !fossil_isspace(zLine[0]) && bSubsectionSeen
1270
+ && sqlite3_strlike("%options:%",blob_str(&line),0)==0 ){
1271
+ subsection = line;
1272
+ }else if( !bAbbrevSubcmd && len>9
1273
+ && (memcmp(zLine,"> fossil ",9)==0
1274
+ || memcmp(zLine,"> fossil",9)==0) ){
1275
+ subsection = line;
1276
+ bSubsectionSeen = 1;
1277
+ }else if( bAbbrevSubcmd && len>5 && memcmp(zLine," ",3)==0
1278
+ && fossil_isalpha(zLine[3]) ){
1279
+ subsection = line;
1280
+ bSubsectionSeen = 1;
1281
+ }else if( len>1 && !fossil_isspace(zLine[0]) && bSubsectionSeen ){
1282
+ blob_reset(&subsection);
1283
+ }
1284
+ }
1285
+ re_free(pRe);
1286
+ blob_trim(pOut);
1287
+ blob_reset(&subsection);
1288
+ return n;
1289
+}
1290
+
1291
+
10641292
10651293
static void multi_column_list(const char **azWord, int nWord){
10661294
int i, j, len;
10671295
int mxLen = 0;
10681296
int nCol;
@@ -1151,55 +1379,68 @@
11511379
;
11521380
11531381
/*
11541382
** COMMAND: help
11551383
**
1156
-** Usage: %fossil help [OPTIONS] [TOPIC]
1384
+** Usage: %fossil help [OPTIONS] [TOPIC] [SUBCOMMAND]
11571385
**
11581386
** Display information on how to use TOPIC, which may be a command, webpage, or
11591387
** setting. Webpage names begin with "/". If TOPIC is omitted, a list of
1160
-** topics is returned.
1388
+** topics is returned. If there is an extra argument after TOPIC, it is
1389
+** the name of a subcommand, in which case only the help text for that one
1390
+** subcommand is shown.
11611391
**
11621392
** The following options can be used when TOPIC is omitted:
11631393
**
11641394
** -a|--all List both common and auxiliary commands
1395
+** -e|--everything List all help on all topics
1396
+** -f|--full List full set of commands (including auxiliary
1397
+** and unsupported "test" commands), options,
1398
+** settings, and web pages
11651399
** -o|--options List command-line options common to all commands
11661400
** -s|--setting List setting names
11671401
** -t|--test List unsupported "test" commands
11681402
** -v|--verbose List both names and help text
11691403
** -x|--aux List only auxiliary commands
11701404
** -w|--www List all web pages
1171
-** -f|--full List full set of commands (including auxiliary
1172
-** and unsupported "test" commands), options,
1173
-** settings, and web pages
1174
-** -e|--everything List all help on all topics
11751405
**
11761406
** These options can be used when TOPIC is present:
11771407
**
1178
-** -h|--html Format output as HTML rather than plain text
11791408
** -c|--commands Restrict TOPIC search to commands
1409
+** -h|--html Format output as HTML rather than plain text
1410
+** -o|--options Show command-line options for TOPIC
1411
+** --raw Output raw, unformatted help text
1412
+** -u|--usage Show a succinct usage summary, not full help text
1413
+**
1414
+** See also: [[usage]], [[options]], [[search]] with the -h option
11801415
*/
11811416
void help_cmd(void){
11821417
int rc;
1183
- int mask = CMDFLAG_ANY;
1184
- int isPage = 0;
1185
- int verboseFlag = 0;
1186
- int commandsFlag = 0;
1187
- const char *z;
1188
- const char *zCmdOrPage;
1189
- const CmdOrPage *pCmd = 0;
1190
- int useHtml = 0;
1191
- const char *zTopic;
1192
- Blob txt;
1418
+ int mask = CMDFLAG_ANY; /* Mask of help topic types */
1419
+ int isPage = 0; /* True if TOPIC is a page */
1420
+ int verboseFlag = 0; /* -v option */
1421
+ int commandsFlag = 0; /* -c option */
1422
+ const char *z; /* Original, untranslated help text */
1423
+ const char *zCmdOrPage; /* "command" or "page" or "setting" */
1424
+ const CmdOrPage *pCmd = 0; /* ptr to aCommand[] entry for TOPIC */
1425
+ int useHtml = 0; /* -h option */
1426
+ int bUsage; /* --usage */
1427
+ int bRaw; /* --raw option */
1428
+ int bOptions; /* --options */
1429
+ const char *zTopic; /* TOPIC argument */
1430
+ const char *zSubtopic = 0; /* SUBTOPIC argument */
1431
+ Blob subtext1, subtext2, s3; /* Subsets of z[] containing subtopic/usage */
1432
+ Blob txt; /* Text after rendering */
1433
+ int bAbbrevSubcmd = 0; /* Help text uses abbreviated subcommands */
1434
+
11931435
verboseFlag = find_option("verbose","v",0)!=0;
11941436
commandsFlag = find_option("commands","c",0)!=0;
11951437
useHtml = find_option("html","h",0)!=0;
1196
- if( find_option("options","o",0) ){
1197
- fossil_print("%s", zOptions);
1198
- return;
1199
- }
1200
- else if( find_option("all","a",0) ){
1438
+ bRaw = find_option("raw",0,0)!=0;
1439
+ bOptions = find_option("options","o",0)!=0;
1440
+ bUsage = find_option("usage","u",0)!=0;
1441
+ if( find_option("all","a",0) ){
12011442
command_list(CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER, verboseFlag, useHtml);
12021443
return;
12031444
}
12041445
else if( find_option("www","w",0) ){
12051446
command_list(CMDFLAG_WEBPAGE, verboseFlag, useHtml);
@@ -1238,23 +1479,32 @@
12381479
CMDFLAG_SETTING | CMDFLAG_TEST, useHtml, 0);
12391480
return;
12401481
}
12411482
verify_all_options();
12421483
if( g.argc<3 ){
1484
+ if( bOptions ){
1485
+ fossil_print("%s", zOptions);
1486
+ return;
1487
+ }
12431488
z = g.argv[0];
12441489
fossil_print(
12451490
"Usage: %s help TOPIC\n"
1246
- "Try \"%s help help\" or \"%s help -a\" for more options\n"
1247
- "Frequently used commands:\n",
1248
- z, z, z);
1491
+ "Things to try:\n\n"
1492
+ " %s help help\n"
1493
+ " %s help -o\n"
1494
+ " %s help -a\n"
1495
+ " %s search -h TOPIC\n\n"
1496
+ "Other common values for TOPIC:\n\n",
1497
+ z, z, z, z, z);
12491498
command_list(CMDFLAG_1ST_TIER,verboseFlag,useHtml);
12501499
if( !verboseFlag ) version_cmd();
12511500
return;
12521501
}
12531502
zTopic = g.argv[2];
1503
+ zSubtopic = g.argc>=4 ? g.argv[3] : 0;
12541504
isPage = ('/' == zTopic[0]) ? 1 : 0;
1255
- if(isPage){
1505
+ if( isPage ){
12561506
zCmdOrPage = "page";
12571507
}else if( commandsFlag ){
12581508
mask = CMDFLAG_COMMAND;
12591509
zCmdOrPage = "command";
12601510
}else{
@@ -1273,24 +1523,48 @@
12731523
fossil_print("Did you mean one of these TOPICs:\n");
12741524
n = dispatch_approx_match(g.argv[2], 5, az);
12751525
for(i=0; i<n; i++){
12761526
fossil_print(" * %s\n", az[i]);
12771527
}
1278
- fossil_print("Also consider using:\n");
1528
+ fossil_print("Other commands to try:\n");
12791529
fossil_print(" fossil search -h PATTERN ;# search all help text\n");
12801530
fossil_print(" fossil help -a ;# show all commands\n");
12811531
fossil_print(" fossil help -w ;# show all web-pages\n");
12821532
fossil_print(" fossil help -s ;# show all settings\n");
12831533
fossil_print(" fossil help -o ;# show global options\n");
1284
- fossil_exit(1);
1534
+ return;
12851535
}
1536
+ bAbbrevSubcmd = (pCmd->eCmdFlags & CMDFLAG_ABBREVSUBCMD)!=0;
12861537
z = pCmd->zHelp;
12871538
if( z==0 ){
12881539
fossil_fatal("no help available for the %s %s",
12891540
pCmd->zName, zCmdOrPage);
12901541
}
1291
- if( pCmd->eCmdFlags & CMDFLAG_SETTING ){
1542
+ blob_init(&subtext1, 0, 0);
1543
+ blob_init(&subtext2, 0, 0);
1544
+ blob_init(&s3, 0, 0);
1545
+ if( zSubtopic!=0 ){
1546
+ if( simplify_to_subtopic(z, &subtext1, zTopic, zSubtopic, bAbbrevSubcmd) ){
1547
+ z = blob_str(&subtext1);
1548
+ }else{
1549
+ fossil_print("No subtopic \"%s\" for \"%s\".\n", zSubtopic, zTopic);
1550
+ bUsage = 1;
1551
+ zSubtopic = 0;
1552
+ }
1553
+ }
1554
+ if( bUsage ){
1555
+ if( simplify_to_usage(z, &subtext2, zTopic, bAbbrevSubcmd) ){
1556
+ z = blob_str(&subtext2);
1557
+ }else{
1558
+ bUsage = 0;
1559
+ }
1560
+ }
1561
+ if( bOptions ){
1562
+ simplify_to_options(z, &s3, bAbbrevSubcmd, zTopic);
1563
+ z = blob_str(&s3);
1564
+ }
1565
+ if( pCmd && pCmd->eCmdFlags & CMDFLAG_SETTING ){
12921566
const Setting *pSetting = db_find_setting(pCmd->zName, 0);
12931567
char *zDflt = 0;
12941568
if( pSetting!=0 && pSetting->def!=0 && *pSetting->def!=0 ){
12951569
zDflt = mprintf(" (default: %s)", pSetting->def);
12961570
}
@@ -1299,17 +1573,21 @@
12991573
(pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : ""
13001574
);
13011575
fossil_free(zDflt);
13021576
}
13031577
blob_init(&txt, 0, 0);
1304
- if( useHtml ){
1578
+ if( bRaw ){
1579
+ blob_append(&txt, z, -1);
1580
+ }else if( useHtml ){
13051581
help_to_html(z, &txt);
13061582
}else{
1307
- help_to_text(z, &txt);
1583
+ help_to_text(z, &txt, bUsage || zSubtopic!=0);
13081584
}
1309
- fossil_print("%s\n", blob_str(&txt));
1585
+ if( blob_strlen(&txt)>0 ) fossil_print("%s\n", blob_str(&txt));
13101586
blob_reset(&txt);
1587
+ blob_reset(&subtext1);
1588
+ blob_reset(&subtext2);
13111589
}
13121590
13131591
/*
13141592
** Return a pointer to the setting information array.
13151593
**
@@ -1481,11 +1759,11 @@
14811759
sqlite3_result_text(ctx, pPage->zHelp, -1, SQLITE_STATIC);
14821760
break;
14831761
case 4: { /* formatted */
14841762
Blob txt;
14851763
blob_init(&txt, 0, 0);
1486
- help_to_text(pPage->zHelp, &txt);
1764
+ help_to_text(pPage->zHelp, &txt, 0);
14871765
sqlite3_result_text(ctx, blob_str(&txt), -1, fossil_free);
14881766
break;
14891767
}
14901768
case 5: { /* formatted */
14911769
Blob txt;
14921770
--- src/dispatch.c
+++ src/dispatch.c
@@ -54,10 +54,11 @@
54 /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
55 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
56 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
57 #define CMDFLAG_ALIAS 0x2000 /* Command aliases */
58 #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
 
59 /**************************************************************************/
60
61 /* Values for the 2nd parameter to dispatch_name_search() */
62 #define CMDFLAG_ANY 0x0038 /* Match anything */
63 #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -522,13 +523,21 @@
522 }
523
524 /*
525 ** Format help text for TTY display.
526 */
527 static void help_to_text(const char *zHelp, Blob *pText){
528 int i, x;
529 char c;
 
 
 
 
 
 
 
 
530 for(i=0; (c = zHelp[i])!=0; i++){
531 if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){
532 if( i>0 ) blob_append(pText, zHelp, i);
533 blob_append(pText, "fossil", 6);
534 zHelp += i+7;
@@ -603,11 +612,11 @@
603 fossil_print("# %s\n", aCommand[bktHelp[aCommand[i].iHelp][j]].zName);
604 fossil_print("%s\n\n", aCommand[i].zHelp);
605 }else{
606 Blob txt;
607 blob_init(&txt, 0, 0);
608 help_to_text(aCommand[i].zHelp, &txt);
609 for(j=0; j<occHelp[aCommand[i].iHelp]; j++){
610 fossil_print("# %s%s\n",
611 aCommand[bktHelp[aCommand[i].iHelp][j]].zName,
612 (aCommand[i].eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ?
613 " (versionable)" : "");
@@ -855,11 +864,11 @@
855 if( pCmd->zHelp[0]==0 ){
856 @ No help available for "%h(pCmd->zName)"
857 }else if( P("plaintext") ){
858 Blob txt;
859 blob_init(&txt, 0, 0);
860 help_to_text(pCmd->zHelp, &txt);
861 @ <pre class="helpPage">
862 @ %h(blob_str(&txt))
863 @ </pre>
864 blob_reset(&txt);
865 }else if( P("raw") ){
@@ -1059,10 +1068,229 @@
1059 }
1060 @ </dl>
1061 blob_reset(&buf);
1062 style_finish_page();
1063 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1064
1065 static void multi_column_list(const char **azWord, int nWord){
1066 int i, j, len;
1067 int mxLen = 0;
1068 int nCol;
@@ -1151,55 +1379,68 @@
1151 ;
1152
1153 /*
1154 ** COMMAND: help
1155 **
1156 ** Usage: %fossil help [OPTIONS] [TOPIC]
1157 **
1158 ** Display information on how to use TOPIC, which may be a command, webpage, or
1159 ** setting. Webpage names begin with "/". If TOPIC is omitted, a list of
1160 ** topics is returned.
 
 
1161 **
1162 ** The following options can be used when TOPIC is omitted:
1163 **
1164 ** -a|--all List both common and auxiliary commands
 
 
 
 
1165 ** -o|--options List command-line options common to all commands
1166 ** -s|--setting List setting names
1167 ** -t|--test List unsupported "test" commands
1168 ** -v|--verbose List both names and help text
1169 ** -x|--aux List only auxiliary commands
1170 ** -w|--www List all web pages
1171 ** -f|--full List full set of commands (including auxiliary
1172 ** and unsupported "test" commands), options,
1173 ** settings, and web pages
1174 ** -e|--everything List all help on all topics
1175 **
1176 ** These options can be used when TOPIC is present:
1177 **
1178 ** -h|--html Format output as HTML rather than plain text
1179 ** -c|--commands Restrict TOPIC search to commands
 
 
 
 
 
 
1180 */
1181 void help_cmd(void){
1182 int rc;
1183 int mask = CMDFLAG_ANY;
1184 int isPage = 0;
1185 int verboseFlag = 0;
1186 int commandsFlag = 0;
1187 const char *z;
1188 const char *zCmdOrPage;
1189 const CmdOrPage *pCmd = 0;
1190 int useHtml = 0;
1191 const char *zTopic;
1192 Blob txt;
 
 
 
 
 
 
 
1193 verboseFlag = find_option("verbose","v",0)!=0;
1194 commandsFlag = find_option("commands","c",0)!=0;
1195 useHtml = find_option("html","h",0)!=0;
1196 if( find_option("options","o",0) ){
1197 fossil_print("%s", zOptions);
1198 return;
1199 }
1200 else if( find_option("all","a",0) ){
1201 command_list(CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER, verboseFlag, useHtml);
1202 return;
1203 }
1204 else if( find_option("www","w",0) ){
1205 command_list(CMDFLAG_WEBPAGE, verboseFlag, useHtml);
@@ -1238,23 +1479,32 @@
1238 CMDFLAG_SETTING | CMDFLAG_TEST, useHtml, 0);
1239 return;
1240 }
1241 verify_all_options();
1242 if( g.argc<3 ){
 
 
 
 
1243 z = g.argv[0];
1244 fossil_print(
1245 "Usage: %s help TOPIC\n"
1246 "Try \"%s help help\" or \"%s help -a\" for more options\n"
1247 "Frequently used commands:\n",
1248 z, z, z);
 
 
 
 
1249 command_list(CMDFLAG_1ST_TIER,verboseFlag,useHtml);
1250 if( !verboseFlag ) version_cmd();
1251 return;
1252 }
1253 zTopic = g.argv[2];
 
1254 isPage = ('/' == zTopic[0]) ? 1 : 0;
1255 if(isPage){
1256 zCmdOrPage = "page";
1257 }else if( commandsFlag ){
1258 mask = CMDFLAG_COMMAND;
1259 zCmdOrPage = "command";
1260 }else{
@@ -1273,24 +1523,48 @@
1273 fossil_print("Did you mean one of these TOPICs:\n");
1274 n = dispatch_approx_match(g.argv[2], 5, az);
1275 for(i=0; i<n; i++){
1276 fossil_print(" * %s\n", az[i]);
1277 }
1278 fossil_print("Also consider using:\n");
1279 fossil_print(" fossil search -h PATTERN ;# search all help text\n");
1280 fossil_print(" fossil help -a ;# show all commands\n");
1281 fossil_print(" fossil help -w ;# show all web-pages\n");
1282 fossil_print(" fossil help -s ;# show all settings\n");
1283 fossil_print(" fossil help -o ;# show global options\n");
1284 fossil_exit(1);
1285 }
 
1286 z = pCmd->zHelp;
1287 if( z==0 ){
1288 fossil_fatal("no help available for the %s %s",
1289 pCmd->zName, zCmdOrPage);
1290 }
1291 if( pCmd->eCmdFlags & CMDFLAG_SETTING ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1292 const Setting *pSetting = db_find_setting(pCmd->zName, 0);
1293 char *zDflt = 0;
1294 if( pSetting!=0 && pSetting->def!=0 && *pSetting->def!=0 ){
1295 zDflt = mprintf(" (default: %s)", pSetting->def);
1296 }
@@ -1299,17 +1573,21 @@
1299 (pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : ""
1300 );
1301 fossil_free(zDflt);
1302 }
1303 blob_init(&txt, 0, 0);
1304 if( useHtml ){
 
 
1305 help_to_html(z, &txt);
1306 }else{
1307 help_to_text(z, &txt);
1308 }
1309 fossil_print("%s\n", blob_str(&txt));
1310 blob_reset(&txt);
 
 
1311 }
1312
1313 /*
1314 ** Return a pointer to the setting information array.
1315 **
@@ -1481,11 +1759,11 @@
1481 sqlite3_result_text(ctx, pPage->zHelp, -1, SQLITE_STATIC);
1482 break;
1483 case 4: { /* formatted */
1484 Blob txt;
1485 blob_init(&txt, 0, 0);
1486 help_to_text(pPage->zHelp, &txt);
1487 sqlite3_result_text(ctx, blob_str(&txt), -1, fossil_free);
1488 break;
1489 }
1490 case 5: { /* formatted */
1491 Blob txt;
1492
--- src/dispatch.c
+++ src/dispatch.c
@@ -54,10 +54,11 @@
54 /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */
55 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
56 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
57 #define CMDFLAG_ALIAS 0x2000 /* Command aliases */
58 #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
59 #define CMDFLAG_ABBREVSUBCMD 0x8000 /* Help text abbreviates subcommands */
60 /**************************************************************************/
61
62 /* Values for the 2nd parameter to dispatch_name_search() */
63 #define CMDFLAG_ANY 0x0038 /* Match anything */
64 #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */
@@ -522,13 +523,21 @@
523 }
524
525 /*
526 ** Format help text for TTY display.
527 */
528 static void help_to_text(const char *zHelp, Blob *pText, int bUsage){
529 int i, x;
530 char c;
531 if( zHelp[0]=='>' ){
532 if( !bUsage ){
533 blob_appendf(pText, "Usage:");
534 }else{
535 blob_append_char(pText, ' ');
536 }
537 zHelp++;
538 }
539 for(i=0; (c = zHelp[i])!=0; i++){
540 if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){
541 if( i>0 ) blob_append(pText, zHelp, i);
542 blob_append(pText, "fossil", 6);
543 zHelp += i+7;
@@ -603,11 +612,11 @@
612 fossil_print("# %s\n", aCommand[bktHelp[aCommand[i].iHelp][j]].zName);
613 fossil_print("%s\n\n", aCommand[i].zHelp);
614 }else{
615 Blob txt;
616 blob_init(&txt, 0, 0);
617 help_to_text(aCommand[i].zHelp, &txt, 0);
618 for(j=0; j<occHelp[aCommand[i].iHelp]; j++){
619 fossil_print("# %s%s\n",
620 aCommand[bktHelp[aCommand[i].iHelp][j]].zName,
621 (aCommand[i].eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ?
622 " (versionable)" : "");
@@ -855,11 +864,11 @@
864 if( pCmd->zHelp[0]==0 ){
865 @ No help available for "%h(pCmd->zName)"
866 }else if( P("plaintext") ){
867 Blob txt;
868 blob_init(&txt, 0, 0);
869 help_to_text(pCmd->zHelp, &txt, 0);
870 @ <pre class="helpPage">
871 @ %h(blob_str(&txt))
872 @ </pre>
873 blob_reset(&txt);
874 }else if( P("raw") ){
@@ -1059,10 +1068,229 @@
1068 }
1069 @ </dl>
1070 blob_reset(&buf);
1071 style_finish_page();
1072 }
1073
1074 /*
1075 ** Analyze p and return one of three values:
1076 **
1077 ** 0 p is the continuation of a prior subcommand.
1078 **
1079 ** 1 p is text past the end of a prior subcommand.
1080 **
1081 ** 2 p is the start of a new subcommand.
1082 */
1083 static int is_subcommand(Blob *p, int bAbbrevSubcmd){
1084 int i, sz;
1085 const unsigned char *z = (const unsigned char*)blob_buffer(p);
1086 sz = blob_size(p);
1087 if( sz>6 ) sz = 6;
1088 for(i=0; i<sz && fossil_isspace(z[i]); i++){}
1089 if( i>=sz ) return 0;
1090
1091 if( bAbbrevSubcmd==0 ){
1092 if( i>1 ) return 0;
1093 return z[0]=='>' ? 2 : 1;
1094 }else{
1095 return (i==3 && fossil_isalpha(z[3])) ? 2 : 1;
1096 }
1097 }
1098
1099 /*
1100 ** Input z[] is help text for zTopic. If zTopic has sub-command zSub,
1101 ** then cut out all portions of the original help text that do not
1102 ** directly pertain to zSub and write the zSub-relevant parts into
1103 ** pOut.
1104 **
1105 ** Return the number of lines of z[] written into pOut. A return of
1106 ** zero means no simplification occurred.
1107 */
1108 static int simplify_to_subtopic(
1109 const char *z, /* Full original help text */
1110 Blob *pOut, /* Write simplified help text here */
1111 const char *zTopic, /* TOPIC */
1112 const char *zSubtopic, /* SUBTOPIC */
1113 int bAbbrevSubcmd /* True if z[] contains abbreviated subcommands */
1114 ){
1115 Blob in, line; //, subsection;
1116 int n = 0;
1117 char *zQTop = re_quote(zTopic);
1118 char *zQSub = re_quote(zSubtopic);
1119 char *zPattern;
1120 ReCompiled *pRe = 0;
1121
1122 if( bAbbrevSubcmd ){
1123 zPattern = mprintf(" ([a-z]+ ?\\| ?)*%s\\b", zQSub);
1124 }else{
1125 zPattern = mprintf("> ?fossil [-a-z]+ .*\\b%s\\b", zQSub);
1126 }
1127 fossil_free(zQTop);
1128 fossil_free(zQSub);
1129 re_compile(&pRe, zPattern, 0);
1130 fossil_free(zPattern);
1131 blob_init(&in, z, -1);
1132 while( blob_line(&in, &line) ){
1133 if( re_match(pRe, (unsigned char*)blob_buffer(&line), blob_size(&line)) ){
1134 int atStart = 1;
1135 blob_appendb(pOut, &line);
1136 n++;
1137 while( blob_line(&in, &line) ){
1138 if( re_match(pRe,(unsigned char*)blob_buffer(&line),blob_size(&line)) ){
1139 blob_appendb(pOut, &line);
1140 n++;
1141 atStart = 1;
1142 }else{
1143 int x = is_subcommand(&line,bAbbrevSubcmd);
1144 if( x==2 ){
1145 if( atStart ){
1146 blob_appendb(pOut, &line);
1147 n++;
1148 }else{
1149 break;
1150 }
1151 }else if( x==1 ){
1152 break;
1153 }else{
1154 blob_appendb(pOut, &line);
1155 n++;
1156 atStart = 0;
1157 }
1158 }
1159 }
1160 }
1161 }
1162 blob_reset(&line);
1163 re_free(pRe);
1164 if( n ){
1165 blob_trim(pOut);
1166 blob_reset(&in);
1167 }
1168 return n;
1169 }
1170
1171 /*
1172 ** Input p is a "Usage:" line or a subcommand line. Simplify this line
1173 ** for the --usage option and write it into pOut.
1174 */
1175 static void simplify_usage_line(
1176 Blob *p,
1177 Blob *pOut,
1178 int bAbbrevSubcmd,
1179 const char *zCmd
1180 ){
1181 const char *z = blob_buffer(p);
1182 int sz = blob_size(p);
1183 int i = 0;
1184 if( sz>6 && z[0]=='U' ){
1185 for(i=1; i<sz && !fossil_isspace(z[i]); i++){}
1186 }else if( sz>0 && z[0]=='>' ){
1187 i = 1;
1188 }else if( sz>4 && bAbbrevSubcmd
1189 && memcmp(z," ",3)==0 && !fossil_isspace(z[3]) ){
1190 int j;
1191 for(j=3; j<sz-1 && (z[j]!=' ' || z[j+1]!=' '); j++){}
1192 blob_appendf(pOut, "fossil %s %.*s\n", zCmd, j-3, &z[3]);
1193 return;
1194 }else{
1195 while( i<sz && fossil_isspace(z[i]) ) i++;
1196 if( i+2<sz && (z[i]=='o' || z[i]=='O') && z[i+1]=='r' ){
1197 while( i<sz && !fossil_isspace(z[i]) ) i++;
1198 }
1199 }
1200 while( i<sz && fossil_isspace(z[i]) ) i++;
1201 blob_append(pOut, &z[i], sz-i);
1202 }
1203
1204 /*
1205 ** Input z[] is help text for a command zTopic. Write into pOut all lines of
1206 ** z[] that show the command-line syntax for that command. Lines written
1207 ** to pOut are lines that begin with out of:
1208 **
1209 ** Usage:
1210 ** or:
1211 ** > fossil TOPIC
1212 **
1213 ** Return the number of lines written into pOut.
1214 */
1215 static int simplify_to_usage(
1216 const char *z, /* Full original help text */
1217 Blob *pOut, /* Write simplified help text here */
1218 const char *zTopic, /* The command for which z[] is full help text */
1219 int bAbbrevSubcmd /* z[] uses abbreviated subcommands */
1220 ){
1221 ReCompiled *pRe = 0;
1222 Blob in, line;
1223 int n = 0;
1224
1225 if( bAbbrevSubcmd ){
1226 re_compile(&pRe, "^(Usage: | [a-z][-a-z|]+ .*)", 0);
1227 }else{
1228 re_compile(&pRe, "^(Usage: | *[Oo]r: +%fossi |> ?fossil )", 0);
1229 }
1230 blob_init(&in, z, -1);
1231 while( blob_line(&in, &line) ){
1232 if( re_match(pRe, (unsigned char*)blob_buffer(&line), blob_strlen(&line)) ){
1233 simplify_usage_line(&line, pOut, bAbbrevSubcmd, zTopic);
1234 n++;
1235 }
1236 }
1237 re_free(pRe);
1238 if( n ) blob_trim(pOut);
1239 return n;
1240 }
1241
1242 /*
1243 ** Input z[] is help text. Write into pOut all lines of z[] that show
1244 ** command-line options. Return the number of lines written.
1245 */
1246 static int simplify_to_options(
1247 const char *z, /* Full original help text */
1248 Blob *pOut, /* Write simplified help text here */
1249 int bAbbrevSubcmd, /* z[] uses abbreviated subcommands */
1250 const char *zCmd /* Name of the command that z[] describes */
1251 ){
1252 ReCompiled *pRe = 0;
1253 Blob txt, line, subsection;
1254 int n = 0;
1255 int bSubsectionSeen = 0;
1256
1257 blob_init(&txt, z, -1);
1258 blob_init(&subsection, 0, 0);
1259 re_compile(&pRe, "^ +-.* ", 0);
1260 while( blob_line(&txt, &line) ){
1261 int len = blob_size(&line);
1262 unsigned char *zLine = (unsigned char *)blob_buffer(&line);
1263 if( re_match(pRe, zLine, len) ){
1264 if( blob_size(&subsection) ){
1265 simplify_usage_line(&subsection, pOut, bAbbrevSubcmd, zCmd);
1266 blob_reset(&subsection);
1267 }
1268 blob_appendb(pOut, &line);
1269 }else if( len>7 && !fossil_isspace(zLine[0]) && bSubsectionSeen
1270 && sqlite3_strlike("%options:%",blob_str(&line),0)==0 ){
1271 subsection = line;
1272 }else if( !bAbbrevSubcmd && len>9
1273 && (memcmp(zLine,"> fossil ",9)==0
1274 || memcmp(zLine,"> fossil",9)==0) ){
1275 subsection = line;
1276 bSubsectionSeen = 1;
1277 }else if( bAbbrevSubcmd && len>5 && memcmp(zLine," ",3)==0
1278 && fossil_isalpha(zLine[3]) ){
1279 subsection = line;
1280 bSubsectionSeen = 1;
1281 }else if( len>1 && !fossil_isspace(zLine[0]) && bSubsectionSeen ){
1282 blob_reset(&subsection);
1283 }
1284 }
1285 re_free(pRe);
1286 blob_trim(pOut);
1287 blob_reset(&subsection);
1288 return n;
1289 }
1290
1291
1292
1293 static void multi_column_list(const char **azWord, int nWord){
1294 int i, j, len;
1295 int mxLen = 0;
1296 int nCol;
@@ -1151,55 +1379,68 @@
1379 ;
1380
1381 /*
1382 ** COMMAND: help
1383 **
1384 ** Usage: %fossil help [OPTIONS] [TOPIC] [SUBCOMMAND]
1385 **
1386 ** Display information on how to use TOPIC, which may be a command, webpage, or
1387 ** setting. Webpage names begin with "/". If TOPIC is omitted, a list of
1388 ** topics is returned. If there is an extra argument after TOPIC, it is
1389 ** the name of a subcommand, in which case only the help text for that one
1390 ** subcommand is shown.
1391 **
1392 ** The following options can be used when TOPIC is omitted:
1393 **
1394 ** -a|--all List both common and auxiliary commands
1395 ** -e|--everything List all help on all topics
1396 ** -f|--full List full set of commands (including auxiliary
1397 ** and unsupported "test" commands), options,
1398 ** settings, and web pages
1399 ** -o|--options List command-line options common to all commands
1400 ** -s|--setting List setting names
1401 ** -t|--test List unsupported "test" commands
1402 ** -v|--verbose List both names and help text
1403 ** -x|--aux List only auxiliary commands
1404 ** -w|--www List all web pages
 
 
 
 
1405 **
1406 ** These options can be used when TOPIC is present:
1407 **
 
1408 ** -c|--commands Restrict TOPIC search to commands
1409 ** -h|--html Format output as HTML rather than plain text
1410 ** -o|--options Show command-line options for TOPIC
1411 ** --raw Output raw, unformatted help text
1412 ** -u|--usage Show a succinct usage summary, not full help text
1413 **
1414 ** See also: [[usage]], [[options]], [[search]] with the -h option
1415 */
1416 void help_cmd(void){
1417 int rc;
1418 int mask = CMDFLAG_ANY; /* Mask of help topic types */
1419 int isPage = 0; /* True if TOPIC is a page */
1420 int verboseFlag = 0; /* -v option */
1421 int commandsFlag = 0; /* -c option */
1422 const char *z; /* Original, untranslated help text */
1423 const char *zCmdOrPage; /* "command" or "page" or "setting" */
1424 const CmdOrPage *pCmd = 0; /* ptr to aCommand[] entry for TOPIC */
1425 int useHtml = 0; /* -h option */
1426 int bUsage; /* --usage */
1427 int bRaw; /* --raw option */
1428 int bOptions; /* --options */
1429 const char *zTopic; /* TOPIC argument */
1430 const char *zSubtopic = 0; /* SUBTOPIC argument */
1431 Blob subtext1, subtext2, s3; /* Subsets of z[] containing subtopic/usage */
1432 Blob txt; /* Text after rendering */
1433 int bAbbrevSubcmd = 0; /* Help text uses abbreviated subcommands */
1434
1435 verboseFlag = find_option("verbose","v",0)!=0;
1436 commandsFlag = find_option("commands","c",0)!=0;
1437 useHtml = find_option("html","h",0)!=0;
1438 bRaw = find_option("raw",0,0)!=0;
1439 bOptions = find_option("options","o",0)!=0;
1440 bUsage = find_option("usage","u",0)!=0;
1441 if( find_option("all","a",0) ){
 
1442 command_list(CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER, verboseFlag, useHtml);
1443 return;
1444 }
1445 else if( find_option("www","w",0) ){
1446 command_list(CMDFLAG_WEBPAGE, verboseFlag, useHtml);
@@ -1238,23 +1479,32 @@
1479 CMDFLAG_SETTING | CMDFLAG_TEST, useHtml, 0);
1480 return;
1481 }
1482 verify_all_options();
1483 if( g.argc<3 ){
1484 if( bOptions ){
1485 fossil_print("%s", zOptions);
1486 return;
1487 }
1488 z = g.argv[0];
1489 fossil_print(
1490 "Usage: %s help TOPIC\n"
1491 "Things to try:\n\n"
1492 " %s help help\n"
1493 " %s help -o\n"
1494 " %s help -a\n"
1495 " %s search -h TOPIC\n\n"
1496 "Other common values for TOPIC:\n\n",
1497 z, z, z, z, z);
1498 command_list(CMDFLAG_1ST_TIER,verboseFlag,useHtml);
1499 if( !verboseFlag ) version_cmd();
1500 return;
1501 }
1502 zTopic = g.argv[2];
1503 zSubtopic = g.argc>=4 ? g.argv[3] : 0;
1504 isPage = ('/' == zTopic[0]) ? 1 : 0;
1505 if( isPage ){
1506 zCmdOrPage = "page";
1507 }else if( commandsFlag ){
1508 mask = CMDFLAG_COMMAND;
1509 zCmdOrPage = "command";
1510 }else{
@@ -1273,24 +1523,48 @@
1523 fossil_print("Did you mean one of these TOPICs:\n");
1524 n = dispatch_approx_match(g.argv[2], 5, az);
1525 for(i=0; i<n; i++){
1526 fossil_print(" * %s\n", az[i]);
1527 }
1528 fossil_print("Other commands to try:\n");
1529 fossil_print(" fossil search -h PATTERN ;# search all help text\n");
1530 fossil_print(" fossil help -a ;# show all commands\n");
1531 fossil_print(" fossil help -w ;# show all web-pages\n");
1532 fossil_print(" fossil help -s ;# show all settings\n");
1533 fossil_print(" fossil help -o ;# show global options\n");
1534 return;
1535 }
1536 bAbbrevSubcmd = (pCmd->eCmdFlags & CMDFLAG_ABBREVSUBCMD)!=0;
1537 z = pCmd->zHelp;
1538 if( z==0 ){
1539 fossil_fatal("no help available for the %s %s",
1540 pCmd->zName, zCmdOrPage);
1541 }
1542 blob_init(&subtext1, 0, 0);
1543 blob_init(&subtext2, 0, 0);
1544 blob_init(&s3, 0, 0);
1545 if( zSubtopic!=0 ){
1546 if( simplify_to_subtopic(z, &subtext1, zTopic, zSubtopic, bAbbrevSubcmd) ){
1547 z = blob_str(&subtext1);
1548 }else{
1549 fossil_print("No subtopic \"%s\" for \"%s\".\n", zSubtopic, zTopic);
1550 bUsage = 1;
1551 zSubtopic = 0;
1552 }
1553 }
1554 if( bUsage ){
1555 if( simplify_to_usage(z, &subtext2, zTopic, bAbbrevSubcmd) ){
1556 z = blob_str(&subtext2);
1557 }else{
1558 bUsage = 0;
1559 }
1560 }
1561 if( bOptions ){
1562 simplify_to_options(z, &s3, bAbbrevSubcmd, zTopic);
1563 z = blob_str(&s3);
1564 }
1565 if( pCmd && pCmd->eCmdFlags & CMDFLAG_SETTING ){
1566 const Setting *pSetting = db_find_setting(pCmd->zName, 0);
1567 char *zDflt = 0;
1568 if( pSetting!=0 && pSetting->def!=0 && *pSetting->def!=0 ){
1569 zDflt = mprintf(" (default: %s)", pSetting->def);
1570 }
@@ -1299,17 +1573,21 @@
1573 (pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : ""
1574 );
1575 fossil_free(zDflt);
1576 }
1577 blob_init(&txt, 0, 0);
1578 if( bRaw ){
1579 blob_append(&txt, z, -1);
1580 }else if( useHtml ){
1581 help_to_html(z, &txt);
1582 }else{
1583 help_to_text(z, &txt, bUsage || zSubtopic!=0);
1584 }
1585 if( blob_strlen(&txt)>0 ) fossil_print("%s\n", blob_str(&txt));
1586 blob_reset(&txt);
1587 blob_reset(&subtext1);
1588 blob_reset(&subtext2);
1589 }
1590
1591 /*
1592 ** Return a pointer to the setting information array.
1593 **
@@ -1481,11 +1759,11 @@
1759 sqlite3_result_text(ctx, pPage->zHelp, -1, SQLITE_STATIC);
1760 break;
1761 case 4: { /* formatted */
1762 Blob txt;
1763 blob_init(&txt, 0, 0);
1764 help_to_text(pPage->zHelp, &txt, 0);
1765 sqlite3_result_text(ctx, blob_str(&txt), -1, fossil_free);
1766 break;
1767 }
1768 case 5: { /* formatted */
1769 Blob txt;
1770
--- src/export.c
+++ src/export.c
@@ -480,10 +480,12 @@
480480
**
481481
** See also: import
482482
*/
483483
/*
484484
** COMMAND: export*
485
+**
486
+** Usage: %fossil export --git [REPOSITORY]
485487
**
486488
** This command is deprecated. Use "fossil git export" instead.
487489
*/
488490
void export_cmd(void){
489491
Stmt q, q2, q3;
490492
--- src/export.c
+++ src/export.c
@@ -480,10 +480,12 @@
480 **
481 ** See also: import
482 */
483 /*
484 ** COMMAND: export*
 
 
485 **
486 ** This command is deprecated. Use "fossil git export" instead.
487 */
488 void export_cmd(void){
489 Stmt q, q2, q3;
490
--- src/export.c
+++ src/export.c
@@ -480,10 +480,12 @@
480 **
481 ** See also: import
482 */
483 /*
484 ** COMMAND: export*
485 **
486 ** Usage: %fossil export --git [REPOSITORY]
487 **
488 ** This command is deprecated. Use "fossil git export" instead.
489 */
490 void export_cmd(void){
491 Stmt q, q2, q3;
492
--- src/fossil.page.pikchrshowasm.js
+++ src/fossil.page.pikchrshowasm.js
@@ -524,11 +524,11 @@
524524
ForceResizeKludge();
525525
}/*onPikchrshowLoaded()*/;
526526
527527
528528
/**
529
- Predefined scripts. Each entry is an object:
529
+ Predefined example pikchr scripts. Each entry is an object:
530530
531531
{
532532
name: required string,
533533
code: optional code string. An entry with a falsy code is treated
534534
like a separator in the resulting SELECT element (a
535535
--- src/fossil.page.pikchrshowasm.js
+++ src/fossil.page.pikchrshowasm.js
@@ -524,11 +524,11 @@
524 ForceResizeKludge();
525 }/*onPikchrshowLoaded()*/;
526
527
528 /**
529 Predefined scripts. Each entry is an object:
530
531 {
532 name: required string,
533 code: optional code string. An entry with a falsy code is treated
534 like a separator in the resulting SELECT element (a
535
--- src/fossil.page.pikchrshowasm.js
+++ src/fossil.page.pikchrshowasm.js
@@ -524,11 +524,11 @@
524 ForceResizeKludge();
525 }/*onPikchrshowLoaded()*/;
526
527
528 /**
529 Predefined example pikchr scripts. Each entry is an object:
530
531 {
532 name: required string,
533 code: optional code string. An entry with a falsy code is treated
534 like a separator in the resulting SELECT element (a
535
+12 -1
--- src/fuzz.c
+++ src/fuzz.c
@@ -60,10 +60,11 @@
6060
*/
6161
#define FUZZ_WIKI 0 /* The Fossil-Wiki formatter */
6262
#define FUZZ_MARKDOWN 1 /* The Markdown formatter */
6363
#define FUZZ_ARTIFACT 2 /* Fuzz the artifact parser */
6464
#define FUZZ_WIKI2 3 /* FOSSIL_WIKI and FOSSIL_MARKDOWN */
65
+#define FUZZ_COMFORMAT 4 /* comment_print() */
6566
#endif
6667
6768
/* The type of fuzzing to do */
6869
static int eFuzzType = FUZZ_WIKI;
6970
@@ -93,13 +94,20 @@
9394
blob_reset(&out);
9495
markdown_to_html(&in, &title, &out);
9596
blob_reset(&title);
9697
break;
9798
}
98
- case FUZZ_ARTIFACT:
99
+ case FUZZ_ARTIFACT: {
99100
fossil_fatal("FUZZ_ARTIFACT is not implemented.");
100101
break;
102
+ }
103
+ case FUZZ_COMFORMAT: {
104
+ if( nByte>=3 && aData[1]!=0 && memchr(&aData[1], 0, nByte-1)!=0 ){
105
+ int flags = (int)aData[0];
106
+ comment_print((const char*)&aData[1],0,15,80,flags);
107
+ }
108
+ }
101109
}
102110
blob_reset(&in);
103111
blob_reset(&out);
104112
return 0;
105113
}
@@ -116,10 +124,12 @@
116124
eFuzzType = FUZZ_WIKI;
117125
}else if( fossil_strcmp(zType,"markdown")==0 ){
118126
eFuzzType = FUZZ_MARKDOWN;
119127
}else if( fossil_strcmp(zType,"wiki2")==0 ){
120128
eFuzzType = FUZZ_WIKI2;
129
+ }else if( fossil_strcmp(zType,"comformat")==0 ){
130
+ eFuzzType = FUZZ_COMFORMAT;
121131
}else{
122132
fossil_fatal("unknown fuzz type: \"%s\"", zType);
123133
}
124134
}
125135
@@ -139,10 +149,11 @@
139149
**
140150
** Usage: %fossil test-fuzz [-fuzztype TYPE] INPUTFILE...
141151
**
142152
** Run a fuzz test using INPUTFILE as the test data. TYPE can be one of:
143153
**
154
+** comformat Fuzz the comment_print() routine
144155
** wiki Fuzz the Fossil-wiki translator
145156
** markdown Fuzz the markdown translator
146157
** artifact Fuzz the artifact parser
147158
** wiki2 Fuzz the Fossil-wiki and markdown translator
148159
*/
149160
--- src/fuzz.c
+++ src/fuzz.c
@@ -60,10 +60,11 @@
60 */
61 #define FUZZ_WIKI 0 /* The Fossil-Wiki formatter */
62 #define FUZZ_MARKDOWN 1 /* The Markdown formatter */
63 #define FUZZ_ARTIFACT 2 /* Fuzz the artifact parser */
64 #define FUZZ_WIKI2 3 /* FOSSIL_WIKI and FOSSIL_MARKDOWN */
 
65 #endif
66
67 /* The type of fuzzing to do */
68 static int eFuzzType = FUZZ_WIKI;
69
@@ -93,13 +94,20 @@
93 blob_reset(&out);
94 markdown_to_html(&in, &title, &out);
95 blob_reset(&title);
96 break;
97 }
98 case FUZZ_ARTIFACT:
99 fossil_fatal("FUZZ_ARTIFACT is not implemented.");
100 break;
 
 
 
 
 
 
 
101 }
102 blob_reset(&in);
103 blob_reset(&out);
104 return 0;
105 }
@@ -116,10 +124,12 @@
116 eFuzzType = FUZZ_WIKI;
117 }else if( fossil_strcmp(zType,"markdown")==0 ){
118 eFuzzType = FUZZ_MARKDOWN;
119 }else if( fossil_strcmp(zType,"wiki2")==0 ){
120 eFuzzType = FUZZ_WIKI2;
 
 
121 }else{
122 fossil_fatal("unknown fuzz type: \"%s\"", zType);
123 }
124 }
125
@@ -139,10 +149,11 @@
139 **
140 ** Usage: %fossil test-fuzz [-fuzztype TYPE] INPUTFILE...
141 **
142 ** Run a fuzz test using INPUTFILE as the test data. TYPE can be one of:
143 **
 
144 ** wiki Fuzz the Fossil-wiki translator
145 ** markdown Fuzz the markdown translator
146 ** artifact Fuzz the artifact parser
147 ** wiki2 Fuzz the Fossil-wiki and markdown translator
148 */
149
--- src/fuzz.c
+++ src/fuzz.c
@@ -60,10 +60,11 @@
60 */
61 #define FUZZ_WIKI 0 /* The Fossil-Wiki formatter */
62 #define FUZZ_MARKDOWN 1 /* The Markdown formatter */
63 #define FUZZ_ARTIFACT 2 /* Fuzz the artifact parser */
64 #define FUZZ_WIKI2 3 /* FOSSIL_WIKI and FOSSIL_MARKDOWN */
65 #define FUZZ_COMFORMAT 4 /* comment_print() */
66 #endif
67
68 /* The type of fuzzing to do */
69 static int eFuzzType = FUZZ_WIKI;
70
@@ -93,13 +94,20 @@
94 blob_reset(&out);
95 markdown_to_html(&in, &title, &out);
96 blob_reset(&title);
97 break;
98 }
99 case FUZZ_ARTIFACT: {
100 fossil_fatal("FUZZ_ARTIFACT is not implemented.");
101 break;
102 }
103 case FUZZ_COMFORMAT: {
104 if( nByte>=3 && aData[1]!=0 && memchr(&aData[1], 0, nByte-1)!=0 ){
105 int flags = (int)aData[0];
106 comment_print((const char*)&aData[1],0,15,80,flags);
107 }
108 }
109 }
110 blob_reset(&in);
111 blob_reset(&out);
112 return 0;
113 }
@@ -116,10 +124,12 @@
124 eFuzzType = FUZZ_WIKI;
125 }else if( fossil_strcmp(zType,"markdown")==0 ){
126 eFuzzType = FUZZ_MARKDOWN;
127 }else if( fossil_strcmp(zType,"wiki2")==0 ){
128 eFuzzType = FUZZ_WIKI2;
129 }else if( fossil_strcmp(zType,"comformat")==0 ){
130 eFuzzType = FUZZ_COMFORMAT;
131 }else{
132 fossil_fatal("unknown fuzz type: \"%s\"", zType);
133 }
134 }
135
@@ -139,10 +149,11 @@
149 **
150 ** Usage: %fossil test-fuzz [-fuzztype TYPE] INPUTFILE...
151 **
152 ** Run a fuzz test using INPUTFILE as the test data. TYPE can be one of:
153 **
154 ** comformat Fuzz the comment_print() routine
155 ** wiki Fuzz the Fossil-wiki translator
156 ** markdown Fuzz the markdown translator
157 ** artifact Fuzz the artifact parser
158 ** wiki2 Fuzz the Fossil-wiki and markdown translator
159 */
160
+6 -6
--- src/hook.c
+++ src/hook.c
@@ -198,39 +198,39 @@
198198
**
199199
** Usage: %fossil hook COMMAND ...
200200
**
201201
** Commands include:
202202
**
203
-** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER
203
+** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER
204204
**
205205
** Create a new hook. The --command and --type arguments are
206206
** required. --sequence is optional.
207207
**
208
-** > fossil hook delete ID ...
208
+** > fossil hook delete ID ...
209209
**
210210
** Delete one or more hooks by their IDs. ID can be "all"
211211
** to delete all hooks. Caution: There is no "undo" for
212212
** this operation. Deleted hooks are permanently lost.
213213
**
214
-** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ...
214
+** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ...
215215
**
216216
** Make changes to one or more existing hooks. The ID argument
217217
** is either a hook-id, or a list of hook-ids, or the keyword
218218
** "all". For example, to disable hook number 2, use:
219219
**
220220
** fossil hook edit --type disabled 2
221221
**
222
-** > fossil hook list
222
+** > fossil hook list
223223
**
224224
** Show all current hooks
225225
**
226
-** > fossil hook status
226
+** > fossil hook status
227227
**
228228
** Print the values of CONFIG table entries that are relevant to
229229
** hook processing. Used for debugging.
230230
**
231
-** > fossil hook test [OPTIONS] ID
231
+** > fossil hook test [OPTIONS] ID
232232
**
233233
** Run the hook script given by ID for testing purposes.
234234
** Options:
235235
**
236236
** --dry-run Print the script on stdout rather than run it
237237
--- src/hook.c
+++ src/hook.c
@@ -198,39 +198,39 @@
198 **
199 ** Usage: %fossil hook COMMAND ...
200 **
201 ** Commands include:
202 **
203 ** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER
204 **
205 ** Create a new hook. The --command and --type arguments are
206 ** required. --sequence is optional.
207 **
208 ** > fossil hook delete ID ...
209 **
210 ** Delete one or more hooks by their IDs. ID can be "all"
211 ** to delete all hooks. Caution: There is no "undo" for
212 ** this operation. Deleted hooks are permanently lost.
213 **
214 ** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ...
215 **
216 ** Make changes to one or more existing hooks. The ID argument
217 ** is either a hook-id, or a list of hook-ids, or the keyword
218 ** "all". For example, to disable hook number 2, use:
219 **
220 ** fossil hook edit --type disabled 2
221 **
222 ** > fossil hook list
223 **
224 ** Show all current hooks
225 **
226 ** > fossil hook status
227 **
228 ** Print the values of CONFIG table entries that are relevant to
229 ** hook processing. Used for debugging.
230 **
231 ** > fossil hook test [OPTIONS] ID
232 **
233 ** Run the hook script given by ID for testing purposes.
234 ** Options:
235 **
236 ** --dry-run Print the script on stdout rather than run it
237
--- src/hook.c
+++ src/hook.c
@@ -198,39 +198,39 @@
198 **
199 ** Usage: %fossil hook COMMAND ...
200 **
201 ** Commands include:
202 **
203 ** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER
204 **
205 ** Create a new hook. The --command and --type arguments are
206 ** required. --sequence is optional.
207 **
208 ** > fossil hook delete ID ...
209 **
210 ** Delete one or more hooks by their IDs. ID can be "all"
211 ** to delete all hooks. Caution: There is no "undo" for
212 ** this operation. Deleted hooks are permanently lost.
213 **
214 ** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ...
215 **
216 ** Make changes to one or more existing hooks. The ID argument
217 ** is either a hook-id, or a list of hook-ids, or the keyword
218 ** "all". For example, to disable hook number 2, use:
219 **
220 ** fossil hook edit --type disabled 2
221 **
222 ** > fossil hook list
223 **
224 ** Show all current hooks
225 **
226 ** > fossil hook status
227 **
228 ** Print the values of CONFIG table entries that are relevant to
229 ** hook processing. Used for debugging.
230 **
231 ** > fossil hook test [OPTIONS] ID
232 **
233 ** Run the hook script given by ID for testing purposes.
234 ** Options:
235 **
236 ** --dry-run Print the script on stdout rather than run it
237
+12 -12
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -948,31 +948,31 @@
948948
if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
949949
}
950950
#endif /* FOSSIL_ENABLE_SSL */
951951
952952
/*
953
-** COMMAND: tls-config*
954
-** COMMAND: ssl-config
953
+** COMMAND: tls-config* abbreviated-subcommands
954
+** COMMAND: ssl-config abbreviated-subcommands
955955
**
956956
** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
957957
**
958958
** This command is used to view or modify the TLS (Transport Layer
959959
** Security) configuration for Fossil. TLS (formerly SSL) is the
960960
** encryption technology used for secure HTTPS transport.
961961
**
962962
** Sub-commands:
963963
**
964
-** remove-exception DOMAINS Remove TLS cert exceptions for the domains
965
-** listed. Or remove them all if the --all
966
-** option is specified.
967
-**
968
-** scrub ?--force? Remove all SSL configuration data from the
969
-** repository. Use --force to omit the
970
-** confirmation.
971
-**
972
-** show ?-v? Show the TLS configuration. Add -v to see
973
-** additional explanation
964
+** remove-exception DOMAINS Remove TLS cert exceptions for the domains
965
+** listed. Or remove them all if the --all
966
+** option is specified.
967
+**
968
+** scrub ?--force? Remove all SSL configuration data from the
969
+** repository. Use --force to omit the
970
+** confirmation.
971
+**
972
+** show ?-v? Show the TLS configuration. Add -v to see
973
+** additional explanation
974974
*/
975975
void test_tlsconfig_info(void){
976976
const char *zCmd;
977977
size_t nCmd;
978978
int nHit = 0;
979979
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -948,31 +948,31 @@
948 if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
949 }
950 #endif /* FOSSIL_ENABLE_SSL */
951
952 /*
953 ** COMMAND: tls-config*
954 ** COMMAND: ssl-config
955 **
956 ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
957 **
958 ** This command is used to view or modify the TLS (Transport Layer
959 ** Security) configuration for Fossil. TLS (formerly SSL) is the
960 ** encryption technology used for secure HTTPS transport.
961 **
962 ** Sub-commands:
963 **
964 ** remove-exception DOMAINS Remove TLS cert exceptions for the domains
965 ** listed. Or remove them all if the --all
966 ** option is specified.
967 **
968 ** scrub ?--force? Remove all SSL configuration data from the
969 ** repository. Use --force to omit the
970 ** confirmation.
971 **
972 ** show ?-v? Show the TLS configuration. Add -v to see
973 ** additional explanation
974 */
975 void test_tlsconfig_info(void){
976 const char *zCmd;
977 size_t nCmd;
978 int nHit = 0;
979
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -948,31 +948,31 @@
948 if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
949 }
950 #endif /* FOSSIL_ENABLE_SSL */
951
952 /*
953 ** COMMAND: tls-config* abbreviated-subcommands
954 ** COMMAND: ssl-config abbreviated-subcommands
955 **
956 ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
957 **
958 ** This command is used to view or modify the TLS (Transport Layer
959 ** Security) configuration for Fossil. TLS (formerly SSL) is the
960 ** encryption technology used for secure HTTPS transport.
961 **
962 ** Sub-commands:
963 **
964 ** remove-exception DOMAINS Remove TLS cert exceptions for the domains
965 ** listed. Or remove them all if the --all
966 ** option is specified.
967 **
968 ** scrub ?--force? Remove all SSL configuration data from the
969 ** repository. Use --force to omit the
970 ** confirmation.
971 **
972 ** show ?-v? Show the TLS configuration. Add -v to see
973 ** additional explanation
974 */
975 void test_tlsconfig_info(void){
976 const char *zCmd;
977 size_t nCmd;
978 int nHit = 0;
979
+12 -12
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -948,31 +948,31 @@
948948
if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
949949
}
950950
#endif /* FOSSIL_ENABLE_SSL */
951951
952952
/*
953
-** COMMAND: tls-config*
954
-** COMMAND: ssl-config
953
+** COMMAND: tls-config* abbreviated-subcommands
954
+** COMMAND: ssl-config abbreviated-subcommands
955955
**
956956
** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
957957
**
958958
** This command is used to view or modify the TLS (Transport Layer
959959
** Security) configuration for Fossil. TLS (formerly SSL) is the
960960
** encryption technology used for secure HTTPS transport.
961961
**
962962
** Sub-commands:
963963
**
964
-** remove-exception DOMAINS Remove TLS cert exceptions for the domains
965
-** listed. Or remove them all if the --all
966
-** option is specified.
967
-**
968
-** scrub ?--force? Remove all SSL configuration data from the
969
-** repository. Use --force to omit the
970
-** confirmation.
971
-**
972
-** show ?-v? Show the TLS configuration. Add -v to see
973
-** additional explanation
964
+** remove-exception DOMAINS Remove TLS cert exceptions for the domains
965
+** listed. Or remove them all if the --all
966
+** option is specified.
967
+**
968
+** scrub ?--force? Remove all SSL configuration data from the
969
+** repository. Use --force to omit the
970
+** confirmation.
971
+**
972
+** show ?-v? Show the TLS configuration. Add -v to see
973
+** additional explanation
974974
*/
975975
void test_tlsconfig_info(void){
976976
const char *zCmd;
977977
size_t nCmd;
978978
int nHit = 0;
979979
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -948,31 +948,31 @@
948 if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
949 }
950 #endif /* FOSSIL_ENABLE_SSL */
951
952 /*
953 ** COMMAND: tls-config*
954 ** COMMAND: ssl-config
955 **
956 ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
957 **
958 ** This command is used to view or modify the TLS (Transport Layer
959 ** Security) configuration for Fossil. TLS (formerly SSL) is the
960 ** encryption technology used for secure HTTPS transport.
961 **
962 ** Sub-commands:
963 **
964 ** remove-exception DOMAINS Remove TLS cert exceptions for the domains
965 ** listed. Or remove them all if the --all
966 ** option is specified.
967 **
968 ** scrub ?--force? Remove all SSL configuration data from the
969 ** repository. Use --force to omit the
970 ** confirmation.
971 **
972 ** show ?-v? Show the TLS configuration. Add -v to see
973 ** additional explanation
974 */
975 void test_tlsconfig_info(void){
976 const char *zCmd;
977 size_t nCmd;
978 int nHit = 0;
979
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -948,31 +948,31 @@
948 if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath;
949 }
950 #endif /* FOSSIL_ENABLE_SSL */
951
952 /*
953 ** COMMAND: tls-config* abbreviated-subcommands
954 ** COMMAND: ssl-config abbreviated-subcommands
955 **
956 ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...]
957 **
958 ** This command is used to view or modify the TLS (Transport Layer
959 ** Security) configuration for Fossil. TLS (formerly SSL) is the
960 ** encryption technology used for secure HTTPS transport.
961 **
962 ** Sub-commands:
963 **
964 ** remove-exception DOMAINS Remove TLS cert exceptions for the domains
965 ** listed. Or remove them all if the --all
966 ** option is specified.
967 **
968 ** scrub ?--force? Remove all SSL configuration data from the
969 ** repository. Use --force to omit the
970 ** confirmation.
971 **
972 ** show ?-v? Show the TLS configuration. Add -v to see
973 ** additional explanation
974 */
975 void test_tlsconfig_info(void){
976 const char *zCmd;
977 size_t nCmd;
978 int nHit = 0;
979
+3 -3
--- src/interwiki.c
+++ src/interwiki.c
@@ -161,23 +161,23 @@
161161
** Usage: %fossil interwiki COMMAND ...
162162
**
163163
** Manage the "intermap" that defines the mapping from interwiki tags
164164
** to complete URLs for interwiki links.
165165
**
166
-** > fossil interwiki delete TAG ...
166
+** > fossil interwiki delete TAG ...
167167
**
168168
** Delete one or more interwiki maps.
169169
**
170
-** > fossil interwiki edit TAG --base URL --hash PATH --wiki PATH
170
+** > fossil interwiki edit TAG --base URL --hash PATH --wiki PATH
171171
**
172172
** Create an interwiki referenced call TAG. The base URL is
173173
** the --base option, which is required. The --hash and --wiki
174174
** paths are optional. The TAG must be lower-case alphanumeric
175175
** and must be unique. A new entry is created if it does not
176176
** already exit.
177177
**
178
-** > fossil interwiki list
178
+** > fossil interwiki list
179179
**
180180
** Show all interwiki mappings.
181181
*/
182182
void interwiki_cmd(void){
183183
const char *zCmd;
184184
--- src/interwiki.c
+++ src/interwiki.c
@@ -161,23 +161,23 @@
161 ** Usage: %fossil interwiki COMMAND ...
162 **
163 ** Manage the "intermap" that defines the mapping from interwiki tags
164 ** to complete URLs for interwiki links.
165 **
166 ** > fossil interwiki delete TAG ...
167 **
168 ** Delete one or more interwiki maps.
169 **
170 ** > fossil interwiki edit TAG --base URL --hash PATH --wiki PATH
171 **
172 ** Create an interwiki referenced call TAG. The base URL is
173 ** the --base option, which is required. The --hash and --wiki
174 ** paths are optional. The TAG must be lower-case alphanumeric
175 ** and must be unique. A new entry is created if it does not
176 ** already exit.
177 **
178 ** > fossil interwiki list
179 **
180 ** Show all interwiki mappings.
181 */
182 void interwiki_cmd(void){
183 const char *zCmd;
184
--- src/interwiki.c
+++ src/interwiki.c
@@ -161,23 +161,23 @@
161 ** Usage: %fossil interwiki COMMAND ...
162 **
163 ** Manage the "intermap" that defines the mapping from interwiki tags
164 ** to complete URLs for interwiki links.
165 **
166 ** > fossil interwiki delete TAG ...
167 **
168 ** Delete one or more interwiki maps.
169 **
170 ** > fossil interwiki edit TAG --base URL --hash PATH --wiki PATH
171 **
172 ** Create an interwiki referenced call TAG. The base URL is
173 ** the --base option, which is required. The --hash and --wiki
174 ** paths are optional. The TAG must be lower-case alphanumeric
175 ** and must be unique. A new entry is created if it does not
176 ** already exit.
177 **
178 ** > fossil interwiki list
179 **
180 ** Show all interwiki mappings.
181 */
182 void interwiki_cmd(void){
183 const char *zCmd;
184
+1 -2
--- src/main.c
+++ src/main.c
@@ -3599,15 +3599,14 @@
35993599
g.httpSSLConn = 0;
36003600
}
36013601
#endif /* FOSSIL_ENABLE_SSL */
36023602
36033603
#else /* WIN32 */
3604
- find_server_repository(2, 0);
3604
+ /* Win32 implementation */
36053605
if( fossil_strcmp(g.zRepositoryName,"/")==0 ){
36063606
allowRepoList = 1;
36073607
}
3608
- /* Win32 implementation */
36093608
if( allowRepoList ){
36103609
flags |= HTTP_SERVER_REPOLIST;
36113610
}
36123611
if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
36133612
win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
36143613
--- src/main.c
+++ src/main.c
@@ -3599,15 +3599,14 @@
3599 g.httpSSLConn = 0;
3600 }
3601 #endif /* FOSSIL_ENABLE_SSL */
3602
3603 #else /* WIN32 */
3604 find_server_repository(2, 0);
3605 if( fossil_strcmp(g.zRepositoryName,"/")==0 ){
3606 allowRepoList = 1;
3607 }
3608 /* Win32 implementation */
3609 if( allowRepoList ){
3610 flags |= HTTP_SERVER_REPOLIST;
3611 }
3612 if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
3613 win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
3614
--- src/main.c
+++ src/main.c
@@ -3599,15 +3599,14 @@
3599 g.httpSSLConn = 0;
3600 }
3601 #endif /* FOSSIL_ENABLE_SSL */
3602
3603 #else /* WIN32 */
3604 /* Win32 implementation */
3605 if( fossil_strcmp(g.zRepositoryName,"/")==0 ){
3606 allowRepoList = 1;
3607 }
 
3608 if( allowRepoList ){
3609 flags |= HTTP_SERVER_REPOLIST;
3610 }
3611 if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){
3612 win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile,
3613
+1 -1
--- src/main.mk
+++ src/main.mk
@@ -2136,11 +2136,11 @@
21362136
$(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
21372137
$(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
21382138
21392139
$(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
21402140
$(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
2141
- -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore \
2141
+ -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackAlloc,stackRestore \
21422142
-sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \
21432143
-sENVIRONMENT=web \
21442144
-sMODULARIZE \
21452145
-sEXPORT_NAME=initPikchrModule \
21462146
--minify 0
21472147
--- src/main.mk
+++ src/main.mk
@@ -2136,11 +2136,11 @@
2136 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
2137 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
2138
2139 $(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
2140 $(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
2141 -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackRestore \
2142 -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \
2143 -sENVIRONMENT=web \
2144 -sMODULARIZE \
2145 -sEXPORT_NAME=initPikchrModule \
2146 --minify 0
2147
--- src/main.mk
+++ src/main.mk
@@ -2136,11 +2136,11 @@
2136 $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c
2137 $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@
2138
2139 $(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c
2140 $(EMCC_WRAPPER) -o $@ $(EMCC_OPT) --no-entry \
2141 -sEXPORTED_RUNTIME_METHODS=cwrap,setValue,getValue,stackSave,stackAlloc,stackRestore \
2142 -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \
2143 -sENVIRONMENT=web \
2144 -sMODULARIZE \
2145 -sEXPORT_NAME=initPikchrModule \
2146 --minify 0
2147
+93 -4
--- src/patch.c
+++ src/patch.c
@@ -698,10 +698,26 @@
698698
fossil_fatal("cannot change to directory \"%s\"", zDir);
699699
}
700700
fossil_free(zToFree);
701701
return zPatchFile;
702702
}
703
+
704
+/*
705
+** Resolves a patch-command remote system name, accounting for patch
706
+** aliases.
707
+**
708
+** If a CONFIG table entry matching name='patch-alias:$zKey' is found,
709
+** the corresponding value is returned, else a fossil_strdup() of zKey
710
+** is returned. The caller is responsible for passing the resulting
711
+** string to fossil_free().
712
+*/
713
+static char *patch_resolve_remote(const char *zKey){
714
+ char *zAlias = db_text(0, "SELECT value FROM config "
715
+ "WHERE name = 'patch-alias:%q'",
716
+ zKey);
717
+ return zAlias ? zAlias : fossil_strdup(zKey);
718
+}
703719
704720
/*
705721
** Create a FILE* that will execute the remote side of a push or pull
706722
** using ssh (probably) or fossil for local pushes and pulls. Return
707723
** a FILE* obtained from popen() into which we write the patch, or from
@@ -729,11 +745,11 @@
729745
if( mFlags & PATCH_DRYRUN ) blob_appendf(&flgs, " -n");
730746
zForce = blob_size(&flgs)>0 ? blob_str(&flgs) : "";
731747
if( g.argc!=4 ){
732748
usage(mprintf("%s [USER@]HOST:DIRECTORY", zThisCmd));
733749
}
734
- zRemote = fossil_strdup(g.argv[3]);
750
+ zRemote = patch_resolve_remote(g.argv[3]);
735751
zDir = (char*)file_skip_userhost(zRemote);
736752
if( zDir==0 ){
737753
if( isRetry ) goto remote_command_error;
738754
zDir = zRemote;
739755
blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
@@ -778,11 +794,11 @@
778794
/*
779795
** Toggle the use-path-for-ssh setting for the remote host defined
780796
** by g.argv[3].
781797
*/
782798
static void patch_toggle_ssh_needs_path(void){
783
- char *zRemote = fossil_strdup(g.argv[3]);
799
+ char *zRemote = patch_resolve_remote(g.argv[3]);
784800
char *zDir = (char*)file_skip_userhost(zRemote);
785801
if( zDir ){
786802
*(char*)(zDir - 1) = 0;
787803
ssh_needs_path_argument(zRemote, 99);
788804
}
@@ -905,11 +921,10 @@
905921
db_finalize(&q);
906922
diff_end(pCfg, nErr);
907923
if( nErr ) fossil_fatal("abort due to prior errors");
908924
}
909925
910
-
911926
/*
912927
** COMMAND: patch
913928
**
914929
** Usage: %fossil patch SUBCOMMAND ?ARGS ..?
915930
**
@@ -916,10 +931,22 @@
916931
** This command is used to create, view, and apply Fossil binary patches.
917932
** A Fossil binary patch is a single (binary) file that captures all of the
918933
** uncommitted changes of a check-out. Use Fossil binary patches to transfer
919934
** proposed or incomplete changes between machines for testing or analysis.
920935
**
936
+** > fossil patch alias add|rm|ls|list ?ARGS?
937
+**
938
+** Manage remote-name aliases, which act as short-form
939
+** equivalents to REMOTE-CHECKOUT strings. Aliases are local to
940
+** a given repository and do not sync. Subcommands:
941
+**
942
+** ... add ALIAS REMOTE-CHECKOUT Add ALIAS as an alias
943
+** for REMOTE-CHECKOUT.
944
+** ... ls|list List all local aliases.
945
+** ... rm ALIAS [ALIAS...] Remove named aliases
946
+** ... rm --all Remove all aliases
947
+**
921948
** > fossil patch create [DIRECTORY] PATCHFILE
922949
**
923950
** Create a new binary patch in PATCHFILE that captures all uncommitted
924951
** changes in the check-out at DIRECTORY, or the current directory if
925952
** DIRECTORY is omitted. If PATCHFILE is "-" then the binary patch
@@ -996,14 +1023,76 @@
9961023
void patch_cmd(void){
9971024
const char *zCmd;
9981025
size_t n;
9991026
if( g.argc<3 ){
10001027
patch_usage:
1001
- usage("apply|create|diff|gdiff|pull|push|view");
1028
+ usage("alias|apply|create|diff|gdiff|pull|push|view");
10021029
}
10031030
zCmd = g.argv[2];
10041031
n = strlen(zCmd);
1032
+ if( strncmp(zCmd, "alias", n)==0 ){
1033
+ const char * zArg = g.argc>3 ? g.argv[3] : 0;
1034
+ db_must_be_within_tree();
1035
+ if( 0==zArg ){
1036
+ goto usage_patch_alias;
1037
+ }else if( 0==strcmp("ls",zArg) || 0==strcmp("list",zArg) ){
1038
+ /* alias ls|list */
1039
+ Stmt q;
1040
+ int nAlias = 0;
1041
+
1042
+ verify_all_options();
1043
+ db_prepare(&q, "SELECT substr(name,13), value FROM config "
1044
+ "WHERE name GLOB 'patch-alias:*' ORDER BY name");
1045
+ while( SQLITE_ROW==db_step(&q) ){
1046
+ const char *zName = db_column_text(&q, 0);
1047
+ const char *zVal = db_column_text(&q, 1);
1048
+ ++nAlias;
1049
+ fossil_print("%s = %s\n", zName, zVal);
1050
+ }
1051
+ db_finalize(&q);
1052
+ if( 0==nAlias ){
1053
+ fossil_print("No patch aliases defined\n");
1054
+ }
1055
+ }else if( 0==strcmp("add", zArg) ){
1056
+ /* alias add localName remote */
1057
+ verify_all_options();
1058
+ if( 6!=g.argc ){
1059
+ usage("alias add localName remote");
1060
+ }
1061
+ db_unprotect(PROTECT_CONFIG);
1062
+ db_multi_exec("REPLACE INTO config (name, value, mtime) "
1063
+ "VALUES ('patch-alias:%q', %Q, unixepoch())",
1064
+ g.argv[4], g.argv[5]);
1065
+ db_protect_pop();
1066
+ }else if( 0==strcmp("rm", zArg) ){
1067
+ /* alias rm */
1068
+ const int fAll = 0!=find_option("all", 0, 0);
1069
+ if( fAll ? g.argc<4 : g.argc<5 ){
1070
+ usage("alias rm [-all] [aliasGlob [...aliasGlobN]]");
1071
+ }
1072
+ verify_all_options();
1073
+ db_unprotect(PROTECT_CONFIG);
1074
+ if( 0!=fAll ){
1075
+ db_multi_exec("DELETE FROM config WHERE name GLOB 'patch-alias:*'");
1076
+ }else{
1077
+ Stmt q;
1078
+ int i;
1079
+ db_prepare(&q, "DELETE FROM config WHERE name "
1080
+ "GLOB 'patch-alias:' || :pattern");
1081
+ for(i = 4; i < g.argc; ++i){
1082
+ db_bind_text(&q, ":pattern", g.argv[i]);
1083
+ db_step(&q);
1084
+ db_reset(&q);
1085
+ }
1086
+ db_finalize(&q);
1087
+ }
1088
+ db_protect_pop();
1089
+ }else{
1090
+ usage_patch_alias:
1091
+ usage("alias ls|list|add|rm ...");
1092
+ }
1093
+ }else
10051094
if( strncmp(zCmd, "apply", n)==0 ){
10061095
char *zIn;
10071096
unsigned flags = 0;
10081097
if( find_option("dry-run","n",0) ) flags |= PATCH_DRYRUN;
10091098
if( find_option("verbose","v",0) ) flags |= PATCH_VERBOSE;
10101099
--- src/patch.c
+++ src/patch.c
@@ -698,10 +698,26 @@
698 fossil_fatal("cannot change to directory \"%s\"", zDir);
699 }
700 fossil_free(zToFree);
701 return zPatchFile;
702 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
703
704 /*
705 ** Create a FILE* that will execute the remote side of a push or pull
706 ** using ssh (probably) or fossil for local pushes and pulls. Return
707 ** a FILE* obtained from popen() into which we write the patch, or from
@@ -729,11 +745,11 @@
729 if( mFlags & PATCH_DRYRUN ) blob_appendf(&flgs, " -n");
730 zForce = blob_size(&flgs)>0 ? blob_str(&flgs) : "";
731 if( g.argc!=4 ){
732 usage(mprintf("%s [USER@]HOST:DIRECTORY", zThisCmd));
733 }
734 zRemote = fossil_strdup(g.argv[3]);
735 zDir = (char*)file_skip_userhost(zRemote);
736 if( zDir==0 ){
737 if( isRetry ) goto remote_command_error;
738 zDir = zRemote;
739 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
@@ -778,11 +794,11 @@
778 /*
779 ** Toggle the use-path-for-ssh setting for the remote host defined
780 ** by g.argv[3].
781 */
782 static void patch_toggle_ssh_needs_path(void){
783 char *zRemote = fossil_strdup(g.argv[3]);
784 char *zDir = (char*)file_skip_userhost(zRemote);
785 if( zDir ){
786 *(char*)(zDir - 1) = 0;
787 ssh_needs_path_argument(zRemote, 99);
788 }
@@ -905,11 +921,10 @@
905 db_finalize(&q);
906 diff_end(pCfg, nErr);
907 if( nErr ) fossil_fatal("abort due to prior errors");
908 }
909
910
911 /*
912 ** COMMAND: patch
913 **
914 ** Usage: %fossil patch SUBCOMMAND ?ARGS ..?
915 **
@@ -916,10 +931,22 @@
916 ** This command is used to create, view, and apply Fossil binary patches.
917 ** A Fossil binary patch is a single (binary) file that captures all of the
918 ** uncommitted changes of a check-out. Use Fossil binary patches to transfer
919 ** proposed or incomplete changes between machines for testing or analysis.
920 **
 
 
 
 
 
 
 
 
 
 
 
 
921 ** > fossil patch create [DIRECTORY] PATCHFILE
922 **
923 ** Create a new binary patch in PATCHFILE that captures all uncommitted
924 ** changes in the check-out at DIRECTORY, or the current directory if
925 ** DIRECTORY is omitted. If PATCHFILE is "-" then the binary patch
@@ -996,14 +1023,76 @@
996 void patch_cmd(void){
997 const char *zCmd;
998 size_t n;
999 if( g.argc<3 ){
1000 patch_usage:
1001 usage("apply|create|diff|gdiff|pull|push|view");
1002 }
1003 zCmd = g.argv[2];
1004 n = strlen(zCmd);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1005 if( strncmp(zCmd, "apply", n)==0 ){
1006 char *zIn;
1007 unsigned flags = 0;
1008 if( find_option("dry-run","n",0) ) flags |= PATCH_DRYRUN;
1009 if( find_option("verbose","v",0) ) flags |= PATCH_VERBOSE;
1010
--- src/patch.c
+++ src/patch.c
@@ -698,10 +698,26 @@
698 fossil_fatal("cannot change to directory \"%s\"", zDir);
699 }
700 fossil_free(zToFree);
701 return zPatchFile;
702 }
703
704 /*
705 ** Resolves a patch-command remote system name, accounting for patch
706 ** aliases.
707 **
708 ** If a CONFIG table entry matching name='patch-alias:$zKey' is found,
709 ** the corresponding value is returned, else a fossil_strdup() of zKey
710 ** is returned. The caller is responsible for passing the resulting
711 ** string to fossil_free().
712 */
713 static char *patch_resolve_remote(const char *zKey){
714 char *zAlias = db_text(0, "SELECT value FROM config "
715 "WHERE name = 'patch-alias:%q'",
716 zKey);
717 return zAlias ? zAlias : fossil_strdup(zKey);
718 }
719
720 /*
721 ** Create a FILE* that will execute the remote side of a push or pull
722 ** using ssh (probably) or fossil for local pushes and pulls. Return
723 ** a FILE* obtained from popen() into which we write the patch, or from
@@ -729,11 +745,11 @@
745 if( mFlags & PATCH_DRYRUN ) blob_appendf(&flgs, " -n");
746 zForce = blob_size(&flgs)>0 ? blob_str(&flgs) : "";
747 if( g.argc!=4 ){
748 usage(mprintf("%s [USER@]HOST:DIRECTORY", zThisCmd));
749 }
750 zRemote = patch_resolve_remote(g.argv[3]);
751 zDir = (char*)file_skip_userhost(zRemote);
752 if( zDir==0 ){
753 if( isRetry ) goto remote_command_error;
754 zDir = zRemote;
755 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
@@ -778,11 +794,11 @@
794 /*
795 ** Toggle the use-path-for-ssh setting for the remote host defined
796 ** by g.argv[3].
797 */
798 static void patch_toggle_ssh_needs_path(void){
799 char *zRemote = patch_resolve_remote(g.argv[3]);
800 char *zDir = (char*)file_skip_userhost(zRemote);
801 if( zDir ){
802 *(char*)(zDir - 1) = 0;
803 ssh_needs_path_argument(zRemote, 99);
804 }
@@ -905,11 +921,10 @@
921 db_finalize(&q);
922 diff_end(pCfg, nErr);
923 if( nErr ) fossil_fatal("abort due to prior errors");
924 }
925
 
926 /*
927 ** COMMAND: patch
928 **
929 ** Usage: %fossil patch SUBCOMMAND ?ARGS ..?
930 **
@@ -916,10 +931,22 @@
931 ** This command is used to create, view, and apply Fossil binary patches.
932 ** A Fossil binary patch is a single (binary) file that captures all of the
933 ** uncommitted changes of a check-out. Use Fossil binary patches to transfer
934 ** proposed or incomplete changes between machines for testing or analysis.
935 **
936 ** > fossil patch alias add|rm|ls|list ?ARGS?
937 **
938 ** Manage remote-name aliases, which act as short-form
939 ** equivalents to REMOTE-CHECKOUT strings. Aliases are local to
940 ** a given repository and do not sync. Subcommands:
941 **
942 ** ... add ALIAS REMOTE-CHECKOUT Add ALIAS as an alias
943 ** for REMOTE-CHECKOUT.
944 ** ... ls|list List all local aliases.
945 ** ... rm ALIAS [ALIAS...] Remove named aliases
946 ** ... rm --all Remove all aliases
947 **
948 ** > fossil patch create [DIRECTORY] PATCHFILE
949 **
950 ** Create a new binary patch in PATCHFILE that captures all uncommitted
951 ** changes in the check-out at DIRECTORY, or the current directory if
952 ** DIRECTORY is omitted. If PATCHFILE is "-" then the binary patch
@@ -996,14 +1023,76 @@
1023 void patch_cmd(void){
1024 const char *zCmd;
1025 size_t n;
1026 if( g.argc<3 ){
1027 patch_usage:
1028 usage("alias|apply|create|diff|gdiff|pull|push|view");
1029 }
1030 zCmd = g.argv[2];
1031 n = strlen(zCmd);
1032 if( strncmp(zCmd, "alias", n)==0 ){
1033 const char * zArg = g.argc>3 ? g.argv[3] : 0;
1034 db_must_be_within_tree();
1035 if( 0==zArg ){
1036 goto usage_patch_alias;
1037 }else if( 0==strcmp("ls",zArg) || 0==strcmp("list",zArg) ){
1038 /* alias ls|list */
1039 Stmt q;
1040 int nAlias = 0;
1041
1042 verify_all_options();
1043 db_prepare(&q, "SELECT substr(name,13), value FROM config "
1044 "WHERE name GLOB 'patch-alias:*' ORDER BY name");
1045 while( SQLITE_ROW==db_step(&q) ){
1046 const char *zName = db_column_text(&q, 0);
1047 const char *zVal = db_column_text(&q, 1);
1048 ++nAlias;
1049 fossil_print("%s = %s\n", zName, zVal);
1050 }
1051 db_finalize(&q);
1052 if( 0==nAlias ){
1053 fossil_print("No patch aliases defined\n");
1054 }
1055 }else if( 0==strcmp("add", zArg) ){
1056 /* alias add localName remote */
1057 verify_all_options();
1058 if( 6!=g.argc ){
1059 usage("alias add localName remote");
1060 }
1061 db_unprotect(PROTECT_CONFIG);
1062 db_multi_exec("REPLACE INTO config (name, value, mtime) "
1063 "VALUES ('patch-alias:%q', %Q, unixepoch())",
1064 g.argv[4], g.argv[5]);
1065 db_protect_pop();
1066 }else if( 0==strcmp("rm", zArg) ){
1067 /* alias rm */
1068 const int fAll = 0!=find_option("all", 0, 0);
1069 if( fAll ? g.argc<4 : g.argc<5 ){
1070 usage("alias rm [-all] [aliasGlob [...aliasGlobN]]");
1071 }
1072 verify_all_options();
1073 db_unprotect(PROTECT_CONFIG);
1074 if( 0!=fAll ){
1075 db_multi_exec("DELETE FROM config WHERE name GLOB 'patch-alias:*'");
1076 }else{
1077 Stmt q;
1078 int i;
1079 db_prepare(&q, "DELETE FROM config WHERE name "
1080 "GLOB 'patch-alias:' || :pattern");
1081 for(i = 4; i < g.argc; ++i){
1082 db_bind_text(&q, ":pattern", g.argv[i]);
1083 db_step(&q);
1084 db_reset(&q);
1085 }
1086 db_finalize(&q);
1087 }
1088 db_protect_pop();
1089 }else{
1090 usage_patch_alias:
1091 usage("alias ls|list|add|rm ...");
1092 }
1093 }else
1094 if( strncmp(zCmd, "apply", n)==0 ){
1095 char *zIn;
1096 unsigned flags = 0;
1097 if( find_option("dry-run","n",0) ) flags |= PATCH_DRYRUN;
1098 if( find_option("verbose","v",0) ) flags |= PATCH_VERBOSE;
1099
+1 -1
--- src/rebuild.c
+++ src/rebuild.c
@@ -1414,11 +1414,11 @@
14141414
}
14151415
14161416
/*
14171417
** COMMAND: deconstruct*
14181418
**
1419
-** Usage %fossil deconstruct ?OPTIONS? DESTINATION
1419
+** Usage: %fossil deconstruct ?OPTIONS? DESTINATION
14201420
**
14211421
** This command exports all artifacts of a given repository and writes all
14221422
** artifacts to the file system. The DESTINATION directory will be populated
14231423
** with subdirectories AA and files AA/BBBBBBBBB.., where AABBBBBBBBB.. is the
14241424
** 40+ character artifact ID, AA the first 2 characters.
14251425
--- src/rebuild.c
+++ src/rebuild.c
@@ -1414,11 +1414,11 @@
1414 }
1415
1416 /*
1417 ** COMMAND: deconstruct*
1418 **
1419 ** Usage %fossil deconstruct ?OPTIONS? DESTINATION
1420 **
1421 ** This command exports all artifacts of a given repository and writes all
1422 ** artifacts to the file system. The DESTINATION directory will be populated
1423 ** with subdirectories AA and files AA/BBBBBBBBB.., where AABBBBBBBBB.. is the
1424 ** 40+ character artifact ID, AA the first 2 characters.
1425
--- src/rebuild.c
+++ src/rebuild.c
@@ -1414,11 +1414,11 @@
1414 }
1415
1416 /*
1417 ** COMMAND: deconstruct*
1418 **
1419 ** Usage: %fossil deconstruct ?OPTIONS? DESTINATION
1420 **
1421 ** This command exports all artifacts of a given repository and writes all
1422 ** artifacts to the file system. The DESTINATION directory will be populated
1423 ** with subdirectories AA and files AA/BBBBBBBBB.., where AABBBBBBBBB.. is the
1424 ** 40+ character artifact ID, AA the first 2 characters.
1425
+39
--- src/regexp.c
+++ src/regexp.c
@@ -682,10 +682,49 @@
682682
if( j>0 && pRe->zInit[j-1]==0 ) j--;
683683
pRe->nInit = j;
684684
}
685685
return pRe->zErr;
686686
}
687
+
688
+/*
689
+** The input zIn is a string that we want to match exactly as part of
690
+** a regular expression. Return a new string (in space obtained from
691
+** fossil_malloc() or the equivalent) that escapes all regexp syntax
692
+** characters in zIn.
693
+*/
694
+char *re_quote(const char *zIn){
695
+ Blob out;
696
+ blob_init(&out, 0, 0);
697
+ while( zIn[0] ){
698
+ switch( zIn[0] ){
699
+ case '.':
700
+ case '?':
701
+ case '*':
702
+ case '+':
703
+ case '\\':
704
+ case '(':
705
+ case ')':
706
+ case '[':
707
+ case ']':
708
+ case '|':
709
+ case '^':
710
+ case '$':
711
+ case '{':
712
+ case '}': {
713
+ blob_appendf(&out,"\\x%02x", (unsigned char)zIn[0]);
714
+ break;
715
+ }
716
+ default: {
717
+ blob_append_char(&out, zIn[0]);
718
+ break;
719
+ }
720
+ }
721
+ zIn++;
722
+ }
723
+ blob_materialize(&out);
724
+ return out.aData;
725
+}
687726
688727
/*
689728
** Implementation of the regexp() SQL function. This function implements
690729
** the build-in REGEXP operator. The first argument to the function is the
691730
** pattern and the second argument is the string. So, the SQL statements:
692731
--- src/regexp.c
+++ src/regexp.c
@@ -682,10 +682,49 @@
682 if( j>0 && pRe->zInit[j-1]==0 ) j--;
683 pRe->nInit = j;
684 }
685 return pRe->zErr;
686 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
687
688 /*
689 ** Implementation of the regexp() SQL function. This function implements
690 ** the build-in REGEXP operator. The first argument to the function is the
691 ** pattern and the second argument is the string. So, the SQL statements:
692
--- src/regexp.c
+++ src/regexp.c
@@ -682,10 +682,49 @@
682 if( j>0 && pRe->zInit[j-1]==0 ) j--;
683 pRe->nInit = j;
684 }
685 return pRe->zErr;
686 }
687
688 /*
689 ** The input zIn is a string that we want to match exactly as part of
690 ** a regular expression. Return a new string (in space obtained from
691 ** fossil_malloc() or the equivalent) that escapes all regexp syntax
692 ** characters in zIn.
693 */
694 char *re_quote(const char *zIn){
695 Blob out;
696 blob_init(&out, 0, 0);
697 while( zIn[0] ){
698 switch( zIn[0] ){
699 case '.':
700 case '?':
701 case '*':
702 case '+':
703 case '\\':
704 case '(':
705 case ')':
706 case '[':
707 case ']':
708 case '|':
709 case '^':
710 case '$':
711 case '{':
712 case '}': {
713 blob_appendf(&out,"\\x%02x", (unsigned char)zIn[0]);
714 break;
715 }
716 default: {
717 blob_append_char(&out, zIn[0]);
718 break;
719 }
720 }
721 zIn++;
722 }
723 blob_materialize(&out);
724 return out.aData;
725 }
726
727 /*
728 ** Implementation of the regexp() SQL function. This function implements
729 ** the build-in REGEXP operator. The first argument to the function is the
730 ** pattern and the second argument is the string. So, the SQL statements:
731
+62 -33
--- src/search.c
+++ src/search.c
@@ -630,10 +630,14 @@
630630
zSnip[k++] = '&';
631631
j += 4;
632632
}else{
633633
zSnip[k++] = c;
634634
}
635
+ }else if( c=='%' && strncmp(&zSnip[j],"%fossil",7)==0 ){
636
+ /* no-op */
637
+ }else if( (c=='[' || c==']') && zSnip[j+1]==c ){
638
+ j++;
635639
}else{
636640
zSnip[k++] = c;
637641
}
638642
}
639643
zSnip[k] = 0;
@@ -645,30 +649,38 @@
645649
**
646650
** COMMAND: search*
647651
**
648652
** Usage: %fossil search [OPTIONS] PATTERN...
649653
**
650
-** Search the repository database for PATTERN and show matches.
651
-** The following elements of the repository can be searched:
652
-**
653
-** * check-in comments
654
-** * embedded documentation
655
-** * forum posts
656
-** * tickets
657
-** * tech notes
658
-** * wiki pages
659
-** * built-in fossil help text
660
-**
661
-** Use options (listed below) to select the scope of the search. The
662
-** default is check-in comments only.
654
+** Search the repository for PATTERN and show matches. Depending on
655
+** options and how the administrator has search configured for the
656
+** repository, the search can cover:
657
+**
658
+** * check-in comments (-c)
659
+** * embedded documentation (--docs)
660
+** * forum posts (--forum)
661
+** * tickets (--tickets)
662
+** * tech notes (--technotes)
663
+** * wiki pages (--wiki)
664
+** * built-in fossil help text (-h)
665
+** * all of the above (-a)
666
+**
667
+** Use options below to select the scope of the search. The
668
+** default is check-in comments only (-c).
669
+**
670
+** Output is colorized if writing to a TTY and if the NO_COLOR environment
671
+** variable is not set. Use the "--highlight 0" option to disable colorization
672
+** or use "--highlight 91" to force it on. Change the argument to --highlight
673
+** to change the color.
663674
**
664675
** Options:
665676
** -a|--all Search everything
666677
** -c|--checkins Search checkin comments
667678
** --docs Search embedded documentation
668679
** --forum Search forum posts
669680
** -h|--bi-help Search built-in help
681
+** --highlight N Used VT100 color N for matching text. 0 means "off".
670682
** -n|--limit N Limit output to N matches
671683
** --technotes Search tech notes
672684
** --tickets Search tickets
673685
** -W|--width WIDTH Set display width to WIDTH columns, 0 for
674686
** unlimited. Defaults to the terminal's width.
@@ -687,14 +699,24 @@
687699
const char *zScope = 0;
688700
const char *zWidth = find_option("width","W",1);
689701
int bDebug = find_option("debug",0,0)!=0; /* Undocumented */
690702
int nLimit = zLimit ? atoi(zLimit) : -1000;
691703
int width;
692
- int nTty = fossil_isatty(1) ? 91 : 0;
704
+ int nTty = 0; /* VT100 highlight color for matching text */
705
+ const char *zHighlight = 0;
706
+
707
+ /* Only colorize the output if talking to a tty and NO_COLOR does not
708
+ ** exist or is false. */
709
+ if( fossil_isatty(1) ){
710
+ char *zNoColor = fossil_getenv("NO_COLOR");
711
+ if( zNoColor==0 || zNoColor[0]==0 || is_false(zNoColor) ){
712
+ nTty = 91;
713
+ }
714
+ }
693715
694716
/* Undocumented option to change highlight color */
695
- const char *zHighlight = find_option("highlight",0,1);
717
+ zHighlight = find_option("highlight",0,1);
696718
if( zHighlight ) nTty = atoi(zHighlight);
697719
698720
/* Undocumented option (legacy) */
699721
zScope = find_option("scope",0,1);
700722
@@ -1036,21 +1058,28 @@
10361058
" FROM event JOIN blob on event.objid=blob.rid"
10371059
" WHERE search_match('',body('f',rid,NULL));"
10381060
);
10391061
}
10401062
if( (srchFlags & SRCH_HELP)!=0 ){
1063
+ const char *zPrefix;
10411064
helptext_vtab_register(g.db);
1065
+ if( srchFlags==SRCH_HELP ){
1066
+ zPrefix = "The";
1067
+ }else{
1068
+ zPrefix = "Built-in help for the";
1069
+ }
10421070
db_multi_exec(
10431071
"INSERT INTO x(label,url,score,id,snip)"
1044
- " SELECT format('Built-in help for the \"%%s\" %%s',name,type),"
1072
+ " SELECT format('%q \"%%s\" %%s',name,type),"
10451073
" '/help?cmd='||name,"
10461074
" search_score(),"
10471075
" 'h'||rowid,"
10481076
" search_snippet()"
10491077
" FROM helptext"
10501078
" WHERE search_match(format('the \"%%s\" %%s',name,type),"
1051
- " helptext.helptext);"
1079
+ " helptext.helptext);",
1080
+ zPrefix
10521081
);
10531082
}
10541083
}
10551084
10561085
/*
@@ -2262,32 +2291,32 @@
22622291
}
22632292
fossil_print(" done\n");
22642293
}
22652294
22662295
/*
2267
-** COMMAND: fts-config*
2296
+** COMMAND: fts-config* abbreviated-subcommands
22682297
**
22692298
** Usage: fossil fts-config ?SUBCOMMAND? ?ARGUMENT?
22702299
**
22712300
** The "fossil fts-config" command configures the full-text search capabilities
22722301
** of the repository. Subcommands:
22732302
**
2274
-** reindex Rebuild the search index. This is a no-op if
2275
-** index search is disabled
2276
-**
2277
-** index (on|off) Turn the search index on or off
2278
-**
2279
-** enable TYPE .. Enable search for TYPE. TYPE is one of:
2280
-** check-in, document, ticket, wiki, technote,
2281
-** forum, help, or all
2282
-**
2283
-** disable TYPE ... Disable search for TYPE
2284
-**
2285
-** tokenizer VALUE Select a tokenizer for indexed search. VALUE
2286
-** may be one of (porter, on, off, trigram, unicode61),
2287
-** and "on" is equivalent to "porter". Unindexed
2288
-** search never uses tokenization or stemming.
2303
+** reindex Rebuild the search index. This is a no-op if
2304
+** index search is disabled
2305
+**
2306
+** index (on|off) Turn the search index on or off
2307
+**
2308
+** enable TYPE .. Enable search for TYPE. TYPE is one of:
2309
+** check-in, document, ticket, wiki, technote,
2310
+** forum, help, or all
2311
+**
2312
+** disable TYPE ... Disable search for TYPE
2313
+**
2314
+** tokenizer VALUE Select a tokenizer for indexed search. VALUE
2315
+** may be one of (porter, on, off, trigram, unicode61),
2316
+** and "on" is equivalent to "porter". Unindexed
2317
+** search never uses tokenization or stemming.
22892318
**
22902319
** The current search settings are displayed after any changes are applied.
22912320
** Run this command with no arguments to simply see the settings.
22922321
*/
22932322
void fts_config_cmd(void){
22942323
--- src/search.c
+++ src/search.c
@@ -630,10 +630,14 @@
630 zSnip[k++] = '&';
631 j += 4;
632 }else{
633 zSnip[k++] = c;
634 }
 
 
 
 
635 }else{
636 zSnip[k++] = c;
637 }
638 }
639 zSnip[k] = 0;
@@ -645,30 +649,38 @@
645 **
646 ** COMMAND: search*
647 **
648 ** Usage: %fossil search [OPTIONS] PATTERN...
649 **
650 ** Search the repository database for PATTERN and show matches.
651 ** The following elements of the repository can be searched:
652 **
653 ** * check-in comments
654 ** * embedded documentation
655 ** * forum posts
656 ** * tickets
657 ** * tech notes
658 ** * wiki pages
659 ** * built-in fossil help text
660 **
661 ** Use options (listed below) to select the scope of the search. The
662 ** default is check-in comments only.
 
 
 
 
 
 
 
663 **
664 ** Options:
665 ** -a|--all Search everything
666 ** -c|--checkins Search checkin comments
667 ** --docs Search embedded documentation
668 ** --forum Search forum posts
669 ** -h|--bi-help Search built-in help
 
670 ** -n|--limit N Limit output to N matches
671 ** --technotes Search tech notes
672 ** --tickets Search tickets
673 ** -W|--width WIDTH Set display width to WIDTH columns, 0 for
674 ** unlimited. Defaults to the terminal's width.
@@ -687,14 +699,24 @@
687 const char *zScope = 0;
688 const char *zWidth = find_option("width","W",1);
689 int bDebug = find_option("debug",0,0)!=0; /* Undocumented */
690 int nLimit = zLimit ? atoi(zLimit) : -1000;
691 int width;
692 int nTty = fossil_isatty(1) ? 91 : 0;
 
 
 
 
 
 
 
 
 
 
693
694 /* Undocumented option to change highlight color */
695 const char *zHighlight = find_option("highlight",0,1);
696 if( zHighlight ) nTty = atoi(zHighlight);
697
698 /* Undocumented option (legacy) */
699 zScope = find_option("scope",0,1);
700
@@ -1036,21 +1058,28 @@
1036 " FROM event JOIN blob on event.objid=blob.rid"
1037 " WHERE search_match('',body('f',rid,NULL));"
1038 );
1039 }
1040 if( (srchFlags & SRCH_HELP)!=0 ){
 
1041 helptext_vtab_register(g.db);
 
 
 
 
 
1042 db_multi_exec(
1043 "INSERT INTO x(label,url,score,id,snip)"
1044 " SELECT format('Built-in help for the \"%%s\" %%s',name,type),"
1045 " '/help?cmd='||name,"
1046 " search_score(),"
1047 " 'h'||rowid,"
1048 " search_snippet()"
1049 " FROM helptext"
1050 " WHERE search_match(format('the \"%%s\" %%s',name,type),"
1051 " helptext.helptext);"
 
1052 );
1053 }
1054 }
1055
1056 /*
@@ -2262,32 +2291,32 @@
2262 }
2263 fossil_print(" done\n");
2264 }
2265
2266 /*
2267 ** COMMAND: fts-config*
2268 **
2269 ** Usage: fossil fts-config ?SUBCOMMAND? ?ARGUMENT?
2270 **
2271 ** The "fossil fts-config" command configures the full-text search capabilities
2272 ** of the repository. Subcommands:
2273 **
2274 ** reindex Rebuild the search index. This is a no-op if
2275 ** index search is disabled
2276 **
2277 ** index (on|off) Turn the search index on or off
2278 **
2279 ** enable TYPE .. Enable search for TYPE. TYPE is one of:
2280 ** check-in, document, ticket, wiki, technote,
2281 ** forum, help, or all
2282 **
2283 ** disable TYPE ... Disable search for TYPE
2284 **
2285 ** tokenizer VALUE Select a tokenizer for indexed search. VALUE
2286 ** may be one of (porter, on, off, trigram, unicode61),
2287 ** and "on" is equivalent to "porter". Unindexed
2288 ** search never uses tokenization or stemming.
2289 **
2290 ** The current search settings are displayed after any changes are applied.
2291 ** Run this command with no arguments to simply see the settings.
2292 */
2293 void fts_config_cmd(void){
2294
--- src/search.c
+++ src/search.c
@@ -630,10 +630,14 @@
630 zSnip[k++] = '&';
631 j += 4;
632 }else{
633 zSnip[k++] = c;
634 }
635 }else if( c=='%' && strncmp(&zSnip[j],"%fossil",7)==0 ){
636 /* no-op */
637 }else if( (c=='[' || c==']') && zSnip[j+1]==c ){
638 j++;
639 }else{
640 zSnip[k++] = c;
641 }
642 }
643 zSnip[k] = 0;
@@ -645,30 +649,38 @@
649 **
650 ** COMMAND: search*
651 **
652 ** Usage: %fossil search [OPTIONS] PATTERN...
653 **
654 ** Search the repository for PATTERN and show matches. Depending on
655 ** options and how the administrator has search configured for the
656 ** repository, the search can cover:
657 **
658 ** * check-in comments (-c)
659 ** * embedded documentation (--docs)
660 ** * forum posts (--forum)
661 ** * tickets (--tickets)
662 ** * tech notes (--technotes)
663 ** * wiki pages (--wiki)
664 ** * built-in fossil help text (-h)
665 ** * all of the above (-a)
666 **
667 ** Use options below to select the scope of the search. The
668 ** default is check-in comments only (-c).
669 **
670 ** Output is colorized if writing to a TTY and if the NO_COLOR environment
671 ** variable is not set. Use the "--highlight 0" option to disable colorization
672 ** or use "--highlight 91" to force it on. Change the argument to --highlight
673 ** to change the color.
674 **
675 ** Options:
676 ** -a|--all Search everything
677 ** -c|--checkins Search checkin comments
678 ** --docs Search embedded documentation
679 ** --forum Search forum posts
680 ** -h|--bi-help Search built-in help
681 ** --highlight N Used VT100 color N for matching text. 0 means "off".
682 ** -n|--limit N Limit output to N matches
683 ** --technotes Search tech notes
684 ** --tickets Search tickets
685 ** -W|--width WIDTH Set display width to WIDTH columns, 0 for
686 ** unlimited. Defaults to the terminal's width.
@@ -687,14 +699,24 @@
699 const char *zScope = 0;
700 const char *zWidth = find_option("width","W",1);
701 int bDebug = find_option("debug",0,0)!=0; /* Undocumented */
702 int nLimit = zLimit ? atoi(zLimit) : -1000;
703 int width;
704 int nTty = 0; /* VT100 highlight color for matching text */
705 const char *zHighlight = 0;
706
707 /* Only colorize the output if talking to a tty and NO_COLOR does not
708 ** exist or is false. */
709 if( fossil_isatty(1) ){
710 char *zNoColor = fossil_getenv("NO_COLOR");
711 if( zNoColor==0 || zNoColor[0]==0 || is_false(zNoColor) ){
712 nTty = 91;
713 }
714 }
715
716 /* Undocumented option to change highlight color */
717 zHighlight = find_option("highlight",0,1);
718 if( zHighlight ) nTty = atoi(zHighlight);
719
720 /* Undocumented option (legacy) */
721 zScope = find_option("scope",0,1);
722
@@ -1036,21 +1058,28 @@
1058 " FROM event JOIN blob on event.objid=blob.rid"
1059 " WHERE search_match('',body('f',rid,NULL));"
1060 );
1061 }
1062 if( (srchFlags & SRCH_HELP)!=0 ){
1063 const char *zPrefix;
1064 helptext_vtab_register(g.db);
1065 if( srchFlags==SRCH_HELP ){
1066 zPrefix = "The";
1067 }else{
1068 zPrefix = "Built-in help for the";
1069 }
1070 db_multi_exec(
1071 "INSERT INTO x(label,url,score,id,snip)"
1072 " SELECT format('%q \"%%s\" %%s',name,type),"
1073 " '/help?cmd='||name,"
1074 " search_score(),"
1075 " 'h'||rowid,"
1076 " search_snippet()"
1077 " FROM helptext"
1078 " WHERE search_match(format('the \"%%s\" %%s',name,type),"
1079 " helptext.helptext);",
1080 zPrefix
1081 );
1082 }
1083 }
1084
1085 /*
@@ -2262,32 +2291,32 @@
2291 }
2292 fossil_print(" done\n");
2293 }
2294
2295 /*
2296 ** COMMAND: fts-config* abbreviated-subcommands
2297 **
2298 ** Usage: fossil fts-config ?SUBCOMMAND? ?ARGUMENT?
2299 **
2300 ** The "fossil fts-config" command configures the full-text search capabilities
2301 ** of the repository. Subcommands:
2302 **
2303 ** reindex Rebuild the search index. This is a no-op if
2304 ** index search is disabled
2305 **
2306 ** index (on|off) Turn the search index on or off
2307 **
2308 ** enable TYPE .. Enable search for TYPE. TYPE is one of:
2309 ** check-in, document, ticket, wiki, technote,
2310 ** forum, help, or all
2311 **
2312 ** disable TYPE ... Disable search for TYPE
2313 **
2314 ** tokenizer VALUE Select a tokenizer for indexed search. VALUE
2315 ** may be one of (porter, on, off, trigram, unicode61),
2316 ** and "on" is equivalent to "porter". Unindexed
2317 ** search never uses tokenization or stemming.
2318 **
2319 ** The current search settings are displayed after any changes are applied.
2320 ** Run this command with no arguments to simply see the settings.
2321 */
2322 void fts_config_cmd(void){
2323
--- src/unversioned.c
+++ src/unversioned.c
@@ -218,12 +218,12 @@
218218
}
219219
return 0;
220220
}
221221
222222
/*
223
-** COMMAND: uv#
224
-** COMMAND: unversioned
223
+** COMMAND: uv# abbreviated-subcommands
224
+** COMMAND: unversioned abbreviated-subcommands
225225
**
226226
** Usage: %fossil unversioned SUBCOMMAND ARGS...
227227
** or: %fossil uv SUBCOMMAND ARGS..
228228
**
229229
** Unversioned files (UV-files) are artifacts that are synced and are available
230230
--- src/unversioned.c
+++ src/unversioned.c
@@ -218,12 +218,12 @@
218 }
219 return 0;
220 }
221
222 /*
223 ** COMMAND: uv#
224 ** COMMAND: unversioned
225 **
226 ** Usage: %fossil unversioned SUBCOMMAND ARGS...
227 ** or: %fossil uv SUBCOMMAND ARGS..
228 **
229 ** Unversioned files (UV-files) are artifacts that are synced and are available
230
--- src/unversioned.c
+++ src/unversioned.c
@@ -218,12 +218,12 @@
218 }
219 return 0;
220 }
221
222 /*
223 ** COMMAND: uv# abbreviated-subcommands
224 ** COMMAND: unversioned abbreviated-subcommands
225 **
226 ** Usage: %fossil unversioned SUBCOMMAND ARGS...
227 ** or: %fossil uv SUBCOMMAND ARGS..
228 **
229 ** Unversioned files (UV-files) are artifacts that are synced and are available
230
+1 -2
--- src/user.c
+++ src/user.c
@@ -331,12 +331,11 @@
331331
** > fossil user default ?USERNAME?
332332
**
333333
** Query or set the default user. The default user is the
334334
** user for command-line interaction.
335335
**
336
-** > fossil user list
337
-** > fossil user ls
336
+** > fossil user list | ls
338337
**
339338
** List all users known to the repository
340339
**
341340
** > fossil user new ?USERNAME? ?CONTACT-INFO? ?PASSWORD?
342341
**
343342
--- src/user.c
+++ src/user.c
@@ -331,12 +331,11 @@
331 ** > fossil user default ?USERNAME?
332 **
333 ** Query or set the default user. The default user is the
334 ** user for command-line interaction.
335 **
336 ** > fossil user list
337 ** > fossil user ls
338 **
339 ** List all users known to the repository
340 **
341 ** > fossil user new ?USERNAME? ?CONTACT-INFO? ?PASSWORD?
342 **
343
--- src/user.c
+++ src/user.c
@@ -331,12 +331,11 @@
331 ** > fossil user default ?USERNAME?
332 **
333 ** Query or set the default user. The default user is the
334 ** user for command-line interaction.
335 **
336 ** > fossil user list | ls
 
337 **
338 ** List all users known to the repository
339 **
340 ** > fossil user new ?USERNAME? ?CONTACT-INFO? ?PASSWORD?
341 **
342
+1 -1
--- src/utf8.c
+++ src/utf8.c
@@ -25,11 +25,11 @@
2525
#ifdef _WIN32
2626
# include <windows.h>
2727
#endif
2828
#include "cygsup.h"
2929
30
-#if defined(_WIN32) || defined(__CYGWIN__)
30
+#if defined(_WIN32)
3131
/*
3232
** Translate MBCS to UTF-8. Return a pointer to the translated text.
3333
** Call fossil_mbcs_free() to deallocate any memory used to store the
3434
** returned pointer when done.
3535
*/
3636
--- src/utf8.c
+++ src/utf8.c
@@ -25,11 +25,11 @@
25 #ifdef _WIN32
26 # include <windows.h>
27 #endif
28 #include "cygsup.h"
29
30 #if defined(_WIN32) || defined(__CYGWIN__)
31 /*
32 ** Translate MBCS to UTF-8. Return a pointer to the translated text.
33 ** Call fossil_mbcs_free() to deallocate any memory used to store the
34 ** returned pointer when done.
35 */
36
--- src/utf8.c
+++ src/utf8.c
@@ -25,11 +25,11 @@
25 #ifdef _WIN32
26 # include <windows.h>
27 #endif
28 #include "cygsup.h"
29
30 #if defined(_WIN32)
31 /*
32 ** Translate MBCS to UTF-8. Return a pointer to the translated text.
33 ** Call fossil_mbcs_free() to deallocate any memory used to store the
34 ** returned pointer when done.
35 */
36
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -100,10 +100,11 @@
100100
#define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
101101
#define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
102102
#define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
103103
#define CMDFLAG_ALIAS 0x2000 /* Command aliases */
104104
#define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
105
+#define CMDFLAG_ABBREVSUBCMD 0x8000 /* Abbreviated subcmd in help text */
105106
/**************************************************************************/
106107
107108
/*
108109
** Each entry looks like this:
109110
*/
@@ -280,10 +281,12 @@
280281
aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
281282
}else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
282283
aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
283284
}else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
284285
aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
286
+ }else if( j==23 && strncmp(&zLine[i], "abbreviated-subcommands", 23)==0 ){
287
+ aEntry[nUsed].eType |= CMDFLAG_ABBREVSUBCMD;
285288
}else{
286289
fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
287290
zFile, nLine, j, &zLine[i]);
288291
nErr++;
289292
}
290293
291294
ADDED win/build32.bat
292295
ADDED win/build64.bat
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -100,10 +100,11 @@
100 #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
101 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
102 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
103 #define CMDFLAG_ALIAS 0x2000 /* Command aliases */
104 #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
 
105 /**************************************************************************/
106
107 /*
108 ** Each entry looks like this:
109 */
@@ -280,10 +281,12 @@
280 aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
281 }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
282 aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
283 }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
284 aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
 
 
285 }else{
286 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
287 zFile, nLine, j, &zLine[i]);
288 nErr++;
289 }
290
291 DDED win/build32.bat
292 DDED win/build64.bat
--- tools/mkindex.c
+++ tools/mkindex.c
@@ -100,10 +100,11 @@
100 #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */
101 #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */
102 #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */
103 #define CMDFLAG_ALIAS 0x2000 /* Command aliases */
104 #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */
105 #define CMDFLAG_ABBREVSUBCMD 0x8000 /* Abbreviated subcmd in help text */
106 /**************************************************************************/
107
108 /*
109 ** Each entry looks like this:
110 */
@@ -280,10 +281,12 @@
281 aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9);
282 }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){
283 aEntry[nUsed].eType |= CMDFLAG_HIDDEN;
284 }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){
285 aEntry[nUsed].eType |= CMDFLAG_LDAVG_EXEMPT;
286 }else if( j==23 && strncmp(&zLine[i], "abbreviated-subcommands", 23)==0 ){
287 aEntry[nUsed].eType |= CMDFLAG_ABBREVSUBCMD;
288 }else{
289 fprintf(stderr, "%s:%d: unknown option: '%.*s'\n",
290 zFile, nLine, j, &zLine[i]);
291 nErr++;
292 }
293
294 DDED win/build32.bat
295 DDED win/build64.bat
--- a/win/build32.bat
+++ b/win/build32.bat
@@ -0,0 +1,3 @@
1
+REM Based on /wiki/Release%20Build%20How-To
2
+nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_ENABLE_WINXP=1 OPTIMIZATIONS=4 clean fossil.exe
3
+dumpbin /dependents fossil.exe
--- a/win/build32.bat
+++ b/win/build32.bat
@@ -0,0 +1,3 @@
 
 
 
--- a/win/build32.bat
+++ b/win/build32.bat
@@ -0,0 +1,3 @@
1 REM Based on /wiki/Release%20Build%20How-To
2 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_ENABLE_WINXP=1 OPTIMIZATIONS=4 clean fossil.exe
3 dumpbin /dependents fossil.exe
--- a/win/build64.bat
+++ b/win/build64.bat
@@ -0,0 +1,3 @@
1
+REM Based on /wiki/Release%20Build%20How-To
2
+nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 OPTIMIZATIONS=4 clean fossil.exe
3
+dumpbin /dependents fossil.exe
--- a/win/build64.bat
+++ b/win/build64.bat
@@ -0,0 +1,3 @@
 
 
 
--- a/win/build64.bat
+++ b/win/build64.bat
@@ -0,0 +1,3 @@
1 REM Based on /wiki/Release%20Build%20How-To
2 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 OPTIMIZATIONS=4 clean fossil.exe
3 dumpbin /dependents fossil.exe
+7 -19
--- www/build.wiki
+++ www/build.wiki
@@ -340,48 +340,36 @@
340340
found in the help text for the [/help?cmd=test-fuzz|test-fuzz
341341
command].
342342
343343
Fuzzing requires:
344344
345
- * Customizing the build of fossil a small bit.
346345
* The clang C compiler.
347346
* libfuzzer. On Ubuntu-derived systems, it can be installed with
348347
<tt>apt install libfuzzer-XYZ</tt>, where XYZ is a version number
349348
(several versions may be available on any given system)
350349
351350
352
-First, modify the top-level <tt>Makefile.in</tt>:
353
-
354
- * Extend the <tt>TCCFLAGS</tt> variable with: <tt>-fsanitize=fuzzer
355
- -DFOSSIL_FUZZ</tt> (and see [/finfo/src/fuzz.c | src/fuzz.c] for
356
- more options).
357
- * Rename <tt>APPNAME</tt> from <tt>fossil</tt> to <tt>fossil-fuzz</tt>.
358
-
359
-Then rebuild:
360
-
361
-<pre></code>$ make clean
362
-$ ./configure CC=/path/to/clang
363
-$ make
351
+Compile as follows:
352
+
353
+<pre><code>make clean
354
+make TCCFLAGS='-DFOSSIL_FUZZ -fsanitize=fuzzer,address,undefined -O0 -g' CC=clang
364355
</code></pre>
365356
366
-If clang is your default compiler, the <tt>CC</tt> configure option is
367
-not required.
368
-
369
-The resulting <tt>fossil-fuzz</tt> binary differs from the standard
357
+The resulting <tt>fossil</tt> binary differs from the standard
370358
one primarily in that it runs the <tt>test-fuzz</tt> command by
371359
default. It needs to be told what to fuzz and needs to be given a
372360
directory of input files to seed the fuzzer with:
373361
374362
375
-<pre></code>$ mkdir cases
363
+<pre><code>$ mkdir cases
376364
# Copy input files into ./cases. e.g. when fuzzing the markdown
377365
# processor, copy any to-be-tested .md files into that directory.
378366
# Then start the fuzzer:
379367
$ ./fossil-fuzz --fuzztype markdown cases
380368
</code></pre>
381369
382
-As it works, it writes its mutated test files into the test-input
370
+As it works, it writes its mutated test files into the "cases"
383371
directory, each one named in the form of a hash. When it finds a
384372
problem it will produce a stack trace for the offending code, will
385373
output the name of the file which triggered the crash (named
386374
<tt>cases/SOME_HASH</tt>) and may, depending on the nature of the
387375
problem, produce a file named <tt>crash-SOMETHING</tt>. In theory the
388376
--- www/build.wiki
+++ www/build.wiki
@@ -340,48 +340,36 @@
340 found in the help text for the [/help?cmd=test-fuzz|test-fuzz
341 command].
342
343 Fuzzing requires:
344
345 * Customizing the build of fossil a small bit.
346 * The clang C compiler.
347 * libfuzzer. On Ubuntu-derived systems, it can be installed with
348 <tt>apt install libfuzzer-XYZ</tt>, where XYZ is a version number
349 (several versions may be available on any given system)
350
351
352 First, modify the top-level <tt>Makefile.in</tt>:
353
354 * Extend the <tt>TCCFLAGS</tt> variable with: <tt>-fsanitize=fuzzer
355 -DFOSSIL_FUZZ</tt> (and see [/finfo/src/fuzz.c | src/fuzz.c] for
356 more options).
357 * Rename <tt>APPNAME</tt> from <tt>fossil</tt> to <tt>fossil-fuzz</tt>.
358
359 Then rebuild:
360
361 <pre></code>$ make clean
362 $ ./configure CC=/path/to/clang
363 $ make
364 </code></pre>
365
366 If clang is your default compiler, the <tt>CC</tt> configure option is
367 not required.
368
369 The resulting <tt>fossil-fuzz</tt> binary differs from the standard
370 one primarily in that it runs the <tt>test-fuzz</tt> command by
371 default. It needs to be told what to fuzz and needs to be given a
372 directory of input files to seed the fuzzer with:
373
374
375 <pre></code>$ mkdir cases
376 # Copy input files into ./cases. e.g. when fuzzing the markdown
377 # processor, copy any to-be-tested .md files into that directory.
378 # Then start the fuzzer:
379 $ ./fossil-fuzz --fuzztype markdown cases
380 </code></pre>
381
382 As it works, it writes its mutated test files into the test-input
383 directory, each one named in the form of a hash. When it finds a
384 problem it will produce a stack trace for the offending code, will
385 output the name of the file which triggered the crash (named
386 <tt>cases/SOME_HASH</tt>) and may, depending on the nature of the
387 problem, produce a file named <tt>crash-SOMETHING</tt>. In theory the
388
--- www/build.wiki
+++ www/build.wiki
@@ -340,48 +340,36 @@
340 found in the help text for the [/help?cmd=test-fuzz|test-fuzz
341 command].
342
343 Fuzzing requires:
344
 
345 * The clang C compiler.
346 * libfuzzer. On Ubuntu-derived systems, it can be installed with
347 <tt>apt install libfuzzer-XYZ</tt>, where XYZ is a version number
348 (several versions may be available on any given system)
349
350
351 Compile as follows:
352
353 <pre><code>make clean
354 make TCCFLAGS='-DFOSSIL_FUZZ -fsanitize=fuzzer,address,undefined -O0 -g' CC=clang
 
 
 
 
 
 
 
 
355 </code></pre>
356
357 The resulting <tt>fossil</tt> binary differs from the standard
 
 
 
358 one primarily in that it runs the <tt>test-fuzz</tt> command by
359 default. It needs to be told what to fuzz and needs to be given a
360 directory of input files to seed the fuzzer with:
361
362
363 <pre><code>$ mkdir cases
364 # Copy input files into ./cases. e.g. when fuzzing the markdown
365 # processor, copy any to-be-tested .md files into that directory.
366 # Then start the fuzzer:
367 $ ./fossil-fuzz --fuzztype markdown cases
368 </code></pre>
369
370 As it works, it writes its mutated test files into the "cases"
371 directory, each one named in the form of a hash. When it finds a
372 problem it will produce a stack trace for the offending code, will
373 output the name of the file which triggered the crash (named
374 <tt>cases/SOME_HASH</tt>) and may, depending on the nature of the
375 problem, produce a file named <tt>crash-SOMETHING</tt>. In theory the
376
--- www/changes.wiki
+++ www/changes.wiki
@@ -53,10 +53,12 @@
5353
and debugging
5454
* Fix a bug in [/help?cmd=patch|fossil patch create] that causes
5555
[/help?cmd=revert|fossil revert] operations that happened on individual
5656
files after a [/help?cmd=merge|fossil merge] to be omitted from the
5757
patch.
58
+ * Added the [/help?cmd=patch|patch alias] command for managing aliases
59
+ for remote checkout names.
5860
5961
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
6062
6163
* The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
6264
that have non-ASCII filenames
6365
--- www/changes.wiki
+++ www/changes.wiki
@@ -53,10 +53,12 @@
53 and debugging
54 * Fix a bug in [/help?cmd=patch|fossil patch create] that causes
55 [/help?cmd=revert|fossil revert] operations that happened on individual
56 files after a [/help?cmd=merge|fossil merge] to be omitted from the
57 patch.
 
 
58
59 <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
60
61 * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
62 that have non-ASCII filenames
63
--- www/changes.wiki
+++ www/changes.wiki
@@ -53,10 +53,12 @@
53 and debugging
54 * Fix a bug in [/help?cmd=patch|fossil patch create] that causes
55 [/help?cmd=revert|fossil revert] operations that happened on individual
56 files after a [/help?cmd=merge|fossil merge] to be omitted from the
57 patch.
58 * Added the [/help?cmd=patch|patch alias] command for managing aliases
59 for remote checkout names.
60
61 <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
62
63 * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
64 that have non-ASCII filenames
65

Keyboard Shortcuts

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