/* here it is! */ int parser(unsigned inflag,char* token,int tokmax,char* line,char* white,char* brkchar,char* quote, char eschar,char* brkused,int* next,char* quoted){ int qp; char c,nc; *brkused=0; /* initialize to null */ *quoted=0; /* assume not quoted */ if(!line[*next]) /* if we're at end of line, indicate such */ return 1; _p_state=IN_WHITE; /* initialize state */ _p_curquote=0; /* initialize previous quote char */ _p_flag=inflag; /* set option flag */ for(_p_tokpos=0;c=line[*next];++(*next)) /* main loop */ { if((qp=sindex(c,brkchar))>=0) /* break */ { switch(_p_state) { case IN_WHITE: /* these are the same here ... */ case IN_TOKEN: /* ... just get out */ case IN_OZONE: /* ditto */ ++(*next); *brkused=brkchar[qp]; goto byebye; case IN_QUOTE: /* just keep going */ chstore(token,tokmax,c); break; } } else if((qp=sindex(c,quote))>=0) /* quote */ { switch(_p_state) { case IN_WHITE: /* these are identical, */ _p_state=IN_QUOTE; /* change states */ _p_curquote=quote[qp]; /* save quote char */ *quoted=1; /* set to true as long as something is in quotes */ break; case IN_QUOTE: if(quote[qp]==_p_curquote) /* same as the beginning quote? */ { _p_state=IN_OZONE; _p_curquote=0; } else chstore(token,tokmax,c); /* treat as regular char */ break; case IN_TOKEN: case IN_OZONE: *brkused=c; /* uses quote as break char */ goto byebye; } } else if((qp=sindex(c,white))>=0) /* white */ { switch(_p_state) { case IN_WHITE: case IN_OZONE: break; /* keep going */ case IN_TOKEN: _p_state=IN_OZONE; break; case IN_QUOTE: chstore(token,tokmax,c); /* it's valid here */ break; } } else if(c==eschar) /* escape */ { nc=line[(*next)+1]; if(nc==0) /* end of line */ { *brkused=0; chstore(token,tokmax,c); ++(*next); goto byebye; } switch(_p_state) { case IN_WHITE: --(*next); _p_state=IN_TOKEN; break; case IN_TOKEN: case IN_QUOTE: ++(*next); chstore(token,tokmax,nc); break; case IN_OZONE: goto byebye; } } else /* anything else is just a real character */ { switch(_p_state) { case IN_WHITE: _p_state=IN_TOKEN; /* switch states */ case IN_TOKEN: /* these 2 are */ case IN_QUOTE: /* identical here */ chstore(token,tokmax,c); break; case IN_OZONE: goto byebye; } } } /* end of main loop */ byebye: token[_p_tokpos]=0; /* make sure token ends with EOS */ return 0; }
int Parse(char *token, int tokmax, char *line, int *next, int *brkpos, int *quotepos) { int qp; int i, c, nc; *brkpos = -1; *quotepos = -1; for (i = 0; i < NN; i++) quote_open[i] = 0; if (!line[*next]) return 1; state = IN_WHITE; for (tokpos = 0; (c = line[*next]); (*next)++) { if ((qp = sindex(c, delim)) >= 0) { switch(state) { case IN_WHITE: case IN_TOKEN: case IN_OZONE: (*next)++; *brkpos = qp; goto OUT; case IN_QUOTE: chstore(token, tokmax, c); break; } } else if ((qp = sindex(c, quote_begin)) >= 0) { switch (state) { case IN_WHITE: state = IN_QUOTE; *quotepos = qp; quote_open[qp]++; break; case IN_QUOTE: if (qp == *quotepos) { if (c == quote_end[*quotepos]) { state = IN_OZONE; quote_open[qp]--; } else { quote_open[qp]++; chstore(token, tokmax, c); } } else { chstore(token, tokmax, c); } break; case IN_TOKEN: case IN_OZONE: goto OUT; } } else if ((qp = sindex(c, quote_end)) >= 0) { switch (state) { case IN_QUOTE: if (quote_open[qp] > 1) { chstore(token, tokmax, c); quote_open[qp]--; } else if (quote_open[qp] < 1) { chstore(token, tokmax, c); } else { state = IN_OZONE; quote_open[qp]--; } break; default: *quotepos = qp; return -1; } } else if ((qp = sindex(c, white)) >= 0) { switch (state) { case IN_WHITE: case IN_OZONE: break; case IN_TOKEN: state = IN_OZONE; break; case IN_QUOTE: chstore(token, tokmax, c); break; } } else if (c == escape) { nc = line[(*next)+1]; if (nc == '\0') { chstore(token, tokmax, c); (*next)++; goto OUT; } switch(state) { case IN_WHITE: (*next)--; state = IN_TOKEN; break; case IN_TOKEN: case IN_QUOTE: (*next)++; chstore(token, tokmax, nc); break; case IN_OZONE: goto OUT; } } else { switch (state) { case IN_WHITE: state = IN_TOKEN; case IN_TOKEN: case IN_QUOTE: chstore(token, tokmax, c); break; case IN_OZONE: goto OUT; } } } OUT: token[tokpos] = '\0'; return 0; }