dpost.ps: increase linewidth to match groff
[troff.git] / tr2ps / ustr.c
blob1ba5d5ac8e417bac8925ca5c9249a46fcbd1d48e
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include "ustr.h"
8 #define MAXFLEN (1 << 20)
10 struct ustr {
11 char buf[MAXFLEN];
12 int len;
13 int cur;
16 int uc_dec(uc_t *dst, char *src)
18 int l = 1;
19 char *s = src;
20 if (~*s & 0xc0) {
21 *dst = *s;
22 return 1;
24 while (l < 6 && *s & (0x40 >> l))
25 l++;
26 *dst = (0x3f >> l) & *s++;
27 while (l--)
28 *dst = (*dst << 6) | (*s++ & 0x3f);
29 return s - src;
32 int uc_enc(char *d, uc_t c)
34 int n, l;
35 if (c > 0xffff) {
36 *d++ = 0xf0 | (c >> 18);
37 l = 3;
38 } else if (c > 0x7ff) {
39 *d++ = 0xe0 | (c >> 12);
40 l = 2;
41 } else if (c > 0x7f) {
42 *d++ = 0xc0 | (c >> 6);
43 l = 1;
44 } else {
45 *d++ = c;
46 l = 0;
48 n = l + 1;
49 while (l--)
50 *d++ = 0x80 | (c >> (l * 6)) & 0x3f;
51 return n;
54 struct ustr *ustr_fill(int fd)
56 struct ustr *us = malloc(sizeof(*us));
57 int nr = 0;
58 int cr = 0;
59 while ((cr = read(fd, us->buf + nr, MAXFLEN - nr)) > 0)
60 nr += cr;
61 us->len = nr;
62 us->cur = 0;
63 return us;
66 void ustr_free(struct ustr *us)
68 free(us);
71 int ustr_int(struct ustr *us, int *i)
73 int n = 0;
74 int base = 10;
75 int neg = 0;
76 char *s, *e = us->buf + us->len;
77 int len;
78 ustr_skipws(us);
79 s = us->buf + us->cur;
80 if (*s == '-')
81 neg = 1;
82 if (*s == '-' || *s == '+')
83 s++;
84 if (s[0] == '0') {
85 base = 8;
86 if (tolower(s[1]) == 'x')
87 base = 16;
88 s += base == 8 ? 1 : 2;
90 while (s < e) {
91 if (*s >= '0' && *s <= '9')
92 n = n * base + *s - '0';
93 else if (base == 16 && tolower(*s) >= 'a' && tolower(*s) <= 'f')
94 n = n * base + 10 + tolower(*s) - 'a';
95 else
96 break;
97 s++;
99 *i = neg ? -n : n;
100 len = s - (us->buf + us->cur);
101 us->cur += len;
102 return us->cur < us->len ? len : -1;
105 int ustr_str(struct ustr *us, char *s, int len)
107 int i = 0;
108 ustr_skipws(us);
109 while (i < len && us->cur < us->len && !isspace(us->buf[us->cur]))
110 s[i++] = us->buf[us->cur++];
111 s[i] = '\0';
112 return us->cur < us->len ? i : -1;
115 int ustr_uc_nospace(struct ustr *us, uc_t *t)
117 int len;
118 ustr_skipws(us);
119 if (us->cur >= us->len)
120 return -1;
121 len = uc_dec(t, us->buf + us->cur);
122 us->cur += len;
123 return len;
126 int ustr_uc(struct ustr *us, uc_t *t)
128 int len;
129 if (us->cur >= us->len)
130 return -1;
131 len = uc_dec(t, us->buf + us->cur);
132 us->cur += len;
133 return len;
136 int ustr_skipws(struct ustr *us)
138 int c = us->cur;
139 while (us->cur < us->len && isspace(us->buf[us->cur]))
140 us->cur++;
141 return us->cur - c;
144 int ustr_eol(struct ustr *us)
146 int c = us->cur;
147 while (us->cur < us->len && us->buf[us->cur] != '\n')
148 us->cur++;
149 if (us->cur < us->len)
150 us->cur++;
151 return us->cur - c;
154 int ustr_line(struct ustr *us, char *s, int len)
156 int i = 0;
157 while (i < len && us->cur < us->len && us->buf[us->cur] != '\n')
158 s[i++] = us->buf[us->cur++];
159 if (us->cur < us->len)
160 s[i++] = us->buf[us->cur++];
161 s[i] = '\0';
162 return i;
165 void ustr_seek(struct ustr *us, int pos)
167 us->cur = pos;
170 int ustr_pos(struct ustr *us)
172 return us->cur;
175 void ustr_back(struct ustr *us)
177 us->cur--;