mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
Var substitution is now handled in the same pass as embedded return values.
This prevents var substitution from being performed on the return value of a function. The local variable ifs can now be set to specify a custom field separator for use in for loops. file.find will also insert ifs between file names instead of a space if it is set. file.find will also no longer put . and .. in a list of file names.
This commit is contained in:
parent
ce2cfbcf45
commit
8b31103e6f
4 changed files with 83 additions and 86 deletions
|
@ -37,7 +37,7 @@ typedef struct gib_buffer_data_s {
|
||||||
struct dstring_s *loop_program;
|
struct dstring_s *loop_program;
|
||||||
struct dstring_s *loop_data;
|
struct dstring_s *loop_data;
|
||||||
|
|
||||||
char *loop_var_p, *loop_list_p;
|
char *loop_var_p, *loop_list_p, *loop_ifs_p;
|
||||||
|
|
||||||
// Data for handling return values
|
// Data for handling return values
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -30,6 +30,5 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void GIB_Process_Variable (struct dstring_s *token);
|
void GIB_Process_Variable (struct dstring_s *token);
|
||||||
void GIB_Process_Variables_All (struct dstring_s *token);
|
|
||||||
int GIB_Process_Math (struct dstring_s *token);
|
int GIB_Process_Math (struct dstring_s *token);
|
||||||
int GIB_Process_Token (struct dstring_s *token, char delim);
|
int GIB_Process_Token (struct dstring_s *token, char delim);
|
||||||
|
|
|
@ -329,7 +329,7 @@ GIB___For_f (void)
|
||||||
Cbuf_InsertText (cbuf_active, "break;");
|
Cbuf_InsertText (cbuf_active, "break;");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (end = GIB_DATA(cbuf_active)->loop_list_p; *end && !isspace((byte) *end); end++);
|
for (end = GIB_DATA(cbuf_active)->loop_list_p; !strchr(GIB_DATA(cbuf_active)->loop_ifs_p, *end); end++);
|
||||||
if (*end) {
|
if (*end) {
|
||||||
old = *end;
|
old = *end;
|
||||||
*end = 0;
|
*end = 0;
|
||||||
|
@ -337,7 +337,7 @@ GIB___For_f (void)
|
||||||
GIB_Var_Set_Local (cbuf_active, GIB_DATA(cbuf_active)->loop_var_p, GIB_DATA(cbuf_active)->loop_list_p);
|
GIB_Var_Set_Local (cbuf_active, GIB_DATA(cbuf_active)->loop_var_p, GIB_DATA(cbuf_active)->loop_list_p);
|
||||||
if (old)
|
if (old)
|
||||||
*end = old;
|
*end = old;
|
||||||
while (isspace ((byte)*end))
|
while (*end && strchr(GIB_DATA(cbuf_active)->loop_ifs_p, *end))
|
||||||
end++;
|
end++;
|
||||||
GIB_DATA(cbuf_active)->loop_list_p = end;
|
GIB_DATA(cbuf_active)->loop_list_p = end;
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,9 @@ GIB_For_f (void)
|
||||||
);
|
);
|
||||||
} else if (GIB_Argv (3)[0]) {
|
} else if (GIB_Argv (3)[0]) {
|
||||||
char *ll;
|
char *ll;
|
||||||
|
const char *ifs;
|
||||||
cbuf_t *sub = Cbuf_New (&gib_interp);
|
cbuf_t *sub = Cbuf_New (&gib_interp);
|
||||||
|
// Create loop buffer
|
||||||
GIB_DATA(sub)->type = GIB_BUFFER_LOOP;
|
GIB_DATA(sub)->type = GIB_BUFFER_LOOP;
|
||||||
GIB_DATA(sub)->locals = GIB_DATA(cbuf_active)->locals;
|
GIB_DATA(sub)->locals = GIB_DATA(cbuf_active)->locals;
|
||||||
GIB_DATA(sub)->loop_program = dstring_newstr ();
|
GIB_DATA(sub)->loop_program = dstring_newstr ();
|
||||||
|
@ -361,13 +363,19 @@ GIB_For_f (void)
|
||||||
Cbuf_DeleteStack (cbuf_active->down);
|
Cbuf_DeleteStack (cbuf_active->down);
|
||||||
cbuf_active->down = sub;
|
cbuf_active->down = sub;
|
||||||
sub->up = cbuf_active;
|
sub->up = cbuf_active;
|
||||||
|
// Store all for-loop data in one big buffer (easy to clean up)
|
||||||
dstring_appendstr (GIB_DATA(sub)->loop_data, GIB_Argv(3));
|
dstring_appendstr (GIB_DATA(sub)->loop_data, GIB_Argv(3));
|
||||||
dstring_append (GIB_DATA(sub)->loop_data, GIB_Argv(1), strlen(GIB_Argv(1))+1);
|
dstring_append (GIB_DATA(sub)->loop_data, GIB_Argv(1), strlen(GIB_Argv(1))+1);
|
||||||
|
if (!(ifs = GIB_Var_Get_Local (cbuf_active, "ifs")))
|
||||||
|
ifs = " \n\t";
|
||||||
|
dstring_append (GIB_DATA(sub)->loop_data, ifs, strlen(ifs)+1);
|
||||||
|
// Store pointers to data
|
||||||
ll = GIB_DATA(sub)->loop_data->str;
|
ll = GIB_DATA(sub)->loop_data->str;
|
||||||
while (isspace ((byte) *ll))
|
while (isspace ((byte) *ll))
|
||||||
ll++;
|
ll++;
|
||||||
GIB_DATA(sub)->loop_list_p = ll;
|
GIB_DATA(sub)->loop_list_p = ll; // List to iterate through
|
||||||
GIB_DATA(sub)->loop_var_p = GIB_DATA(sub)->loop_data->str + strlen(GIB_Argv(3))+1;
|
GIB_DATA(sub)->loop_var_p = GIB_DATA(sub)->loop_data->str + strlen(GIB_Argv(3))+1; // Var to use
|
||||||
|
GIB_DATA(sub)->loop_ifs_p = GIB_DATA(sub)->loop_var_p + strlen(GIB_Argv(1))+1; // Internal field separator
|
||||||
dstring_appendstr (GIB_DATA(sub)->loop_program, "__for;");
|
dstring_appendstr (GIB_DATA(sub)->loop_program, "__for;");
|
||||||
dstring_appendstr (GIB_DATA(sub)->loop_program, GIB_Argv(4));
|
dstring_appendstr (GIB_DATA(sub)->loop_program, GIB_Argv(4));
|
||||||
Cbuf_AddText (sub, GIB_DATA(sub)->loop_program->str);
|
Cbuf_AddText (sub, GIB_DATA(sub)->loop_program->str);
|
||||||
|
@ -596,6 +604,7 @@ GIB_File_Find_f (void)
|
||||||
DIR *directory;
|
DIR *directory;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
char *path;
|
char *path;
|
||||||
|
const char *ifs;
|
||||||
dstring_t *list;
|
dstring_t *list;
|
||||||
|
|
||||||
if (GIB_Argc () < 2 || GIB_Argc () > 3) {
|
if (GIB_Argc () < 2 || GIB_Argc () > 3) {
|
||||||
|
@ -620,9 +629,13 @@ GIB_File_Find_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
list = dstring_newstr ();
|
list = dstring_newstr ();
|
||||||
|
if (!(ifs = GIB_Var_Get_Local (cbuf_active, "ifs")))
|
||||||
|
ifs = " ";
|
||||||
while ((entry = readdir (directory))) {
|
while ((entry = readdir (directory))) {
|
||||||
if (!fnmatch (GIB_Argv (1), entry->d_name, 0)) {
|
if (strcmp (entry->d_name, ".") &&
|
||||||
dstring_appendstr (list, " ");
|
strcmp (entry->d_name, "..") &&
|
||||||
|
!fnmatch (GIB_Argv (1), entry->d_name, 0)) {
|
||||||
|
dstring_appendstr (list, ifs);
|
||||||
dstring_appendstr (list, entry->d_name);
|
dstring_appendstr (list, entry->d_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,17 +106,69 @@ GIB_Process_Variable (struct dstring_s *dstr, unsigned int pos, qboolean toleran
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
GIB_Process_Variables_All (struct dstring_s *token)
|
GIB_Process_Math (struct dstring_s *token)
|
||||||
{
|
{
|
||||||
int i, n, m;
|
double value;
|
||||||
|
|
||||||
|
value = EXP_Evaluate (token->str);
|
||||||
|
if (EXP_ERROR) {
|
||||||
|
// FIXME: Give real error descriptions
|
||||||
|
Cbuf_Error ("math", "Expression \"%s\" caused error %i", token->str, EXP_ERROR);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
dstring_clearstr (token);
|
||||||
|
dsprintf (token, "%.10g", value);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
GIB_Process_Embedded (struct dstring_s *token)
|
||||||
|
{
|
||||||
|
cbuf_t *sub;
|
||||||
|
int i, n, m, i1, i2;
|
||||||
|
char c = 0, *p;
|
||||||
dstring_t *var = dstring_newstr ();
|
dstring_t *var = dstring_newstr ();
|
||||||
char c = 0;
|
|
||||||
char *p;
|
|
||||||
int i1, i2;
|
|
||||||
qboolean index;
|
qboolean index;
|
||||||
|
|
||||||
for (i = 0; token->str[i]; i++) {
|
if (GIB_DATA(cbuf_active)->ret.waiting) {
|
||||||
if (token->str[i] == '$') {
|
if (!GIB_DATA(cbuf_active)->ret.available) {
|
||||||
|
GIB_DATA(cbuf_active)->ret.waiting = false;
|
||||||
|
Cbuf_Error ("return", "Embedded command did not return a value.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
i = GIB_DATA(cbuf_active)->ret.token_pos; // Jump to the right place
|
||||||
|
} else
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
for (; token->str[i]; i++) {
|
||||||
|
if (token->str[i] == '`') {
|
||||||
|
n = i;
|
||||||
|
if ((c = GIB_Parse_Match_Backtick (token->str, &i))) {
|
||||||
|
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (GIB_DATA(cbuf_active)->ret.available) {
|
||||||
|
dstring_replace (token, n, i-n+1, GIB_DATA(cbuf_active)->ret.retval->str,
|
||||||
|
strlen(GIB_DATA(cbuf_active)->ret.retval->str));
|
||||||
|
i = n + strlen(GIB_DATA(cbuf_active)->ret.retval->str) - 1;
|
||||||
|
GIB_DATA(cbuf_active)->ret.waiting = false;
|
||||||
|
GIB_DATA(cbuf_active)->ret.available = false;
|
||||||
|
} else {
|
||||||
|
sub = Cbuf_New (&gib_interp);
|
||||||
|
GIB_DATA(sub)->type = GIB_BUFFER_PROXY;
|
||||||
|
GIB_DATA(sub)->locals = GIB_DATA(cbuf_active)->locals;
|
||||||
|
dstring_insert (sub->buf, 0, token->str+n+1, i-n-1);
|
||||||
|
if (cbuf_active->down)
|
||||||
|
Cbuf_DeleteStack (cbuf_active->down);
|
||||||
|
cbuf_active->down = sub;
|
||||||
|
sub->up = cbuf_active;
|
||||||
|
cbuf_active->state = CBUF_STATE_STACK;
|
||||||
|
GIB_DATA(cbuf_active)->ret.waiting = true;
|
||||||
|
GIB_DATA(cbuf_active)->ret.token_pos = n;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (token->str[i] == '$') {
|
||||||
index = false;
|
index = false;
|
||||||
if (token->str[i+1] == '{') {
|
if (token->str[i+1] == '{') {
|
||||||
n = i+1;
|
n = i+1;
|
||||||
|
@ -150,6 +202,7 @@ GIB_Process_Variables_All (struct dstring_s *token)
|
||||||
n++;
|
n++;
|
||||||
if (!token->str[i+n]) {
|
if (!token->str[i+n]) {
|
||||||
Cbuf_Error ("parse", "Could not find match for [");
|
Cbuf_Error ("parse", "Could not find match for [");
|
||||||
|
c = '[';
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,77 +249,13 @@ GIB_Process_Variables_All (struct dstring_s *token)
|
||||||
dstring_clearstr (var);
|
dstring_clearstr (var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
dstring_delete (var);
|
||||||
ERROR:
|
ERROR:
|
||||||
dstring_delete (var);
|
dstring_delete (var);
|
||||||
return c ? -1 : 0;
|
return c ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
GIB_Process_Math (struct dstring_s *token)
|
|
||||||
{
|
|
||||||
double value;
|
|
||||||
|
|
||||||
value = EXP_Evaluate (token->str);
|
|
||||||
if (EXP_ERROR) {
|
|
||||||
// FIXME: Give real error descriptions
|
|
||||||
Cbuf_Error ("math", "Expression \"%s\" caused error %i", token->str, EXP_ERROR);
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
dstring_clearstr (token);
|
|
||||||
dsprintf (token, "%.10g", value);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
GIB_Process_Embedded (struct dstring_s *token)
|
|
||||||
{
|
|
||||||
cbuf_t *sub;
|
|
||||||
int i, n;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
if (GIB_DATA(cbuf_active)->ret.waiting) {
|
|
||||||
if (!GIB_DATA(cbuf_active)->ret.available) {
|
|
||||||
GIB_DATA(cbuf_active)->ret.waiting = false;
|
|
||||||
Cbuf_Error ("return", "Embedded command did not return a value.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
i = GIB_DATA(cbuf_active)->ret.token_pos; // Jump to the right place
|
|
||||||
} else
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (; token->str[i]; i++) {
|
|
||||||
if (token->str[i] == '`') {
|
|
||||||
n = i;
|
|
||||||
if ((c = GIB_Parse_Match_Backtick (token->str, &i))) {
|
|
||||||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (GIB_DATA(cbuf_active)->ret.available) {
|
|
||||||
dstring_replace (token, n, i-n+1, GIB_DATA(cbuf_active)->ret.retval->str,
|
|
||||||
strlen(GIB_DATA(cbuf_active)->ret.retval->str));
|
|
||||||
i = n + strlen(GIB_DATA(cbuf_active)->ret.retval->str) - 1;
|
|
||||||
GIB_DATA(cbuf_active)->ret.waiting = false;
|
|
||||||
GIB_DATA(cbuf_active)->ret.available = false;
|
|
||||||
} else {
|
|
||||||
sub = Cbuf_New (&gib_interp);
|
|
||||||
GIB_DATA(sub)->type = GIB_BUFFER_PROXY;
|
|
||||||
GIB_DATA(sub)->locals = GIB_DATA(cbuf_active)->locals;
|
|
||||||
dstring_insert (sub->buf, 0, token->str+n+1, i-n-1);
|
|
||||||
if (cbuf_active->down)
|
|
||||||
Cbuf_DeleteStack (cbuf_active->down);
|
|
||||||
cbuf_active->down = sub;
|
|
||||||
sub->up = cbuf_active;
|
|
||||||
cbuf_active->state = CBUF_STATE_STACK;
|
|
||||||
GIB_DATA(cbuf_active)->ret.waiting = true;
|
|
||||||
GIB_DATA(cbuf_active)->ret.token_pos = n;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GIB_Process_Escapes (dstring_t *token)
|
GIB_Process_Escapes (dstring_t *token)
|
||||||
{
|
{
|
||||||
|
@ -283,13 +272,9 @@ GIB_Process_Escapes (dstring_t *token)
|
||||||
int
|
int
|
||||||
GIB_Process_Token (dstring_t *token, char delim)
|
GIB_Process_Token (dstring_t *token, char delim)
|
||||||
{
|
{
|
||||||
if (delim != '{' && delim != '\"') {
|
if (delim != '{' && delim != '\"')
|
||||||
if (GIB_Process_Embedded (token))
|
if (GIB_Process_Embedded (token))
|
||||||
return -1;
|
return -1;
|
||||||
if (GIB_Process_Variables_All (token))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delim == '(')
|
if (delim == '(')
|
||||||
if (GIB_Process_Math (token))
|
if (GIB_Process_Math (token))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in a new issue