Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmpdcurses/pdcurses/scanw.c
3153 views
1
/* PDCurses */
2
3
#include <curspriv.h>
4
5
/*man-start**************************************************************
6
7
scanw
8
-----
9
10
### Synopsis
11
12
int scanw(const char *fmt, ...);
13
int wscanw(WINDOW *win, const char *fmt, ...);
14
int mvscanw(int y, int x, const char *fmt, ...);
15
int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...);
16
int vwscanw(WINDOW *win, const char *fmt, va_list varglist);
17
int vw_scanw(WINDOW *win, const char *fmt, va_list varglist);
18
19
### Description
20
21
These routines correspond to the standard C library's scanf() family.
22
Each gets a string from the window via wgetnstr(), and uses the
23
resulting line as input for the scan.
24
25
The duplication between vwscanw() and vw_scanw() is for historic
26
reasons. In PDCurses, they're the same.
27
28
### Return Value
29
30
On successful completion, these functions return the number of items
31
successfully matched. Otherwise they return ERR.
32
33
### Portability
34
X/Open ncurses NetBSD
35
scanw Y Y Y
36
wscanw Y Y Y
37
mvscanw Y Y Y
38
mvwscanw Y Y Y
39
vwscanw Y Y Y
40
vw_scanw Y Y Y
41
42
**man-end****************************************************************/
43
44
#include <string.h>
45
46
#ifndef HAVE_VSSCANF
47
# include <stdlib.h>
48
# include <ctype.h>
49
# include <limits.h>
50
51
static int _pdc_vsscanf(const char *, const char *, va_list);
52
53
# define vsscanf _pdc_vsscanf
54
#endif
55
56
int vwscanw(WINDOW *win, const char *fmt, va_list varglist)
57
{
58
char scanbuf[256];
59
60
PDC_LOG(("vwscanw() - called\n"));
61
62
if (wgetnstr(win, scanbuf, 255) == ERR)
63
return ERR;
64
65
return vsscanf(scanbuf, fmt, varglist);
66
}
67
68
int scanw(const char *fmt, ...)
69
{
70
va_list args;
71
int retval;
72
73
PDC_LOG(("scanw() - called\n"));
74
75
va_start(args, fmt);
76
retval = vwscanw(stdscr, fmt, args);
77
va_end(args);
78
79
return retval;
80
}
81
82
int wscanw(WINDOW *win, const char *fmt, ...)
83
{
84
va_list args;
85
int retval;
86
87
PDC_LOG(("wscanw() - called\n"));
88
89
va_start(args, fmt);
90
retval = vwscanw(win, fmt, args);
91
va_end(args);
92
93
return retval;
94
}
95
96
int mvscanw(int y, int x, const char *fmt, ...)
97
{
98
va_list args;
99
int retval;
100
101
PDC_LOG(("mvscanw() - called\n"));
102
103
if (move(y, x) == ERR)
104
return ERR;
105
106
va_start(args, fmt);
107
retval = vwscanw(stdscr, fmt, args);
108
va_end(args);
109
110
return retval;
111
}
112
113
int mvwscanw(WINDOW *win, int y, int x, const char *fmt, ...)
114
{
115
va_list args;
116
int retval;
117
118
PDC_LOG(("mvscanw() - called\n"));
119
120
if (wmove(win, y, x) == ERR)
121
return ERR;
122
123
va_start(args, fmt);
124
retval = vwscanw(win, fmt, args);
125
va_end(args);
126
127
return retval;
128
}
129
130
int vw_scanw(WINDOW *win, const char *fmt, va_list varglist)
131
{
132
PDC_LOG(("vw_scanw() - called\n"));
133
134
return vwscanw(win, fmt, varglist);
135
}
136
137
#ifndef HAVE_VSSCANF
138
139
/* _pdc_vsscanf() - Internal routine to parse and format an input
140
buffer. It scans a series of input fields; each field is formatted
141
according to a supplied format string and the formatted input is
142
stored in the variable number of addresses passed. Returns the number
143
of input fields or EOF on error.
144
145
Don't compile this unless required. Some compilers (at least Borland
146
C++ 3.0) have to link with math libraries due to the use of floats.
147
148
Based on vsscanf.c and input.c from emx 0.8f library source,
149
Copyright (c) 1990-1992 by Eberhard Mattes, who has kindly agreed to
150
its inclusion in PDCurses. */
151
152
#define WHITE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
153
154
#define NEXT(x) \
155
do { \
156
x = *buf++; \
157
if (!x) \
158
return (count ? count : EOF); \
159
++chars; \
160
} while (0)
161
162
#define UNGETC() \
163
do { \
164
--buf; --chars; \
165
} while (0)
166
167
static int _pdc_vsscanf(const char *buf, const char *fmt, va_list arg_ptr)
168
{
169
int count, chars, c, width, radix, d, i;
170
int *int_ptr;
171
long *long_ptr;
172
short *short_ptr;
173
char *char_ptr;
174
unsigned char f;
175
char neg, assign, ok, size;
176
long n;
177
char map[256], end;
178
double dx, dd, *dbl_ptr;
179
float *flt_ptr;
180
int exp;
181
char eneg;
182
183
count = 0;
184
chars = 0;
185
c = 0;
186
while ((f = *fmt) != 0)
187
{
188
if (WHITE(f))
189
{
190
do
191
{
192
++fmt;
193
f = *fmt;
194
}
195
while (WHITE(f));
196
do
197
{
198
c = *buf++;
199
if (!c)
200
{
201
if (!f || count)
202
return count;
203
else
204
return EOF;
205
} else
206
++chars;
207
}
208
while (WHITE(c));
209
UNGETC();
210
} else if (f != '%')
211
{
212
NEXT(c);
213
if (c != f)
214
return count;
215
++fmt;
216
} else
217
{
218
assign = TRUE;
219
width = INT_MAX;
220
char_ptr = NULL;
221
++fmt;
222
if (*fmt == '*')
223
{
224
assign = FALSE;
225
++fmt;
226
}
227
if (isdigit(*fmt))
228
{
229
width = 0;
230
while (isdigit(*fmt))
231
width = width * 10 + (*fmt++ - '0');
232
if (!width)
233
width = INT_MAX;
234
}
235
size = 0;
236
if (*fmt == 'h' || *fmt == 'l')
237
size = *fmt++;
238
f = *fmt;
239
switch (f)
240
{
241
case 'c':
242
if (width == INT_MAX)
243
width = 1;
244
if (assign)
245
char_ptr = va_arg(arg_ptr, char *);
246
while (width > 0)
247
{
248
--width;
249
NEXT(c);
250
if (assign)
251
{
252
*char_ptr++ = (char) c;
253
++count;
254
}
255
}
256
break;
257
case '[':
258
memset(map, 0, 256);
259
end = 0;
260
++fmt;
261
if (*fmt == '^')
262
{
263
++fmt;
264
end = 1;
265
}
266
i = 0;
267
for (;;)
268
{
269
f = (unsigned char) *fmt;
270
switch (f)
271
{
272
case 0:
273
/* avoid skipping past 0 */
274
--fmt;
275
NEXT(c);
276
goto string;
277
case ']':
278
if (i > 0)
279
{
280
NEXT(c);
281
goto string;
282
}
283
/* no break */
284
default:
285
if (fmt[1] == '-' && fmt[2]
286
&& f < (unsigned char)fmt[2])
287
{
288
memset(map + f, 1, (unsigned char)fmt[2] - f);
289
fmt += 2;
290
}
291
else
292
map[f] = 1;
293
break;
294
}
295
++fmt;
296
++i;
297
}
298
case 's':
299
memset(map, 0, 256);
300
map[' '] = 1;
301
map['\n'] = 1;
302
map['\r'] = 1;
303
map['\t'] = 1;
304
end = 1;
305
do
306
{
307
NEXT(c);
308
}
309
while (WHITE(c));
310
string:
311
if (assign)
312
char_ptr = va_arg(arg_ptr, char *);
313
while (width > 0 && map[(unsigned char) c] != end)
314
{
315
--width;
316
if (assign)
317
*char_ptr++ = (char) c;
318
c = *buf++;
319
if (!c)
320
break;
321
else
322
++chars;
323
}
324
if (assign)
325
{
326
*char_ptr = 0;
327
++count;
328
}
329
if (!c)
330
return count;
331
else
332
UNGETC();
333
break;
334
case 'f':
335
case 'e':
336
case 'E':
337
case 'g':
338
case 'G':
339
neg = ok = FALSE;
340
dx = 0.0;
341
do
342
{
343
NEXT(c);
344
}
345
while (WHITE(c));
346
if (c == '+')
347
{
348
NEXT(c);
349
--width;
350
} else if (c == '-')
351
{
352
neg = TRUE;
353
NEXT(c);
354
--width;
355
}
356
while (width > 0 && isdigit(c))
357
{
358
--width;
359
dx = dx * 10.0 + (double) (c - '0');
360
ok = TRUE;
361
c = *buf++;
362
if (!c)
363
break;
364
else
365
++chars;
366
}
367
if (width > 0 && c == '.')
368
{
369
--width;
370
dd = 10.0;
371
NEXT(c);
372
while (width > 0 && isdigit(c))
373
{
374
--width;
375
dx += (double) (c - '0') / dd;
376
dd *= 10.0;
377
ok = TRUE;
378
c = *buf++;
379
if (!c)
380
break;
381
else
382
++chars;
383
}
384
}
385
if (!ok)
386
return count;
387
if (width > 0 && (c == 'e' || c == 'E'))
388
{
389
eneg = FALSE;
390
exp = 0;
391
NEXT(c);
392
--width;
393
if (width > 0 && c == '+')
394
{
395
NEXT(c);
396
--width;
397
} else if (width > 0 && c == '-')
398
{
399
eneg = TRUE;
400
NEXT(c);
401
--width;
402
}
403
if (!(width > 0 && isdigit(c)))
404
{
405
UNGETC();
406
return count;
407
}
408
while (width > 0 && isdigit(c))
409
{
410
--width;
411
exp = exp * 10 + (c - '0');
412
c = *buf++;
413
if (!c)
414
break;
415
else
416
++chars;
417
}
418
if (eneg)
419
exp = -exp;
420
while (exp > 0)
421
{
422
dx *= 10.0;
423
--exp;
424
}
425
while (exp < 0)
426
{
427
dx /= 10.0;
428
++exp;
429
}
430
}
431
if (assign)
432
{
433
if (neg)
434
dx = -dx;
435
if (size == 'l')
436
{
437
dbl_ptr = va_arg(arg_ptr, double *);
438
*dbl_ptr = dx;
439
}
440
else
441
{
442
flt_ptr = va_arg(arg_ptr, float *);
443
*flt_ptr = (float)dx;
444
}
445
++count;
446
}
447
if (!c)
448
return count;
449
else
450
UNGETC();
451
break;
452
case 'i':
453
neg = FALSE;
454
radix = 10;
455
do
456
{
457
NEXT(c);
458
}
459
while (WHITE(c));
460
if (!(width > 0 && c == '0'))
461
goto scan_complete_number;
462
NEXT(c);
463
--width;
464
if (width > 0 && (c == 'x' || c == 'X'))
465
{
466
NEXT(c);
467
radix = 16;
468
--width;
469
}
470
else if (width > 0 && (c >= '0' && c <= '7'))
471
radix = 8;
472
goto scan_unsigned_number;
473
case 'd':
474
case 'u':
475
case 'o':
476
case 'x':
477
case 'X':
478
do
479
{
480
NEXT(c);
481
}
482
while (WHITE(c));
483
switch (f)
484
{
485
case 'o':
486
radix = 8;
487
break;
488
case 'x':
489
case 'X':
490
radix = 16;
491
break;
492
default:
493
radix = 10;
494
break;
495
}
496
scan_complete_number:
497
neg = FALSE;
498
if (width > 0 && c == '+')
499
{
500
NEXT(c);
501
--width;
502
}
503
else if (width > 0 && c == '-' && radix == 10)
504
{
505
neg = TRUE;
506
NEXT(c);
507
--width;
508
}
509
scan_unsigned_number:
510
n = 0;
511
ok = FALSE;
512
while (width > 0)
513
{
514
--width;
515
if (isdigit(c))
516
d = c - '0';
517
else if (isupper(c))
518
d = c - 'A' + 10;
519
else if (islower(c))
520
d = c - 'a' + 10;
521
else
522
break;
523
if (d < 0 || d >= radix)
524
break;
525
ok = TRUE;
526
n = n * radix + d;
527
c = *buf++;
528
if (!c)
529
break;
530
else
531
++chars;
532
}
533
if (!ok)
534
return count;
535
if (assign)
536
{
537
if (neg)
538
n = -n;
539
switch (size)
540
{
541
case 'h':
542
short_ptr = va_arg(arg_ptr, short *);
543
*short_ptr = (short) n;
544
break;
545
case 'l':
546
long_ptr = va_arg(arg_ptr, long *);
547
*long_ptr = (long) n;
548
break;
549
default:
550
int_ptr = va_arg(arg_ptr, int *);
551
*int_ptr = (int) n;
552
}
553
++count;
554
}
555
if (!c)
556
return count;
557
else
558
UNGETC();
559
break;
560
case 'n':
561
if (assign)
562
{
563
int_ptr = va_arg(arg_ptr, int *);
564
*int_ptr = chars;
565
++count;
566
}
567
break;
568
default:
569
if (!f) /* % at end of string */
570
return count;
571
NEXT(c);
572
if (c != f)
573
return count;
574
break;
575
}
576
++fmt;
577
}
578
}
579
return count;
580
}
581
#endif /* HAVE_VSSCANF */
582
583