2004-05-15 23:55:53 +00:00
|
|
|
#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
|
2004-05-16 07:54:22 +00:00
|
|
|
Bskipws(Biobufhdr *bp) {
|
2004-05-15 23:55:53 +00:00
|
|
|
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) {
|
2004-05-16 07:54:22 +00:00
|
|
|
if (c >= '0' && c <= '9'){
|
2004-05-15 23:55:53 +00:00
|
|
|
if (base == 8 && c > '7') return(-1);
|
|
|
|
|
else return(c - '0');
|
2004-05-16 07:54:22 +00:00
|
|
|
}
|
2004-05-15 23:55:53 +00:00
|
|
|
|
2004-05-16 07:54:22 +00:00
|
|
|
if (base == 16){
|
2004-05-15 23:55:53 +00:00
|
|
|
if (c >= 'a' && c <= 'f') return(10 + c - 'a');
|
|
|
|
|
else if (c >= 'A' && c <= 'F') return(10 + c - 'A');
|
2004-05-16 07:54:22 +00:00
|
|
|
}
|
2004-05-15 23:55:53 +00:00
|
|
|
|
|
|
|
|
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
|
2004-05-16 07:54:22 +00:00
|
|
|
Bgetfield(Biobufhdr *bp, int type, void *thing, int size) {
|
2004-05-15 23:55:53 +00:00
|
|
|
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);
|
|
|
|
|
}
|