build: Use arch-dir.
[mes.git] / lib / libmes.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
4  *
5  * This file is part of Mes.
6  *
7  * Mes is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or (at
10  * your option) any later version.
11  *
12  * Mes is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <libmes.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 int
26 isdigit (int c)
27 {
28   return c >= '0' && c <= '9';
29 }
30
31 int
32 isxdigit (int c)
33 {
34   return isdigit (c) || c >= 'a' && c <= 'f';
35 }
36
37 int
38 isspace (int c)
39 {
40   return (c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || c == ' ');
41 }
42
43 int
44 isnumber (int c, int base)
45 {
46   if (base == 2)
47     return (c >= '0') && (c <= '1');
48   if (base == 8)
49     return (c >= '0') && (c <= '7');
50   if (base == 10)
51     return isdigit (c);
52   if (base == 16)
53     return isxdigit (c);
54 }
55
56 int
57 abtoi (char const **p, int base)
58 {
59   char const *s = *p;
60   int i = 0;
61   int sign = 1;
62   if (!base) base = 10;
63   if (*s && *s == '-')
64     {
65       sign = -1;
66       s++;
67     }
68   while (isnumber (*s, base))
69     {
70       i *= base;
71       int m = *s > '9' ? 'a' - 10 : '0';
72       i += *s - m;
73       s++;
74     }
75   *p = s;
76   return i * sign;
77 }
78
79 int
80 atoi (char const *s)
81 {
82   char const *p = s;
83   return abtoi (&p, 0);
84 }
85
86 char const*
87 itoa (int x)
88 {
89   static char itoa_buf[12];
90   char *p = itoa_buf + 11;
91   *p-- = 0;
92
93   int sign = 0;
94   unsigned u = x;
95   if (x < 0)
96     {
97       sign = 1;
98       u = -x;
99     }
100
101   do
102      {
103        *p-- = '0' + (u % 10);
104        u = u / 10;
105      } while (u);
106
107   if (sign && *(p + 1) != '0')
108     *p-- = '-';
109
110   return p+1;
111 }
112
113 char const*
114 itoab (int x, int base)
115 {
116   static char itoa_buf[12];
117   char *p = itoa_buf + 11;
118   *p-- = 0;
119
120   int sign = 0;
121   unsigned u = x;
122   if (x < 0)
123     {
124       sign = 1;
125       u = -x;
126     }
127
128   do
129      {
130        int i = u % base;
131        *p-- = i > 9 ? 'a' + i - 10 : '0' + i;
132        x = u / base;
133      } while (u);
134
135   if (sign && *(p + 1) != '0')
136     *p-- = '-';
137
138   return p+1;
139 }
140
141 int _ungetc_pos = -1;
142 char _ungetc_buf[10];
143
144 int
145 fdgetc (int fd)
146 {
147   char c;
148   int i;
149   if (_ungetc_pos == -1)
150     {
151       int r = read (fd, &c, 1);
152       if (r < 1)
153         return -1;
154       i = c;
155    }
156   else
157     {
158       i = _ungetc_buf[_ungetc_pos];
159       _ungetc_pos -= 1;
160      }
161   if (i < 0)
162     i += 256;
163
164   return i;
165 }
166
167 int
168 fdputc (int c, int fd)
169 {
170   write (fd, (char*)&c, 1);
171   return 0;
172 }
173
174 int
175 fdputs (char const* s, int fd)
176 {
177   int i = strlen (s);
178   write (fd, s, i);
179   return 0;
180 }
181
182 int
183 fdungetc (int c, int fd)
184 {
185   _ungetc_pos++;
186   _ungetc_buf[_ungetc_pos] = c;
187   return c;
188 }
189
190 #if POSIX
191 #define STDERR 2
192 int
193 eputs (char const* s)
194 {
195   int i = strlen (s);
196   write (STDERR, s, i);
197   return 0;
198 }
199 #endif
200
201 int
202 eputc (int c)
203 {
204   return fdputc (c, STDERR);
205 }