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/main.h>
#include <qse/cmn/mbwc.h> #include <qse/cmn/mbwc.h>
#include <qse/cmn/xma.h> #include <qse/cmn/xma.h>
#include <qse/cmn/glob.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
@ -62,6 +63,17 @@
static qse_awk_rtx_t* app_rtx = QSE_NULL; static qse_awk_rtx_t* app_rtx = QSE_NULL;
static int app_debug = 0; 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 struct arg_t
{ {
qse_awk_parsestd_type_t ist; /* input source type */ qse_awk_parsestd_type_t ist; /* input source type */
@ -71,11 +83,9 @@ struct arg_t
qse_char_t** files; qse_char_t** files;
} isp; } isp;
qse_size_t isfl; /* the number of input source files */ qse_size_t isfl; /* the number of input source files */
qse_char_t* osf; /* output source file */ 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_htb_t* gvm; /* global variable map */
qse_char_t* fs; /* field separator */ qse_char_t* fs; /* field separator */
qse_char_t* call; /* function to call */ 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(" -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(" -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(" -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) #if defined(QSE_BUILD_DEBUG)
qse_fprintf (out, QSE_T(" -X number fail the number'th memory allocation\n")); qse_fprintf (out, QSE_T(" -X number fail the number'th memory allocation\n"));
#endif #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 int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
{ {
static qse_opt_lng_t lng[] = 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 = static qse_opt_t opt =
{ {
#if defined(QSE_BUILD_DEBUG) #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 #else
QSE_T("Dc:f:d:F:v:m:h"), QSE_T("hDc:f:d:F:v:m:w"),
#endif #endif
lng 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 isfc = 16; /* the capacity of isf */
qse_size_t isfl = 0; /* number of input source files */ 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** isf = QSE_NULL; /* input source files */
qse_char_t* osf = QSE_NULL; /* output source file */ 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_htb_t* gvm = QSE_NULL; /* global variable map */
qse_char_t* fs = QSE_NULL; /* field separator */ qse_char_t* fs = QSE_NULL; /* field separator */
qse_char_t* call = QSE_NULL; /* function to call */ qse_char_t* call = QSE_NULL; /* function to call */
int oops_ret = -1; int oops_ret = -1;
int do_glob = 0;
memset (arg, 0, QSE_SIZEOF(*arg));
isf = (qse_char_t**) malloc (QSE_SIZEOF(*isf) * isfc); isf = (qse_char_t**) malloc (QSE_SIZEOF(*isf) * isfc);
if (isf == QSE_NULL) if (isf == QSE_NULL)
@ -637,6 +722,12 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
break; break;
} }
case QSE_T('w'):
{
do_glob = 1;
break;
}
#if defined(QSE_BUILD_DEBUG) #if defined(QSE_BUILD_DEBUG)
case QSE_T('X'): 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) if (opt.ind < argc)
{ {
/* the remaining arguments are input console file names */ /* the remaining arguments are input console file names */
if (expand_wildcard (argc - opt.ind, &argv[opt.ind], do_glob, &arg->icf) <= -1)
icfc = argc - opt.ind + 1;
icf = (qse_char_t**) malloc (QSE_SIZEOF(qse_char_t*)*icfc);
if (icf == QSE_NULL)
{ {
print_error (QSE_T("out of memory\n")); print_error (QSE_T("out of memory\n"));
goto oops; 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->osf = osf;
arg->icf = icf;
arg->icfl = icfl;
arg->gvm = gvm; arg->gvm = gvm;
arg->fs = fs; arg->fs = fs;
arg->call = call; arg->call = call;
@ -779,7 +852,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
oops: oops:
if (gvm != QSE_NULL) qse_htb_close (gvm); if (gvm != QSE_NULL) qse_htb_close (gvm);
if (icf != QSE_NULL) free (icf); purge_xarg (&arg->icf);
if (isf != QSE_NULL) free (isf); if (isf != QSE_NULL) free (isf);
return oops_ret; return oops_ret;
} }
@ -789,7 +862,7 @@ static void freearg (struct arg_t* arg)
if (arg->ist == QSE_AWK_PARSESTD_FILE && if (arg->ist == QSE_AWK_PARSESTD_FILE &&
arg->isp.files != QSE_NULL) free (arg->isp.files); arg->isp.files != QSE_NULL) free (arg->isp.files);
/*if (arg->osf != QSE_NULL) free (arg->osf);*/ /*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); 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(); qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
memset (&arg, 0, QSE_SIZEOF(arg)); memset (&arg, 0, QSE_SIZEOF(arg));
arg.icf.mmgr = mmgr;
i = comparg (argc, argv, &arg); i = comparg (argc, argv, &arg);
if (i <= 0) if (i <= 0)
@ -1010,7 +1084,8 @@ static int awk_main (int argc, qse_char_t* argv[])
rtx = qse_awk_rtx_openstd ( rtx = qse_awk_rtx_openstd (
awk, 0, QSE_T("qseawk"), 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) if (rtx == QSE_NULL)
{ {
print_awkerr (awk); print_awkerr (awk);

View File

@ -70,6 +70,7 @@ static int g_infile_pos = 0;
static int g_option = 0; static int g_option = 0;
static int g_separate = 0; static int g_separate = 0;
static int g_inplace = 0; static int g_inplace = 0;
static int g_wildcard = 0;
#if defined(QSE_ENABLE_SEDTRACER) #if defined(QSE_ENABLE_SEDTRACER)
static int g_trace = 0; static int g_trace = 0;
#endif #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(" -i perform in-place editing. imply -s\n"));
qse_fprintf (out, QSE_T(" -s process input files separately\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(" -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(" <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(" -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(" -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(" -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) #if defined(QSE_ENABLE_SEDTRACER)
qse_fprintf (out, QSE_T(" -t print command traces\n")); qse_fprintf (out, QSE_T(" -t print command traces\n"));
#endif #endif
@ -246,9 +248,9 @@ static int handle_args (int argc, qse_char_t* argv[])
static qse_opt_t opt = static qse_opt_t opt =
{ {
#if defined(QSE_BUILD_DEBUG) #if defined(QSE_BUILD_DEBUG)
QSE_T("hne:f:o:rRisawxytm:X:"), QSE_T("hne:f:o:rRisabxytm:wX:"),
#else #else
QSE_T("hne:f:o:rRisawxytm:"), QSE_T("hne:f:o:rRisabxytm:w"),
#endif #endif
lng lng
}; };
@ -318,7 +320,7 @@ static int handle_args (int argc, qse_char_t* argv[])
g_option |= QSE_SED_STRICT; g_option |= QSE_SED_STRICT;
break; break;
case QSE_T('w'): case QSE_T('b'):
g_option |= QSE_SED_EXTENDEDADR; g_option |= QSE_SED_EXTENDEDADR;
break; break;
@ -343,6 +345,10 @@ static int handle_args (int argc, qse_char_t* argv[])
g_memlimit = qse_strtoulong (opt.arg); g_memlimit = qse_strtoulong (opt.arg);
break; break;
case QSE_T('w'):
g_wildcard = 1;
break;
#if defined(QSE_BUILD_DEBUG) #if defined(QSE_BUILD_DEBUG)
case QSE_T('X'): case QSE_T('X'):
g_failmalloc = qse_strtoulong (opt.arg); 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 #endif
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
struct xarg_t struct xarg_t
{ {
qse_mmgr_t* mmgr; qse_mmgr_t* mmgr;
@ -599,7 +603,7 @@ struct xarg_t
typedef struct xarg_t 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; xarg_t* xarg = (xarg_t*)ctx;
@ -633,10 +637,11 @@ static void purge_xarg (xarg_t* xarg)
xarg->size = 0; xarg->size = 0;
xarg->capa = 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; int i;
qse_cstr_t tmp; 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++) for (i = 0; i < argc; i++)
{ {
int x; int x;
x = qse_glob (argv[i], collect, xarg,
if (glob)
{
x = qse_glob (argv[i], collect_into_xarg, xarg,
QSE_GLOB_NOESCAPE | QSE_GLOB_PERIOD | QSE_GLOB_IGNORECASE, QSE_GLOB_NOESCAPE | QSE_GLOB_PERIOD | QSE_GLOB_IGNORECASE,
xarg->mmgr xarg->mmgr
); );
if (x <= -1) return -1; if (x <= -1) return -1;
}
else x = 0;
if (x == 0) if (x == 0)
{ {
/* not expanded. just use it as is */ /* not expanded. just use it as is */
tmp.ptr = argv[i]; tmp.ptr = argv[i];
tmp.len = qse_strlen(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; return 0;
} }
#endif
static int sed_main (int argc, qse_char_t* argv[]) static int sed_main (int argc, qse_char_t* argv[])
{ {
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL(); 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; qse_size_t script_count;
int ret = -1; int ret = -1;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
xarg_t xarg; xarg_t xarg;
int xarg_inited = 0; int xarg_inited = 0;
#endif
ret = handle_args (argc, argv); ret = handle_args (argc, argv);
if (ret <= -1) return -1; 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); if (g_trace) qse_sed_setexectracer (sed, trace_exec);
#endif #endif
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
qse_memset (&xarg, 0, QSE_SIZEOF(xarg)); qse_memset (&xarg, 0, QSE_SIZEOF(xarg));
xarg.mmgr = qse_sed_getmmgr(sed); xarg.mmgr = qse_sed_getmmgr(sed);
xarg_inited = 1; xarg_inited = 1;
#endif
if (g_separate && g_infile_pos > 0) 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 out_inplace;
qse_sed_iostd_t* output_file = QSE_NULL; qse_sed_iostd_t* output_file = QSE_NULL;
qse_sed_iostd_t* output = QSE_NULL; qse_sed_iostd_t* output = QSE_NULL;
qse_char_t** inptr; int inpos;
int inpos, num_ins;
if (g_output_file && if (g_output_file &&
qse_strcmp (g_output_file, QSE_T("-")) != 0) 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; output = output_file;
} }
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
/* perform wild-card expansions for non-unix platforms */ /* 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")); qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
goto oops; goto oops;
} }
num_ins = xarg.size; for (inpos = 0; inpos < xarg.size; inpos++)
inptr = xarg.ptr;
#else
num_ins = argc - g_infile_pos;
inptr = &argv[g_infile_pos];
#endif
for (inpos = 0; inpos < num_ins; inpos++)
{ {
qse_sed_iostd_t in[2]; qse_sed_iostd_t in[2];
qse_char_t* tmpl_tmpfile; qse_char_t* tmpl_tmpfile;
in[0].type = QSE_SED_IOSTD_FILE; in[0].type = QSE_SED_IOSTD_FILE;
in[0].u.file.path = 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[0].u.file.cmgr = g_infile_cmgr;
in[1].type = QSE_SED_IOSTD_NULL; 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) if (g_infile_pos > 0)
{ {
int i, num_ins; int i;
const qse_char_t* tmp; const qse_char_t* tmp;
/* input files are specified on the command line */ /* input files are specified on the command line */
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
/* perform wild-card expansions for non-unix platforms */ /* 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")); qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
goto oops; goto oops;
} }
num_ins = xarg.size; in = QSE_MMGR_ALLOC (qse_sed_getmmgr(sed), QSE_SIZEOF(*in) * (xarg.size + 1));
#else
num_ins = argc - g_infile_pos;
#endif
in = QSE_MMGR_ALLOC (qse_sed_getmmgr(sed), QSE_SIZEOF(*in) * (num_ins + 1));
if (in == QSE_NULL) if (in == QSE_NULL)
{ {
qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n")); qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
goto oops; goto oops;
} }
for (i = 0; i < num_ins; i++) for (i = 0; i < xarg.size; i++)
{ {
in[i].type = QSE_SED_IOSTD_FILE; in[i].type = QSE_SED_IOSTD_FILE;
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
tmp = xarg.ptr[i]; tmp = xarg.ptr[i];
#else
tmp = argv[g_infile_pos++];
#endif
in[i].u.file.path = in[i].u.file.path =
(qse_strcmp (tmp, QSE_T("-")) == 0)? QSE_NULL: tmp; (qse_strcmp (tmp, QSE_T("-")) == 0)? QSE_NULL: tmp;
in[i].u.file.cmgr = g_infile_cmgr; in[i].u.file.cmgr = g_infile_cmgr;
@ -1008,10 +993,7 @@ static int sed_main (int argc, qse_char_t* argv[])
ret = 0; ret = 0;
oops: oops:
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
if (xarg_inited) purge_xarg (&xarg); if (xarg_inited) purge_xarg (&xarg);
#endif
if (sed) qse_sed_close (sed); if (sed) qse_sed_close (sed);
if (fs) qse_fs_close (fs); if (fs) qse_fs_close (fs);
if (xma_mmgr.ctx) qse_xma_close (xma_mmgr.ctx); if (xma_mmgr.ctx) qse_xma_close (xma_mmgr.ctx);