added -w to awk. changed -w to -b in sed and added -w to sed

This commit is contained in:
hyung-hwan 2012-09-04 10:15:49 +00:00
parent f0e03cb4ca
commit e059a337eb
2 changed files with 142 additions and 85 deletions

View File

@ -29,6 +29,7 @@
#include <qse/cmn/main.h>
#include <qse/cmn/mbwc.h>
#include <qse/cmn/xma.h>
#include <qse/cmn/glob.h>
#include <string.h>
#include <signal.h>
@ -62,6 +63,17 @@
static qse_awk_rtx_t* app_rtx = QSE_NULL;
static int app_debug = 0;
typedef struct arg_t arg_t;
typedef struct xarg_t xarg_t;
struct xarg_t
{
qse_mmgr_t* mmgr;
qse_char_t** ptr;
qse_size_t size;
qse_size_t capa;
};
struct arg_t
{
qse_awk_parsestd_type_t ist; /* input source type */
@ -71,11 +83,9 @@ struct arg_t
qse_char_t** files;
} isp;
qse_size_t isfl; /* the number of input source files */
qse_char_t* osf; /* output source file */
xarg_t icf; /* input console files */
qse_char_t** icf; /* input console files */
qse_size_t icfl; /* the number of input console files */
qse_htb_t* gvm; /* global variable map */
qse_char_t* fs; /* field separator */
qse_char_t* call; /* function to call */
@ -444,6 +454,8 @@ static void print_usage (QSE_FILE* out, const qse_char_t* argv0)
qse_fprintf (out, QSE_T(" -F/--field-separator string set a field separator(FS)\n"));
qse_fprintf (out, QSE_T(" -v/--assign var=value add a global variable with a value\n"));
qse_fprintf (out, QSE_T(" -m/--memory-limit number limit the memory usage (bytes)\n"));
qse_fprintf (out, QSE_T(" -w expand datafile wildcards\n"));
#if defined(QSE_BUILD_DEBUG)
qse_fprintf (out, QSE_T(" -X number fail the number'th memory allocation\n"));
#endif
@ -460,6 +472,86 @@ static void print_usage (QSE_FILE* out, const qse_char_t* argv0)
}
}
/* ---------------------------------------------------------------------- */
static int collect_into_xarg (const qse_cstr_t* path, void* ctx)
{
xarg_t* xarg = (xarg_t*)ctx;
if (xarg->size <= xarg->capa)
{
qse_char_t** tmp;
tmp = QSE_MMGR_REALLOC (
xarg->mmgr, xarg->ptr,
QSE_SIZEOF(*tmp) * (xarg->capa + 128 + 1));
if (tmp == QSE_NULL) return -1;
xarg->ptr = tmp;
xarg->capa += 128;
}
xarg->ptr[xarg->size] = qse_strdup (path->ptr, xarg->mmgr);
if (xarg->ptr[xarg->size] == QSE_NULL) return -1;
xarg->size++;
return 0;
}
static void purge_xarg (xarg_t* xarg)
{
if (xarg->ptr)
{
qse_size_t i;
for (i = 0; i < xarg->size; i++)
QSE_MMGR_FREE (xarg->mmgr, xarg->ptr[i]);
QSE_MMGR_FREE (xarg->mmgr, xarg->ptr);
xarg->size = 0;
xarg->capa = 0;
xarg->ptr = QSE_NULL;
}
}
static int expand_wildcard (int argc, qse_char_t* argv[], int glob, xarg_t* xarg)
{
int i;
qse_cstr_t tmp;
for (i = 0; i < argc; i++)
{
int x;
if (glob)
{
x = qse_glob (argv[i], collect_into_xarg, xarg,
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
QSE_GLOB_NOESCAPE | QSE_GLOB_PERIOD | QSE_GLOB_IGNORECASE,
#else
QSE_GLOB_PERIOD,
#endif
xarg->mmgr
);
if (x <= -1) return -1;
}
else x = 0;
if (x == 0)
{
/* not expanded. just use it as is */
tmp.ptr = argv[i];
tmp.len = qse_strlen(argv[i]);
if (collect_into_xarg (&tmp, xarg) <= -1) return -1;
}
}
xarg->ptr[xarg->size] = QSE_NULL;
return 0;
}
/* ---------------------------------------------------------------------- */
static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
{
static qse_opt_lng_t lng[] =
@ -502,9 +594,9 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
static qse_opt_t opt =
{
#if defined(QSE_BUILD_DEBUG)
QSE_T("Dc:f:d:F:v:m:X:h"),
QSE_T("hDc:f:d:F:v:m:wX:"),
#else
QSE_T("Dc:f:d:F:v:m:h"),
QSE_T("hDc:f:d:F:v:m:w"),
#endif
lng
};
@ -513,21 +605,14 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
qse_size_t isfc = 16; /* the capacity of isf */
qse_size_t isfl = 0; /* number of input source files */
qse_size_t icfc = 0; /* the capacity of icf */
qse_size_t icfl = 0; /* the number of input console files */
qse_char_t** isf = QSE_NULL; /* input source files */
qse_char_t* osf = QSE_NULL; /* output source file */
qse_char_t** icf = QSE_NULL; /* input console files */
qse_htb_t* gvm = QSE_NULL; /* global variable map */
qse_char_t* fs = QSE_NULL; /* field separator */
qse_char_t* call = QSE_NULL; /* function to call */
int oops_ret = -1;
memset (arg, 0, QSE_SIZEOF(*arg));
int do_glob = 0;
isf = (qse_char_t**) malloc (QSE_SIZEOF(*isf) * isfc);
if (isf == QSE_NULL)
@ -637,6 +722,12 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
break;
}
case QSE_T('w'):
{
do_glob = 1;
break;
}
#if defined(QSE_BUILD_DEBUG)
case QSE_T('X'):
{
@ -745,32 +836,14 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
if (opt.ind < argc)
{
/* the remaining arguments are input console file names */
icfc = argc - opt.ind + 1;
icf = (qse_char_t**) malloc (QSE_SIZEOF(qse_char_t*)*icfc);
if (icf == QSE_NULL)
if (expand_wildcard (argc - opt.ind, &argv[opt.ind], do_glob, &arg->icf) <= -1)
{
print_error (QSE_T("out of memory\n"));
goto oops;
}
if (opt.ind >= argc)
{
/* no input(console) file names are specified.
* the standard input becomes the input console */
icf[icfl++] = QSE_T("");
}
else
{
do { icf[icfl++] = argv[opt.ind++]; } while (opt.ind < argc);
}
icf[icfl] = QSE_NULL;
}
arg->osf = osf;
arg->icf = icf;
arg->icfl = icfl;
arg->gvm = gvm;
arg->fs = fs;
arg->call = call;
@ -779,7 +852,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
oops:
if (gvm != QSE_NULL) qse_htb_close (gvm);
if (icf != QSE_NULL) free (icf);
purge_xarg (&arg->icf);
if (isf != QSE_NULL) free (isf);
return oops_ret;
}
@ -789,7 +862,7 @@ static void freearg (struct arg_t* arg)
if (arg->ist == QSE_AWK_PARSESTD_FILE &&
arg->isp.files != QSE_NULL) free (arg->isp.files);
/*if (arg->osf != QSE_NULL) free (arg->osf);*/
if (arg->icf != QSE_NULL) free (arg->icf);
purge_xarg (&arg->icf);
if (arg->gvm != QSE_NULL) qse_htb_close (arg->gvm);
}
@ -912,6 +985,7 @@ static int awk_main (int argc, qse_char_t* argv[])
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
memset (&arg, 0, QSE_SIZEOF(arg));
arg.icf.mmgr = mmgr;
i = comparg (argc, argv, &arg);
if (i <= 0)
@ -1010,7 +1084,8 @@ static int awk_main (int argc, qse_char_t* argv[])
rtx = qse_awk_rtx_openstd (
awk, 0, QSE_T("qseawk"),
(const qse_char_t*const*)arg.icf, QSE_NULL, arg.console_cmgr);
(const qse_char_t*const*)arg.icf.ptr,
QSE_NULL, arg.console_cmgr);
if (rtx == QSE_NULL)
{
print_awkerr (awk);

View File

@ -70,6 +70,7 @@ static int g_infile_pos = 0;
static int g_option = 0;
static int g_separate = 0;
static int g_inplace = 0;
static int g_wildcard = 0;
#if defined(QSE_ENABLE_SEDTRACER)
static int g_trace = 0;
#endif
@ -161,11 +162,12 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[])
qse_fprintf (out, QSE_T(" -i perform in-place editing. imply -s\n"));
qse_fprintf (out, QSE_T(" -s process input files separately\n"));
qse_fprintf (out, QSE_T(" -a perform strict address and label check\n"));
qse_fprintf (out, QSE_T(" -w allow extended address formats\n"));
qse_fprintf (out, QSE_T(" -b allow extended address formats\n"));
qse_fprintf (out, QSE_T(" <start~step>,<start,+line>,<start,~line>,<0,/regex/>\n"));
qse_fprintf (out, QSE_T(" -x allow text on the same line as c, a, i\n"));
qse_fprintf (out, QSE_T(" -y ensure a newline at text end\n"));
qse_fprintf (out, QSE_T(" -m number specify the maximum amount of memory to use in bytes\n"));
qse_fprintf (out, QSE_T(" -w expand file wildcards\n"));
#if defined(QSE_ENABLE_SEDTRACER)
qse_fprintf (out, QSE_T(" -t print command traces\n"));
#endif
@ -246,9 +248,9 @@ static int handle_args (int argc, qse_char_t* argv[])
static qse_opt_t opt =
{
#if defined(QSE_BUILD_DEBUG)
QSE_T("hne:f:o:rRisawxytm:X:"),
QSE_T("hne:f:o:rRisabxytm:wX:"),
#else
QSE_T("hne:f:o:rRisawxytm:"),
QSE_T("hne:f:o:rRisabxytm:w"),
#endif
lng
};
@ -318,7 +320,7 @@ static int handle_args (int argc, qse_char_t* argv[])
g_option |= QSE_SED_STRICT;
break;
case QSE_T('w'):
case QSE_T('b'):
g_option |= QSE_SED_EXTENDEDADR;
break;
@ -343,6 +345,10 @@ static int handle_args (int argc, qse_char_t* argv[])
g_memlimit = qse_strtoulong (opt.arg);
break;
case QSE_T('w'):
g_wildcard = 1;
break;
#if defined(QSE_BUILD_DEBUG)
case QSE_T('X'):
g_failmalloc = qse_strtoulong (opt.arg);
@ -587,8 +593,6 @@ static void trace_exec (qse_sed_t* sed, qse_sed_exec_op_t op, const qse_sed_cmd_
}
#endif
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
struct xarg_t
{
qse_mmgr_t* mmgr;
@ -599,7 +603,7 @@ struct xarg_t
typedef struct xarg_t xarg_t;
static int collect (const qse_cstr_t* path, void* ctx)
static int collect_into_xarg (const qse_cstr_t* path, void* ctx)
{
xarg_t* xarg = (xarg_t*)ctx;
@ -633,10 +637,11 @@ static void purge_xarg (xarg_t* xarg)
xarg->size = 0;
xarg->capa = 0;
xarg->ptr = QSE_NULL;
}
}
static int expand (int argc, qse_char_t* argv[], xarg_t* xarg)
static int expand_wildcards (int argc, qse_char_t* argv[], int glob, xarg_t* xarg)
{
int i;
qse_cstr_t tmp;
@ -644,27 +649,30 @@ static int expand (int argc, qse_char_t* argv[], xarg_t* xarg)
for (i = 0; i < argc; i++)
{
int x;
x = qse_glob (argv[i], collect, xarg,
QSE_GLOB_NOESCAPE | QSE_GLOB_PERIOD | QSE_GLOB_IGNORECASE,
xarg->mmgr
);
if (x <= -1) return -1;
if (glob)
{
x = qse_glob (argv[i], collect_into_xarg, xarg,
QSE_GLOB_NOESCAPE | QSE_GLOB_PERIOD | QSE_GLOB_IGNORECASE,
xarg->mmgr
);
if (x <= -1) return -1;
}
else x = 0;
if (x == 0)
{
/* not expanded. just use it as is */
tmp.ptr = argv[i];
tmp.len = qse_strlen(argv[i]);
if (collect (&tmp, xarg) <= -1) return -1;
if (collect_into_xarg (&tmp, xarg) <= -1) return -1;
}
}
return 0;
}
#endif
static int sed_main (int argc, qse_char_t* argv[])
{
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
@ -673,10 +681,8 @@ static int sed_main (int argc, qse_char_t* argv[])
qse_size_t script_count;
int ret = -1;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
xarg_t xarg;
int xarg_inited = 0;
#endif
ret = handle_args (argc, argv);
if (ret <= -1) return -1;
@ -773,11 +779,9 @@ static int sed_main (int argc, qse_char_t* argv[])
if (g_trace) qse_sed_setexectracer (sed, trace_exec);
#endif
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
qse_memset (&xarg, 0, QSE_SIZEOF(xarg));
xarg.mmgr = qse_sed_getmmgr(sed);
xarg_inited = 1;
#endif
if (g_separate && g_infile_pos > 0)
{
@ -786,8 +790,7 @@ static int sed_main (int argc, qse_char_t* argv[])
qse_sed_iostd_t out_inplace;
qse_sed_iostd_t* output_file = QSE_NULL;
qse_sed_iostd_t* output = QSE_NULL;
qse_char_t** inptr;
int inpos, num_ins;
int inpos;
if (g_output_file &&
qse_strcmp (g_output_file, QSE_T("-")) != 0)
@ -812,29 +815,21 @@ static int sed_main (int argc, qse_char_t* argv[])
output = output_file;
}
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
/* perform wild-card expansions for non-unix platforms */
if (expand (argc - g_infile_pos, &argv[g_infile_pos], &xarg) <= -1)
if (expand_wildcards (argc - g_infile_pos, &argv[g_infile_pos], g_wildcard, &xarg) <= -1)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
goto oops;
}
num_ins = xarg.size;
inptr = xarg.ptr;
#else
num_ins = argc - g_infile_pos;
inptr = &argv[g_infile_pos];
#endif
for (inpos = 0; inpos < num_ins; inpos++)
for (inpos = 0; inpos < xarg.size; inpos++)
{
qse_sed_iostd_t in[2];
qse_char_t* tmpl_tmpfile;
in[0].type = QSE_SED_IOSTD_FILE;
in[0].u.file.path =
(qse_strcmp (inptr[inpos], QSE_T("-")) == 0)? QSE_NULL: inptr[inpos];
(qse_strcmp (xarg.ptr[inpos], QSE_T("-")) == 0)? QSE_NULL: xarg.ptr[inpos];
in[0].u.file.cmgr = g_infile_cmgr;
in[1].type = QSE_SED_IOSTD_NULL;
@ -931,39 +926,29 @@ static int sed_main (int argc, qse_char_t* argv[])
if (g_infile_pos > 0)
{
int i, num_ins;
int i;
const qse_char_t* tmp;
/* input files are specified on the command line */
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
/* perform wild-card expansions for non-unix platforms */
if (expand (argc - g_infile_pos, &argv[g_infile_pos], &xarg) <= -1)
if (expand_wildcards (argc - g_infile_pos, &argv[g_infile_pos], g_wildcard, &xarg) <= -1)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
goto oops;
}
num_ins = xarg.size;
#else
num_ins = argc - g_infile_pos;
#endif
in = QSE_MMGR_ALLOC (qse_sed_getmmgr(sed), QSE_SIZEOF(*in) * (num_ins + 1));
in = QSE_MMGR_ALLOC (qse_sed_getmmgr(sed), QSE_SIZEOF(*in) * (xarg.size + 1));
if (in == QSE_NULL)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
goto oops;
}
for (i = 0; i < num_ins; i++)
for (i = 0; i < xarg.size; i++)
{
in[i].type = QSE_SED_IOSTD_FILE;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
tmp = xarg.ptr[i];
#else
tmp = argv[g_infile_pos++];
#endif
in[i].u.file.path =
(qse_strcmp (tmp, QSE_T("-")) == 0)? QSE_NULL: tmp;
in[i].u.file.cmgr = g_infile_cmgr;
@ -1008,10 +993,7 @@ static int sed_main (int argc, qse_char_t* argv[])
ret = 0;
oops:
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
if (xarg_inited) purge_xarg (&xarg);
#endif
if (sed) qse_sed_close (sed);
if (fs) qse_fs_close (fs);
if (xma_mmgr.ctx) qse_xma_close (xma_mmgr.ctx);