core: Fix compile warnings.
[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 <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 int
27 isdigit (int c)
28 {
29   return c >= '0' && c <= '9';
30 }
31
32 int
33 isxdigit (int c)
34 {
35   return isdigit (c) || c >= 'a' && c <= 'f';
36 }
37
38 int
39 isspace (int c)
40 {
41   return (c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || c == ' ');
42 }
43
44 int
45 isnumber (int c, int base)
46 {
47   if (base == 2)
48     return (c >= '0') && (c <= '1');
49   if (base == 8)
50     return (c >= '0') && (c <= '7');
51   if (base == 10)
52     return isdigit (c);
53   if (base == 16)
54     return isxdigit (c);
55 }
56
57 int
58 abtoi (char const **p, int base)
59 {
60   char const *s = *p;
61   int i = 0;
62   int sign = 1;
63   if (!base) base = 10;
64   if (*s && *s == '-')
65     {
66       sign = -1;
67       s++;
68     }
69   while (isnumber (*s, base))
70     {
71       i *= base;
72       int m = *s > '9' ? 'a' - 10 : '0';
73       i += *s - m;
74       s++;
75     }
76   *p = s;
77   return i * sign;
78 }
79
80 int
81 atoi (char const *s)
82 {
83   char const *p = s;
84   return abtoi (&p, 0);
85 }
86
87 char const*
88 number_to_ascii (int x, int base, int signed_p)
89 {
90   static char itoa_buf[12];
91   char *p = itoa_buf + 11;
92   *p-- = 0;
93
94   int sign = 0;
95   unsigned u = x;
96   if (signed_p && x < 0)
97     {
98       sign = 1;
99       u = -x;
100     }
101
102   do
103      {
104        int i = u % base;
105        *p-- = i > 9 ? 'a' + i - 10 : '0' + i;
106        u = u / base;
107      } while (u);
108
109   if (sign && *(p + 1) != '0')
110     *p-- = '-';
111
112   return p+1;
113 }
114
115 char const*
116 itoab (int x, int base)
117 {
118   return number_to_ascii (x, base, 1);
119 }
120
121 char const*
122 itoa (int x)
123 {
124   return number_to_ascii (x, 10, 1);
125 }
126
127 char const*
128 utoa (unsigned x)
129 {
130   return number_to_ascii (x, 10, 0);
131 }
132
133 int _ungetc_pos = -1;
134 int _ungetc_fd = -1;
135 char _ungetc_buf[10];
136
137 int
138 fdgetc (int fd)
139 {
140   char c;
141   int i;
142   if (_ungetc_pos == -1)
143     {
144       int r = read (fd, &c, 1);
145       if (r < 1)
146         return -1;
147       i = c;
148    }
149   else
150     {
151       if (_ungetc_fd != fd)
152         {
153           eputs (" ***MES LIB C*** fdgetc ungetc conflict unget-fd=");
154           eputs (itoa (_ungetc_fd));
155           eputs (", fdgetc-fd=");
156           eputs (itoa (fd));
157           eputs ("\n");
158           exit (1);
159         }
160       i = _ungetc_buf[_ungetc_pos];
161       _ungetc_pos -= 1;
162       if (_ungetc_pos == -1)
163         _ungetc_fd = -1;
164      }
165   if (i < 0)
166     i += 256;
167
168   return i;
169 }
170
171 int
172 fdputc (int c, int fd)
173 {
174   write (fd, (char*)&c, 1);
175   return 0;
176 }
177
178 int
179 fdputs (char const* s, int fd)
180 {
181   int i = strlen (s);
182   write (fd, s, i);
183   return 0;
184 }
185
186 int
187 fdungetc (int c, int fd)
188 {
189   if (_ungetc_pos == -1)
190     _ungetc_fd = fd;
191   else if (_ungetc_fd != fd)
192     {
193       eputs (" ***MES LIB C*** fdungetc ungetc conflict unget-fd=");
194       eputs (itoa (_ungetc_fd));
195       eputs (", fdungetc-fd=");
196       eputs (itoa (fd));
197       eputs ("\n");
198       exit (1);
199     }
200   _ungetc_pos++;
201   _ungetc_buf[_ungetc_pos] = c;
202   return c;
203 }
204
205 int
206 _fdungetc_p (int fd)
207 {
208   return _ungetc_pos > -1;
209 }
210
211 #if POSIX || __x86_64__
212 #define STDERR 2
213 int
214 eputs (char const* s)
215 {
216   int i = strlen (s);
217   write (STDERR, s, i);
218   return 0;
219 }
220 #endif
221
222 int
223 eputc (int c)
224 {
225   return fdputc (c, STDERR);
226 }