diff options
author | rsc <devnull@localhost> | 2004-05-15 23:55:53 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-05-15 23:55:53 +0000 |
commit | 61f5c35c9465f0702739b41249a664d409f0482c (patch) | |
tree | 17546b7dcc76abd9ee74dc7543cc77121acfe39a /src/cmd/postscript/tr2post/Bgetfield.c | |
parent | 173302913ebce353eadcbb12d71c3759cbe79e34 (diff) | |
download | plan9port-61f5c35c9465f0702739b41249a664d409f0482c.tar.gz plan9port-61f5c35c9465f0702739b41249a664d409f0482c.tar.bz2 plan9port-61f5c35c9465f0702739b41249a664d409f0482c.zip |
more files
Diffstat (limited to 'src/cmd/postscript/tr2post/Bgetfield.c')
-rw-r--r-- | src/cmd/postscript/tr2post/Bgetfield.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/cmd/postscript/tr2post/Bgetfield.c b/src/cmd/postscript/tr2post/Bgetfield.c new file mode 100644 index 00000000..8922139d --- /dev/null +++ b/src/cmd/postscript/tr2post/Bgetfield.c @@ -0,0 +1,156 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "../common/common.h" +#include "tr2post.h" + +#undef isspace +#define isspace bisspace + +int +isspace(Rune r) +{ + return(r==' ' || r=='\t' || r=='\n' || r == '\r' || r=='\f'); +} + +int +Bskipws(Biobuf *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(Biobuf *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); +} |