#include #include #include #include "../common/common.h" #include "tr2post.h" int isspace(Rune r) { return r==' ' || r=='\t' || r=='\n' || r=='\r' || r=='\f'; } int Bskipws(Biobufhdr *bp) { int r, sindex = 0; /* skip over initial white space */ do { r = Bgetrune(bp); if (r == '\n') inputlineno++; sindex++; } while (r>=0 && isspace(r)); if (r<0) return(-1); else if (!isspace(r)) { Bungetrune(bp); --sindex; } return sindex; } int asc2dig(char c, int base) { if (c >= '0' && c <= '9') if (base == 8 && c > '7') return(-1); else return(c - '0'); if (base == 16) if (c >= 'a' && c <= 'f') return(10 + c - 'a'); else if (c >= 'A' && c <= 'F') return(10 + c - 'A'); return(-1); } /* * get a string of type: "d" for decimal integer, "u" for unsigned, * "s" for string", "c" for char, * return the number of characters gotten for the field. If nothing * was gotten and the end of file was reached, a negative value * from the Bgetrune is returned. */ int Bgetfield(Biobufhdr *bp, int type, void *thing, int size) { int base = 10; int dig; int negate = 0; int sindex = 0, i, j, n = 0; long r; Rune R; unsigned u = 0; BOOLEAN bailout = FALSE; char c[UTFmax]; /* skip over initial white space */ if (Bskipws(bp) < 0) return(-1); r = 0; switch (type) { case 'd': while (!bailout && (r = Bgetrune(bp))>=0) { switch (sindex++) { case 0: switch (r) { case '-': negate = 1; continue; case '+': continue; case '0': base = 8; continue; default: break; } break; case 1: if ((r == 'x' || r == 'X') && base == 8) { base = 16; continue; } break; } if ((dig = asc2dig(r, base)) == -1) bailout = TRUE; else n = dig + (n * base); } if (r < 0) return(-1); *(int *)thing = (negate)?-n:n; Bungetrune(bp); break; case 'u': while (!bailout && (r = Bgetrune(bp))>=0) { switch (sindex++) { case 0: if (*c == '0') { base = 8; continue; } break; case 1: if ((r == 'x' || r == 'X') && base == 8) { base = 16; continue; } break; } if ((dig = asc2dig(r, base)) == -1) bailout = TRUE; else u = dig + (n * base); } *(int *)thing = u; if (r < 0) return(-1); Bungetrune(bp); break; case 's': j = 0; while (size > j+UTFmax && (r = Bgetrune(bp)) >= 0 && !isspace(r)) { R = r; i = runetochar(&(((char *)thing)[j]), &R); j += i; sindex++; } ((char *)thing)[j] = '\0'; if (r < 0) return(-1); Bungetrune(bp); break; case 'r': if ((r = Bgetrune(bp))>=0) { *(Rune *)thing = r; sindex++; return(sindex); } if (r <= 0) return(-1); Bungetrune(bp); break; default: return(-2); } if (r < 0 && sindex == 0) return(r); else if (bailout && sindex == 1) { return(0); } else return(sindex); }