Calling newLISP from C

Started by itistoday, February 28, 2008, 08:46:22 PM

Previous topic - Next topic

itistoday

Note: If you're wondering why there's a space in between semi-colons and parenthesis it's because this forum cannot handle them.  It took me a while to figure this out.  Try posting this: 'exec(asdf)' (no quotes) followed immediately by a semi-colon.  Just try it.



Update: Woah.. and apparently it doesn't like the ".h" on the end of a header file either... Very very weird forum.




I wrote some convenience functions for dealing with newLISP in C.  I use the term "dealing with" as opposed to "using" because currently it doesn't seem like newLISP is really designed to be called from C/C++ applications.  It would be nice for example if C apps could have direct access to raw data types inside of the newLISP world instead of having to parse strings.



Here are some examples of using some of these functions:



nl_exec(const char *cmd, ...)
nl_exec("(append {/tmp/} (lower-case (slice (join (find-all {[a-zA-Z]+} {%s}) {-}) 0 10)) {.socket})", name) ;

int nl_copyresult(char *buff, int len, int options) ;
char buff[100];
nl_copyresult(buff, 100, NL_NO_QUOTE) ;


There we passed NL_NO_QUOTE because since, again, the only interface you have to newLISP is what's output on the read-eval loop, strings will have quotes around them, and you probably don't want those.



char *nl_result(void) ;
char *my_copy = strcpy(nl_result()) ;

Note: nl_result returns a pointer to newLISP's result buffer (with the n removed), so you probably want to copy it.



Here's the code:



Header file:


#define NL_NO_QUOTE (1<<0)

int nl_load(void) ;
bool nl_loaded(void) ;
int nl_exec(const char *cmd, ...) ;
int nl_error(void) ; // result of running nl_exec
char * nl_result(void) ;
int nl_copyresult(char *buff, int len, int options) ;


Implementation:


#include <stdarg>

static bool newlisp_loaded = false;
static char * (*newlispEvalStr)(char *) ;
static char * nl_buff = NULL; // pointer to newlisp's result buffer
static int nl_err = 0;

int load_newlisp()
{
// load newLISP.(dylib|so|dll) ...

newlisp_loaded = true;
nl_exec("(signal 2 true)") ; // default action for SIGINT, makes ^C work properly
return 0;
}

bool nl_loaded()
{
return newlisp_loaded;
}

#define CMD_BUFF_LEN 2048
int nl_exec(const char *cmd_fmt, ...)
{
va_list data;
static char cmd_buff[CMD_BUFF_LEN];

if ( ! newlisp_loaded ) {
log_err("nl_exec: newlisp not loaded") ;
return -1;
}

va_start(data, cmd_fmt) ;
vsnprintf(cmd_buff, CMD_BUFF_LEN-1, cmd_fmt, data) ;
va_end(data) ;

nl_buff = newlispEvalStr(cmd_buff) ;

if (strncmp(nl_buff, "nmissing", 8) != 0)
nl_err = 0;
else
nl_err = -1; // error occurred, most likely command too long

return nl_err;
}

char * nl_result()
{
if ( ! newlisp_loaded ) {
log_err("nl_result: newlisp not loaded") ;
return NULL;
}
else if (nl_buff == NULL) {
log_err("nl_result: nl_exec not called") ;
return NULL;
}

char *ptr = nl_buff;
while (*ptr != '') ++ptr;
*(--ptr) = ''; // get rid of n

return nl_buff;
}

int nl_copyresult(char *buff, int len, int options)
{
if ( ! newlisp_loaded ) {
log_err("nl_copyresult: newlisp not loaded") ;
return -1;
}
else if ( nl_buff == NULL ) {
log_err("nl_copyresult: nl_exec not called") ;
return -1;
}

char *ptr = nl_buff;
int copied = 0;

if ( (NL_NO_QUOTE & options) > 0 && *ptr == '"' )
++ptr;

while ( *ptr != '' && --len >= 0 ) {
*buff = *ptr;
++ptr; ++buff; ++copied;
}

if ( len > 0 )
{
if ( *(ptr-1) == 'n' ) {
*(--buff) = '';
--copied;
}
else *buff = '';

if ( (NL_NO_QUOTE & options) > 0 && *(buff-1) == '"' ) {
*(buff-1) = '';
--copied;
}
}

return copied;
}

int nl_error(void)
{
return nl_err;
}
Get your Objective newLISP groove on.

Ryon

#1
The "semicolon-space" issue reported above is a quirk in the PHP software used by the newLISP Fan Club, and possibly also in the syntax of the C language whichAllows.multiple(elements);ToBeEntered_without(delimiting,spaces).



It is NOT a fault in newLISP itself.
\"Give me a Kaypro 64 and a dial tone, and I can do anything!\"

itistoday

#2
Quote from: "Ryon"It is NOT a fault in newLISP itself.


I don't think I said it was newLISP's fault did I?
Get your Objective newLISP groove on.

cormullion

#3
you're both right :)