| 
									
										
										
										
											2009-05-30 00:21:41 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2009-03-02 21:34:43 +00:00
										 |  |  |  * $Id$ | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-04-23 08:28:43 +00:00
										 |  |  |     Copyright 2006-2011 Chung, Hyung-Hwan. | 
					
						
							| 
									
										
										
										
											2009-09-16 04:01:02 +00:00
										 |  |  |     This file is part of QSE. | 
					
						
							| 
									
										
										
										
											2009-03-02 21:34:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 04:01:02 +00:00
										 |  |  |     QSE is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |     it under the terms of the GNU Lesser General Public License as  | 
					
						
							|  |  |  |     published by the Free Software Foundation, either version 3 of  | 
					
						
							|  |  |  |     the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2009-03-02 21:34:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 04:01:02 +00:00
										 |  |  |     QSE is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |     GNU Lesser General Public License for more details. | 
					
						
							| 
									
										
										
										
											2009-03-02 21:34:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 04:01:02 +00:00
										 |  |  |     You should have received a copy of the GNU Lesser General Public  | 
					
						
							|  |  |  |     License along with QSE. If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2009-03-02 21:34:43 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | #include <qse/sed/std.h>
 | 
					
						
							| 
									
										
										
										
											2009-03-11 07:38:35 +00:00
										 |  |  | #include <qse/cmn/str.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-08 07:34:49 +00:00
										 |  |  | #include <qse/cmn/mem.h>
 | 
					
						
							| 
									
										
										
										
											2009-05-03 06:16:24 +00:00
										 |  |  | #include <qse/cmn/chr.h>
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | #include <qse/cmn/opt.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-09 01:05:48 +00:00
										 |  |  | #include <qse/cmn/sio.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | #include <qse/cmn/xma.h>
 | 
					
						
							| 
									
										
										
										
											2011-10-14 22:57:41 +00:00
										 |  |  | #include <qse/cmn/path.h>
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | #include <qse/cmn/fs.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-05 07:08:19 +00:00
										 |  |  | #include <qse/cmn/stdio.h>
 | 
					
						
							|  |  |  | #include <qse/cmn/main.h>
 | 
					
						
							| 
									
										
										
										
											2009-03-02 21:34:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-20 22:40:45 +00:00
										 |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | #	include <windows.h>
 | 
					
						
							|  |  |  | #	include <tchar.h>
 | 
					
						
							|  |  |  | #	include <process.h>
 | 
					
						
							|  |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | #	define INCL_DOSPROCESS
 | 
					
						
							|  |  |  | #	define INCL_DOSEXCEPTIONS
 | 
					
						
							|  |  |  | #	define INCL_ERRORS
 | 
					
						
							|  |  |  | #	include <os2.h>
 | 
					
						
							|  |  |  | #	include <signal.h>
 | 
					
						
							|  |  |  | #elif defined(__DOS__)
 | 
					
						
							|  |  |  | #	include <dos.h>
 | 
					
						
							|  |  |  | #	include <signal.h>
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #	include <unistd.h>
 | 
					
						
							|  |  |  | #	include <errno.h>
 | 
					
						
							|  |  |  | #	include <signal.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | static struct | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qse_sed_iostd_t* io; | 
					
						
							|  |  |  | 	qse_size_t capa; | 
					
						
							|  |  |  | 	qse_size_t size; | 
					
						
							|  |  |  | } g_script =  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	QSE_NULL, | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | 	0 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | static qse_char_t* g_output_file = QSE_NULL; | 
					
						
							|  |  |  | static int g_infile_pos = 0; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | static int g_option = 0; | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | static int g_separate = 0; | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | static int g_inplace = 0; | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #if defined(QSE_ENABLE_SEDTRACER)
 | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | static int g_trace = 0; | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | static qse_ulong_t g_memlimit = 0; | 
					
						
							| 
									
										
										
										
											2011-09-20 22:40:45 +00:00
										 |  |  | static qse_sed_t* g_sed = QSE_NULL; | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-20 00:51:02 +00:00
										 |  |  | #if defined(QSE_BUILD_DEBUG)
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | static qse_ulong_t g_failmalloc; | 
					
						
							|  |  |  | static qse_ulong_t debug_mmgr_count = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void* debug_mmgr_alloc (void* ctx, qse_size_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	debug_mmgr_count++; | 
					
						
							|  |  |  | 	if (debug_mmgr_count % g_failmalloc == 0) return QSE_NULL; | 
					
						
							|  |  |  | 	return malloc (size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void* debug_mmgr_realloc (void* ctx, void* ptr, qse_size_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	debug_mmgr_count++; | 
					
						
							|  |  |  | 	if (debug_mmgr_count % g_failmalloc == 0) return QSE_NULL; | 
					
						
							|  |  |  | 	return realloc (ptr, size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void debug_mmgr_free (void* ctx, void* ptr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	free (ptr); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static qse_mmgr_t debug_mmgr = | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	debug_mmgr_alloc, | 
					
						
							|  |  |  | 	debug_mmgr_realloc, | 
					
						
							|  |  |  | 	debug_mmgr_free, | 
					
						
							|  |  |  | 	QSE_NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | static qse_mmgr_t xma_mmgr =  | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-04 01:48:42 +00:00
										 |  |  | 	(qse_mmgr_alloc_t)qse_xma_alloc, | 
					
						
							|  |  |  | 	(qse_mmgr_realloc_t)qse_xma_realloc, | 
					
						
							|  |  |  | 	(qse_mmgr_free_t)qse_xma_free, | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 	QSE_NULL | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[]) | 
					
						
							| 
									
										
										
										
											2009-03-02 21:34:43 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-05 07:08:19 +00:00
										 |  |  | 	const qse_char_t* b = qse_basename (argv[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	qse_fprintf (out, QSE_T("USAGE: %s [options] script [file]\n"), b); | 
					
						
							|  |  |  | 	qse_fprintf (out, QSE_T("       %s [options] -f script-file [file]\n"), b); | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T("       %s [options] -e script [file]\n"), b); | 
					
						
							| 
									
										
										
										
											2009-09-05 07:08:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T("options as follows:\n")); | 
					
						
							| 
									
										
										
										
											2009-09-05 07:08:19 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -h        show this message\n")); | 
					
						
							|  |  |  | 	qse_fprintf (out, QSE_T(" -n        disable auto-print\n")); | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -e script specify a script.  \n")); | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -f file   specify a script file\n")); | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -o file   specify an output file\n")); | 
					
						
							| 
									
										
										
										
											2011-09-05 10:21:54 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -r        use the extended regular expression\n")); | 
					
						
							| 
									
										
										
										
											2011-09-09 01:49:53 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -R        enable non-standard extensions to the regular expression\n")); | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -i        perform in-place editing. imply -s\n")); | 
					
						
							|  |  |  | 	qse_fprintf (out, QSE_T(" -s        process input files separately\n")); | 
					
						
							| 
									
										
										
										
											2011-09-20 22:40:45 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -a        perform strict address and label check\n")); | 
					
						
							| 
									
										
										
										
											2011-09-29 00:31:17 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -w        allow extended address formats\n")); | 
					
						
							|  |  |  | 	qse_fprintf (out, QSE_T("           <start~step>,<start,+line>,<start,~line>,<0,/regex/>\n")); | 
					
						
							| 
									
										
										
										
											2011-09-05 10:21:54 +00:00
										 |  |  | 	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")); | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #if defined(QSE_ENABLE_SEDTRACER)
 | 
					
						
							|  |  |  | 	qse_fprintf (out, QSE_T(" -t        print command traces\n")); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 	qse_fprintf (out, QSE_T(" -m number specify the maximum amount of memory to use in bytes\n")); | 
					
						
							| 
									
										
										
										
											2011-09-20 00:51:02 +00:00
										 |  |  | #if defined(QSE_BUILD_DEBUG)
 | 
					
						
							|  |  |  | 	qse_fprintf (out, QSE_T(" -X number fail the number'th memory allocation\n")); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | static int add_script (const qse_char_t* str, int mem) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (g_script.size >= g_script.capa) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		qse_sed_iostd_t* tmp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		tmp = QSE_MMGR_REALLOC ( | 
					
						
							|  |  |  | 			QSE_MMGR_GETDFL(),  | 
					
						
							|  |  |  | 			g_script.io,  | 
					
						
							|  |  |  | 			QSE_SIZEOF(*g_script.io) * (g_script.capa + 16 + 1)); | 
					
						
							|  |  |  | 		if (tmp == QSE_NULL)  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory while processing %s\n"), str); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		g_script.io = tmp; | 
					
						
							|  |  |  | 		g_script.capa += 16; | 
					
						
							|  |  |  | 	}  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mem) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		g_script.io[g_script.size].type = QSE_SED_IOSTD_MEM; | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | 		/* though its type is not qualified to be const, 
 | 
					
						
							|  |  |  | 		 * u.mem.ptr is actually const when used for input */ | 
					
						
							|  |  |  | 		g_script.io[g_script.size].u.mem.ptr = (qse_char_t*)str; | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 		g_script.io[g_script.size].u.mem.len = qse_strlen(str); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		g_script.io[g_script.size].type = QSE_SED_IOSTD_FILE; | 
					
						
							|  |  |  | 		g_script.io[g_script.size].u.file =  | 
					
						
							|  |  |  | 			(qse_strcmp (str, QSE_T("-")) == 0)? QSE_NULL: str; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	g_script.size++; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void free_scripts (void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (g_script.io) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		QSE_MMGR_FREE (QSE_MMGR_GETDFL(), g_script.io); | 
					
						
							|  |  |  | 		g_script.io = QSE_NULL; | 
					
						
							|  |  |  | 		g_script.capa = 0; | 
					
						
							|  |  |  | 		g_script.size = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | static int handle_args (int argc, qse_char_t* argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static qse_opt_t opt =  | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-09-20 00:51:02 +00:00
										 |  |  | #if defined(QSE_BUILD_DEBUG)
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 		QSE_T("hne:f:o:rRisawxytm:X:"), | 
					
						
							| 
									
										
										
										
											2011-09-20 00:51:02 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 		QSE_T("hne:f:o:rRisawxytm:"), | 
					
						
							| 
									
										
										
										
											2011-09-20 00:51:02 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 		QSE_NULL | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	qse_cint_t c; | 
					
						
							| 
									
										
										
										
											2009-03-02 21:44:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 	while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF) | 
					
						
							| 
									
										
										
										
											2009-03-11 04:39:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 		switch (c) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				print_usage (QSE_STDERR, argc, argv); | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 				goto oops; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 06:11:56 +00:00
										 |  |  | 			case QSE_T('?'): | 
					
						
							|  |  |  | 				qse_fprintf (QSE_STDERR,  | 
					
						
							|  |  |  | 					QSE_T("ERROR: bad option - %c\n"), | 
					
						
							|  |  |  | 					opt.opt | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				print_usage (QSE_STDERR, argc, argv); | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 				goto oops; | 
					
						
							| 
									
										
										
										
											2009-06-08 06:11:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			case QSE_T(':'): | 
					
						
							|  |  |  | 				qse_fprintf (QSE_STDERR,  | 
					
						
							|  |  |  | 					QSE_T("ERROR: bad parameter for %c\n"), | 
					
						
							|  |  |  | 					opt.opt | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				print_usage (QSE_STDERR, argc, argv); | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 				goto oops; | 
					
						
							| 
									
										
										
										
											2009-06-08 06:11:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 			case QSE_T('h'): | 
					
						
							|  |  |  | 				print_usage (QSE_STDOUT, argc, argv); | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 				goto done; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			case QSE_T('n'): | 
					
						
							|  |  |  | 				g_option |= QSE_SED_QUIET; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 			case QSE_T('e'): | 
					
						
							|  |  |  | 				if (add_script (opt.arg, 1) <= -1) goto oops; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 10:21:54 +00:00
										 |  |  | 			case QSE_T('f'): | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 				if (add_script (opt.arg, 0) <= -1) goto oops; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2009-06-18 06:43:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			case QSE_T('o'): | 
					
						
							|  |  |  | 				g_output_file = opt.arg; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-18 06:43:50 +00:00
										 |  |  | 			case QSE_T('r'): | 
					
						
							| 
									
										
										
										
											2011-09-03 09:27:44 +00:00
										 |  |  | 				g_option |= QSE_SED_EXTENDEDREX; | 
					
						
							| 
									
										
										
										
											2009-06-18 06:43:50 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2009-09-01 07:24:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-09 01:49:53 +00:00
										 |  |  | 			case QSE_T('R'): | 
					
						
							|  |  |  | 				g_option |= QSE_SED_NONSTDEXTREX; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			case QSE_T('i'): | 
					
						
							|  |  |  | 				/* 'i' implies 's'. */ | 
					
						
							|  |  |  | 				g_inplace = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			case QSE_T('s'): | 
					
						
							|  |  |  | 				g_separate = 1; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-09-05 10:21:54 +00:00
										 |  |  | 			case QSE_T('a'): | 
					
						
							|  |  |  | 				g_option |= QSE_SED_STRICT; | 
					
						
							| 
									
										
										
										
											2009-09-01 07:24:06 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 10:21:54 +00:00
										 |  |  | 			case QSE_T('w'): | 
					
						
							| 
									
										
										
										
											2011-09-29 00:31:17 +00:00
										 |  |  | 				g_option |= QSE_SED_EXTENDEDADR; | 
					
						
							| 
									
										
										
										
											2009-09-01 07:24:06 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2009-09-05 07:08:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-05 10:21:54 +00:00
										 |  |  | 			case QSE_T('x'): | 
					
						
							|  |  |  | 				g_option |= QSE_SED_SAMELINE; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case QSE_T('y'): | 
					
						
							|  |  |  | 				g_option |= QSE_SED_ENSURENL; | 
					
						
							| 
									
										
										
										
											2009-09-05 07:08:19 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 			case QSE_T('t'): | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #if defined(QSE_ENABLE_SEDTRACER)
 | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 				g_trace = 1; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 				print_usage (QSE_STDERR, argc, argv); | 
					
						
							|  |  |  | 				goto oops; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 			case QSE_T('m'): | 
					
						
							|  |  |  | 				g_memlimit = qse_strtoulong (opt.arg); | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2011-09-20 00:51:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(QSE_BUILD_DEBUG)
 | 
					
						
							|  |  |  | 			case QSE_T('X'): | 
					
						
							|  |  |  |                     g_failmalloc = qse_strtoulong (opt.arg); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 	if (opt.ind < argc && g_script.size <= 0)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (add_script (argv[opt.ind++], 1) <= -1) goto oops; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 	if (opt.ind < argc) g_infile_pos = opt.ind; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 	if (g_script.size <= 0) | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		print_usage (QSE_STDERR, argc, argv); | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 		goto oops; | 
					
						
							| 
									
										
										
										
											2009-03-11 04:39:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 	g_script.io[g_script.size].type = QSE_SED_IOSTD_NULL; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2009-09-08 07:34:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | oops: | 
					
						
							|  |  |  | 	free_scripts (); | 
					
						
							|  |  |  | 	return -1; | 
					
						
							| 
									
										
										
										
											2009-09-08 07:34:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | done: | 
					
						
							|  |  |  | 	free_scripts (); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-09-08 07:34:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | void print_exec_error (qse_sed_t* sed) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const qse_sed_loc_t* errloc = qse_sed_geterrloc(sed); | 
					
						
							|  |  |  | 	if (errloc->line > 0 || errloc->colm > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		qse_fprintf (QSE_STDERR,  | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			QSE_T("ERROR: cannot execute - %s at line %lu column %lu\n"), | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			qse_sed_geterrmsg(sed), | 
					
						
							|  |  |  | 			(unsigned long)errloc->line, | 
					
						
							|  |  |  | 			(unsigned long)errloc->colm | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		qse_fprintf (QSE_STDERR,  | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			QSE_T("ERROR: cannot execute - %s\n"), | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			qse_sed_geterrmsg(sed) | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-20 22:40:45 +00:00
										 |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | static BOOL WINAPI stop_run (DWORD ctrl_type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (ctrl_type == CTRL_C_EVENT || | 
					
						
							|  |  |  | 	    ctrl_type == CTRL_CLOSE_EVENT) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		qse_sed_stop (g_sed); | 
					
						
							|  |  |  | 		return TRUE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static ULONG _System stop_run ( | 
					
						
							|  |  |  | 	PEXCEPTIONREPORTRECORD p1, | 
					
						
							|  |  |  | 	PEXCEPTIONREGISTRATIONRECORD p2, | 
					
						
							|  |  |  | 	PCONTEXTRECORD p3, | 
					
						
							|  |  |  | 	PVOID pv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (p1->ExceptionNum == XCPT_SIGNAL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (p1->ExceptionInfo[0] == XCPT_SIGNAL_INTR || | 
					
						
							|  |  |  | 		    p1->ExceptionInfo[0] == XCPT_SIGNAL_KILLPROC || | 
					
						
							|  |  |  | 		    p1->ExceptionInfo[0] == XCPT_SIGNAL_BREAK) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			APIRET rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			qse_sed_stop (g_sed); | 
					
						
							|  |  |  | 			rc = DosAcknowledgeSignalException (p1->ExceptionInfo[0]); | 
					
						
							|  |  |  | 			return (rc != NO_ERROR)? 1: XCPT_CONTINUE_EXECUTION;  | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return XCPT_CONTINUE_SEARCH; /* exception not resolved */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #elif defined(__DOS__)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void setsignal (int sig, void(*handler)(int)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	signal (sig, handler); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void stop_run (int sig) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	qse_sed_stop (g_sed); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int setsignal (int sig, void(*handler)(int), int restart) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct sigaction sa_int; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sa_int.sa_handler = handler; | 
					
						
							|  |  |  | 	sigemptyset (&sa_int.sa_mask); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	sa_int.sa_flags = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (restart) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	#ifdef SA_RESTART
 | 
					
						
							|  |  |  | 		sa_int.sa_flags |= SA_RESTART; | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	#ifdef SA_INTERRUPT
 | 
					
						
							|  |  |  | 		sa_int.sa_flags |= SA_INTERRUPT; | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return sigaction (sig, &sa_int, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void stop_run (int sig) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int e = errno; | 
					
						
							|  |  |  | 	qse_sed_stop (g_sed); | 
					
						
							|  |  |  | 	errno = e; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(__OS2__)
 | 
					
						
							|  |  |  | static EXCEPTIONREGISTRATIONRECORD os2_excrr = { 0 }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void set_intr_run (void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	SetConsoleCtrlHandler (stop_run, TRUE); | 
					
						
							|  |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | 	APIRET rc; | 
					
						
							|  |  |  | 	os2_excrr.ExceptionHandler = (ERR)stop_run; | 
					
						
							|  |  |  | 	rc = DosSetExceptionHandler (&os2_excrr); | 
					
						
							|  |  |  | 	/*if (rc != NO_ERROR)...*/ | 
					
						
							|  |  |  | #elif defined(__DOS__)
 | 
					
						
							|  |  |  | 	setsignal (SIGINT, stop_run); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	/*setsignal (SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/ | 
					
						
							|  |  |  | 	setsignal (SIGINT, stop_run, 0); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void unset_intr_run (void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | 	SetConsoleCtrlHandler (stop_run, FALSE); | 
					
						
							|  |  |  | #elif defined(__OS2__)
 | 
					
						
							|  |  |  | 	APIRET rc; | 
					
						
							|  |  |  | 	rc = DosUnsetExceptionHandler (&os2_excrr); | 
					
						
							|  |  |  | 	/*if (rc != NO_ERROR) ...*/ | 
					
						
							|  |  |  | #elif defined(__DOS__)
 | 
					
						
							|  |  |  | 	setsignal (SIGINT, SIG_DFL); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	setsignal (SIGINT, SIG_DFL, 1); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #if defined(QSE_ENABLE_SEDTRACER)
 | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | static void trace_exec (qse_sed_t* sed, qse_sed_exec_op_t op, const qse_sed_cmd_t* cmd) | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	switch (op) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 		case QSE_SED_EXEC_READ: | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | 			qse_fprintf (QSE_STDERR, QSE_T("reading...\n")); | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case QSE_SED_EXEC_WRITE: | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | 			qse_fprintf (QSE_STDERR, QSE_T("wrting...\n")); | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | 		/* TODO: use function to get hold space and pattern space and print them */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 		case QSE_SED_EXEC_MATCH: | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | 			qse_fprintf (QSE_STDERR, QSE_T("%s:%lu [%c] MA\n"),  | 
					
						
							|  |  |  | 				((cmd->lid && cmd->lid[0])? cmd->lid: QSE_T("<<UNKNOWN>>")),  | 
					
						
							|  |  |  | 				(unsigned long)cmd->loc.line, | 
					
						
							|  |  |  | 				cmd->type | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 		case QSE_SED_EXEC_EXEC: | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | 			qse_fprintf (QSE_STDERR, QSE_T("%s:%lu [%c] EC\n"),  | 
					
						
							|  |  |  | 				((cmd->lid && cmd->lid[0])? cmd->lid: QSE_T("<<UNKNOWN>>")),  | 
					
						
							|  |  |  | 				(unsigned long)cmd->loc.line, | 
					
						
							|  |  |  | 				cmd->type | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | int sed_main (int argc, qse_char_t* argv[]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 	qse_mmgr_t* mmgr = QSE_NULL; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 	qse_sed_t* sed = QSE_NULL; | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 	qse_fs_t* fs = QSE_NULL; | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 	qse_size_t script_count; | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 	int ret = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = handle_args (argc, argv); | 
					
						
							|  |  |  | 	if (ret <= -1) return -1; | 
					
						
							|  |  |  | 	if (ret == 0) return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = -1; | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-20 00:51:02 +00:00
										 |  |  | #if defined(QSE_BUILD_DEBUG)
 | 
					
						
							|  |  |  | 	if (g_failmalloc > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		debug_mmgr.ctx = QSE_NULL; | 
					
						
							|  |  |  | 		mmgr = &debug_mmgr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 	if (g_memlimit > 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-08-15 03:07:31 +00:00
										 |  |  | 		xma_mmgr.ctx = qse_xma_open (QSE_NULL, 0, g_memlimit); | 
					
						
							|  |  |  | 		if (xma_mmgr.ctx == QSE_NULL) | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			qse_printf (QSE_T("ERROR: cannot open memory heap\n")); | 
					
						
							|  |  |  | 			goto oops; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		mmgr = &xma_mmgr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 	if (g_separate && g_infile_pos > 0 && g_inplace) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		fs = qse_fs_open (mmgr, 0); | 
					
						
							|  |  |  | 		if (fs == QSE_NULL) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open file system handler\n")); | 
					
						
							|  |  |  | 			goto oops; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (qse_fs_chdir (fs, QSE_T(".")) <= -1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			qse_fprintf (QSE_STDERR,  | 
					
						
							|  |  |  | 				QSE_T("ERROR: cannot change direcotry in file system handler - %s\n"),  | 
					
						
							|  |  |  | 				qse_fs_geterrmsg(fs) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 			goto oops; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 	sed = qse_sed_openstdwithmmgr (mmgr, 0); | 
					
						
							| 
									
										
										
										
											2009-03-02 21:44:36 +00:00
										 |  |  | 	if (sed == QSE_NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 		qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open stream editor\n")); | 
					
						
							| 
									
										
										
										
											2009-03-02 21:44:36 +00:00
										 |  |  | 		goto oops; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-06-08 00:23:53 +00:00
										 |  |  | 	qse_sed_setoption (sed, g_option); | 
					
						
							| 
									
										
										
										
											2009-03-11 04:39:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 	if (qse_sed_compstd (sed, g_script.io, &script_count) <= -1) | 
					
						
							| 
									
										
										
										
											2009-03-11 04:39:18 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-08-26 21:03:51 +00:00
										 |  |  | 		const qse_sed_loc_t* errloc = qse_sed_geterrloc(sed); | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 		const qse_char_t* target; | 
					
						
							|  |  |  | 		qse_char_t exprbuf[128]; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		if (g_script.io[script_count].type == QSE_SED_IOSTD_FILE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			target = g_script.io[script_count].u.file; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			/* i dont' use QSE_SED_IOSTD_SIO for input */	 | 
					
						
							|  |  |  | 			QSE_ASSERT (g_script.io[script_count].type == QSE_SED_IOSTD_MEM); | 
					
						
							|  |  |  | 			qse_sprintf (exprbuf, QSE_COUNTOF(exprbuf),  | 
					
						
							|  |  |  | 				QSE_T("expression #%lu"), (unsigned long)script_count); | 
					
						
							|  |  |  | 			target = exprbuf; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-18 07:15:14 +00:00
										 |  |  | 		if (errloc->line > 0 || errloc->colm > 0) | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			qse_fprintf (QSE_STDERR,  | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 				QSE_T("ERROR: cannot compile %s - %s at line %lu column %lu\n"), | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 				target, | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 				qse_sed_geterrmsg(sed), | 
					
						
							| 
									
										
										
										
											2010-08-18 07:15:14 +00:00
										 |  |  | 				(unsigned long)errloc->line, | 
					
						
							|  |  |  | 				(unsigned long)errloc->colm | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			qse_fprintf (QSE_STDERR,  | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 				QSE_T("ERROR: cannot compile %s - %s\n"), | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 				target, | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 				qse_sed_geterrmsg(sed) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-03-11 04:39:18 +00:00
										 |  |  | 		goto oops; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-03-02 21:44:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #if defined(QSE_ENABLE_SEDTRACER)
 | 
					
						
							| 
									
										
										
										
											2011-10-06 00:41:04 +00:00
										 |  |  | 	if (g_trace) qse_sed_setexectracer (sed, trace_exec); | 
					
						
							| 
									
										
										
										
											2011-10-07 23:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-09-24 08:52:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 	if (g_separate && g_infile_pos > 0) | 
					
						
							| 
									
										
										
										
											2009-04-02 19:15:45 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 		/* 's' and input files are specified on the command line */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		qse_sed_iostd_t out_file; | 
					
						
							|  |  |  | 		qse_sed_iostd_t out_inplace; | 
					
						
							|  |  |  | 		qse_sed_iostd_t* output_file = QSE_NULL; | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 		qse_sed_iostd_t* output = QSE_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (g_output_file &&  | 
					
						
							|  |  |  | 		    qse_strcmp (g_output_file, QSE_T("-")) != 0) | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			out_file.type = QSE_SED_IOSTD_SIO; | 
					
						
							|  |  |  | 			out_file.u.sio = qse_sio_open ( | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 				qse_sed_getmmgr(sed), | 
					
						
							|  |  |  | 				0, | 
					
						
							|  |  |  | 				g_output_file, | 
					
						
							|  |  |  | 				QSE_SIO_WRITE | | 
					
						
							|  |  |  | 				QSE_SIO_CREATE | | 
					
						
							|  |  |  | 				QSE_SIO_TRUNCATE | | 
					
						
							|  |  |  | 				QSE_SIO_IGNOREMBWCERR | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 			); | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			if (out_file.u.sio == QSE_NULL) | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 				qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open %s\n"), g_output_file); | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 				goto oops; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			output_file = &out_file; | 
					
						
							|  |  |  | 			output = output_file; | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		while (g_infile_pos < argc) | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			qse_sed_iostd_t in[2]; | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			qse_char_t* tmpl_tmpfile; | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			in[0].type = QSE_SED_IOSTD_FILE; | 
					
						
							|  |  |  | 			in[0].u.file = | 
					
						
							|  |  |  | 				(qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)?  | 
					
						
							|  |  |  | 				QSE_NULL: argv[g_infile_pos]; | 
					
						
							|  |  |  | 			in[1].type = QSE_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			tmpl_tmpfile = QSE_NULL; | 
					
						
							|  |  |  | 			if (g_inplace && in[0].u.file) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				tmpl_tmpfile = qse_strdup2 (in[0].u.file, QSE_T(".XXXX"),  qse_sed_getmmgr(sed)); | 
					
						
							|  |  |  | 				if (tmpl_tmpfile == QSE_NULL) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n")); | 
					
						
							|  |  |  | 					goto oops; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				out_inplace.type = QSE_SED_IOSTD_SIO; | 
					
						
							|  |  |  | 				out_inplace.u.sio = qse_sio_open ( | 
					
						
							|  |  |  | 					qse_sed_getmmgr(sed), | 
					
						
							|  |  |  | 					0, | 
					
						
							|  |  |  | 					tmpl_tmpfile, | 
					
						
							|  |  |  | 					QSE_SIO_WRITE | | 
					
						
							|  |  |  | 					QSE_SIO_CREATE | | 
					
						
							|  |  |  | 					QSE_SIO_IGNOREMBWCERR | | 
					
						
							|  |  |  | 					QSE_SIO_EXCLUSIVE | | 
					
						
							|  |  |  | 					QSE_SIO_TEMPORARY | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				if (out_inplace.u.sio == QSE_NULL) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open %s\n"), tmpl_tmpfile); | 
					
						
							|  |  |  | 					QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile); | 
					
						
							|  |  |  | 					goto oops; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				output = &out_inplace; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			if (qse_sed_execstd (sed, in, output) <= -1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (output) qse_sio_close (output->u.sio); | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (tmpl_tmpfile)  | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | TODO: | 
					
						
							|  |  |  | 					qse_fs_remove (fs, tmpl_tmpfile); | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 					QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 				print_exec_error (sed); | 
					
						
							|  |  |  | 				goto oops; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-10-12 00:19:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			if (tmpl_tmpfile) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				QSE_ASSERT (output == &out_inplace); | 
					
						
							|  |  |  | 				qse_sio_close (output->u.sio); | 
					
						
							|  |  |  | 				output = output_file; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (qse_fs_move (fs, tmpl_tmpfile, in[0].u.file) <= -1) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot rename %s to %s. not deleting %s - %s\n"),  | 
					
						
							|  |  |  | 						tmpl_tmpfile, in[0].u.file, tmpl_tmpfile, qse_fs_geterrmsg(fs)); | 
					
						
							|  |  |  | 					QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile); | 
					
						
							|  |  |  | 					goto oops; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-20 22:40:45 +00:00
										 |  |  | 			if (qse_sed_isstop (sed)) break; | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			g_infile_pos++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (output) qse_sio_close (output->u.sio); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		int xx; | 
					
						
							|  |  |  | 		qse_sed_iostd_t* in = QSE_NULL; | 
					
						
							|  |  |  | 		qse_sed_iostd_t out; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (g_infile_pos > 0) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			int i, num_ins; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 			/* input files are specified on the command line */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 			num_ins = argc - g_infile_pos; | 
					
						
							|  |  |  | 			in = QSE_MMGR_ALLOC (qse_sed_getmmgr(sed), QSE_SIZEOF(*in) * (num_ins + 1)); | 
					
						
							|  |  |  | 			if (in == QSE_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 				qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n")); | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 				goto oops; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i = 0; i < num_ins; i++) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				in[i].type = QSE_SED_IOSTD_FILE; | 
					
						
							|  |  |  | 				in[i].u.file = | 
					
						
							|  |  |  | 					(qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)?  | 
					
						
							|  |  |  | 					QSE_NULL: argv[g_infile_pos]; | 
					
						
							|  |  |  | 				g_infile_pos++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			in[i].type = QSE_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (g_output_file) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			out.type = QSE_SED_IOSTD_FILE; | 
					
						
							|  |  |  | 			out.u.file =  | 
					
						
							|  |  |  | 				(qse_strcmp (g_output_file, QSE_T("-")) == 0)?  | 
					
						
							|  |  |  | 				QSE_NULL: g_output_file; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-20 22:40:45 +00:00
										 |  |  | 		g_sed = sed; | 
					
						
							|  |  |  | 		set_intr_run (); | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 		xx = qse_sed_execstd (sed, in, (g_output_file? &out: QSE_NULL)); | 
					
						
							|  |  |  | 		if (in) QSE_MMGR_FREE (qse_sed_getmmgr(sed), in); | 
					
						
							| 
									
										
										
										
											2011-09-20 22:40:45 +00:00
										 |  |  | 		unset_intr_run (); | 
					
						
							|  |  |  | 		g_sed = QSE_NULL; | 
					
						
							| 
									
										
										
										
											2011-09-18 09:41:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (xx <= -1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			print_exec_error (sed); | 
					
						
							|  |  |  | 			goto oops; | 
					
						
							| 
									
										
										
										
											2009-05-25 07:29:12 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-04-02 19:15:45 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-02 21:44:36 +00:00
										 |  |  | 	ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | oops: | 
					
						
							| 
									
										
										
										
											2010-07-29 07:27:03 +00:00
										 |  |  | 	if (sed) qse_sed_close (sed); | 
					
						
							| 
									
										
										
										
											2011-11-20 16:24:11 +00:00
										 |  |  | 	if (fs) qse_fs_close (fs); | 
					
						
							| 
									
										
										
										
											2011-08-15 03:07:31 +00:00
										 |  |  | 	if (xma_mmgr.ctx) qse_xma_close (xma_mmgr.ctx); | 
					
						
							| 
									
										
										
										
											2011-10-03 01:25:23 +00:00
										 |  |  | 	free_scripts (); | 
					
						
							| 
									
										
										
										
											2009-03-02 21:44:36 +00:00
										 |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2009-03-02 21:34:43 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-03-02 21:44:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-18 07:15:14 +00:00
										 |  |  | int qse_main (int argc, qse_achar_t* argv[]) | 
					
						
							| 
									
										
										
										
											2009-03-11 04:39:18 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return qse_runmain (argc, argv, sed_main); | 
					
						
							|  |  |  | } |