3 * utilities for helping parsing
13 void badcmd(ParseState *ps, const char *fmt, ...) {
20 int ps_word(ParseState *ps) {
22 if (!ps->remain) return 0;
23 space= strchr(ps->remain, ' ');
24 ps->thisword= ps->remain;
26 ps->lthisword= space - ps->thisword;
27 ps->remain= space + 1;
29 ps->lthisword= strlen(ps->remain);
35 int ps_needword(ParseState *ps) {
36 if (!ps_word(ps)) { badcmd(ps,"too few args"); return 0; }
40 int ps_neednumber(ParseState *ps, long *r, long mi, long mx, const char *wh) {
44 if (!ps_needword(ps)) return 0;
45 errno= 0; v= strtol(ps->thisword,&ep,0);
46 if (errno || ep != ps->thisword + ps->lthisword) {
47 badcmd(ps,"invalid number for %s",wh);
50 if (v < mi || v > mx) {
51 badcmd(ps,"%s %ld out of range %ld..%ld",wh,v,mi,mx);
58 int ps_neednoargs(ParseState *ps) {
60 badcmd(ps,"too many arguments");
66 int ps_needhextoend(ParseState *ps, Byte *d, int *len_io) {
67 Byte *d_begin, *d_end;
74 if (!ps->remain) { badcmd(ps,"need hex data block"); return 0; }
76 if (!ps_word(ps)) break;
77 while (ps->lthisword > 0) {
78 if (ps->lthisword & 1) {
79 badcmd(ps,"hex data block with odd number of digits in part");
82 buf[0]= ps->thisword[0];
83 buf[1]= ps->thisword[1];
84 if (d >= d_end) { badcmd(ps,"hex data block too long"); return 0; }
85 *d++= strtoul(buf,&ep,16);
86 if (*ep) { badcmd(ps,"invalid digit in hex data block"); return 0; }
96 const void *any_lookup(ParseState *ps, const void *inf, int ninfsmax,
102 i<ninfsmax && (tname= *(const char *const*)inf);
103 inf= (const char*)inf + sz)
104 if (!thiswordstrcmp(ps,tname))
109 const void *any_needword_lookup(ParseState *ps, const void *infs, int ninfsmax,
110 size_t sz, const char *what) {
112 if (!ps_needword(ps)) return 0;
113 r= any_lookup(ps,infs,ninfsmax,sz);
114 if (!r) { badcmd(ps,"unknown %s",what); return 0; }
118 int lstrstrcmp(const char *a, int la, const char *b) {
122 minl= la < lb ? la : lb;
126 return (la < lb ? -1 :
130 int thiswordstrcmp(ParseState *ps, const char *b) {
131 return lstrstrcmp(ps->thisword, ps->lthisword, b);