run gib through indent

This commit is contained in:
Bill Currie 2003-02-14 22:42:11 +00:00
parent 851d203916
commit c91137e4db
13 changed files with 974 additions and 774 deletions

View file

@ -31,10 +31,9 @@
#include "ops.h"
exp_error_t EXP_ERROR;
char *exp_error_msg = 0;
char *exp_error_msg = 0;
optable_t optable[] =
{
optable_t optable[] = {
{"!", OP_Not, 1},
{"**", OP_Exp, 2},
{"/", OP_Div, 2},
@ -55,8 +54,7 @@ optable_t optable[] =
{"", 0, 0}
};
functable_t functable[] =
{
functable_t functable[] = {
{"sqrt", Func_Sqrt, 1},
{"abs", Func_Abs, 1},
{"sin", Func_Sin, 1},
@ -69,28 +67,28 @@ functable_t functable[] =
};
// Error handling
static exp_error_t
static exp_error_t
EXP_Error (exp_error_t err, const char *msg)
{
EXP_ERROR = err;
if (exp_error_msg)
free (exp_error_msg);
exp_error_msg = strdup(msg);
return err;
EXP_ERROR = err;
if (exp_error_msg)
free (exp_error_msg);
exp_error_msg = strdup (msg);
return err;
}
const char *
EXP_GetErrorMsg (void)
{
return exp_error_msg;
return exp_error_msg;
}
static token
*EXP_NewToken (void)
static token *
EXP_NewToken (void)
{
token *new;
token *new;
new = malloc(sizeof(token));
new = malloc (sizeof (token));
if (!new)
return 0;
@ -113,15 +111,16 @@ EXP_FindIndexByFunc (opfunc func)
static optable_t *
EXP_FindOpByStr (const char *str)
{
int i, len, fi;
int i, len, fi;
for (i = 0, len = 0, fi = -1; optable[i].func; i++)
if (!strncmp(str, optable[i].str, strlen(optable[i].str)) && strlen(optable[i].str) > len) {
len = strlen(optable[i].str);
if (!strncmp (str, optable[i].str, strlen (optable[i].str))
&& strlen (optable[i].str) > len) {
len = strlen (optable[i].str);
fi = i;
}
if (fi >= 0)
return optable+fi;
return optable + fi;
else
return 0;
}
@ -129,24 +128,26 @@ EXP_FindOpByStr (const char *str)
static functable_t *
EXP_FindFuncByStr (const char *str)
{
int i, len, fi;
int i, len, fi;
for (i = 0, len = 0, fi = -1; functable[i].func; i++)
if (!strncmp(str, functable[i].str, strlen(functable[i].str)) && strlen(functable[i].str) > len) {
len = strlen(functable[i].str);
if (!strncmp (str, functable[i].str, strlen (functable[i].str))
&& strlen (functable[i].str) > len) {
len = strlen (functable[i].str);
fi = i;
}
if (fi >= 0)
return functable+fi;
return functable + fi;
else
return 0;
}
static int
EXP_ContainsCommas (token *chain)
EXP_ContainsCommas (token * chain)
{
token *cur;
int paren = 0;
token *cur;
int paren = 0;
for (cur = chain; cur; cur = cur->generic.next) {
if (cur->generic.type == TOKEN_OPAREN)
paren++;
@ -157,15 +158,15 @@ EXP_ContainsCommas (token *chain)
if (cur->generic.type == TOKEN_COMMA)
return 1;
}
return -1; // We should never get here
return -1; // We should never get here
}
static int
EXP_DoFunction (token *chain)
EXP_DoFunction (token * chain)
{
token *cur, *temp;
double *oplist = 0;
double value;
token *cur, *temp;
double *oplist = 0;
double value;
unsigned int numops = 0;
@ -176,13 +177,13 @@ EXP_DoFunction (token *chain)
temp = 0;
if (cur->generic.type == TOKEN_NUM) {
numops++;
oplist = realloc(oplist, sizeof(double)*numops);
oplist[numops-1] = cur->num.value;
oplist = realloc (oplist, sizeof (double) * numops);
oplist[numops - 1] = cur->num.value;
}
EXP_RemoveToken (cur);
}
if (numops == chain->func.func->operands) {
value = chain->func.func->func(oplist, numops); // Heh
value = chain->func.func->func (oplist, numops); // Heh
chain->generic.type = TOKEN_NUM;
chain->num.value = value;
if (oplist)
@ -193,17 +194,18 @@ EXP_DoFunction (token *chain)
free (oplist);
return -1;
}
return -2; // We shouldn't get here
return -2; // We shouldn't get here
}
static int
EXP_DoUnary (token *chain)
EXP_DoUnary (token * chain)
{
if (chain->generic.next->generic.type == TOKEN_OP)
EXP_DoUnary (chain->generic.next);
if (chain->generic.next->generic.type != TOKEN_NUM)
return -1; // In theory, this should never happen
chain->generic.next->num.value = chain->op.op->func(chain->generic.next->num.value, 0);
return -1; // In theory, this should never happen
chain->generic.next->num.value =
chain->op.op->func (chain->generic.next->num.value, 0);
EXP_RemoveToken (chain);
return 0;
}
@ -211,95 +213,86 @@ EXP_DoUnary (token *chain)
token *
EXP_ParseString (char *str)
{
char buf[256];
char buf[256];
token *chain, *new, *cur;
int i,m;
optable_t *op;
token *chain, *new, *cur;
int i, m;
optable_t *op;
functable_t *func;
cur = chain = EXP_NewToken();
cur = chain = EXP_NewToken ();
chain->generic.type = TOKEN_OPAREN;
chain->generic.prev = 0;
chain->generic.next = 0;
for (i = 0; i < strlen(str); i++)
{
for (i = 0; i < strlen (str); i++) {
m = 0;
while(isspace((byte)str[i]))
while (isspace ((byte) str[i]))
i++;
if (!str[i])
break;
if (isdigit((byte)str[i]) || str[i] == '.')
{
while ((isdigit((byte)str[i]) // A number
|| str[i] == '.' // A decimal point
|| str[i] == 'e' // An exponent
|| ((str[i] == '-' || str[i] == '+') && str[i-1] == 'e')) // A + or - after an exponent
&& i < strlen(str) // We are within the string
&& m < 256) // And there is space in the buffer
if (isdigit ((byte) str[i]) || str[i] == '.') {
while ((isdigit ((byte) str[i]) // A number
|| str[i] == '.' // A decimal point
|| str[i] == 'e' // An exponent
|| ((str[i] == '-' || str[i] == '+')
&& str[i - 1] == 'e')) // A + or - after an exponent
&& i < strlen (str) // We are within the string
&& m < 256) // And there is space in the buffer
buf[m++] = str[i++];
buf[m] = 0;
new = EXP_NewToken();
new = EXP_NewToken ();
new->generic.type = TOKEN_NUM;
new->num.value = atof(buf);
new->num.value = atof (buf);
new->generic.prev = cur;
new->generic.next = 0;
cur->generic.next = new;
cur = new;
i--;
}
else if (str[i] == ',')
{
new = EXP_NewToken();
} else if (str[i] == ',') {
new = EXP_NewToken ();
new->generic.type = TOKEN_COMMA;
new->generic.prev = cur;
new->generic.next = 0;
cur->generic.next = new;
cur = new;
}
else if (str[i] == '(')
{
new = EXP_NewToken();
} else if (str[i] == '(') {
new = EXP_NewToken ();
new->generic.type = TOKEN_OPAREN;
new->generic.prev = cur;
new->generic.next = 0;
cur->generic.next = new;
cur = new;
}
else if (str[i] == ')')
{
new = EXP_NewToken();
} else if (str[i] == ')') {
new = EXP_NewToken ();
new->generic.type = TOKEN_CPAREN;
new->generic.prev = cur;
new->generic.next = 0;
cur->generic.next = new;
cur = new;
}
else
{
while(!(isdigit((byte)str[i])) && !isspace((byte)str[i])
&& str[i] != '.' && str[i] != '(' && str[i] != ')'
&& str[i] != ',' && m < 256) {
buf[m++] = str[i++];
} else {
while (!(isdigit ((byte) str[i])) && !isspace ((byte) str[i])
&& str[i] != '.' && str[i] != '(' && str[i] != ')'
&& str[i] != ',' && m < 256) {
buf[m++] = str[i++];
}
buf[m] = 0;
if (m)
{
if (m) {
if ((op = EXP_FindOpByStr (buf))) {
i -= (m - strlen(op->str) + 1);
new = EXP_NewToken();
i -= (m - strlen (op->str) + 1);
new = EXP_NewToken ();
new->generic.type = TOKEN_OP;
if (*(op->str) == '-') // HACK HACK HACK
op = optable + 6; // Always assume subtraction for - initially
if (*(op->str) == '-') // HACK HACK HACK
op = optable + 6; // Always assume subtraction for -
// initially
new->op.op = op;
new->generic.prev = cur;
new->generic.next = 0;
cur->generic.next = new;
cur = new;
} else if ((func = EXP_FindFuncByStr(buf))) {
i -= (m - strlen(func->str) + 1);
new = EXP_NewToken();
} else if ((func = EXP_FindFuncByStr (buf))) {
i -= (m - strlen (func->str) + 1);
new = EXP_NewToken ();
new->generic.type = TOKEN_FUNC;
new->func.func = func;
new->generic.prev = cur;
@ -308,13 +301,14 @@ EXP_ParseString (char *str)
cur = new;
} else {
EXP_DestroyTokens (chain);
EXP_Error (EXP_E_INVOP, va("Unknown operator or function '%s'.", buf));
EXP_Error (EXP_E_INVOP,
va ("Unknown operator or function '%s'.", buf));
return 0;
}
}
}
}
new = EXP_NewToken();
new = EXP_NewToken ();
new->generic.type = TOKEN_CPAREN;
new->generic.prev = cur;
new->generic.next = 0;
@ -323,61 +317,73 @@ EXP_ParseString (char *str)
}
exp_error_t
EXP_SimplifyTokens (token *chain)
EXP_SimplifyTokens (token * chain)
{
exp_error_t res;
int i;
token *cur;
token *temp;
int i;
token *cur;
token *temp;
/* First, get rid of parentheses */
for (cur = chain->generic.next; cur->generic.type != TOKEN_CPAREN; cur = cur->generic.next)
{
if (cur->generic.type == TOKEN_OPAREN)
{
res = EXP_SimplifyTokens(cur); /* Call ourself to simplify parentheses content */
for (cur = chain->generic.next; cur->generic.type != TOKEN_CPAREN;
cur = cur->generic.next) {
if (cur->generic.type == TOKEN_OPAREN) {
res = EXP_SimplifyTokens (cur); /* Call ourself to simplify
parentheses content */
if (res)
return res;
if (cur->generic.prev->generic.type == TOKEN_FUNC) { // These are arguments to a function
if (cur->generic.prev->generic.type == TOKEN_FUNC) {
// These are arguments to a function
cur = cur->generic.prev;
if (EXP_DoFunction (cur))
return EXP_Error (EXP_E_SYNTAX, va("Invalid number of arguments to function '%s'.", cur->func.func->str));
return EXP_Error (EXP_E_SYNTAX,
va
("Invalid number of arguments to function '%s'.",
cur->func.func->str));
} else {
if (EXP_ContainsCommas (cur))
return EXP_Error (EXP_E_SYNTAX, "Comma used outside of a function argument list.");
return EXP_Error (EXP_E_SYNTAX,
"Comma used outside of a function argument list.");
temp = cur;
cur = cur->generic.next;
EXP_RemoveToken(temp); /* Remove parentheses, leaving value behind */
EXP_RemoveToken(cur->generic.next);
EXP_RemoveToken (temp); /* Remove parentheses, leaving value
behind */
EXP_RemoveToken (cur->generic.next);
}
}
}
/* Next, evaluate all operators in order of operations */
for (i = 0; optable[i].func; i++)
{
for (cur = chain->generic.next; cur->generic.type != TOKEN_CPAREN; cur = cur->generic.next)
{
if (cur->generic.type == TOKEN_OP && cur->op.op == optable + i && cur->generic.next) {
for (i = 0; optable[i].func; i++) {
for (cur = chain->generic.next; cur->generic.type != TOKEN_CPAREN;
cur = cur->generic.next) {
if (cur->generic.type == TOKEN_OP && cur->op.op == optable + i
&& cur->generic.next) {
// If a unary operator is in our way, it gets evaluated early
if (cur->generic.next->generic.type == TOKEN_OP)
if (EXP_DoUnary (cur->generic.next))
return EXP_Error (EXP_E_SYNTAX, va("Unary operator '%s' not followed by a unary operator or numerical value.", cur->generic.next->op.op->str));
if (optable[i].operands == 1 && cur->generic.next->generic.type == TOKEN_NUM) {
cur->generic.next->num.value = optable[i].func(cur->generic.next->num.value, 0);
return EXP_Error (EXP_E_SYNTAX,
va
("Unary operator '%s' not followed by a unary operator or numerical value.",
cur->generic.next->op.op->str));
if (optable[i].operands == 1
&& cur->generic.next->generic.type == TOKEN_NUM) {
cur->generic.next->num.value =
optable[i].func (cur->generic.next->num.value, 0);
temp = cur;
cur = cur->generic.next;
EXP_RemoveToken(temp);
}
else if (cur->generic.prev->generic.type == TOKEN_NUM && cur->generic.next->generic.type == TOKEN_NUM)
{
cur->generic.prev->num.value = optable[i].func(cur->generic.prev->num.value, cur->generic.next->num.value);
EXP_RemoveToken (temp);
} else if (cur->generic.prev->generic.type == TOKEN_NUM
&& cur->generic.next->generic.type == TOKEN_NUM) {
cur->generic.prev->num.value =
optable[i].func (cur->generic.prev->num.value,
cur->generic.next->num.value);
temp = cur;
cur = cur->generic.prev;
EXP_RemoveToken(temp->generic.next);
EXP_RemoveToken(temp);
EXP_RemoveToken (temp->generic.next);
EXP_RemoveToken (temp);
}
}
}
@ -386,41 +392,39 @@ EXP_SimplifyTokens (token *chain)
}
void
EXP_RemoveToken (token *tok)
EXP_RemoveToken (token * tok)
{
tok->generic.prev->generic.next = tok->generic.next;
tok->generic.next->generic.prev = tok->generic.prev;
free(tok);
free (tok);
}
void
EXP_DestroyTokens (token *chain)
EXP_DestroyTokens (token * chain)
{
token *temp;
for (;chain; chain = temp)
{
token *temp;
for (; chain; chain = temp) {
temp = chain->generic.next;
free(chain);
free (chain);
}
}
double
EXP_Evaluate (char *str)
{
token *chain;
double res;
token *chain;
double res;
EXP_ERROR = EXP_E_NORMAL;
if (!(chain = EXP_ParseString (str)))
return 0;
if (EXP_Validate (chain))
{
if (EXP_Validate (chain)) {
EXP_DestroyTokens (chain);
return 0;
}
if (EXP_SimplifyTokens (chain))
{
if (EXP_SimplifyTokens (chain)) {
EXP_DestroyTokens (chain);
return 0;
}
@ -430,7 +434,7 @@ EXP_Evaluate (char *str)
}
void
EXP_InsertTokenAfter (token *spot, token *new)
EXP_InsertTokenAfter (token * spot, token * new)
{
spot->generic.next->generic.prev = new;
new->generic.next = spot->generic.next;
@ -440,48 +444,63 @@ EXP_InsertTokenAfter (token *spot, token *new)
exp_error_t
EXP_Validate (token *chain)
EXP_Validate (token * chain)
{
token *cur, *new;
int paren = 0;
token *cur, *new;
int paren = 0;
for (cur = chain; cur->generic.next; cur = cur->generic.next)
{
for (cur = chain; cur->generic.next; cur = cur->generic.next) {
if (cur->generic.type == TOKEN_OPAREN)
paren++;
if (cur->generic.type == TOKEN_CPAREN)
paren--;
/* Implied multiplication */
if ((cur->generic.type == TOKEN_NUM && (
cur->generic.next->generic.type == TOKEN_OPAREN || // 5(1+1)
cur->generic.next->generic.type == TOKEN_FUNC || // 5 sin (1+1)
(cur->generic.next->generic.type == TOKEN_OP && cur->generic.next->op.op->operands == 1))) || // 5!(1+1)
(cur->generic.type == TOKEN_CPAREN && (
cur->generic.next->generic.type == TOKEN_NUM || // (1+1)5
cur->generic.next->generic.type == TOKEN_OPAREN))) // (1+1)(1+1)
if ((cur->generic.type == TOKEN_NUM && (cur->generic.next->generic.type == TOKEN_OPAREN || // 5(1+1)
cur->generic.next->generic.type == TOKEN_FUNC || // 5 sin (1+1)
(cur->generic.next->generic.type == TOKEN_OP && cur->generic.next->op.op->operands == 1))) || // 5!(1+1)
(cur->generic.type == TOKEN_CPAREN && (cur->generic.next->generic.type == TOKEN_NUM || // (1+1)5
cur->generic.next->generic.type == TOKEN_OPAREN))) // (1+1)(1+1)
{
new = EXP_NewToken ();
new->generic.type = TOKEN_OP;
new->op.op = EXP_FindOpByStr ("*");
EXP_InsertTokenAfter (cur, new);
}
else if ((cur->generic.type == TOKEN_OP || cur->generic.type == TOKEN_OPAREN) && cur->generic.next->generic.type == TOKEN_OP)
{
if (cur->generic.next->op.op->func == OP_Sub) /* Stupid hack for negation */
} else
if ((cur->generic.type == TOKEN_OP
|| cur->generic.type == TOKEN_OPAREN)
&& cur->generic.next->generic.type == TOKEN_OP) {
if (cur->generic.next->op.op->func == OP_Sub) /* Stupid hack for
negation */
cur->generic.next->op.op = optable + 3;
else if (cur->generic.next->op.op->operands == 2)
return EXP_Error (EXP_E_SYNTAX, va ("Operator '%s' does not follow a number or numerical value.", cur->generic.next->op.op->str));
}
else if (cur->generic.type == TOKEN_FUNC && cur->generic.next->generic.type != TOKEN_OPAREN)
return EXP_Error (EXP_E_SYNTAX, va("Function '%s' called without an argument list.", cur->func.func->str));
else if (cur->generic.type == TOKEN_COMMA && ((cur->generic.prev->generic.type != TOKEN_CPAREN
&& cur->generic.prev->generic.type != TOKEN_NUM) || paren <= 1))
return EXP_Error (EXP_E_SYNTAX, "Comma used outside of a function or after a non-number.");
else if (cur->generic.type == TOKEN_OP && cur->generic.next->generic.type == TOKEN_CPAREN)
return EXP_Error (EXP_E_SYNTAX, va("Operator '%s' is missing an operand.", cur->op.op->str));
else if (cur->generic.type == TOKEN_NUM && cur->generic.next->generic.type == TOKEN_NUM)
return EXP_Error (EXP_E_SYNTAX, "Double number error (two numbers next two each other without an operator).");
else if (cur->generic.type == TOKEN_OPAREN && cur->generic.next->generic.type == TOKEN_CPAREN)
return EXP_Error (EXP_E_SYNTAX,
va
("Operator '%s' does not follow a number or numerical value.",
cur->generic.next->op.op->str));
} else if (cur->generic.type == TOKEN_FUNC
&& cur->generic.next->generic.type != TOKEN_OPAREN)
return EXP_Error (EXP_E_SYNTAX,
va
("Function '%s' called without an argument list.",
cur->func.func->str));
else if (cur->generic.type == TOKEN_COMMA
&&
((cur->generic.prev->generic.type != TOKEN_CPAREN
&& cur->generic.prev->generic.type != TOKEN_NUM)
|| paren <= 1))
return EXP_Error (EXP_E_SYNTAX,
"Comma used outside of a function or after a non-number.");
else if (cur->generic.type == TOKEN_OP
&& cur->generic.next->generic.type == TOKEN_CPAREN)
return EXP_Error (EXP_E_SYNTAX,
va ("Operator '%s' is missing an operand.",
cur->op.op->str));
else if (cur->generic.type == TOKEN_NUM
&& cur->generic.next->generic.type == TOKEN_NUM)
return EXP_Error (EXP_E_SYNTAX,
"Double number error (two numbers next two each other without an operator).");
else if (cur->generic.type == TOKEN_OPAREN
&& cur->generic.next->generic.type == TOKEN_CPAREN)
return EXP_Error (EXP_E_PAREN, "Empty parentheses found.");
}
@ -492,31 +511,30 @@ EXP_Validate (token *chain)
}
void
EXP_PrintTokens (token *chain)
EXP_PrintTokens (token * chain)
{
for (; chain; chain = chain->generic.next)
switch (chain->generic.type)
{
switch (chain->generic.type) {
case TOKEN_OPAREN:
printf("(");
printf ("(");
break;
case TOKEN_CPAREN:
printf(")");
printf (")");
break;
case TOKEN_COMMA:
printf(",");
printf (",");
break;
case TOKEN_NUM:
printf("%f", chain->num.value);
printf ("%f", chain->num.value);
break;
case TOKEN_OP:
printf("%s", chain->op.op->str);
printf ("%s", chain->op.op->str);
break;
case TOKEN_FUNC:
printf("%s", chain->func.func->str);
printf ("%s", chain->func.func->str);
break;
case TOKEN_GENERIC:
break;
}
printf("\n");
printf ("\n");
}

View file

@ -32,8 +32,8 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] = "$Id$";
#include <stdlib.h>
#include <string.h>
@ -61,17 +61,17 @@ GIB_Buffer_Construct (struct cbuf_s *cbuf)
void
GIB_Buffer_Destruct (struct cbuf_s *cbuf)
{
gib_buffer_data_t *g = GIB_DATA(cbuf);
gib_buffer_data_t *g = GIB_DATA (cbuf);
unsigned int i, j;
dstring_delete (g->arg_composite);
if (g->locals)
Hash_DelTable (g->locals);
if (g->program)
GIB_Tree_Unref (&g->program);
if (g->script && !(--g->script->refs)) {
free ((void *)g->script->text);
free ((void *)g->script->file);
free ((void *) g->script->text);
free ((void *) g->script->file);
free (g->script);
}
for (i = 0; i < g->stack.size; i++) {
@ -88,8 +88,8 @@ GIB_Buffer_Destruct (struct cbuf_s *cbuf)
void
GIB_Buffer_Reset (struct cbuf_s *cbuf)
{
gib_buffer_data_t *g = GIB_DATA(cbuf);
gib_buffer_data_t *g = GIB_DATA (cbuf);
if (g->locals)
Hash_FlushTable (g->locals);
g->globals = gib_globals;
@ -103,19 +103,20 @@ GIB_Buffer_Reset (struct cbuf_s *cbuf)
g->script = 0;
g->stack.p = 0;
g->waitret = g->done = false;
}
void
GIB_Buffer_Set_Program (cbuf_t *cbuf, gib_tree_t *program)
GIB_Buffer_Set_Program (cbuf_t * cbuf, gib_tree_t * program)
{
GIB_DATA(cbuf)->program = program;
GIB_DATA (cbuf)->program = program;
}
static unsigned int
GIB_Buffer_Get_Line_Num (const char *program, unsigned int pos)
{
unsigned int i, line;
for (i = 0, line = 1; i < pos; i++)
if (program[i] == '\n')
line++;
@ -123,7 +124,7 @@ GIB_Buffer_Get_Line_Num (const char *program, unsigned int pos)
}
void
GIB_Buffer_Add (cbuf_t *cbuf, const char *str)
GIB_Buffer_Add (cbuf_t * cbuf, const char *str)
{
gib_buffer_data_t *g = GIB_DATA (cbuf);
gib_tree_t **save, *cur;
@ -134,125 +135,126 @@ GIB_Buffer_Add (cbuf_t *cbuf, const char *str)
} else
save = &g->program;
if (!(*save = GIB_Parse_Lines (str, 0, TREE_NORMAL)))
Sys_Printf (
"-----------------\n"
"|GIB Parse Error|\n"
"-----------------\n"
"Parse error while adding text to GIB buffer.\n"
"Line %u: %s\n", GIB_Buffer_Get_Line_Num (str, GIB_Parse_ErrorPos()), GIB_Parse_ErrorMsg()
Sys_Printf ("-----------------\n"
"|GIB Parse Error|\n"
"-----------------\n"
"Parse error while adding text to GIB buffer.\n"
"Line %u: %s\n", GIB_Buffer_Get_Line_Num (str,
GIB_Parse_ErrorPos
()),
GIB_Parse_ErrorMsg ()
);
}
void
GIB_Buffer_Insert (cbuf_t *cbuf, const char *str)
GIB_Buffer_Insert (cbuf_t * cbuf, const char *str)
{
gib_buffer_data_t *g = GIB_DATA (cbuf);
gib_tree_t *lines, *cur;
if ((lines = GIB_Parse_Lines (str, 0, TREE_NORMAL))) {
for (cur = lines; cur; cur = cur->next);
//if (g->ip) { // This buffer is already running!
// if (g->ip) { // This buffer is already running!
GIB_Tree_Unref (&g->program);
cur->next = g->program;
g->program = lines;
} else
Sys_Printf (
"-----------------\n"
"|GIB Parse Error|\n"
"-----------------\n"
"Parse error while inserting text into GIB buffer.\n"
"Line %u: %s\n", GIB_Buffer_Get_Line_Num (str, GIB_Parse_ErrorPos()), GIB_Parse_ErrorMsg()
Sys_Printf ("-----------------\n"
"|GIB Parse Error|\n"
"-----------------\n"
"Parse error while inserting text into GIB buffer.\n"
"Line %u: %s\n", GIB_Buffer_Get_Line_Num (str,
GIB_Parse_ErrorPos
()),
GIB_Parse_ErrorMsg ()
);
}
void
GIB_Buffer_Push_Sstack (struct cbuf_s *cbuf)
{
gib_buffer_data_t *g = GIB_DATA(cbuf);
gib_buffer_data_t *g = GIB_DATA (cbuf);
if (++g->stack.p > g->stack.size) {
g->stack.values = realloc(g->stack.values, sizeof (struct gib_dsarray_s) * g->stack.p);
g->stack.values[g->stack.p-1].dstrs = 0;
g->stack.values[g->stack.p-1].size = g->stack.values[g->stack.p-1].realsize = 0;
g->stack.values =
realloc (g->stack.values,
sizeof (struct gib_dsarray_s) * g->stack.p);
g->stack.values[g->stack.p - 1].dstrs = 0;
g->stack.values[g->stack.p - 1].size =
g->stack.values[g->stack.p - 1].realsize = 0;
g->stack.size = g->stack.p;
}
g->stack.values[g->stack.p-1].size = 0;
g->stack.values[g->stack.p - 1].size = 0;
}
void
GIB_Buffer_Pop_Sstack (struct cbuf_s *cbuf)
{
GIB_DATA(cbuf)->stack.p--;
GIB_DATA (cbuf)->stack.p--;
}
dstring_t *
GIB_Buffer_Dsarray_Get (struct cbuf_s *cbuf)
{
struct gib_dsarray_s *vals = GIB_DATA(cbuf)->stack.values+GIB_DATA(cbuf)->stack.p-1;
struct gib_dsarray_s *vals =
GIB_DATA (cbuf)->stack.values + GIB_DATA (cbuf)->stack.p - 1;
if (++vals->size > vals->realsize) {
vals->dstrs = realloc (vals->dstrs, sizeof (dstring_t *) * vals->size);
vals->dstrs[vals->size-1] = dstring_newstr ();
vals->dstrs[vals->size - 1] = dstring_newstr ();
vals->realsize = vals->size;
} else
dstring_clearstr (vals->dstrs[vals->size-1]);
return vals->dstrs[vals->size-1];
dstring_clearstr (vals->dstrs[vals->size - 1]);
return vals->dstrs[vals->size - 1];
}
static int
GIB_Buffer_Get_Line_Info (cbuf_t *cbuf, char **line)
GIB_Buffer_Get_Line_Info (cbuf_t * cbuf, char **line)
{
const char *text;
unsigned int ofs, i, start, linenum;
// Do we have a copy of the original program this buffer comes from?
if (GIB_DATA(cbuf)->script) {
text = GIB_DATA(cbuf)->script->text;
for (ofs = GIB_DATA(cbuf)->ip->start, start = 0, i = 0, linenum = 1; i <= ofs; i++)
if (GIB_DATA (cbuf)->script) {
text = GIB_DATA (cbuf)->script->text;
for (ofs = GIB_DATA (cbuf)->ip->start, start = 0, i = 0, linenum = 1;
i <= ofs; i++)
if (text[i] == '\n') {
start = i+1;
start = i + 1;
linenum++;
}
while (text[i] != '\n')
i++;
*line = malloc (i - start + 1);
memcpy (*line, text+start, i - start);
(*line)[i-start] = 0;
memcpy (*line, text + start, i - start);
(*line)[i - start] = 0;
return linenum;
} else {
*line = strdup (GIB_DATA(cbuf)->ip->str);
*line = strdup (GIB_DATA (cbuf)->ip->str);
return -1;
}
}
void
GIB_Buffer_Error (cbuf_t *cbuf, const char *type, const char *fmt, va_list args)
GIB_Buffer_Error (cbuf_t * cbuf, const char *type, const char *fmt,
va_list args)
{
char *line;
int linenum;
dstring_t *message = dstring_newstr();
char *line;
int linenum;
dstring_t *message = dstring_newstr ();
dvsprintf (message, fmt, args);
va_end (args);
Sys_Printf ( "---------------------\n"
"|GIB Execution Error|\n"
"---------------------\n"
"Type: %s\n",
type
);
Sys_Printf ("---------------------\n"
"|GIB Execution Error|\n"
"---------------------\n" "Type: %s\n", type);
if ((linenum = GIB_Buffer_Get_Line_Info (cbuf, &line)) != -1)
Sys_Printf ( "%s:%i: %s\n"
"-->%s\n",
GIB_DATA(cbuf)->script->file,
linenum,
message->str,
line
);
Sys_Printf ("%s:%i: %s\n"
"-->%s\n",
GIB_DATA (cbuf)->script->file, linenum, message->str, line);
else
Sys_Printf ( "%s\n"
"-->%s\n",
message->str,
line
);
Sys_Printf ("%s\n" "-->%s\n", message->str, line);
cbuf->state = CBUF_STATE_ERROR;
dstring_delete (message);
free (line);

View file

@ -32,8 +32,9 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] =
"$Id$";
#include <ctype.h>
#include <stdlib.h>
@ -63,22 +64,23 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/gib_thread.h"
#include "regex.h"
char gib_null_string[] = "";
char gib_null_string[] = "";
hashtab_t *gib_builtins;
hashtab_t *gib_builtins;
/*
Hashtable callbacks
*/
static const char *
static const char *
GIB_Builtin_Get_Key (void *ele, void *ptr)
{
return ((gib_builtin_t *)ele)->name->str;
return ((gib_builtin_t *) ele)->name->str;
}
static void
GIB_Builtin_Free (void *ele, void *ptr)
{
gib_builtin_t *b;
b = (gib_builtin_t *) ele;
dstring_delete (b->name);
free (b);
@ -93,13 +95,14 @@ void
GIB_Builtin_Add (const char *name, void (*func) (void))
{
gib_builtin_t *new;
if (!gib_builtins)
gib_builtins = Hash_NewTable (1024, GIB_Builtin_Get_Key, GIB_Builtin_Free, 0);
gib_builtins =
Hash_NewTable (1024, GIB_Builtin_Get_Key, GIB_Builtin_Free, 0);
new = calloc (1, sizeof (gib_builtin_t));
new->func = func;
new->name = dstring_newstr();
new->name = dstring_newstr ();
dstring_appendstr (new->name, name);
Hash_Add (gib_builtins, new);
}
@ -122,11 +125,12 @@ GIB_Builtin_Find (const char *name)
dstring_t *
GIB_Return (const char *str)
{
dstring_t *dstr;
if (GIB_DATA(cbuf_active)->waitret) {
dstring_t *dstr;
if (GIB_DATA (cbuf_active)->waitret) {
dstr = GIB_Buffer_Dsarray_Get (cbuf_active);
dstring_clearstr (dstr);
if (!str)
if (!str)
return dstr;
else
dstring_appendstr (dstr, str);
@ -137,8 +141,8 @@ GIB_Return (const char *str)
void
GIB_Error (const char *type, const char *fmt, ...)
{
va_list args;
va_list args;
va_start (args, fmt);
GIB_Buffer_Error (cbuf_active, type, fmt, args);
va_end (args);
@ -160,16 +164,19 @@ GIB_Function_f (void)
// Is the function program already tokenized?
if (GIB_Argm (2)->delim != '{') {
// Parse on the fly
if (!(program = GIB_Parse_Lines (GIB_Argv(2), 0, TREE_NORMAL))) {
if (!(program = GIB_Parse_Lines (GIB_Argv (2), 0, TREE_NORMAL))) {
// Error!
GIB_Error ("parse", "Parse error while defining function '%s'.", GIB_Argv(1));
GIB_Error ("parse", "Parse error while defining function '%s'.",
GIB_Argv (1));
return;
}
} else
program = GIB_Argm (2)->children;
GIB_Function_Define (GIB_Argv(1), GIB_Argv(2), program, GIB_DATA(cbuf_active)->script, GIB_DATA(cbuf_active)->globals);
GIB_Function_Define (GIB_Argv (1), GIB_Argv (2), program,
GIB_DATA (cbuf_active)->script,
GIB_DATA (cbuf_active)->globals);
}
}
}
static void
GIB_Function_Get_f (void)
@ -178,6 +185,7 @@ GIB_Function_Get_f (void)
GIB_USAGE ("name");
else {
gib_function_t *f;
if ((f = GIB_Function_Find (GIB_Argv (1))))
GIB_Return (f->text->str);
else
@ -188,16 +196,19 @@ GIB_Function_Get_f (void)
static void
GIB_Local_f (void)
{
gib_var_t *var;
gib_var_t *var;
unsigned int index;
hashtab_t *zero = 0;
hashtab_t *zero = 0;
if (GIB_Argc () < 2)
GIB_USAGE ("var [= value1 value2 ...]");
else {
var = GIB_Var_Get_Complex (&GIB_DATA(cbuf_active)->locals, &zero, GIB_Argv(1), &index, true);
if (GIB_Argc() >= 3)
GIB_Var_Assign (var, index, cbuf_active->args->argv+3, GIB_Argc() - 3);
var =
GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->locals, &zero,
GIB_Argv (1), &index, true);
if (GIB_Argc () >= 3)
GIB_Var_Assign (var, index, cbuf_active->args->argv + 3,
GIB_Argc () - 3);
}
}
@ -205,71 +216,77 @@ GIB_Local_f (void)
static void
GIB_Global_f (void)
{
gib_var_t *var;
gib_var_t *var;
unsigned int index;
hashtab_t *zero = 0;
hashtab_t *zero = 0;
if (GIB_Argc () < 2)
GIB_USAGE ("var [= value1 value2 ...]");
else {
var = GIB_Var_Get_Complex (&GIB_DATA(cbuf_active)->globals, &zero, GIB_Argv(1), &index, true);
if (GIB_Argc() >= 3)
GIB_Var_Assign (var, index, cbuf_active->args->argv+3, GIB_Argc() - 3);
var =
GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->globals, &zero,
GIB_Argv (1), &index, true);
if (GIB_Argc () >= 3)
GIB_Var_Assign (var, index, cbuf_active->args->argv + 3,
GIB_Argc () - 3);
}
}
static void
GIB_Domain_f (void)
{
if (GIB_Argc() != 2)
if (GIB_Argc () != 2)
GIB_USAGE ("domain");
else
GIB_DATA(cbuf_active)->globals = GIB_Domain_Get (GIB_Argv(1));
GIB_DATA (cbuf_active)->globals = GIB_Domain_Get (GIB_Argv (1));
}
static void
GIB_Domain_Clear_f (void)
{
if (GIB_Argc() != 2)
if (GIB_Argc () != 2)
GIB_USAGE ("domain");
else
Hash_FlushTable (GIB_Domain_Get (GIB_Argv(2)));
Hash_FlushTable (GIB_Domain_Get (GIB_Argv (2)));
}
static void
GIB_Return_f (void)
{
cbuf_t *sp = cbuf_active->up;
GIB_DATA(cbuf_active)->done = true;
if (GIB_Argc() > 1 && sp && sp->interpreter == &gib_interp && GIB_DATA(sp)->waitret) {
cbuf_t *sp = cbuf_active->up;
GIB_DATA (cbuf_active)->done = true;
if (GIB_Argc () > 1 && sp && sp->interpreter == &gib_interp
&& GIB_DATA (sp)->waitret) {
unsigned int i;
dstring_t *dstr;
for (i = 1; i < GIB_Argc(); i++) {
dstring_t *dstr;
for (i = 1; i < GIB_Argc (); i++) {
dstr = GIB_Buffer_Dsarray_Get (sp);
dstring_clearstr (dstr);
dstring_appendstr (dstr, GIB_Argv(i));
dstring_appendstr (dstr, GIB_Argv (i));
}
}
}
static void
GIB_For_f (void)
{
dstring_t *dstr;
dstring_t *dstr;
unsigned int i;
if (GIB_Argc() < 5) {
GIB_DATA(cbuf_active)->ip = GIB_DATA(cbuf_active)->ip->jump;
if (GIB_Argc () < 5) {
GIB_DATA (cbuf_active)->ip = GIB_DATA (cbuf_active)->ip->jump;
return;
}
GIB_Buffer_Push_Sstack (cbuf_active);
dstr = GIB_Buffer_Dsarray_Get (cbuf_active);
dstring_clearstr (dstr);
dstring_appendstr (dstr, GIB_Argv(1));
for (i = GIB_Argc()-2; i > 2; i--) {
dstring_appendstr (dstr, GIB_Argv (1));
for (i = GIB_Argc () - 2; i > 2; i--) {
dstr = GIB_Buffer_Dsarray_Get (cbuf_active);
dstring_appendstr (dstr, GIB_Argv(i));
dstring_appendstr (dstr, GIB_Argv (i));
}
GIB_Execute_For_Next (cbuf_active);
}
@ -277,13 +294,14 @@ GIB_For_f (void)
static void
GIB_Break_f (void)
{
if (!GIB_DATA(cbuf_active)->ip->jump) {
if (!GIB_DATA (cbuf_active)->ip->jump) {
GIB_Error ("loop", "Break command attempted outside of a loop.");
return;
}
if (!GIB_DATA(cbuf_active)->ip->jump->flags & TREE_COND) // In a for loop?
GIB_Buffer_Pop_Sstack (cbuf_active); // Kill it
GIB_DATA(cbuf_active)->ip = GIB_DATA(cbuf_active)->ip->jump->jump;
if (!GIB_DATA (cbuf_active)->ip->jump->flags & TREE_COND) // In a for
// loop?
GIB_Buffer_Pop_Sstack (cbuf_active); // Kill it
GIB_DATA (cbuf_active)->ip = GIB_DATA (cbuf_active)->ip->jump->jump;
}
static gib_tree_t gib_cont = {
@ -296,16 +314,16 @@ static gib_tree_t gib_cont = {
static void
GIB_Continue_f (void)
{
if (!GIB_DATA(cbuf_active)->ip->jump) {
if (!GIB_DATA (cbuf_active)->ip->jump) {
GIB_Error ("loop", "Continue command attempted outside of a loop.");
return;
}
if (GIB_DATA(cbuf_active)->ip->jump->flags & TREE_COND) {
gib_cont.next = GIB_DATA(cbuf_active)->ip->jump;
GIB_DATA(cbuf_active)->ip = &gib_cont;
if (GIB_DATA (cbuf_active)->ip->jump->flags & TREE_COND) {
gib_cont.next = GIB_DATA (cbuf_active)->ip->jump;
GIB_DATA (cbuf_active)->ip = &gib_cont;
} else {
GIB_Execute_For_Next (cbuf_active);
GIB_DATA(cbuf_active)->ip = GIB_DATA(cbuf_active)->ip->jump;
GIB_DATA (cbuf_active)->ip = GIB_DATA (cbuf_active)->ip->jump;
}
}
@ -314,14 +332,16 @@ static void
GIB_Runexported_f (void)
{
gib_function_t *f;
if (!(f = GIB_Function_Find (Cmd_Argv (0))))
Sys_Printf ("Error: No function found for exported command \"%s\".\n"
"This is most likely a bug, please report it to"
"The QuakeForge developers.", Cmd_Argv(0));
"The QuakeForge developers.", Cmd_Argv (0));
else {
cbuf_t *sub = Cbuf_New (&gib_interp);
GIB_Function_Execute (sub, f, cbuf_active->args->argv, cbuf_active->args->argc);
cbuf_t *sub = Cbuf_New (&gib_interp);
GIB_Function_Execute (sub, f, cbuf_active->args->argv,
cbuf_active->args->argc);
cbuf_active->down = sub;
sub->up = cbuf_active;
cbuf_active->state = CBUF_STATE_STACK;
@ -332,19 +352,23 @@ static void
GIB_Function_Export_f (void)
{
gib_function_t *f;
int i;
if (GIB_Argc() < 2)
int i;
if (GIB_Argc () < 2)
GIB_USAGE ("function1 [function2 function3 ...]");
for (i = 1; i < GIB_Argc(); i++) {
for (i = 1; i < GIB_Argc (); i++) {
if (!(f = GIB_Function_Find (GIB_Argv (i))))
GIB_Error ("function", "%s: function '%s' not found.", GIB_Argv(0), GIB_Argv (i));
GIB_Error ("function", "%s: function '%s' not found.", GIB_Argv (0),
GIB_Argv (i));
else if (!f->exported) {
if (Cmd_Exists (f->name)) {
GIB_Error ("export", "%s: A console command with the name '%s' already exists.", GIB_Argv(0), GIB_Argv(i));
GIB_Error ("export",
"%s: A console command with the name '%s' already exists.",
GIB_Argv (0), GIB_Argv (i));
return;
} else {
Cmd_AddCommand (f->name, GIB_Runexported_f, "Exported GIB function.");
Cmd_AddCommand (f->name, GIB_Runexported_f,
"Exported GIB function.");
f->exported = true;
}
}
@ -354,19 +378,20 @@ GIB_Function_Export_f (void)
static void
GIB_Length_f (void)
{
dstring_t *ret;
if (GIB_Argc() != 2)
dstring_t *ret;
if (GIB_Argc () != 2)
GIB_USAGE ("string");
else if ((ret = GIB_Return (0)))
dsprintf (ret, "%i", (int) strlen(GIB_Argv(1)));
dsprintf (ret, "%i", (int) strlen (GIB_Argv (1)));
}
static void
GIB_Equal_f (void)
{
if (GIB_Argc() != 3)
if (GIB_Argc () != 3)
GIB_USAGE ("string1 string2");
else if (strcmp(GIB_Argv(1), GIB_Argv(2)))
else if (strcmp (GIB_Argv (1), GIB_Argv (2)))
GIB_Return ("0");
else
GIB_Return ("1");
@ -375,14 +400,15 @@ GIB_Equal_f (void)
static void
GIB_Slice_f (void)
{
dstring_t *ret;
int start, end, len;
if (GIB_Argc() < 3 || GIB_Argc() > 4)
dstring_t *ret;
int start, end, len;
if (GIB_Argc () < 3 || GIB_Argc () > 4)
GIB_USAGE ("string start [end]");
else {
len = strlen (GIB_Argv(1));
start = atoi (GIB_Argv(2));
end = *GIB_Argv(3) ? atoi (GIB_Argv(3)) : len;
len = strlen (GIB_Argv (1));
start = atoi (GIB_Argv (2));
end = *GIB_Argv (3) ? atoi (GIB_Argv (3)) : len;
if (end < 0)
end += len;
else if (end > len)
@ -394,7 +420,7 @@ GIB_Slice_f (void)
} else if (start >= len || start >= end)
return;
if ((ret = GIB_Return (0)))
dstring_appendsubstr (ret, GIB_Argv(1)+start, end-start);
dstring_appendsubstr (ret, GIB_Argv (1) + start, end - start);
}
}
@ -402,59 +428,67 @@ GIB_Slice_f (void)
static void
GIB_Slice_Find_f (void)
{
char *res;
if (GIB_Argc() != 3) {
char *res;
if (GIB_Argc () != 3) {
GIB_USAGE ("haystack needle");
return;
} else if (!GIB_CanReturn ())
return;
else if ((res = strstr(GIB_Argv(1), GIB_Argv(2)))) {
dsprintf (GIB_Return (0), "%lu", (unsigned long int)(res - GIB_Argv(1)));
dsprintf (GIB_Return (0), "%lu", (unsigned long int)(res - GIB_Argv(1))+strlen (GIB_Argv(2)));
}
else if ((res = strstr (GIB_Argv (1), GIB_Argv (2)))) {
dsprintf (GIB_Return (0), "%lu",
(unsigned long int) (res - GIB_Argv (1)));
dsprintf (GIB_Return (0), "%lu",
(unsigned long int) (res - GIB_Argv (1)) +
strlen (GIB_Argv (2)));
}
}
static void
GIB_Split_f (void)
{
char *end, *start;
char *end, *start;
const char *ifs;
if (GIB_Argc() < 2 || GIB_Argc() > 3) {
if (GIB_Argc () < 2 || GIB_Argc () > 3) {
GIB_USAGE ("string [fs]");
return;
}
ifs = GIB_Argc() == 3 ? GIB_Argv (2) : " \t\r\n";
end = GIB_Argv(1);
ifs = GIB_Argc () == 3 ? GIB_Argv (2) : " \t\r\n";
end = GIB_Argv (1);
while (*end) {
for (; strchr(ifs, *end); end++)
for (; strchr (ifs, *end); end++)
if (!*end)
return;
start = end;
while (!strchr(ifs, *end))
while (!strchr (ifs, *end))
end++;
if (*end)
*(end++) = 0;
GIB_Return (start);
GIB_Return (start);
}
}
static void
GIB_Regex_Match_f (void)
{
regex_t *reg;
if (GIB_Argc() != 4) {
regex_t *reg;
if (GIB_Argc () != 4) {
GIB_USAGE ("string regex options");
return;
}
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
GIB_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
else if (regexec(reg, GIB_Argv(1), 0, 0, 0))
if (!
(reg =
GIB_Regex_Compile (GIB_Argv (2),
REG_EXTENDED |
GIB_Regex_Translate_Options (GIB_Argv (3)))))
GIB_Error ("regex", "%s: %s", GIB_Argv (0), GIB_Regex_Error ());
else if (regexec (reg, GIB_Argv (1), 0, 0, 0))
GIB_Return ("0");
else
GIB_Return ("1");
@ -463,53 +497,64 @@ GIB_Regex_Match_f (void)
static void
GIB_Regex_Replace_f (void)
{
regex_t *reg;
int ofs, len;
regmatch_t match[10];
if (GIB_Argc() != 5) {
regex_t *reg;
int ofs, len;
regmatch_t match[10];
if (GIB_Argc () != 5) {
GIB_USAGE ("string regex options replacement");
return;
}
ofs = 0;
len = strlen (GIB_Argv(4));
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
GIB_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
else if (strchr(GIB_Argv(3), 'g'))
while (!regexec(reg, GIB_Argv(1)+ofs, 10, match, ofs > 0 ? REG_NOTBOL : 0) && match[0].rm_eo)
ofs += GIB_Regex_Apply_Match (match, GIB_Argd(1), ofs, GIB_Argv(4));
else if (!regexec(reg, GIB_Argv(1), 10, match, 0) && match[0].rm_eo)
GIB_Regex_Apply_Match (match, GIB_Argd(1), 0, GIB_Argv(4));
GIB_Return (GIB_Argv(1));
len = strlen (GIB_Argv (4));
if (!
(reg =
GIB_Regex_Compile (GIB_Argv (2),
REG_EXTENDED |
GIB_Regex_Translate_Options (GIB_Argv (3)))))
GIB_Error ("regex", "%s: %s", GIB_Argv (0), GIB_Regex_Error ());
else if (strchr (GIB_Argv (3), 'g'))
while (!regexec
(reg, GIB_Argv (1) + ofs, 10, match, ofs > 0 ? REG_NOTBOL : 0)
&& match[0].rm_eo)
ofs +=
GIB_Regex_Apply_Match (match, GIB_Argd (1), ofs, GIB_Argv (4));
else if (!regexec (reg, GIB_Argv (1), 10, match, 0) && match[0].rm_eo)
GIB_Regex_Apply_Match (match, GIB_Argd (1), 0, GIB_Argv (4));
GIB_Return (GIB_Argv (1));
}
static void
GIB_Regex_Extract_f (void)
{
regex_t *reg;
regex_t *reg;
regmatch_t *match;
int i;
char o;
if (GIB_Argc() != 4) {
int i;
char o;
if (GIB_Argc () != 4) {
GIB_USAGE ("string regex options");
return;
} else if (!GIB_CanReturn ())
return;
match = calloc (32, sizeof(regmatch_t));
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
GIB_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
else if (!regexec(reg, GIB_Argv(1), 32, match, 0) && match[0].rm_eo) {
match = calloc (32, sizeof (regmatch_t));
if (!
(reg =
GIB_Regex_Compile (GIB_Argv (2),
REG_EXTENDED |
GIB_Regex_Translate_Options (GIB_Argv (3)))))
GIB_Error ("regex", "%s: %s", GIB_Argv (0), GIB_Regex_Error ());
else if (!regexec (reg, GIB_Argv (1), 32, match, 0) && match[0].rm_eo) {
dsprintf (GIB_Return (0), "%lu", (unsigned long) match[0].rm_eo);
for (i = 0; i < 32; i++) {
if (match[i].rm_so != -1) {
o = GIB_Argv(1)[match[i].rm_eo];
GIB_Argv(1)[match[i].rm_eo] = 0;
GIB_Return (GIB_Argv(1)+match[i].rm_so);
GIB_Argv(1)[match[i].rm_eo] = o;
o = GIB_Argv (1)[match[i].rm_eo];
GIB_Argv (1)[match[i].rm_eo] = 0;
GIB_Return (GIB_Argv (1) + match[i].rm_so);
GIB_Argv (1)[match[i].rm_eo] = o;
}
}
}
@ -520,48 +565,57 @@ static void
GIB_Thread_Create_f (void)
{
gib_function_t *f;
if (GIB_Argc() < 2)
if (GIB_Argc () < 2)
GIB_USAGE ("function [arg1 arg2 ...]");
else if (!(f = GIB_Function_Find (GIB_Argv(1))))
GIB_Error ("function", "%s: no function named '%s' exists.", GIB_Argv(0), GIB_Argv(1));
else if (!(f = GIB_Function_Find (GIB_Argv (1))))
GIB_Error ("function", "%s: no function named '%s' exists.",
GIB_Argv (0), GIB_Argv (1));
else {
gib_thread_t *thread = GIB_Thread_New ();
GIB_Function_Execute (thread->cbuf, f, cbuf_active->args->argv+1, cbuf_active->args->argc-1);
GIB_Function_Execute (thread->cbuf, f, cbuf_active->args->argv + 1,
cbuf_active->args->argc - 1);
GIB_Thread_Add (thread);
if (GIB_CanReturn ())
dsprintf (GIB_Return(0), "%lu", thread->id);
dsprintf (GIB_Return (0), "%lu", thread->id);
}
}
static void
GIB_Thread_Kill_f (void)
{
if (GIB_Argc() != 2)
if (GIB_Argc () != 2)
GIB_USAGE ("id");
else {
gib_thread_t *thread;
cbuf_t *cur;
unsigned long int id = strtoul (GIB_Argv(1), 0, 10);
cbuf_t *cur;
unsigned long int id = strtoul (GIB_Argv (1), 0, 10);
thread = GIB_Thread_Find (id);
if (!thread) {
GIB_Error ("thread", "%s: thread %lu does not exist.", GIB_Argv(0), id);
GIB_Error ("thread", "%s: thread %lu does not exist.", GIB_Argv (0),
id);
return;
}
thread->trash = true;
// Set error condition on the top of the stack so the thread will exit if currently running
for (cur = thread->cbuf; cur->down && cur->down->state != CBUF_STATE_JUNK; cur = cur->down);
// Set error condition on the top of the stack so the thread will exit
// if currently running
for (cur = thread->cbuf;
cur->down && cur->down->state != CBUF_STATE_JUNK; cur = cur->down);
cur->state = CBUF_STATE_ERROR;
GIB_DATA(cur)->done = true;
GIB_DATA (cur)->done = true;
}
}
static void
GIB_Thread_List_f (void)
{
if (GIB_Argc() != 1)
if (GIB_Argc () != 1)
GIB_USAGE ("");
else if (GIB_CanReturn()) {
else if (GIB_CanReturn ()) {
gib_thread_t *cur;
for (cur = gib_threads; cur; cur = cur->next)
dsprintf (GIB_Return (0), "%lu", cur->id);
}
@ -571,35 +625,36 @@ static void
GIB_Event_Register_f (void)
{
gib_function_t *func;
if (GIB_Argc() != 3)
if (GIB_Argc () != 3)
GIB_USAGE ("event function");
else if (!(func = GIB_Function_Find (GIB_Argv(2))) && GIB_Argv(2)[0])
GIB_Error ("function", "Function %s not found.", GIB_Argv(2));
else if (GIB_Event_Register (GIB_Argv(1), func))
GIB_Error ("event", "Event %s not found.", GIB_Argv(1));
else if (!(func = GIB_Function_Find (GIB_Argv (2))) && GIB_Argv (2)[0])
GIB_Error ("function", "Function %s not found.", GIB_Argv (2));
else if (GIB_Event_Register (GIB_Argv (1), func))
GIB_Error ("event", "Event %s not found.", GIB_Argv (1));
}
/* File access */
int (*GIB_File_Transform_Path) (dstring_t *path) = NULL;
int (*GIB_File_Transform_Path) (dstring_t * path) = NULL;
static int
GIB_File_Transform_Path_Null (dstring_t *path)
GIB_File_Transform_Path_Null (dstring_t * path)
{
char *s;
char *s;
// Convert backslash to forward slash
for (s = strchr(path->str, '\\'); s; s = strchr (s, '\\'))
for (s = strchr (path->str, '\\'); s; s = strchr (s, '\\'))
*s = '/';
return 0;
}
static int
GIB_File_Transform_Path_Secure (dstring_t *path)
GIB_File_Transform_Path_Secure (dstring_t * path)
{
char *s /* , e_dir[MAX_OSPATH] */;
for (s = strchr(path->str, '\\'); s; s = strchr (s, '\\'))
char *s /* , e_dir[MAX_OSPATH] */ ;
for (s = strchr (path->str, '\\'); s; s = strchr (s, '\\'))
*s = '/';
if (Sys_PathType (path->str) != PATHTYPE_RELATIVE_BELOW)
return -1;
@ -610,13 +665,13 @@ GIB_File_Transform_Path_Secure (dstring_t *path)
dstring_insertstr (path, 0, fs_userpath->string);
return 0;
}
static void
GIB_File_Read_f (void)
{
QFile *file;
char *path;
int len;
int len;
dstring_t *ret;
if (GIB_Argc () != 2) {
@ -624,13 +679,12 @@ GIB_File_Read_f (void)
return;
}
if (!*GIB_Argv (1)) {
GIB_Error ("file",
"%s: null filename provided", GIB_Argv(0));
GIB_Error ("file", "%s: null filename provided", GIB_Argv (0));
return;
}
if (GIB_File_Transform_Path (GIB_Argd(1))) {
if (GIB_File_Transform_Path (GIB_Argd (1))) {
GIB_Error ("access",
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
"%s: access to %s denied", GIB_Argv (0), GIB_Argv (1));
return;
}
if (!(ret = GIB_Return (0)))
@ -639,7 +693,7 @@ GIB_File_Read_f (void)
file = Qopen (path, "r");
if (file) {
len = Qfilesize (file);
ret->size = len+1;
ret->size = len + 1;
dstring_adjust (ret);
Qread (file, ret->str, len);
ret->str[len] = 0;
@ -647,7 +701,8 @@ GIB_File_Read_f (void)
}
if (!file) {
GIB_Error ("file",
"%s: could not read %s: %s", GIB_Argv(0), path, strerror (errno));
"%s: could not read %s: %s", GIB_Argv (0), path,
strerror (errno));
return;
}
}
@ -657,25 +712,25 @@ GIB_File_Write_f (void)
{
QFile *file;
char *path;
if (GIB_Argc () != 3) {
GIB_USAGE ("file data");
return;
}
if (!*GIB_Argv(1)) {
GIB_Error ("file",
"%s: null filename provided", GIB_Argv(0));
if (!*GIB_Argv (1)) {
GIB_Error ("file", "%s: null filename provided", GIB_Argv (0));
return;
}
if (GIB_File_Transform_Path (GIB_Argd(1))) {
if (GIB_File_Transform_Path (GIB_Argd (1))) {
GIB_Error ("access",
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
"%s: access to %s denied", GIB_Argv (0), GIB_Argv (1));
return;
}
path = GIB_Argv(1);
path = GIB_Argv (1);
if (!(file = Qopen (path, "w"))) {
GIB_Error ("file",
"%s: could not open %s for writing: %s", GIB_Argv(0), path, strerror (errno));
"%s: could not open %s for writing: %s", GIB_Argv (0), path,
strerror (errno));
return;
}
Qprintf (file, "%s", GIB_Argv (2));
@ -687,37 +742,39 @@ GIB_File_Find_f (void)
{
DIR *directory;
struct dirent *entry;
const char *path, *glob = 0;
char *s;
const char *path, *glob = 0;
char *s;
if (GIB_Argc () != 2) {
GIB_USAGE ("glob");
return;
}
if (GIB_File_Transform_Path (GIB_Argd(1))) {
if (GIB_File_Transform_Path (GIB_Argd (1))) {
GIB_Error ("access",
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
"%s: access to %s denied", GIB_Argv (0), GIB_Argv (1));
return;
}
path = GIB_Argv(1);
path = GIB_Argv (1);
s = strrchr (path, '/');
if (!s) { // No slash in path
glob = path; // The glob is the entire argument
path = "."; // The path is the current directory
} else if (s == path) // Unix filesystem root (carne only)
if (!s) { // No slash in path
glob = path; // The glob is the entire argument
path = "."; // The path is the current directory
} else if (s == path) // Unix filesystem root (carne only)
path = "/";
else {
*s = 0; // Split the string at the final slash
glob = s+1;
*s = 0; // Split the string at the final slash
glob = s + 1;
}
directory = opendir (path);
if (!directory) {
GIB_Error ("file",
"%s: could not open directory %s: %s", GIB_Argv(0), path, strerror (errno));
"%s: could not open directory %s: %s", GIB_Argv (0), path,
strerror (errno));
return;
}
while ((entry = readdir (directory)))
if (strcmp (entry->d_name, ".") && strcmp (entry->d_name, "..") && !fnmatch (glob, entry->d_name, 0))
if (strcmp (entry->d_name, ".") && strcmp (entry->d_name, "..")
&& !fnmatch (glob, entry->d_name, 0))
GIB_Return (entry->d_name);
closedir (directory);
}
@ -725,88 +782,92 @@ GIB_File_Find_f (void)
static void
GIB_File_Move_f (void)
{
char *path1, *path2;
char *path1, *path2;
if (GIB_Argc () != 3) {
GIB_USAGE ("from_file to_file");
return;
}
if (GIB_File_Transform_Path (GIB_Argd(1))) {
if (GIB_File_Transform_Path (GIB_Argd (1))) {
GIB_Error ("access",
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
"%s: access to %s denied", GIB_Argv (0), GIB_Argv (1));
return;
}
if (GIB_File_Transform_Path (GIB_Argd(2))) {
if (GIB_File_Transform_Path (GIB_Argd (2))) {
GIB_Error ("access",
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(2));
"%s: access to %s denied", GIB_Argv (0), GIB_Argv (2));
return;
}
path1 = GIB_Argv(1);
path2 = GIB_Argv(2);
path1 = GIB_Argv (1);
path2 = GIB_Argv (2);
if (Qrename (path1, path2))
GIB_Error ("file", "%s: could not move %s to %s: %s", GIB_Argv(0), path1, path2, strerror(errno));
GIB_Error ("file", "%s: could not move %s to %s: %s", GIB_Argv (0),
path1, path2, strerror (errno));
}
static void
GIB_File_Delete_f (void)
{
char *path;
char *path;
if (GIB_Argc () != 2) {
GIB_USAGE ("file");
return;
}
if (GIB_File_Transform_Path (GIB_Argd(1))) {
if (GIB_File_Transform_Path (GIB_Argd (1))) {
GIB_Error ("access",
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
"%s: access to %s denied", GIB_Argv (0), GIB_Argv (1));
return;
}
path = GIB_Argv (1);
if (Qremove(path))
GIB_Error ("file", "%s: could not delete %s: %s", GIB_Argv(0), path, strerror(errno));
if (Qremove (path))
GIB_Error ("file", "%s: could not delete %s: %s", GIB_Argv (0), path,
strerror (errno));
}
static void
GIB_Range_f (void)
{
double i, inc, start, limit;
dstring_t *dstr;
double i, inc, start, limit;
dstring_t *dstr;
if (GIB_Argc () < 3 || GIB_Argc () > 4) {
GIB_USAGE ("lower upper [step]");
return;
}
limit = atof(GIB_Argv(2));
start = atof(GIB_Argv(1));
limit = atof (GIB_Argv (2));
start = atof (GIB_Argv (1));
if (GIB_Argc () == 4) {
if ((inc = atof(GIB_Argv(3))) == 0.0)
if ((inc = atof (GIB_Argv (3))) == 0.0)
return;
} else
inc = limit < start ? -1.0 : 1.0;
for (i = atof(GIB_Argv(1)); inc < 0 ? i >= limit : i <= limit; i += inc) {
if (!(dstr = GIB_Return(0)))
for (i = atof (GIB_Argv (1)); inc < 0 ? i >= limit : i <= limit; i += inc) {
if (!(dstr = GIB_Return (0)))
return;
dsprintf(dstr, "%.10g", i);
dsprintf (dstr, "%.10g", i);
}
}
static void
GIB_Print_f (void)
{
if (GIB_Argc() != 2) {
if (GIB_Argc () != 2) {
GIB_USAGE ("text");
return;
}
Sys_Printf ("%s", GIB_Argv(1));
Sys_Printf ("%s", GIB_Argv (1));
}
static void
GIB_Random_f (void)
{
dstring_t *ret;
if (GIB_Argc() != 1)
dstring_t *ret;
if (GIB_Argc () != 1)
GIB_USAGE ("");
else if ((ret = GIB_Return (0)))
dsprintf (ret, "%.10g", (double) rand ()/(double) RAND_MAX);
dsprintf (ret, "%.10g", (double) rand () / (double) RAND_MAX);
}
void
@ -817,7 +878,7 @@ GIB_Builtin_Init (qboolean sandbox)
GIB_File_Transform_Path = GIB_File_Transform_Path_Secure;
else
GIB_File_Transform_Path = GIB_File_Transform_Path_Null;
GIB_Builtin_Add ("function", GIB_Function_f);
GIB_Builtin_Add ("function::get", GIB_Function_Get_f);
GIB_Builtin_Add ("function::export", GIB_Function_Export_f);

View file

@ -32,8 +32,9 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] =
"$Id$";
#include <string.h>
#include <stdlib.h>
@ -51,52 +52,58 @@ static void
GIB_Execute_Generate_Composite (struct cbuf_s *cbuf)
{
cbuf_args_t *args = cbuf->args;
int i;
int i;
dstring_clearstr (GIB_DATA (cbuf)->arg_composite);
for (i = 0; i < args->argc; i++) {
// ->str could be moved by realloc when a dstring is resized
// so save the offset instead of the pointer
args->args[i] = (const char *) strlen (GIB_DATA (cbuf)->arg_composite->str);
args->args[i] =
(const char *) strlen (GIB_DATA (cbuf)->arg_composite->str);
dstring_appendstr (GIB_DATA (cbuf)->arg_composite, args->argv[i]->str);
dstring_appendstr (GIB_DATA (cbuf)->arg_composite, " ");
}
// Get rid of trailing space
GIB_DATA (cbuf)->arg_composite->str[strlen(GIB_DATA (cbuf)->arg_composite->str)-1] = 0;
GIB_DATA (cbuf)->arg_composite->
str[strlen (GIB_DATA (cbuf)->arg_composite->str) - 1] = 0;
for (i = 0; i < args->argc; i++)
// now that arg_composite is done we can add the pointer to the stored
// offsets and get valid pointers. This *should* be portable.
args->args[i] += (unsigned long int) GIB_DATA (cbuf)->arg_composite->str;
}
args->args[i] +=
(unsigned long int) GIB_DATA (cbuf)->arg_composite->str;
}
static void
GIB_Execute_Split_Array (cbuf_t *cbuf)
GIB_Execute_Split_Array (cbuf_t * cbuf)
{
gib_var_t *var;
gib_var_t *var;
unsigned int i;
int start = 0, end = 0;
char *c, *str = cbuf->args->argv[cbuf->args->argc-1]->str+1;
void *m = cbuf->args->argm[cbuf->args->argc-1];
int start = 0, end = 0;
char *c, *str = cbuf->args->argv[cbuf->args->argc - 1]->str + 1;
void *m = cbuf->args->argm[cbuf->args->argc - 1];
i = strlen(str)-1;
i = strlen (str) - 1;
if (str[i] == ']')
for (; i; i--)
if (str[i] == '[') {
str[i] = 0;
start = atoi (str+i+1);
if ((c = strchr (str+i+1, ':'))) {
start = atoi (str + i + 1);
if ((c = strchr (str + i + 1, ':'))) {
if (c[1] != ']')
end = atoi (c+1);
end = atoi (c + 1);
else
end = (int) ((unsigned int)~0>>1);
end = (int) ((unsigned int) ~0 >> 1);
} else
end = start+1;
end = start + 1;
break;
}
cbuf->args->argc--;
if (!(var = GIB_Var_Get_Complex (&GIB_DATA(cbuf)->locals, &GIB_DATA(cbuf)->globals, str, &i, false)))
if (!
(var =
GIB_Var_Get_Complex (&GIB_DATA (cbuf)->locals,
&GIB_DATA (cbuf)->globals, str, &i, false)))
return;
if (end < 0)
end += var->size;
@ -113,26 +120,26 @@ GIB_Execute_Split_Array (cbuf_t *cbuf)
Cbuf_ArgsAdd (cbuf->args, var->array[i]->str);
else
Cbuf_ArgsAdd (cbuf->args, "");
cbuf->args->argm[cbuf->args->argc-1] = m;
cbuf->args->argm[cbuf->args->argc - 1] = m;
}
}
static int
GIB_Execute_Prepare_Line (cbuf_t *cbuf, gib_tree_t *line)
GIB_Execute_Prepare_Line (cbuf_t * cbuf, gib_tree_t * line)
{
gib_tree_t *cur;
cbuf_args_t *args = cbuf->args;
unsigned int pos;
args->argc = 0;
for (cur = line->children; cur; cur = cur->next) {
if (cur->flags & TREE_CONCAT) {
pos = args->argv[args->argc-1]->size-1;
pos = args->argv[args->argc - 1]->size - 1;
if (cur->flags & TREE_P_EMBED) {
GIB_Process_Embedded (cur, cbuf->args);
} else
dstring_appendstr (args->argv[args->argc-1], cur->str);
dstring_appendstr (args->argv[args->argc - 1], cur->str);
} else {
pos = 0;
if (cur->flags & TREE_P_EMBED) {
@ -140,9 +147,10 @@ GIB_Execute_Prepare_Line (cbuf_t *cbuf, gib_tree_t *line)
GIB_Process_Embedded (cur, cbuf->args);
} else
Cbuf_ArgsAdd (args, cur->str);
args->argm[args->argc-1] = cur;
args->argm[args->argc - 1] = cur;
}
if (cur->delim == '(' && GIB_Process_Math (args->argv[args->argc-1], pos))
if (cur->delim == '('
&& GIB_Process_Math (args->argv[args->argc - 1], pos))
return -1;
if (cur->flags & TREE_ASPLIT)
GIB_Execute_Split_Array (cbuf);
@ -151,30 +159,34 @@ GIB_Execute_Prepare_Line (cbuf_t *cbuf, gib_tree_t *line)
}
int
GIB_Execute_For_Next (cbuf_t *cbuf)
GIB_Execute_For_Next (cbuf_t * cbuf)
{
unsigned int index;
gib_var_t *var;
struct gib_dsarray_s *array = GIB_DATA(cbuf)->stack.values+GIB_DATA(cbuf)->stack.p-1;
gib_var_t *var;
struct gib_dsarray_s *array =
GIB_DATA (cbuf)->stack.values + GIB_DATA (cbuf)->stack.p - 1;
if (array->size == 1) {
GIB_Buffer_Pop_Sstack (cbuf);
return 0;
}
array->size--;
var = GIB_Var_Get_Complex (&GIB_DATA(cbuf)->locals, &GIB_DATA(cbuf)->globals, array->dstrs[0]->str, &index, true);
var =
GIB_Var_Get_Complex (&GIB_DATA (cbuf)->locals,
&GIB_DATA (cbuf)->globals, array->dstrs[0]->str,
&index, true);
dstring_clearstr (var->array[index]);
dstring_appendstr (var->array[index], array->dstrs[array->size]->str);
return 1;
}
void
GIB_Execute (cbuf_t *cbuf)
GIB_Execute (cbuf_t * cbuf)
{
gib_buffer_data_t *g = GIB_DATA (cbuf);
gib_builtin_t *b;
gib_function_t *f;
int cond;
int cond;
if (!g->program)
return;
if (!g->ip)
@ -183,7 +195,10 @@ GIB_Execute (cbuf_t *cbuf)
if (GIB_Execute_Prepare_Line (cbuf, g->ip))
return;
if (g->ip->flags & TREE_COND) {
cond = g->ip->flags & TREE_NOT ? atoi (cbuf->args->argv[1]->str) : !atoi (cbuf->args->argv[1]->str);
cond =
g->ip->flags & TREE_NOT ? atoi (cbuf->args->argv[1]->
str) : !atoi (cbuf->args->
argv[1]->str);
if (cond)
g->ip = g->ip->jump;
} else if (g->ip->flags & TREE_FORNEXT) {
@ -200,25 +215,34 @@ GIB_Execute (cbuf_t *cbuf)
GIB_Buffer_Push_Sstack (cbuf);
} else
g->waitret = false;
if (cbuf->args->argc >= 2 && !strcmp (cbuf->args->argv[1]->str, "=") && ((gib_tree_t *)cbuf->args->argm[1])->delim == ' ') {
if (cbuf->args->argc >= 2 && !strcmp (cbuf->args->argv[1]->str, "=")
&& ((gib_tree_t *) cbuf->args->argm[1])->delim == ' ') {
unsigned int index;
gib_var_t *var = GIB_Var_Get_Complex (&g->locals, &g->globals, cbuf->args->argv[0]->str, &index, true);
GIB_Var_Assign (var, index, cbuf->args->argv+2, cbuf->args->argc-2);
}
else if ((b = GIB_Builtin_Find (cbuf->args->argv[0]->str))) {
gib_var_t *var =
GIB_Var_Get_Complex (&g->locals, &g->globals,
cbuf->args->argv[0]->str, &index,
true);
GIB_Var_Assign (var, index, cbuf->args->argv + 2,
cbuf->args->argc - 2);
} else if ((b = GIB_Builtin_Find (cbuf->args->argv[0]->str))) {
b->func ();
} else if ((f = GIB_Function_Find (cbuf->args->argv[0]->str))) {
cbuf_t *new = Cbuf_PushStack (&gib_interp);
GIB_Function_Execute (new, f, cbuf->args->argv, cbuf->args->argc);
cbuf_t *new = Cbuf_PushStack (&gib_interp);
GIB_Function_Execute (new, f, cbuf->args->argv,
cbuf->args->argc);
} else {
GIB_Execute_Generate_Composite (cbuf);
if (Cmd_Command (cbuf->args))
GIB_Error ("command", "No builtin, function, or console command named '%s' was found.", cbuf->args->argv[0]->str);
GIB_Error ("command",
"No builtin, function, or console command named '%s' was found.",
cbuf->args->argv[0]->str);
}
}
if (!(g->ip = g->ip->next)) // No more commands
if (!(g->ip = g->ip->next)) // No more commands
g->done = true;
if (cbuf->state) // Let the stack walker figure out what to do
if (cbuf->state) // Let the stack walker figure out what
// to do
return;
}
}

View file

@ -32,8 +32,9 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] =
"$Id$";
#include <stdlib.h>
#include <string.h>
@ -49,7 +50,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/gib_tree.h"
#include "QF/va.h"
hashtab_t *gib_functions = 0;
hashtab_t *gib_functions = 0;
/*
GIB_Function_New
@ -61,7 +62,8 @@ static gib_function_t *
GIB_Function_New (const char *name)
{
gib_function_t *new = calloc (1, sizeof (gib_function_t));
new->text = dstring_newstr();
new->text = dstring_newstr ();
new->name = strdup (name);
return new;
}
@ -72,20 +74,21 @@ GIB_Function_New (const char *name)
static const char *
GIB_Function_Get_Key (void *ele, void *ptr)
{
return ((gib_function_t *)ele)->name;
return ((gib_function_t *) ele)->name;
}
static void
GIB_Function_Free (void *ele, void *ptr)
{
gib_function_t *func = (gib_function_t *)ele;
gib_function_t *func = (gib_function_t *) ele;
dstring_delete (func->text);
free ((void *)func->name);
free ((void *) func->name);
if (func->program)
GIB_Tree_Free_Recursive (func->program);
if (func->script && !(--func->script->refs)) {
free ((void *)func->script->text);
free ((void *)func->script->file);
free ((void *) func->script->text);
free ((void *) func->script->file);
free (func->script);
}
free (func);
@ -99,23 +102,25 @@ GIB_Function_Free (void *ele, void *ptr)
hash if needed.
*/
void
GIB_Function_Define (const char *name, const char *text, gib_tree_t *program, gib_script_t *script, hashtab_t *globals)
GIB_Function_Define (const char *name, const char *text, gib_tree_t * program,
gib_script_t * script, hashtab_t * globals)
{
gib_function_t *func;
GIB_Tree_Ref (&program);
if (script)
script->refs++;
if (!gib_functions)
gib_functions = Hash_NewTable (1024, GIB_Function_Get_Key, GIB_Function_Free, 0);
gib_functions =
Hash_NewTable (1024, GIB_Function_Get_Key, GIB_Function_Free, 0);
func = Hash_Find(gib_functions, name);
func = Hash_Find (gib_functions, name);
if (func) {
dstring_clearstr (func->text);
GIB_Tree_Unref (&func->program);
if (func->script && !(--func->script->refs)) {
free ((void *)func->script->text);
free ((void *)func->script->file);
free ((void *) func->script->text);
free ((void *) func->script->file);
free (func->script);
}
} else {
@ -144,22 +149,23 @@ GIB_Function_Find (const char *name)
}
void
GIB_Function_Prepare_Args (cbuf_t *cbuf, dstring_t **args, unsigned int argc)
GIB_Function_Prepare_Args (cbuf_t * cbuf, dstring_t ** args, unsigned int argc)
{
static hashtab_t *zero = 0;
unsigned int i;
gib_var_t *var;
gib_var_t *var;
static char argss[] = "args";
var = GIB_Var_Get_Complex (&GIB_DATA(cbuf)->locals, &zero, argss, &i, true);
var =
GIB_Var_Get_Complex (&GIB_DATA (cbuf)->locals, &zero, argss, &i, true);
var->array = realloc (var->array, sizeof (dstring_t *) * argc);
memset (var->array+1, 0, (argc-1) * sizeof (dstring_t *));
memset (var->array + 1, 0, (argc - 1) * sizeof (dstring_t *));
var->size = argc;
for (i = 0; i < argc; i++) {
if (var->array[i])
dstring_clearstr(var->array[i]);
dstring_clearstr (var->array[i]);
else
var->array[i] = dstring_newstr();
var->array[i] = dstring_newstr ();
dstring_appendstr (var->array[i], args[i]->str);
}
}
@ -172,13 +178,14 @@ GIB_Function_Prepare_Args (cbuf_t *cbuf, dstring_t **args, unsigned int argc)
*/
void
GIB_Function_Execute (cbuf_t *cbuf, gib_function_t *func, dstring_t **args, unsigned int argc)
GIB_Function_Execute (cbuf_t * cbuf, gib_function_t * func, dstring_t ** args,
unsigned int argc)
{
GIB_Tree_Ref (&func->program);
if (func->script)
func->script->refs++;
GIB_Buffer_Set_Program (cbuf, func->program);
GIB_DATA(cbuf)->script = func->script;
GIB_DATA(cbuf)->globals = func->globals;
GIB_DATA (cbuf)->script = func->script;
GIB_DATA (cbuf)->globals = func->globals;
GIB_Function_Prepare_Args (cbuf, args, argc);
}

View file

@ -32,8 +32,9 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] =
"$Id$";
#include <string.h>
#include <stdlib.h>
@ -54,7 +55,8 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/cvar.h"
static void
GIB_Exec_Override_f (void) {
GIB_Exec_Override_f (void)
{
char *f;
int mark;
@ -69,18 +71,22 @@ GIB_Exec_Override_f (void) {
Sys_Printf ("couldn't exec %s\n", Cmd_Argv (1));
return;
}
if (!Cvar_Command() && (cmd_warncmd->int_val || (developer && developer->int_val)))
if (!Cvar_Command ()
&& (cmd_warncmd->int_val || (developer && developer->int_val)))
Sys_Printf ("execing %s\n", Cmd_Argv (1));
if (!strcmp (Cmd_Argv (1) + strlen (Cmd_Argv(1)) - 4, ".gib") || cbuf_active->interpreter == &gib_interp) {
if (!strcmp (Cmd_Argv (1) + strlen (Cmd_Argv (1)) - 4, ".gib")
|| cbuf_active->interpreter == &gib_interp) {
// GIB script, put it in a new buffer on the stack
cbuf_t *sub = Cbuf_PushStack (&gib_interp);
GIB_DATA(sub)->script = malloc (sizeof (gib_script_t));
GIB_DATA(sub)->script->file = strdup (Cmd_Argv(1));
GIB_DATA(sub)->script->text = strdup (f);
GIB_DATA(sub)->script->refs = 1;
cbuf_t *sub = Cbuf_PushStack (&gib_interp);
GIB_DATA (sub)->script = malloc (sizeof (gib_script_t));
GIB_DATA (sub)->script->file = strdup (Cmd_Argv (1));
GIB_DATA (sub)->script->text = strdup (f);
GIB_DATA (sub)->script->refs = 1;
Cbuf_AddText (sub, f);
if (gib_parse_error && cbuf_active->interpreter == &gib_interp)
GIB_Error ("parse", "%s: Parse error while executing %s.", Cmd_Argv(0), Cmd_Argv(1));
GIB_Error ("parse", "%s: Parse error while executing %s.",
Cmd_Argv (0), Cmd_Argv (1));
} else
Cbuf_InsertText (cbuf_active, f);
Hunk_FreeToLowMark (mark);
@ -90,7 +96,7 @@ void
GIB_Init (qboolean sandbox)
{
// Override the exec command with a GIB-aware one
if (Cmd_Exists("exec")) {
if (Cmd_Exists ("exec")) {
Cmd_RemoveCommand ("exec");
Cmd_AddCommand ("exec", GIB_Exec_Override_f, "Execute a script file.");
}

View file

@ -32,8 +32,8 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] = "$Id$";
#include <ctype.h>
#include <string.h>
@ -87,6 +87,7 @@ static char
GIB_Parse_Match_Dquote (const char *str, unsigned int *i)
{
unsigned int n = *i;
for ((*i)++; str[*i]; (*i)++) {
if (str[*i] == '\n')
break;
@ -100,8 +101,9 @@ GIB_Parse_Match_Dquote (const char *str, unsigned int *i)
char
GIB_Parse_Match_Brace (const char *str, unsigned int *i)
{
char c;
char c;
unsigned int n = *i;
for ((*i)++; str[*i]; (*i)++) {
if (str[*i] == '\"') {
if ((c = GIB_Parse_Match_Dquote (str, i)))
@ -110,7 +112,7 @@ GIB_Parse_Match_Brace (const char *str, unsigned int *i)
if ((c = GIB_Parse_Match_Brace (str, i)))
return c;
} else if (str[*i] == '}')
return 0;
return 0;
}
*i = n;
return '{';
@ -119,8 +121,9 @@ GIB_Parse_Match_Brace (const char *str, unsigned int *i)
char
GIB_Parse_Match_Paren (const char *str, unsigned int *i)
{
char c;
char c;
unsigned int n = *i;
for ((*i)++; str[*i]; (*i)++) {
if (str[*i] == '(') {
if ((c = GIB_Parse_Match_Paren (str, i)))
@ -138,12 +141,13 @@ GIB_Parse_Match_Paren (const char *str, unsigned int *i)
char
GIB_Parse_Match_Backtick (const char *str, unsigned int *i)
{
char c;
char c;
unsigned int n = *i;
for ((*i)++; str[*i]; (*i)++) {
if (str[*i] == '`')
return 0;
else if (str[*i] == '\"') { // Skip over strings as usual
else if (str[*i] == '\"') { // Skip over strings as usual
if ((c = GIB_Parse_Match_Dquote (str, i)))
return c;
}
@ -155,8 +159,9 @@ GIB_Parse_Match_Backtick (const char *str, unsigned int *i)
char
GIB_Parse_Match_Index (const char *str, unsigned int *i)
{
char c;
char c;
unsigned int n = *i;
for ((*i)++; str[*i]; (*i)++) {
if (str[*i] == '[' && (c = GIB_Parse_Match_Index (str, i)))
return c;
@ -170,12 +175,13 @@ GIB_Parse_Match_Index (const char *str, unsigned int *i)
char
GIB_Parse_Match_Var (const char *str, unsigned int *i)
{
char c;
char c;
(*i)++;
if (str[*i] == '{' && (c = GIB_Parse_Match_Brace (str, i)))
return c;
else {
for (; isalnum((byte) str[*i]) || str[*i] == '_'; (*i)++);
for (; isalnum ((byte) str[*i]) || str[*i] == '_'; (*i)++);
if (str[*i] == '[') {
if ((c = GIB_Parse_Match_Index (str, i)))
return c;
@ -185,7 +191,7 @@ GIB_Parse_Match_Var (const char *str, unsigned int *i)
return 0;
}
qboolean gib_parse_error;
qboolean gib_parse_error;
unsigned int gib_parse_error_pos;
const char *gib_parse_error_msg;
@ -212,19 +218,20 @@ GIB_Parse_ErrorPos (void)
// FIXME: Concatenation in stupid circumstances should generate errors
static gib_tree_t *
GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_tree_flags_t flags, gib_tree_t **embedded)
GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs,
gib_tree_flags_t flags, gib_tree_t ** embedded)
{
char c, delim, *str;
char c, delim, *str;
unsigned int tstart, start;
gib_tree_t *nodes = 0, *cur, *new, *embs = 0, *tmp;
gib_tree_t **node = &nodes;
qboolean cat = false;
qboolean cat = false;
gib_parse_error = false;
while (1) {
// Skip whitespace
while (program[*i] != '\n' && isspace((byte)program[*i]))
while (program[*i] != '\n' && isspace ((byte) program[*i]))
(*i)++;
// Check for concatenation, skip comma and any more whitespace
if (program[*i] == ',') {
@ -256,7 +263,9 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_t
// Find the end of a "normal" token
delim = ' ';
tstart = *i;
for (;program[*i] && !isspace((byte)program[*i]) && program[*i] != ',' && program[*i] != ';'; (*i)++) {
for (;
program[*i] && !isspace ((byte) program[*i])
&& program[*i] != ',' && program[*i] != ';'; (*i)++) {
if (program[*i] == '{') {
if ((c = GIB_Parse_Match_Brace (program, i)))
goto ERROR;
@ -266,9 +275,10 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_t
} else if (program[*i] == '`') {
if ((c = GIB_Parse_Match_Backtick (program, i)))
goto ERROR;
// Handle comments
} else if (program[*i] == '/' && program[*i+1] == '/') {
for((*i) += 2; program[*i] && program[*i] != '\n'; (*i)++);
// Handle comments
} else if (program[*i] == '/' && program[*i + 1] == '/') {
for ((*i) += 2; program[*i] && program[*i] != '\n';
(*i)++);
goto DONE;
}
}
@ -278,20 +288,24 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_t
cur->start = start + pofs;
cur->end = *i + pofs;
cur->delim = delim;
str = calloc (*i - tstart + 1, sizeof(char));
memcpy (str, program+tstart, *i - tstart);
// Don't bother parsing further if we are concatenating, as the resulting
str = calloc (*i - tstart + 1, sizeof (char));
memcpy (str, program + tstart, *i - tstart);
// Don't bother parsing further if we are concatenating, as the
// resulting
// string would differ from the parsed program.
if (cur->delim == '{' && !cat) {
// Try to parse sub-program
if (!(new = GIB_Parse_Lines (str, tstart+pofs, flags)))
if (!(new = GIB_Parse_Lines (str, tstart + pofs, flags)))
goto ERROR;
cur->children = new;
// Check for embedded commands/variables
// Check for embedded commands/variables
} else if (cur->delim == ' ' || cur->delim == '(') {
if (!(cur->children = GIB_Parse_Embedded (str, tstart+pofs, flags, &new))) {
// There could be no embedded elements, so check for a real error
if (!
(cur->children =
GIB_Parse_Embedded (str, tstart + pofs, flags, &new))) {
// There could be no embedded elements, so check for a real
// error
if (gib_parse_error)
goto ERROR;
} else {
@ -309,7 +323,7 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_t
if (cur->delim == ' ' && str[0] == '@' && !cat) {
cur->flags |= TREE_ASPLIT;
}
// We can handle escape characters now
// We can handle escape characters now
} else if (cur->delim == '\"')
GIB_Process_Escapes (str);
cur->str = str;
@ -326,32 +340,40 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_t
(*i)++;
node = &cur->next;
}
DONE:
DONE:
*embedded = embs;
return nodes;
ERROR:
ERROR:
if (c)
GIB_Parse_Error (va("Could not find match for '%c'.", c), *i+pofs);
GIB_Parse_Error (va ("Could not find match for '%c'.", c), *i + pofs);
if (nodes)
GIB_Tree_Free_Recursive (nodes);
return 0;
}
static gib_tree_t *
GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
GIB_Parse_Semantic_Preprocess (gib_tree_t * line)
{
gib_tree_t *p, *start = line;
unsigned int flags = line->flags;
while (!strcmp (line->children->str, "if") || !strcmp (line->children->str, "ifnot")) {
while (!strcmp (line->children->str, "if")
|| !strcmp (line->children->str, "ifnot")) {
// Sanity checking
if (!line->children->next || !line->children->next->next) {
GIB_Parse_Error ("Not enough arguments to 'if' statement.", line->start);
GIB_Parse_Error ("Not enough arguments to 'if' statement.",
line->start);
return line;
} else if (!line->children->next->next->children || line->children->next->next->delim != '{') {
GIB_Parse_Error ("First program block in 'if' statement not enclosed in braces or invalid.", line->start);
} else if (!line->children->next->next->children
|| line->children->next->next->delim != '{') {
GIB_Parse_Error
("First program block in 'if' statement not enclosed in braces or invalid.",
line->start);
return line;
} else if (line->flags & TREE_EMBED) {
GIB_Parse_Error ("'if' statements may not be used in embedded commands.", line->start);
GIB_Parse_Error
("'if' statements may not be used in embedded commands.",
line->start);
return line;
}
// Set conditional flag
@ -364,17 +386,21 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
line->next = line->children->next->next->children;
line->children->next->next->children = 0;
// Find end of subprogram
while (line->next) line = line->next;
while (line->next)
line = line->next;
line->next = GIB_Tree_New (flags | TREE_END);
line = line->next;
// Mark jump point
p->jump = line;
line->flags |= TREE_END; // Last instruction of subprogram
line->flags |= TREE_END; // Last instruction of subprogram
// Handle "else"
if (p->children->next->next->next && !strcmp (p->children->next->next->next->str, "else")) {
if (p->children->next->next->next
&& !strcmp (p->children->next->next->next->str, "else")) {
// Sanity checking
if (!p->children->next->next->next->next) {
GIB_Parse_Error ("'if' statement contains 'else' but no secondary program block or command.", line->start);
GIB_Parse_Error
("'if' statement contains 'else' but no secondary program block or command.",
line->start);
return line;
}
// Is "else" followed by a subprogram?
@ -382,7 +408,8 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
// Move subprogram inline
line->next = p->children->next->next->next->next->children;
p->children->next->next->next->next->children = 0;
while (line->next) line = line->next;
while (line->next)
line = line->next;
} else {
// Push rest of tokens into a new line
line->next = GIB_Tree_New (flags);
@ -390,7 +417,9 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
p->children->next->next->next->next = 0;
line = line->next;
}
} else break; // Don't touch if statements in the sub program
} else
break; // Don't touch if statements in the sub
// program
}
// Now we know our exit point, set it on all our ending instructions
while (start) {
@ -405,13 +434,19 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
if (!strcmp (line->children->str, "while")) {
// Sanity checks
if (!line->children->next || !line->children->next->next) {
GIB_Parse_Error ("Not enough arguments to 'while' statement.", line->start);
GIB_Parse_Error ("Not enough arguments to 'while' statement.",
line->start);
return line;
} else if (!line->children->next->next->children || line->children->next->next->delim != '{') {
GIB_Parse_Error ("Program block in 'while' statement not enclosed in braces or invalid.", line->start);
} else if (!line->children->next->next->children
|| line->children->next->next->delim != '{') {
GIB_Parse_Error
("Program block in 'while' statement not enclosed in braces or invalid.",
line->start);
return line;
} else if (line->flags & TREE_EMBED) {
GIB_Parse_Error ("'while' statements may not be used in embedded commands.", line->start);
GIB_Parse_Error
("'while' statements may not be used in embedded commands.",
line->start);
return line;
}
// Set conditional flag
@ -432,16 +467,23 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
p->jump = line;
} else if (!strcmp (line->children->str, "for")) {
gib_tree_t *tmp;
// Sanity checks
if (!line->children->next || !line->children->next->next || strcmp (line->children->next->next->str, "in") || !line->children->next->next->next || !line->children->next->next->next->next) {
if (!line->children->next || !line->children->next->next
|| strcmp (line->children->next->next->str, "in")
|| !line->children->next->next->next
|| !line->children->next->next->next->next) {
GIB_Parse_Error ("Malformed 'for' statement.", line->start);
return line;
}
// Find last token in line (contains program block)
for (tmp = line->children->next->next->next->next; tmp->next; tmp = tmp->next);
for (tmp = line->children->next->next->next->next; tmp->next;
tmp = tmp->next);
// More sanity
if (tmp->delim != '{' || !tmp->children) {
GIB_Parse_Error ("Program block in 'for' statement not enclosed in braces or invalid.", line->start);
GIB_Parse_Error
("Program block in 'for' statement not enclosed in braces or invalid.",
line->start);
return line;
}
p = line;
@ -457,19 +499,19 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
line = line->next;
// Mark jump point out of loop
p->jump = line;
}
}
return line;
}
}
gib_tree_t *
GIB_Parse_Lines (const char *program, unsigned int pofs, gib_tree_flags_t flags)
{
unsigned int i = 0, lstart;
gib_tree_t *lines = 0, *cur, *tokens, **line = &lines, *embs;
char *str;
char *str;
while (1) {
while (isspace((byte)program[i]) || program[i] == ';')
while (isspace ((byte) program[i]) || program[i] == ';')
i++;
if (!program[i])
break;
@ -479,8 +521,8 @@ GIB_Parse_Lines (const char *program, unsigned int pofs, gib_tree_flags_t flags)
// Link it in
cur = GIB_Tree_New (flags);
cur->delim = '\n';
str = calloc (i - lstart + 1, sizeof(char));
memcpy (str, program+lstart, i - lstart);
str = calloc (i - lstart + 1, sizeof (char));
memcpy (str, program + lstart, i - lstart);
cur->str = str;
cur->start = lstart + pofs;
cur->end = i + pofs;
@ -500,48 +542,51 @@ GIB_Parse_Lines (const char *program, unsigned int pofs, gib_tree_flags_t flags)
goto ERROR;
}
return lines;
ERROR:
ERROR:
if (lines)
GIB_Tree_Free_Recursive (lines);
return 0;
}
gib_tree_t *
GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_flags_t flags, gib_tree_t **embedded)
GIB_Parse_Embedded (const char *program, unsigned int pofs,
gib_tree_flags_t flags, gib_tree_t ** embedded)
{
unsigned int i, n, t;
char c, d, *str;
char c, d, *str;
gib_tree_t *lines = 0, **line = &lines, *cur, *tokens, *emb, *tmp;
unsigned int start, end;
gib_parse_error = false;
*embedded = 0;
for (i = 0; program[i]; i++) {
if (program[i] == '`' || (program[i] == '$' && program[i+1] == '(')) {
if (program[i] == '`' || (program[i] == '$' && program[i + 1] == '(')) {
// Extract the embedded command
start = i;
if (program[i] == '`') {
n = i+1;
n = i + 1;
if ((c = GIB_Parse_Match_Backtick (program, &i)))
goto ERROR;
} else {
n = ++i+1;
n = ++i + 1;
if ((c = GIB_Parse_Match_Paren (program, &i)))
goto ERROR;
}
end = i+1;
end = i + 1;
// Construct the actual line to be executed
cur = GIB_Tree_New (flags | TREE_EMBED);
cur->delim = '`';
str = calloc (i - n + 1, sizeof (char));
memcpy (str, program+n, i - n);
memcpy (str, program + n, i - n);
cur->str = str;
cur->start = start + pofs;
cur->end = end + pofs;
c = 0;
t = 0;
if (!(tokens = GIB_Parse_Tokens (cur->str, &t, start + pofs, flags, &emb)))
if (!
(tokens =
GIB_Parse_Tokens (cur->str, &t, start + pofs, flags, &emb)))
goto ERROR;
cur->children = tokens;
GIB_Parse_Semantic_Preprocess (cur)->next = *embedded;
@ -555,7 +600,8 @@ GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_flags_t fla
*embedded = emb;
} else
*embedded = cur;
// Create a representative child node for GIB_Process_Embedded to use
// Create a representative child node for GIB_Process_Embedded to
// use
cur = GIB_Tree_New (flags | TREE_EMBED);
cur->delim = '`';
// Save start/end indices
@ -563,27 +609,28 @@ GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_flags_t fla
cur->end = end;
*line = cur;
line = &cur->next;
// Check for variable substitution
// Check for variable substitution
} else if (program[i] == '$' || program[i] == '#') {
// Extract variable name
start = i;
end = 0;
d = program[i];
if (program[i+1] == '{') {
n = i+2;
if (program[i + 1] == '{') {
n = i + 2;
end++;
} else
n = i+1;
n = i + 1;
if ((c = GIB_Parse_Match_Var (program, &i)))
goto ERROR;
end += i;
cur = GIB_Tree_New (flags | TREE_EMBED);
cur->delim = d;
str = calloc (i - n + 1, sizeof(char));
memcpy (str, program+n, i - n);
str = calloc (i - n + 1, sizeof (char));
memcpy (str, program + n, i - n);
cur->str = str;
// Can we use the name as is, or must processing be done at runtime?
// Can we use the name as is, or must processing be done at
// runtime?
if (strchr (str, '$') || strchr (str, '#'))
cur->flags |= TREE_P_EMBED;
// Save start/end indices
@ -592,12 +639,12 @@ GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_flags_t fla
*line = cur;
line = &cur->next;
// Don't skip anything important
if (program[n-1] != '{')
if (program[n - 1] != '{')
i--;
}
}
return lines;
ERROR:
ERROR:
if (c)
GIB_Parse_Error (va ("Could not find match for '%c'.", c), i + pofs);
if (lines)

View file

@ -32,8 +32,8 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] = "$Id$";
#include <string.h>
#include <ctype.h>
@ -52,13 +52,14 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "exp.h"
static int
GIB_Process_Variable (dstring_t *token, unsigned int *i)
GIB_Process_Variable (dstring_t * token, unsigned int *i)
{
hashtab_t *one = GIB_DATA(cbuf_active)->locals, *two = GIB_DATA(cbuf_active)->globals;
hashtab_t *one = GIB_DATA (cbuf_active)->locals, *two =
GIB_DATA (cbuf_active)->globals;
unsigned int n = *i, j, k, start = *i, index = 0, len, len2;
gib_var_t *var = 0;
cvar_t *cvar;
char c;
gib_var_t *var = 0;
cvar_t *cvar;
char c;
const char *str;
(*i)++;
@ -70,7 +71,8 @@ GIB_Process_Variable (dstring_t *token, unsigned int *i)
n += 2;
len = 1;
} else {
for (; isalnum((byte) token->str[*i]) || token->str[*i] == '_'; (*i)++);
for (; isalnum ((byte) token->str[*i]) || token->str[*i] == '_';
(*i)++);
if (token->str[*i] == '[') {
if ((c = GIB_Parse_Match_Index (token->str, i))) {
GIB_Error ("Parse", "Could not find match for %c.", c);
@ -89,25 +91,26 @@ GIB_Process_Variable (dstring_t *token, unsigned int *i)
if (GIB_Process_Variable (token, &n))
return -1;
index = 0;
if (n && token->str[n-1] == ']')
for (j = n-1; j; j--)
if (n && token->str[n - 1] == ']')
for (j = n - 1; j; j--)
if (token->str[j] == '[') {
index = atoi (token->str+j+1);
index = atoi (token->str + j + 1);
token->str[j] = 0;
}
if ((var = GIB_Var_Get (one, two, token->str+k)) && index < var->size && var->array[index]) {
if ((var = GIB_Var_Get (one, two, token->str + k)) && index < var->size
&& var->array[index]) {
if (token->str[start] == '#')
str = va("%u", var->size - index);
str = va ("%u", var->size - index);
else
str = var->array[index]->str;
} else if (token->str[start] == '#')
str = "0";
else if ((cvar = Cvar_FindVar (token->str+k)))
else if ((cvar = Cvar_FindVar (token->str + k)))
str = cvar->string;
else
str = "";
token->str[n] = c;
len += n-start;
len += n - start;
len2 = strlen (str);
dstring_replace (token, start, len, str, len2);
*i = start + len2 - 1;
@ -117,91 +120,105 @@ GIB_Process_Variable (dstring_t *token, unsigned int *i)
int
GIB_Process_Math (struct dstring_s *token, unsigned int i)
{
double value;
value = EXP_Evaluate (token->str+i);
double value;
value = EXP_Evaluate (token->str + i);
if (EXP_ERROR) {
GIB_Error ("math", "Expression \"%s\" caused an error:\n%s", token->str, EXP_GetErrorMsg());
GIB_Error ("math", "Expression \"%s\" caused an error:\n%s", token->str,
EXP_GetErrorMsg ());
return -1;
} else {
token->str[i] = 0;
token->size = i+1;
token->size = i + 1;
dasprintf (token, "%.10g", value);
}
return 0;
}
int
GIB_Process_Embedded (gib_tree_t *node, cbuf_args_t *args)
GIB_Process_Embedded (gib_tree_t * node, cbuf_args_t * args)
{
unsigned int n, j;
gib_var_t *var;
cvar_t *cvar;
gib_var_t *var;
cvar_t *cvar;
gib_tree_t *cur;
unsigned int index, prev = 0;
const char *str = node->str;
for (cur = node->children; cur; cur = cur->next) {
if (cur->start > prev)
dstring_appendsubstr (args->argv[args->argc-1], str+prev, cur->start - prev);
dstring_appendsubstr (args->argv[args->argc - 1], str + prev,
cur->start - prev);
prev = cur->end;
if (!cur->str) {
struct gib_dsarray_s *retvals = GIB_DATA(cbuf_active)->stack.values+GIB_DATA(cbuf_active)->stack.p-1;
struct gib_dsarray_s *retvals =
GIB_DATA (cbuf_active)->stack.values +
GIB_DATA (cbuf_active)->stack.p - 1;
if (retvals->size != 1) {
if (!*args->argv[args->argc-1]->str)
if (!*args->argv[args->argc - 1]->str)
args->argc--;
for (j = 0; j < retvals->size; j++) {
Cbuf_ArgsAdd (args, retvals->dstrs[j]->str);
args->argm[args->argc-1] = node;
args->argm[args->argc - 1] = node;
}
if (str[prev] && retvals->size) // Still more stuff left?
if (str[prev] && retvals->size) // Still more stuff left?
Cbuf_ArgsAdd (args, "");
} else
dstring_appendstr (args->argv[args->argc-1], retvals->dstrs[0]->str);
dstring_appendstr (args->argv[args->argc - 1],
retvals->dstrs[0]->str);
GIB_Buffer_Pop_Sstack (cbuf_active);
} else if (cur->flags & TREE_P_EMBED) {
n = args->argv[args->argc-1]->size-1;
n = args->argv[args->argc - 1]->size - 1;
if (cur->delim == '$')
dstring_appendstr (args->argv[args->argc-1], "${");
dstring_appendstr (args->argv[args->argc - 1], "${");
else
dstring_appendstr (args->argv[args->argc-1], "#{");
dstring_appendstr (args->argv[args->argc-1], cur->str);
dstring_appendstr (args->argv[args->argc-1], "}");
if (GIB_Process_Variable (args->argv[args->argc-1], &n))
dstring_appendstr (args->argv[args->argc - 1], "#{");
dstring_appendstr (args->argv[args->argc - 1], cur->str);
dstring_appendstr (args->argv[args->argc - 1], "}");
if (GIB_Process_Variable (args->argv[args->argc - 1], &n))
return -1;
} else if ((var = GIB_Var_Get_Complex (&GIB_DATA(cbuf_active)->locals, &GIB_DATA(cbuf_active)->globals, (char *)cur->str, &index, false))) {
} else
if ((var =
GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->locals,
&GIB_DATA (cbuf_active)->globals,
(char *) cur->str, &index, false))) {
if (cur->delim == '$')
dstring_appendstr (args->argv[args->argc-1], var->array[index]->str);
dstring_appendstr (args->argv[args->argc - 1],
var->array[index]->str);
else
dasprintf (args->argv[args->argc-1], "%u", var->size - index);
dasprintf (args->argv[args->argc - 1], "%u", var->size - index);
} else if (cur->delim == '#')
dstring_appendstr (args->argv[args->argc-1], "0");
dstring_appendstr (args->argv[args->argc - 1], "0");
else if ((cvar = Cvar_FindVar (cur->str)))
dstring_appendstr (args->argv[args->argc-1], cvar->string);
dstring_appendstr (args->argv[args->argc - 1], cvar->string);
}
if (str[prev])
dstring_appendstr (args->argv[args->argc-1], str+prev);
dstring_appendstr (args->argv[args->argc - 1], str + prev);
return 0;
}
void
GIB_Process_Escapes (char *str)
{
int i, j;
char c;
int i, j;
char c;
for (i = 0, j = 0; str[i]; j++) {
if (str[i] == '\\') {
i++;
if (isdigit ((byte) str[i]) &&
isdigit ((byte) str[i+1]) &&
isdigit ((byte) str[i+2])) {
unsigned int num;
if ((num = 100 * (str[i] - '0') + 10 * (str[i+1] - '0') + (str[i+2] - '0')) <= 255) {
c = (char) num;
i += 3;
} else
c = '\\';
} else switch (str[i++]) {
isdigit ((byte) str[i + 1]) && isdigit ((byte) str[i + 2])) {
unsigned int num;
if ((num =
100 * (str[i] - '0') + 10 * (str[i + 1] - '0') +
(str[i + 2] - '0')) <= 255) {
c = (char) num;
i += 3;
} else
c = '\\';
} else
switch (str[i++]) {
case 'n':
c = '\n';
break;
@ -221,7 +238,7 @@ GIB_Process_Escapes (char *str)
c = '\\';
i--;
break;
}
}
str[j] = c;
} else
str[j] = str[i++];

View file

@ -32,8 +32,9 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] =
"$Id$";
#include <stdlib.h>
#include <string.h>
@ -46,7 +47,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/gib_regex.h"
#include "QF/qtypes.h"
hashtab_t *gib_regexs;
hashtab_t *gib_regexs;
static char errstr[1024];
static const char *
@ -63,7 +64,7 @@ GIB_Regex_Free (void *ele, void *ptr)
free (ele);
}
void
void
GIB_Regex_Init (void)
{
gib_regexs = Hash_NewTable (512, GIB_Regex_Get_Key, GIB_Regex_Free, 0);
@ -74,8 +75,8 @@ GIB_Regex_Compile (const char *regex, int cflags)
{
static unsigned int num_regexs = 0;
gib_regex_t *reg;
int res;
int res;
// Already compiled ?
if ((reg = Hash_Find (gib_regexs, regex))) {
// Did cflags change?
@ -84,21 +85,20 @@ GIB_Regex_Compile (const char *regex, int cflags)
reg->cflags = cflags;
if ((res = regcomp (&(reg->comp), regex, cflags))) {
// Blew up, remove from hash
regerror(res, &(reg->comp), errstr, sizeof(errstr));
regerror (res, &(reg->comp), errstr, sizeof (errstr));
regfree (&(reg->comp));
free (reg->regex);
free (Hash_Del (gib_regexs, regex));
num_regexs--;
return 0;
} else
} else
return &(reg->comp);
}
else
} else
return &(reg->comp);
} else {
reg = calloc (1, sizeof (gib_regex_t));
if ((res = regcomp (&(reg->comp), regex, cflags))) {
regerror(res, &(reg->comp), errstr, sizeof(errstr));
regerror (res, &(reg->comp), errstr, sizeof (errstr));
regfree (&(reg->comp));
free (reg);
return 0;
@ -108,7 +108,7 @@ GIB_Regex_Compile (const char *regex, int cflags)
if (++num_regexs > 128) {
Hash_FlushTable (gib_regexs);
num_regexs = 0;
}
}
Hash_Add (gib_regexs, reg);
return &(reg->comp);
}
@ -124,44 +124,48 @@ GIB_Regex_Error (void)
int
GIB_Regex_Translate_Options (const char *opstr)
{
int options = 0;
int options = 0;
if (strchr (opstr, 'i'))
options |= REG_ICASE;
if (strchr (opstr, 'n'))
options |= REG_NEWLINE;
return options;
}
unsigned int
GIB_Regex_Apply_Match (regmatch_t match[10], dstring_t *dstr, unsigned int ofs, const char *replace)
GIB_Regex_Apply_Match (regmatch_t match[10], dstring_t * dstr, unsigned int ofs,
const char *replace)
{
int i, start, len, sub, rlen = strlen(replace);
char *matched;
start = match[0].rm_so+ofs;
int i, start, len, sub, rlen = strlen (replace);
char *matched;
start = match[0].rm_so + ofs;
len = match[0].rm_eo - match[0].rm_so;
// Save matched pattern space
matched = calloc (len + 1, sizeof(char));
memcpy (matched, dstr->str+start, match[0].rm_eo - match[0].rm_so);
matched = calloc (len + 1, sizeof (char));
memcpy (matched, dstr->str + start, match[0].rm_eo - match[0].rm_so);
dstring_replace (dstr, start, len, replace, rlen);
for (i = start; i < start+rlen; i++) {
for (i = start; i < start + rlen; i++) {
if (dstr->str[i] == '\\') {
if (dstr->str[i+1] == '&') {
if (dstr->str[i + 1] == '&') {
dstring_snip (dstr, i, 1);
rlen--;
continue;
}
if (isdigit ((byte) dstr->str[i+1])) {
if (i && dstr->str[i-1] == '\\') { // Escaped, not a true back reference
if (isdigit ((byte) dstr->str[i + 1])) {
if (i && dstr->str[i - 1] == '\\') { // Escaped, not a true
// back reference
dstring_snip (dstr, i, 1);
rlen--;
continue;
}
sub = dstr->str[i+1] - '0';
sub = dstr->str[i + 1] - '0';
if (match[sub].rm_so != -1) {
dstring_replace (dstr, i, 2, matched+match[sub].rm_so, match[sub].rm_eo - match[sub].rm_so);
dstring_replace (dstr, i, 2, matched + match[sub].rm_so,
match[sub].rm_eo - match[sub].rm_so);
rlen += match[sub].rm_eo - match[sub].rm_so - 2;
} else {
dstring_snip (dstr, i, 2);
@ -170,7 +174,7 @@ GIB_Regex_Apply_Match (regmatch_t match[10], dstring_t *dstr, unsigned int ofs,
}
} else if (dstr->str[i] == '&') {
dstring_replace (dstr, i, 1, matched, len);
rlen += strlen(matched) - 1;
rlen += strlen (matched) - 1;
}
}
free (matched);

View file

@ -32,14 +32,14 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] = "$Id$";
#include <stdlib.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "QF/sys.h"
#include "QF/sys.h"
#include "QF/cbuf.h"
#include "QF/gib_parse.h"
#include "QF/gib_thread.h"
@ -51,12 +51,12 @@ static __attribute__ ((unused)) const char rcsid[] =
gib_thread_t *gib_threads = 0;
gib_thread_t **gib_thread_p = &gib_threads;
hashtab_t *gib_events;
hashtab_t *gib_events;
static unsigned long int nextid = 0;
void
GIB_Thread_Add (gib_thread_t *thread)
GIB_Thread_Add (gib_thread_t * thread)
{
thread->prev = *gib_thread_p;
*gib_thread_p = thread;
@ -64,7 +64,7 @@ GIB_Thread_Add (gib_thread_t *thread)
}
void
GIB_Thread_Remove (gib_thread_t *thread)
GIB_Thread_Remove (gib_thread_t * thread)
{
if (thread->prev)
thread->prev->next = thread->next;
@ -82,8 +82,8 @@ gib_thread_t *
GIB_Thread_Find (unsigned long int id)
{
gib_thread_t *cur;
for (cur = gib_threads; cur; cur=cur->next)
for (cur = gib_threads; cur; cur = cur->next)
if (cur->id == id)
return cur;
return 0;
@ -92,7 +92,8 @@ GIB_Thread_Find (unsigned long int id)
gib_thread_t *
GIB_Thread_New (void)
{
gib_thread_t *new = calloc (1, sizeof(gib_thread_t));
gib_thread_t *new = calloc (1, sizeof (gib_thread_t));
new->cbuf = Cbuf_New (&gib_interp);
new->id = nextid;
nextid++;
@ -100,7 +101,7 @@ GIB_Thread_New (void)
}
static void
GIB_Thread_Delete (gib_thread_t *thread)
GIB_Thread_Delete (gib_thread_t * thread)
{
Cbuf_DeleteStack (thread->cbuf);
free (thread);
@ -110,9 +111,10 @@ void
GIB_Thread_Execute (void)
{
gib_thread_t *cur, *tmp;
if (!gib_threads)
return;
for (cur = gib_threads; cur; cur = tmp) {
tmp = cur->next;
if (cur->trash) {
@ -126,14 +128,15 @@ GIB_Thread_Execute (void)
static const char *
GIB_Event_Get_Key (void *ele, void *ptr)
{
return ((gib_event_t *)ele)->name;
return ((gib_event_t *) ele)->name;
}
static void
GIB_Event_Free (void *ele, void *ptr)
{
gib_event_t *ev = (gib_event_t *)ele;
free ((void *)ev->name);
gib_event_t *ev = (gib_event_t *) ele;
free ((void *) ev->name);
free (ev);
}
@ -141,7 +144,7 @@ gib_event_t *
GIB_Event_New (const char *name)
{
gib_event_t *new;
new = calloc (1, sizeof (gib_event_t));
new->name = strdup (name);
Hash_Add (gib_events, new);
@ -149,10 +152,10 @@ GIB_Event_New (const char *name)
}
int
GIB_Event_Register (const char *name, gib_function_t *func)
GIB_Event_Register (const char *name, gib_function_t * func)
{
gib_event_t *ev;
if (!(ev = Hash_Find (gib_events, name)))
return -1;
ev->func = func;
@ -160,28 +163,28 @@ GIB_Event_Register (const char *name, gib_function_t *func)
}
void
GIB_Event_Callback (gib_event_t *event, unsigned int argc, ...)
GIB_Event_Callback (gib_event_t * event, unsigned int argc, ...)
{
gib_function_t *f = event->func;
gib_thread_t *thread;
cbuf_args_t *args;
va_list ap;
va_list ap;
unsigned int i;
if (!f)
return;
thread = GIB_Thread_New ();
args = Cbuf_ArgsNew ();
va_start (ap, argc);
Cbuf_ArgsAdd (args, f->name);
for (i = 0; i < argc; i++)
Cbuf_ArgsAdd (args, va_arg (ap, const char *));
Cbuf_ArgsAdd (args, va_arg (ap, const char *));
va_end (ap);
GIB_Function_Execute (thread->cbuf, f, args->argv, args->argc);
GIB_Thread_Add (thread);
Cbuf_ArgsDelete (args);

View file

@ -32,8 +32,8 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] = "$Id$";
#include <stdlib.h>
#include <string.h>
@ -46,14 +46,15 @@ gib_tree_t *
GIB_Tree_New (gib_tree_flags_t flags)
{
gib_tree_t *new = calloc (1, sizeof (gib_tree_t));
new->flags = flags;
// All nodes are created for a reason, so start with 1 ref
new->refs = 1;
new->refs = 1;
return new;
}
void
GIB_Tree_Free_Recursive (gib_tree_t *tree)
GIB_Tree_Free_Recursive (gib_tree_t * tree)
{
gib_tree_t *n;
@ -65,26 +66,24 @@ GIB_Tree_Free_Recursive (gib_tree_t *tree)
// Parent is about to bite the dust, meaning one less reference
GIB_Tree_Unref (&tree->children);
if (tree->str)
free((void *) tree->str);
free(tree);
free ((void *) tree->str);
free (tree);
}
}
void
GIB_Tree_Ref (gib_tree_t **tp)
GIB_Tree_Ref (gib_tree_t ** tp)
{
(*tp)->refs++;
Sys_DPrintf ("Ref: %p %u\n", *tp, (*tp)->refs);
}
void
GIB_Tree_Unref (gib_tree_t **tp)
GIB_Tree_Unref (gib_tree_t ** tp)
{
Sys_DPrintf ("Unref: %p %u\n", *tp, (*tp)->refs-1);
Sys_DPrintf ("Unref: %p %u\n", *tp, (*tp)->refs - 1);
if (!(--(*tp)->refs)) {
GIB_Tree_Free_Recursive (*tp);
*tp = 0;
}
}

View file

@ -32,8 +32,8 @@
# include "config.h"
#endif
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
static __attribute__ ((unused))
const char rcsid[] = "$Id$";
#include <string.h>
#include <stdlib.h>
@ -43,14 +43,15 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/gib_vars.h"
#include "QF/gib_buffer.h"
#include "QF/gib_parse.h"
hashtab_t *gib_globals = 0;
hashtab_t *gib_domains = 0;
hashtab_t *gib_globals = 0;
hashtab_t *gib_domains = 0;
static gib_var_t *
GIB_Var_New (const char *key)
{
gib_var_t *new = calloc (1, sizeof (gib_var_t));
gib_var_t *new = calloc (1, sizeof (gib_var_t));
new->array = calloc (1, sizeof (dstring_t *));
new->key = strdup (key);
return new;
@ -59,25 +60,27 @@ GIB_Var_New (const char *key)
static const char *
GIB_Var_Get_Key (void *ele, void *ptr)
{
return ((gib_var_t *)ele)->key;
return ((gib_var_t *) ele)->key;
}
static void
GIB_Var_Free (void *ele, void *ptr)
{
unsigned int i;
gib_var_t *l = (gib_var_t *)ele;
gib_var_t *l = (gib_var_t *) ele;
for (i = 0; i < l->size; i++)
if (l->array[i])
dstring_delete (l->array[i]);
free((void *)l->key);
free(l);
free ((void *) l->key);
free (l);
}
gib_var_t *
GIB_Var_Get (hashtab_t *first, hashtab_t *second, const char *key)
GIB_Var_Get (hashtab_t * first, hashtab_t * second, const char *key)
{
gib_var_t *var;
gib_var_t *var;
if (first && (var = Hash_Find (first, key)))
return var;
else if (second && (var = Hash_Find (second, key)))
@ -88,18 +91,19 @@ GIB_Var_Get (hashtab_t *first, hashtab_t *second, const char *key)
/* Modifies key but restores it before returning */
gib_var_t *
GIB_Var_Get_Complex (hashtab_t **first, hashtab_t **second, char *key, unsigned int *ind, qboolean create)
GIB_Var_Get_Complex (hashtab_t ** first, hashtab_t ** second, char *key,
unsigned int *ind, qboolean create)
{
unsigned int i, index;
qboolean fix = false;
gib_var_t *var;
i = strlen(key);
qboolean fix = false;
gib_var_t *var;
i = strlen (key);
index = 0;
if (i && key[i-1] == ']')
if (i && key[i - 1] == ']')
for (i--; i; i--)
if (key[i] == '[') {
index = atoi (key+i+1);
index = atoi (key + i + 1);
key[i] = 0;
fix = true;
break;
@ -110,16 +114,20 @@ GIB_Var_Get_Complex (hashtab_t **first, hashtab_t **second, char *key, unsigned
if (!*first)
*first = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0);
Hash_Add (*first, var);
} else return 0;
} else
return 0;
}
if (fix)
key[i] = '[';
if (index >= var->size) {
if (create) {
var->array = realloc (var->array, (index+1) * sizeof (dstring_t *));
memset (var->array+var->size, 0, (index+1 - var->size) * sizeof (dstring_t *));
var->size = index+1;
} else return 0;
var->array =
realloc (var->array, (index + 1) * sizeof (dstring_t *));
memset (var->array + var->size, 0,
(index + 1 - var->size) * sizeof (dstring_t *));
var->size = index + 1;
} else
return 0;
}
if (!var->array[index])
var->array[index] = dstring_newstr ();
@ -128,7 +136,8 @@ GIB_Var_Get_Complex (hashtab_t **first, hashtab_t **second, char *key, unsigned
}
void
GIB_Var_Assign (gib_var_t *var, unsigned int index, dstring_t **values, unsigned int numv)
GIB_Var_Assign (gib_var_t * var, unsigned int index, dstring_t ** values,
unsigned int numv)
{
unsigned int i, len;
@ -136,7 +145,8 @@ GIB_Var_Assign (gib_var_t *var, unsigned int index, dstring_t **values, unsigned
len = numv + index;
if (len >= var->size) {
var->array = realloc (var->array, len * sizeof (dstring_t *));
memset (var->array+var->size, 0, (len-var->size) * sizeof (dstring_t *));
memset (var->array + var->size, 0,
(len - var->size) * sizeof (dstring_t *));
var->size = len;
} else if (len < var->size) {
for (i = len; i < var->size; i++)
@ -146,26 +156,27 @@ GIB_Var_Assign (gib_var_t *var, unsigned int index, dstring_t **values, unsigned
}
var->size = len;
for (i = 0; i < numv; i++) {
if (var->array[i+index])
dstring_clearstr (var->array[i+index]);
if (var->array[i + index])
dstring_clearstr (var->array[i + index]);
else
var->array[i+index] = dstring_newstr ();
dstring_appendstr (var->array[i+index], values[i]->str);
var->array[i + index] = dstring_newstr ();
dstring_appendstr (var->array[i + index], values[i]->str);
}
}
static const char *
GIB_Domain_Get_Key (void *ele, void *ptr)
{
return ((gib_domain_t *)ele)->name;
return ((gib_domain_t *) ele)->name;
}
static void
GIB_Domain_Free (void *ele, void *ptr)
{
gib_domain_t *l = (gib_domain_t *)ele;
gib_domain_t *l = (gib_domain_t *) ele;
Hash_DelTable (l->vars);
free ((void *)l->name);
free ((void *) l->name);
free (l);
}
@ -173,9 +184,10 @@ hashtab_t *
GIB_Domain_Get (const char *name)
{
gib_domain_t *d = Hash_Find (gib_domains, name);
if (!d) {
d = calloc (1, sizeof (gib_domain_t));
d->name = strdup(name);
d->name = strdup (name);
d->vars = Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0);
Hash_Add (gib_domains, d);
}

View file

@ -62,7 +62,7 @@ OP_Div (double op1, double op2)
double
OP_Exp (double op1, double op2)
{
return pow(op1, op2);
return pow (op1, op2);
}
double