XINU
doscan.c
Go to the documentation of this file.
1 /* doscan.c - _doscan, _innum, _instr, _getccl */
2 
3 /* Character look-ahead to be implemented as: ch=control(unit,TTY_IOC_NEXTC) */
4 
5 #include <ctype.h>
6 
7 #define EOF (-2)
8 #define NULL 0
9 
10 #define SPC 01
11 #define STP 02
12 
13 #define SHORT 0
14 #define REGULAR 1
15 #define LONG 2
16 
17 static int _innum(int **, int, int, int, int (*getc) (int, int),
18  int (*ungetc) (int, int), int, int, int *);
19 static int _instr(register char *, int, int, int (*getc) (int, int),
20  int (*ungetc) (int, int), int, int, int *);
21 static char *_getccl(char *);
22 
23 char _sctab[128] = {
24  0, 0, 0, 0, 0, 0, 0, 0,
25  0, SPC, SPC, 0, 0, 0, 0, 0,
26  0, 0, 0, 0, 0, 0, 0, 0,
27  0, 0, 0, 0, 0, 0, 0, 0,
28  SPC, 0, 0, 0, 0, 0, 0, 0,
29  0, 0, 0, 0, 0, 0, 0, 0,
30  0, 0, 0, 0, 0, 0, 0, 0,
31  0, 0, 0, 0, 0, 0, 0, 0,
32 };
33 
34 /*------------------------------------------------------------------------
35  * _doscan - Scan and recognize input according to a format.
36  *------------------------------------------------------------------------
37  */
38 int _doscan(
39  register char *fmt, /* format str for scanf */
40  register int **argp, /* arguments to scanf */
41  int (*getch)(int, int), /* function to get char */
42  int (*ungetch)(int, int),/* function to unget char */
43  int arg1, /* arg to getch/ungetch */
44  int arg2 /* 2nd arg to getch/unge*/
45  )
46 {
47  register int ch;
48  int nmatch, len, ch1;
49  int **ptr, fileended, size;
50 
51  nmatch = 0;
52  fileended = 0;
53  for (;;)
54  {
55  switch (ch = *fmt++)
56  {
57  case '\0':
58  return (nmatch);
59  case '%':
60  if ((ch = *fmt++) == '%')
61  {
62  goto def;
63  }
64  ptr = 0;
65  if (ch != '*')
66  {
67  ptr = argp++;
68  }
69  else
70  {
71  ch = *fmt++;
72  }
73  len = 0;
74  size = REGULAR;
75  while (isdigit(ch))
76  {
77  len = len * 10 + ch - '0';
78  ch = *fmt++;
79  }
80  if (len == 0)
81  {
82  len = 30000;
83  }
84  if (ch == 'l')
85  {
86  ch = *fmt++;
87  size = LONG;
88  }
89  else if (ch == 'h')
90  {
91  size = SHORT;
92  ch = *fmt++;
93  }
94  else if (ch == '[')
95  {
96  fmt = _getccl(fmt);
97  }
98  if (isupper(ch))
99  {
100  ch = tolower(ch);
101  size = LONG;
102  }
103  if (ch == '\0')
104  {
105  return (-1);
106  }
107  if (_innum
108  (ptr, ch, len, size,
109  getch, ungetch, arg1, arg2, &fileended) && ptr)
110  {
111  nmatch++;
112  }
113  if (fileended)
114  {
115  return (nmatch ? nmatch : -1);
116  }
117  break;
118 
119  case ' ':
120  case '\n':
121  case '\t':
122  while ((ch1 =
123  (*getch) (arg1,
124  arg2)) == ' ' || ch1 == '\t' || ch1 == '\n')
125  {;
126  }
127  if (ch1 != EOF)
128  {
129  (*ungetch) (arg1, arg2);
130  }
131  break;
132 
133  default:
134  def:
135  ch1 = (*getch) (arg1, arg2);
136  if (ch1 != ch)
137  {
138  if (ch1 == EOF)
139  {
140  return (-1);
141  }
142  (*ungetch) (arg1, arg2);
143  return nmatch;
144  }
145  }
146  }
147 }
148 
149 /*------------------------------------------------------------------------
150  * _innum - DOCUMENT
151  *------------------------------------------------------------------------
152  */
153 static int _innum(
154  int **ptr,
155  int type,
156  int len,
157  int size,
158  int (*getch)(int, int),
159  int (*ungetch)(int, int),
160  int arg1,
161  int arg2,
162  int *eofptr
163  )
164 {
165  extern double atof(char *p);
166  register char *np;
167  char numbuf[64];
168  register char c, base;
169  int negflg, c1, ndigit;
170  long lcval;
171 
172  if (type == 'c' || type == 's' || type == '[')
173  {
174  return (_instr
175  (ptr ? *(char **)ptr : (char *)NULL, type, len, getch,
176  ungetch, arg1, arg2, eofptr));
177  }
178  lcval = 0;
179  ndigit = 0;
180  base = 10;
181  if (type == 'o')
182  {
183  base = 8;
184  }
185  else if (type == 'x')
186  {
187  base = 16;
188  }
189  np = numbuf;
190  negflg = 0;
191  while ((c = (*getch) (arg1, arg2)) == ' ' || c == '\t' || c == '\n')
192  {;
193  }
194  if (c == '-')
195  {
196  negflg++;
197  *np++ = c;
198  c = (*getch) (arg1, arg2);
199  len--;
200  }
201  else if (c == '+')
202  {
203  len--;
204  c = (*getch) (arg1, arg2);
205  }
206 
207  for (; --len >= 0; *np++ = c, c = (*getch) (arg1, arg2))
208  {
209  if (((isdigit(c)) || base == 16)
210  && (('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')))
211  {
212  ndigit++;
213  if (base == 8)
214  {
215  lcval <<= 3;
216  }
217  else if (base == 10)
218  {
219  lcval = ((lcval << 2) + lcval) << 1;
220  }
221  else
222  {
223  lcval <<= 4;
224  }
225  c1 = c;
226  if ('0' <= c && c <= '9')
227  {
228  c -= '0';
229  }
230  else if ('a' <= c && c <= 'f')
231  {
232  c -= 'a' - 10;
233  }
234  else
235  {
236  c -= 'A' - 10;
237  }
238  lcval += c;
239  c = c1;
240  continue;
241  }
242  else
243  {
244  break;
245  }
246  }
247  if (negflg)
248  {
249  lcval = -lcval;
250  }
251  if (c != EOF)
252  {
253  (*ungetch) (arg1, arg2);
254  *eofptr = 0;
255  }
256  else
257  {
258  *eofptr = 1;
259  }
260  if (ptr == NULL || np == numbuf)
261  {
262  return 0;
263  }
264  *np++ = 0;
265  switch (size)
266  {
267  case SHORT:
268  **(short **)ptr = lcval;
269  break;
270 
271  case REGULAR:
272  **(int **)ptr = lcval;
273  break;
274 
275  case LONG:
276  **(long **)ptr = lcval;
277  break;
278  }
279  return 1;
280 }
281 
282 /*------------------------------------------------------------------------
283  * _instr - DOCUMENT
284  *------------------------------------------------------------------------
285  */
286 static int _instr(
287  register char *ptr,
288  int type,
289  int len,
290  int (*getch)(int, int),
291  int (*ungetch)(int, int),
292  int arg1,
293  int arg2,
294  int *eofptr
295  )
296 {
297  register unsigned int ch;
298  register char *optr;
299  int ignstp;
300 
301  *eofptr = 0;
302  optr = ptr;
303  if (type == 'c' && len == 30000)
304  {
305  len = 1;
306  }
307  ignstp = 0;
308  if (type == 's')
309  {
310  ignstp = SPC;
311  }
312  while (_sctab[ch = (*getch) (arg1, arg2)] & ignstp)
313  {
314  if (ch == EOF)
315  {
316  break;
317  }
318  }
319  ignstp = SPC;
320  if (type == 'c')
321  {
322  ignstp = 0;
323  }
324  else if (type == '[')
325  {
326  ignstp = STP;
327  }
328  while (ch != EOF && (_sctab[ch] & ignstp) == 0)
329  {
330  if (ptr)
331  {
332  *ptr++ = ch;
333  }
334  if (--len <= 0)
335  {
336  break;
337  }
338  ch = (*getch) (arg1, arg2);
339  }
340  if (ch != EOF)
341  {
342  if (len > 0)
343  {
344  (*ungetch) (arg1, arg2);
345  }
346  *eofptr = 0;
347  }
348  else
349  {
350  *eofptr = 1;
351  }
352  if (ptr && ptr != optr)
353  {
354  if (type != 'c')
355  {
356  *ptr++ = '\0';
357  }
358  return 1;
359  }
360  return 0;
361 }
362 
363 /*------------------------------------------------------------------------
364  * _getccl - DOCUMENT
365  *------------------------------------------------------------------------
366  */
367 static char *_getccl(
368  char *s
369  )
370 {
371  int c, t;
372 
373  t = 0;
374  if (*s == '^')
375  {
376  t++;
377  s++;
378  }
379  for (c = 0; c < 128; c++)
380  {
381  if (t)
382  {
383  _sctab[c] &= ~STP;
384  }
385  else
386  {
387  _sctab[c] |= STP;
388  }
389  }
390  while (((c = *s++) & 0177) != ']')
391  {
392  if (t)
393  {
394  _sctab[c++] |= STP;
395  }
396  else
397  {
398  _sctab[c++] &= ~STP;
399  }
400  if (c == 0)
401  {
402  return (--s);
403  }
404  }
405  return s;
406 }
static int ungetch(int, int)
Definition: fscanf.c:60
#define tolower(c)
アルファベットの大文字を小文字に変換するマクロ
#define STP
Definition: doscan.c:11
#define isdigit(c)
文字が10進数の数字かどうかをチェックするマクロ
Definition: ctype.h:78
#define EOF
Definition: doscan.c:7
int _doscan(register char *fmt, register int **argp, int(*getch)(int, int), int(*ungetch)(int, int), int arg1, int arg2)
Definition: doscan.c:38
static int _innum(int **, int, int, int, int(*getc)(int, int), int(*ungetc)(int, int), int, int, int *)
Definition: doscan.c:153
#define isupper(c)
文字がアルファベットの大文字かどうかをチェックするマクロ
Definition: ctype.h:62
「文字種類の判定」や「文字変換」を行う関数マクロを提供する。
syscall getc(did32)
Definition: getc.c:9
#define SPC
Definition: doscan.c:10
#define LONG
Definition: doscan.c:15
static int getch(int, int)
Definition: fscanf.c:40
#define SHORT
Definition: doscan.c:13
#define NULL
Definition: doscan.c:8
char _sctab[128]
Definition: doscan.c:23
#define REGULAR
Definition: doscan.c:14
static int _instr(register char *, int, int, int(*getc)(int, int), int(*ungetc)(int, int), int, int, int *)
Definition: doscan.c:286
static char * _getccl(char *)
Definition: doscan.c:367