Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Systemtap: add new role "attached" for "probe" kind , and run CPreProcessor as a guest parser #3607

Merged
merged 9 commits into from
Dec 24, 2022
2 changes: 2 additions & 0 deletions Tmain/list-roles.d/stdout-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Ruby L/library required on loaded by "require"
Ruby L/library requiredRel on loaded by "require_relative" method
Sh h/heredoc endmarker on end marker
Sh s/script loaded on loaded
SystemTap p/probe attached on attached by code for probing
SystemVerilog m/module decl on declaring instances
SystemdUnit u/unit After on referred in After key
SystemdUnit u/unit Before on referred in Before key
Expand Down Expand Up @@ -212,6 +213,7 @@ Ruby L/library required on loaded by "require"
Ruby L/library requiredRel on loaded by "require_relative" method
Sh h/heredoc endmarker on end marker
Sh s/script loaded on loaded
SystemTap p/probe attached on attached by code for probing
SystemVerilog m/module decl on declaring instances
SystemdUnit u/unit After on referred in After key
SystemdUnit u/unit Before on referred in Before key
Expand Down
2 changes: 1 addition & 1 deletion Tmain/optscript.d/error-undefined-if-if.expected
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ top| |bottom
Execution stack:
top| a {a} --if-- {true {a} if} --if-- |bottom
Dictionary stack:
top| -dict:1- -dict:88- |bottom
top| -dict:1- -dict:89- |bottom
2 changes: 1 addition & 1 deletion Tmain/optscript.d/error-undefined-if.expected
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ top| |bottom
Execution stack:
top| a {a} --if-- |bottom
Dictionary stack:
top| -dict:1- -dict:88- |bottom
top| -dict:1- -dict:89- |bottom
7 changes: 7 additions & 0 deletions Tmain/optscript.d/typeattrconv.expected
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@ arraytype
(--arraytype--)
(--dicttype--)
(--arraytype--)
3
abc
/abc
true
{}
[]
true
Binary file modified Tmain/optscript.d/typeattrconv.ps
Binary file not shown.
4 changes: 3 additions & 1 deletion Units/parser-systemtap.r/probes.d/args.ctags
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
--sort=no
--fields=+ne
--fields=+ner
--extras=+r
--extras=+g
110 changes: 72 additions & 38 deletions Units/parser-systemtap.r/probes.d/expected.tags
Original file line number Diff line number Diff line change
@@ -1,38 +1,72 @@
tcp_get_info_rto input.stp /^function tcp_get_info_rto:long(sock:long)$/;" f line:33 end:44
tcp_get_info_snd_cwnd input.stp /^function tcp_get_info_snd_cwnd:long(sock:long)$/;" f line:50 end:60
tcp_ts_get_info_state input.stp /^function tcp_ts_get_info_state:long(sock:long)$/;" f line:78 end:83
__tcp_sock_dport input.stp /^function __tcp_sock_dport:long (sock:long)$/;" f line:86 end:93
__get_skb_tcphdr_new input.stp /^@__private30 function __get_skb_tcphdr_new:long(skb:long)$/;" f line:96 end:107
__get_skb_tcphdr input.stp /^function __get_skb_tcphdr:long(skb:long)$/;" f line:110 end:118
__tcp_skb_urg input.stp /^function __tcp_skb_urg:long (tcphdr:long)$/;" f line:121 end:124
__tcp_skb_ack input.stp /^function __tcp_skb_ack:long (tcphdr:long)$/;" f line:127 end:130
__tcp_skb_psh input.stp /^function __tcp_skb_psh:long (tcphdr:long)$/;" f line:133 end:136
__tcp_skb_rst input.stp /^function __tcp_skb_rst:long (tcphdr:long)$/;" f line:139 end:142
__tcp_skb_syn input.stp /^function __tcp_skb_syn:long (tcphdr:long)$/;" f line:145 end:148
__tcp_skb_fin input.stp /^function __tcp_skb_fin:long (tcphdr:long)$/;" f line:151 end:154
__tcp_skb_sport input.stp /^function __tcp_skb_sport:long (tcphdr:long)$/;" f line:157 end:160
__tcp_skb_dport input.stp /^function __tcp_skb_dport:long (tcphdr:long){$/;" f line:163 end:165
__tcp_sock_sport input.stp /^function __tcp_sock_sport:long (sock:long)$/;" f line:168 end:174
sockstate input.stp /^@__private30 global sockstate[12]$/;" v line:176
tcp_sockstate_str input.stp /^function tcp_sockstate_str:string (state:long) {$/;" f line:192 end:194
tcp_ts_get_info_snd_ssthresh input.stp /^function tcp_ts_get_info_snd_ssthresh:long(sock:long)$/;" f line:199 end:209
tcp_ts_get_info_rcv_mss input.stp /^function tcp_ts_get_info_rcv_mss:long(sock:long)$/;" f line:213 end:224
__sockopt input.stp /^@__private30 global __sockopt[18]$/;" v line:248
tcp_sockopt_str input.stp /^function tcp_sockopt_str:string (optname:long)$/;" f line:281 end:285
__ipv6_sockopt input.stp /^@__private30 global __ipv6_sockopt[55]$/;" v line:349
tcp_ipv6_sockopt_str input.stp /^function tcp_ipv6_sockopt_str:string (optname:long)$/;" f line:467 end:471
tcp.sendmsg input.stp /^probe tcp.sendmsg = kernel.function("tcp_sendmsg") {$/;" p line:483 end:488
tcp.sendmsg.return input.stp /^probe tcp.sendmsg.return = kernel.function("tcp_sendmsg").return {$/;" p line:498 end:501
tcp.recvmsg input.stp /^probe tcp.recvmsg = kernel.function("tcp_recvmsg") {$/;" p line:516 end:525
tcp.recvmsg.return input.stp /^probe tcp.recvmsg.return = kernel.function("tcp_recvmsg").return {$/;" p line:540 end:548
tcp.disconnect input.stp /^probe tcp.disconnect = kernel.function("tcp_disconnect") {$/;" p line:564 end:573
tcp.disconnect.return input.stp /^probe tcp.disconnect.return = kernel.function("tcp_disconnect").return {$/;" p line:583 end:586
tcp.setsockopt input.stp /^probe tcp.setsockopt = tcp.ipv4.setsockopt, tcp.ipv6.setsockopt$/;" p line:601 end:603
tcp.ipv4.setsockopt input.stp /^probe tcp.ipv4.setsockopt = kernel.function("tcp_setsockopt")$/;" p line:604 end:613
tcp.ipv6.setsockopt input.stp /^probe tcp.ipv6.setsockopt = kernel.function("ipv6_setsockopt")!,$/;" p line:614 end:624
tcp.setsockopt.return input.stp /^probe tcp.setsockopt.return = tcp.ipv4.setsockopt.return,$/;" p line:634 end:637
tcp.ipv4.setsockopt.return input.stp /^probe tcp.ipv4.setsockopt.return = kernel.function("tcp_setsockopt").return$/;" p line:638 end:642
tcp.ipv6.setsockopt.return input.stp /^probe tcp.ipv6.setsockopt.return = kernel.function("ipv6_setsockopt").return!,$/;" p line:643 end:648
tcp.receive input.stp /^probe tcp.receive = tcp.ipv4.receive, tcp.ipv6.receive$/;" p line:667 end:669
tcp.ipv4.receive input.stp /^probe tcp.ipv4.receive = kernel.function("tcp_v4_rcv")$/;" p line:671 end:694
tcp.ipv6.receive input.stp /^probe tcp.ipv6.receive = kernel.function("tcp_v6_rcv")!,$/;" p line:696 end:730
tcp_get_info_rto input.stp /^function tcp_get_info_rto:long(sock:long)$/;" f line:33 roles:def end:44
tcp_get_info_snd_cwnd input.stp /^function tcp_get_info_snd_cwnd:long(sock:long)$/;" f line:50 roles:def end:60
tcp_ts_get_info_state input.stp /^function tcp_ts_get_info_state:long(sock:long)$/;" f line:78 roles:def end:83
__tcp_sock_dport input.stp /^function __tcp_sock_dport:long (sock:long)$/;" f line:86 roles:def end:93
__get_skb_tcphdr_new input.stp /^@__private30 function __get_skb_tcphdr_new:long(skb:long)$/;" f line:96 roles:def end:107
__get_skb_tcphdr input.stp /^function __get_skb_tcphdr:long(skb:long)$/;" f line:110 roles:def end:118
__tcp_skb_urg input.stp /^function __tcp_skb_urg:long (tcphdr:long)$/;" f line:121 roles:def end:124
__tcp_skb_ack input.stp /^function __tcp_skb_ack:long (tcphdr:long)$/;" f line:127 roles:def end:130
__tcp_skb_psh input.stp /^function __tcp_skb_psh:long (tcphdr:long)$/;" f line:133 roles:def end:136
__tcp_skb_rst input.stp /^function __tcp_skb_rst:long (tcphdr:long)$/;" f line:139 roles:def end:142
__tcp_skb_syn input.stp /^function __tcp_skb_syn:long (tcphdr:long)$/;" f line:145 roles:def end:148
__tcp_skb_fin input.stp /^function __tcp_skb_fin:long (tcphdr:long)$/;" f line:151 roles:def end:154
__tcp_skb_sport input.stp /^function __tcp_skb_sport:long (tcphdr:long)$/;" f line:157 roles:def end:160
__tcp_skb_dport input.stp /^function __tcp_skb_dport:long (tcphdr:long){$/;" f line:163 roles:def end:165
__tcp_sock_sport input.stp /^function __tcp_sock_sport:long (sock:long)$/;" f line:168 roles:def end:174
sockstate input.stp /^@__private30 global sockstate[12]$/;" v line:176 roles:def
init input.stp /^probe init {$/;" p line:177 roles:attached end:190
tcp_sockstate_str input.stp /^function tcp_sockstate_str:string (state:long) {$/;" f line:192 roles:def end:194
tcp_ts_get_info_snd_ssthresh input.stp /^function tcp_ts_get_info_snd_ssthresh:long(sock:long)$/;" f line:199 roles:def end:209
tcp_ts_get_info_rcv_mss input.stp /^function tcp_ts_get_info_rcv_mss:long(sock:long)$/;" f line:213 roles:def end:224
__sockopt input.stp /^@__private30 global __sockopt[18]$/;" v line:248 roles:def
init input.stp /^probe init {$/;" p line:249 roles:attached end:279
tcp_sockopt_str input.stp /^function tcp_sockopt_str:string (optname:long)$/;" f line:281 roles:def end:285
__ipv6_sockopt input.stp /^@__private30 global __ipv6_sockopt[55]$/;" v line:349 roles:def
init input.stp /^probe init {$/;" p line:350 roles:attached end:465
tcp_ipv6_sockopt_str input.stp /^function tcp_ipv6_sockopt_str:string (optname:long)$/;" f line:467 roles:def end:471
tcp.sendmsg input.stp /^probe tcp.sendmsg = kernel.function("tcp_sendmsg") {$/;" p line:483 roles:def end:488
tcp.sendmsg.return input.stp /^probe tcp.sendmsg.return = kernel.function("tcp_sendmsg").return {$/;" p line:498 roles:def end:501
tcp.recvmsg input.stp /^probe tcp.recvmsg = kernel.function("tcp_recvmsg") {$/;" p line:516 roles:def end:525
tcp.recvmsg.return input.stp /^probe tcp.recvmsg.return = kernel.function("tcp_recvmsg").return {$/;" p line:540 roles:def end:548
tcp.disconnect input.stp /^probe tcp.disconnect = kernel.function("tcp_disconnect") {$/;" p line:564 roles:def end:573
tcp.disconnect.return input.stp /^probe tcp.disconnect.return = kernel.function("tcp_disconnect").return {$/;" p line:583 roles:def end:586
tcp.setsockopt input.stp /^probe tcp.setsockopt = tcp.ipv4.setsockopt, tcp.ipv6.setsockopt$/;" p line:601 roles:def end:603
tcp.ipv4.setsockopt input.stp /^probe tcp.ipv4.setsockopt = kernel.function("tcp_setsockopt")$/;" p line:604 roles:def end:613
tcp.ipv6.setsockopt input.stp /^probe tcp.ipv6.setsockopt = kernel.function("ipv6_setsockopt")!,$/;" p line:614 roles:def end:624
tcp.setsockopt.return input.stp /^probe tcp.setsockopt.return = tcp.ipv4.setsockopt.return,$/;" p line:634 roles:def end:637
tcp.ipv4.setsockopt.return input.stp /^probe tcp.ipv4.setsockopt.return = kernel.function("tcp_setsockopt").return$/;" p line:638 roles:def end:642
tcp.ipv6.setsockopt.return input.stp /^probe tcp.ipv6.setsockopt.return = kernel.function("ipv6_setsockopt").return!,$/;" p line:643 roles:def end:648
tcp.receive input.stp /^probe tcp.receive = tcp.ipv4.receive, tcp.ipv6.receive$/;" p line:667 roles:def end:669
tcp.ipv4.receive input.stp /^probe tcp.ipv4.receive = kernel.function("tcp_v4_rcv")$/;" p line:671 roles:def end:694
tcp.ipv6.receive input.stp /^probe tcp.ipv6.receive = kernel.function("tcp_v6_rcv")!,$/;" p line:696 roles:def end:730
linux/version.h input.stp /^#include <linux\/version.h>/;" h line:22 roles:system
net/sock.h input.stp /^#include <net\/sock.h>/;" h line:23 roles:system
net/tcp.h input.stp /^#include <net\/tcp.h>/;" h line:24 roles:system
net/ip.h input.stp /^#include <net\/ip.h>/;" h line:25 roles:system
linux/skbuff.h input.stp /^#include <linux\/skbuff.h>/;" h line:26 roles:system
TCP_CONGESTION input.stp /^#define TCP_CONGESTION /;" d line:229 file: roles:def end:229
TCP_MD5SIG input.stp /^#define TCP_MD5SIG /;" d line:232 file: roles:def end:232
TCP_COOKIE_TRANSACTIONS input.stp /^#define TCP_COOKIE_TRANSACTIONS /;" d line:235 file: roles:def end:235
TCP_THIN_LINEAR_TIMEOUTS input.stp /^#define TCP_THIN_LINEAR_TIMEOUTS /;" d line:238 file: roles:def end:238
TCP_THIN_DUPACK input.stp /^#define TCP_THIN_DUPACK /;" d line:241 file: roles:def end:241
TCP_USER_TIMEOUT input.stp /^#define TCP_USER_TIMEOUT /;" d line:244 file: roles:def end:244
linux/in6.h input.stp /^#include <linux\/in6.h>/;" h line:289 roles:system
IPV6_2292PKTINFO input.stp /^#define IPV6_2292PKTINFO /;" d line:291 file: roles:def end:291
IPV6_2292HOPOPTS input.stp /^#define IPV6_2292HOPOPTS /;" d line:294 file: roles:def end:294
IPV6_2292DSTOPTS input.stp /^#define IPV6_2292DSTOPTS /;" d line:297 file: roles:def end:297
IPV6_2292RTHDR input.stp /^#define IPV6_2292RTHDR /;" d line:300 file: roles:def end:300
IPV6_2292PKTOPTIONS input.stp /^#define IPV6_2292PKTOPTIONS /;" d line:303 file: roles:def end:303
IPV6_2292HOPLIMIT input.stp /^#define IPV6_2292HOPLIMIT /;" d line:306 file: roles:def end:306
IPV6_RECVPKTINFO input.stp /^#define IPV6_RECVPKTINFO /;" d line:309 file: roles:def end:309
IPV6_RECVHOPLIMIT input.stp /^#define IPV6_RECVHOPLIMIT /;" d line:312 file: roles:def end:312
IPV6_RECVHOPOPTS input.stp /^#define IPV6_RECVHOPOPTS /;" d line:315 file: roles:def end:315
IPV6_RTHDRDSTOPTS input.stp /^#define IPV6_RTHDRDSTOPTS /;" d line:318 file: roles:def end:318
IPV6_RECVRTHDR input.stp /^#define IPV6_RECVRTHDR /;" d line:321 file: roles:def end:321
IPV6_RECVDSTOPTS input.stp /^#define IPV6_RECVDSTOPTS /;" d line:324 file: roles:def end:324
IPV6_RECVPATHMTU input.stp /^#define IPV6_RECVPATHMTU /;" d line:327 file: roles:def end:327
IPV6_PATHMTU input.stp /^#define IPV6_PATHMTU /;" d line:330 file: roles:def end:330
IPV6_DONTFRAG input.stp /^#define IPV6_DONTFRAG /;" d line:333 file: roles:def end:333
IPV6_ADDR_PREFERENCES input.stp /^#define IPV6_ADDR_PREFERENCES /;" d line:336 file: roles:def end:336
IPV6_MINHOPCOUNT input.stp /^#define IPV6_MINHOPCOUNT /;" d line:339 file: roles:def end:339
IPV6_RECVORIGDSTADDR input.stp /^#define IPV6_RECVORIGDSTADDR /;" d line:342 file: roles:def end:342
IPV6_TRANSPARENT input.stp /^#define IPV6_TRANSPARENT /;" d line:345 file: roles:def end:345
19 changes: 17 additions & 2 deletions docs/contributions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -429,21 +429,36 @@ Title of commit log and pull request

* Use following prefixes for the changes other than parsers.

main:
main
Changes for files under ``main/`` directory

Units:
Units
Changes for the test cases under ``Units/`` directory

Tmain
Changes for the test cases under ``Tmain/`` directory

units
Changes for the test harness (misc/units.py) itself

docs(web)
Changes for the ``docs/*.rst``

docs(man)
Changes for the ``man/*.rst``

dsl
Changes operators that can be used in optscript command

operators
Changes operators that can be used in optlib `{{` ... `}}` blocks

prelude
Changes optlib procedures defined in main/CommonPrelude.ps

CXX (or Cxx)
Changes affecting all parsers defined in parsers/cxx

See also the output of ``git log`` command.

* Combine prefixes with a comma if a change modifies multiple parts of our source tree
Expand Down
1 change: 1 addition & 0 deletions docs/man-pages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Man pages
ctags-lang-r(7) <man/ctags-lang-r.7.rst>
ctags-lang-rmarkdown(7) <man/ctags-lang-rmarkdown.7.rst>
ctags-lang-sql(7) <man/ctags-lang-sql.7.rst>
ctags-lang-systemtap(7) <man/ctags-lang-systemtap.7.rst>
ctags-lang-tcl(7) <man/ctags-lang-tcl.7.rst>
ctags-lang-verilog(7) <man/ctags-lang-verilog.7.rst>

Expand Down
53 changes: 53 additions & 0 deletions docs/man/ctags-lang-systemtap.7.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.. _ctags-lang-systemtap(7):

==============================================================
ctags-lang-systemtap
==============================================================

Random notes about tagging SystepTap source code with Universal Ctags

:Version: 6.0.0
:Manual group: Universal Ctags
:Manual section: 7

SYNOPSIS
--------
| **ctags** ... --languages=+SystemTap ...
| **ctags** ... --language-force=SystemTap ...
| **ctags** ... --map-SystemTap=+.stp ...
DESCRIPTION
-----------
This man page gathers random notes about tagging SystemTap scripts.

Guests
~~~~~~~~~~~
The SystemTap parser runs CPreProcessor as a guest parser on the areas
surrounded by `%{` and `%}`.

"input.stp"

.. code-block:: SystemTap
%{
#define X 1
%}
"output.tags"
with "--options=NONE -o - --sort=no --extras=+{guest} input.stp"

.. code-block:: tags
X input.stp /^#define X /;" d file:
VERSIONS
--------

Change since "0.0"
~~~~~~~~~~~~~~~~~~

* New role ``attached`` for ``probe`` kind

SEE ALSO
--------
:ref:`ctags(1) <ctags(1)>`, `SystemTap Language Reference <https://sourceware.org/systemtap/langref>`_ (https://sourceware.org/systemtap/langref/)
45 changes: 40 additions & 5 deletions dsl/optscript.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ static EsObject* OPT_KEY_dstack;
*/

static EsObject* array_new (unsigned int attr);
static EsObject* array_shared_new (EsObject* original, unsigned int attr);

static EsObject* array_es_init_fat (void *fat, void *ptr, void *extra);
static void array_es_free (void *ptr, void *fat);
Expand Down Expand Up @@ -375,8 +376,8 @@ declop(execstack);
declop(type);
declop(cvn);
declop(cvs);

/* cvlit, cvx, xcheck, executeonly, noacess, readonly,
declop(cvx);
/* cvlit, xcheck, executeonly, noacess, readonly,
rcheck, wcheck, cvi, cvr, cvrs, cvs,... */

/* Operators for Virtual Memory Operators */
Expand Down Expand Up @@ -570,6 +571,7 @@ opt_init (void)
defop (opt_system_dict, type, 1, "any TYPE name");
defop (opt_system_dict, cvn, 1, "string CVN name");
defop (opt_system_dict, cvs, 2, "any string CVS string");
defop (opt_system_dict, cvx, 1, "any CVX any");

defop (opt_system_dict, null, 0, "- NULL null");
defop (opt_system_dict, bind, 1, "proc BIND proc");
Expand Down Expand Up @@ -1973,6 +1975,14 @@ array_new (unsigned int attr)
return es_fatptr_new (OPT_TYPE_ARRAY, a, &attr);
}

static EsObject*
array_shared_new (EsObject* original, unsigned int attr)
{
ptrArray *a = es_pointer_get (original);
ptrArrayRef (a);
return es_fatptr_new (OPT_TYPE_ARRAY, a, &attr);
}

static EsObject*
array_es_init_fat (void *fat, void *ptr, void *extra)
{
Expand All @@ -1991,9 +2001,6 @@ array_es_free (void *ptr, void *fat)
static int
array_es_equal (const void *a, const void *afat, const void *b, const void *bfat)
{
if (((ArrayFat *)afat)->attr != ((ArrayFat *)bfat)->attr)
return 0;

if (ptrArrayIsEmpty ((ptrArray *)a) && ptrArrayIsEmpty ((ptrArray*)b))
return 1;
else if (a == b)
Expand Down Expand Up @@ -3931,6 +3938,34 @@ op_cvs (OptVM *vm, EsObject *name)
return es_false;
}

static EsObject*
op_cvx (OptVM *vm, EsObject *name)
{
EsObject *o = ptrArrayLast (vm->ostack);

if (es_object_get_type (o) == OPT_TYPE_ARRAY
&& (! (((ArrayFat *)es_fatptr_get (o))->attr & ATTR_EXECUTABLE)))
{
EsObject *xarray = array_shared_new (o,
((ArrayFat *)es_fatptr_get (o))->attr | ATTR_EXECUTABLE);
ptrArrayDeleteLast (vm->ostack);
vm_ostack_push (vm, xarray);
es_object_unref(xarray);

}
else if (es_object_get_type (o) == OPT_TYPE_NAME
&& (! (((NameFat *)es_fatptr_get (o))->attr & ATTR_EXECUTABLE)))
{
EsObject *symbol = es_pointer_get (o);
EsObject *xname = name_new (symbol, ((NameFat *)es_fatptr_get (o))->attr | ATTR_EXECUTABLE);
ptrArrayDeleteLast (vm->ostack);
vm_ostack_push (vm, xname);
es_object_unref(xname);
}

return es_false;
}


/*
* Misc operators
Expand Down
20 changes: 20 additions & 0 deletions main/CommonPrelude.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,24 @@ const char ctagsCommonPrelude []=
" } forall\n"
" dup true ne { pop pop false } if\n"
"} __bddef\n"
"\n"
"% define @1 ~ @9.\n"
"1 1 9 {\n"
" dup\n"
" mark (- @) 3 -1 roll ?0 add ( matchloc) _buildstring\n"
" exch dup\n"
" mark (@) 3 -1 roll ?0 add _buildstring cvn\n"
" exch\n"
" [ exch /start /_matchloc cvx ] cvx __bddef\n"
"} for\n"
"\n"
"% define 1@ ~ 9@.\n"
"1 1 9 {\n"
" dup\n"
" mark (- ) 3 -1 roll ?0 add (@ matchloc) _buildstring\n"
" exch dup\n"
" mark exch ?0 add (@) _buildstring cvn\n"
" exch\n"
" [ exch /end /_matchloc cvx ] cvx __bddef\n"
"} for\n"
;
Binary file modified main/CommonPrelude.ps
Binary file not shown.
Loading