Fossil SCM
Merge from trunk.
Commit
b591622016a515c46be58151abf92c093f781c85b911bca71d479d1113d37d71
Parent
58ecb3a4d2c6d6c…
34 files changed
+38
-16
+30
+4
-4
+256
-244
+751
-617
+1
-1
+1
-1
+1
-1
+7
-7
+1
-1
+7
-4
+314
-36
+2
+1
-1
+12
-1
+6
-6
+12
-12
+12
-12
+3
-3
+1
-2
+1
-1
+93
-4
+1
-1
+39
+62
-33
+2
-2
+1
-2
+1
-1
+3
+3
+3
+7
-19
+2
~
auto.def
~
autosetup/local.tcl
~
extsrc/pikchr-worker.js
~
extsrc/pikchr.c
~
extsrc/pikchr.js
~
extsrc/pikchr.wasm
~
src/alerts.c
~
src/allrepo.c
~
src/blob.c
~
src/branch.c
~
src/cache.c
~
src/comformat.c
~
src/dispatch.c
~
src/export.c
~
src/fossil.page.pikchrshowasm.js
~
src/fuzz.c
~
src/hook.c
~
src/http_ssl.c
~
src/http_ssl.c
~
src/interwiki.c
~
src/main.c
~
src/main.mk
~
src/patch.c
~
src/rebuild.c
~
src/regexp.c
~
src/search.c
~
src/unversioned.c
~
src/user.c
~
src/utf8.c
~
tools/mkindex.c
~
win/build32.bat
~
win/build64.bat
~
www/build.wiki
~
www/changes.wiki
M
auto.def
+38
-16
| --- auto.def | ||
| +++ auto.def | ||
| @@ -337,12 +337,12 @@ | ||
| 337 | 337 | } |
| 338 | 338 | |
| 339 | 339 | # Check for libraries that need to be sorted out early |
| 340 | 340 | cc-check-function-in-lib iconv iconv |
| 341 | 341 | |
| 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 | |
| 344 | 344 | |
| 345 | 345 | # Helper for OpenSSL checking |
| 346 | 346 | proc check-for-openssl {msg {cflags {}} {libs {-lssl -lcrypto -lpthread}}} { |
| 347 | 347 | msg-checking "Checking for $msg..." |
| 348 | 348 | set rc 0 |
| @@ -507,10 +507,12 @@ | ||
| 507 | 507 | set ssllibs "$dir/libssl.a $dir/libcrypto.a -lpthread" |
| 508 | 508 | if {[check-for-openssl $msg "$cflags $ldflags" $ssllibs]} { |
| 509 | 509 | incr found |
| 510 | 510 | break |
| 511 | 511 | } |
| 512 | + # This test should arguably fail here if --with-openssl=X | |
| 513 | + # points to an invalid X. | |
| 512 | 514 | } |
| 513 | 515 | } |
| 514 | 516 | } |
| 515 | 517 | } |
| 516 | 518 | if {$found} { |
| @@ -862,24 +864,10 @@ | ||
| 862 | 864 | # We need to link with libubsan if we're compiling under |
| 863 | 865 | # GCC with -fsanitize=undefined. |
| 864 | 866 | cc-check-function-in-lib __ubsan_handle_add_overflow ubsan |
| 865 | 867 | } |
| 866 | 868 | } |
| 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 | 869 | |
| 882 | 870 | ######################################################################## |
| 883 | 871 | # @proj-check-emsdk |
| 884 | 872 | # |
| 885 | 873 | # Emscripten is used for doing in-tree builds of web-based WASM stuff, |
| @@ -958,10 +946,44 @@ | ||
| 958 | 946 | define EMCC_OPT "" |
| 959 | 947 | catch {exec rm -f tools/emcc.sh} |
| 960 | 948 | } |
| 961 | 949 | |
| 962 | 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 | +}} | |
| 963 | 985 | |
| 964 | 986 | # Tag container builds with a prefix of the checkin ID of the version |
| 965 | 987 | # of Fossil each one contains. This not only allows multiple images |
| 966 | 988 | # to coexist and multiple containers to be created unamgiguosly from |
| 967 | 989 | # them, it also changes the URL we fetch the source tarball from, so |
| 968 | 990 |
| --- 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 |
+30
| --- autosetup/local.tcl | ||
| +++ autosetup/local.tcl | ||
| @@ -27,5 +27,35 @@ | ||
| 27 | 27 | set tclconfig($name) [string trim $value '] |
| 28 | 28 | } |
| 29 | 29 | } |
| 30 | 30 | return [array get tclconfig] |
| 31 | 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 | +} | |
| 32 | 62 |
| --- 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 |
+4
-4
| --- extsrc/pikchr-worker.js | ||
| +++ extsrc/pikchr-worker.js | ||
| @@ -36,11 +36,11 @@ | ||
| 36 | 36 | pikchr: source code for the pikchr, |
| 37 | 37 | darkMode: boolean true to adjust colors for a dark color scheme, |
| 38 | 38 | cssClass: CSS class name to add to the SVG |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | - Workers-to-Main types | |
| 41 | + Workers-to-Main message types: | |
| 42 | 42 | |
| 43 | 43 | - stdout, stderr: indicate stdout/stderr output from the wasm |
| 44 | 44 | layer. The data property is the string of the output, noting |
| 45 | 45 | that the emscripten binding emits these one line at a time. Thus, |
| 46 | 46 | if a C-side puts() emits multiple lines in a single call, the JS |
| @@ -50,21 +50,21 @@ | ||
| 50 | 50 | |
| 51 | 51 | - module: Status text. This is intended to alert the main thread |
| 52 | 52 | about module loading status so that, e.g., the main thread can |
| 53 | 53 | update a progress widget and DTRT when the module is finished |
| 54 | 54 | loading and available for work. Status messages come in the form |
| 55 | - | |
| 55 | + | |
| 56 | 56 | {type:'module', data:{ |
| 57 | 57 | type:'status', |
| 58 | 58 | data: {text:string|null, step:1-based-integer} |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | with an incrementing step value for each subsequent message. When |
| 62 | 62 | the module loading is complete, a message with a text value of |
| 63 | 63 | null is posted. |
| 64 | 64 | |
| 65 | - - pikchr: | |
| 65 | + - pikchr: | |
| 66 | 66 | |
| 67 | 67 | {type: 'pikchr', |
| 68 | 68 | data:{ |
| 69 | 69 | pikchr: input text, |
| 70 | 70 | result: rendered result (SVG on success, HTML on error), |
| @@ -162,11 +162,11 @@ | ||
| 162 | 162 | } |
| 163 | 163 | return; |
| 164 | 164 | }; |
| 165 | 165 | console.warn("Unknown pikchr-worker message type:",ev); |
| 166 | 166 | }; |
| 167 | - | |
| 167 | + | |
| 168 | 168 | /** |
| 169 | 169 | emscripten module for use with build mode -sMODULARIZE. |
| 170 | 170 | */ |
| 171 | 171 | const pikchrModule = { |
| 172 | 172 | print: function(){wMsg('stdout', Array.prototype.slice.call(arguments));}, |
| 173 | 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 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 @@ | ||
| 125 | 125 | #include <assert.h> |
| 126 | 126 | #define count(X) (sizeof(X)/sizeof(X[0])) |
| 127 | 127 | #ifndef M_PI |
| 128 | 128 | # define M_PI 3.1415926535897932385 |
| 129 | 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 | + | |
| 130 | 142 | |
| 131 | 143 | /* Limit the number of tokens in a single script to avoid run-away |
| 132 | 144 | ** macro expansion attacks. See forum post |
| 133 | 145 | ** https://pikchr.org/home/forumpost/ef8684c6955a411a |
| 134 | 146 | */ |
| @@ -492,11 +504,11 @@ | ||
| 492 | 504 | static PObj *pik_position_assert(Pik*,PPoint*,PToken*,PPoint*); |
| 493 | 505 | static PNum pik_dist(PPoint*,PPoint*); |
| 494 | 506 | static void pik_add_macro(Pik*,PToken *pId,PToken *pCode); |
| 495 | 507 | |
| 496 | 508 | |
| 497 | -#line 523 "pikchr.c" | |
| 509 | +#line 535 "pikchr.c" | |
| 498 | 510 | /**************** End of %include directives **********************************/ |
| 499 | 511 | /* These constants specify the various numeric values for terminal symbols. |
| 500 | 512 | ***************** Begin token definitions *************************************/ |
| 501 | 513 | #ifndef T_ID |
| 502 | 514 | #define T_ID 1 |
| @@ -1745,22 +1757,22 @@ | ||
| 1745 | 1757 | ** inside the C code. |
| 1746 | 1758 | */ |
| 1747 | 1759 | /********* Begin destructor definitions ***************************************/ |
| 1748 | 1760 | case 100: /* statement_list */ |
| 1749 | 1761 | { |
| 1750 | -#line 511 "pikchr.y" | |
| 1762 | +#line 523 "pikchr.y" | |
| 1751 | 1763 | pik_elist_free(p,(yypminor->yy235)); |
| 1752 | -#line 1777 "pikchr.c" | |
| 1764 | +#line 1789 "pikchr.c" | |
| 1753 | 1765 | } |
| 1754 | 1766 | break; |
| 1755 | 1767 | case 101: /* statement */ |
| 1756 | 1768 | case 102: /* unnamed_statement */ |
| 1757 | 1769 | case 103: /* basetype */ |
| 1758 | 1770 | { |
| 1759 | -#line 513 "pikchr.y" | |
| 1771 | +#line 525 "pikchr.y" | |
| 1760 | 1772 | pik_elem_free(p,(yypminor->yy162)); |
| 1761 | -#line 1786 "pikchr.c" | |
| 1773 | +#line 1798 "pikchr.c" | |
| 1762 | 1774 | } |
| 1763 | 1775 | break; |
| 1764 | 1776 | /********* End destructor definitions *****************************************/ |
| 1765 | 1777 | default: break; /* If no destructor action specified: do nothing */ |
| 1766 | 1778 | } |
| @@ -1991,14 +2003,14 @@ | ||
| 1991 | 2003 | #endif |
| 1992 | 2004 | while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); |
| 1993 | 2005 | /* Here code is inserted which will execute if the parser |
| 1994 | 2006 | ** stack every overflows */ |
| 1995 | 2007 | /******** Begin %stack_overflow code ******************************************/ |
| 1996 | -#line 545 "pikchr.y" | |
| 2008 | +#line 557 "pikchr.y" | |
| 1997 | 2009 | |
| 1998 | 2010 | pik_error(p, 0, "parser stack overflow"); |
| 1999 | -#line 2024 "pikchr.c" | |
| 2011 | +#line 2036 "pikchr.c" | |
| 2000 | 2012 | /******** End %stack_overflow code ********************************************/ |
| 2001 | 2013 | pik_parserARG_STORE /* Suppress warning about unused %extra_argument var */ |
| 2002 | 2014 | pik_parserCTX_STORE |
| 2003 | 2015 | } |
| 2004 | 2016 | |
| @@ -2419,619 +2431,619 @@ | ||
| 2419 | 2431 | ** break; |
| 2420 | 2432 | */ |
| 2421 | 2433 | /********** Begin reduce actions **********************************************/ |
| 2422 | 2434 | YYMINORTYPE yylhsminor; |
| 2423 | 2435 | case 0: /* document ::= statement_list */ |
| 2424 | -#line 549 "pikchr.y" | |
| 2436 | +#line 561 "pikchr.y" | |
| 2425 | 2437 | {pik_render(p,yymsp[0].minor.yy235);} |
| 2426 | -#line 2451 "pikchr.c" | |
| 2438 | +#line 2463 "pikchr.c" | |
| 2427 | 2439 | break; |
| 2428 | 2440 | case 1: /* statement_list ::= statement */ |
| 2429 | -#line 552 "pikchr.y" | |
| 2441 | +#line 564 "pikchr.y" | |
| 2430 | 2442 | { yylhsminor.yy235 = pik_elist_append(p,0,yymsp[0].minor.yy162); } |
| 2431 | -#line 2456 "pikchr.c" | |
| 2443 | +#line 2468 "pikchr.c" | |
| 2432 | 2444 | yymsp[0].minor.yy235 = yylhsminor.yy235; |
| 2433 | 2445 | break; |
| 2434 | 2446 | case 2: /* statement_list ::= statement_list EOL statement */ |
| 2435 | -#line 554 "pikchr.y" | |
| 2447 | +#line 566 "pikchr.y" | |
| 2436 | 2448 | { yylhsminor.yy235 = pik_elist_append(p,yymsp[-2].minor.yy235,yymsp[0].minor.yy162); } |
| 2437 | -#line 2462 "pikchr.c" | |
| 2449 | +#line 2474 "pikchr.c" | |
| 2438 | 2450 | yymsp[-2].minor.yy235 = yylhsminor.yy235; |
| 2439 | 2451 | break; |
| 2440 | 2452 | case 3: /* statement ::= */ |
| 2441 | -#line 557 "pikchr.y" | |
| 2453 | +#line 569 "pikchr.y" | |
| 2442 | 2454 | { yymsp[1].minor.yy162 = 0; } |
| 2443 | -#line 2468 "pikchr.c" | |
| 2455 | +#line 2480 "pikchr.c" | |
| 2444 | 2456 | break; |
| 2445 | 2457 | case 4: /* statement ::= direction */ |
| 2446 | -#line 558 "pikchr.y" | |
| 2458 | +#line 570 "pikchr.y" | |
| 2447 | 2459 | { pik_set_direction(p,yymsp[0].minor.yy0.eCode); yylhsminor.yy162=0; } |
| 2448 | -#line 2473 "pikchr.c" | |
| 2460 | +#line 2485 "pikchr.c" | |
| 2449 | 2461 | yymsp[0].minor.yy162 = yylhsminor.yy162; |
| 2450 | 2462 | break; |
| 2451 | 2463 | case 5: /* statement ::= lvalue ASSIGN rvalue */ |
| 2452 | -#line 559 "pikchr.y" | |
| 2464 | +#line 571 "pikchr.y" | |
| 2453 | 2465 | {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" | |
| 2455 | 2467 | yymsp[-2].minor.yy162 = yylhsminor.yy162; |
| 2456 | 2468 | break; |
| 2457 | 2469 | case 6: /* statement ::= PLACENAME COLON unnamed_statement */ |
| 2458 | -#line 561 "pikchr.y" | |
| 2470 | +#line 573 "pikchr.y" | |
| 2459 | 2471 | { 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" | |
| 2461 | 2473 | yymsp[-2].minor.yy162 = yylhsminor.yy162; |
| 2462 | 2474 | break; |
| 2463 | 2475 | case 7: /* statement ::= PLACENAME COLON position */ |
| 2464 | -#line 563 "pikchr.y" | |
| 2476 | +#line 575 "pikchr.y" | |
| 2465 | 2477 | { yylhsminor.yy162 = pik_elem_new(p,0,0,0); |
| 2466 | 2478 | 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" | |
| 2468 | 2480 | yymsp[-2].minor.yy162 = yylhsminor.yy162; |
| 2469 | 2481 | break; |
| 2470 | 2482 | case 8: /* statement ::= unnamed_statement */ |
| 2471 | -#line 565 "pikchr.y" | |
| 2483 | +#line 577 "pikchr.y" | |
| 2472 | 2484 | {yylhsminor.yy162 = yymsp[0].minor.yy162;} |
| 2473 | -#line 2498 "pikchr.c" | |
| 2485 | +#line 2510 "pikchr.c" | |
| 2474 | 2486 | yymsp[0].minor.yy162 = yylhsminor.yy162; |
| 2475 | 2487 | break; |
| 2476 | 2488 | case 9: /* statement ::= print prlist */ |
| 2477 | -#line 566 "pikchr.y" | |
| 2489 | +#line 578 "pikchr.y" | |
| 2478 | 2490 | {pik_append(p,"<br>\n",5); yymsp[-1].minor.yy162=0;} |
| 2479 | -#line 2504 "pikchr.c" | |
| 2491 | +#line 2516 "pikchr.c" | |
| 2480 | 2492 | break; |
| 2481 | 2493 | case 10: /* statement ::= ASSERT LP expr EQ expr RP */ |
| 2482 | -#line 571 "pikchr.y" | |
| 2494 | +#line 583 "pikchr.y" | |
| 2483 | 2495 | {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" | |
| 2485 | 2497 | break; |
| 2486 | 2498 | case 11: /* statement ::= ASSERT LP position EQ position RP */ |
| 2487 | -#line 573 "pikchr.y" | |
| 2499 | +#line 585 "pikchr.y" | |
| 2488 | 2500 | {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" | |
| 2490 | 2502 | break; |
| 2491 | 2503 | case 12: /* statement ::= DEFINE ID CODEBLOCK */ |
| 2492 | -#line 574 "pikchr.y" | |
| 2504 | +#line 586 "pikchr.y" | |
| 2493 | 2505 | {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" | |
| 2495 | 2507 | break; |
| 2496 | 2508 | case 13: /* rvalue ::= PLACENAME */ |
| 2497 | -#line 585 "pikchr.y" | |
| 2509 | +#line 597 "pikchr.y" | |
| 2498 | 2510 | {yylhsminor.yy21 = pik_lookup_color(p,&yymsp[0].minor.yy0);} |
| 2499 | -#line 2524 "pikchr.c" | |
| 2511 | +#line 2536 "pikchr.c" | |
| 2500 | 2512 | yymsp[0].minor.yy21 = yylhsminor.yy21; |
| 2501 | 2513 | break; |
| 2502 | 2514 | case 14: /* pritem ::= FILL */ |
| 2503 | 2515 | case 15: /* pritem ::= COLOR */ yytestcase(yyruleno==15); |
| 2504 | 2516 | case 16: /* pritem ::= THICKNESS */ yytestcase(yyruleno==16); |
| 2505 | -#line 590 "pikchr.y" | |
| 2517 | +#line 602 "pikchr.y" | |
| 2506 | 2518 | {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" | |
| 2508 | 2520 | break; |
| 2509 | 2521 | case 17: /* pritem ::= rvalue */ |
| 2510 | -#line 593 "pikchr.y" | |
| 2522 | +#line 605 "pikchr.y" | |
| 2511 | 2523 | {pik_append_num(p,"",yymsp[0].minor.yy21);} |
| 2512 | -#line 2537 "pikchr.c" | |
| 2524 | +#line 2549 "pikchr.c" | |
| 2513 | 2525 | break; |
| 2514 | 2526 | case 18: /* pritem ::= STRING */ |
| 2515 | -#line 594 "pikchr.y" | |
| 2527 | +#line 606 "pikchr.y" | |
| 2516 | 2528 | {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" | |
| 2518 | 2530 | break; |
| 2519 | 2531 | case 19: /* prsep ::= COMMA */ |
| 2520 | -#line 595 "pikchr.y" | |
| 2532 | +#line 607 "pikchr.y" | |
| 2521 | 2533 | {pik_append(p, " ", 1);} |
| 2522 | -#line 2547 "pikchr.c" | |
| 2534 | +#line 2559 "pikchr.c" | |
| 2523 | 2535 | break; |
| 2524 | 2536 | case 20: /* unnamed_statement ::= basetype attribute_list */ |
| 2525 | -#line 598 "pikchr.y" | |
| 2537 | +#line 610 "pikchr.y" | |
| 2526 | 2538 | {yylhsminor.yy162 = yymsp[-1].minor.yy162; pik_after_adding_attributes(p,yylhsminor.yy162);} |
| 2527 | -#line 2552 "pikchr.c" | |
| 2539 | +#line 2564 "pikchr.c" | |
| 2528 | 2540 | yymsp[-1].minor.yy162 = yylhsminor.yy162; |
| 2529 | 2541 | break; |
| 2530 | 2542 | case 21: /* basetype ::= CLASSNAME */ |
| 2531 | -#line 600 "pikchr.y" | |
| 2543 | +#line 612 "pikchr.y" | |
| 2532 | 2544 | {yylhsminor.yy162 = pik_elem_new(p,&yymsp[0].minor.yy0,0,0); } |
| 2533 | -#line 2558 "pikchr.c" | |
| 2545 | +#line 2570 "pikchr.c" | |
| 2534 | 2546 | yymsp[0].minor.yy162 = yylhsminor.yy162; |
| 2535 | 2547 | break; |
| 2536 | 2548 | case 22: /* basetype ::= STRING textposition */ |
| 2537 | -#line 602 "pikchr.y" | |
| 2549 | +#line 614 "pikchr.y" | |
| 2538 | 2550 | {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" | |
| 2540 | 2552 | yymsp[-1].minor.yy162 = yylhsminor.yy162; |
| 2541 | 2553 | break; |
| 2542 | 2554 | case 23: /* basetype ::= LB savelist statement_list RB */ |
| 2543 | -#line 604 "pikchr.y" | |
| 2555 | +#line 616 "pikchr.y" | |
| 2544 | 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; } |
| 2545 | -#line 2570 "pikchr.c" | |
| 2557 | +#line 2582 "pikchr.c" | |
| 2546 | 2558 | break; |
| 2547 | 2559 | case 24: /* savelist ::= */ |
| 2548 | -#line 609 "pikchr.y" | |
| 2560 | +#line 621 "pikchr.y" | |
| 2549 | 2561 | {yymsp[1].minor.yy235 = p->list; p->list = 0;} |
| 2550 | -#line 2575 "pikchr.c" | |
| 2562 | +#line 2587 "pikchr.c" | |
| 2551 | 2563 | break; |
| 2552 | 2564 | case 25: /* relexpr ::= expr */ |
| 2553 | -#line 616 "pikchr.y" | |
| 2565 | +#line 628 "pikchr.y" | |
| 2554 | 2566 | {yylhsminor.yy72.rAbs = yymsp[0].minor.yy21; yylhsminor.yy72.rRel = 0;} |
| 2555 | -#line 2580 "pikchr.c" | |
| 2567 | +#line 2592 "pikchr.c" | |
| 2556 | 2568 | yymsp[0].minor.yy72 = yylhsminor.yy72; |
| 2557 | 2569 | break; |
| 2558 | 2570 | case 26: /* relexpr ::= expr PERCENT */ |
| 2559 | -#line 617 "pikchr.y" | |
| 2571 | +#line 629 "pikchr.y" | |
| 2560 | 2572 | {yylhsminor.yy72.rAbs = 0; yylhsminor.yy72.rRel = yymsp[-1].minor.yy21/100;} |
| 2561 | -#line 2586 "pikchr.c" | |
| 2573 | +#line 2598 "pikchr.c" | |
| 2562 | 2574 | yymsp[-1].minor.yy72 = yylhsminor.yy72; |
| 2563 | 2575 | break; |
| 2564 | 2576 | case 27: /* optrelexpr ::= */ |
| 2565 | -#line 619 "pikchr.y" | |
| 2577 | +#line 631 "pikchr.y" | |
| 2566 | 2578 | {yymsp[1].minor.yy72.rAbs = 0; yymsp[1].minor.yy72.rRel = 1.0;} |
| 2567 | -#line 2592 "pikchr.c" | |
| 2579 | +#line 2604 "pikchr.c" | |
| 2568 | 2580 | break; |
| 2569 | 2581 | case 28: /* attribute_list ::= relexpr alist */ |
| 2570 | -#line 621 "pikchr.y" | |
| 2582 | +#line 633 "pikchr.y" | |
| 2571 | 2583 | {pik_add_direction(p,0,&yymsp[-1].minor.yy72);} |
| 2572 | -#line 2597 "pikchr.c" | |
| 2584 | +#line 2609 "pikchr.c" | |
| 2573 | 2585 | break; |
| 2574 | 2586 | case 29: /* attribute ::= numproperty relexpr */ |
| 2575 | -#line 625 "pikchr.y" | |
| 2587 | +#line 637 "pikchr.y" | |
| 2576 | 2588 | { pik_set_numprop(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72); } |
| 2577 | -#line 2602 "pikchr.c" | |
| 2589 | +#line 2614 "pikchr.c" | |
| 2578 | 2590 | break; |
| 2579 | 2591 | case 30: /* attribute ::= dashproperty expr */ |
| 2580 | -#line 626 "pikchr.y" | |
| 2592 | +#line 638 "pikchr.y" | |
| 2581 | 2593 | { pik_set_dashed(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy21); } |
| 2582 | -#line 2607 "pikchr.c" | |
| 2594 | +#line 2619 "pikchr.c" | |
| 2583 | 2595 | break; |
| 2584 | 2596 | case 31: /* attribute ::= dashproperty */ |
| 2585 | -#line 627 "pikchr.y" | |
| 2597 | +#line 639 "pikchr.y" | |
| 2586 | 2598 | { pik_set_dashed(p,&yymsp[0].minor.yy0,0); } |
| 2587 | -#line 2612 "pikchr.c" | |
| 2599 | +#line 2624 "pikchr.c" | |
| 2588 | 2600 | break; |
| 2589 | 2601 | case 32: /* attribute ::= colorproperty rvalue */ |
| 2590 | -#line 628 "pikchr.y" | |
| 2602 | +#line 640 "pikchr.y" | |
| 2591 | 2603 | { pik_set_clrprop(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy21); } |
| 2592 | -#line 2617 "pikchr.c" | |
| 2604 | +#line 2629 "pikchr.c" | |
| 2593 | 2605 | break; |
| 2594 | 2606 | case 33: /* attribute ::= go direction optrelexpr */ |
| 2595 | -#line 629 "pikchr.y" | |
| 2607 | +#line 641 "pikchr.y" | |
| 2596 | 2608 | { pik_add_direction(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72);} |
| 2597 | -#line 2622 "pikchr.c" | |
| 2609 | +#line 2634 "pikchr.c" | |
| 2598 | 2610 | break; |
| 2599 | 2611 | case 34: /* attribute ::= go direction even position */ |
| 2600 | -#line 630 "pikchr.y" | |
| 2612 | +#line 642 "pikchr.y" | |
| 2601 | 2613 | {pik_evenwith(p,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy63);} |
| 2602 | -#line 2627 "pikchr.c" | |
| 2614 | +#line 2639 "pikchr.c" | |
| 2603 | 2615 | break; |
| 2604 | 2616 | case 35: /* attribute ::= CLOSE */ |
| 2605 | -#line 631 "pikchr.y" | |
| 2617 | +#line 643 "pikchr.y" | |
| 2606 | 2618 | { pik_close_path(p,&yymsp[0].minor.yy0); } |
| 2607 | -#line 2632 "pikchr.c" | |
| 2619 | +#line 2644 "pikchr.c" | |
| 2608 | 2620 | break; |
| 2609 | 2621 | case 36: /* attribute ::= CHOP */ |
| 2610 | -#line 632 "pikchr.y" | |
| 2622 | +#line 644 "pikchr.y" | |
| 2611 | 2623 | { p->cur->bChop = 1; } |
| 2612 | -#line 2637 "pikchr.c" | |
| 2624 | +#line 2649 "pikchr.c" | |
| 2613 | 2625 | break; |
| 2614 | 2626 | case 37: /* attribute ::= FROM position */ |
| 2615 | -#line 633 "pikchr.y" | |
| 2627 | +#line 645 "pikchr.y" | |
| 2616 | 2628 | { pik_set_from(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); } |
| 2617 | -#line 2642 "pikchr.c" | |
| 2629 | +#line 2654 "pikchr.c" | |
| 2618 | 2630 | break; |
| 2619 | 2631 | case 38: /* attribute ::= TO position */ |
| 2620 | -#line 634 "pikchr.y" | |
| 2632 | +#line 646 "pikchr.y" | |
| 2621 | 2633 | { pik_add_to(p,p->cur,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy63); } |
| 2622 | -#line 2647 "pikchr.c" | |
| 2634 | +#line 2659 "pikchr.c" | |
| 2623 | 2635 | break; |
| 2624 | 2636 | case 39: /* attribute ::= THEN */ |
| 2625 | -#line 635 "pikchr.y" | |
| 2637 | +#line 647 "pikchr.y" | |
| 2626 | 2638 | { pik_then(p, &yymsp[0].minor.yy0, p->cur); } |
| 2627 | -#line 2652 "pikchr.c" | |
| 2639 | +#line 2664 "pikchr.c" | |
| 2628 | 2640 | break; |
| 2629 | 2641 | case 40: /* attribute ::= THEN optrelexpr HEADING expr */ |
| 2630 | 2642 | case 42: /* attribute ::= GO optrelexpr HEADING expr */ yytestcase(yyruleno==42); |
| 2631 | -#line 637 "pikchr.y" | |
| 2643 | +#line 649 "pikchr.y" | |
| 2632 | 2644 | {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" | |
| 2634 | 2646 | break; |
| 2635 | 2647 | case 41: /* attribute ::= THEN optrelexpr EDGEPT */ |
| 2636 | 2648 | case 43: /* attribute ::= GO optrelexpr EDGEPT */ yytestcase(yyruleno==43); |
| 2637 | -#line 638 "pikchr.y" | |
| 2649 | +#line 650 "pikchr.y" | |
| 2638 | 2650 | {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" | |
| 2640 | 2652 | break; |
| 2641 | 2653 | case 44: /* attribute ::= AT position */ |
| 2642 | -#line 643 "pikchr.y" | |
| 2654 | +#line 655 "pikchr.y" | |
| 2643 | 2655 | { pik_set_at(p,0,&yymsp[0].minor.yy63,&yymsp[-1].minor.yy0); } |
| 2644 | -#line 2669 "pikchr.c" | |
| 2656 | +#line 2681 "pikchr.c" | |
| 2645 | 2657 | break; |
| 2646 | 2658 | case 45: /* attribute ::= SAME */ |
| 2647 | -#line 645 "pikchr.y" | |
| 2659 | +#line 657 "pikchr.y" | |
| 2648 | 2660 | {pik_same(p,0,&yymsp[0].minor.yy0);} |
| 2649 | -#line 2674 "pikchr.c" | |
| 2661 | +#line 2686 "pikchr.c" | |
| 2650 | 2662 | break; |
| 2651 | 2663 | case 46: /* attribute ::= SAME AS object */ |
| 2652 | -#line 646 "pikchr.y" | |
| 2664 | +#line 658 "pikchr.y" | |
| 2653 | 2665 | {pik_same(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);} |
| 2654 | -#line 2679 "pikchr.c" | |
| 2666 | +#line 2691 "pikchr.c" | |
| 2655 | 2667 | break; |
| 2656 | 2668 | case 47: /* attribute ::= STRING textposition */ |
| 2657 | -#line 647 "pikchr.y" | |
| 2669 | +#line 659 "pikchr.y" | |
| 2658 | 2670 | {pik_add_txt(p,&yymsp[-1].minor.yy0,yymsp[0].minor.yy188);} |
| 2659 | -#line 2684 "pikchr.c" | |
| 2671 | +#line 2696 "pikchr.c" | |
| 2660 | 2672 | break; |
| 2661 | 2673 | case 48: /* attribute ::= FIT */ |
| 2662 | -#line 648 "pikchr.y" | |
| 2674 | +#line 660 "pikchr.y" | |
| 2663 | 2675 | {pik_size_to_fit(p,&yymsp[0].minor.yy0,3); } |
| 2664 | -#line 2689 "pikchr.c" | |
| 2676 | +#line 2701 "pikchr.c" | |
| 2665 | 2677 | break; |
| 2666 | 2678 | case 49: /* attribute ::= BEHIND object */ |
| 2667 | -#line 649 "pikchr.y" | |
| 2679 | +#line 661 "pikchr.y" | |
| 2668 | 2680 | {pik_behind(p,yymsp[0].minor.yy162);} |
| 2669 | -#line 2694 "pikchr.c" | |
| 2681 | +#line 2706 "pikchr.c" | |
| 2670 | 2682 | break; |
| 2671 | 2683 | case 50: /* withclause ::= DOT_E edge AT position */ |
| 2672 | 2684 | case 51: /* withclause ::= edge AT position */ yytestcase(yyruleno==51); |
| 2673 | -#line 657 "pikchr.y" | |
| 2685 | +#line 669 "pikchr.y" | |
| 2674 | 2686 | { 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" | |
| 2676 | 2688 | break; |
| 2677 | 2689 | case 52: /* numproperty ::= HEIGHT|WIDTH|RADIUS|DIAMETER|THICKNESS */ |
| 2678 | -#line 661 "pikchr.y" | |
| 2690 | +#line 673 "pikchr.y" | |
| 2679 | 2691 | {yylhsminor.yy0 = yymsp[0].minor.yy0;} |
| 2680 | -#line 2705 "pikchr.c" | |
| 2692 | +#line 2717 "pikchr.c" | |
| 2681 | 2693 | yymsp[0].minor.yy0 = yylhsminor.yy0; |
| 2682 | 2694 | break; |
| 2683 | 2695 | case 53: /* boolproperty ::= CW */ |
| 2684 | -#line 672 "pikchr.y" | |
| 2696 | +#line 684 "pikchr.y" | |
| 2685 | 2697 | {p->cur->cw = 1;} |
| 2686 | -#line 2711 "pikchr.c" | |
| 2698 | +#line 2723 "pikchr.c" | |
| 2687 | 2699 | break; |
| 2688 | 2700 | case 54: /* boolproperty ::= CCW */ |
| 2689 | -#line 673 "pikchr.y" | |
| 2701 | +#line 685 "pikchr.y" | |
| 2690 | 2702 | {p->cur->cw = 0;} |
| 2691 | -#line 2716 "pikchr.c" | |
| 2703 | +#line 2728 "pikchr.c" | |
| 2692 | 2704 | break; |
| 2693 | 2705 | case 55: /* boolproperty ::= LARROW */ |
| 2694 | -#line 674 "pikchr.y" | |
| 2706 | +#line 686 "pikchr.y" | |
| 2695 | 2707 | {p->cur->larrow=1; p->cur->rarrow=0; } |
| 2696 | -#line 2721 "pikchr.c" | |
| 2708 | +#line 2733 "pikchr.c" | |
| 2697 | 2709 | break; |
| 2698 | 2710 | case 56: /* boolproperty ::= RARROW */ |
| 2699 | -#line 675 "pikchr.y" | |
| 2711 | +#line 687 "pikchr.y" | |
| 2700 | 2712 | {p->cur->larrow=0; p->cur->rarrow=1; } |
| 2701 | -#line 2726 "pikchr.c" | |
| 2713 | +#line 2738 "pikchr.c" | |
| 2702 | 2714 | break; |
| 2703 | 2715 | case 57: /* boolproperty ::= LRARROW */ |
| 2704 | -#line 676 "pikchr.y" | |
| 2716 | +#line 688 "pikchr.y" | |
| 2705 | 2717 | {p->cur->larrow=1; p->cur->rarrow=1; } |
| 2706 | -#line 2731 "pikchr.c" | |
| 2718 | +#line 2743 "pikchr.c" | |
| 2707 | 2719 | break; |
| 2708 | 2720 | case 58: /* boolproperty ::= INVIS */ |
| 2709 | -#line 677 "pikchr.y" | |
| 2721 | +#line 689 "pikchr.y" | |
| 2710 | 2722 | {p->cur->sw = -0.00001;} |
| 2711 | -#line 2736 "pikchr.c" | |
| 2723 | +#line 2748 "pikchr.c" | |
| 2712 | 2724 | break; |
| 2713 | 2725 | case 59: /* boolproperty ::= THICK */ |
| 2714 | -#line 678 "pikchr.y" | |
| 2726 | +#line 690 "pikchr.y" | |
| 2715 | 2727 | {p->cur->sw *= 1.5;} |
| 2716 | -#line 2741 "pikchr.c" | |
| 2728 | +#line 2753 "pikchr.c" | |
| 2717 | 2729 | break; |
| 2718 | 2730 | case 60: /* boolproperty ::= THIN */ |
| 2719 | -#line 679 "pikchr.y" | |
| 2731 | +#line 691 "pikchr.y" | |
| 2720 | 2732 | {p->cur->sw *= 0.67;} |
| 2721 | -#line 2746 "pikchr.c" | |
| 2733 | +#line 2758 "pikchr.c" | |
| 2722 | 2734 | break; |
| 2723 | 2735 | case 61: /* boolproperty ::= SOLID */ |
| 2724 | -#line 680 "pikchr.y" | |
| 2736 | +#line 692 "pikchr.y" | |
| 2725 | 2737 | {p->cur->sw = pik_value(p,"thickness",9,0); |
| 2726 | 2738 | p->cur->dotted = p->cur->dashed = 0.0;} |
| 2727 | -#line 2752 "pikchr.c" | |
| 2739 | +#line 2764 "pikchr.c" | |
| 2728 | 2740 | break; |
| 2729 | 2741 | case 62: /* textposition ::= */ |
| 2730 | -#line 683 "pikchr.y" | |
| 2742 | +#line 695 "pikchr.y" | |
| 2731 | 2743 | {yymsp[1].minor.yy188 = 0;} |
| 2732 | -#line 2757 "pikchr.c" | |
| 2744 | +#line 2769 "pikchr.c" | |
| 2733 | 2745 | break; |
| 2734 | 2746 | 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" | |
| 2736 | 2748 | {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" | |
| 2738 | 2750 | yymsp[-1].minor.yy188 = yylhsminor.yy188; |
| 2739 | 2751 | break; |
| 2740 | 2752 | case 64: /* position ::= expr COMMA expr */ |
| 2741 | -#line 689 "pikchr.y" | |
| 2753 | +#line 701 "pikchr.y" | |
| 2742 | 2754 | {yylhsminor.yy63.x=yymsp[-2].minor.yy21; yylhsminor.yy63.y=yymsp[0].minor.yy21;} |
| 2743 | -#line 2768 "pikchr.c" | |
| 2755 | +#line 2780 "pikchr.c" | |
| 2744 | 2756 | yymsp[-2].minor.yy63 = yylhsminor.yy63; |
| 2745 | 2757 | break; |
| 2746 | 2758 | case 65: /* position ::= place PLUS expr COMMA expr */ |
| 2747 | -#line 691 "pikchr.y" | |
| 2759 | +#line 703 "pikchr.y" | |
| 2748 | 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;} |
| 2749 | -#line 2774 "pikchr.c" | |
| 2761 | +#line 2786 "pikchr.c" | |
| 2750 | 2762 | yymsp[-4].minor.yy63 = yylhsminor.yy63; |
| 2751 | 2763 | break; |
| 2752 | 2764 | case 66: /* position ::= place MINUS expr COMMA expr */ |
| 2753 | -#line 692 "pikchr.y" | |
| 2765 | +#line 704 "pikchr.y" | |
| 2754 | 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;} |
| 2755 | -#line 2780 "pikchr.c" | |
| 2767 | +#line 2792 "pikchr.c" | |
| 2756 | 2768 | yymsp[-4].minor.yy63 = yylhsminor.yy63; |
| 2757 | 2769 | break; |
| 2758 | 2770 | case 67: /* position ::= place PLUS LP expr COMMA expr RP */ |
| 2759 | -#line 694 "pikchr.y" | |
| 2771 | +#line 706 "pikchr.y" | |
| 2760 | 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;} |
| 2761 | -#line 2786 "pikchr.c" | |
| 2773 | +#line 2798 "pikchr.c" | |
| 2762 | 2774 | yymsp[-6].minor.yy63 = yylhsminor.yy63; |
| 2763 | 2775 | break; |
| 2764 | 2776 | case 68: /* position ::= place MINUS LP expr COMMA expr RP */ |
| 2765 | -#line 696 "pikchr.y" | |
| 2777 | +#line 708 "pikchr.y" | |
| 2766 | 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;} |
| 2767 | -#line 2792 "pikchr.c" | |
| 2779 | +#line 2804 "pikchr.c" | |
| 2768 | 2780 | yymsp[-6].minor.yy63 = yylhsminor.yy63; |
| 2769 | 2781 | break; |
| 2770 | 2782 | case 69: /* position ::= LP position COMMA position RP */ |
| 2771 | -#line 697 "pikchr.y" | |
| 2783 | +#line 709 "pikchr.y" | |
| 2772 | 2784 | {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" | |
| 2774 | 2786 | break; |
| 2775 | 2787 | case 70: /* position ::= LP position RP */ |
| 2776 | -#line 698 "pikchr.y" | |
| 2788 | +#line 710 "pikchr.y" | |
| 2777 | 2789 | {yymsp[-2].minor.yy63=yymsp[-1].minor.yy63;} |
| 2778 | -#line 2803 "pikchr.c" | |
| 2790 | +#line 2815 "pikchr.c" | |
| 2779 | 2791 | break; |
| 2780 | 2792 | case 71: /* position ::= expr between position AND position */ |
| 2781 | -#line 700 "pikchr.y" | |
| 2793 | +#line 712 "pikchr.y" | |
| 2782 | 2794 | {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" | |
| 2784 | 2796 | yymsp[-4].minor.yy63 = yylhsminor.yy63; |
| 2785 | 2797 | break; |
| 2786 | 2798 | case 72: /* position ::= expr LT position COMMA position GT */ |
| 2787 | -#line 702 "pikchr.y" | |
| 2799 | +#line 714 "pikchr.y" | |
| 2788 | 2800 | {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" | |
| 2790 | 2802 | yymsp[-5].minor.yy63 = yylhsminor.yy63; |
| 2791 | 2803 | break; |
| 2792 | 2804 | case 73: /* position ::= expr ABOVE position */ |
| 2793 | -#line 703 "pikchr.y" | |
| 2805 | +#line 715 "pikchr.y" | |
| 2794 | 2806 | {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y += yymsp[-2].minor.yy21;} |
| 2795 | -#line 2820 "pikchr.c" | |
| 2807 | +#line 2832 "pikchr.c" | |
| 2796 | 2808 | yymsp[-2].minor.yy63 = yylhsminor.yy63; |
| 2797 | 2809 | break; |
| 2798 | 2810 | case 74: /* position ::= expr BELOW position */ |
| 2799 | -#line 704 "pikchr.y" | |
| 2811 | +#line 716 "pikchr.y" | |
| 2800 | 2812 | {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.y -= yymsp[-2].minor.yy21;} |
| 2801 | -#line 2826 "pikchr.c" | |
| 2813 | +#line 2838 "pikchr.c" | |
| 2802 | 2814 | yymsp[-2].minor.yy63 = yylhsminor.yy63; |
| 2803 | 2815 | break; |
| 2804 | 2816 | case 75: /* position ::= expr LEFT OF position */ |
| 2805 | -#line 705 "pikchr.y" | |
| 2817 | +#line 717 "pikchr.y" | |
| 2806 | 2818 | {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x -= yymsp[-3].minor.yy21;} |
| 2807 | -#line 2832 "pikchr.c" | |
| 2819 | +#line 2844 "pikchr.c" | |
| 2808 | 2820 | yymsp[-3].minor.yy63 = yylhsminor.yy63; |
| 2809 | 2821 | break; |
| 2810 | 2822 | case 76: /* position ::= expr RIGHT OF position */ |
| 2811 | -#line 706 "pikchr.y" | |
| 2823 | +#line 718 "pikchr.y" | |
| 2812 | 2824 | {yylhsminor.yy63=yymsp[0].minor.yy63; yylhsminor.yy63.x += yymsp[-3].minor.yy21;} |
| 2813 | -#line 2838 "pikchr.c" | |
| 2825 | +#line 2850 "pikchr.c" | |
| 2814 | 2826 | yymsp[-3].minor.yy63 = yylhsminor.yy63; |
| 2815 | 2827 | break; |
| 2816 | 2828 | case 77: /* position ::= expr ON HEADING EDGEPT OF position */ |
| 2817 | -#line 708 "pikchr.y" | |
| 2829 | +#line 720 "pikchr.y" | |
| 2818 | 2830 | {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" | |
| 2820 | 2832 | yymsp[-5].minor.yy63 = yylhsminor.yy63; |
| 2821 | 2833 | break; |
| 2822 | 2834 | case 78: /* position ::= expr HEADING EDGEPT OF position */ |
| 2823 | -#line 710 "pikchr.y" | |
| 2835 | +#line 722 "pikchr.y" | |
| 2824 | 2836 | {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" | |
| 2826 | 2838 | yymsp[-4].minor.yy63 = yylhsminor.yy63; |
| 2827 | 2839 | break; |
| 2828 | 2840 | case 79: /* position ::= expr EDGEPT OF position */ |
| 2829 | -#line 712 "pikchr.y" | |
| 2841 | +#line 724 "pikchr.y" | |
| 2830 | 2842 | {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" | |
| 2832 | 2844 | yymsp[-3].minor.yy63 = yylhsminor.yy63; |
| 2833 | 2845 | break; |
| 2834 | 2846 | case 80: /* position ::= expr ON HEADING expr FROM position */ |
| 2835 | -#line 714 "pikchr.y" | |
| 2847 | +#line 726 "pikchr.y" | |
| 2836 | 2848 | {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" | |
| 2838 | 2850 | yymsp[-5].minor.yy63 = yylhsminor.yy63; |
| 2839 | 2851 | break; |
| 2840 | 2852 | case 81: /* position ::= expr HEADING expr FROM position */ |
| 2841 | -#line 716 "pikchr.y" | |
| 2853 | +#line 728 "pikchr.y" | |
| 2842 | 2854 | {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" | |
| 2844 | 2856 | yymsp[-4].minor.yy63 = yylhsminor.yy63; |
| 2845 | 2857 | break; |
| 2846 | 2858 | case 82: /* place ::= edge OF object */ |
| 2847 | -#line 728 "pikchr.y" | |
| 2859 | +#line 740 "pikchr.y" | |
| 2848 | 2860 | {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" | |
| 2850 | 2862 | yymsp[-2].minor.yy63 = yylhsminor.yy63; |
| 2851 | 2863 | break; |
| 2852 | 2864 | case 83: /* place2 ::= object */ |
| 2853 | -#line 729 "pikchr.y" | |
| 2865 | +#line 741 "pikchr.y" | |
| 2854 | 2866 | {yylhsminor.yy63 = pik_place_of_elem(p,yymsp[0].minor.yy162,0);} |
| 2855 | -#line 2880 "pikchr.c" | |
| 2867 | +#line 2892 "pikchr.c" | |
| 2856 | 2868 | yymsp[0].minor.yy63 = yylhsminor.yy63; |
| 2857 | 2869 | break; |
| 2858 | 2870 | case 84: /* place2 ::= object DOT_E edge */ |
| 2859 | -#line 730 "pikchr.y" | |
| 2871 | +#line 742 "pikchr.y" | |
| 2860 | 2872 | {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" | |
| 2862 | 2874 | yymsp[-2].minor.yy63 = yylhsminor.yy63; |
| 2863 | 2875 | break; |
| 2864 | 2876 | case 85: /* place2 ::= NTH VERTEX OF object */ |
| 2865 | -#line 731 "pikchr.y" | |
| 2877 | +#line 743 "pikchr.y" | |
| 2866 | 2878 | {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" | |
| 2868 | 2880 | yymsp[-3].minor.yy63 = yylhsminor.yy63; |
| 2869 | 2881 | break; |
| 2870 | 2882 | case 86: /* object ::= nth */ |
| 2871 | -#line 743 "pikchr.y" | |
| 2883 | +#line 755 "pikchr.y" | |
| 2872 | 2884 | {yylhsminor.yy162 = pik_find_nth(p,0,&yymsp[0].minor.yy0);} |
| 2873 | -#line 2898 "pikchr.c" | |
| 2885 | +#line 2910 "pikchr.c" | |
| 2874 | 2886 | yymsp[0].minor.yy162 = yylhsminor.yy162; |
| 2875 | 2887 | break; |
| 2876 | 2888 | case 87: /* object ::= nth OF|IN object */ |
| 2877 | -#line 744 "pikchr.y" | |
| 2889 | +#line 756 "pikchr.y" | |
| 2878 | 2890 | {yylhsminor.yy162 = pik_find_nth(p,yymsp[0].minor.yy162,&yymsp[-2].minor.yy0);} |
| 2879 | -#line 2904 "pikchr.c" | |
| 2891 | +#line 2916 "pikchr.c" | |
| 2880 | 2892 | yymsp[-2].minor.yy162 = yylhsminor.yy162; |
| 2881 | 2893 | break; |
| 2882 | 2894 | case 88: /* objectname ::= THIS */ |
| 2883 | -#line 746 "pikchr.y" | |
| 2895 | +#line 758 "pikchr.y" | |
| 2884 | 2896 | {yymsp[0].minor.yy162 = p->cur;} |
| 2885 | -#line 2910 "pikchr.c" | |
| 2897 | +#line 2922 "pikchr.c" | |
| 2886 | 2898 | break; |
| 2887 | 2899 | case 89: /* objectname ::= PLACENAME */ |
| 2888 | -#line 747 "pikchr.y" | |
| 2900 | +#line 759 "pikchr.y" | |
| 2889 | 2901 | {yylhsminor.yy162 = pik_find_byname(p,0,&yymsp[0].minor.yy0);} |
| 2890 | -#line 2915 "pikchr.c" | |
| 2902 | +#line 2927 "pikchr.c" | |
| 2891 | 2903 | yymsp[0].minor.yy162 = yylhsminor.yy162; |
| 2892 | 2904 | break; |
| 2893 | 2905 | case 90: /* objectname ::= objectname DOT_U PLACENAME */ |
| 2894 | -#line 749 "pikchr.y" | |
| 2906 | +#line 761 "pikchr.y" | |
| 2895 | 2907 | {yylhsminor.yy162 = pik_find_byname(p,yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);} |
| 2896 | -#line 2921 "pikchr.c" | |
| 2908 | +#line 2933 "pikchr.c" | |
| 2897 | 2909 | yymsp[-2].minor.yy162 = yylhsminor.yy162; |
| 2898 | 2910 | break; |
| 2899 | 2911 | case 91: /* nth ::= NTH CLASSNAME */ |
| 2900 | -#line 751 "pikchr.y" | |
| 2912 | +#line 763 "pikchr.y" | |
| 2901 | 2913 | {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" | |
| 2903 | 2915 | yymsp[-1].minor.yy0 = yylhsminor.yy0; |
| 2904 | 2916 | break; |
| 2905 | 2917 | case 92: /* nth ::= NTH LAST CLASSNAME */ |
| 2906 | -#line 752 "pikchr.y" | |
| 2918 | +#line 764 "pikchr.y" | |
| 2907 | 2919 | {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" | |
| 2909 | 2921 | yymsp[-2].minor.yy0 = yylhsminor.yy0; |
| 2910 | 2922 | break; |
| 2911 | 2923 | case 93: /* nth ::= LAST CLASSNAME */ |
| 2912 | -#line 753 "pikchr.y" | |
| 2924 | +#line 765 "pikchr.y" | |
| 2913 | 2925 | {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.eCode = -1;} |
| 2914 | -#line 2939 "pikchr.c" | |
| 2926 | +#line 2951 "pikchr.c" | |
| 2915 | 2927 | break; |
| 2916 | 2928 | case 94: /* nth ::= LAST */ |
| 2917 | -#line 754 "pikchr.y" | |
| 2929 | +#line 766 "pikchr.y" | |
| 2918 | 2930 | {yylhsminor.yy0=yymsp[0].minor.yy0; yylhsminor.yy0.eCode = -1;} |
| 2919 | -#line 2944 "pikchr.c" | |
| 2931 | +#line 2956 "pikchr.c" | |
| 2920 | 2932 | yymsp[0].minor.yy0 = yylhsminor.yy0; |
| 2921 | 2933 | break; |
| 2922 | 2934 | case 95: /* nth ::= NTH LB RB */ |
| 2923 | -#line 755 "pikchr.y" | |
| 2935 | +#line 767 "pikchr.y" | |
| 2924 | 2936 | {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" | |
| 2926 | 2938 | yymsp[-2].minor.yy0 = yylhsminor.yy0; |
| 2927 | 2939 | break; |
| 2928 | 2940 | case 96: /* nth ::= NTH LAST LB RB */ |
| 2929 | -#line 756 "pikchr.y" | |
| 2941 | +#line 768 "pikchr.y" | |
| 2930 | 2942 | {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" | |
| 2932 | 2944 | yymsp[-3].minor.yy0 = yylhsminor.yy0; |
| 2933 | 2945 | break; |
| 2934 | 2946 | case 97: /* nth ::= LAST LB RB */ |
| 2935 | -#line 757 "pikchr.y" | |
| 2947 | +#line 769 "pikchr.y" | |
| 2936 | 2948 | {yymsp[-2].minor.yy0=yymsp[-1].minor.yy0; yymsp[-2].minor.yy0.eCode = -1; } |
| 2937 | -#line 2962 "pikchr.c" | |
| 2949 | +#line 2974 "pikchr.c" | |
| 2938 | 2950 | break; |
| 2939 | 2951 | case 98: /* expr ::= expr PLUS expr */ |
| 2940 | -#line 759 "pikchr.y" | |
| 2952 | +#line 771 "pikchr.y" | |
| 2941 | 2953 | {yylhsminor.yy21=yymsp[-2].minor.yy21+yymsp[0].minor.yy21;} |
| 2942 | -#line 2967 "pikchr.c" | |
| 2954 | +#line 2979 "pikchr.c" | |
| 2943 | 2955 | yymsp[-2].minor.yy21 = yylhsminor.yy21; |
| 2944 | 2956 | break; |
| 2945 | 2957 | case 99: /* expr ::= expr MINUS expr */ |
| 2946 | -#line 760 "pikchr.y" | |
| 2958 | +#line 772 "pikchr.y" | |
| 2947 | 2959 | {yylhsminor.yy21=yymsp[-2].minor.yy21-yymsp[0].minor.yy21;} |
| 2948 | -#line 2973 "pikchr.c" | |
| 2960 | +#line 2985 "pikchr.c" | |
| 2949 | 2961 | yymsp[-2].minor.yy21 = yylhsminor.yy21; |
| 2950 | 2962 | break; |
| 2951 | 2963 | case 100: /* expr ::= expr STAR expr */ |
| 2952 | -#line 761 "pikchr.y" | |
| 2964 | +#line 773 "pikchr.y" | |
| 2953 | 2965 | {yylhsminor.yy21=yymsp[-2].minor.yy21*yymsp[0].minor.yy21;} |
| 2954 | -#line 2979 "pikchr.c" | |
| 2966 | +#line 2991 "pikchr.c" | |
| 2955 | 2967 | yymsp[-2].minor.yy21 = yylhsminor.yy21; |
| 2956 | 2968 | break; |
| 2957 | 2969 | case 101: /* expr ::= expr SLASH expr */ |
| 2958 | -#line 762 "pikchr.y" | |
| 2970 | +#line 774 "pikchr.y" | |
| 2959 | 2971 | { |
| 2960 | 2972 | if( yymsp[0].minor.yy21==0.0 ){ pik_error(p, &yymsp[-1].minor.yy0, "division by zero"); yylhsminor.yy21 = 0.0; } |
| 2961 | 2973 | else{ yylhsminor.yy21 = yymsp[-2].minor.yy21/yymsp[0].minor.yy21; } |
| 2962 | 2974 | } |
| 2963 | -#line 2988 "pikchr.c" | |
| 2975 | +#line 3000 "pikchr.c" | |
| 2964 | 2976 | yymsp[-2].minor.yy21 = yylhsminor.yy21; |
| 2965 | 2977 | break; |
| 2966 | 2978 | case 102: /* expr ::= MINUS expr */ |
| 2967 | -#line 766 "pikchr.y" | |
| 2979 | +#line 778 "pikchr.y" | |
| 2968 | 2980 | {yymsp[-1].minor.yy21=-yymsp[0].minor.yy21;} |
| 2969 | -#line 2994 "pikchr.c" | |
| 2981 | +#line 3006 "pikchr.c" | |
| 2970 | 2982 | break; |
| 2971 | 2983 | case 103: /* expr ::= PLUS expr */ |
| 2972 | -#line 767 "pikchr.y" | |
| 2984 | +#line 779 "pikchr.y" | |
| 2973 | 2985 | {yymsp[-1].minor.yy21=yymsp[0].minor.yy21;} |
| 2974 | -#line 2999 "pikchr.c" | |
| 2986 | +#line 3011 "pikchr.c" | |
| 2975 | 2987 | break; |
| 2976 | 2988 | case 104: /* expr ::= LP expr RP */ |
| 2977 | -#line 768 "pikchr.y" | |
| 2989 | +#line 780 "pikchr.y" | |
| 2978 | 2990 | {yymsp[-2].minor.yy21=yymsp[-1].minor.yy21;} |
| 2979 | -#line 3004 "pikchr.c" | |
| 2991 | +#line 3016 "pikchr.c" | |
| 2980 | 2992 | break; |
| 2981 | 2993 | case 105: /* expr ::= LP FILL|COLOR|THICKNESS RP */ |
| 2982 | -#line 769 "pikchr.y" | |
| 2994 | +#line 781 "pikchr.y" | |
| 2983 | 2995 | {yymsp[-2].minor.yy21=pik_get_var(p,&yymsp[-1].minor.yy0);} |
| 2984 | -#line 3009 "pikchr.c" | |
| 2996 | +#line 3021 "pikchr.c" | |
| 2985 | 2997 | break; |
| 2986 | 2998 | case 106: /* expr ::= NUMBER */ |
| 2987 | -#line 770 "pikchr.y" | |
| 2999 | +#line 782 "pikchr.y" | |
| 2988 | 3000 | {yylhsminor.yy21=pik_atof(&yymsp[0].minor.yy0);} |
| 2989 | -#line 3014 "pikchr.c" | |
| 3001 | +#line 3026 "pikchr.c" | |
| 2990 | 3002 | yymsp[0].minor.yy21 = yylhsminor.yy21; |
| 2991 | 3003 | break; |
| 2992 | 3004 | case 107: /* expr ::= ID */ |
| 2993 | -#line 771 "pikchr.y" | |
| 3005 | +#line 783 "pikchr.y" | |
| 2994 | 3006 | {yylhsminor.yy21=pik_get_var(p,&yymsp[0].minor.yy0);} |
| 2995 | -#line 3020 "pikchr.c" | |
| 3007 | +#line 3032 "pikchr.c" | |
| 2996 | 3008 | yymsp[0].minor.yy21 = yylhsminor.yy21; |
| 2997 | 3009 | break; |
| 2998 | 3010 | case 108: /* expr ::= FUNC1 LP expr RP */ |
| 2999 | -#line 772 "pikchr.y" | |
| 3011 | +#line 784 "pikchr.y" | |
| 3000 | 3012 | {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" | |
| 3002 | 3014 | yymsp[-3].minor.yy21 = yylhsminor.yy21; |
| 3003 | 3015 | break; |
| 3004 | 3016 | case 109: /* expr ::= FUNC2 LP expr COMMA expr RP */ |
| 3005 | -#line 773 "pikchr.y" | |
| 3017 | +#line 785 "pikchr.y" | |
| 3006 | 3018 | {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" | |
| 3008 | 3020 | yymsp[-5].minor.yy21 = yylhsminor.yy21; |
| 3009 | 3021 | break; |
| 3010 | 3022 | case 110: /* expr ::= DIST LP position COMMA position RP */ |
| 3011 | -#line 774 "pikchr.y" | |
| 3023 | +#line 786 "pikchr.y" | |
| 3012 | 3024 | {yymsp[-5].minor.yy21 = pik_dist(&yymsp[-3].minor.yy63,&yymsp[-1].minor.yy63);} |
| 3013 | -#line 3038 "pikchr.c" | |
| 3025 | +#line 3050 "pikchr.c" | |
| 3014 | 3026 | break; |
| 3015 | 3027 | case 111: /* expr ::= place2 DOT_XY X */ |
| 3016 | -#line 775 "pikchr.y" | |
| 3028 | +#line 787 "pikchr.y" | |
| 3017 | 3029 | {yylhsminor.yy21 = yymsp[-2].minor.yy63.x;} |
| 3018 | -#line 3043 "pikchr.c" | |
| 3030 | +#line 3055 "pikchr.c" | |
| 3019 | 3031 | yymsp[-2].minor.yy21 = yylhsminor.yy21; |
| 3020 | 3032 | break; |
| 3021 | 3033 | case 112: /* expr ::= place2 DOT_XY Y */ |
| 3022 | -#line 776 "pikchr.y" | |
| 3034 | +#line 788 "pikchr.y" | |
| 3023 | 3035 | {yylhsminor.yy21 = yymsp[-2].minor.yy63.y;} |
| 3024 | -#line 3049 "pikchr.c" | |
| 3036 | +#line 3061 "pikchr.c" | |
| 3025 | 3037 | yymsp[-2].minor.yy21 = yylhsminor.yy21; |
| 3026 | 3038 | break; |
| 3027 | 3039 | case 113: /* expr ::= object DOT_L numproperty */ |
| 3028 | 3040 | case 114: /* expr ::= object DOT_L dashproperty */ yytestcase(yyruleno==114); |
| 3029 | 3041 | case 115: /* expr ::= object DOT_L colorproperty */ yytestcase(yyruleno==115); |
| 3030 | -#line 777 "pikchr.y" | |
| 3042 | +#line 789 "pikchr.y" | |
| 3031 | 3043 | {yylhsminor.yy21=pik_property_of(yymsp[-2].minor.yy162,&yymsp[0].minor.yy0);} |
| 3032 | -#line 3057 "pikchr.c" | |
| 3044 | +#line 3069 "pikchr.c" | |
| 3033 | 3045 | yymsp[-2].minor.yy21 = yylhsminor.yy21; |
| 3034 | 3046 | break; |
| 3035 | 3047 | default: |
| 3036 | 3048 | /* (116) lvalue ::= ID */ yytestcase(yyruleno==116); |
| 3037 | 3049 | /* (117) lvalue ::= FILL */ yytestcase(yyruleno==117); |
| @@ -3130,19 +3142,19 @@ | ||
| 3130 | 3142 | ){ |
| 3131 | 3143 | pik_parserARG_FETCH |
| 3132 | 3144 | pik_parserCTX_FETCH |
| 3133 | 3145 | #define TOKEN yyminor |
| 3134 | 3146 | /************ Begin %syntax_error code ****************************************/ |
| 3135 | -#line 537 "pikchr.y" | |
| 3147 | +#line 549 "pikchr.y" | |
| 3136 | 3148 | |
| 3137 | 3149 | if( TOKEN.z && TOKEN.z[0] ){ |
| 3138 | 3150 | pik_error(p, &TOKEN, "syntax error"); |
| 3139 | 3151 | }else{ |
| 3140 | 3152 | pik_error(p, 0, "syntax error"); |
| 3141 | 3153 | } |
| 3142 | 3154 | UNUSED_PARAMETER(yymajor); |
| 3143 | -#line 3168 "pikchr.c" | |
| 3155 | +#line 3180 "pikchr.c" | |
| 3144 | 3156 | /************ End %syntax_error code ******************************************/ |
| 3145 | 3157 | pik_parserARG_STORE /* Suppress warning about unused %extra_argument variable */ |
| 3146 | 3158 | pik_parserCTX_STORE |
| 3147 | 3159 | } |
| 3148 | 3160 | |
| @@ -3407,11 +3419,11 @@ | ||
| 3407 | 3419 | #else |
| 3408 | 3420 | (void)iToken; |
| 3409 | 3421 | return 0; |
| 3410 | 3422 | #endif |
| 3411 | 3423 | } |
| 3412 | -#line 782 "pikchr.y" | |
| 3424 | +#line 794 "pikchr.y" | |
| 3413 | 3425 | |
| 3414 | 3426 | |
| 3415 | 3427 | |
| 3416 | 3428 | /* Chart of the 148 official CSS color names with their |
| 3417 | 3429 | ** corresponding RGB values thru Color Module Level 4: |
| @@ -6495,13 +6507,13 @@ | ||
| 6495 | 6507 | unsigned int i; |
| 6496 | 6508 | mid = (first+last)/2; |
| 6497 | 6509 | zClr = aColor[mid].zName; |
| 6498 | 6510 | for(i=0; i<pId->n; i++){ |
| 6499 | 6511 | c1 = zClr[i]&0x7f; |
| 6500 | - if( isupper(c1) ) c1 = tolower(c1); | |
| 6512 | + if( IsUpper(c1) ) c1 = ToLower(c1); | |
| 6501 | 6513 | c2 = pId->z[i]&0x7f; |
| 6502 | - if( isupper(c2) ) c2 = tolower(c2); | |
| 6514 | + if( IsUpper(c2) ) c2 = ToLower(c2); | |
| 6503 | 6515 | c = c2 - c1; |
| 6504 | 6516 | if( c ) break; |
| 6505 | 6517 | } |
| 6506 | 6518 | if( c==0 && aColor[mid].zName[pId->n] ) c = -1; |
| 6507 | 6519 | if( c==0 ) return (double)aColor[mid].val; |
| @@ -7605,11 +7617,11 @@ | ||
| 7605 | 7617 | } |
| 7606 | 7618 | default: { |
| 7607 | 7619 | c = z[0]; |
| 7608 | 7620 | if( c=='.' ){ |
| 7609 | 7621 | unsigned char c1 = z[1]; |
| 7610 | - if( islower(c1) ){ | |
| 7622 | + if( IsLower(c1) ){ | |
| 7611 | 7623 | const PikWord *pFound; |
| 7612 | 7624 | for(i=2; (c = z[i])>='a' && c<='z'; i++){} |
| 7613 | 7625 | pFound = pik_find_word((const char*)z+1, i-1, |
| 7614 | 7626 | pik_keywords, count(pik_keywords)); |
| 7615 | 7627 | if( pFound && (pFound->eEdge>0 || |
| @@ -7625,15 +7637,15 @@ | ||
| 7625 | 7637 | }else{ |
| 7626 | 7638 | /* Any other "dot" */ |
| 7627 | 7639 | pToken->eType = T_DOT_L; |
| 7628 | 7640 | } |
| 7629 | 7641 | return 1; |
| 7630 | - }else if( isdigit(c1) ){ | |
| 7642 | + }else if( IsDigit(c1) ){ | |
| 7631 | 7643 | i = 0; |
| 7632 | 7644 | /* 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++){} | |
| 7635 | 7647 | pToken->eType = T_DOT_U; |
| 7636 | 7648 | return 1; |
| 7637 | 7649 | }else{ |
| 7638 | 7650 | pToken->eType = T_ERROR; |
| 7639 | 7651 | return 1; |
| @@ -7644,11 +7656,11 @@ | ||
| 7644 | 7656 | int isInt = 1; |
| 7645 | 7657 | if( c!='.' ){ |
| 7646 | 7658 | nDigit = 1; |
| 7647 | 7659 | for(i=1; (c = z[i])>='0' && c<='9'; i++){ nDigit++; } |
| 7648 | 7660 | 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++){} | |
| 7650 | 7662 | pToken->eType = T_NUMBER; |
| 7651 | 7663 | return i; |
| 7652 | 7664 | } |
| 7653 | 7665 | }else{ |
| 7654 | 7666 | isInt = 0; |
| @@ -7700,13 +7712,13 @@ | ||
| 7700 | 7712 | ){ |
| 7701 | 7713 | i += 2; |
| 7702 | 7714 | } |
| 7703 | 7715 | pToken->eType = T_NUMBER; |
| 7704 | 7716 | return i; |
| 7705 | - }else if( islower(c) ){ | |
| 7717 | + }else if( IsLower(c) ){ | |
| 7706 | 7718 | 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++){} | |
| 7708 | 7720 | pFound = pik_find_word((const char*)z, i, |
| 7709 | 7721 | pik_keywords, count(pik_keywords)); |
| 7710 | 7722 | if( pFound ){ |
| 7711 | 7723 | pToken->eType = pFound->eType; |
| 7712 | 7724 | pToken->eCode = pFound->eCode; |
| @@ -7719,19 +7731,19 @@ | ||
| 7719 | 7731 | }else{ |
| 7720 | 7732 | pToken->eType = T_ID; |
| 7721 | 7733 | } |
| 7722 | 7734 | return i; |
| 7723 | 7735 | }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++){} | |
| 7725 | 7737 | pToken->eType = T_PLACENAME; |
| 7726 | 7738 | 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]) ){ | |
| 7728 | 7740 | pToken->eType = T_PARAMETER; |
| 7729 | 7741 | pToken->eCode = z[1] - '1'; |
| 7730 | 7742 | return 2; |
| 7731 | 7743 | }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++){} | |
| 7733 | 7745 | pToken->eType = T_ID; |
| 7734 | 7746 | return i; |
| 7735 | 7747 | }else{ |
| 7736 | 7748 | pToken->eType = T_ERROR; |
| 7737 | 7749 | return 1; |
| @@ -7814,12 +7826,12 @@ | ||
| 7814 | 7826 | /* Remove leading and trailing whitespace from each argument. |
| 7815 | 7827 | ** If what remains is one of $1, $2, ... $9 then transfer the |
| 7816 | 7828 | ** corresponding argument from the outer context */ |
| 7817 | 7829 | for(j=0; j<=nArg; j++){ |
| 7818 | 7830 | 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--; } | |
| 7821 | 7833 | if( t->n==2 && t->z[0]=='$' && t->z[1]>='1' && t->z[1]<='9' ){ |
| 7822 | 7834 | if( pOuter ) *t = pOuter[t->z[1]-'1']; |
| 7823 | 7835 | else t->n = 0; |
| 7824 | 7836 | } |
| 7825 | 7837 | } |
| @@ -7896,11 +7908,11 @@ | ||
| 7896 | 7908 | pMac->inUse = 0; |
| 7897 | 7909 | }else{ |
| 7898 | 7910 | #if 0 |
| 7899 | 7911 | printf("******** Token %s (%d): \"%.*s\" **************\n", |
| 7900 | 7912 | 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); | |
| 7902 | 7914 | #endif |
| 7903 | 7915 | token.n = (unsigned short)(sz & 0xffff); |
| 7904 | 7916 | if( p->nToken++ > PIKCHR_TOKEN_LIMIT ){ |
| 7905 | 7917 | pik_error(p, &token, "script is too complex"); |
| 7906 | 7918 | break; |
| @@ -8242,6 +8254,6 @@ | ||
| 8242 | 8254 | |
| 8243 | 8255 | |
| 8244 | 8256 | #endif /* PIKCHR_TCL */ |
| 8245 | 8257 | |
| 8246 | 8258 | |
| 8247 | -#line 8272 "pikchr.c" | |
| 8259 | +#line 8284 "pikchr.c" | |
| 8248 | 8260 |
| --- 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 | - | |
| 2 | 1 | var initPikchrModule = (() => { |
| 3 | - var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; | |
| 2 | + var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined; | |
| 4 | 3 | |
| 5 | 4 | return ( |
| 6 | -function(config) { | |
| 7 | - var initPikchrModule = config || {}; | |
| 5 | +async function(moduleArg = {}) { | |
| 6 | + var moduleRtn; | |
| 8 | 7 | |
| 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; | |
| 10 | 23 | |
| 24 | +// Set up the promise that indicates the Module is initialized | |
| 11 | 25 | var readyPromiseResolve, readyPromiseReject; |
| 12 | 26 | |
| 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; | |
| 16 | 30 | }); |
| 17 | 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. | |
| 18 | 45 | var moduleOverrides = Object.assign({}, Module); |
| 19 | 46 | |
| 20 | 47 | var arguments_ = []; |
| 21 | 48 | |
| 22 | 49 | var thisProgram = "./this.program"; |
| 23 | 50 | |
| 24 | 51 | var quit_ = (status, toThrow) => { |
| 25 | - throw toThrow; | |
| 52 | + throw toThrow; | |
| 26 | 53 | }; |
| 27 | 54 | |
| 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 | |
| 32 | 56 | var scriptDirectory = ""; |
| 33 | 57 | |
| 34 | 58 | 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 | + } | |
| 89 | 107 | } else {} |
| 90 | 108 | |
| 91 | 109 | var out = Module["print"] || console.log.bind(console); |
| 92 | 110 | |
| 93 | -var err = Module["printErr"] || console.warn.bind(console); | |
| 111 | +var err = Module["printErr"] || console.error.bind(console); | |
| 94 | 112 | |
| 113 | +// Merge back in the overrides | |
| 95 | 114 | Object.assign(Module, moduleOverrides); |
| 96 | 115 | |
| 116 | +// Free the object hierarchy contained in the overrides, this lets the GC | |
| 117 | +// reclaim data used. | |
| 97 | 118 | moduleOverrides = null; |
| 98 | 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. | |
| 99 | 124 | if (Module["arguments"]) arguments_ = Module["arguments"]; |
| 100 | 125 | |
| 101 | 126 | if (Module["thisProgram"]) thisProgram = Module["thisProgram"]; |
| 102 | 127 | |
| 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 | |
| 115 | 142 | var wasmMemory; |
| 116 | 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() | |
| 117 | 149 | var ABORT = false; |
| 118 | 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. | |
| 119 | 154 | var EXITSTATUS; |
| 120 | 155 | |
| 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; | |
| 223 | 160 | |
| 224 | 161 | var runtimeInitialized = false; |
| 225 | 162 | |
| 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); | |
| 228 | 184 | } |
| 229 | 185 | |
| 186 | +// end include: runtime_shared.js | |
| 230 | 187 | 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 | + } | |
| 235 | 193 | } |
| 236 | - } | |
| 237 | - callRuntimeCallbacks(__ATPRERUN__); | |
| 194 | + callRuntimeCallbacks(onPreRuns); | |
| 238 | 195 | } |
| 239 | 196 | |
| 240 | 197 | function initRuntime() { |
| 241 | - runtimeInitialized = true; | |
| 242 | - callRuntimeCallbacks(__ATINIT__); | |
| 198 | + runtimeInitialized = true; | |
| 199 | + wasmExports["e"](); | |
| 243 | 200 | } |
| 244 | 201 | |
| 245 | 202 | 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; | |
| 270 | 220 | |
| 271 | 221 | var dependenciesFulfilled = null; |
| 272 | 222 | |
| 273 | 223 | function addRunDependency(id) { |
| 274 | - runDependencies++; | |
| 275 | - if (Module["monitorRunDependencies"]) { | |
| 276 | - Module["monitorRunDependencies"](runDependencies); | |
| 277 | - } | |
| 224 | + runDependencies++; | |
| 225 | + Module["monitorRunDependencies"]?.(runDependencies); | |
| 278 | 226 | } |
| 279 | 227 | |
| 280 | 228 | 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; | |
| 316 | 266 | } |
| 317 | 267 | |
| 318 | 268 | var wasmBinaryFile; |
| 319 | 269 | |
| 320 | -wasmBinaryFile = "pikchr.wasm"; | |
| 321 | - | |
| 322 | -if (!isDataURI(wasmBinaryFile)) { | |
| 323 | - wasmBinaryFile = locateFile(wasmBinaryFile); | |
| 270 | +function findWasmBinary() { | |
| 271 | + return locateFile("pikchr.wasm"); | |
| 324 | 272 | } |
| 325 | 273 | |
| 326 | -function getBinary(file) { | |
| 327 | - try { | |
| 274 | +function getBinarySync(file) { | |
| 328 | 275 | if (file == wasmBinaryFile && wasmBinary) { |
| 329 | - return new Uint8Array(wasmBinary); | |
| 276 | + return new Uint8Array(wasmBinary); | |
| 330 | 277 | } |
| 331 | 278 | if (readBinary) { |
| 332 | - return readBinary(file); | |
| 279 | + return readBinary(file); | |
| 333 | 280 | } |
| 334 | 281 | 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 | +}; | |
| 546 | 595 | |
| 547 | 596 | var _exit = exitJS; |
| 548 | 597 | |
| 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 === | |
| 645 | 775 | Module["stackSave"] = stackSave; |
| 646 | 776 | |
| 647 | 777 | Module["stackRestore"] = stackRestore; |
| 778 | + | |
| 779 | +Module["stackAlloc"] = stackAlloc; | |
| 648 | 780 | |
| 649 | 781 | Module["cwrap"] = cwrap; |
| 650 | 782 | |
| 651 | 783 | Module["setValue"] = setValue; |
| 652 | 784 | |
| 653 | 785 | Module["getValue"] = getValue; |
| 654 | 786 | |
| 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 | + } | |
| 692 | 817 | } |
| 693 | 818 | |
| 694 | 819 | 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 | + } | |
| 699 | 824 | } |
| 700 | 825 | |
| 701 | 826 | run(); |
| 702 | 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 | + | |
| 703 | 836 | |
| 704 | - return initPikchrModule.ready | |
| 837 | + return moduleRtn; | |
| 705 | 838 | } |
| 706 | 839 | ); |
| 707 | 840 | })(); |
| 708 | -if (typeof exports === 'object' && typeof module === 'object') | |
| 841 | +if (typeof exports === 'object' && typeof module === 'object') { | |
| 709 | 842 | 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); | |
| 714 | 848 |
| --- 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 | ||
| 1 | 1 |
| --- 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 @@ | ||
| 1133 | 1133 | ** designated host and port and all times. |
| 1134 | 1134 | */ |
| 1135 | 1135 | |
| 1136 | 1136 | |
| 1137 | 1137 | /* |
| 1138 | -** COMMAND: alerts* | |
| 1138 | +** COMMAND: alerts* abbreviated-subcommands | |
| 1139 | 1139 | ** |
| 1140 | 1140 | ** Usage: %fossil alerts SUBCOMMAND ARGS... |
| 1141 | 1141 | ** |
| 1142 | 1142 | ** Subcommands: |
| 1143 | 1143 | ** |
| 1144 | 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* |
| 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 @@ | ||
| 51 | 51 | blob_appendf(pExtra, " %s", g.argv[i]); |
| 52 | 52 | } |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | /* |
| 56 | -** COMMAND: all | |
| 56 | +** COMMAND: all abbreviated-subcommands | |
| 57 | 57 | ** |
| 58 | 58 | ** Usage: %fossil all SUBCOMMAND ... |
| 59 | 59 | ** |
| 60 | 60 | ** The ~/.fossil file records the location of all repositories for a |
| 61 | 61 | ** user. This command performs certain operations on all repositories |
| 62 | 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 |
| 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 @@ | ||
| 1994 | 1994 | zUtf8 = blob_str(pBlob) + bomSize; |
| 1995 | 1995 | zUtf8 = fossil_unicode_to_utf8(zUtf8); |
| 1996 | 1996 | blob_reset(pBlob); |
| 1997 | 1997 | blob_set_dynamic(pBlob, zUtf8); |
| 1998 | 1998 | }else if( useMbcs && invalid_utf8(pBlob) ){ |
| 1999 | -#if defined(_WIN32) || defined(__CYGWIN__) | |
| 1999 | +#if defined(_WIN32) | |
| 2000 | 2000 | zUtf8 = fossil_mbcs_to_utf8(blob_str(pBlob)); |
| 2001 | 2001 | blob_reset(pBlob); |
| 2002 | 2002 | blob_append(pBlob, zUtf8, -1); |
| 2003 | 2003 | fossil_mbcs_free(zUtf8); |
| 2004 | 2004 | #else |
| 2005 | 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) || 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 @@ | ||
| 598 | 598 | ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS? |
| 599 | 599 | ** |
| 600 | 600 | ** Run various subcommands to manage branches of the open repository or |
| 601 | 601 | ** of the repository identified by the -R or --repository option. |
| 602 | 602 | ** |
| 603 | -** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES? | |
| 603 | +** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES? | |
| 604 | 604 | ** |
| 605 | 605 | ** Adds or cancels the "closed" tag to one or more branches. |
| 606 | 606 | ** It accepts arbitrary unambiguous symbolic names but |
| 607 | 607 | ** will only resolve check-in names and skips any which resolve |
| 608 | 608 | ** to non-leaf check-ins. |
| @@ -612,26 +612,26 @@ | ||
| 612 | 612 | ** to stdout |
| 613 | 613 | ** -v|--verbose Output more information |
| 614 | 614 | ** --date-override DATE DATE to use instead of 'now' |
| 615 | 615 | ** --user-override USER USER to use instead of the current default |
| 616 | 616 | ** |
| 617 | -** > fossil branch current | |
| 617 | +** > fossil branch current | |
| 618 | 618 | ** |
| 619 | 619 | ** Print the name of the branch for the current check-out |
| 620 | 620 | ** |
| 621 | -** > fossil branch hide|unhide ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES? | |
| 621 | +** > fossil branch hide|unhide ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES? | |
| 622 | 622 | ** |
| 623 | 623 | ** Adds or cancels the "hidden" tag for the specified branches or |
| 624 | 624 | ** or check-in IDs. Accepts the same options as the close |
| 625 | 625 | ** subcommand. |
| 626 | 626 | ** |
| 627 | -** > fossil branch info BRANCH-NAME | |
| 627 | +** > fossil branch info BRANCH-NAME | |
| 628 | 628 | ** |
| 629 | 629 | ** Print information about a branch |
| 630 | 630 | ** |
| 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? | |
| 633 | 633 | ** |
| 634 | 634 | ** List all branches. |
| 635 | 635 | ** |
| 636 | 636 | ** Options: |
| 637 | 637 | ** -a|--all List all branches. Default show only open branches |
| @@ -653,11 +653,11 @@ | ||
| 653 | 653 | ** The "lsh" variant of this subcommand shows recently changed branches, |
| 654 | 654 | ** and accepts an optional LIMIT argument (defaults to 5) to cap output, |
| 655 | 655 | ** but no GLOB argument. All other options are supported, with -t being |
| 656 | 656 | ** an implied no-op. |
| 657 | 657 | ** |
| 658 | -** > fossil branch new BRANCH-NAME BASIS ?OPTIONS? | |
| 658 | +** > fossil branch new BRANCH-NAME BASIS ?OPTIONS? | |
| 659 | 659 | ** |
| 660 | 660 | ** Create a new branch BRANCH-NAME off of check-in BASIS. |
| 661 | 661 | ** |
| 662 | 662 | ** Options: |
| 663 | 663 | ** --private Branch is private (i.e., remains local) |
| 664 | 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 |
| --- 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 @@ | ||
| 255 | 255 | void cache_initialize(void){ |
| 256 | 256 | sqlite3_close(cacheOpen(1)); |
| 257 | 257 | } |
| 258 | 258 | |
| 259 | 259 | /* |
| 260 | -** COMMAND: cache* | |
| 260 | +** COMMAND: cache* abbreviated-subcommands | |
| 261 | 261 | ** |
| 262 | 262 | ** Usage: %fossil cache SUBCOMMAND |
| 263 | 263 | ** |
| 264 | 264 | ** Manage the cache used for potentially expensive web pages such as |
| 265 | 265 | ** /zip and /tarball. SUBCOMMAND can be: |
| 266 | 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* |
| 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 @@ | ||
| 220 | 220 | int maxChars, /* [in] Optimization hint to abort before space found. */ |
| 221 | 221 | int *sumWidth /* [out] Summated width of all characters to next space. */ |
| 222 | 222 | ){ |
| 223 | 223 | int cchUTF8, utf32, wcwidth = 0; |
| 224 | 224 | int nextIndex = index; |
| 225 | + if( zLine[index]==0 ) return index; | |
| 225 | 226 | for(;;){ |
| 226 | 227 | char_info_utf8(&zLine[nextIndex],&cchUTF8,&utf32); |
| 227 | 228 | nextIndex += cchUTF8; |
| 228 | 229 | wcwidth += cli_wcwidth(utf32); |
| 229 | 230 | if( zLine[nextIndex]==0 || fossil_isspace(zLine[nextIndex]) || |
| @@ -263,14 +264,16 @@ | ||
| 263 | 264 | int maxUTF8 = 1; /* Expected sequence length. */ |
| 264 | 265 | char c = z[i++]; |
| 265 | 266 | if( c==0x1b && z[i]=='[' ){ |
| 266 | 267 | do{ |
| 267 | 268 | 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 | + } | |
| 272 | 275 | } |
| 273 | 276 | if( (c&0x80)==0x00 ){ /* 7-bit ASCII character. */ |
| 274 | 277 | *pCchUTF8 = 1; |
| 275 | 278 | *pUtf32 = (int)z[0]; |
| 276 | 279 | return; |
| 277 | 280 |
| --- 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 @@ | ||
| 54 | 54 | /* NOTE: 0x0400 = CMDFLAG_SENSITIVE in mkindex.c! */ |
| 55 | 55 | #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */ |
| 56 | 56 | #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */ |
| 57 | 57 | #define CMDFLAG_ALIAS 0x2000 /* Command aliases */ |
| 58 | 58 | #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */ |
| 59 | +#define CMDFLAG_ABBREVSUBCMD 0x8000 /* Help text abbreviates subcommands */ | |
| 59 | 60 | /**************************************************************************/ |
| 60 | 61 | |
| 61 | 62 | /* Values for the 2nd parameter to dispatch_name_search() */ |
| 62 | 63 | #define CMDFLAG_ANY 0x0038 /* Match anything */ |
| 63 | 64 | #define CMDFLAG_PREFIX 0x0200 /* Prefix match is ok */ |
| @@ -522,13 +523,21 @@ | ||
| 522 | 523 | } |
| 523 | 524 | |
| 524 | 525 | /* |
| 525 | 526 | ** Format help text for TTY display. |
| 526 | 527 | */ |
| 527 | -static void help_to_text(const char *zHelp, Blob *pText){ | |
| 528 | +static void help_to_text(const char *zHelp, Blob *pText, int bUsage){ | |
| 528 | 529 | int i, x; |
| 529 | 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 | + } | |
| 530 | 539 | for(i=0; (c = zHelp[i])!=0; i++){ |
| 531 | 540 | if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){ |
| 532 | 541 | if( i>0 ) blob_append(pText, zHelp, i); |
| 533 | 542 | blob_append(pText, "fossil", 6); |
| 534 | 543 | zHelp += i+7; |
| @@ -603,11 +612,11 @@ | ||
| 603 | 612 | fossil_print("# %s\n", aCommand[bktHelp[aCommand[i].iHelp][j]].zName); |
| 604 | 613 | fossil_print("%s\n\n", aCommand[i].zHelp); |
| 605 | 614 | }else{ |
| 606 | 615 | Blob txt; |
| 607 | 616 | blob_init(&txt, 0, 0); |
| 608 | - help_to_text(aCommand[i].zHelp, &txt); | |
| 617 | + help_to_text(aCommand[i].zHelp, &txt, 0); | |
| 609 | 618 | for(j=0; j<occHelp[aCommand[i].iHelp]; j++){ |
| 610 | 619 | fossil_print("# %s%s\n", |
| 611 | 620 | aCommand[bktHelp[aCommand[i].iHelp][j]].zName, |
| 612 | 621 | (aCommand[i].eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? |
| 613 | 622 | " (versionable)" : ""); |
| @@ -855,11 +864,11 @@ | ||
| 855 | 864 | if( pCmd->zHelp[0]==0 ){ |
| 856 | 865 | @ No help available for "%h(pCmd->zName)" |
| 857 | 866 | }else if( P("plaintext") ){ |
| 858 | 867 | Blob txt; |
| 859 | 868 | blob_init(&txt, 0, 0); |
| 860 | - help_to_text(pCmd->zHelp, &txt); | |
| 869 | + help_to_text(pCmd->zHelp, &txt, 0); | |
| 861 | 870 | @ <pre class="helpPage"> |
| 862 | 871 | @ %h(blob_str(&txt)) |
| 863 | 872 | @ </pre> |
| 864 | 873 | blob_reset(&txt); |
| 865 | 874 | }else if( P("raw") ){ |
| @@ -1059,10 +1068,229 @@ | ||
| 1059 | 1068 | } |
| 1060 | 1069 | @ </dl> |
| 1061 | 1070 | blob_reset(&buf); |
| 1062 | 1071 | style_finish_page(); |
| 1063 | 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 | + | |
| 1064 | 1292 | |
| 1065 | 1293 | static void multi_column_list(const char **azWord, int nWord){ |
| 1066 | 1294 | int i, j, len; |
| 1067 | 1295 | int mxLen = 0; |
| 1068 | 1296 | int nCol; |
| @@ -1151,55 +1379,68 @@ | ||
| 1151 | 1379 | ; |
| 1152 | 1380 | |
| 1153 | 1381 | /* |
| 1154 | 1382 | ** COMMAND: help |
| 1155 | 1383 | ** |
| 1156 | -** Usage: %fossil help [OPTIONS] [TOPIC] | |
| 1384 | +** Usage: %fossil help [OPTIONS] [TOPIC] [SUBCOMMAND] | |
| 1157 | 1385 | ** |
| 1158 | 1386 | ** Display information on how to use TOPIC, which may be a command, webpage, or |
| 1159 | 1387 | ** 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. | |
| 1161 | 1391 | ** |
| 1162 | 1392 | ** The following options can be used when TOPIC is omitted: |
| 1163 | 1393 | ** |
| 1164 | 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 | |
| 1165 | 1399 | ** -o|--options List command-line options common to all commands |
| 1166 | 1400 | ** -s|--setting List setting names |
| 1167 | 1401 | ** -t|--test List unsupported "test" commands |
| 1168 | 1402 | ** -v|--verbose List both names and help text |
| 1169 | 1403 | ** -x|--aux List only auxiliary commands |
| 1170 | 1404 | ** -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 | 1405 | ** |
| 1176 | 1406 | ** These options can be used when TOPIC is present: |
| 1177 | 1407 | ** |
| 1178 | -** -h|--html Format output as HTML rather than plain text | |
| 1179 | 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 | |
| 1180 | 1415 | */ |
| 1181 | 1416 | void help_cmd(void){ |
| 1182 | 1417 | 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 | + | |
| 1193 | 1435 | verboseFlag = find_option("verbose","v",0)!=0; |
| 1194 | 1436 | commandsFlag = find_option("commands","c",0)!=0; |
| 1195 | 1437 | 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) ){ | |
| 1201 | 1442 | command_list(CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER, verboseFlag, useHtml); |
| 1202 | 1443 | return; |
| 1203 | 1444 | } |
| 1204 | 1445 | else if( find_option("www","w",0) ){ |
| 1205 | 1446 | command_list(CMDFLAG_WEBPAGE, verboseFlag, useHtml); |
| @@ -1238,23 +1479,32 @@ | ||
| 1238 | 1479 | CMDFLAG_SETTING | CMDFLAG_TEST, useHtml, 0); |
| 1239 | 1480 | return; |
| 1240 | 1481 | } |
| 1241 | 1482 | verify_all_options(); |
| 1242 | 1483 | if( g.argc<3 ){ |
| 1484 | + if( bOptions ){ | |
| 1485 | + fossil_print("%s", zOptions); | |
| 1486 | + return; | |
| 1487 | + } | |
| 1243 | 1488 | z = g.argv[0]; |
| 1244 | 1489 | fossil_print( |
| 1245 | 1490 | "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); | |
| 1249 | 1498 | command_list(CMDFLAG_1ST_TIER,verboseFlag,useHtml); |
| 1250 | 1499 | if( !verboseFlag ) version_cmd(); |
| 1251 | 1500 | return; |
| 1252 | 1501 | } |
| 1253 | 1502 | zTopic = g.argv[2]; |
| 1503 | + zSubtopic = g.argc>=4 ? g.argv[3] : 0; | |
| 1254 | 1504 | isPage = ('/' == zTopic[0]) ? 1 : 0; |
| 1255 | - if(isPage){ | |
| 1505 | + if( isPage ){ | |
| 1256 | 1506 | zCmdOrPage = "page"; |
| 1257 | 1507 | }else if( commandsFlag ){ |
| 1258 | 1508 | mask = CMDFLAG_COMMAND; |
| 1259 | 1509 | zCmdOrPage = "command"; |
| 1260 | 1510 | }else{ |
| @@ -1273,24 +1523,48 @@ | ||
| 1273 | 1523 | fossil_print("Did you mean one of these TOPICs:\n"); |
| 1274 | 1524 | n = dispatch_approx_match(g.argv[2], 5, az); |
| 1275 | 1525 | for(i=0; i<n; i++){ |
| 1276 | 1526 | fossil_print(" * %s\n", az[i]); |
| 1277 | 1527 | } |
| 1278 | - fossil_print("Also consider using:\n"); | |
| 1528 | + fossil_print("Other commands to try:\n"); | |
| 1279 | 1529 | fossil_print(" fossil search -h PATTERN ;# search all help text\n"); |
| 1280 | 1530 | fossil_print(" fossil help -a ;# show all commands\n"); |
| 1281 | 1531 | fossil_print(" fossil help -w ;# show all web-pages\n"); |
| 1282 | 1532 | fossil_print(" fossil help -s ;# show all settings\n"); |
| 1283 | 1533 | fossil_print(" fossil help -o ;# show global options\n"); |
| 1284 | - fossil_exit(1); | |
| 1534 | + return; | |
| 1285 | 1535 | } |
| 1536 | + bAbbrevSubcmd = (pCmd->eCmdFlags & CMDFLAG_ABBREVSUBCMD)!=0; | |
| 1286 | 1537 | z = pCmd->zHelp; |
| 1287 | 1538 | if( z==0 ){ |
| 1288 | 1539 | fossil_fatal("no help available for the %s %s", |
| 1289 | 1540 | pCmd->zName, zCmdOrPage); |
| 1290 | 1541 | } |
| 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 ){ | |
| 1292 | 1566 | const Setting *pSetting = db_find_setting(pCmd->zName, 0); |
| 1293 | 1567 | char *zDflt = 0; |
| 1294 | 1568 | if( pSetting!=0 && pSetting->def!=0 && *pSetting->def!=0 ){ |
| 1295 | 1569 | zDflt = mprintf(" (default: %s)", pSetting->def); |
| 1296 | 1570 | } |
| @@ -1299,17 +1573,21 @@ | ||
| 1299 | 1573 | (pCmd->eCmdFlags & CMDFLAG_VERSIONABLE)!=0 ? " (versionable)" : "" |
| 1300 | 1574 | ); |
| 1301 | 1575 | fossil_free(zDflt); |
| 1302 | 1576 | } |
| 1303 | 1577 | blob_init(&txt, 0, 0); |
| 1304 | - if( useHtml ){ | |
| 1578 | + if( bRaw ){ | |
| 1579 | + blob_append(&txt, z, -1); | |
| 1580 | + }else if( useHtml ){ | |
| 1305 | 1581 | help_to_html(z, &txt); |
| 1306 | 1582 | }else{ |
| 1307 | - help_to_text(z, &txt); | |
| 1583 | + help_to_text(z, &txt, bUsage || zSubtopic!=0); | |
| 1308 | 1584 | } |
| 1309 | - fossil_print("%s\n", blob_str(&txt)); | |
| 1585 | + if( blob_strlen(&txt)>0 ) fossil_print("%s\n", blob_str(&txt)); | |
| 1310 | 1586 | blob_reset(&txt); |
| 1587 | + blob_reset(&subtext1); | |
| 1588 | + blob_reset(&subtext2); | |
| 1311 | 1589 | } |
| 1312 | 1590 | |
| 1313 | 1591 | /* |
| 1314 | 1592 | ** Return a pointer to the setting information array. |
| 1315 | 1593 | ** |
| @@ -1481,11 +1759,11 @@ | ||
| 1481 | 1759 | sqlite3_result_text(ctx, pPage->zHelp, -1, SQLITE_STATIC); |
| 1482 | 1760 | break; |
| 1483 | 1761 | case 4: { /* formatted */ |
| 1484 | 1762 | Blob txt; |
| 1485 | 1763 | blob_init(&txt, 0, 0); |
| 1486 | - help_to_text(pPage->zHelp, &txt); | |
| 1764 | + help_to_text(pPage->zHelp, &txt, 0); | |
| 1487 | 1765 | sqlite3_result_text(ctx, blob_str(&txt), -1, fossil_free); |
| 1488 | 1766 | break; |
| 1489 | 1767 | } |
| 1490 | 1768 | case 5: { /* formatted */ |
| 1491 | 1769 | Blob txt; |
| 1492 | 1770 |
| --- 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 |
+2
| --- src/export.c | ||
| +++ src/export.c | ||
| @@ -480,10 +480,12 @@ | ||
| 480 | 480 | ** |
| 481 | 481 | ** See also: import |
| 482 | 482 | */ |
| 483 | 483 | /* |
| 484 | 484 | ** COMMAND: export* |
| 485 | +** | |
| 486 | +** Usage: %fossil export --git [REPOSITORY] | |
| 485 | 487 | ** |
| 486 | 488 | ** This command is deprecated. Use "fossil git export" instead. |
| 487 | 489 | */ |
| 488 | 490 | void export_cmd(void){ |
| 489 | 491 | Stmt q, q2, q3; |
| 490 | 492 |
| --- 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 |
+1
-1
| --- src/fossil.page.pikchrshowasm.js | ||
| +++ src/fossil.page.pikchrshowasm.js | ||
| @@ -524,11 +524,11 @@ | ||
| 524 | 524 | ForceResizeKludge(); |
| 525 | 525 | }/*onPikchrshowLoaded()*/; |
| 526 | 526 | |
| 527 | 527 | |
| 528 | 528 | /** |
| 529 | - Predefined scripts. Each entry is an object: | |
| 529 | + Predefined example pikchr scripts. Each entry is an object: | |
| 530 | 530 | |
| 531 | 531 | { |
| 532 | 532 | name: required string, |
| 533 | 533 | code: optional code string. An entry with a falsy code is treated |
| 534 | 534 | like a separator in the resulting SELECT element (a |
| 535 | 535 |
| --- 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 @@ | ||
| 60 | 60 | */ |
| 61 | 61 | #define FUZZ_WIKI 0 /* The Fossil-Wiki formatter */ |
| 62 | 62 | #define FUZZ_MARKDOWN 1 /* The Markdown formatter */ |
| 63 | 63 | #define FUZZ_ARTIFACT 2 /* Fuzz the artifact parser */ |
| 64 | 64 | #define FUZZ_WIKI2 3 /* FOSSIL_WIKI and FOSSIL_MARKDOWN */ |
| 65 | +#define FUZZ_COMFORMAT 4 /* comment_print() */ | |
| 65 | 66 | #endif |
| 66 | 67 | |
| 67 | 68 | /* The type of fuzzing to do */ |
| 68 | 69 | static int eFuzzType = FUZZ_WIKI; |
| 69 | 70 | |
| @@ -93,13 +94,20 @@ | ||
| 93 | 94 | blob_reset(&out); |
| 94 | 95 | markdown_to_html(&in, &title, &out); |
| 95 | 96 | blob_reset(&title); |
| 96 | 97 | break; |
| 97 | 98 | } |
| 98 | - case FUZZ_ARTIFACT: | |
| 99 | + case FUZZ_ARTIFACT: { | |
| 99 | 100 | fossil_fatal("FUZZ_ARTIFACT is not implemented."); |
| 100 | 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 | + } | |
| 101 | 109 | } |
| 102 | 110 | blob_reset(&in); |
| 103 | 111 | blob_reset(&out); |
| 104 | 112 | return 0; |
| 105 | 113 | } |
| @@ -116,10 +124,12 @@ | ||
| 116 | 124 | eFuzzType = FUZZ_WIKI; |
| 117 | 125 | }else if( fossil_strcmp(zType,"markdown")==0 ){ |
| 118 | 126 | eFuzzType = FUZZ_MARKDOWN; |
| 119 | 127 | }else if( fossil_strcmp(zType,"wiki2")==0 ){ |
| 120 | 128 | eFuzzType = FUZZ_WIKI2; |
| 129 | + }else if( fossil_strcmp(zType,"comformat")==0 ){ | |
| 130 | + eFuzzType = FUZZ_COMFORMAT; | |
| 121 | 131 | }else{ |
| 122 | 132 | fossil_fatal("unknown fuzz type: \"%s\"", zType); |
| 123 | 133 | } |
| 124 | 134 | } |
| 125 | 135 | |
| @@ -139,10 +149,11 @@ | ||
| 139 | 149 | ** |
| 140 | 150 | ** Usage: %fossil test-fuzz [-fuzztype TYPE] INPUTFILE... |
| 141 | 151 | ** |
| 142 | 152 | ** Run a fuzz test using INPUTFILE as the test data. TYPE can be one of: |
| 143 | 153 | ** |
| 154 | +** comformat Fuzz the comment_print() routine | |
| 144 | 155 | ** wiki Fuzz the Fossil-wiki translator |
| 145 | 156 | ** markdown Fuzz the markdown translator |
| 146 | 157 | ** artifact Fuzz the artifact parser |
| 147 | 158 | ** wiki2 Fuzz the Fossil-wiki and markdown translator |
| 148 | 159 | */ |
| 149 | 160 |
| --- 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 @@ | ||
| 198 | 198 | ** |
| 199 | 199 | ** Usage: %fossil hook COMMAND ... |
| 200 | 200 | ** |
| 201 | 201 | ** Commands include: |
| 202 | 202 | ** |
| 203 | -** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER | |
| 203 | +** > fossil hook add --command COMMAND --type TYPE --sequence NUMBER | |
| 204 | 204 | ** |
| 205 | 205 | ** Create a new hook. The --command and --type arguments are |
| 206 | 206 | ** required. --sequence is optional. |
| 207 | 207 | ** |
| 208 | -** > fossil hook delete ID ... | |
| 208 | +** > fossil hook delete ID ... | |
| 209 | 209 | ** |
| 210 | 210 | ** Delete one or more hooks by their IDs. ID can be "all" |
| 211 | 211 | ** to delete all hooks. Caution: There is no "undo" for |
| 212 | 212 | ** this operation. Deleted hooks are permanently lost. |
| 213 | 213 | ** |
| 214 | -** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ... | |
| 214 | +** > fossil hook edit --command COMMAND --type TYPE --sequence NUMBER ID ... | |
| 215 | 215 | ** |
| 216 | 216 | ** Make changes to one or more existing hooks. The ID argument |
| 217 | 217 | ** is either a hook-id, or a list of hook-ids, or the keyword |
| 218 | 218 | ** "all". For example, to disable hook number 2, use: |
| 219 | 219 | ** |
| 220 | 220 | ** fossil hook edit --type disabled 2 |
| 221 | 221 | ** |
| 222 | -** > fossil hook list | |
| 222 | +** > fossil hook list | |
| 223 | 223 | ** |
| 224 | 224 | ** Show all current hooks |
| 225 | 225 | ** |
| 226 | -** > fossil hook status | |
| 226 | +** > fossil hook status | |
| 227 | 227 | ** |
| 228 | 228 | ** Print the values of CONFIG table entries that are relevant to |
| 229 | 229 | ** hook processing. Used for debugging. |
| 230 | 230 | ** |
| 231 | -** > fossil hook test [OPTIONS] ID | |
| 231 | +** > fossil hook test [OPTIONS] ID | |
| 232 | 232 | ** |
| 233 | 233 | ** Run the hook script given by ID for testing purposes. |
| 234 | 234 | ** Options: |
| 235 | 235 | ** |
| 236 | 236 | ** --dry-run Print the script on stdout rather than run it |
| 237 | 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 |
| --- 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 @@ | ||
| 948 | 948 | if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath; |
| 949 | 949 | } |
| 950 | 950 | #endif /* FOSSIL_ENABLE_SSL */ |
| 951 | 951 | |
| 952 | 952 | /* |
| 953 | -** COMMAND: tls-config* | |
| 954 | -** COMMAND: ssl-config | |
| 953 | +** COMMAND: tls-config* abbreviated-subcommands | |
| 954 | +** COMMAND: ssl-config abbreviated-subcommands | |
| 955 | 955 | ** |
| 956 | 956 | ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...] |
| 957 | 957 | ** |
| 958 | 958 | ** This command is used to view or modify the TLS (Transport Layer |
| 959 | 959 | ** Security) configuration for Fossil. TLS (formerly SSL) is the |
| 960 | 960 | ** encryption technology used for secure HTTPS transport. |
| 961 | 961 | ** |
| 962 | 962 | ** Sub-commands: |
| 963 | 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 | |
| 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 | 974 | */ |
| 975 | 975 | void test_tlsconfig_info(void){ |
| 976 | 976 | const char *zCmd; |
| 977 | 977 | size_t nCmd; |
| 978 | 978 | int nHit = 0; |
| 979 | 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* |
| 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 @@ | ||
| 948 | 948 | if( file_isdir(zPath, ExtFILE)>0 ) *pzStore = zPath; |
| 949 | 949 | } |
| 950 | 950 | #endif /* FOSSIL_ENABLE_SSL */ |
| 951 | 951 | |
| 952 | 952 | /* |
| 953 | -** COMMAND: tls-config* | |
| 954 | -** COMMAND: ssl-config | |
| 953 | +** COMMAND: tls-config* abbreviated-subcommands | |
| 954 | +** COMMAND: ssl-config abbreviated-subcommands | |
| 955 | 955 | ** |
| 956 | 956 | ** Usage: %fossil ssl-config [SUBCOMMAND] [OPTIONS...] [ARGS...] |
| 957 | 957 | ** |
| 958 | 958 | ** This command is used to view or modify the TLS (Transport Layer |
| 959 | 959 | ** Security) configuration for Fossil. TLS (formerly SSL) is the |
| 960 | 960 | ** encryption technology used for secure HTTPS transport. |
| 961 | 961 | ** |
| 962 | 962 | ** Sub-commands: |
| 963 | 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 | |
| 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 | 974 | */ |
| 975 | 975 | void test_tlsconfig_info(void){ |
| 976 | 976 | const char *zCmd; |
| 977 | 977 | size_t nCmd; |
| 978 | 978 | int nHit = 0; |
| 979 | 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* |
| 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 @@ | ||
| 161 | 161 | ** Usage: %fossil interwiki COMMAND ... |
| 162 | 162 | ** |
| 163 | 163 | ** Manage the "intermap" that defines the mapping from interwiki tags |
| 164 | 164 | ** to complete URLs for interwiki links. |
| 165 | 165 | ** |
| 166 | -** > fossil interwiki delete TAG ... | |
| 166 | +** > fossil interwiki delete TAG ... | |
| 167 | 167 | ** |
| 168 | 168 | ** Delete one or more interwiki maps. |
| 169 | 169 | ** |
| 170 | -** > fossil interwiki edit TAG --base URL --hash PATH --wiki PATH | |
| 170 | +** > fossil interwiki edit TAG --base URL --hash PATH --wiki PATH | |
| 171 | 171 | ** |
| 172 | 172 | ** Create an interwiki referenced call TAG. The base URL is |
| 173 | 173 | ** the --base option, which is required. The --hash and --wiki |
| 174 | 174 | ** paths are optional. The TAG must be lower-case alphanumeric |
| 175 | 175 | ** and must be unique. A new entry is created if it does not |
| 176 | 176 | ** already exit. |
| 177 | 177 | ** |
| 178 | -** > fossil interwiki list | |
| 178 | +** > fossil interwiki list | |
| 179 | 179 | ** |
| 180 | 180 | ** Show all interwiki mappings. |
| 181 | 181 | */ |
| 182 | 182 | void interwiki_cmd(void){ |
| 183 | 183 | const char *zCmd; |
| 184 | 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 |
| --- 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 @@ | ||
| 3599 | 3599 | g.httpSSLConn = 0; |
| 3600 | 3600 | } |
| 3601 | 3601 | #endif /* FOSSIL_ENABLE_SSL */ |
| 3602 | 3602 | |
| 3603 | 3603 | #else /* WIN32 */ |
| 3604 | - find_server_repository(2, 0); | |
| 3604 | + /* Win32 implementation */ | |
| 3605 | 3605 | if( fossil_strcmp(g.zRepositoryName,"/")==0 ){ |
| 3606 | 3606 | allowRepoList = 1; |
| 3607 | 3607 | } |
| 3608 | - /* Win32 implementation */ | |
| 3609 | 3608 | if( allowRepoList ){ |
| 3610 | 3609 | flags |= HTTP_SERVER_REPOLIST; |
| 3611 | 3610 | } |
| 3612 | 3611 | if( win32_http_service(iPort, zAltBase, zNotFound, zFileGlob, flags) ){ |
| 3613 | 3612 | win32_http_server(iPort, mxPort, zBrowserCmd, zStopperFile, |
| 3614 | 3613 |
| --- 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 @@ | ||
| 2136 | 2136 | $(OBJDIR)/cson_amalgamation.o: $(SRCDIR_extsrc)/cson_amalgamation.c |
| 2137 | 2137 | $(XTCC) -c $(SRCDIR_extsrc)/cson_amalgamation.c -o $@ |
| 2138 | 2138 | |
| 2139 | 2139 | $(SRCDIR_extsrc)/pikchr.js: $(SRCDIR_extsrc)/pikchr.c |
| 2140 | 2140 | $(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 \ | |
| 2142 | 2142 | -sEXPORTED_FUNCTIONS=_pikchr $(SRCDIR_extsrc)/pikchr.c \ |
| 2143 | 2143 | -sENVIRONMENT=web \ |
| 2144 | 2144 | -sMODULARIZE \ |
| 2145 | 2145 | -sEXPORT_NAME=initPikchrModule \ |
| 2146 | 2146 | --minify 0 |
| 2147 | 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,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 @@ | ||
| 698 | 698 | fossil_fatal("cannot change to directory \"%s\"", zDir); |
| 699 | 699 | } |
| 700 | 700 | fossil_free(zToFree); |
| 701 | 701 | return zPatchFile; |
| 702 | 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 | +} | |
| 703 | 719 | |
| 704 | 720 | /* |
| 705 | 721 | ** Create a FILE* that will execute the remote side of a push or pull |
| 706 | 722 | ** using ssh (probably) or fossil for local pushes and pulls. Return |
| 707 | 723 | ** a FILE* obtained from popen() into which we write the patch, or from |
| @@ -729,11 +745,11 @@ | ||
| 729 | 745 | if( mFlags & PATCH_DRYRUN ) blob_appendf(&flgs, " -n"); |
| 730 | 746 | zForce = blob_size(&flgs)>0 ? blob_str(&flgs) : ""; |
| 731 | 747 | if( g.argc!=4 ){ |
| 732 | 748 | usage(mprintf("%s [USER@]HOST:DIRECTORY", zThisCmd)); |
| 733 | 749 | } |
| 734 | - zRemote = fossil_strdup(g.argv[3]); | |
| 750 | + zRemote = patch_resolve_remote(g.argv[3]); | |
| 735 | 751 | zDir = (char*)file_skip_userhost(zRemote); |
| 736 | 752 | if( zDir==0 ){ |
| 737 | 753 | if( isRetry ) goto remote_command_error; |
| 738 | 754 | zDir = zRemote; |
| 739 | 755 | blob_append_escaped_arg(&cmd, g.nameOfExe, 1); |
| @@ -778,11 +794,11 @@ | ||
| 778 | 794 | /* |
| 779 | 795 | ** Toggle the use-path-for-ssh setting for the remote host defined |
| 780 | 796 | ** by g.argv[3]. |
| 781 | 797 | */ |
| 782 | 798 | 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]); | |
| 784 | 800 | char *zDir = (char*)file_skip_userhost(zRemote); |
| 785 | 801 | if( zDir ){ |
| 786 | 802 | *(char*)(zDir - 1) = 0; |
| 787 | 803 | ssh_needs_path_argument(zRemote, 99); |
| 788 | 804 | } |
| @@ -905,11 +921,10 @@ | ||
| 905 | 921 | db_finalize(&q); |
| 906 | 922 | diff_end(pCfg, nErr); |
| 907 | 923 | if( nErr ) fossil_fatal("abort due to prior errors"); |
| 908 | 924 | } |
| 909 | 925 | |
| 910 | - | |
| 911 | 926 | /* |
| 912 | 927 | ** COMMAND: patch |
| 913 | 928 | ** |
| 914 | 929 | ** Usage: %fossil patch SUBCOMMAND ?ARGS ..? |
| 915 | 930 | ** |
| @@ -916,10 +931,22 @@ | ||
| 916 | 931 | ** This command is used to create, view, and apply Fossil binary patches. |
| 917 | 932 | ** A Fossil binary patch is a single (binary) file that captures all of the |
| 918 | 933 | ** uncommitted changes of a check-out. Use Fossil binary patches to transfer |
| 919 | 934 | ** proposed or incomplete changes between machines for testing or analysis. |
| 920 | 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 | +** | |
| 921 | 948 | ** > fossil patch create [DIRECTORY] PATCHFILE |
| 922 | 949 | ** |
| 923 | 950 | ** Create a new binary patch in PATCHFILE that captures all uncommitted |
| 924 | 951 | ** changes in the check-out at DIRECTORY, or the current directory if |
| 925 | 952 | ** DIRECTORY is omitted. If PATCHFILE is "-" then the binary patch |
| @@ -996,14 +1023,76 @@ | ||
| 996 | 1023 | void patch_cmd(void){ |
| 997 | 1024 | const char *zCmd; |
| 998 | 1025 | size_t n; |
| 999 | 1026 | if( g.argc<3 ){ |
| 1000 | 1027 | patch_usage: |
| 1001 | - usage("apply|create|diff|gdiff|pull|push|view"); | |
| 1028 | + usage("alias|apply|create|diff|gdiff|pull|push|view"); | |
| 1002 | 1029 | } |
| 1003 | 1030 | zCmd = g.argv[2]; |
| 1004 | 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 | |
| 1005 | 1094 | if( strncmp(zCmd, "apply", n)==0 ){ |
| 1006 | 1095 | char *zIn; |
| 1007 | 1096 | unsigned flags = 0; |
| 1008 | 1097 | if( find_option("dry-run","n",0) ) flags |= PATCH_DRYRUN; |
| 1009 | 1098 | if( find_option("verbose","v",0) ) flags |= PATCH_VERBOSE; |
| 1010 | 1099 |
| --- 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 @@ | ||
| 1414 | 1414 | } |
| 1415 | 1415 | |
| 1416 | 1416 | /* |
| 1417 | 1417 | ** COMMAND: deconstruct* |
| 1418 | 1418 | ** |
| 1419 | -** Usage %fossil deconstruct ?OPTIONS? DESTINATION | |
| 1419 | +** Usage: %fossil deconstruct ?OPTIONS? DESTINATION | |
| 1420 | 1420 | ** |
| 1421 | 1421 | ** This command exports all artifacts of a given repository and writes all |
| 1422 | 1422 | ** artifacts to the file system. The DESTINATION directory will be populated |
| 1423 | 1423 | ** with subdirectories AA and files AA/BBBBBBBBB.., where AABBBBBBBBB.. is the |
| 1424 | 1424 | ** 40+ character artifact ID, AA the first 2 characters. |
| 1425 | 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 |
| --- 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 @@ | ||
| 682 | 682 | if( j>0 && pRe->zInit[j-1]==0 ) j--; |
| 683 | 683 | pRe->nInit = j; |
| 684 | 684 | } |
| 685 | 685 | return pRe->zErr; |
| 686 | 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 | +} | |
| 687 | 726 | |
| 688 | 727 | /* |
| 689 | 728 | ** Implementation of the regexp() SQL function. This function implements |
| 690 | 729 | ** the build-in REGEXP operator. The first argument to the function is the |
| 691 | 730 | ** pattern and the second argument is the string. So, the SQL statements: |
| 692 | 731 |
| --- 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 @@ | ||
| 630 | 630 | zSnip[k++] = '&'; |
| 631 | 631 | j += 4; |
| 632 | 632 | }else{ |
| 633 | 633 | zSnip[k++] = c; |
| 634 | 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++; | |
| 635 | 639 | }else{ |
| 636 | 640 | zSnip[k++] = c; |
| 637 | 641 | } |
| 638 | 642 | } |
| 639 | 643 | zSnip[k] = 0; |
| @@ -645,30 +649,38 @@ | ||
| 645 | 649 | ** |
| 646 | 650 | ** COMMAND: search* |
| 647 | 651 | ** |
| 648 | 652 | ** Usage: %fossil search [OPTIONS] PATTERN... |
| 649 | 653 | ** |
| 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. | |
| 663 | 674 | ** |
| 664 | 675 | ** Options: |
| 665 | 676 | ** -a|--all Search everything |
| 666 | 677 | ** -c|--checkins Search checkin comments |
| 667 | 678 | ** --docs Search embedded documentation |
| 668 | 679 | ** --forum Search forum posts |
| 669 | 680 | ** -h|--bi-help Search built-in help |
| 681 | +** --highlight N Used VT100 color N for matching text. 0 means "off". | |
| 670 | 682 | ** -n|--limit N Limit output to N matches |
| 671 | 683 | ** --technotes Search tech notes |
| 672 | 684 | ** --tickets Search tickets |
| 673 | 685 | ** -W|--width WIDTH Set display width to WIDTH columns, 0 for |
| 674 | 686 | ** unlimited. Defaults to the terminal's width. |
| @@ -687,14 +699,24 @@ | ||
| 687 | 699 | const char *zScope = 0; |
| 688 | 700 | const char *zWidth = find_option("width","W",1); |
| 689 | 701 | int bDebug = find_option("debug",0,0)!=0; /* Undocumented */ |
| 690 | 702 | int nLimit = zLimit ? atoi(zLimit) : -1000; |
| 691 | 703 | 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 | + } | |
| 693 | 715 | |
| 694 | 716 | /* Undocumented option to change highlight color */ |
| 695 | - const char *zHighlight = find_option("highlight",0,1); | |
| 717 | + zHighlight = find_option("highlight",0,1); | |
| 696 | 718 | if( zHighlight ) nTty = atoi(zHighlight); |
| 697 | 719 | |
| 698 | 720 | /* Undocumented option (legacy) */ |
| 699 | 721 | zScope = find_option("scope",0,1); |
| 700 | 722 | |
| @@ -1036,21 +1058,28 @@ | ||
| 1036 | 1058 | " FROM event JOIN blob on event.objid=blob.rid" |
| 1037 | 1059 | " WHERE search_match('',body('f',rid,NULL));" |
| 1038 | 1060 | ); |
| 1039 | 1061 | } |
| 1040 | 1062 | if( (srchFlags & SRCH_HELP)!=0 ){ |
| 1063 | + const char *zPrefix; | |
| 1041 | 1064 | helptext_vtab_register(g.db); |
| 1065 | + if( srchFlags==SRCH_HELP ){ | |
| 1066 | + zPrefix = "The"; | |
| 1067 | + }else{ | |
| 1068 | + zPrefix = "Built-in help for the"; | |
| 1069 | + } | |
| 1042 | 1070 | db_multi_exec( |
| 1043 | 1071 | "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)," | |
| 1045 | 1073 | " '/help?cmd='||name," |
| 1046 | 1074 | " search_score()," |
| 1047 | 1075 | " 'h'||rowid," |
| 1048 | 1076 | " search_snippet()" |
| 1049 | 1077 | " FROM helptext" |
| 1050 | 1078 | " WHERE search_match(format('the \"%%s\" %%s',name,type)," |
| 1051 | - " helptext.helptext);" | |
| 1079 | + " helptext.helptext);", | |
| 1080 | + zPrefix | |
| 1052 | 1081 | ); |
| 1053 | 1082 | } |
| 1054 | 1083 | } |
| 1055 | 1084 | |
| 1056 | 1085 | /* |
| @@ -2262,32 +2291,32 @@ | ||
| 2262 | 2291 | } |
| 2263 | 2292 | fossil_print(" done\n"); |
| 2264 | 2293 | } |
| 2265 | 2294 | |
| 2266 | 2295 | /* |
| 2267 | -** COMMAND: fts-config* | |
| 2296 | +** COMMAND: fts-config* abbreviated-subcommands | |
| 2268 | 2297 | ** |
| 2269 | 2298 | ** Usage: fossil fts-config ?SUBCOMMAND? ?ARGUMENT? |
| 2270 | 2299 | ** |
| 2271 | 2300 | ** The "fossil fts-config" command configures the full-text search capabilities |
| 2272 | 2301 | ** of the repository. Subcommands: |
| 2273 | 2302 | ** |
| 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. | |
| 2289 | 2318 | ** |
| 2290 | 2319 | ** The current search settings are displayed after any changes are applied. |
| 2291 | 2320 | ** Run this command with no arguments to simply see the settings. |
| 2292 | 2321 | */ |
| 2293 | 2322 | void fts_config_cmd(void){ |
| 2294 | 2323 |
| --- 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 |
+2
-2
| --- src/unversioned.c | ||
| +++ src/unversioned.c | ||
| @@ -218,12 +218,12 @@ | ||
| 218 | 218 | } |
| 219 | 219 | return 0; |
| 220 | 220 | } |
| 221 | 221 | |
| 222 | 222 | /* |
| 223 | -** COMMAND: uv# | |
| 224 | -** COMMAND: unversioned | |
| 223 | +** COMMAND: uv# abbreviated-subcommands | |
| 224 | +** COMMAND: unversioned abbreviated-subcommands | |
| 225 | 225 | ** |
| 226 | 226 | ** Usage: %fossil unversioned SUBCOMMAND ARGS... |
| 227 | 227 | ** or: %fossil uv SUBCOMMAND ARGS.. |
| 228 | 228 | ** |
| 229 | 229 | ** Unversioned files (UV-files) are artifacts that are synced and are available |
| 230 | 230 |
| --- 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 @@ | ||
| 331 | 331 | ** > fossil user default ?USERNAME? |
| 332 | 332 | ** |
| 333 | 333 | ** Query or set the default user. The default user is the |
| 334 | 334 | ** user for command-line interaction. |
| 335 | 335 | ** |
| 336 | -** > fossil user list | |
| 337 | -** > fossil user ls | |
| 336 | +** > fossil user list | ls | |
| 338 | 337 | ** |
| 339 | 338 | ** List all users known to the repository |
| 340 | 339 | ** |
| 341 | 340 | ** > fossil user new ?USERNAME? ?CONTACT-INFO? ?PASSWORD? |
| 342 | 341 | ** |
| 343 | 342 |
| --- 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 @@ | ||
| 25 | 25 | #ifdef _WIN32 |
| 26 | 26 | # include <windows.h> |
| 27 | 27 | #endif |
| 28 | 28 | #include "cygsup.h" |
| 29 | 29 | |
| 30 | -#if defined(_WIN32) || defined(__CYGWIN__) | |
| 30 | +#if defined(_WIN32) | |
| 31 | 31 | /* |
| 32 | 32 | ** Translate MBCS to UTF-8. Return a pointer to the translated text. |
| 33 | 33 | ** Call fossil_mbcs_free() to deallocate any memory used to store the |
| 34 | 34 | ** returned pointer when done. |
| 35 | 35 | */ |
| 36 | 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) || 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 |
+3
| --- tools/mkindex.c | ||
| +++ tools/mkindex.c | ||
| @@ -100,10 +100,11 @@ | ||
| 100 | 100 | #define CMDFLAG_SENSITIVE 0x0400 /* Security-sensitive setting */ |
| 101 | 101 | #define CMDFLAG_HIDDEN 0x0800 /* Elide from most listings */ |
| 102 | 102 | #define CMDFLAG_LDAVG_EXEMPT 0x1000 /* Exempt from load_control() */ |
| 103 | 103 | #define CMDFLAG_ALIAS 0x2000 /* Command aliases */ |
| 104 | 104 | #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */ |
| 105 | +#define CMDFLAG_ABBREVSUBCMD 0x8000 /* Abbreviated subcmd in help text */ | |
| 105 | 106 | /**************************************************************************/ |
| 106 | 107 | |
| 107 | 108 | /* |
| 108 | 109 | ** Each entry looks like this: |
| 109 | 110 | */ |
| @@ -280,10 +281,12 @@ | ||
| 280 | 281 | aEntry[nUsed].zVar = string_dup(&zLine[i+9], j-9); |
| 281 | 282 | }else if( j==6 && strncmp(&zLine[i], "hidden", 6)==0 ){ |
| 282 | 283 | aEntry[nUsed].eType |= CMDFLAG_HIDDEN; |
| 283 | 284 | }else if( j==14 && strncmp(&zLine[i], "loadavg-exempt", 14)==0 ){ |
| 284 | 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; | |
| 285 | 288 | }else{ |
| 286 | 289 | fprintf(stderr, "%s:%d: unknown option: '%.*s'\n", |
| 287 | 290 | zFile, nLine, j, &zLine[i]); |
| 288 | 291 | nErr++; |
| 289 | 292 | } |
| 290 | 293 | |
| 291 | 294 | ADDED win/build32.bat |
| 292 | 295 | 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 |
+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/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 |
+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 |
| --- 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 @@ | ||
| 340 | 340 | found in the help text for the [/help?cmd=test-fuzz|test-fuzz |
| 341 | 341 | command]. |
| 342 | 342 | |
| 343 | 343 | Fuzzing requires: |
| 344 | 344 | |
| 345 | - * Customizing the build of fossil a small bit. | |
| 346 | 345 | * The clang C compiler. |
| 347 | 346 | * libfuzzer. On Ubuntu-derived systems, it can be installed with |
| 348 | 347 | <tt>apt install libfuzzer-XYZ</tt>, where XYZ is a version number |
| 349 | 348 | (several versions may be available on any given system) |
| 350 | 349 | |
| 351 | 350 | |
| 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 | |
| 364 | 355 | </code></pre> |
| 365 | 356 | |
| 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 | |
| 370 | 358 | one primarily in that it runs the <tt>test-fuzz</tt> command by |
| 371 | 359 | default. It needs to be told what to fuzz and needs to be given a |
| 372 | 360 | directory of input files to seed the fuzzer with: |
| 373 | 361 | |
| 374 | 362 | |
| 375 | -<pre></code>$ mkdir cases | |
| 363 | +<pre><code>$ mkdir cases | |
| 376 | 364 | # Copy input files into ./cases. e.g. when fuzzing the markdown |
| 377 | 365 | # processor, copy any to-be-tested .md files into that directory. |
| 378 | 366 | # Then start the fuzzer: |
| 379 | 367 | $ ./fossil-fuzz --fuzztype markdown cases |
| 380 | 368 | </code></pre> |
| 381 | 369 | |
| 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" | |
| 383 | 371 | directory, each one named in the form of a hash. When it finds a |
| 384 | 372 | problem it will produce a stack trace for the offending code, will |
| 385 | 373 | output the name of the file which triggered the crash (named |
| 386 | 374 | <tt>cases/SOME_HASH</tt>) and may, depending on the nature of the |
| 387 | 375 | problem, produce a file named <tt>crash-SOMETHING</tt>. In theory the |
| 388 | 376 |
| --- 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 |
+2
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -53,10 +53,12 @@ | ||
| 53 | 53 | and debugging |
| 54 | 54 | * Fix a bug in [/help?cmd=patch|fossil patch create] that causes |
| 55 | 55 | [/help?cmd=revert|fossil revert] operations that happened on individual |
| 56 | 56 | files after a [/help?cmd=merge|fossil merge] to be omitted from the |
| 57 | 57 | patch. |
| 58 | + * Added the [/help?cmd=patch|patch alias] command for managing aliases | |
| 59 | + for remote checkout names. | |
| 58 | 60 | |
| 59 | 61 | <h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2> |
| 60 | 62 | |
| 61 | 63 | * The "[/help?cmd=ui|fossil ui /]" command now works even for repositories |
| 62 | 64 | that have non-ASCII filenames |
| 63 | 65 |
| --- 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 |