-
Notifications
You must be signed in to change notification settings - Fork 39
/
kate`-top-to-bottom-orig.c
85 lines (72 loc) · 2.05 KB
/
kate`-top-to-bottom-orig.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*** snip ***/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
struct fields { bool precision_set; };
/*** snip ***/
/*
* Read the precision given by a formatting specifier. This is expected to be
* passed a pointer to the '.' character (if present) which begins the precision
* specification. It will consume as many further character as it needs, up to
* but not including the conversion specifier or ength modifiers.
*
* The argument ap is expected to point to the current va_list; this may be
* moved along by way of va_arg() if appropriate (namely for a precision of '*').
*
* A pointer to the conversion specifier is returned. (That is, a pointer to
* the next character after the precision has been dealt with.)
*/
static const char *
readprecision(const char *p, struct fields *fields, int *precision, va_list *ap)
{
char *ep;
long int l;
assert(p != NULL);
assert(*p != '\0');
assert(fields != NULL);
assert(precision != NULL);
assert(ap != NULL);
/* precision omitted */
if ('.' != *p) {
return p;
}
p++;
/* precision passed as parameter */
if ('*' == *p) {
*precision = va_arg(*ap, int);
fields->precision_set = true;
return p + 1;
}
/* S7.19.6.1 "if only the period is specified, the precision is taken as
* zero." */
if (!isdigit((unsigned char) *p)) {
fields->precision_set = true;
*precision = 0;
return p;
}
/* TODO: do we need to save and restore errno to leave it untouched? */
errno = 0;
l = strtol(p, &ep, 10);
if (ERANGE == errno && (LONG_MAX == l || LONG_MIN == l)) {
/* TODO: handle error */
return NULL;
}
if (l > INT_MAX || l < INT_MIN) {
/* TODO: handle error */
return NULL;
}
assert(ep > p);
*precision = l;
fields->precision_set = true;
return ep;
}
/**************** snip ********************/
int main(void)
{
return 0;
}