still working on sed
This commit is contained in:
		| @ -118,6 +118,15 @@ for (c = sed->cmd.buf; c != sed->cmd.cur; c++) | ||||
| 				QSE_MMGR_FREE (sed->mmgr, c->u.branch.label.ptr); | ||||
| 			break; | ||||
| 	 | ||||
| 		case QSE_SED_CMD_S: | ||||
| 			if (c->u.subst.file.ptr != QSE_NULL) | ||||
| 				QSE_MMGR_FREE (sed->mmgr, c->u.subst.file.ptr); | ||||
| 			if (c->u.subst.rpl.ptr != QSE_NULL) | ||||
| 				QSE_MMGR_FREE (sed->mmgr, c->u.subst.rpl.ptr); | ||||
| 			if (c->u.subst.rex.ptr != QSE_NULL) | ||||
| 				QSE_MMGR_FREE (sed->mmgr, c->u.subst.rex.ptr); | ||||
| 			break; | ||||
|  | ||||
| 		case QSE_SED_CMD_Y: | ||||
| 			if (c->u.transet.ptr != QSE_NULL) | ||||
| 				QSE_MMGR_FREE (sed->mmgr, c->u.transet.ptr); | ||||
| @ -127,8 +136,8 @@ for (c = sed->cmd.buf; c != sed->cmd.cur; c++) | ||||
| 		case QSE_SED_CMD_RR: | ||||
| 		case QSE_SED_CMD_W: | ||||
| 		case QSE_SED_CMD_WW: | ||||
| 			if (c->u.filename.ptr != QSE_NULL) | ||||
| 				QSE_MMGR_FREE (sed->mmgr, c->u.filename.ptr); | ||||
| 			if (c->u.file.ptr != QSE_NULL) | ||||
| 				QSE_MMGR_FREE (sed->mmgr, c->u.file.ptr); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| @ -595,7 +604,7 @@ static int get_file_name (qse_sed_t* sed, qse_sed_cmd_t* cmd) | ||||
| 		qse_str_setlen (t, QSE_STR_LEN(t) - trailing_spaces); | ||||
| 	} | ||||
|  | ||||
| 	qse_str_yield (t, &cmd->u.filename, 0); | ||||
| 	qse_str_yield (t, &cmd->u.file, 0); | ||||
| 	qse_str_close (t); | ||||
| 	return 0; | ||||
|  | ||||
| @ -607,7 +616,8 @@ oops: | ||||
| static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) | ||||
| { | ||||
| 	qse_cint_t c, delim; | ||||
| 	qse_str_t* t = QSE_NULL; | ||||
| 	qse_str_t* t[2] = { QSE_NULL, QSE_NULL }; | ||||
| 	int i; | ||||
|  | ||||
| 	c = CURSC (sed); | ||||
| 	if (c == QSE_CHAR_EOF || IS_LINTERM(c)) | ||||
| @ -625,45 +635,68 @@ static int get_subst (qse_sed_t* sed, qse_sed_cmd_t* cmd) | ||||
| 		goto oops; | ||||
| 	} | ||||
|  | ||||
| 	t = qse_str_open (sed->mmgr, 0, 32); | ||||
| 	if (t == QSE_NULL)  | ||||
| 	{ | ||||
| 		sed->errnum = QSE_SED_ENOMEM; | ||||
| 		goto oops; | ||||
| 	} | ||||
|  | ||||
| 	c = NXTSC (sed); | ||||
| 	while (c != delim) | ||||
| 	{ | ||||
| 		if (c == QSE_CHAR_EOF || IS_LINTERM(c)) | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 	{	 | ||||
| 		t[i] = qse_str_open (sed->mmgr, 0, 32); | ||||
| 		if (t[i] == QSE_NULL)  | ||||
| 		{ | ||||
| 			sed->errnum = QSE_SED_ENOTRM; | ||||
| 			sed->errnum = QSE_SED_ENOMEM; | ||||
| 			goto oops; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 		if (c == QSE_T('\\')) | ||||
|  | ||||
| 	for (i = 0; i < 2; i++) | ||||
| 	{ | ||||
| 		c = NXTSC (sed); | ||||
|  | ||||
| 		while (c != delim) | ||||
| 		{ | ||||
| 			c = NXTSC (sed); | ||||
| 			if (c == QSE_CHAR_EOF || IS_LINTERM(c)) | ||||
| 			{ | ||||
| 				sed->errnum = QSE_SED_ENOTRM; | ||||
| 				goto oops; | ||||
| 			} | ||||
|  | ||||
| 			if (c == QSE_T('n')) c = QSE_T('\n'); | ||||
| 		} | ||||
| 			if (c == QSE_T('\\')) | ||||
| 			{ | ||||
| 				c = NXTSC (sed); | ||||
| 				if (c == QSE_CHAR_EOF || IS_LINTERM(c)) | ||||
| 				{ | ||||
| 					sed->errnum = QSE_SED_ENOTRM; | ||||
| 					goto oops; | ||||
| 				} | ||||
| 	 | ||||
| 				if (c == QSE_T('n')) c = QSE_T('\n'); | ||||
| 			} | ||||
|  | ||||
| 		if (qse_str_ccat (t, c) == (qse_size_t)-1) | ||||
| 		{ | ||||
| 			sed->errnum = QSE_SED_ENOMEM; | ||||
| 			goto oops; | ||||
| 		} | ||||
| 			if (qse_str_ccat (t[i], c) == (qse_size_t)-1) | ||||
| 			{ | ||||
| 				sed->errnum = QSE_SED_ENOMEM; | ||||
| 				goto oops; | ||||
| 			} | ||||
|  | ||||
| 		c = NXTSC (sed); | ||||
| 	}	 | ||||
| 			c = NXTSC (sed); | ||||
| 		}	 | ||||
| 	} | ||||
|  | ||||
| 	c = NXTSC (sed); | ||||
|  | ||||
|  | ||||
| 	ADVSCP (sed); | ||||
| 	if (terminate_command (sed) == -1) goto oops; | ||||
|  | ||||
| 	qse_str_yield (t[1], &cmd->u.subst.rex, 0); | ||||
| 	qse_str_yield (t[0], &cmd->u.subst.rpl, 0); | ||||
|  | ||||
| 	qse_str_close (t[1]); | ||||
| 	qse_str_close (t[0]); | ||||
|  | ||||
| 	return 0; | ||||
|  | ||||
| oops: | ||||
| 	if (t != QSE_NULL) qse_str_close (t); | ||||
| 	if (t[1] != QSE_NULL) qse_str_close (t[1]); | ||||
| 	if (t[0] != QSE_NULL) qse_str_close (t[0]); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| @ -814,7 +847,7 @@ qse_printf (QSE_T("command not recognized [%c]\n"), c); | ||||
| 			 * can be skipped. the branch target is set once a | ||||
| 			 * corresponding } is met. */ | ||||
| 			cmd->type = QSE_SED_CMD_B; | ||||
| 			cmd->negfl = !cmd->negfl; | ||||
| 			cmd->negated = !cmd->negated; | ||||
|  | ||||
| 			if (sed->grplvl >= QSE_COUNTOF(sed->grpcmd)) | ||||
| 			{ | ||||
| @ -943,7 +976,7 @@ qse_printf (QSE_T("cmd->u.branch.target = [%p]\n"), cmd->u.branch.target); | ||||
| 			ADVSCP (sed); | ||||
| 			if (get_file_name (sed, cmd) == -1) return -1; | ||||
|  | ||||
| qse_printf (QSE_T("cmd->u.filename= [%.*s]\n"), (int)cmd->u.filename.len, cmd->u.filename.ptr); | ||||
| qse_printf (QSE_T("cmd->u.file= [%.*s]\n"), (int)cmd->u.file.len, cmd->u.file.ptr); | ||||
| 			break; | ||||
|  | ||||
|  | ||||
| @ -951,6 +984,8 @@ qse_printf (QSE_T("cmd->u.filename= [%.*s]\n"), (int)cmd->u.filename.len, cmd->u | ||||
| 			cmd->type = c; | ||||
| 			ADVSCP (sed); | ||||
| 			if (get_subst (sed, cmd) == -1) return -1; | ||||
| qse_printf (QSE_T("rex= [%.*s]\n"), (int)cmd->u.subst.rex.len, cmd->u.subst.rex.ptr); | ||||
| qse_printf (QSE_T("rpl= [%.*s]\n"), (int)cmd->u.subst.rpl.len, cmd->u.subst.rpl.ptr); | ||||
| 			break; | ||||
|  | ||||
| 		case QSE_T('y'): | ||||
| @ -1039,7 +1074,7 @@ static int compile_source ( | ||||
| 		if (c == QSE_T('!')) | ||||
| 		{ | ||||
| 			/* negate */ | ||||
| 			cmd->negfl = 1; | ||||
| 			cmd->negated = 1; | ||||
| 		} | ||||
|  | ||||
| 		n = command (sed); | ||||
|  | ||||
| @ -46,34 +46,8 @@ struct qse_sed_a_t | ||||
|  | ||||
| struct qse_sed_cmd_t | ||||
| { | ||||
| 	qse_sed_a_t a1; /* optional start address */ | ||||
| 	qse_sed_a_t a2; /* optional end address */ | ||||
|  | ||||
| 	union | ||||
| 	{ | ||||
| 		/* text for the a, i, c commands */ | ||||
| 		qse_xstr_t text;   | ||||
|  | ||||
| 		/* file name for r, w, R, W */ | ||||
| 		qse_xstr_t filename; | ||||
|  | ||||
| 		/* translation set for the y command */ | ||||
| 		qse_xstr_t transet; | ||||
|  | ||||
| 		struct | ||||
| 		{ | ||||
| 			qse_xstr_t label; | ||||
| 			qse_sed_cmd_t* target; | ||||
| 		} branch; | ||||
|  | ||||
| 		void* rex; | ||||
| 	} u;	 | ||||
|  | ||||
| 	qse_char_t* rhs; /* right-hand side of sustitution */ | ||||
|  | ||||
| 	enum | ||||
| 	{ | ||||
|  | ||||
| 		/* print current line number */ | ||||
| 		QSE_SED_CMD_EQ  = QSE_T('='), | ||||
| 		QSE_SED_CMD_Q   = QSE_T('q'), | ||||
| @ -124,8 +98,44 @@ struct qse_sed_cmd_t | ||||
|  | ||||
| 	} type; | ||||
|  | ||||
| 	/* TODO: change the data type to a shorter one to save space */ | ||||
| 	int negfl; | ||||
| 	int negated; | ||||
|  | ||||
| 	qse_sed_a_t a1; /* optional start address */ | ||||
| 	qse_sed_a_t a2; /* optional end address */ | ||||
|  | ||||
| 	union | ||||
| 	{ | ||||
| 		/* text for the a, i, c commands */ | ||||
| 		qse_xstr_t text;   | ||||
|  | ||||
| 		/* file name for r, w, R, W */ | ||||
| 		qse_xstr_t file; | ||||
|  | ||||
| 		/* data for the s command */ | ||||
| 		struct | ||||
| 		{ | ||||
| 			qse_xstr_t rex;  /* regular expression */ | ||||
| 			qse_xstr_t rpl;  /* replacement */ | ||||
|  | ||||
| 			/* flags */ | ||||
| 			qse_xstr_t file; /* file name for w */ | ||||
| 			int pos: 16; | ||||
| 			int p: 1; /* print */ | ||||
| 			int i: 1; /* case insensitive */ | ||||
| 		} subst; | ||||
|  | ||||
| 		/* translation set for the y command */ | ||||
| 		qse_xstr_t transet; | ||||
|  | ||||
| 		struct | ||||
| 		{ | ||||
| 			qse_xstr_t label; | ||||
| 			qse_sed_cmd_t* target; | ||||
| 		} branch; | ||||
|  | ||||
| 		void* rex; | ||||
| 	} u;	 | ||||
|  | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|  | ||||
		Reference in New Issue
	
	Block a user