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; }
97 const void *any_lookup(ParseState *ps, const void *inf, size_t sz) {
101 (tname= *(const char *const*)inf);
102 inf= (const char*)inf + sz)
103 if (!thiswordstrcmp(ps,tname))
108 const void *any_needword_lookup(ParseState *ps, const void *infs,
109 size_t sz, const char *what) {
111 if (!ps_needword(ps)) return 0;
112 r= any_lookup(ps,infs,sz);
113 if (!r) { badcmd(ps,"unknown %s",what); return 0; }
117 int lstrstrcmp(const char *a, int la, const char *b) {
121 minl= la < lb ? la : lb;
125 return (la < lb ? -1 :
129 int thiswordstrcmp(ParseState *ps, const char *b) {
130 return lstrstrcmp(ps->thisword, ps->lthisword, b);