mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-17 22:50:51 +00:00
Changed GIB_Arg* into macros. Cleaned up GIB file access a bit and added
file.move and file.delete builtins. Added Qremove to quakeio.[ch]. Did a little cleaning and commenting in gib_parse.c. Added support for \t and \r escape characters.
This commit is contained in:
parent
7542a2457f
commit
8c2afef44c
6 changed files with 125 additions and 61 deletions
|
@ -29,6 +29,8 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
#include "QF/cbuf.h" // For cbuf_active
|
||||
|
||||
typedef struct gib_builtin_s {
|
||||
struct dstring_s *name;
|
||||
void (*func) (void);
|
||||
|
@ -39,9 +41,11 @@ typedef struct gib_builtin_s {
|
|||
} type;
|
||||
} gib_builtin_t;
|
||||
|
||||
unsigned int GIB_Argc (void);
|
||||
const char *GIB_Argv (unsigned int arg);
|
||||
const char *GIB_Args (unsigned int arg);
|
||||
#define GIB_Argc() (cbuf_active->args->argc)
|
||||
#define GIB_Argv(x) ((x) < cbuf_active->args->argc ? cbuf_active->args->argv[(x)]->str : "")
|
||||
#define GIB_Args(x) ((x) < cbuf_active->args->argc ? cbuf_active->args->args[(x)] : "")
|
||||
#define GIB_Argd(x) ((x) < cbuf_active->args->argc ? cbuf_active->args->argv[(x)] : NULL)
|
||||
|
||||
void GIB_Arg_Strip_Delim (unsigned int arg);
|
||||
void GIB_Return (const char *str);
|
||||
void GIB_Builtin_Add (const char *name, void (*func) (void), enum gib_builtin_type_e type);
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef struct QFile_s QFile;
|
|||
|
||||
void Qexpand_squiggle(const char *path, char *dest);
|
||||
int Qrename(const char *old, const char *new);
|
||||
int Qremove(const char *path);
|
||||
int Qfilesize (QFile *file);
|
||||
QFile *Qopen(const char *path, const char *mode);
|
||||
QFile *Qdopen(int fd, const char *mode);
|
||||
|
|
|
@ -114,46 +114,6 @@ GIB_Builtin_Find (const char *name)
|
|||
return (gib_builtin_t *) Hash_Find (gib_builtins, name);
|
||||
}
|
||||
|
||||
/*
|
||||
GIB_Argc
|
||||
|
||||
Returns the number of arguments available
|
||||
in the current buffer.
|
||||
*/
|
||||
unsigned int
|
||||
GIB_Argc (void)
|
||||
{
|
||||
return cbuf_active->args->argc;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns a specific argument in the current
|
||||
buffer.
|
||||
*/
|
||||
const char *
|
||||
GIB_Argv (unsigned int arg)
|
||||
{
|
||||
if (arg < cbuf_active->args->argc)
|
||||
return cbuf_active->args->argv[arg]->str;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
GIB_Args
|
||||
|
||||
Returns a pointer to the composite command
|
||||
line starting at token arg.
|
||||
*/
|
||||
const char *
|
||||
GIB_Args (unsigned int arg)
|
||||
{
|
||||
if (arg < cbuf_active->args->argc)
|
||||
return cbuf_active->args->args[arg];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
GIB_Arg_Strip_Delim
|
||||
|
||||
|
@ -554,7 +514,7 @@ GIB_File_Read_f (void)
|
|||
"usage: file.read path_and_filename");
|
||||
return;
|
||||
}
|
||||
path = cbuf_active->args->argv[1]->str;
|
||||
path = GIB_Argv (1);
|
||||
if (!GIB_CollapsePath (path)) {
|
||||
Cbuf_Error ("access",
|
||||
"file.read: access to %s denied", path);
|
||||
|
@ -564,7 +524,7 @@ GIB_File_Read_f (void)
|
|||
contents = (char *) COM_LoadHunkFile (path);
|
||||
if (!contents) {
|
||||
Cbuf_Error ("file",
|
||||
"file.read: could not open %s for reading: %s", path, strerror (errno));
|
||||
"file.read: could not open %s/%s for reading: %s", com_gamedir, path, strerror (errno));
|
||||
return;
|
||||
}
|
||||
GIB_Return (contents);
|
||||
|
@ -583,7 +543,7 @@ GIB_File_Write_f (void)
|
|||
"usage: file.write path_and_filename data");
|
||||
return;
|
||||
}
|
||||
path = cbuf_active->args->argv[1]->str;
|
||||
path = GIB_Argv (1);
|
||||
if (!GIB_CollapsePath (path)) {
|
||||
Cbuf_Error ("access",
|
||||
"file.write: access to %s denied", path);
|
||||
|
@ -591,7 +551,7 @@ GIB_File_Write_f (void)
|
|||
}
|
||||
if (!(file = Qopen (va ("%s/%s", com_gamedir, path), "w"))) {
|
||||
Cbuf_Error ("file",
|
||||
"file.write: could not open %s for writing: %s", path, strerror (errno));
|
||||
"file.write: could not open %s/%s for writing: %s", com_gamedir, path, strerror (errno));
|
||||
return;
|
||||
}
|
||||
Qprintf (file, "%s", GIB_Argv (2));
|
||||
|
@ -613,19 +573,18 @@ GIB_File_Find_f (void)
|
|||
"usage: file.find glob [path]");
|
||||
return;
|
||||
}
|
||||
|
||||
path = GIB_Argv (2);
|
||||
if (GIB_Argc () == 3) {
|
||||
path = cbuf_active->args->argv[2]->str;
|
||||
if (!GIB_CollapsePath (path)) {
|
||||
Cbuf_Error ("access",
|
||||
"file.find: access to %s denied", path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
directory = opendir (va ("%s/%s", com_gamedir, GIB_Argv (2)));
|
||||
directory = opendir (va ("%s/%s", com_gamedir, path));
|
||||
if (!directory) {
|
||||
Cbuf_Error ("file",
|
||||
"file.find: could not open directory %s: %s", GIB_Argv (2), strerror (errno));
|
||||
"file.find: could not open directory %s/%s: %s", com_gamedir, path, strerror (errno));
|
||||
return;
|
||||
}
|
||||
list = dstring_newstr ();
|
||||
|
@ -645,7 +604,66 @@ GIB_File_Find_f (void)
|
|||
GIB_Return ("");
|
||||
dstring_delete (list);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GIB_File_Move_f (void)
|
||||
{
|
||||
char *path1, *path2;
|
||||
dstring_t *from, *to;
|
||||
|
||||
if (GIB_Argc () != 3) {
|
||||
Cbuf_Error ("syntax",
|
||||
"file.move: invalid syntax\n"
|
||||
"usage: file.move from_file to_file");
|
||||
return;
|
||||
}
|
||||
path1 = GIB_Argv (1);
|
||||
path2 = GIB_Argv (2);
|
||||
if (!GIB_CollapsePath (path1)) {
|
||||
Cbuf_Error ("access",
|
||||
"file.move: access to %s denied", path1);
|
||||
return;
|
||||
}
|
||||
if (!GIB_CollapsePath (path2)) {
|
||||
Cbuf_Error ("access",
|
||||
"file.move: access to %s denied", path2);
|
||||
return;
|
||||
}
|
||||
from = dstring_newstr ();
|
||||
to = dstring_newstr ();
|
||||
dsprintf (from, "%s/%s", com_gamedir, path1);
|
||||
dsprintf (to, "%s/%s", com_gamedir, path2);
|
||||
if (Qrename (from->str, to->str))
|
||||
Cbuf_Error ("file",
|
||||
"file.move: could not move %s to %s: %s",
|
||||
from->str, to->str, strerror(errno));
|
||||
dstring_delete (from);
|
||||
dstring_delete (to);
|
||||
}
|
||||
|
||||
void
|
||||
GIB_File_Delete_f (void)
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (GIB_Argc () != 2) {
|
||||
Cbuf_Error ("syntax",
|
||||
"file.delete: invalid syntax\n"
|
||||
"usage: file.delete file");
|
||||
return;
|
||||
}
|
||||
path = GIB_Argv (1);
|
||||
if (!GIB_CollapsePath (path)) {
|
||||
Cbuf_Error ("access",
|
||||
"file.delete: access to %s denied", path);
|
||||
return;
|
||||
}
|
||||
if (Qremove(va("%s/%s", com_gamedir, path)))
|
||||
Cbuf_Error ("file",
|
||||
"file.delete: could not delete %s/%s: %s",
|
||||
com_gamedir, path, strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Range_f (void)
|
||||
{
|
||||
|
@ -714,6 +732,8 @@ GIB_Builtin_Init (void)
|
|||
GIB_Builtin_Add ("file.read", GIB_File_Read_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("file.write", GIB_File_Write_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("file.find", GIB_File_Find_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("file.move", GIB_File_Move_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("file.delete", GIB_File_Delete_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("range", GIB_Range_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("print", GIB_Print_f, GIB_BUILTIN_NORMAL);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,13 @@ cbuf_interpreter_t gib_interp = {
|
|||
GIB_Buffer_Destruct,
|
||||
};
|
||||
|
||||
/*
|
||||
GIB_Escaped
|
||||
|
||||
Returns true if character i in str is
|
||||
escaped with a backslash (and the backslash
|
||||
is not itself escaped).
|
||||
*/
|
||||
inline qboolean
|
||||
GIB_Escaped (const char *str, int i)
|
||||
{
|
||||
|
@ -181,6 +188,16 @@ GIB_Parse_Match_Backtick (const char *str, unsigned int *i)
|
|||
return '`';
|
||||
}
|
||||
|
||||
/*
|
||||
GIB_Parse_Match_Index
|
||||
|
||||
Progresses an index variable through a string
|
||||
until a normal brace (]) is reached. Calls
|
||||
other matching functions to skip areas of a
|
||||
string it does not want to handle. Returns
|
||||
0 on success, or the character it could not
|
||||
match otherwise.
|
||||
*/
|
||||
char
|
||||
GIB_Parse_Match_Index (const char *str, unsigned int *i)
|
||||
{
|
||||
|
@ -193,6 +210,14 @@ GIB_Parse_Match_Index (const char *str, unsigned int *i)
|
|||
return '[';
|
||||
}
|
||||
|
||||
/*
|
||||
GIB_Parse_Strip_Comments
|
||||
|
||||
Finds instances of // comments in a cbuf
|
||||
outside of double quotes and snips between
|
||||
the // and the next newline or the end of
|
||||
the string.
|
||||
*/
|
||||
void
|
||||
GIB_Parse_Strip_Comments (struct cbuf_s *cbuf)
|
||||
{
|
||||
|
@ -252,11 +277,9 @@ GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
|||
}
|
||||
|
||||
if (dstr->str[0]) { // If something is left in the buffer
|
||||
if (i) { // If we used any of it
|
||||
if (i)// If we used any of it
|
||||
dstring_insert (cbuf->line, 0, dstr->str, i);
|
||||
Sys_DPrintf ("extracted line: %s\n", cbuf->line->str);
|
||||
}
|
||||
// Clip out what we used or any leftover newlines or ;s
|
||||
// Clip out what we used or any leftover newlines or ;s
|
||||
dstring_snip (dstr, 0, i + (dstr->str[i] == '\n' || dstr->str[i] == ';'));
|
||||
}
|
||||
|
||||
|
@ -348,7 +371,7 @@ GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr, qboolean
|
|||
of pointers to the beginnings of tokens
|
||||
within it.
|
||||
*/
|
||||
void
|
||||
inline static void
|
||||
GIB_Parse_Generate_Composite (struct cbuf_s *cbuf)
|
||||
{
|
||||
cbuf_args_t *args = cbuf->args;
|
||||
|
@ -379,7 +402,7 @@ GIB_Parse_Generate_Composite (struct cbuf_s *cbuf)
|
|||
or concatenates it to the end of the last
|
||||
according to cat.
|
||||
*/
|
||||
inline void
|
||||
inline static void
|
||||
GIB_Parse_Add_Token (struct cbuf_args_s *args, qboolean cat, dstring_t *token)
|
||||
{
|
||||
if (cat) {
|
||||
|
|
|
@ -262,9 +262,17 @@ GIB_Process_Escapes (dstring_t *token)
|
|||
int i;
|
||||
for (i = 0; token->str[i]; i++) {
|
||||
if (token->str[i] == '\\') {
|
||||
dstring_snip (token, i, 1);
|
||||
if (token->str[i] == 'n')
|
||||
token->str[i] = '\n';
|
||||
dstring_snip (token, i, 1); // Get rid of slash
|
||||
switch (token->str[i]) {
|
||||
case 'n':
|
||||
token->str[i] = '\n';
|
||||
break;
|
||||
case 't':
|
||||
token->str[i] = '\t';
|
||||
break;
|
||||
case 'r':
|
||||
token->str[i] = '\r';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,14 @@ Qrename (const char *old, const char *new)
|
|||
return rename (e_old, e_new);
|
||||
}
|
||||
|
||||
int
|
||||
Qremove (const char *path)
|
||||
{
|
||||
char e_path[PATH_MAX];
|
||||
Qexpand_squiggle (path, e_path);
|
||||
return remove (e_path);
|
||||
}
|
||||
|
||||
int
|
||||
Qfilesize (QFile *file)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue