1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier #include "../common/common.h"
5219b2ee8SDavid du Colombier #include "tr2post.h"
6219b2ee8SDavid du Colombier
7219b2ee8SDavid du Colombier int
isspace(Rune r)8219b2ee8SDavid du Colombier isspace(Rune r)
9219b2ee8SDavid du Colombier {
10*456a8764SDavid du Colombier return r==' ' || r=='\t' || r=='\n' || r=='\r' || r=='\f';
11219b2ee8SDavid du Colombier }
12219b2ee8SDavid du Colombier
13219b2ee8SDavid du Colombier int
Bskipws(Biobufhdr * bp)14219b2ee8SDavid du Colombier Bskipws(Biobufhdr *bp) {
15*456a8764SDavid du Colombier int r, sindex = 0;
16219b2ee8SDavid du Colombier
17219b2ee8SDavid du Colombier /* skip over initial white space */
18219b2ee8SDavid du Colombier do {
19219b2ee8SDavid du Colombier r = Bgetrune(bp);
20*456a8764SDavid du Colombier if (r == '\n')
21*456a8764SDavid du Colombier inputlineno++;
22219b2ee8SDavid du Colombier sindex++;
23219b2ee8SDavid du Colombier } while (r>=0 && isspace(r));
24*456a8764SDavid du Colombier if (r<0)
25219b2ee8SDavid du Colombier return(-1);
26*456a8764SDavid du Colombier else if (!isspace(r)) {
27219b2ee8SDavid du Colombier Bungetrune(bp);
28219b2ee8SDavid du Colombier --sindex;
29219b2ee8SDavid du Colombier }
30*456a8764SDavid du Colombier return sindex;
31219b2ee8SDavid du Colombier }
32219b2ee8SDavid du Colombier
33219b2ee8SDavid du Colombier int
asc2dig(char c,int base)34219b2ee8SDavid du Colombier asc2dig(char c, int base) {
35219b2ee8SDavid du Colombier if (c >= '0' && c <= '9')
36*456a8764SDavid du Colombier if (base == 8 && c > '7')
37*456a8764SDavid du Colombier return(-1);
38*456a8764SDavid du Colombier else
39*456a8764SDavid du Colombier return(c - '0');
40219b2ee8SDavid du Colombier if (base == 16)
41*456a8764SDavid du Colombier if (c >= 'a' && c <= 'f')
42*456a8764SDavid du Colombier return(10 + c - 'a');
43*456a8764SDavid du Colombier else if (c >= 'A' && c <= 'F')
44*456a8764SDavid du Colombier return(10 + c - 'A');
45219b2ee8SDavid du Colombier return(-1);
46219b2ee8SDavid du Colombier }
47219b2ee8SDavid du Colombier
48*456a8764SDavid du Colombier /*
49*456a8764SDavid du Colombier * get a string of type: "d" for decimal integer, "u" for unsigned,
50219b2ee8SDavid du Colombier * "s" for string", "c" for char,
51219b2ee8SDavid du Colombier * return the number of characters gotten for the field. If nothing
52219b2ee8SDavid du Colombier * was gotten and the end of file was reached, a negative value
53219b2ee8SDavid du Colombier * from the Bgetrune is returned.
54219b2ee8SDavid du Colombier */
55219b2ee8SDavid du Colombier
56219b2ee8SDavid du Colombier int
Bgetfield(Biobufhdr * bp,int type,void * thing,int size)57219b2ee8SDavid du Colombier Bgetfield(Biobufhdr *bp, int type, void *thing, int size) {
58219b2ee8SDavid du Colombier int base = 10;
59219b2ee8SDavid du Colombier int dig;
60*456a8764SDavid du Colombier int negate = 0;
61*456a8764SDavid du Colombier int sindex = 0, i, j, n = 0;
62*456a8764SDavid du Colombier long r;
63*456a8764SDavid du Colombier Rune R;
64*456a8764SDavid du Colombier unsigned u = 0;
65*456a8764SDavid du Colombier BOOLEAN bailout = FALSE;
66*456a8764SDavid du Colombier char c[UTFmax];
67219b2ee8SDavid du Colombier
68219b2ee8SDavid du Colombier /* skip over initial white space */
69219b2ee8SDavid du Colombier if (Bskipws(bp) < 0)
70219b2ee8SDavid du Colombier return(-1);
71219b2ee8SDavid du Colombier
72*456a8764SDavid du Colombier r = 0;
73219b2ee8SDavid du Colombier switch (type) {
74219b2ee8SDavid du Colombier case 'd':
75219b2ee8SDavid du Colombier while (!bailout && (r = Bgetrune(bp))>=0) {
76219b2ee8SDavid du Colombier switch (sindex++) {
77219b2ee8SDavid du Colombier case 0:
78219b2ee8SDavid du Colombier switch (r) {
79219b2ee8SDavid du Colombier case '-':
80219b2ee8SDavid du Colombier negate = 1;
81219b2ee8SDavid du Colombier continue;
82219b2ee8SDavid du Colombier case '+':
83219b2ee8SDavid du Colombier continue;
84219b2ee8SDavid du Colombier case '0':
85219b2ee8SDavid du Colombier base = 8;
86219b2ee8SDavid du Colombier continue;
87219b2ee8SDavid du Colombier default:
88219b2ee8SDavid du Colombier break;
89219b2ee8SDavid du Colombier }
90219b2ee8SDavid du Colombier break;
91219b2ee8SDavid du Colombier case 1:
92219b2ee8SDavid du Colombier if ((r == 'x' || r == 'X') && base == 8) {
93219b2ee8SDavid du Colombier base = 16;
94219b2ee8SDavid du Colombier continue;
95219b2ee8SDavid du Colombier }
96*456a8764SDavid du Colombier break;
97219b2ee8SDavid du Colombier }
98*456a8764SDavid du Colombier if ((dig = asc2dig(r, base)) == -1)
99*456a8764SDavid du Colombier bailout = TRUE;
100*456a8764SDavid du Colombier else
101*456a8764SDavid du Colombier n = dig + (n * base);
102219b2ee8SDavid du Colombier }
103*456a8764SDavid du Colombier if (r < 0)
104*456a8764SDavid du Colombier return(-1);
105219b2ee8SDavid du Colombier *(int *)thing = (negate)?-n:n;
106219b2ee8SDavid du Colombier Bungetrune(bp);
107219b2ee8SDavid du Colombier break;
108219b2ee8SDavid du Colombier case 'u':
109219b2ee8SDavid du Colombier while (!bailout && (r = Bgetrune(bp))>=0) {
110219b2ee8SDavid du Colombier switch (sindex++) {
111219b2ee8SDavid du Colombier case 0:
112219b2ee8SDavid du Colombier if (*c == '0') {
113219b2ee8SDavid du Colombier base = 8;
114219b2ee8SDavid du Colombier continue;
115219b2ee8SDavid du Colombier }
116219b2ee8SDavid du Colombier break;
117219b2ee8SDavid du Colombier case 1:
118219b2ee8SDavid du Colombier if ((r == 'x' || r == 'X') && base == 8) {
119219b2ee8SDavid du Colombier base = 16;
120219b2ee8SDavid du Colombier continue;
121219b2ee8SDavid du Colombier }
122*456a8764SDavid du Colombier break;
123219b2ee8SDavid du Colombier }
124*456a8764SDavid du Colombier if ((dig = asc2dig(r, base)) == -1)
125*456a8764SDavid du Colombier bailout = TRUE;
126*456a8764SDavid du Colombier else
127*456a8764SDavid du Colombier u = dig + (n * base);
128219b2ee8SDavid du Colombier }
129219b2ee8SDavid du Colombier *(int *)thing = u;
130*456a8764SDavid du Colombier if (r < 0)
131*456a8764SDavid du Colombier return(-1);
132219b2ee8SDavid du Colombier Bungetrune(bp);
133219b2ee8SDavid du Colombier break;
134219b2ee8SDavid du Colombier case 's':
135219b2ee8SDavid du Colombier j = 0;
136*456a8764SDavid du Colombier while (size > j+UTFmax && (r = Bgetrune(bp)) >= 0 &&
137*456a8764SDavid du Colombier !isspace(r)) {
138219b2ee8SDavid du Colombier R = r;
139219b2ee8SDavid du Colombier i = runetochar(&(((char *)thing)[j]), &R);
140219b2ee8SDavid du Colombier j += i;
141219b2ee8SDavid du Colombier sindex++;
142219b2ee8SDavid du Colombier }
143*456a8764SDavid du Colombier ((char *)thing)[j] = '\0';
144*456a8764SDavid du Colombier if (r < 0)
145*456a8764SDavid du Colombier return(-1);
146219b2ee8SDavid du Colombier Bungetrune(bp);
147219b2ee8SDavid du Colombier break;
148219b2ee8SDavid du Colombier case 'r':
149219b2ee8SDavid du Colombier if ((r = Bgetrune(bp))>=0) {
150219b2ee8SDavid du Colombier *(Rune *)thing = r;
151219b2ee8SDavid du Colombier sindex++;
152219b2ee8SDavid du Colombier return(sindex);
153219b2ee8SDavid du Colombier }
154*456a8764SDavid du Colombier if (r <= 0)
155*456a8764SDavid du Colombier return(-1);
156219b2ee8SDavid du Colombier Bungetrune(bp);
157219b2ee8SDavid du Colombier break;
158219b2ee8SDavid du Colombier default:
159219b2ee8SDavid du Colombier return(-2);
160219b2ee8SDavid du Colombier }
161219b2ee8SDavid du Colombier if (r < 0 && sindex == 0)
162219b2ee8SDavid du Colombier return(r);
163219b2ee8SDavid du Colombier else if (bailout && sindex == 1) {
164219b2ee8SDavid du Colombier return(0);
165219b2ee8SDavid du Colombier } else
166219b2ee8SDavid du Colombier return(sindex);
167219b2ee8SDavid du Colombier }
168