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