- fixed a bug of not handling nextfile and nextofile when no files are specified in the standard console handler
(awk/std.c) - enhanced the console handler for StdAwk
This commit is contained in:
		| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: Awk.cpp 223 2009-07-06 12:37:25Z hyunghwan.chung $ | ||||
|  * $Id: Awk.cpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ | ||||
|  * | ||||
|    Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|  | ||||
| @ -88,7 +88,8 @@ Awk::RIOBase::operator Awk* () const | ||||
|  | ||||
| Awk::RIOBase::operator Awk::awk_t* () const  | ||||
| { | ||||
| 	return qse_awk_rtx_getawk (this->run->rtx); | ||||
| 	QSE_ASSERT (qse_awk_rtx_getawk(this->run->rtx) == this->run->awk->awk); | ||||
| 	return this->run->awk->awk; | ||||
| } | ||||
|  | ||||
| Awk::RIOBase::operator Awk::rio_arg_t* () const | ||||
| @ -96,6 +97,11 @@ Awk::RIOBase::operator Awk::rio_arg_t* () const | ||||
| 	return this->riod; | ||||
| } | ||||
|  | ||||
| Awk::RIOBase::operator Awk::Run* () const | ||||
| { | ||||
| 	return this->run; | ||||
| } | ||||
|  | ||||
| Awk::RIOBase::operator Awk::rtx_t* () const | ||||
| { | ||||
| 	return this->run->rtx; | ||||
| @ -146,7 +152,7 @@ Awk::Console::~Console () | ||||
|  | ||||
| int Awk::Console::setFileName (const char_t* name) | ||||
| { | ||||
| 	if (riod->mode == READ) | ||||
| 	if (this->getMode() == READ) | ||||
| 	{ | ||||
| 		return qse_awk_rtx_setfilename ( | ||||
| 			this->run->rtx, name, qse_strlen(name)); | ||||
| @ -396,7 +402,6 @@ int Awk::Argument::init (const char_t* str, size_t len) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| Awk::long_t Awk::Argument::toInt () const | ||||
| { | ||||
| 	return this->inum; | ||||
| @ -1077,10 +1082,6 @@ Awk::Awk () throw (): awk (QSE_NULL), functionMap (QSE_NULL), | ||||
|  | ||||
| { | ||||
| 	this->errmsg[0] = QSE_T('\0'); | ||||
|  | ||||
| 	this->runarg.ptr = QSE_NULL; | ||||
| 	this->runarg.len = 0; | ||||
| 	this->runarg.capa = 0; | ||||
| } | ||||
|  | ||||
| Awk::operator Awk::awk_t* () const | ||||
| @ -1463,43 +1464,52 @@ int Awk::dispatchFunction (Run* run, const char_t* name, size_t len) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int Awk::addArgument (const char_t* arg, size_t len) | ||||
| int Awk::xstrs_t::add (awk_t* awk, const char_t* arg, size_t len) | ||||
| { | ||||
| 	QSE_ASSERT (awk != QSE_NULL); | ||||
|  | ||||
| 	if (runarg.len >= runarg.capa) | ||||
| 	if (this->len >= this->capa) | ||||
| 	{ | ||||
| 		qse_xstr_t* ptr; | ||||
| 		size_t capa = runarg.capa; | ||||
| 		size_t capa = this->capa; | ||||
|  | ||||
| 		capa += 64; | ||||
| 		ptr = (qse_xstr_t*) qse_awk_realloc ( | ||||
| 			awk, runarg.ptr, QSE_SIZEOF(qse_xstr_t)*(capa+1)); | ||||
| 		if (ptr == QSE_NULL) | ||||
| 		{ | ||||
| 			setError (ERR_NOMEM); | ||||
| 			return -1; | ||||
| 		} | ||||
| 			awk, this->ptr, QSE_SIZEOF(qse_xstr_t)*(capa+1)); | ||||
| 		if (ptr == QSE_NULL) return -1; | ||||
|  | ||||
| 		runarg.ptr = ptr; | ||||
| 		runarg.capa = capa; | ||||
| 		this->ptr = ptr; | ||||
| 		this->capa = capa; | ||||
| 	} | ||||
|  | ||||
| 	runarg.ptr[runarg.len].len = len; | ||||
| 	runarg.ptr[runarg.len].ptr = qse_awk_strxdup (awk, arg, len); | ||||
| 	if (runarg.ptr[runarg.len].ptr == QSE_NULL) | ||||
| 	{ | ||||
| 		setError (ERR_NOMEM); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	this->ptr[this->len].len = len; | ||||
| 	this->ptr[this->len].ptr = qse_awk_strxdup (awk, arg, len); | ||||
| 	if (this->ptr[this->len].ptr == QSE_NULL) return -1; | ||||
|  | ||||
| 	runarg.len++; | ||||
| 	runarg.ptr[runarg.len].len = 0; | ||||
| 	runarg.ptr[runarg.len].ptr = QSE_NULL; | ||||
| 	this->len++; | ||||
| 	this->ptr[this->len].len = 0; | ||||
| 	this->ptr[this->len].ptr = QSE_NULL; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void Awk::xstrs_t::clear (awk_t* awk) | ||||
| { | ||||
| 	if (this->ptr != QSE_NULL) | ||||
| 	{ | ||||
| 		qse_awk_free (awk, this->ptr); | ||||
| 		this->ptr = QSE_NULL; | ||||
| 		this->len = 0; | ||||
| 		this->capa = 0; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int Awk::addArgument (const char_t* arg, size_t len) | ||||
| { | ||||
| 	QSE_ASSERT (awk != QSE_NULL); | ||||
| 	int n = runarg.add (awk, arg, len); | ||||
| 	if (n <= -1) setError (ERR_NOMEM); | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| int Awk::addArgument (const char_t* arg) | ||||
| { | ||||
| 	return addArgument (arg, qse_strlen(arg)); | ||||
| @ -1507,14 +1517,7 @@ int Awk::addArgument (const char_t* arg) | ||||
|  | ||||
| void Awk::clearArguments () | ||||
| { | ||||
| 	if (runarg.ptr != QSE_NULL) | ||||
| 	{ | ||||
| 		QSE_ASSERT (awk != QSE_NULL); | ||||
| 		qse_awk_free (awk, runarg.ptr); | ||||
| 		runarg.ptr = QSE_NULL; | ||||
| 		runarg.len = 0; | ||||
| 		runarg.capa = 0; | ||||
| 	} | ||||
| 	runarg.clear (awk); | ||||
| } | ||||
|  | ||||
| int Awk::addGlobal (const char_t* name) | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: StdAwk.cpp 220 2009-07-01 13:14:39Z hyunghwan.chung $ | ||||
|  * $Id: StdAwk.cpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ | ||||
|  * | ||||
|    Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|  | ||||
| @ -23,6 +23,7 @@ | ||||
| #include <qse/cmn/pio.h> | ||||
| #include <qse/cmn/sio.h> | ||||
| #include <qse/cmn/stdio.h> | ||||
| #include "awk.h" | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <math.h> | ||||
| @ -74,6 +75,30 @@ int StdAwk::open () | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| void StdAwk::close () | ||||
| { | ||||
| 	clearConsoleOutputs (); | ||||
| 	Awk::close (); | ||||
| } | ||||
|  | ||||
| int StdAwk::addConsoleOutput (const char_t* arg, size_t len) | ||||
| { | ||||
| 	QSE_ASSERT (awk != QSE_NULL); | ||||
| 	int n = ofile.add (awk, arg, len); | ||||
| 	if (n <= -1) setError (ERR_NOMEM); | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| int StdAwk::addConsoleOutput (const char_t* arg) | ||||
| { | ||||
| 	return addConsoleOutput (arg, qse_strlen(arg)); | ||||
| } | ||||
|  | ||||
| void StdAwk::clearConsoleOutputs () | ||||
| { | ||||
| 	ofile.clear (awk); | ||||
| } | ||||
|  | ||||
| int StdAwk::sin (Run& run, Return& ret, const Argument* args, size_t nargs,  | ||||
| 	const char_t* name, size_t len) | ||||
| { | ||||
| @ -385,345 +410,314 @@ int StdAwk::flushFile (File& io) | ||||
| 	return qse_fio_flush ((qse_fio_t*)io.getHandle()); | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| // console io handlers  | ||||
| int StdAwk::openConsole (Console& io)  | ||||
| int StdAwk::open_console_in (Console& io)  | ||||
| {  | ||||
| 	qse_sio_t* fp; | ||||
| 	Console::Mode mode = io.getMode(); | ||||
| 	qse_awk_rtx_t* rtx = (rtx_t*)io; | ||||
|  | ||||
| 	switch (mode) | ||||
| 	if (runarg.ptr == QSE_NULL)  | ||||
| 	{ | ||||
| 		case Console::READ: | ||||
| 		QSE_ASSERT (runarg.len == 0 && runarg.capa == 0); | ||||
|  | ||||
| 		if (runarg_count == 0)  | ||||
| 		{ | ||||
| 			if (runarg.ptr == QSE_NULL)  | ||||
| 			io.setHandle (qse_sio_in); | ||||
| 			runarg_count++; | ||||
| 			return 1; | ||||
| 		} | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		qse_sio_t* sio; | ||||
| 		const qse_char_t* file; | ||||
| 		qse_awk_val_t* argv; | ||||
| 		qse_map_t* map; | ||||
| 		qse_map_pair_t* pair; | ||||
| 		qse_char_t ibuf[128]; | ||||
| 		qse_size_t ibuflen; | ||||
| 		qse_awk_val_t* v; | ||||
| 		qse_awk_rtx_valtostr_out_t out; | ||||
|  | ||||
| 	nextfile: | ||||
| 		file = runarg.ptr[runarg_index].ptr; | ||||
|  | ||||
| 		if (file == QSE_NULL) | ||||
| 		{ | ||||
| 			/* no more input file */ | ||||
|  | ||||
| 			if (runarg_count == 0) | ||||
| 			{ | ||||
| 				io.setHandle (qse_sio_in); | ||||
| 				return 1; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				qse_sio_t* sio; | ||||
| 				const qse_char_t* file; | ||||
| 				qse_awk_val_t* argv; | ||||
| 				qse_map_t* map; | ||||
| 				qse_map_pair_t* pair; | ||||
| 				qse_char_t ibuf[128]; | ||||
| 				qse_size_t ibuflen; | ||||
| 				qse_awk_val_t* v; | ||||
| 				qse_awk_rtx_valtostr_out_t out; | ||||
| 	 | ||||
| 			nextfile: | ||||
| 				file = runarg.ptr[runarg_index]; | ||||
| 	 | ||||
| 				if (file == QSE_NULL) | ||||
| 				{ | ||||
| 					/* no more input file */ | ||||
| 	 | ||||
| 					if (runarg_count == 0) | ||||
| 					{ | ||||
| 						/* all ARGVs are empty strings.  | ||||
| 						 * so no console files were opened. | ||||
| 						 * open the standard input here. | ||||
| 						 * | ||||
| 						 * 'BEGIN { ARGV[1]=""; ARGV[2]=""; } | ||||
| 						 *        { print $0; }' file1 file2 | ||||
| 						 */ | ||||
| 						io.setHandle (qse_sio_in); | ||||
| 						runarg_count++; | ||||
| 						return 1; | ||||
| 					} | ||||
| 	 | ||||
| 					return 0; | ||||
| 				} | ||||
| 	 | ||||
| 				/* handle special case when ARGV[x] has been altered. | ||||
| 				 * so from here down, the file name gotten from  | ||||
| 				 * rxtn->c.in.files is not important and is overridden  | ||||
| 				 * from ARGV. | ||||
| 				 * 'BEGIN { ARGV[1]="file3"; }  | ||||
| 				/* all ARGVs are empty strings.  | ||||
| 				 * so no console files were opened. | ||||
| 				 * open the standard input here. | ||||
| 				 * | ||||
| 				 * 'BEGIN { ARGV[1]=""; ARGV[2]=""; } | ||||
| 				 *        { print $0; }' file1 file2 | ||||
| 				 */ | ||||
| 				argv = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_ARGV); | ||||
| 				QSE_ASSERT (argv != QSE_NULL); | ||||
| 				QSE_ASSERT (argv->type == QSE_AWK_VAL_MAP); | ||||
| 	 | ||||
| 				map = ((qse_awk_val_map_t*)argv)->map; | ||||
| 				QSE_ASSERT (map != QSE_NULL); | ||||
| 				 | ||||
| 				ibuflen = qse_awk_longtostr ( | ||||
| 					rtx->awk, rxtn->c.in.index + 1, 10, QSE_NULL, | ||||
| 					ibuf, QSE_COUNTOF(ibuf)); | ||||
| 	 | ||||
| 				pair = qse_map_search (map, ibuf, ibuflen); | ||||
| 				QSE_ASSERT (pair != QSE_NULL); | ||||
| 	 | ||||
| 				v = QSE_MAP_VPTR(pair); | ||||
| 				QSE_ASSERT (v != QSE_NULL); | ||||
| 	 | ||||
| 				out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; | ||||
| 				if (qse_awk_rtx_valtostr (rtx, v, &out) == QSE_NULL) return -1; | ||||
| 	 | ||||
| 				if (out.u.cpldup.len == 0) | ||||
| 				{ | ||||
| 					/* the name is empty */ | ||||
| 					qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 					rxtn->c.in.index++; | ||||
| 					goto nextfile; | ||||
| 				} | ||||
| 	 | ||||
| 				if (qse_strlen(out.u.cpldup.ptr) < out.u.cpldup.len) | ||||
| 				{ | ||||
| 					/* the name contains one or more '\0' */ | ||||
| 					qse_cstr_t errarg; | ||||
| 	 | ||||
| 					errarg.ptr = out.u.cpldup.ptr; | ||||
| 					/* use this length not to contains '\0' | ||||
| 					 * in an error message */ | ||||
| 					errarg.len = qse_strlen(out.u.cpldup.ptr); | ||||
| 	 | ||||
| 					qse_awk_rtx_seterror ( | ||||
| 						rtx, QSE_AWK_EIONMNL, 0, &errarg); | ||||
| 	 | ||||
| 					qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 					return -1; | ||||
| 				} | ||||
| 	 | ||||
| 				file = out.u.cpldup.ptr; | ||||
| 	 | ||||
| 				if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) | ||||
| 				{ | ||||
| 					/* special file name '-' */ | ||||
| 					sio = qse_sio_in; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					sio = qse_sio_open ( | ||||
| 						rtx->awk->mmgr, 0, file, QSE_SIO_READ); | ||||
| 					if (sio == QSE_NULL) | ||||
| 					{ | ||||
| 						qse_cstr_t errarg; | ||||
| 	 | ||||
| 						errarg.ptr = file; | ||||
| 						errarg.len = qse_strlen(file); | ||||
| 	 | ||||
| 						qse_awk_rtx_seterror ( | ||||
| 							rtx, QSE_AWK_EOPEN, 0, &errarg); | ||||
| 	 | ||||
| 						qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 						return -1; | ||||
| 					} | ||||
| 				} | ||||
| 	 | ||||
| 				if (qse_awk_rtx_setfilename ( | ||||
| 					rtx, file, qse_strlen(file)) == -1) | ||||
| 				{ | ||||
| 					if (sio != qse_sio_in) qse_sio_close (sio); | ||||
| 					qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 					return -1; | ||||
| 				} | ||||
| 	 | ||||
| 				qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 				riod->handle = sio; | ||||
| 	 | ||||
| 				/* increment the counter of files successfully opened */ | ||||
| 				rxtn->c.in.count++; | ||||
| 			} | ||||
| 	 | ||||
| 			rxtn->c.in.index++; | ||||
| 				io.setHandle (qse_sio_in); | ||||
| 				runarg_count++; | ||||
| 				return 1; | ||||
| 			} | ||||
|  | ||||
| 			break; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		case Console::WRITE: | ||||
| 			break;	 | ||||
| 	} | ||||
| 		// TODO: need to check for '\0' contained??? | ||||
|  | ||||
| 		/* handle special case when ARGV[x] has been altered. | ||||
| 		 * so from here down, the file name gotten from  | ||||
| 		 * rxtn->c.in.files is not important and is overridden  | ||||
| 		 * from ARGV. | ||||
| 		 * 'BEGIN { ARGV[1]="file3"; }  | ||||
| 		 *        { print $0; }' file1 file2 | ||||
| 		 */ | ||||
| 		argv = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_ARGV); | ||||
| 		QSE_ASSERT (argv != QSE_NULL); | ||||
| 		QSE_ASSERT (argv->type == QSE_AWK_VAL_MAP); | ||||
|  | ||||
| 		map = ((qse_awk_val_map_t*)argv)->map; | ||||
| 		QSE_ASSERT (map != QSE_NULL); | ||||
| 		 | ||||
| #if 0 | ||||
| 	FILE* fp = QSE_NULL; | ||||
| 	const char_t* fn = QSE_NULL; | ||||
| 		ibuflen = qse_awk_longtostr ( | ||||
| 			rtx->awk, runarg_index + 1,  | ||||
| 			10, QSE_NULL, | ||||
| 			ibuf, QSE_COUNTOF(ibuf) | ||||
| 		); | ||||
|  | ||||
| 	switch (mode) | ||||
| 	{ | ||||
| 		case StdAwk::Console::READ: | ||||
| 		pair = qse_map_search (map, ibuf, ibuflen); | ||||
| 		QSE_ASSERT (pair != QSE_NULL); | ||||
|  | ||||
| 			if (numConInFiles == 0) fp = stdin; | ||||
| 			else | ||||
| 			{ | ||||
| 				fn = conInFile[0]; | ||||
| 				fp = qse_fopen (fn, QSE_T("r")); | ||||
| 			} | ||||
| 			break; | ||||
| 		v = (qse_awk_val_t*)QSE_MAP_VPTR(pair); | ||||
| 		QSE_ASSERT (v != QSE_NULL); | ||||
|  | ||||
| 		case StdAwk::Console::WRITE: | ||||
| 		out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; | ||||
| 		if (qse_awk_rtx_valtostr (rtx, v, &out) == QSE_NULL) return -1; | ||||
|  | ||||
| 			if (numConOutFiles == 0) fp = stdout; | ||||
| 			else | ||||
| 			{ | ||||
| 				fn = conOutFile[0]; | ||||
| 				fp = qse_fopen (fn, QSE_T("w")); | ||||
| 			} | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	if (fp == NULL) return -1; | ||||
|  | ||||
| 	ConTrack* t = (ConTrack*)  | ||||
| 		qse_awk_alloc (awk, QSE_SIZEOF(ConTrack)); | ||||
| 	if (t == QSE_NULL) | ||||
| 	{ | ||||
| 		if (fp != stdin && fp != stdout) fclose (fp); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	t->handle = fp; | ||||
| 	t->nextConIdx = 1; | ||||
|  | ||||
| 	if (fn != QSE_NULL)  | ||||
| 	{ | ||||
| 		if (io.setFileName(fn) == -1) | ||||
| 		if (out.u.cpldup.len == 0) | ||||
| 		{ | ||||
| 			if (fp != stdin && fp != stdout) fclose (fp); | ||||
| 			qse_awk_free (awk, t); | ||||
| 			/* the name is empty */ | ||||
| 			qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 			runarg_index++; | ||||
| 			goto nextfile; | ||||
| 		} | ||||
|  | ||||
| 		if (qse_strlen(out.u.cpldup.ptr) < out.u.cpldup.len) | ||||
| 		{ | ||||
| 			/* the name contains one or more '\0' */ | ||||
| 			((Run*)io)->setError (ERR_IONMNL, 0, out.u.cpldup.ptr); | ||||
| 			qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		file = out.u.cpldup.ptr; | ||||
|  | ||||
| 		if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) | ||||
| 		{ | ||||
| 			/* special file name '-' */ | ||||
| 			sio = qse_sio_in; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			sio = qse_sio_open ( | ||||
| 				rtx->awk->mmgr, 0, file, QSE_SIO_READ); | ||||
| 			if (sio == QSE_NULL) | ||||
| 			{ | ||||
| 				((Run*)io)->setError (ERR_OPEN, 0, file); | ||||
| 				qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (qse_awk_rtx_setfilename ( | ||||
| 			rtx, file, qse_strlen(file)) == -1) | ||||
| 		{ | ||||
| 			if (sio != qse_sio_in) qse_sio_close (sio); | ||||
| 			qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		qse_awk_rtx_free (rtx, out.u.cpldup.ptr); | ||||
| 		io.setHandle (sio); | ||||
|  | ||||
| 		/* increment the counter of files successfully opened */ | ||||
| 		runarg_count++; | ||||
| 		runarg_index++; | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	io.setHandle (t); | ||||
| 	return 1; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| int StdAwk::open_console_out (Console& io)  | ||||
| { | ||||
| 	qse_awk_rtx_t* rtx = (rtx_t*)io; | ||||
|  | ||||
| 	if (ofile.ptr == QSE_NULL) | ||||
| 	{ | ||||
| 		QSE_ASSERT (ofile.len == 0 && ofile.capa == 0); | ||||
|  | ||||
| 		if (ofile_count == 0)  | ||||
| 		{ | ||||
| 			io.setHandle (qse_sio_out); | ||||
| 			ofile_count++; | ||||
| 			return 1; | ||||
| 		} | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* a temporary variable sio is used here not to change  | ||||
| 		 * any fields of riod when the open operation fails */ | ||||
| 		qse_sio_t* sio; | ||||
| 		const qse_char_t* file; | ||||
|  | ||||
| 		file = ofile.ptr[ofile_index].ptr; | ||||
|  | ||||
| 		if (file == QSE_NULL) | ||||
| 		{ | ||||
| 			/* no more input file */ | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		// TODO: need to check for '\0' contained??? | ||||
|  | ||||
| 		if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) | ||||
| 		{ | ||||
| 			/* special file name '-' */ | ||||
| 			sio = qse_sio_out; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			sio = qse_sio_open ( | ||||
| 				rtx->awk->mmgr, 0, file, QSE_SIO_READ); | ||||
| 			if (sio == QSE_NULL) | ||||
| 			{ | ||||
| 				((Run*)io)->setError (ERR_OPEN, 0, file); | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		if (qse_awk_rtx_setofilename ( | ||||
| 			rtx, file, qse_strlen(file)) == -1) | ||||
| 		{ | ||||
| 			qse_sio_close (sio); | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		io.setHandle (sio); | ||||
|  | ||||
| 		ofile_index++; | ||||
| 		ofile_count++; | ||||
| 		return 1; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int StdAwk::openConsole (Console& io)  | ||||
| { | ||||
| 	Console::Mode mode = io.getMode(); | ||||
|  | ||||
| 	if (mode == Console::READ) | ||||
| 	{ | ||||
| 		runarg_count = 0; | ||||
| 		runarg_index = 0; | ||||
| 		return open_console_in (io); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		QSE_ASSERT (mode == Console::WRITE); | ||||
|  | ||||
| 		ofile_count = 0; | ||||
| 		ofile_index = 0; | ||||
| 		return open_console_out (io); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int StdAwk::closeConsole (Console& io)  | ||||
| {  | ||||
| 	ConTrack* t = (ConTrack*)io.getHandle(); | ||||
| 	FILE* fp = t->handle; | ||||
| 	qse_sio_t* sio; | ||||
|  | ||||
| 	if (fp == stdout || fp == stderr) fflush (fp); | ||||
| 	if (fp != stdin && fp != stdout && fp != stderr) fclose (fp); | ||||
| 	sio = (qse_sio_t*)io.getHandle(); | ||||
| 	if (sio != qse_sio_in && | ||||
| 	    sio != qse_sio_out && | ||||
| 	    sio != qse_sio_err) | ||||
| 	{ | ||||
| 		qse_sio_close (sio); | ||||
| 	} | ||||
|  | ||||
| 	qse_awk_free (awk, t); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| ssize_t StdAwk::readConsole (Console& io, char_t* buf, size_t len)  | ||||
| ssize_t StdAwk::readConsole (Console& io, char_t* data, size_t size)  | ||||
| { | ||||
| 	ConTrack* t = (ConTrack*)io.getHandle(); | ||||
| 	FILE* fp = t->handle; | ||||
| 	ssize_t n = 0; | ||||
| 	qse_ssize_t nn; | ||||
|  | ||||
| 	while (n < (ssize_t)len) | ||||
| 	while ((nn = qse_sio_getsn((qse_sio_t*)io.getHandle(),data,size)) == 0) | ||||
| 	{ | ||||
| 		qse_cint_t c = qse_fgetc (fp); | ||||
| 		if (c == QSE_CHAR_EOF)  | ||||
| 		int n; | ||||
| 		qse_sio_t* sio = (qse_sio_t*)io.getHandle(); | ||||
|  | ||||
| 		n = open_console_in (io); | ||||
| 		if (n == -1) return -1; | ||||
|  | ||||
| 		if (n == 0)  | ||||
| 		{ | ||||
| 			if (qse_ferror(fp)) return -1; | ||||
| 			if (t->nextConIdx >= numConInFiles) break; | ||||
|  | ||||
| 			const char_t* fn = conInFile[t->nextConIdx]; | ||||
| 			FILE* nfp = qse_fopen (fn, QSE_T("r")); | ||||
| 			if (nfp == QSE_NULL) return -1; | ||||
|  | ||||
| 			if (io.setFileName(fn) == -1 || io.setFNR(0) == -1) | ||||
| 			{ | ||||
| 				fclose (nfp); | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			fclose (fp); | ||||
| 			fp = nfp; | ||||
| 			t->nextConIdx++; | ||||
| 			t->handle = fp; | ||||
|  | ||||
| 			if (n == 0) continue; | ||||
| 			else break; | ||||
| 			/* no more input console */ | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		buf[n++] = c; | ||||
| 		if (c == QSE_T('\n')) break; | ||||
| 		if (sio != QSE_NULL &&  | ||||
| 		    sio != qse_sio_in &&  | ||||
| 		    sio != qse_sio_out && | ||||
| 		    sio != qse_sio_err)  | ||||
| 		{ | ||||
| 			qse_sio_close (sio); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return n; | ||||
| 	return nn; | ||||
| } | ||||
|  | ||||
| ssize_t StdAwk::writeConsole (Console& io, const char_t* buf, size_t len)  | ||||
| ssize_t StdAwk::writeConsole (Console& io, const char_t* data, size_t size)  | ||||
| { | ||||
| 	ConTrack* t = (ConTrack*)io.getHandle(); | ||||
| 	FILE* fp = t->handle; | ||||
| 	size_t left = len; | ||||
|  | ||||
| 	while (left > 0) | ||||
| 	{ | ||||
| 		if (*buf == QSE_T('\0'))  | ||||
| 		{ | ||||
| 			if (qse_fputc(*buf,fp) == QSE_CHAR_EOF) return -1; | ||||
| 			left -= 1; buf += 1; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			int chunk = (left > QSE_TYPE_MAX(int))? QSE_TYPE_MAX(int): (int)left; | ||||
| 			int n = qse_fprintf (fp, QSE_T("%.*s"), chunk, buf); | ||||
| 			if (n < 0 || n > chunk) return -1; | ||||
| 			left -= n; buf += n; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return len; | ||||
| 	return qse_sio_putsn ( | ||||
| 		(qse_sio_t*)io.getHandle(), | ||||
| 		data, | ||||
| 		size | ||||
| 	); | ||||
| } | ||||
|  | ||||
| int StdAwk::flushConsole (Console& io)  | ||||
| {  | ||||
| 	ConTrack* t = (ConTrack*)io.getHandle(); | ||||
| 	FILE* fp = t->handle; | ||||
| 	return ::fflush (fp); | ||||
| 	return qse_sio_flush ((qse_sio_t*)io.getHandle()); | ||||
| } | ||||
|  | ||||
| int StdAwk::nextConsole (Console& io)  | ||||
| {  | ||||
| 	StdAwk::Console::Mode mode = io.getMode(); | ||||
| 	int n; | ||||
| 	qse_sio_t* sio = (qse_sio_t*)io.getHandle(); | ||||
|  | ||||
| 	ConTrack* t = (ConTrack*)io.getHandle(); | ||||
| 	FILE* ofp = t->handle; | ||||
| 	FILE* nfp = QSE_NULL; | ||||
| 	const char_t* fn = QSE_NULL; | ||||
| 	n = (io.getMode() == Console::READ)?  | ||||
| 		open_console_in(io): open_console_out(io); | ||||
| 	if (n == -1) return -1; | ||||
|  | ||||
| 	switch (mode) | ||||
| 	if (n == 0)  | ||||
| 	{ | ||||
| 		case StdAwk::Console::READ: | ||||
|  | ||||
| 			if (t->nextConIdx >= numConInFiles) return 0; | ||||
| 			fn = conInFile[t->nextConIdx]; | ||||
| 			nfp = qse_fopen (fn, QSE_T("r")); | ||||
| 			break; | ||||
|  | ||||
| 		case StdAwk::Console::WRITE: | ||||
|  | ||||
| 			if (t->nextConIdx >= numConOutFiles) return 0; | ||||
| 			fn = conOutFile[t->nextConIdx]; | ||||
| 			nfp = qse_fopen (fn, QSE_T("w")); | ||||
| 			break; | ||||
| 		/* if there is no more file, keep the previous handle */ | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (nfp == QSE_NULL) return -1; | ||||
|  | ||||
| 	if (fn != QSE_NULL) | ||||
| 	if (sio != QSE_NULL &&  | ||||
| 	    sio != qse_sio_in &&  | ||||
| 	    sio != qse_sio_out && | ||||
| 	    sio != qse_sio_err) | ||||
| 	{ | ||||
| 		if (io.setFileName (fn) == -1) | ||||
| 		{ | ||||
| 			fclose (nfp); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		qse_sio_close (sio); | ||||
| 	} | ||||
|  | ||||
| 	fclose (ofp); | ||||
|  | ||||
| 	t->nextConIdx++; | ||||
| 	t->handle = nfp; | ||||
|  | ||||
| 	return 1; | ||||
| 	return n; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| // memory allocation primitives | ||||
| void* StdAwk::allocMem (size_t n) throw () | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: run.c 220 2009-07-01 13:14:39Z hyunghwan.chung $ | ||||
|  * $Id: run.c 224 2009-07-07 13:05:10Z hyunghwan.chung $ | ||||
|  * | ||||
|    Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|  | ||||
| @ -667,7 +667,6 @@ qse_awk_rtx_t* qse_awk_rtx_open ( | ||||
| 		return QSE_NULL; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/* initialize the run object */ | ||||
| 	if (init_rtx (rtx, awk, rio) == -1)  | ||||
| 	{ | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: std.c 212 2009-06-25 07:39:27Z hyunghwan.chung $ | ||||
|  * $Id: std.c 224 2009-07-07 13:05:10Z hyunghwan.chung $ | ||||
|  * | ||||
|    Copyright 2006-2009 Chung, Hyung-Hwan. | ||||
|  | ||||
| @ -85,6 +85,7 @@ typedef struct rxtn_t | ||||
| 		{ | ||||
| 			const qse_char_t*const* files; | ||||
| 			qse_size_t index; | ||||
| 			qse_size_t count; | ||||
| 		} out; | ||||
| 	} c;  /* console */ | ||||
|  | ||||
| @ -609,7 +610,15 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) | ||||
| 			/* if no input files is specified,  | ||||
| 			 * open the standard input */ | ||||
| 			QSE_ASSERT (rxtn->c.in.index == 0); | ||||
| 			riod->handle = qse_sio_in; | ||||
|  | ||||
| 			if (rxtn->c.in.count == 0) | ||||
| 			{ | ||||
| 				riod->handle = qse_sio_in; | ||||
| 				rxtn->c.in.count++; | ||||
| 				return 1; | ||||
| 			} | ||||
|  | ||||
| 			return 0; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @ -740,17 +749,25 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) | ||||
|  | ||||
| 			/* increment the counter of files successfully opened */ | ||||
| 			rxtn->c.in.count++; | ||||
| 			rxtn->c.in.index++; | ||||
| 			return 1; | ||||
| 		} | ||||
|  | ||||
| 		rxtn->c.in.index++; | ||||
| 		return 1; | ||||
| 	} | ||||
| 	else if (riod->mode == QSE_AWK_RIO_CONSOLE_WRITE) | ||||
| 	{ | ||||
| 		if (rxtn->c.out.files == QSE_NULL) | ||||
| 		{ | ||||
| 			QSE_ASSERT (rxtn->c.out.index == 0); | ||||
| 			riod->handle = qse_sio_out; | ||||
|  | ||||
| 			if (rxtn->c.out.count == 0) | ||||
| 			{ | ||||
| 				riod->handle = qse_sio_out; | ||||
| 				rxtn->c.out.count++; | ||||
| 				return 1; | ||||
| 			} | ||||
|  | ||||
| 			return 0; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @ -797,10 +814,12 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) | ||||
| 			} | ||||
|  | ||||
| 			riod->handle = sio; | ||||
|  | ||||
| 			rxtn->c.out.index++; | ||||
| 			rxtn->c.out.count++; | ||||
| 			return 1; | ||||
| 		} | ||||
|  | ||||
| 		rxtn->c.out.index++; | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
| 	return -1; | ||||
| @ -810,8 +829,6 @@ static qse_ssize_t awk_rio_console ( | ||||
| 	qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod, | ||||
| 	qse_char_t* data, qse_size_t size) | ||||
| { | ||||
| 	rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx); | ||||
|  | ||||
| 	if (cmd == QSE_AWK_RIO_OPEN) | ||||
| 	{ | ||||
| 		return open_rio_console (rtx, riod); | ||||
| @ -830,73 +847,32 @@ static qse_ssize_t awk_rio_console ( | ||||
| 	} | ||||
| 	else if (cmd == QSE_AWK_RIO_READ) | ||||
| 	{ | ||||
| 		qse_ssize_t n; | ||||
| 		qse_ssize_t nn; | ||||
|  | ||||
| 		while ((n = qse_sio_getsn((qse_sio_t*)riod->handle,data,size)) == 0) | ||||
| 		while ((nn = qse_sio_getsn((qse_sio_t*)riod->handle,data,size)) == 0) | ||||
| 		{ | ||||
| 			qse_sio_t* sio; | ||||
| 			const qse_char_t* file; | ||||
| 			int n; | ||||
| 			qse_sio_t* sio = (qse_sio_t*)riod->handle; | ||||
|  | ||||
| 			/* it has reached the end of the current file. | ||||
| 			 * open the next file if available */ | ||||
| 			if (rxtn->c.in.files == QSE_NULL || | ||||
| 			    rxtn->c.in.files[rxtn->c.in.index] == QSE_NULL) | ||||
| 			n = open_rio_console (rtx, riod); | ||||
| 			if (n == -1) return -1; | ||||
|  | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				/* no more input console */ | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			file = rxtn->c.in.files[rxtn->c.in.index]; | ||||
|  | ||||
| 			if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) | ||||
| 			if (sio != QSE_NULL &&  | ||||
| 			    sio != qse_sio_in &&  | ||||
| 			    sio != qse_sio_out && | ||||
| 			    sio != qse_sio_err)  | ||||
| 			{ | ||||
| 				sio = qse_sio_in; | ||||
| 				qse_sio_close (sio); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				sio = qse_sio_open ( | ||||
| 					rtx->awk->mmgr, 0, file, QSE_SIO_READ); | ||||
| 				if (sio == QSE_NULL) | ||||
| 				{ | ||||
| 					qse_cstr_t errarg; | ||||
| 	 | ||||
| 					errarg.ptr = file; | ||||
| 					errarg.len = qse_strlen(file); | ||||
| 	 | ||||
| 					qse_awk_rtx_seterror ( | ||||
| 						rtx, QSE_AWK_EOPEN, 0, &errarg); | ||||
| 					return -1; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if (qse_awk_rtx_setfilename ( | ||||
| 				rtx, file, qse_strlen(file)) == -1) | ||||
| 			{ | ||||
| 				if (sio != qse_sio_in) qse_sio_close (sio); | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			if (qse_awk_rtx_setgbl ( | ||||
| 				rtx, QSE_AWK_GBL_FNR, qse_awk_val_zero) == -1) | ||||
| 			{ | ||||
| 				/* need to reset FNR */ | ||||
| 				if (sio != qse_sio_in) qse_sio_close (sio); | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			if (riod->handle != QSE_NULL && | ||||
| 			    riod->handle != qse_sio_in && | ||||
| 			    riod->handle != qse_sio_out && | ||||
| 			    riod->handle != qse_sio_err)  | ||||
| 			{ | ||||
| 				qse_sio_close ((qse_sio_t*)riod->handle); | ||||
| 			} | ||||
|  | ||||
| 			riod->handle = sio; | ||||
| 			rxtn->c.in.index++;	 | ||||
| 		} | ||||
|  | ||||
| 		return n; | ||||
| 		return nn; | ||||
| 	} | ||||
| 	else if (cmd == QSE_AWK_RIO_WRITE) | ||||
| 	{ | ||||
| @ -1019,6 +995,7 @@ qse_awk_rtx_t* qse_awk_rtx_openstd ( | ||||
| 	rxtn->c.in.count = 0; | ||||
| 	rxtn->c.out.files = ocf; | ||||
| 	rxtn->c.out.index = 0; | ||||
| 	rxtn->c.out.count = 0; | ||||
|  | ||||
| 	return rtx; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user