alloc array for commands, use string ptr in parse_command_string()

This commit is contained in:
Glenn L McGrath 2003-03-09 11:06:38 +00:00
parent e7a8bc949b
commit 4c6523a90b

@ -104,7 +104,7 @@ typedef struct sed_cmd_s {
} sed_cmd_t; } sed_cmd_t;
/* globals */ /* globals */
static sed_cmd_t *sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */ static sed_cmd_t **sed_cmds = NULL; /* growable arrary holding a sequence of sed cmds */
static int ncmds = 0; /* number of sed commands */ static int ncmds = 0; /* number of sed commands */
/*static char *cur_file = NULL;*/ /* file currently being processed XXX: do I need this? */ /*static char *cur_file = NULL;*/ /* file currently being processed XXX: do I need this? */
@ -120,19 +120,19 @@ static void destroy_cmd_strs(void)
/* destroy all the elements in the array */ /* destroy all the elements in the array */
while (--ncmds >= 0) { while (--ncmds >= 0) {
if (sed_cmds[ncmds].beg_match) { if (sed_cmds[ncmds]->beg_match) {
regfree(sed_cmds[ncmds].beg_match); regfree(sed_cmds[ncmds]->beg_match);
free(sed_cmds[ncmds].beg_match); free(sed_cmds[ncmds]->beg_match);
} }
if (sed_cmds[ncmds].end_match) { if (sed_cmds[ncmds]->end_match) {
regfree(sed_cmds[ncmds].end_match); regfree(sed_cmds[ncmds]->end_match);
free(sed_cmds[ncmds].end_match); free(sed_cmds[ncmds]->end_match);
} }
if (sed_cmds[ncmds].sub_match) { if (sed_cmds[ncmds]->sub_match) {
regfree(sed_cmds[ncmds].sub_match); regfree(sed_cmds[ncmds]->sub_match);
free(sed_cmds[ncmds].sub_match); free(sed_cmds[ncmds]->sub_match);
} }
free(sed_cmds[ncmds].replace); free(sed_cmds[ncmds]->replace);
} }
/* destroy the array */ /* destroy the array */
@ -382,8 +382,6 @@ static int parse_file_cmd(sed_cmd_t *sed_cmd, const char *filecmdstr)
static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr) static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
{ {
int idx = 0;
/* parse the command /* parse the command
* format is: [addr][,addr]cmd * format is: [addr][,addr]cmd
* |----||-----||-| * |----||-----||-|
@ -391,29 +389,29 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
*/ */
/* first part (if present) is an address: either a '$', a number or a /regex/ */ /* first part (if present) is an address: either a '$', a number or a /regex/ */
idx = get_address(&sed_cmd->delimiter, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); cmdstr += get_address(&sed_cmd->delimiter, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match);
/* second part (if present) will begin with a comma */ /* second part (if present) will begin with a comma */
if (cmdstr[idx] == ',') { if (*cmdstr == ',') {
int tmp_idx; int tmp_idx;
idx++; cmdstr++;
tmp_idx = get_address(&sed_cmd->delimiter, &cmdstr[idx], &sed_cmd->end_line, &sed_cmd->end_match); tmp_idx = get_address(&sed_cmd->delimiter, cmdstr, &sed_cmd->end_line, &sed_cmd->end_match);
if (tmp_idx == 0) { if (tmp_idx == 0) {
error_msg_and_die("get_address: no address found in string\n" error_msg_and_die("get_address: no address found in string\n"
"\t(you probably didn't check the string you passed me)"); "\t(you probably didn't check the string you passed me)");
} }
idx += tmp_idx; cmdstr += tmp_idx;
} }
/* skip whitespace before the command */ /* skip whitespace before the command */
while (isspace(cmdstr[idx])) while (isspace(*cmdstr))
idx++; cmdstr++;
/* there my be the inversion flag between part2 and part3 */ /* there my be the inversion flag between part2 and part3 */
sed_cmd->invert = 0; sed_cmd->invert = 0;
if (cmdstr[idx] == '!') { if (*cmdstr == '!') {
sed_cmd->invert = 1; sed_cmd->invert = 1;
idx++; cmdstr++;
#ifdef SED_FEATURE_STRICT_CHECKING #ifdef SED_FEATURE_STRICT_CHECKING
/* According to the spec /* According to the spec
@ -421,48 +419,49 @@ static char *parse_cmd_str(sed_cmd_t * const sed_cmd, char *cmdstr)
* and conforming applications shall not follow a '!' character * and conforming applications shall not follow a '!' character
* with <blank>s. * with <blank>s.
*/ */
if (isblank(cmdstr[idx]) { if (isblank(*cmdstr) {
error_msg_and_die("blank follows '!'"); error_msg_and_die("blank follows '!'");
} }
#else #else
/* skip whitespace before the command */ /* skip whitespace before the command */
while (isspace(cmdstr[idx])) while (isspace(*cmdstr))
idx++; cmdstr++;
#endif #endif
} }
/* last part (mandatory) will be a command */ /* last part (mandatory) will be a command */
if (cmdstr[idx] == '\0') if (*cmdstr == '\0')
error_msg_and_die("missing command"); error_msg_and_die("missing command");
sed_cmd->cmd = cmdstr[idx];
sed_cmd->cmd = *cmdstr;
/* if it was a single-letter command that takes no arguments (such as 'p' /* 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 */ * or 'd') all we need to do is increment the index past that command */
if (strchr("pd=", sed_cmd->cmd)) { if (strchr("pd=", sed_cmd->cmd)) {
idx++; cmdstr++;
} }
/* handle (s)ubstitution command */ /* handle (s)ubstitution command */
else if (sed_cmd->cmd == 's') { else if (sed_cmd->cmd == 's') {
idx += parse_subst_cmd(sed_cmd, &cmdstr[idx]); cmdstr += parse_subst_cmd(sed_cmd, cmdstr);
} }
/* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */
else if (strchr("aic", sed_cmd->cmd)) { else if (strchr("aic", sed_cmd->cmd)) {
if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') 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"); error_msg_and_die("only a beginning address can be specified for edit commands");
idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]); cmdstr += parse_edit_cmd(sed_cmd, cmdstr);
} }
/* handle file cmds: (r)ead */ /* handle file cmds: (r)ead */
else if (sed_cmd->cmd == 'r') { else if (sed_cmd->cmd == 'r') {
if (sed_cmd->end_line || sed_cmd->end_match) if (sed_cmd->end_line || sed_cmd->end_match)
error_msg_and_die("Command only uses one address"); error_msg_and_die("Command only uses one address");
idx += parse_file_cmd(sed_cmd, &cmdstr[idx]); cmdstr += parse_file_cmd(sed_cmd, cmdstr);
} }
else { else {
error_msg_and_die("Unsupported command %c", sed_cmd->cmd); error_msg_and_die("Unsupported command %c", sed_cmd->cmd);
} }
/* give back whatever's left over */ /* give back whatever's left over */
return (char *)&cmdstr[idx]; return(cmdstr);
} }
static void add_cmd_str(const char * const cmdstr) static void add_cmd_str(const char * const cmdstr)
@ -483,11 +482,11 @@ static void add_cmd_str(const char * const cmdstr)
continue; continue;
} }
/* grow the array */ /* grow the array */
sed_cmds = xrealloc(sed_cmds, sizeof(sed_cmd_t) * (++ncmds)); sed_cmds = xrealloc(sed_cmds, sizeof(sed_cmd_t *) * (++ncmds));
/* zero new element */ /* zero new element */
memset(&sed_cmds[ncmds-1], 0, sizeof(sed_cmd_t)); sed_cmds[ncmds-1] = xcalloc(1, sizeof(sed_cmd_t));
/* load command string into new array element, get remainder */ /* load command string into new array element, get remainder */
mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr); mystr = parse_cmd_str(sed_cmds[ncmds-1], mystr);
} while (mystr && strlen(mystr)); } while (mystr && strlen(mystr));
} }
@ -676,7 +675,7 @@ static void process_file(FILE *file)
/* for every line, go through all the commands */ /* for every line, go through all the commands */
for (i = 0; i < ncmds; i++) { for (i = 0; i < ncmds; i++) {
sed_cmd_t *sed_cmd = &sed_cmds[i]; sed_cmd_t *sed_cmd = sed_cmds[i];
int deleted = 0; int deleted = 0;
/* /*
@ -745,7 +744,7 @@ static void process_file(FILE *file)
* (this is quite possibly the second printing) */ * (this is quite possibly the second printing) */
if (sed_cmd->sub_p) if (sed_cmd->sub_p)
altered |= do_subst_command(sed_cmd, &line); altered |= do_subst_command(sed_cmd, &line);
if (altered && (i+1 >= ncmds || sed_cmds[i+1].cmd != 's')) if (altered && (i+1 >= ncmds || sed_cmds[i+1]->cmd != 's'))
puts(line); puts(line);
break; break;