コード例 #1
0
ファイル: sed.c プロジェクト: BackupTheBerlios/athomux-svn
/*
 *  Process the commands arguments
 */
static char *parse_cmd_args(sed_cmd_t *sed_cmd, char *cmdstr)
{
	/* handle (s)ubstitution command */
	if (sed_cmd->cmd == 's') cmdstr += parse_subst_cmd(sed_cmd, cmdstr);
	/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
	else if (strchr("aic", sed_cmd->cmd)) {
		if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c')
			bb_error_msg_and_die
				("only a beginning address can be specified for edit commands");
		while(isspace(*cmdstr)) cmdstr++;
		sed_cmd->string = bb_xstrdup(cmdstr);
		parse_escapes(sed_cmd->string,sed_cmd->string,strlen(cmdstr),0,0);
		cmdstr += strlen(cmdstr);
	/* handle file cmds: (r)ead */
	} else if(strchr("rw", sed_cmd->cmd)) {
		if (sed_cmd->end_line || sed_cmd->end_match)
			bb_error_msg_and_die("Command only uses one address");
		cmdstr += parse_file_cmd(sed_cmd, cmdstr, &sed_cmd->string);
		if(sed_cmd->cmd=='w')
			sed_cmd->file=bb_xfopen(sed_cmd->string,"w");
	/* handle branch commands */
	} else if (strchr(":bt", sed_cmd->cmd)) {
		int length;

		while(isspace(*cmdstr)) cmdstr++;
		length = strcspn(cmdstr, semicolon_whitespace);
		if (length) {
			sed_cmd->string = strndup(cmdstr, length);
			cmdstr += length;
		}
	}
	/* translation command */
	else if (sed_cmd->cmd == 'y') {
		char *match, *replace;
		int i=cmdstr[0];

		cmdstr+=parse_regex_delim(cmdstr, &match, &replace)+1;
		/* \n already parsed, but \delimiter needs unescaping. */
		parse_escapes(match,match,strlen(match),i,i);
		parse_escapes(replace,replace,strlen(replace),i,i);

		sed_cmd->string = xcalloc(1, (strlen(match) + 1) * 2);
		for (i = 0; match[i] && replace[i]; i++) {
			sed_cmd->string[i * 2] = match[i];
			sed_cmd->string[(i * 2) + 1] = replace[i];
		}
		free(match);
		free(replace);
	}
	/* if it wasnt a single-letter command that takes no arguments
	 * then it must be an invalid command.
	 */
	else if (strchr("dDgGhHlnNpPqx={}", sed_cmd->cmd) == 0) {
		bb_error_msg_and_die("Unsupported command %c", sed_cmd->cmd);
	}

	/* give back whatever's left over */
	return (cmdstr);
}
コード例 #2
0
ファイル: sed.c プロジェクト: BackupTheBerlios/wl530g-svn
static char *parse_cmd_str(struct sed_cmd * const sed_cmd, const char *const cmdstr)
{
	int idx = 0;

	/* parse the command
	 * format is: [addr][,addr]cmd
	 *            |----||-----||-|
	 *            part1 part2  part3
	 */

	/* first part (if present) is an address: either a number or a /regex/ */
	if (isdigit(cmdstr[idx]) || cmdstr[idx] == '/')
		idx = get_address(sed_cmd, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match);

	/* second part (if present) will begin with a comma */
	if (cmdstr[idx] == ',') {
		idx++;
		idx += get_address(sed_cmd, &cmdstr[idx], &sed_cmd->end_line, &sed_cmd->end_match);
	}

	/* last part (mandatory) will be a command */
	if (cmdstr[idx] == '\0')
		error_msg_and_die("missing command");
	sed_cmd->cmd = cmdstr[idx];

	/* if it was a single-letter command that takes no arguments (such as 'p'
	 * or 'd') all we need to do is increment the index past that command */
	if (strchr("pd", cmdstr[idx])) {
		idx++;
	}
	/* handle (s)ubstitution command */
	else if (sed_cmd->cmd == 's') {
		idx += parse_subst_cmd(sed_cmd, &cmdstr[idx]);
	}
	/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
	else if (strchr("aic", sed_cmd->cmd)) {
		if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c')
			error_msg_and_die("only a beginning address can be specified for edit commands");
		idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]);
	}
	/* handle file cmds: (r)ead */
	else if (sed_cmd->cmd == 'r') {
		if (sed_cmd->end_line || sed_cmd->end_match)
			error_msg_and_die("Command only uses one address");
		idx += parse_file_cmd(sed_cmd, &cmdstr[idx]);
	}
	else {
		error_msg_and_die("invalid command");
	}

	/* give back whatever's left over */
	return (char *)&cmdstr[idx];
}
コード例 #3
0
ファイル: sed.c プロジェクト: rehsack/busybox
/*
 *  Process the commands arguments
 */
static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
{
	static const char cmd_letters[] ALIGN1 = "saicrw:btTydDgGhHlnNpPqx={}";
	enum {
		IDX_s = 0,
		IDX_a,
		IDX_i,
		IDX_c,
		IDX_r,
		IDX_w,
		IDX_colon,
		IDX_b,
		IDX_t,
		IDX_T,
		IDX_y,
		IDX_d,
		IDX_D,
		IDX_g,
		IDX_G,
		IDX_h,
		IDX_H,
		IDX_l,
		IDX_n,
		IDX_N,
		IDX_p,
		IDX_P,
		IDX_q,
		IDX_x,
		IDX_equal,
		IDX_lbrace,
		IDX_rbrace,
		IDX_nul
	};
	unsigned idx;

	BUILD_BUG_ON(sizeof(cmd_letters)-1 != IDX_nul);

	idx = strchrnul(cmd_letters, sed_cmd->cmd) - cmd_letters;

	/* handle (s)ubstitution command */
	if (idx == IDX_s) {
		cmdstr += parse_subst_cmd(sed_cmd, cmdstr);
	}
	/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
	else if (idx <= IDX_c) { /* a,i,c */
		unsigned len;

		if (idx < IDX_c) { /* a,i */
			if (sed_cmd->end_line || sed_cmd->end_match)
				bb_error_msg_and_die("command '%c' uses only one address", sed_cmd->cmd);
		}
		for (;;) {
			if (*cmdstr == '\n' || *cmdstr == '\\') {
				cmdstr++;
				break;
			}
			if (!isspace(*cmdstr))
				break;
			cmdstr++;
		}
		len = strlen(cmdstr);
		sed_cmd->string = copy_parsing_escapes(cmdstr, len);
		cmdstr += len;
		/* "\anychar" -> "anychar" */
		parse_escapes(sed_cmd->string, sed_cmd->string, -1, '\0', '\0');
	}
	/* handle file cmds: (r)ead */
	else if (idx <= IDX_w) { /* r,w */
		if (idx < IDX_w) { /* r */
			if (sed_cmd->end_line || sed_cmd->end_match)
				bb_error_msg_and_die("command '%c' uses only one address", sed_cmd->cmd);
		}
		cmdstr += parse_file_cmd(/*sed_cmd,*/ cmdstr, &sed_cmd->string);
		if (sed_cmd->cmd == 'w') {
			sed_cmd->sw_file = xfopen_for_write(sed_cmd->string);
			sed_cmd->sw_last_char = '\n';
		}
	}
	/* handle branch commands */
	else if (idx <= IDX_T) { /* :,b,t,T */
		int length;

		cmdstr = skip_whitespace(cmdstr);
		length = strcspn(cmdstr, semicolon_whitespace);
		if (length) {
			sed_cmd->string = xstrndup(cmdstr, length);
			cmdstr += length;
		}
	}
	/* translation command */
	else if (idx == IDX_y) {
		char *match, *replace;
		int i = cmdstr[0];

		cmdstr += parse_regex_delim(cmdstr, &match, &replace)+1;
		/* \n already parsed, but \delimiter needs unescaping. */
		parse_escapes(match,   match,   -1, i, i);
		parse_escapes(replace, replace, -1, i, i);

		sed_cmd->string = xzalloc((strlen(match) + 1) * 2);
		for (i = 0; match[i] && replace[i]; i++) {
			sed_cmd->string[i*2] = match[i];
			sed_cmd->string[i*2+1] = replace[i];
		}
		free(match);
		free(replace);
	}
	/* if it wasn't a single-letter command that takes no arguments
	 * then it must be an invalid command.
	 */
	else if (idx >= IDX_nul) { /* not d,D,g,G,h,H,l,n,N,p,P,q,x,=,{,} */
		bb_error_msg_and_die("unsupported command %c", sed_cmd->cmd);
	}

	/* give back whatever's left over */
	return cmdstr;
}