Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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