1*219b2ee8SDavid du Colombier #include <u.h> 2*219b2ee8SDavid du Colombier #include <libc.h> 3*219b2ee8SDavid du Colombier #include <bio.h> 4*219b2ee8SDavid du Colombier #include "../common/common.h" 5*219b2ee8SDavid du Colombier #include "tr2post.h" 6*219b2ee8SDavid du Colombier 7*219b2ee8SDavid du Colombier int 8*219b2ee8SDavid du Colombier isspace(Rune r) 9*219b2ee8SDavid du Colombier { 10*219b2ee8SDavid du Colombier return(r==' ' || r=='\t' || r=='\n' || r == '\r' || r=='\f'); 11*219b2ee8SDavid du Colombier } 12*219b2ee8SDavid du Colombier 13*219b2ee8SDavid du Colombier int 14*219b2ee8SDavid du Colombier Bskipws(Biobufhdr *bp) { 15*219b2ee8SDavid du Colombier int r; 16*219b2ee8SDavid du Colombier char c[UTFmax]; 17*219b2ee8SDavid du Colombier int sindex = 0; 18*219b2ee8SDavid du Colombier 19*219b2ee8SDavid du Colombier /* skip over initial white space */ 20*219b2ee8SDavid du Colombier do { 21*219b2ee8SDavid du Colombier r = Bgetrune(bp); 22*219b2ee8SDavid du Colombier if (r == '\n') inputlineno++; 23*219b2ee8SDavid du Colombier sindex++; 24*219b2ee8SDavid du Colombier } while (r>=0 && isspace(r)); 25*219b2ee8SDavid du Colombier if (r<0) { 26*219b2ee8SDavid du Colombier return(-1); 27*219b2ee8SDavid du Colombier } else if (!isspace(r)) { 28*219b2ee8SDavid du Colombier Bungetrune(bp); 29*219b2ee8SDavid du Colombier --sindex; 30*219b2ee8SDavid du Colombier } 31*219b2ee8SDavid du Colombier return(sindex); 32*219b2ee8SDavid du Colombier } 33*219b2ee8SDavid du Colombier 34*219b2ee8SDavid du Colombier int 35*219b2ee8SDavid du Colombier asc2dig(char c, int base) { 36*219b2ee8SDavid du Colombier if (c >= '0' && c <= '9') 37*219b2ee8SDavid du Colombier if (base == 8 && c > '7') return(-1); 38*219b2ee8SDavid du Colombier else return(c - '0'); 39*219b2ee8SDavid du Colombier 40*219b2ee8SDavid du Colombier if (base == 16) 41*219b2ee8SDavid du Colombier if (c >= 'a' && c <= 'f') return(10 + c - 'a'); 42*219b2ee8SDavid du Colombier else if (c >= 'A' && c <= 'F') return(10 + c - 'A'); 43*219b2ee8SDavid du Colombier 44*219b2ee8SDavid du Colombier return(-1); 45*219b2ee8SDavid du Colombier } 46*219b2ee8SDavid du Colombier 47*219b2ee8SDavid du Colombier /* get a string of type: "d" for decimal integer, "u" for unsigned, 48*219b2ee8SDavid du Colombier * "s" for string", "c" for char, 49*219b2ee8SDavid du Colombier * return the number of characters gotten for the field. If nothing 50*219b2ee8SDavid du Colombier * was gotten and the end of file was reached, a negative value 51*219b2ee8SDavid du Colombier * from the Bgetrune is returned. 52*219b2ee8SDavid du Colombier */ 53*219b2ee8SDavid du Colombier 54*219b2ee8SDavid du Colombier int 55*219b2ee8SDavid du Colombier Bgetfield(Biobufhdr *bp, int type, void *thing, int size) { 56*219b2ee8SDavid du Colombier int r; 57*219b2ee8SDavid du Colombier Rune R; 58*219b2ee8SDavid du Colombier char c[UTFmax]; 59*219b2ee8SDavid du Colombier int sindex = 0, i, j, n = 0; 60*219b2ee8SDavid du Colombier int negate = 0; 61*219b2ee8SDavid du Colombier int base = 10; 62*219b2ee8SDavid du Colombier BOOLEAN bailout = FALSE; 63*219b2ee8SDavid du Colombier int dig; 64*219b2ee8SDavid du Colombier unsigned int u = 0; 65*219b2ee8SDavid du Colombier 66*219b2ee8SDavid du Colombier /* skip over initial white space */ 67*219b2ee8SDavid du Colombier if (Bskipws(bp) < 0) 68*219b2ee8SDavid du Colombier return(-1); 69*219b2ee8SDavid du Colombier 70*219b2ee8SDavid du Colombier switch (type) { 71*219b2ee8SDavid du Colombier case 'd': 72*219b2ee8SDavid du Colombier while (!bailout && (r = Bgetrune(bp))>=0) { 73*219b2ee8SDavid du Colombier switch (sindex++) { 74*219b2ee8SDavid du Colombier case 0: 75*219b2ee8SDavid du Colombier switch (r) { 76*219b2ee8SDavid du Colombier case '-': 77*219b2ee8SDavid du Colombier negate = 1; 78*219b2ee8SDavid du Colombier continue; 79*219b2ee8SDavid du Colombier case '+': 80*219b2ee8SDavid du Colombier continue; 81*219b2ee8SDavid du Colombier case '0': 82*219b2ee8SDavid du Colombier base = 8; 83*219b2ee8SDavid du Colombier continue; 84*219b2ee8SDavid du Colombier default: 85*219b2ee8SDavid du Colombier break; 86*219b2ee8SDavid du Colombier } 87*219b2ee8SDavid du Colombier break; 88*219b2ee8SDavid du Colombier case 1: 89*219b2ee8SDavid du Colombier if ((r == 'x' || r == 'X') && base == 8) { 90*219b2ee8SDavid du Colombier base = 16; 91*219b2ee8SDavid du Colombier continue; 92*219b2ee8SDavid du Colombier } 93*219b2ee8SDavid du Colombier } 94*219b2ee8SDavid du Colombier if ((dig = asc2dig(r, base)) == -1) bailout = TRUE; 95*219b2ee8SDavid du Colombier else n = dig + (n * base); 96*219b2ee8SDavid du Colombier } 97*219b2ee8SDavid du Colombier if (r < 0) return(-1); 98*219b2ee8SDavid du Colombier *(int *)thing = (negate)?-n:n; 99*219b2ee8SDavid du Colombier Bungetrune(bp); 100*219b2ee8SDavid du Colombier break; 101*219b2ee8SDavid du Colombier case 'u': 102*219b2ee8SDavid du Colombier while (!bailout && (r = Bgetrune(bp))>=0) { 103*219b2ee8SDavid du Colombier switch (sindex++) { 104*219b2ee8SDavid du Colombier case 0: 105*219b2ee8SDavid du Colombier if (*c == '0') { 106*219b2ee8SDavid du Colombier base = 8; 107*219b2ee8SDavid du Colombier continue; 108*219b2ee8SDavid du Colombier } 109*219b2ee8SDavid du Colombier break; 110*219b2ee8SDavid du Colombier case 1: 111*219b2ee8SDavid du Colombier if ((r == 'x' || r == 'X') && base == 8) { 112*219b2ee8SDavid du Colombier base = 16; 113*219b2ee8SDavid du Colombier continue; 114*219b2ee8SDavid du Colombier } 115*219b2ee8SDavid du Colombier } 116*219b2ee8SDavid du Colombier if ((dig = asc2dig(r, base)) == -1) bailout = TRUE; 117*219b2ee8SDavid du Colombier else u = dig + (n * base); 118*219b2ee8SDavid du Colombier } 119*219b2ee8SDavid du Colombier *(int *)thing = u; 120*219b2ee8SDavid du Colombier if (r < 0) return(-1); 121*219b2ee8SDavid du Colombier Bungetrune(bp); 122*219b2ee8SDavid du Colombier break; 123*219b2ee8SDavid du Colombier case 's': 124*219b2ee8SDavid du Colombier j = 0; 125*219b2ee8SDavid du Colombier while ((size>j+UTFmax) && (r = Bgetrune(bp))>=0 && !isspace(r)) { 126*219b2ee8SDavid du Colombier R = r; 127*219b2ee8SDavid du Colombier i = runetochar(&(((char *)thing)[j]), &R); 128*219b2ee8SDavid du Colombier j += i; 129*219b2ee8SDavid du Colombier sindex++; 130*219b2ee8SDavid du Colombier } 131*219b2ee8SDavid du Colombier ((char *)thing)[j++] = '\0'; 132*219b2ee8SDavid du Colombier if (r < 0) return(-1); 133*219b2ee8SDavid du Colombier Bungetrune(bp); 134*219b2ee8SDavid du Colombier break; 135*219b2ee8SDavid du Colombier case 'r': 136*219b2ee8SDavid du Colombier if ((r = Bgetrune(bp))>=0) { 137*219b2ee8SDavid du Colombier *(Rune *)thing = r; 138*219b2ee8SDavid du Colombier sindex++; 139*219b2ee8SDavid du Colombier return(sindex); 140*219b2ee8SDavid du Colombier } 141*219b2ee8SDavid du Colombier if (r <= 0) return(-1); 142*219b2ee8SDavid du Colombier Bungetrune(bp); 143*219b2ee8SDavid du Colombier break; 144*219b2ee8SDavid du Colombier default: 145*219b2ee8SDavid du Colombier return(-2); 146*219b2ee8SDavid du Colombier } 147*219b2ee8SDavid du Colombier if (r < 0 && sindex == 0) 148*219b2ee8SDavid du Colombier return(r); 149*219b2ee8SDavid du Colombier else if (bailout && sindex == 1) { 150*219b2ee8SDavid du Colombier return(0); 151*219b2ee8SDavid du Colombier } else 152*219b2ee8SDavid du Colombier return(sindex); 153*219b2ee8SDavid du Colombier } 154