diff --git a/ase/cmd/awk/awk.c b/ase/cmd/awk/awk.c index 2933506c..c84c7090 100644 --- a/ase/cmd/awk/awk.c +++ b/ase/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 468 2008-12-10 10:19:59Z baconevi $ + * $Id: awk.c 469 2008-12-11 10:05:28Z baconevi $ */ #include @@ -122,527 +122,6 @@ static int custom_awk_sprintf ( return n; } -static ase_ssize_t awk_extio_pipe ( - int cmd, void* arg, ase_char_t* data, ase_size_t size) -{ - ase_awk_extio_t* epa = (ase_awk_extio_t*)arg; - - switch (cmd) - { - case ASE_AWK_IO_OPEN: - { - FILE* handle; - const ase_char_t* mode; - - if (epa->mode == ASE_AWK_EXTIO_PIPE_READ) - mode = ASE_T("r"); - else if (epa->mode == ASE_AWK_EXTIO_PIPE_WRITE) - mode = ASE_T("w"); - else return -1; /* TODO: any way to set the error number? */ - - dprint (ASE_T("opening %s of type %d (pipe)\n"), epa->name, epa->type); - handle = ase_popen (epa->name, mode); - if (handle == NULL) return -1; - epa->handle = (void*)handle; - return 1; - } - - case ASE_AWK_IO_CLOSE: - { - dprint (ASE_T("closing %s of type (pipe) %d\n"), epa->name, epa->type); - fclose ((FILE*)epa->handle); - epa->handle = NULL; - return 0; - } - - case ASE_AWK_IO_READ: - { - /* - int chunk = (size > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): (int)size; - if (ase_fgets (data, chunk, (FILE*)epa->handle) == ASE_NULL) - { - if (ferror((FILE*)epa->handle)) return -1; - return 0; - } - return ase_strlen(data); - */ - ase_ssize_t n = 0; - FILE* fp = (FILE*)epa->handle; - while (!ase_feof(fp) && n < size) - { - ase_cint_t c = ase_fgetc (fp); - if (c == ASE_CHAR_EOF) - { - if (ase_ferror(fp)) n = -1; - break; - } - data[n++] = c; - } - return n; - } - - case ASE_AWK_IO_WRITE: - { - FILE* fp = (FILE*)epa->handle; - size_t left = size; - - while (left > 0) - { - if (*data == ASE_T('\0')) - { - #if defined(ASE_CHAR_IS_WCHAR) && defined(__linux) - if (fputc ('\0', fp) == EOF) - #else - if (ase_fputc (*data, fp) == ASE_CHAR_EOF) - #endif - { - return -1; - } - left -= 1; data += 1; - } - else - { - #if defined(ASE_CHAR_IS_WCHAR) && defined(__linux) - /* fwprintf seems to return an error with the file - * pointer opened by popen, as of this writing. - * anyway, hopefully the following replacement - * will work all the way. */ - int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): (int)left; - int n = fprintf (fp, "%.*ls", chunk, data); - if (n >= 0) - { - size_t x; - for (x = 0; x < chunk; x++) - { - if (data[x] == ASE_T('\0')) break; - } - n = x; - } - #else - int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): (int)left; - int n = ase_fprintf (fp, ASE_T("%.*s"), chunk, data); - #endif - - if (n < 0 || n > chunk) return -1; - left -= n; data += n; - } - } - - return size; - } - - case ASE_AWK_IO_FLUSH: - { - if (epa->mode == ASE_AWK_EXTIO_PIPE_READ) return -1; - return fflush ((FILE*)epa->handle); - } - - case ASE_AWK_IO_NEXT: - { - return -1; - } - } - - return -1; -} - -static ase_ssize_t awk_extio_file ( - int cmd, void* arg, ase_char_t* data, ase_size_t size) -{ - ase_awk_extio_t* epa = (ase_awk_extio_t*)arg; - - switch (cmd) - { - case ASE_AWK_IO_OPEN: - { - FILE* handle; - const ase_char_t* mode; - - if (epa->mode == ASE_AWK_EXTIO_FILE_READ) - mode = ASE_T("r"); - else if (epa->mode == ASE_AWK_EXTIO_FILE_WRITE) - mode = ASE_T("w"); - else if (epa->mode == ASE_AWK_EXTIO_FILE_APPEND) - mode = ASE_T("a"); - else return -1; /* TODO: any way to set the error number? */ - - dprint (ASE_T("opening %s of type %d (file)\n"), epa->name, epa->type); - handle = ase_fopen (epa->name, mode); - if (handle == NULL) - { - ase_cstr_t errarg; - - errarg.ptr = epa->name; - errarg.len = ase_strlen(epa->name); - - ase_awk_setrunerror (epa->run, ASE_AWK_EOPEN, 0, &errarg, 1); - return -1; - } - - epa->handle = (void*)handle; - return 1; - } - - case ASE_AWK_IO_CLOSE: - { - dprint (ASE_T("closing %s of type %d (file)\n"), epa->name, epa->type); - fclose ((FILE*)epa->handle); - epa->handle = NULL; - return 0; - } - - case ASE_AWK_IO_READ: - { - /* - int chunk = (size > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): (int)size; - if (ase_fgets (data, chunk, (FILE*)epa->handle) == ASE_NULL) - { - if (ferror((FILE*)epa->handle)) return -1; - return 0; - } - return ase_strlen(data); - */ - ase_ssize_t n = 0; - FILE* fp = (FILE*)epa->handle; - while (!ase_feof(fp) && n < size) - { - ase_cint_t c = ase_fgetc (fp); - if (c == ASE_CHAR_EOF) - { - if (ase_ferror(fp)) n = -1; - break; - } - data[n++] = c; - } - return n; - } - - case ASE_AWK_IO_WRITE: - { - FILE* fp = (FILE*)epa->handle; - ase_ssize_t left = size; - - while (left > 0) - { - if (*data == ASE_T('\0')) - { - if (ase_fputc (*data, fp) == ASE_CHAR_EOF) return -1; - left -= 1; data += 1; - } - else - { - int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): (int)left; - int n = ase_fprintf (fp, ASE_T("%.*s"), chunk, data); - if (n < 0) return -1; - left -= n; data += n; - } - } - - return size; - } - - case ASE_AWK_IO_FLUSH: - { - if (fflush ((FILE*)epa->handle) == EOF) return -1; - return 0; - } - - case ASE_AWK_IO_NEXT: - { - return -1; - } - - } - - return -1; -} - -static int open_extio_console (ase_awk_extio_t* epa); -static int close_extio_console (ase_awk_extio_t* epa); -static int next_extio_console (ase_awk_extio_t* epa); - -static ase_ssize_t getdata (ase_char_t* data, ase_size_t size, FILE* fp) -{ - ase_ssize_t n = 0; - while (!ase_feof(fp) && n < size) - { - ase_cint_t c = ase_fgetc (fp); - if (c == ASE_CHAR_EOF) - { - if (ase_ferror(fp)) n = -1; - break; - } - data[n++] = c; - if (c == ASE_T('\n')) break; - } - return n; -} - -static ase_ssize_t awk_extio_console ( - int cmd, void* arg, ase_char_t* data, ase_size_t size) -{ - ase_awk_extio_t* epa = (ase_awk_extio_t*)arg; - runio_data_t* rd = (runio_data_t*)epa->data; - - if (cmd == ASE_AWK_IO_OPEN) - { - return open_extio_console (epa); - } - else if (cmd == ASE_AWK_IO_CLOSE) - { - return close_extio_console (epa); - } - else if (cmd == ASE_AWK_IO_READ) - { - ase_ssize_t n; - /*int chunk = (size > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): (int)size; - - while (ase_fgets (data, chunk, (FILE*)epa->handle) == ASE_NULL) - { - if (ferror((FILE*)epa->handle)) return -1;*/ - - while ((n = getdata(data,size,(FILE*)epa->handle)) == 0) - { - /* it has reached the end of the current file. - * open the next file if available */ - if (rd->icf[rd->icf_no] == ASE_NULL) - { - /* no more input console */ - return 0; - } - - if (rd->icf[rd->icf_no][0] == ASE_T('\0')) - { - if (epa->handle != ASE_NULL && - epa->handle != stdin && - epa->handle != stdout && - epa->handle != stderr) - { - /* TODO: ................................ */ - if (fclose ((FILE*)epa->handle) == EOF) - { - ase_cstr_t errarg; - - errarg.ptr = ASE_T("console"); - errarg.len = 7; - - ase_awk_setrunerror (epa->run, ASE_AWK_ECLOSE, 0, &errarg, 1); - return -1; - } - } - - epa->handle = stdin; - } - else - { - FILE* fp = ase_fopen (rd->icf[rd->icf_no], ASE_T("r")); - if (fp == ASE_NULL) - { - ase_cstr_t errarg; - - errarg.ptr = rd->icf[rd->icf_no]; - errarg.len = ase_strlen(rd->icf[rd->icf_no]); - - ase_awk_setrunerror (epa->run, ASE_AWK_EOPEN, 0, &errarg, 1); - return -1; - } - - if (ase_awk_setfilename ( - epa->run, rd->icf[rd->icf_no], - ase_strlen(rd->icf[rd->icf_no])) == -1) - { - fclose (fp); - return -1; - } - - if (ase_awk_setglobal ( - epa->run, ASE_AWK_GLOBAL_FNR, ase_awk_val_zero) == -1) - { - /* need to reset FNR */ - fclose (fp); - return -1; - } - - if (epa->handle != ASE_NULL && - epa->handle != stdin && - epa->handle != stdout && - epa->handle != stderr) - { - /* TODO: ................................ */ - if (fclose ((FILE*)epa->handle) == EOF) - { - ase_cstr_t errarg; - - errarg.ptr = ASE_T("console"); - errarg.len = 7; - - ase_awk_setrunerror (epa->run, ASE_AWK_ECLOSE, 0, &errarg, 1); - - fclose (fp); - return -1; - } - } - - dprint (ASE_T("open the next console [%s]\n"), rd->icf[rd->icf_no]); - epa->handle = fp; - } - - rd->icf_no++; - } - - /*return ase_strlen(data);*/ - return n; - } - else if (cmd == ASE_AWK_IO_WRITE) - { - FILE* fp = (FILE*)epa->handle; - ase_ssize_t left = size; - - while (left > 0) - { - if (*data == ASE_T('\0')) - { - if (ase_fputc (*data, fp) == ASE_CHAR_EOF) return -1; - left -= 1; data += 1; - } - else - { - int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): (int)left; - int n = ase_fprintf (fp, ASE_T("%.*s"), chunk, data); - if (n < 0) return -1; - left -= n; data += n; - } - } - - return size; - } - else if (cmd == ASE_AWK_IO_FLUSH) - { - if (fflush ((FILE*)epa->handle) == EOF) return -1; - return 0; - } - else if (cmd == ASE_AWK_IO_NEXT) - { - return next_extio_console (epa); - } - - return -1; -} - -static int open_extio_console (ase_awk_extio_t* epa) -{ - runio_data_t* rd = (runio_data_t*)epa->data; - /* TODO: OpenConsole in GUI APPLICATION */ - - dprint (ASE_T("opening console[%s] of type %x\n"), epa->name, epa->type); - - if (epa->mode == ASE_AWK_EXTIO_CONSOLE_READ) - { - if (rd->icf[rd->icf_no] == ASE_NULL) - { - /* no more input file */ - dprint (ASE_T("console - no more file\n"));; - return 0; - } - - if (rd->icf[rd->icf_no][0] == ASE_T('\0')) - { - dprint (ASE_T(" console(r) - \n")); - epa->handle = stdin; - } - else - { - /* a temporary variable fp is used here not to change - * any fields of epa when the open operation fails */ - FILE* fp = ase_fopen (rd->icf[rd->icf_no], ASE_T("r")); - if (fp == ASE_NULL) - { - ase_cstr_t errarg; - - errarg.ptr = rd->icf[rd->icf_no]; - errarg.len = ase_strlen(rd->icf[rd->icf_no]); - - ase_awk_setrunerror (epa->run, ASE_AWK_EOPEN, 0, &errarg, 1); - return -1; - } - - dprint (ASE_T(" console(r) - %s\n"), rd->icf[rd->icf_no]); - if (ase_awk_setfilename ( - epa->run, rd->icf[rd->icf_no], - ase_strlen(rd->icf[rd->icf_no])) == -1) - { - fclose (fp); - return -1; - } - - epa->handle = fp; - } - - rd->icf_no++; - return 1; - } - else if (epa->mode == ASE_AWK_EXTIO_CONSOLE_WRITE) - { - dprint (ASE_T(" console(w) - \n")); - - if (ase_awk_setofilename (epa->run, ASE_T(""), 0) == -1) - { - return -1; - } - - epa->handle = stdout; - return 1; - } - - return -1; -} - -static int close_extio_console (ase_awk_extio_t* epa) -{ - dprint (ASE_T("closing console of type %x\n"), epa->type); - - if (epa->handle != ASE_NULL && - epa->handle != stdin && - epa->handle != stdout && - epa->handle != stderr) - { - if (fclose ((FILE*)epa->handle) == EOF) - { - ase_cstr_t errarg; - - errarg.ptr = epa->name; - errarg.len = ase_strlen(epa->name); - - ase_awk_setrunerror (epa->run, ASE_AWK_ECLOSE, 0, &errarg, 1); - return -1; - } - } - - return 0; -} - -static int next_extio_console (ase_awk_extio_t* epa) -{ - int n; - FILE* fp = (FILE*)epa->handle; - - dprint (ASE_T("switching console[%s] of type %x\n"), epa->name, epa->type); - - n = open_extio_console(epa); - if (n == -1) return -1; - - if (n == 0) - { - /* if there is no more file, keep the previous handle */ - return 0; - } - - if (fp != ASE_NULL && fp != stdin && - fp != stdout && fp != stderr) fclose (fp); - - return n; -} - ase_awk_t* app_awk = NULL; ase_awk_run_t* app_run = NULL; @@ -720,7 +199,7 @@ static void on_run_return ( } dprint (ASE_T("[NAMED VARIABLES]\n")); - ase_map_walk (ase_awk_getrunnamedvarmap(run), print_awk_value, run); + ase_map_walk (ase_awk_getrunnvmap(run), print_awk_value, run); dprint (ASE_T("[END NAMED VARIABLES]\n")); } @@ -781,42 +260,6 @@ static void print_usage (const ase_char_t* argv0) } } -static int run_awk ( - ase_awk_t* awk, const ase_char_t* mfn, - ase_awk_runarg_t* runarg, ase_char_t** icf) -{ - ase_awk_runcbs_t runcbs; - ase_awk_runios_t runios; - runio_data_t rd; - - rd.icf = icf; - rd.icf_no = 0; - - runios.pipe = awk_extio_pipe; - runios.file = awk_extio_file; - runios.console = awk_extio_console; - runios.data = &rd; - - runcbs.on_start = on_run_start; - runcbs.on_statement = on_run_statement; - runcbs.on_return = on_run_return; - runcbs.on_end = on_run_end; - runcbs.data = ASE_NULL; - - if (ase_awk_run (awk, mfn, &runios, &runcbs, runarg, ASE_NULL) == -1) - { - ase_printf ( - ASE_T("RUN ERROR: CODE [%d] LINE [%u] %s\n"), - ase_awk_geterrnum(awk), - (unsigned int)ase_awk_geterrlin(awk), - ase_awk_geterrmsg(awk)); - - return -1; - } - - return 0; -} - static int bfn_sleep ( ase_awk_run_t* run, const ase_char_t* fnm, ase_size_t fnl) { @@ -1231,7 +674,9 @@ static int awk_main (int argc, ase_char_t* argv[]) ASE_T("PARSE ERROR: CODE [%d] LINE [%u] %s\n"), ase_awk_geterrnum(awk), (unsigned int)ase_awk_geterrlin(awk), - ase_awk_geterrmsg(awk)); + ase_awk_geterrmsg(awk) + ); + close_awk (awk); return -1; } @@ -1243,8 +688,15 @@ static int awk_main (int argc, ase_char_t* argv[]) signal (SIGINT, stop_run); #endif - if (run_awk (awk, mfn, runarg, ao.icf) == -1) + if (ase_awk_runsimple (awk, ao.icf) == -1) { + ase_printf ( + ASE_T("RUN ERROR: CODE [%d] LINE [%u] %s\n"), + ase_awk_geterrnum(awk), + (unsigned int)ase_awk_geterrlin(awk), + ase_awk_geterrmsg(awk) + ); + close_awk (awk); return -1; } diff --git a/ase/include/ase/awk/awk.h b/ase/include/ase/awk/awk.h index b49288b4..f9ef8e73 100644 --- a/ase/include/ase/awk/awk.h +++ b/ase/include/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 468 2008-12-10 10:19:59Z baconevi $ + * $Id: awk.h 469 2008-12-11 10:05:28Z baconevi $ * * {License} */ @@ -700,7 +700,7 @@ void ase_awk_setprmfns ( * you may call ase_awk_close instead of destroying and creating a new * ase_awk_t instance using ase_awk_close() and ase_awk_open(). * - * RETURNS 0 on success, -1 on failure + * RETURN 0 on success, -1 on failure */ int ase_awk_clear ( /* the pointer to an ase_awk_t instance */ @@ -850,6 +850,18 @@ int ase_awk_parsesimple ( ); /******/ +/****f* ase.awk/ase_awk_runsimple + * NAME + * ase_awk_runsimple - run a parsed program + * + * SYNOPSIS + */ +int ase_awk_runsimple ( + ase_awk_t* awk, + ase_char_t** icf /* input console files */ +); +/******/ + /** * Executes a parsed program. * @@ -887,47 +899,117 @@ ase_size_t ase_awk_getnargs (ase_awk_run_t* run); */ ase_awk_val_t* ase_awk_getarg (ase_awk_run_t* run, ase_size_t idx); -/** - * Gets the value of a global variable. +/****f* ase.awk/ase_awk_getglobal + * NAME + * ase_awk_getglobal - gets the value of a global variable * - * @param run A run-time context - * @param id The ID to a global variable. - * This value correspondsto the predefined global variable IDs or - * the value returned by ase_awk_addglobal. - * @return - * The pointer to a value is returned. This function never fails - * so long as id is valid. Otherwise, you may fall into trouble. + * PARAMETERS + * id - A global variable id. An ID is one of the predefined global + * variable IDs or the value returned by ase_awk_addglobal(). + * + * RETURN + * The pointer to a value is returned. This function never fails + * so long as id is valid. Otherwise, you may fall into trouble. */ -ase_awk_val_t* ase_awk_getglobal (ase_awk_run_t* run, int id); -int ase_awk_setglobal (ase_awk_run_t* run, int id, ase_awk_val_t* val); +ase_awk_val_t* ase_awk_getglobal ( + ase_awk_run_t* run, + int id +); +/******/ -/** - * Sets the return value of a function from within a function handler. +int ase_awk_setglobal ( + ase_awk_run_t* run, + int id, + ase_awk_val_t* val +); + +/****f* ase.awk/ase_awk_setretval + * NAME + * ase_awk_setretval - set the return value * - * @param run A run-time context - * @param val A pointer to the value to set. - * ase_awk_refupval and ase_awk_refdownval are not needed because - * ase_awk_setretval never fails and it updates the reference count - * of the value properly. + * DESCRIPTION + * The ase_awk_setretval() sets the return value of a function + * when called from within a function handlers. The caller doesn't + * have to invoke ase_awk_refupval() and ase_awk_refdownval() + * with the value to be passed to ase_awk_setretval(). + * The ase_awk_setretval() will update its reference count properly + * once the return value is set. */ -void ase_awk_setretval (ase_awk_run_t* run, ase_awk_val_t* val); +void ase_awk_setretval ( + ase_awk_run_t* run, + ase_awk_val_t* val +); int ase_awk_setfilename ( ase_awk_run_t* run, const ase_char_t* name, ase_size_t len); int ase_awk_setofilename ( ase_awk_run_t* run, const ase_char_t* name, ase_size_t len); -ase_awk_t* ase_awk_getrunawk (ase_awk_run_t* awk); -void* ase_awk_getruncustomdata (ase_awk_run_t* awk); -ase_map_t* ase_awk_getrunnamedvarmap (ase_awk_run_t* awk); + +/****f* ase.awk/ase_awk_getrunawk + * NAME + * ase_awk_getrunawk - get the owning awk object + * + * SYNOPSIS + */ +ase_awk_t* ase_awk_getrunawk ( + ase_awk_run_t* run +); +/******/ + +/****f* ase.awk/ase_awk_getrunmmgr + * NAME + * ase_awk_getrunmmgr - get the memory manager of a run object + * + * SYNOPSIS + */ +ase_mmgr_t* ase_awk_getrunmmgr ( + ase_awk_run_t* run +); +/******/ + +/****f* ase.awk/ase_awk_getrundata + * NAME + * ase_awk_getrundata - get the user-specified data for a run object + * + * SYNOPSIS + */ +void* ase_awk_getrundata ( + ase_awk_run_t* awk +); +/******/ + +/****f* ase.awk/ase_awk_getrunnvmap + * NAME + * ase_awk_getrunnvmap - get the map of named variables + * + * SYNOPSIS + */ +ase_map_t* ase_awk_getrunnvmap ( + ase_awk_run_t* run +); +/******/ /* functions to manipulate the run-time error */ -int ase_awk_getrunerrnum (ase_awk_run_t* run); -ase_size_t ase_awk_getrunerrlin (ase_awk_run_t* run); -const ase_char_t* ase_awk_getrunerrmsg (ase_awk_run_t* run); -void ase_awk_setrunerrnum (ase_awk_run_t* run, int errnum); -void ase_awk_setrunerrmsg (ase_awk_run_t* run, - int errnum, ase_size_t errlin, const ase_char_t* errmsg); +int ase_awk_getrunerrnum ( + ase_awk_run_t* run +); +ase_size_t ase_awk_getrunerrlin ( + ase_awk_run_t* run +); +const ase_char_t* ase_awk_getrunerrmsg ( + ase_awk_run_t* run +); +void ase_awk_setrunerrnum ( + ase_awk_run_t* run, + int errnum +); +void ase_awk_setrunerrmsg ( + ase_awk_run_t* run, + int errnum, + ase_size_t errlin, + const ase_char_t* errmsg +); void ase_awk_getrunerror ( ase_awk_run_t* run, int* errnum, diff --git a/ase/lib/awk/Awk.cpp b/ase/lib/awk/Awk.cpp index f0e7e6b8..41d5c385 100644 --- a/ase/lib/awk/Awk.cpp +++ b/ase/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 468 2008-12-10 10:19:59Z baconevi $ + * $Id: Awk.cpp 469 2008-12-11 10:05:28Z baconevi $ * * {License} */ @@ -1673,7 +1673,7 @@ Awk::ssize_t Awk::consoleHandler ( int Awk::functionHandler ( run_t* run, const char_t* name, size_t len) { - Run* ctx = (Run*) ase_awk_getruncustomdata (run); + Run* ctx = (Run*) ase_awk_getrundata (run); Awk* awk = ctx->awk; return awk->dispatchFunction (ctx, name, len); } diff --git a/ase/lib/awk/run.c b/ase/lib/awk/run.c index 955a547b..f864db27 100644 --- a/ase/lib/awk/run.c +++ b/ase/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 466 2008-12-09 09:50:40Z baconevi $ + * $Id: run.c 469 2008-12-11 10:05:28Z baconevi $ * * {License} */ @@ -599,12 +599,17 @@ ase_awk_t* ase_awk_getrunawk (ase_awk_run_t* run) return run->awk; } -void* ase_awk_getruncustomdata (ase_awk_run_t* run) +ase_mmgr_t* ase_awk_getrunmmgr (ase_awk_run_t* run) +{ + return run->awk->mmgr; +} + +void* ase_awk_getrundata (ase_awk_run_t* run) { return run->data; } -ase_map_t* ase_awk_getrunnamedvarmap (ase_awk_run_t* run) +ase_map_t* ase_awk_getrunnvmap (ase_awk_run_t* run) { return run->named; } diff --git a/ase/lib/awk/std.c b/ase/lib/awk/std.c index 81c8c945..c9ba632f 100644 --- a/ase/lib/awk/std.c +++ b/ase/lib/awk/std.c @@ -87,6 +87,9 @@ static ase_ssize_t sf_in (int cmd, void* arg, ase_char_t* data, ase_size_t size) if (cmd == ASE_AWK_IO_OPEN) { if (sf->in.index >= sf->in.count) return 0; + /* + if (sf->in.files[sf->in.index] == ASE_NULL) return 0; + */ if (sf->in.files[sf->in.index][0] == ASE_T('\0')) { @@ -111,8 +114,14 @@ static ase_ssize_t sf_in (int cmd, void* arg, ase_char_t* data, ase_size_t size) } else if (cmd == ASE_AWK_IO_CLOSE) { - if (sf->in.index >= sf->in.count) return 0; - if (sf->in.handle != ase_sio_in) ase_sio_close (sf->in.handle); + if (sf->in.handle != ASE_NULL && + sf->in.handle != ase_sio_in && + sf->in.handle != ase_sio_out && + sf->in.handle != ase_sio_err) + { + ase_sio_close (sf->in.handle); + } + return 0; } else if (cmd == ASE_AWK_IO_READ) @@ -141,49 +150,15 @@ static ase_ssize_t sf_in (int cmd, void* arg, ase_char_t* data, ase_size_t size) ); if (sf->in.handle == ASE_NULL) return -1; } + /* TODO: reset internal line counters... + set new source name.... ase_awk_setsinname (); */ + goto retry; } - #if 0 - while (!ase_feof(fp) && n < size) - { - ase_cint_t c = ase_fgetc (fp); - if (c == ASE_CHAR_EOF) - { - if (ase_ferror(fp)) n = -1; - break; - } - data[n++] = c; - } - - if (n == 0) - { - sf->in.index++; - if (sf->in.index < sf->in.count) - { - if (fp != ase_sio_in) ase_sio_close (fp); - if (sf->in.files[sf->in.index][0] == ASE_T('\0')) - { - sf->in.handle = ase_sio_in; - } - else - { - sf->in.handle = ase_sio_open ( - ase_awk_getmmgr(sf->awk), 0, - sf->in.files[sf->in.index], ASE_SIO_READ); - if (sf->in.handle == ASE_NULL) return -1; - } - /* TODO: reset internal line counters... - ase_awk_setsinname (); - */ - goto retry; - } - } - #endif - return n; } @@ -215,9 +190,17 @@ static ase_ssize_t sf_out (int cmd, void* arg, ase_char_t* data, ase_size_t size } else if (cmd == ASE_AWK_IO_CLOSE) { - ase_sio_flush (sf->out.handle); - if (sf->out.handle != ase_sio_out && - sf->out.handle != ase_sio_err) ase_sio_close (sf->out.handle); + if (sf->out.handle != ASE_NULL) + { + ase_sio_flush (sf->out.handle); + if (sf->out.handle != ase_sio_in && + sf->out.handle != ase_sio_out && + sf->out.handle != ase_sio_err) + { + ase_sio_close (sf->out.handle); + } + } + return 0; } else if (cmd == ASE_AWK_IO_WRITE) @@ -280,6 +263,7 @@ int ase_awk_parsesimple ( } sf.out.file = osf; + sf.out.handle = ASE_NULL; sf.awk = awk; sio.in = sf_in; @@ -291,8 +275,443 @@ int ase_awk_parsesimple ( /*** RUNSIMPLE ***/ -ase_awk_run_t* ase_awk_runsimple ( - ase_awk_t* awk, ase_size_t argc, const char* args[]) +typedef struct runio_data_t { - return ASE_NULL; + ase_char_t** icf; /* input console files */ + ase_size_t icf_cur; +} runio_data_t; + +static ase_ssize_t awk_extio_pipe ( + int cmd, void* arg, ase_char_t* data, ase_size_t size) +{ + ase_awk_extio_t* epa = (ase_awk_extio_t*)arg; + + switch (cmd) + { + case ASE_AWK_IO_OPEN: + { + ase_sio_t* handle; + int mode; + + if (epa->mode == ASE_AWK_EXTIO_PIPE_READ) + { + mode = ASE_SIO_READ; + } + else if (epa->mode == ASE_AWK_EXTIO_PIPE_WRITE) + { + mode = ASE_SIO_WRITE | + ASE_SIO_TRUNCATE | + ASE_SIO_CREATE; + } + else return -1; /* TODO: any way to set the error number? */ + + //dprint (ASE_T("opening %s of type %d (pipe)\n"), epa->name, epa->type); + + // TOOD: pipe open.... + handle = ase_sio_open (ase_awk_getrunmmgr(epa->run), 0, epa->name, mode); + if (handle == ASE_NULL) return -1; + epa->handle = (void*)handle; + return 1; + } + + case ASE_AWK_IO_CLOSE: + { + //dprint (ASE_T("closing %s of type (pipe) %d\n"), epa->name, epa->type); + ase_sio_close ((ase_sio_t*)epa->handle); + epa->handle = ASE_NULL; + return 0; + } + + case ASE_AWK_IO_READ: + { + return ase_sio_getsx ( + (ase_sio_t*)epa->handle, + data, + size + ); + } + + case ASE_AWK_IO_WRITE: + { + return ase_sio_putsx ( + (ase_sio_t*)epa->handle, + data, + size + ); + } + + case ASE_AWK_IO_FLUSH: + { + /*if (epa->mode == ASE_AWK_EXTIO_PIPE_READ) return -1;*/ + return ase_sio_flush ((ase_sio_t*)epa->handle); + } + + case ASE_AWK_IO_NEXT: + { + return -1; + } + } + + return -1; +} + +static ase_ssize_t awk_extio_file ( + int cmd, void* arg, ase_char_t* data, ase_size_t size) +{ + ase_awk_extio_t* epa = (ase_awk_extio_t*)arg; + + switch (cmd) + { + case ASE_AWK_IO_OPEN: + { + ase_sio_t* handle; + int mode; + + if (epa->mode == ASE_AWK_EXTIO_FILE_READ) + { + mode = ASE_SIO_READ; + } + else if (epa->mode == ASE_AWK_EXTIO_FILE_WRITE) + { + mode = ASE_SIO_WRITE | + ASE_SIO_CREATE | + ASE_SIO_TRUNCATE; + } + else if (epa->mode == ASE_AWK_EXTIO_FILE_APPEND) + { + mode = ASE_SIO_APPEND | + ASE_SIO_CREATE | + ASE_SIO_TRUNCATE; + } + else return -1; /* TODO: any way to set the error number? */ + + //dprint (ASE_T("opening %s of type %d (file)\n"), epa->name, epa->type); + handle = ase_sio_open ( + ase_awk_getrunmmgr(epa->run), + 0, + epa->name, + mode + ); + if (handle == ASE_NULL) + { + ase_cstr_t errarg; + + errarg.ptr = epa->name; + errarg.len = ase_strlen(epa->name); + + ase_awk_setrunerror (epa->run, ASE_AWK_EOPEN, 0, &errarg, 1); + return -1; + } + + epa->handle = (void*)handle; + return 1; + } + + case ASE_AWK_IO_CLOSE: + { + //dprint (ASE_T("closing %s of type %d (file)\n"), epa->name, epa->type); + ase_sio_close ((ase_sio_t*)epa->handle); + epa->handle = ASE_NULL; + return 0; + } + + case ASE_AWK_IO_READ: + { + return ase_sio_getsx ( + (ase_sio_t*)epa->handle, + data, + size + ); + } + + case ASE_AWK_IO_WRITE: + { + return ase_sio_putsx ( + (ase_sio_t*)epa->handle, + data, + size + ); + } + + case ASE_AWK_IO_FLUSH: + { + return ase_sio_flush ((ase_sio_t*)epa->handle); + } + + case ASE_AWK_IO_NEXT: + { + return -1; + } + + } + + return -1; +} + +static int open_extio_console (ase_awk_extio_t* epa); +static int close_extio_console (ase_awk_extio_t* epa); +static int next_extio_console (ase_awk_extio_t* epa); + +static ase_ssize_t awk_extio_console ( + int cmd, void* arg, ase_char_t* data, ase_size_t size) +{ + ase_awk_extio_t* epa = (ase_awk_extio_t*)arg; + runio_data_t* rd = (runio_data_t*)epa->data; + + if (cmd == ASE_AWK_IO_OPEN) + { + return open_extio_console (epa); + } + else if (cmd == ASE_AWK_IO_CLOSE) + { + return close_extio_console (epa); + } + else if (cmd == ASE_AWK_IO_READ) + { + ase_ssize_t n; + + while ((n = ase_sio_getsx((ase_sio_t*)epa->handle,data,size)) == 0) + { + /* it has reached the end of the current file. + * open the next file if available */ + if (rd->icf[rd->icf_cur] == ASE_NULL) + { + /* no more input console */ + return 0; + } + + if (rd->icf[rd->icf_cur][0] == ASE_T('\0')) + { + if (epa->handle != ASE_NULL && + epa->handle != ase_sio_in && + epa->handle != ase_sio_out && + epa->handle != ase_sio_err) + { + ase_sio_close ((ase_sio_t*)epa->handle); + } + + epa->handle = ase_sio_in; + } + else + { + ase_sio_t* fp; + + fp = ase_sio_open ( + ase_awk_getrunmmgr(epa->run), + 0, + rd->icf[rd->icf_cur], + ASE_SIO_READ + ); + + if (fp == ASE_NULL) + { + ase_cstr_t errarg; + + errarg.ptr = rd->icf[rd->icf_cur]; + errarg.len = ase_strlen(rd->icf[rd->icf_cur]); + + ase_awk_setrunerror (epa->run, ASE_AWK_EOPEN, 0, &errarg, 1); + return -1; + } + + if (ase_awk_setfilename ( + epa->run, rd->icf[rd->icf_cur], + ase_strlen(rd->icf[rd->icf_cur])) == -1) + { + ase_sio_close (fp); + return -1; + } + + if (ase_awk_setglobal ( + epa->run, ASE_AWK_GLOBAL_FNR, ase_awk_val_zero) == -1) + { + /* need to reset FNR */ + ase_sio_close (fp); + return -1; + } + + if (epa->handle != ASE_NULL && + epa->handle != ase_sio_in && + epa->handle != ase_sio_out && + epa->handle != ase_sio_err) + { + ase_sio_close ((ase_sio_t*)epa->handle); + } + + //dprint (ASE_T("open the next console [%s]\n"), rd->icf[rd->icf_cur]); + epa->handle = fp; + } + + rd->icf_cur++; + } + + return n; + } + else if (cmd == ASE_AWK_IO_WRITE) + { + return ase_sio_putsx ( + (ase_sio_t*)epa->handle, + data, + size + ); + } + else if (cmd == ASE_AWK_IO_FLUSH) + { + return ase_sio_flush ((ase_sio_t*)epa->handle); + } + else if (cmd == ASE_AWK_IO_NEXT) + { + return next_extio_console (epa); + } + + return -1; +} + +static int open_extio_console (ase_awk_extio_t* epa) +{ + runio_data_t* rd = (runio_data_t*)epa->data; + + + //dprint (ASE_T("opening console[%s] of type %x\n"), epa->name, epa->type); + + if (epa->mode == ASE_AWK_EXTIO_CONSOLE_READ) + { + if (rd->icf[rd->icf_cur] == ASE_NULL) + { + /* no more input file */ + //dprint (ASE_T("console - no more file\n"));; + return 0; + } + + if (rd->icf[rd->icf_cur][0] == ASE_T('\0')) + { + //dprint (ASE_T(" console(r) - \n")); + epa->handle = ase_sio_in; + } + else + { + /* a temporary variable fp is used here not to change + * any fields of epa when the open operation fails */ + ase_sio_t* fp; + + fp = ase_sio_open ( + ase_awk_getrunmmgr(epa->run), + 0, + rd->icf[rd->icf_cur], + ASE_SIO_READ + ); + if (fp == ASE_NULL) + { + ase_cstr_t errarg; + + errarg.ptr = rd->icf[rd->icf_cur]; + errarg.len = ase_strlen(rd->icf[rd->icf_cur]); + + ase_awk_setrunerror (epa->run, ASE_AWK_EOPEN, 0, &errarg, 1); + return -1; + } + + //dprint (ASE_T(" console(r) - %s\n"), rd->icf[rd->icf_cur]); + if (ase_awk_setfilename ( + epa->run, rd->icf[rd->icf_cur], + ase_strlen(rd->icf[rd->icf_cur])) == -1) + { + ase_sio_close (fp); + return -1; + } + + epa->handle = fp; + } + + rd->icf_cur++; + return 1; + } + else if (epa->mode == ASE_AWK_EXTIO_CONSOLE_WRITE) + { + //dprint (ASE_T(" console(w) - \n")); + + if (ase_awk_setofilename (epa->run, ASE_T(""), 0) == -1) + { + return -1; + } + + epa->handle = ase_sio_out; + return 1; + } + + return -1; +} + +static int close_extio_console (ase_awk_extio_t* epa) +{ + //dprint (ASE_T("closing console of type %x\n"), epa->type); + + if (epa->handle != ASE_NULL && + epa->handle != ase_sio_in && + epa->handle != ase_sio_out && + epa->handle != ase_sio_err) + { + ase_sio_close ((ase_sio_t*)epa->handle); + } + + return 0; +} + +static int next_extio_console (ase_awk_extio_t* epa) +{ + int n; + ase_sio_t* fp = (ase_sio_t*)epa->handle; + + //dprint (ASE_T("switching console[%s] of type %x\n"), epa->name, epa->type); + + n = open_extio_console(epa); + if (n == -1) return -1; + + if (n == 0) + { + /* if there is no more file, keep the previous handle */ + return 0; + } + + if (fp != ASE_NULL && + fp != ase_sio_in && + fp != ase_sio_out && + fp != ase_sio_err) + { + ase_sio_close (fp); + } + + return n; +} + +int ase_awk_runsimple (ase_awk_t* awk, ase_char_t** icf) +{ + ase_awk_runcbs_t runcbs; + ase_awk_runios_t runios; + runio_data_t rd; + + rd.icf = icf; + rd.icf_cur = 0; + + runios.pipe = awk_extio_pipe; + runios.file = awk_extio_file; + runios.console = awk_extio_console; + runios.data = &rd; + + /* + runcbs.on_start = on_run_start; + runcbs.on_statement = on_run_statement; + runcbs.on_return = on_run_return; + runcbs.on_end = on_run_end; + runcbs.data = ASE_NULL; + */ + + return ase_awk_run ( + awk, + ASE_NULL/*mfn*/, + &runios, + ASE_NULL/*&runcbs*/, + ASE_NULL/*runarg*/, + ASE_NULL + ); } diff --git a/ase/lib/cmn/sio.c b/ase/lib/cmn/sio.c index 99f9c18e..2c756d19 100644 --- a/ase/lib/cmn/sio.c +++ b/ase/lib/cmn/sio.c @@ -315,8 +315,24 @@ static ase_ssize_t __sio_input (int cmd, void* arg, void* buf, ase_size_t size) ase_sio_t* sio = (ase_sio_t*)arg; ASE_ASSERT (sio != ASE_NULL); + if (cmd == ASE_TIO_IO_DATA) { + #ifdef _WIN32 + /* TODO: I hate this way of adjusting the handle value + * Is there any good ways to do it statically? */ + HANDLE h = sio->fio.handle; + if (h == (HANDLE)STD_INPUT_HANDLE || + h == (HANDLE)STD_OUTPUT_HANDLE || + h == (HANDLE)STD_ERROR_HANDLE) + { + h = GetStdHandle((DWORD)h); + if (h != INVALID_HANDLE_VALUE && h != NULL) + { + sio->fio.handle = h; + } + } + #endif return ase_fio_read (&sio->fio, buf, size); } @@ -331,6 +347,21 @@ static ase_ssize_t __sio_output (int cmd, void* arg, void* buf, ase_size_t size) if (cmd == ASE_TIO_IO_DATA) { + #ifdef _WIN32 + /* TODO: I hate this way of adjusting the handle value + * Is there any good ways to do it statically? */ + HANDLE h = sio->fio.handle; + if (h == (HANDLE)STD_INPUT_HANDLE || + h == (HANDLE)STD_OUTPUT_HANDLE || + h == (HANDLE)STD_ERROR_HANDLE) + { + h = GetStdHandle((DWORD)h); + if (h != INVALID_HANDLE_VALUE && h != NULL) + { + sio->fio.handle = h; + } + } + #endif return ase_fio_write (&sio->fio, buf, size); }