Help needed to replace some printfs in the lpeg source with something else

81 views
Skip to first unread message

Eduardo Ochs

unread,
Jan 9, 2024, 4:42:44 PMJan 9
to Lua list
Hi list,

I am the author of this thing, that adds a Lua interpreter to Emacs,

https://github.com/edrx/emlua/#introduction

but I was only able to write it because someone - nerditation - helped
me with the part in C...

https://github.com/edrx/emlua/blob/main/emlua.cpp

Now I'm going to ask for help on another thing in C - this time to
make the debugging functions of lpeg slightly more useful.


1. Introduction and demo
========================
This is what I use to compile lpeg with "-DLPEG_DEBUG" on Debian, and
to test the methods :pcode() and :ptree(), that are only available
when LPEG_DEBUG is defined:

export S=$HOME/snarf
mkdir -p $S/http/www.inf.puc-rio.br/~roberto/lpeg/
cd $S/http/www.inf.puc-rio.br/~roberto/lpeg/
wget -nc 'http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.1.0.tar.gz'

rm -Rv ~/usrc/lpeg-1.1.0/
mkdir ~/usrc/lpeg-1.1.0/
tar -C ~/usrc/ -xvzf
$S/http/www.inf.puc-rio.br/~roberto/lpeg/lpeg-1.1.0.tar.gz
cd ~/usrc/lpeg-1.1.0/
ls *.c *.h | tee .files.ch
etags $(cat .files.ch)

rm -fv *.o
rm -fv *.so
rm -fv om
make LUADIR=/usr/include/lua5.1 COPT="-O2 -DLPEG_DEBUG"

lua5.1
HOME = os.getenv("HOME")
package.cpath = HOME.."/usrc/lpeg-1.1.0/?.so;" .. package.cpath
require "lpeg"
AlphaNumeric = lpeg.R("AZ", "az", "09")
AnchorChar = AlphaNumeric + lpeg.S("!#$%()*+,-./:;=?@^_{|}~")
AnchorChar:pcode()
AnchorChar:ptree()
os.exit()

When I run all that in a shell, the log of the last part is:

Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> HOME = os.getenv("HOME")
> package.cpath = HOME.."/usrc/lpeg-1.1.0/?.so;" .. package.cpath
> require "lpeg"
> AlphaNumeric = lpeg.R("AZ", "az", "09")
> AnchorChar = AlphaNumeric + lpeg.S("!#$%()*+,-./:;=?@^_{|}~")
> AnchorChar:pcode()
[]
00: set (20-3) [(21)(23-25)(28-3b)(3d)(3f-5a)(5e-5f)(61-7e)]
04: end
> AnchorChar:ptree()
[]
set(04-12) [(21)(23-25)(28-3b)(3d)(3f-5a)(5e-5f)(61-7e)]
> os.exit()

but pcode and ptree don't return strings - they _print_ strings...



2. Help needed
==============
The file ptree.c in the lpeg source contains these lines:

static struct luaL_Reg pattreg[] = {
{"ptree", lp_printtree},
{"pcode", lp_printcode},
{"match", lp_match},
{"B", lp_behind},
...
}

and lpprint.h contains this:

#if defined(LPEG_DEBUG)

void printpatt (Instruction *p, int n);
void printtree (TTree *tree, int ident);
void printktable (lua_State *L, int idx);
void printcharset (const byte *st);
void printcaplist (Capture *cap, Capture *limit);
void printinst (const Instruction *op, const Instruction *p);

#else

#define printktable(L,idx) \
luaL_error(L, "function only implemented in debug mode")
#define printtree(tree,i) \
luaL_error(L, "function only implemented in debug mode")
#define printpatt(p,n) \
luaL_error(L, "function only implemented in debug mode")

#endif

The debugging functions - in lpprint.c - are implemented using
"printf"s. Suppose that we replace all of the 32 occurrence of
"printf" in lpprint.c by "mylpegprintf_C", and mylpegprintf_C is a
function or macro that would do this (in pseudocode in Lua):

mylpegprintf_C = function (fmt, ...)
if _G.mylpegprintf
then local str = sprintf(fmt, ...) -- calls sprintf in C
_G.mylpegprintf(str) -- calls Lua
else printf(fmt, ...) -- calls printf in C
end
end

then it would be trivial to write variants of :pcode and :ptree that
would return strings instead of just printing things...

Anyone would like to help me with that? I can't offer fame or fortune
- just credit and many, many thanks...

Thanks in advance (hopefully),
Eduardo Ochs
http://anggtwu.net/eepitch.html
http://anggtwu.net/emacsconf2023.html

Roberto Ierusalimschy

unread,
Jan 10, 2024, 1:10:40 PMJan 10
to lu...@googlegroups.com
> The debugging functions - in lpprint.c - are implemented using
> "printf"s. Suppose that we replace all of the 32 occurrence of
> "printf" in lpprint.c by "mylpegprintf_C", and mylpegprintf_C is a
> function or macro that would do this (in pseudocode in Lua):
>
> mylpegprintf_C = function (fmt, ...)
> if _G.mylpegprintf
> then local str = sprintf(fmt, ...) -- calls sprintf in C
> _G.mylpegprintf(str) -- calls Lua
> else printf(fmt, ...) -- calls printf in C
> end
> end
>
> then it would be trivial to write variants of :pcode and :ptree that
> would return strings instead of just printing things...

If I would do that kind of thing (I probably will, but not now), I would
use a 'string buffer' from the auxiliary library to built the resulting
string, all in C.

I would change all calls to printf to something like this:

printf(fmt, ...) --> myprintf(b, fmt, ...)

The function 'myprintf' would be something like this:

static void myprintf (luaL_Buffer *B, const char *fmt, ...) {
va_list argp;
char *buff[250];
int len;
va_start(argp, fmt);
len = vsprintf(buff, fmt, argp);
va_end(argp);
luaL_addlstring(B, buff, len);
}

The main functions would be responsible for creating the buffers and
finishing them to create the final string result.

-- Roberto
Reply all
Reply to author
Forward
0 new messages