chiark / gitweb /
better default target
[trains.git] / hostside / parseutils.c
1 /**/
2
3 #include <stdarg.h>
4 #include <errno.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "hostside.h"
9
10 void badcmd(ParseState *ps, const char *fmt, ...) {
11   va_list al;
12   va_start(al,fmt);
13   vbadcmd(ps,fmt,al);
14   va_end(al);
15 }
16
17 int ps_word(ParseState *ps) {
18   const char *space;
19   if (!ps->remain) return 0;
20   space= strchr(ps->remain, ' ');
21   ps->thisword= ps->remain;
22   if (space) {
23     ps->lthisword= space - ps->thisword;
24     ps->remain= space + 1;
25   } else {
26     ps->lthisword= strlen(ps->remain);
27     ps->remain= 0;
28   }
29   return 1;
30 }
31
32 int ps_needword(ParseState *ps) {
33   if (!ps_word(ps)) { badcmd(ps,"too few args"); return 0; }
34   return 1;
35 }
36
37 int ps_neednumber(ParseState *ps, long *r, long mi, long mx, const char *wh) {
38   char *ep;
39   long v;
40   
41   if (!ps_needword(ps)) return 0;
42   errno= 0; v= strtol(ps->thisword,&ep,0);
43   if (errno || ep != ps->thisword + ps->lthisword) {
44     badcmd(ps,"invalid number for %s",wh);
45     return 0;
46   }
47   if (v < mi || v > mx) {
48     badcmd(ps,"%s %ld out of range %ld..%ld",wh,v,mi,mx);
49     return 0;
50   }
51   *r= v;
52   return 1;
53 }
54
55 int ps_neednoargs(ParseState *ps) {
56   if (ps->remain) {
57     badcmd(ps,"too many arguments");
58     return 0;
59   }
60   return 1;
61 }
62  
63 int ps_needhextoend(ParseState *ps, Byte *d, int *len_io) {
64   Byte *d_begin, *d_end;
65   char buf[3], *ep;
66
67   d_begin= d;
68   d_end= d + *len_io;
69   buf[2]= 0;
70   
71   if (!ps->remain) { badcmd(ps,"need hex data block"); return 0; }
72   for (;;) {
73     if (!ps_word(ps)) break;
74     while (ps->lthisword > 0) {
75       if (ps->lthisword & 1) {
76         badcmd(ps,"hex data block with odd number of digits in part");
77         return 0;
78       }
79       buf[0]= ps->thisword[0];
80       buf[1]= ps->thisword[1];
81       if (d >= d_end) { badcmd(ps,"hex data block too long"); return 0; }
82       *d++= strtoul(buf,&ep,16);
83       if (*ep) { badcmd(ps,"invalid digit in hex data block"); return 0; }
84       ps->lthisword -= 2;
85       ps->thisword += 2;
86     }
87   }
88
89   *len_io= d - d_begin;
90   return 1;
91 }
92
93 int lstrstrcmp(const char *a, int la, const char *b) {
94   int lb, minl, r;
95
96   lb= strlen(b);
97   minl= la < lb ? la : lb;
98   r= memcmp(a,b,minl);
99   if (r) return r;
100
101   return (la < lb ? -1 :
102           la > lb ? 1 : 0);
103 }
104
105 int thiswordstrcmp(ParseState *ps, const char *b) {
106   return lstrstrcmp(ps->thisword, ps->lthisword, b);
107 }
108