3 * utilities for helping parsing
13 int badcmd(ParseState *ps, const char *fmt, ...) {
17 r= vbadcmd(ps,fmt,al);
22 int ps_word(ParseState *ps) {
24 if (!ps->remain) { ps->lthisword=0; return -1; }
25 space= strchr(ps->remain, ' ');
26 ps->thisword= ps->remain;
28 ps->lthisword= space - ps->thisword;
29 ps->remain= space + 1;
31 ps->lthisword= strlen(ps->remain);
37 int ps_needword(ParseState *ps) {
38 if (ps_word(ps)<0) return badcmd(ps,"too few args");
42 void ps_pushbackword(ParseState *ps) {
43 ps->remain= ps->thisword;
46 int ps_neednumber(ParseState *ps, long *r,
47 long mi, long mx, const char *wh) {
51 MUSTECR( ps_needword(ps) );
52 errno= 0; v= strtol(ps->thisword,&ep,0);
53 if (errno || ep != ps->thisword + ps->lthisword)
54 return badcmd(ps,"invalid number for %s",wh);
56 return badcmd(ps,"%s %ld out of range %ld..%ld",wh,v,mi,mx);
61 int ps_neednoargs(ParseState *ps) {
63 return badcmd(ps,"too many arguments");
67 int ps_needhextoend(ParseState *ps, Byte *d, int *len_io) {
68 Byte *d_begin, *d_end;
75 if (!ps->remain) return badcmd(ps,"need hex data block");
77 if (ps_word(ps)<0) break;
78 while (ps->lthisword > 0) {
79 if (ps->lthisword & 1)
80 return badcmd(ps,"hex data block with odd number of digits in part");
81 buf[0]= ps->thisword[0];
82 buf[1]= ps->thisword[1];
83 if (d >= d_end) return badcmd(ps,"hex data block too long");
84 *d++= strtoul(buf,&ep,16);
85 if (*ep) return badcmd(ps,"invalid digit in hex data block");
95 const void *any_lookup(ParseState *ps, const void *inf, int ninfsmax,
101 i<ninfsmax && (tname= *(const char *const*)inf);
102 i++, inf= (const char*)inf + sz)
103 if (!thiswordstrcmp(ps,tname))
108 const void *any_needword_lookup(ParseState *ps, const void *infs, int ninfsmax,
109 size_t sz, const char *what) {
113 ec= ps_needword(ps); if (ec) return 0;
114 r= any_lookup(ps,infs,ninfsmax,sz);
116 badcmd(ps,"unknown %s %.*s",what, ps->lthisword,ps->thisword);
122 int lstrstrcmp(const char *a, int la, const char *b) {
126 minl= la < lb ? la : lb;
130 return (la < lb ? -1 :
134 int thiswordstrcmp(ParseState *ps, const char *b) {
135 return lstrstrcmp(ps->thisword, ps->lthisword, b);