123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #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;
- char c[UTFmax];
- int 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 r;
- Rune R;
- char c[UTFmax];
- int sindex = 0, i, j, n = 0;
- int negate = 0;
- int base = 10;
- BOOLEAN bailout = FALSE;
- int dig;
- unsigned int u = 0;
- /* skip over initial white space */
- if (Bskipws(bp) < 0)
- return(-1);
- 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;
- }
- }
- 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;
- }
- }
- 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);
- }
|