How to "%q" format a lua_Buffer in the C-API - c

string.format("%q", foo_str) will format a string to add the appropriate escape chars to make it safe to read back into the Lua interpreter. How can I best use this function to format a Lua_Buffer from the C-API? More generally, how can I access the string.* functions from the C-API? I could use lua_pcall("string.format", ...), but curious if there is a more direct way.

The format function is defined as static in the lstrlib.c module, so AFAIK the only way to get to it is through the string table.
I suppose you could look at addquoted in lstrlib.c and adjust it for your use, but probably easier to just call string.format.

Related

Call function only knowing parameter types at runtime in C?

Let's say I have a function:
int foo (int A, char B){...}
One of the features I want to implement is the capability for the user to call any function on the application through the Linux terminal. So as an input for the software, in the terminal they type something like:
foo 2 'a'
Then my application parses that, and using the symbol tables it is able to find the address for foo(), as well as the type for all its parameters.
However, I'm not sure how I would pass the parameters to the function when calling it, since I can have hundreds of different parameters types combination depending on the function called.
Any hint how that could be achieved without having hundreds of nested if statements to cast the parameters to the correct types before calling the functions?
That functionality is similar to what GDB has, where you can do call foo(2,'a') and GDB calls that function to you.
There are two approaches to this. If what you described is all you want to do, then you can use the dyncall library so that you dont have to worry about platform/compiler-specific calling semantics yourself:
The dyncall library encapsulates architecture-, OS- and compiler-specific function call semantics in a virtual bind argument parameters from left to right and then call interface allowing programmers to call C functions in a completely dynamic manner. In other words, instead of calling a function directly, the dyncall library provides a mechanism to push the function parameters manually and to issue the call afterwards.
The other approach is, if you might want to do more: e.g. what if an argument cannot be created by a literal? What if the argument is the output of another function? Can you write f(123, g("a")) in your console? Can you write x=g("a"); f(x)? And if(cond) x="a" else x="b"; f(x) In this case you need to embed a scripting language like e.g. LUA.
If you compile your binary with debug information, you can extract it using libdwarf (https://www.prevanders.net/dwarf.html), so for every function you can get a list a parameters with types and you would know how to interpret user's input.

Is there a built-in way to parse standard escape sequences in a user-supplied string in C?

In C, if I put a literal string like "Hello World \n\t\x90\x53" into my code, the compiler will parse the escape sequences into the correct bytes and leave the rest of characters alone.
If the above string is instead supplied by the user, either on the command line or in a file, is there a way to invoke the compiler's functionality to get the same literal bytes into a char[]?
Obviously I could manually implement the functionality by hardcoding the escape sequences, but I would prefer not to do that if I can just invoke some compiler library instead.
No, there's no standard function to do that.
A suggestion for a non-standard library solution is to use glib's g_strcompress() function.

Find formatted string

I'm interested in something like strstr() function but that I could pass a formatted string as argument, like what I pass to printf(). To be clear, let's get an example:
Suppose that I want to find this text: "abc:123" where abc could be any string with any size followed by ':' and then followed by some integer number. I suppose a good function could receive as argument something like this: "%s:%d".
Something else, I want to use this embedded, so I can't get big and/or esoteric libraries.
Thanks and best regards!
You can use sscanf. It takes a string and a format as input and you fill variables as a result. Regular expressions are also something to consider
Use should use regular expressions.
This thread may help you: Compiling/Matching POSIX Regular Expressions in C
Gentleman,
I found this CRX and it is exactly what I wanted. Thanks everybody!
Alternatively, you can directly use printf function. The function outputs strings on default uart (mine is uart0).
But prior to using printf, proper set-up and configuration is required.

How to call a varargs function via dbus?

How to call a varargs function via dbus, like printf?
The server is written in C, the client is written in Python.
My questions are how to write the XML spec file? And how to write my GObject?
Thanks in advance.
[I use DBus-GLib.]
There is no way to call a variadic function programmatically with varying number and type of arguments. You could use the corresponding "v" functions (vprintf etc.) but there's no way to make the va_list to pass to them from foreign code and pass it over DBus.
In any case you really need to rethink your design. It's unsafe to call printf with a format string that's not 100% controlled by your program. Passing a client-provided format string is a formula for disaster, because printf invokes undefined behavior if the format string does not match the arguments. In nearly all real-world situations, this will mean privilege elevation vulns!

Mapping variable argument LISP function to C function - C

I am developing a custom LISP interpreter. It won't support defining functions like in LISP, instead all functions are mapped to C functions. When it sees an expression like,
(substr 'input '1 '1)
it knows to call internal substr function and return the result.
Now I am planning to implement a message function which supports basic formatting and writes the output to stdout. Something like,
(message "Hello, %s" name)
%s will be replaced with value in variable name.
Current plan is to directly pass the format and arguments to functions like printf. In that way, I can support all formats that printf supports. But problem comes with variable number of arguments. One way to do will be something like,
if(argcount == 1)
/* call printf with one arg */
else if(argcount == 2)
/* call printf with two arg */
....
This works, but I am wondering is there a better way to achieve this?
I doubt there is a way to do this. The reason is that the number of parameters to your lisp function is only known at runtime, but the number of arguments to a C function must be known at compile time.
This includes va_lists unless you want to hack at them in some kind of platform specific way.
The best you can really do is write a function in C which is capable of looping through the arguments one at a time and doing something with them. The only way I can see around this is to not only store a function pointer for each of your internal functions, but to also store a "calling convention" which will give information about whether it takes parameters in the ordinary way or whether it finishes with the equivalent of a va_list.
Functions like printf would have a wrapper, printf_wrapper, say, and you'd store a function pointer to the wrapper. This wrapper would accept the format string as an ordinary parameter, followed by a list or array of other parameters (roughly analogous to a va_list).
You might indicate that printf_wrapper finishes with a parameter that expects a list by specifying the calling conventions for the printf_wrapper function as "va_list_type", meaning that it takes the usual fixed parameters, and that all remaining parameters must be bundled up and supplied to it as a list.
Of course writing a printf_wrapper function which can split up and parse a format string into multiple format strings is a bit of work. Here's an example of where I did precisely this so that I could add my own custom format specifiers:
https://github.com/wbhart/bsdnt/blob/v0.26/helper.c
Have your C function take parameters somewhat like argc/argv. That is, take a parameter specifying the number of parameters, and then a pointer to a list of pointers for each parameter.
Slightly better than an if-else chain would be a switch.
switch(argcount){
case 1: printf(arg[0]); break;
case 2: printf(arg[0],arg[1]); break;
//etc.
}

Resources