summaryrefslogtreecommitdiff
path: root/clients/lib/old
diff options
context:
space:
mode:
Diffstat (limited to 'clients/lib/old')
-rw-r--r--clients/lib/old/Makefile35
-rw-r--r--clients/lib/old/iolib.c618
-rw-r--r--clients/lib/old/lualib.h33
-rw-r--r--clients/lib/old/mathlib.c230
-rw-r--r--clients/lib/old/strlib.c276
5 files changed, 1192 insertions, 0 deletions
diff --git a/clients/lib/old/Makefile b/clients/lib/old/Makefile
new file mode 100644
index 00000000..b9668617
--- /dev/null
+++ b/clients/lib/old/Makefile
@@ -0,0 +1,35 @@
+# makefile for lualib
+
+LUA= ../../..
+
+include $(LUA)/config
+
+EXTRA_DEFS= $(POPEN) $(NOSTRERROR)
+
+OBJS= iolib.o mathlib.o strlib.o
+SRCS= iolib.c mathlib.c strlib.c
+
+SLIB= $(LIB)/liboldlualib.a
+
+# dynamic libraries only work for SunOs
+DLIB= $(LIB)/liboldlualib.so.$(VERSION)
+
+all: $(SLIB)
+
+dynamic: $(DLIB)
+
+$(SLIB): $(OBJS)
+ ar rcu $@ $(OBJS)
+ $(RANLIB) $(SLIB)
+
+$(DLIB): $(OBJS)
+ ld -o $@ $(OBJS)
+
+clean:
+ rm -f $(OBJS) $(SLIB) $(DLIB)
+
+co:
+ co -f -M -rv2_4 $(SRCS)
+
+klean: clean
+ rm -f $(SRCS)
diff --git a/clients/lib/old/iolib.c b/clients/lib/old/iolib.c
new file mode 100644
index 00000000..9ed7e479
--- /dev/null
+++ b/clients/lib/old/iolib.c
@@ -0,0 +1,618 @@
+/*
+** iolib.c
+** Input/output library to LUA
+*/
+
+char *rcs_iolib="$Id: iolib.c,v 1.44 1996/05/03 20:10:59 roberto Exp $";
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "lua.h"
+#include "luadebug.h"
+#include "lualib.h"
+
+static FILE *in=stdin, *out=stdout;
+
+
+#ifdef POPEN
+FILE *popen();
+int pclose();
+#else
+#define popen(x,y) NULL /* that is, popen always fails */
+#define pclose(x) (-1)
+#endif
+
+
+static void pushresult (int i)
+{
+ if (i)
+ lua_pushnumber (1);
+ else
+ lua_pushnil();
+}
+
+static void closeread (void)
+{
+ if (in != stdin)
+ {
+ if (pclose(in) == -1)
+ fclose(in);
+ in = stdin;
+ }
+}
+
+static void closewrite (void)
+{
+ if (out != stdout)
+ {
+ if (pclose(out) == -1)
+ fclose(out);
+ out = stdout;
+ }
+}
+
+/*
+** Open a file to read.
+** LUA interface:
+** status = readfrom (filename)
+** where:
+** status = 1 -> success
+** status = nil -> error
+*/
+static void io_readfrom (void)
+{
+ if (lua_getparam (1) == LUA_NOOBJECT)
+ { /* restore standart input */
+ closeread();
+ lua_pushnumber (1);
+ }
+ else
+ {
+ char *s = lua_check_string(1, "readfrom");
+ FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
+ if (fp == NULL)
+ lua_pushnil();
+ else
+ {
+ closeread();
+ in = fp;
+ lua_pushnumber (1);
+ }
+ }
+}
+
+
+/*
+** Open a file to write.
+** LUA interface:
+** status = writeto (filename)
+** where:
+** status = 1 -> success
+** status = nil -> error
+*/
+static void io_writeto (void)
+{
+ if (lua_getparam (1) == LUA_NOOBJECT) /* restore standart output */
+ {
+ closewrite();
+ lua_pushnumber (1);
+ }
+ else
+ {
+ char *s = lua_check_string(1, "writeto");
+ FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
+ if (fp == NULL)
+ lua_pushnil();
+ else
+ {
+ closewrite();
+ out = fp;
+ lua_pushnumber (1);
+ }
+ }
+}
+
+
+/*
+** Open a file to write appended.
+** LUA interface:
+** status = appendto (filename)
+** where:
+** status = 1 -> success
+** status = nil -> error
+*/
+static void io_appendto (void)
+{
+ char *s = lua_check_string(1, "appendto");
+ FILE *fp = fopen (s, "a");
+ if (fp == NULL)
+ lua_pushnil();
+ else
+ {
+ if (out != stdout) fclose (out);
+ out = fp;
+ lua_pushnumber(1);
+ }
+}
+
+
+static char getformat (char *f, int *just, int *m, int *n)
+{
+ int t;
+ switch (*f++)
+ {
+ case 'q': case 'Q':
+ case 's': case 'S':
+ case 'i': case 'I':
+ t = tolower(*(f-1));
+ break;
+ case 'f': case 'F': case 'g': case 'G': case 'e': case 'E':
+ t = 'f';
+ break;
+ default:
+ t = 0; /* to avoid compiler warnings */
+ lua_arg_error("read/write (format)");
+ }
+ *just = (*f == '<' || *f == '>' || *f == '|') ? *f++ : '>';
+ if (isdigit(*f))
+ {
+ *m = 0;
+ while (isdigit(*f))
+ *m = *m*10 + (*f++ - '0');
+ }
+ else
+ *m = -1;
+ if (*f == '.')
+ {
+ f++; /* skip point */
+ *n = 0;
+ while (isdigit(*f))
+ *n = *n*10 + (*f++ - '0');
+ }
+ else
+ *n = -1;
+ return t;
+}
+
+
+/*
+** Read a variable. On error put nil on stack.
+** LUA interface:
+** variable = read ([format])
+**
+** O formato pode ter um dos seguintes especificadores:
+**
+** s ou S -> para string
+** f ou F, g ou G, e ou E -> para reais
+** i ou I -> para inteiros
+**
+** Estes especificadores podem vir seguidos de numero que representa
+** o numero de campos a serem lidos.
+*/
+
+static int read_until_char (int del)
+{
+ int c;
+ while((c = fgetc(in)) != EOF && c != del)
+ luaI_addchar(c);
+ return c;
+}
+
+static void read_until_blank (void)
+{
+ int c;
+ while((c = fgetc(in)) != EOF && !isspace(c))
+ luaI_addchar(c);
+ if (c != EOF) ungetc(c,in);
+}
+
+static void read_m (int m)
+{
+ int c;
+ while (m-- && (c = fgetc(in)) != EOF)
+ luaI_addchar(c);
+}
+
+
+static void read_free (void)
+{
+ int c;
+ while (isspace(c=fgetc(in)))
+ ;
+ if (c == EOF)
+ {
+ lua_pushnil();
+ return;
+ }
+ if (c == '\"' || c == '\'')
+ { /* string */
+ c = read_until_char(c);
+ if (c == EOF)
+ lua_pushnil();
+ else
+ lua_pushstring(luaI_addchar(0));
+ }
+ else
+ {
+ double d;
+ char dummy;
+ char *s;
+ luaI_addchar(c);
+ read_until_blank();
+ s = luaI_addchar(0);
+ if (sscanf(s, "%lf %c", &d, &dummy) == 1)
+ lua_pushnumber(d);
+ else
+ lua_pushstring(s);
+ }
+}
+
+static void io_read (void)
+{
+ lua_Object o = lua_getparam (1);
+ luaI_addchar(0); /* initialize buffer */
+ if (o == LUA_NOOBJECT) /* free format */
+ read_free();
+ else /* formatted */
+ {
+ int m, dummy1, dummy2;
+ switch (getformat(lua_check_string(1, "read"), &dummy1, &m, &dummy2))
+ {
+ case 's':
+ {
+ char *s;
+ if (m < 0)
+ read_until_blank();
+ else
+ read_m(m);
+ s = luaI_addchar(0);
+ if ((m >= 0 && strlen(s) == m) || (m < 0 && strlen(s) > 0))
+ lua_pushstring(s);
+ else
+ lua_pushnil();
+ break;
+ }
+
+ case 'i': /* can read as float, since it makes no difference to Lua */
+ case 'f':
+ {
+ double d;
+ int result;
+ if (m < 0)
+ result = fscanf(in, "%lf", &d);
+ else
+ {
+ read_m(m);
+ result = sscanf(luaI_addchar(0), "%lf", &d);
+ }
+ if (result == 1)
+ lua_pushnumber(d);
+ else
+ lua_pushnil();
+ break;
+ }
+ default:
+ lua_arg_error("read (format)");
+ }
+ }
+}
+
+
+/*
+** Read characters until a given one. The delimiter is not read.
+*/
+static void io_readuntil (void)
+{
+ int del, c;
+ lua_Object p = lua_getparam(1);
+ luaI_addchar(0); /* initialize buffer */
+ if (p == LUA_NOOBJECT || lua_isnil(p))
+ del = EOF;
+ else
+ del = *lua_check_string(1, "readuntil");
+ c = read_until_char(del);
+ if (c != EOF) ungetc(c,in);
+ lua_pushstring(luaI_addchar(0));
+}
+
+
+/*
+** Write a variable. On error put 0 on stack, otherwise put 1.
+** LUA interface:
+** status = write (variable [,format])
+**
+** O formato pode ter um dos seguintes especificadores:
+**
+** s ou S -> para string
+** f ou F, g ou G, e ou E -> para reais
+** i ou I -> para inteiros
+**
+** Estes especificadores podem vir seguidos de:
+**
+** [?][m][.n]
+**
+** onde:
+** ? -> indica justificacao
+** < = esquerda
+** | = centro
+** > = direita (default)
+** m -> numero maximo de campos (se exceder estoura)
+** n -> indica precisao para
+** reais -> numero de casas decimais
+** inteiros -> numero minimo de digitos
+** string -> nao se aplica
+*/
+
+static int write_fill (int n, int c)
+{
+ while (n--)
+ if (fputc(c, out) == EOF)
+ return 0;
+ return 1;
+}
+
+static int write_string (char *s, int just, int m)
+{
+ int status;
+ int l = strlen(s);
+ int pre; /* number of blanks before string */
+ if (m < 0) m = l;
+ else if (l > m)
+ {
+ write_fill(m, '*');
+ return 0;
+ }
+ pre = (just == '<') ? 0 : (just == '>') ? m-l : (m-l)/2;
+ status = write_fill(pre, ' ');
+ status = status && fprintf(out, "%s", s) >= 0;
+ status = status && write_fill(m-(l+pre), ' ');
+ return status;
+}
+
+static int write_quoted (int just, int m)
+{
+ luaI_addchar(0);
+ luaI_addquoted(lua_check_string(1, "write"));
+ return write_string(luaI_addchar(0), just, m);
+}
+
+static int write_float (int just, int m, int n)
+{
+ char buffer[100];
+ lua_Object p = lua_getparam(1);
+ float number;
+ if (!lua_isnumber(p)) return 0;
+ number = lua_getnumber(p);
+ if (n >= 0)
+ sprintf(buffer, "%.*f", n, number);
+ else
+ sprintf(buffer, "%g", number);
+ return write_string(buffer, just, m);
+}
+
+
+static int write_int (int just, int m, int n)
+{
+ char buffer[100];
+ lua_Object p = lua_getparam(1);
+ int number;
+ if (!lua_isnumber(p)) return 0;
+ number = (int)lua_getnumber(p);
+ if (n >= 0)
+ sprintf(buffer, "%.*d", n, number);
+ else
+ sprintf(buffer, "%d", number);
+ return write_string(buffer, just, m);
+}
+
+
+static void io_write (void)
+{
+ int status = 0;
+ if (lua_getparam (2) == LUA_NOOBJECT) /* free format */
+ {
+ lua_Object o1 = lua_getparam(1);
+ int t = lua_type(o1);
+ if (t == LUA_T_NUMBER)
+ status = fprintf (out, "%g", lua_getnumber(o1)) >= 0;
+ else if (t == LUA_T_STRING)
+ status = fprintf (out, "%s", lua_getstring(o1)) >= 0;
+ }
+ else /* formated */
+ {
+ int just, m, n;
+ switch (getformat(lua_check_string(2, "write"), &just, &m, &n))
+ {
+ case 's':
+ {
+ lua_Object p = lua_getparam(1);
+ if (lua_isstring(p))
+ status = write_string(lua_getstring(p), just, m);
+ else
+ status = 0;
+ break;
+ }
+ case 'q':
+ status = write_quoted(just, m);
+ break;
+ case 'f':
+ status = write_float(just, m, n);
+ break;
+ case 'i':
+ status = write_int(just, m, n);
+ break;
+ }
+ }
+ if (status)
+ lua_pushnumber(status);
+ else
+ lua_pushnil();
+}
+
+/*
+** Execute a executable program using "system".
+** Return the result of execution.
+*/
+static void io_execute (void)
+{
+ lua_pushnumber(system(lua_check_string(1, "execute")));
+}
+
+/*
+** Remove a file. On error return nil.
+*/
+static void io_remove (void)
+{
+ pushresult(remove(lua_check_string(1, "remove")) == 0);
+}
+
+static void io_rename (void)
+{
+ char *f1 = lua_check_string(1, "rename");
+ char *f2 = lua_check_string(2, "rename");
+ pushresult(rename(f1, f2) == 0);
+}
+
+static void io_tmpname (void)
+{
+ lua_pushstring(tmpnam(NULL));
+}
+
+static void io_errorno (void)
+{
+/* lua_pushstring(strerror(errno));*/
+}
+
+
+/*
+** To get a environment variable
+*/
+static void io_getenv (void)
+{
+ char *env = getenv(lua_check_string(1, "getenv"));
+ lua_pushstring(env); /* if NULL push nil */
+}
+
+/*
+** Return user formatted time stamp
+*/
+static void io_date (void)
+{
+ time_t t;
+ struct tm *tm;
+ char *s;
+ char b[BUFSIZ];
+ if (lua_getparam(1) == LUA_NOOBJECT)
+ s = "%c";
+ else
+ s = lua_check_string(1, "date");
+ time(&t); tm = localtime(&t);
+ if (strftime(b,sizeof(b),s,tm))
+ lua_pushstring(b);
+ else
+ lua_error("invalid `date' format");
+}
+
+/*
+** To exit
+*/
+static void io_exit (void)
+{
+ lua_Object o = lua_getparam(1);
+ int code = lua_isnumber(o) ? (int)lua_getnumber(o) : 1;
+ exit(code);
+}
+
+/*
+** To debug a lua program. Start a dialog with the user, interpreting
+ lua commands until an 'cont'.
+*/
+static void io_debug (void)
+{
+ while (1)
+ {
+ char buffer[250];
+ fprintf(stderr, "lua_debug> ");
+ if (fgets(buffer, sizeof(buffer), stdin) == 0) return;
+ if (strcmp(buffer, "cont") == 0) return;
+ lua_dostring(buffer);
+ }
+}
+
+
+static void lua_printstack (FILE *f)
+{
+ int level = 0;
+ lua_Object func;
+ fprintf(f, "Active Stack:\n");
+ while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT)
+ {
+ char *name;
+ int currentline;
+ fprintf(f, "\t");
+ switch (*lua_getobjname(func, &name))
+ {
+ case 'g':
+ fprintf(f, "function %s", name);
+ break;
+ case 'f':
+ fprintf(f, "`%s' fallback", name);
+ break;
+ default:
+ {
+ char *filename;
+ int linedefined;
+ lua_funcinfo(func, &filename, &linedefined);
+ if (linedefined == 0)
+ fprintf(f, "main of %s", filename);
+ else if (linedefined < 0)
+ fprintf(f, "%s", filename);
+ else
+ fprintf(f, "function (%s:%d)", filename, linedefined);
+ }
+ }
+ if ((currentline = lua_currentline(func)) > 0)
+ fprintf(f, " at line %d", currentline);
+ fprintf(f, "\n");
+ }
+}
+
+
+static void errorfb (void)
+{
+ lua_Object o = lua_getparam(1);
+ char *s = lua_isstring(o) ? lua_getstring(o) : "(no messsage)";
+ fprintf(stderr, "lua: %s\n", s);
+ lua_printstack(stderr);
+}
+
+
+static struct lua_reg iolib[] = {
+{"readfrom", io_readfrom},
+{"writeto", io_writeto},
+{"appendto", io_appendto},
+{"read", io_read},
+{"readuntil",io_readuntil},
+{"write", io_write},
+{"execute", io_execute},
+{"remove", io_remove},
+{"rename", io_rename},
+{"tmpname", io_tmpname},
+{"ioerror", io_errorno},
+{"getenv", io_getenv},
+{"date", io_date},
+{"exit", io_exit},
+{"debug", io_debug},
+{"print_stack", errorfb}
+};
+
+void iolib_open (void)
+{
+ luaI_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
+ lua_setfallback("error", errorfb);
+}
diff --git a/clients/lib/old/lualib.h b/clients/lib/old/lualib.h
new file mode 100644
index 00000000..6005d7c2
--- /dev/null
+++ b/clients/lib/old/lualib.h
@@ -0,0 +1,33 @@
+/*
+** Libraries to be used in LUA programs
+** Grupo de Tecnologia em Computacao Grafica
+** TeCGraf - PUC-Rio
+** $Id: lualib.h,v 1.8 1996/04/30 21:13:55 roberto Exp $
+*/
+
+#ifndef lualib_h
+#define lualib_h
+
+#include "lua.h"
+
+void iolib_open (void);
+void strlib_open (void);
+void mathlib_open (void);
+
+
+/* auxiliar functions (private) */
+
+struct lua_reg {
+ char *name;
+ lua_CFunction func;
+};
+
+void luaI_openlib (struct lua_reg *l, int n);
+void lua_arg_error(char *funcname);
+char *lua_check_string (int numArg, char *funcname);
+double lua_check_number (int numArg, char *funcname);
+char *luaI_addchar (int c);
+void luaI_addquoted (char *s);
+
+#endif
+
diff --git a/clients/lib/old/mathlib.c b/clients/lib/old/mathlib.c
new file mode 100644
index 00000000..07081e48
--- /dev/null
+++ b/clients/lib/old/mathlib.c
@@ -0,0 +1,230 @@
+/*
+** mathlib.c
+** Mathematics library to LUA
+*/
+
+char *rcs_mathlib="$Id: mathlib.c,v 1.17 1996/04/30 21:13:55 roberto Exp $";
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "lualib.h"
+#include "lua.h"
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+#define TODEGREE(a) ((a)*180.0/PI)
+#define TORAD(a) ((a)*PI/180.0)
+
+static void math_abs (void)
+{
+ double d = lua_check_number(1, "abs");
+ if (d < 0) d = -d;
+ lua_pushnumber (d);
+}
+
+
+static void math_sin (void)
+{
+ double d = lua_check_number(1, "sin");
+ lua_pushnumber (sin(TORAD(d)));
+}
+
+
+
+static void math_cos (void)
+{
+ double d = lua_check_number(1, "cos");
+ lua_pushnumber (cos(TORAD(d)));
+}
+
+
+
+static void math_tan (void)
+{
+ double d = lua_check_number(1, "tan");
+ lua_pushnumber (tan(TORAD(d)));
+}
+
+
+static void math_asin (void)
+{
+ double d = lua_check_number(1, "asin");
+ lua_pushnumber (TODEGREE(asin(d)));
+}
+
+
+static void math_acos (void)
+{
+ double d = lua_check_number(1, "acos");
+ lua_pushnumber (TODEGREE(acos(d)));
+}
+
+
+static void math_atan (void)
+{
+ double d = lua_check_number(1, "atan");
+ lua_pushnumber (TODEGREE(atan(d)));
+}
+
+
+static void math_atan2 (void)
+{
+ double d1 = lua_check_number(1, "atan2");
+ double d2 = lua_check_number(2, "atan2");
+ lua_pushnumber (TODEGREE(atan2(d1, d2)));
+}
+
+
+static void math_ceil (void)
+{
+ double d = lua_check_number(1, "ceil");
+ lua_pushnumber (ceil(d));
+}
+
+
+static void math_floor (void)
+{
+ double d = lua_check_number(1, "floor");
+ lua_pushnumber (floor(d));
+}
+
+static void math_mod (void)
+{
+ int d1 = (int)lua_check_number(1, "mod");
+ int d2 = (int)lua_check_number(2, "mod");
+ lua_pushnumber (d1%d2);
+}
+
+
+static void math_sqrt (void)
+{
+ double d = lua_check_number(1, "sqrt");
+ lua_pushnumber (sqrt(d));
+}
+
+static int old_pow;
+
+static void math_pow (void)
+{
+ lua_Object o1 = lua_getparam (1);
+ lua_Object o2 = lua_getparam (2);
+ lua_Object op = lua_getparam(3);
+ if (!lua_isnumber(o1) || !lua_isnumber(o2) || *(lua_getstring(op)) != 'p')
+ {
+ lua_Object old = lua_getref(old_pow);
+ lua_pushobject(o1);
+ lua_pushobject(o2);
+ lua_pushobject(op);
+ if (lua_callfunction(old) != 0)
+ lua_error(NULL);
+ }
+ else
+ {
+ double d1 = lua_getnumber(o1);
+ double d2 = lua_getnumber(o2);
+ lua_pushnumber (pow(d1,d2));
+ }
+}
+
+static void math_min (void)
+{
+ int i=1;
+ double dmin = lua_check_number(i, "min");
+ while (lua_getparam(++i) != LUA_NOOBJECT)
+ {
+ double d = lua_check_number(i, "min");
+ if (d < dmin) dmin = d;
+ }
+ lua_pushnumber (dmin);
+}
+
+static void math_max (void)
+{
+ int i=1;
+ double dmax = lua_check_number(i, "max");
+ while (lua_getparam(++i) != LUA_NOOBJECT)
+ {
+ double d = lua_check_number(i, "max");
+ if (d > dmax) dmax = d;
+ }
+ lua_pushnumber (dmax);
+}
+
+static void math_log (void)
+{
+ double d = lua_check_number(1, "log");
+ lua_pushnumber (log(d));
+}
+
+
+static void math_log10 (void)
+{
+ double d = lua_check_number(1, "log10");
+ lua_pushnumber (log10(d));
+}
+
+
+static void math_exp (void)
+{
+ double d = lua_check_number(1, "exp");
+ lua_pushnumber (exp(d));
+}
+
+static void math_deg (void)
+{
+ float d = lua_check_number(1, "deg");
+ lua_pushnumber (d*180./PI);
+}
+
+static void math_rad (void)
+{
+ float d = lua_check_number(1, "rad");
+ lua_pushnumber (d/180.*PI);
+}
+
+static void math_random (void)
+{
+ lua_pushnumber((double)(rand()%RAND_MAX) / (double)RAND_MAX);
+}
+
+static void math_randomseed (void)
+{
+ srand(lua_check_number(1, "randomseed"));
+}
+
+
+static struct lua_reg mathlib[] = {
+{"abs", math_abs},
+{"sin", math_sin},
+{"cos", math_cos},
+{"tan", math_tan},
+{"asin", math_asin},
+{"acos", math_acos},
+{"atan", math_atan},
+{"atan2", math_atan2},
+{"ceil", math_ceil},
+{"floor", math_floor},
+{"mod", math_mod},
+{"sqrt", math_sqrt},
+{"min", math_min},
+{"max", math_max},
+{"log", math_log},
+{"log10", math_log10},
+{"exp", math_exp},
+{"deg", math_deg},
+{"rad", math_rad},
+{"random", math_random},
+{"randomseed", math_randomseed}
+};
+
+/*
+** Open math library
+*/
+void mathlib_open (void)
+{
+ luaI_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0])));
+ old_pow = lua_refobject(lua_setfallback("arith", math_pow), 1);
+}
+
diff --git a/clients/lib/old/strlib.c b/clients/lib/old/strlib.c
new file mode 100644
index 00000000..6a99871c
--- /dev/null
+++ b/clients/lib/old/strlib.c
@@ -0,0 +1,276 @@
+/*
+** strlib.c
+** String library to LUA
+*/
+
+char *rcs_strlib="$Id: strlib.c,v 1.23 1996/04/30 21:13:55 roberto Exp $";
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include "lua.h"
+#include "lualib.h"
+
+
+void lua_arg_error(char *funcname)
+{
+ char buff[100];
+ sprintf(buff, "incorrect arguments to function `%s'", funcname);
+ lua_error(buff);
+}
+
+char *lua_check_string (int numArg, char *funcname)
+{
+ lua_Object o = lua_getparam(numArg);
+ if (!lua_isstring(o))
+ lua_arg_error(funcname);
+ return lua_getstring(o);
+}
+
+double lua_check_number (int numArg, char *funcname)
+{
+ lua_Object o = lua_getparam(numArg);
+ if (!lua_isnumber(o))
+ lua_arg_error(funcname);
+ return lua_getnumber(o);
+}
+
+static int lua_opt_number (int numArg, int def, char *funcname)
+{
+ return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
+ (int)lua_check_number(numArg, funcname);
+}
+
+char *luaI_addchar (int c)
+{
+ static char *buff = NULL;
+ static int max = 0;
+ static int n = 0;
+ if (n >= max)
+ {
+ if (max == 0)
+ {
+ max = 100;
+ buff = (char *)malloc(max);
+ }
+ else
+ {
+ max *= 2;
+ buff = (char *)realloc(buff, max);
+ }
+ if (buff == NULL)
+ lua_error("memory overflow");
+ }
+ buff[n++] = c;
+ if (c == 0)
+ n = 0; /* prepare for next string */
+ return buff;
+}
+
+
+/*
+** Return the position of the first caracter of a substring into a string
+** LUA interface:
+** n = strfind (string, substring, init, end)
+*/
+static void str_find (void)
+{
+ char *s1 = lua_check_string(1, "strfind");
+ char *s2 = lua_check_string(2, "strfind");
+ int init = lua_opt_number(3, 1, "strfind") - 1;
+ char *f = (init>=0 && init<=strlen(s1)) ? strstr(s1+init,s2) : NULL;
+ if (f != NULL)
+ {
+ int pos = f-s1+1;
+ if (lua_opt_number(4, INT_MAX, "strfind") >= pos+strlen(s2)-1)
+ lua_pushnumber (pos);
+ else
+ lua_pushnil();
+ }
+ else
+ lua_pushnil();
+}
+
+/*
+** Return the string length
+** LUA interface:
+** n = strlen (string)
+*/
+static void str_len (void)
+{
+ char *s = lua_check_string(1, "strlen");
+ lua_pushnumber(strlen(s));
+}
+
+
+/*
+** Return the substring of a string, from start to end
+** LUA interface:
+** substring = strsub (string, start, end)
+*/
+static void str_sub (void)
+{
+ char *s = lua_check_string(1, "strsub");
+ int start = (int)lua_check_number(2, "strsub");
+ int end = lua_opt_number(3, strlen(s), "strsub");
+ if (end < start || start < 1 || end > strlen(s))
+ lua_pushliteral("");
+ else
+ {
+ luaI_addchar(0);
+ while (start <= end)
+ luaI_addchar(s[start++ - 1]);
+ lua_pushstring (luaI_addchar(0));
+ }
+}
+
+/*
+** Convert a string to lower case.
+** LUA interface:
+** lowercase = strlower (string)
+*/
+static void str_lower (void)
+{
+ char *s = lua_check_string(1, "strlower");
+ luaI_addchar(0);
+ while (*s)
+ luaI_addchar(tolower(*s++));
+ lua_pushstring(luaI_addchar(0));
+}
+
+
+/*
+** Convert a string to upper case.
+** LUA interface:
+** uppercase = strupper (string)
+*/
+static void str_upper (void)
+{
+ char *s = lua_check_string(1, "strupper");
+ luaI_addchar(0);
+ while (*s)
+ luaI_addchar(toupper(*s++));
+ lua_pushstring(luaI_addchar(0));
+}
+
+/*
+** get ascii value of a character in a string
+*/
+static void str_ascii (void)
+{
+ char *s = lua_check_string(1, "ascii");
+ int pos = lua_opt_number(2, 1, "ascii") - 1;
+ if (pos<0 || pos>=strlen(s))
+ lua_arg_error("ascii");
+ lua_pushnumber(s[pos]);
+}
+
+void luaI_addquoted (char *s)
+{
+ luaI_addchar('"');
+ for (; *s; s++)
+ {
+ if (*s == '"' || *s == '\\' || *s == '\n')
+ luaI_addchar('\\');
+ luaI_addchar(*s);
+ }
+ luaI_addchar('"');
+}
+
+#define MAX_CONVERTION 2000
+#define MAX_FORMAT 50
+
+static void str_format (void)
+{
+ int arg = 1;
+ char *strfrmt = lua_check_string(arg++, "format");
+ luaI_addchar(0); /* initialize */
+ while (*strfrmt)
+ {
+ if (*strfrmt != '%')
+ luaI_addchar(*strfrmt++);
+ else if (*++strfrmt == '%')
+ luaI_addchar(*strfrmt++); /* %% */
+ else
+ { /* format item */
+ char form[MAX_FORMAT]; /* store the format ('%...') */
+ char buff[MAX_CONVERTION]; /* store the formated value */
+ int size = 0;
+ int i = 0;
+ form[i++] = '%';
+ form[i] = *strfrmt++;
+ while (!isalpha(form[i]))
+ {
+ if (isdigit(form[i]))
+ {
+ size = size*10 + form[i]-'0';
+ if (size >= MAX_CONVERTION)
+ lua_error("format size/precision too long in function `format'");
+ }
+ else if (form[i] == '.')
+ size = 0; /* re-start */
+ if (++i >= MAX_FORMAT)
+ lua_error("bad format in function `format'");
+ form[i] = *strfrmt++;
+ }
+ form[i+1] = 0; /* ends string */
+ switch (form[i])
+ {
+ case 'q':
+ luaI_addquoted(lua_check_string(arg++, "format"));
+ buff[0] = '\0'; /* addchar already done */
+ break;
+ case 's':
+ {
+ char *s = lua_check_string(arg++, "format");
+ if (strlen(s) >= MAX_CONVERTION)
+ lua_error("string argument too long in function `format'");
+ sprintf(buff, form, s);
+ break;
+ }
+ case 'c': case 'd': case 'i': case 'o':
+ case 'u': case 'x': case 'X':
+ sprintf(buff, form, (int)lua_check_number(arg++, "format"));
+ break;
+ case 'e': case 'E': case 'f': case 'g':
+ sprintf(buff, form, lua_check_number(arg++, "format"));
+ break;
+ default: /* also treat cases 'pnLlh' */
+ lua_error("invalid format option in function `format'");
+ }
+ for (i=0; buff[i]; i++) /* move formated value to result */
+ luaI_addchar(buff[i]);
+ }
+ }
+ lua_pushstring(luaI_addchar(0)); /* push the result */
+}
+
+
+void luaI_openlib (struct lua_reg *l, int n)
+{
+ int i;
+ for (i=0; i<n; i++)
+ lua_register(l[i].name, l[i].func);
+}
+
+static struct lua_reg strlib[] = {
+{"strfind", str_find},
+{"strlen", str_len},
+{"strsub", str_sub},
+{"strlower", str_lower},
+{"strupper", str_upper},
+{"ascii", str_ascii},
+{"format", str_format}
+};
+
+
+/*
+** Open string library
+*/
+void strlib_open (void)
+{
+ luaI_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
+}