Skip to content

Commit

Permalink
Merge pull request universal-ctags#3607 from masatake/systemtap--prob…
Browse files Browse the repository at this point in the history
…e-attached

Systemtap: add new role "attached" for "probe" kind , and run CPreProcessor as a guest parser
  • Loading branch information
masatake authored and leleliu008 committed Dec 25, 2022
2 parents fe02d29 + d56036c commit 4c97cd6
Show file tree
Hide file tree
Showing 35 changed files with 479 additions and 90 deletions.
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

0 comments on commit 4c97cd6

Please sign in to comment.