/MirOS/dist/jupp/joe-3.1jupp30.tgz
[alioth/jupp.git] / utils.c
1 /* $MirOS: contrib/code/jupp/utils.c,v 1.4 2017/01/10 19:05:17 tg Exp $ */
2 /*
3  *      Various utilities
4  *      Copyright
5  *              (C) 1992 Joseph H. Allen
6  *              (C) 2001 Marek 'Marx' Grac
7  *
8  *      This file is part of JOE (Joe's Own Editor)
9  */
10 #include "config.h"
11
12 #include <errno.h>
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16 #ifdef HAVE_STDLIB_H
17 #include <stdlib.h>
18 #endif
19
20 #include "i18n.h"
21 #include "utf8.h"
22 #include "charmap.h"
23 #include "blocks.h"
24 #include "utils.h"
25
26 /*
27  * return minimum/maximum of two numbers
28  */
29 unsigned int uns_min(unsigned int a, unsigned int b)
30 {
31         return a < b ? a : b;
32 }
33
34 signed int int_min(signed int a, signed int b)
35 {
36         return a < b ? a : b;
37 }
38
39 signed long int long_max(signed long int a, signed long int b)
40 {
41         return a > b ? a : b;
42 }
43
44 signed long int long_min(signed long int a, signed long int b)
45 {
46         return a < b ? a : b;
47 }
48
49 /* Versions of 'read' and 'write' which automatically retry when interrupted */
50 ssize_t joe_read(int fd, void *buf, size_t size)
51 {
52         ssize_t rt;
53
54         do {
55                 rt = read(fd, buf, size);
56         } while (rt < 0 && errno == EINTR);
57         return rt;
58 }
59
60 ssize_t joe_write(int fd, void *buf, size_t size)
61 {
62         ssize_t rt;
63
64         do {
65                 rt = write(fd, buf, size);
66         } while (rt < 0 && errno == EINTR);
67         return rt;
68 }
69
70 #ifndef SIG_ERR
71 #define SIG_ERR ((sighandler_t) -1)
72 #endif
73
74 /* wrapper to hide signal interface differrencies */
75 int joe_set_signal(int signum, sighandler_t handler)
76 {
77         int retval;
78 #ifdef HAVE_SIGACTION
79         struct sigaction sact;
80
81         mset(&sact, 0, sizeof(sact));
82         sact.sa_handler = handler;
83 #ifdef SA_INTERRUPT
84         sact.sa_flags = SA_INTERRUPT;
85 #endif
86         retval = sigaction(signum, &sact, NULL);
87 #elif defined(HAVE_SIGVEC)
88         struct sigvec svec;
89
90         mset(&svec, 0, sizeof(svec));
91         svec.sv_handler = handler;
92 #ifdef HAVE_SV_INTERRUPT
93         svec.sv_flags = SV_INTERRUPT;
94 #endif
95         retval = sigvec(signum, &svec, NULL);
96 #else
97         retval = (signal(signum, handler) != SIG_ERR) ? 0 : -1;
98 #ifdef HAVE_SIGINTERRUPT
99         siginterrupt(signum, 1);
100 #endif
101 #endif
102         return(retval);
103 }
104
105 /* Helpful little parsing utilities */
106
107 /* Skip whitespace and return first non-whitespace character */
108
109 int parse_ws(unsigned char **pp,int cmt)
110 {
111         unsigned char *p = *pp;
112         while (*p==' ' || *p=='\t')
113                 ++p;
114         if (*p=='\r' || *p=='\n' || *p==cmt)
115                 *p = 0;
116         *pp = p;
117         return *p;
118 }
119
120 /* Parse an identifier into a buffer.  Identifier is truncated to a maximum of len chars. */
121
122 int parse_ident(unsigned char **pp, unsigned char *buf, int len)
123 {
124         unsigned char *p = *pp;
125         if (joe_isalpha_(locale_map,*p)) {
126                 while(len && joe_isalnum_(locale_map,*p))
127                         *buf++= *p++, --len;
128                 *buf=0;
129                 while(joe_isalnum_(locale_map,*p))
130                         ++p;
131                 *pp = p;
132                 return 0;
133         } else
134                 return -1;
135 }
136
137 /* Parse to next whitespace */
138
139 int parse_tows(unsigned char **pp, unsigned char *buf)
140 {
141         unsigned char *p = *pp;
142         while (*p && *p!=' ' && *p!='\t' && *p!='\n' && *p!='\r' && *p!='#')
143                 *buf++ = *p++;
144
145         *pp = p;
146         *buf = 0;
147         return 0;
148 }
149
150 /* Parse a keyword */
151
152 int parse_kw(unsigned char **pp, unsigned char *kw)
153 {
154         unsigned char *p = *pp;
155         while(*kw && *kw==*p)
156                 ++kw, ++p;
157         if(!*kw && !joe_isalnum_(locale_map,*p)) {
158                 *pp = p;
159                 return 0;
160         } else
161                 return -1;
162 }
163
164 /* Parse a field */
165
166 int parse_field(unsigned char **pp, unsigned char *kw)
167 {
168         unsigned char *p = *pp;
169         while(*kw && *kw==*p)
170                 ++kw, ++p;
171         if(!*kw && (!*p || *p==' ' || *p=='\t' || *p=='#' || *p=='\n' || *p=='\r')) {
172                 *pp = p;
173                 return 0;
174         } else
175                 return -1;
176 }
177
178 /* Parse a character */
179
180 int parse_char(unsigned char **pp, unsigned char c)
181 {
182         unsigned char *p = *pp;
183         if (*p == c) {
184                 *pp = p+1;
185                 return 0;
186         } else
187                 return -1;
188 }
189
190 /* Parse an integer.  Returns 0 for success. */
191
192 int parse_int(unsigned char **pp, int *buf)
193 {
194         unsigned char *p = *pp;
195         if ((*p>='0' && *p<='9') || *p=='-') {
196                 *buf = atoi((char *)p);
197                 if(*p=='-')
198                         ++p;
199                 while(*p>='0' && *p<='9')
200                         ++p;
201                 *pp = p;
202                 return 0;
203         } else
204                 return -1;
205 }
206
207 /* Parse a string into a buffer.  Returns 0 for success.
208    Leaves escape sequences in string. */
209
210 int parse_string(unsigned char **pp, unsigned char *buf, int len)
211 {
212         unsigned char *p= *pp;
213         if(*p=='\"') {
214                 ++p;
215                 while(len && *p && *p!='\"')
216                         if(*p=='\\' && p[1] && len>2) {
217                                 *buf++ = *p++;
218                                 *buf++ = *p++;
219                                 len-=2;
220                         } else {
221                                 *buf++ = *p++;
222                                 --len;
223                         }
224                 *buf = 0;
225                 while(*p && *p!='\"')
226                         if(*p=='\\' && p[1])
227                                 p+=2;
228                         else
229                                 p++;
230                 if(*p=='\"') {
231                         *pp= p+1;
232                         return 0;
233                 }
234         }
235         return -1;
236 }
237
238 /* Parse a character range: a-z */
239
240 int parse_range(unsigned char **pp, int *first, int *second)
241 {
242         unsigned char *p= *pp;
243         int a, b;
244         if(!*p)
245                 return -1;
246         if(*p=='\\' && p[1]) {
247                 ++p;
248                 if(*p=='n')
249                         a = '\n';
250                 else if(*p=='t')
251                         a = '\t';
252                 else
253                         a = *p;
254                 ++p;
255         } else
256                 a = *p++;
257         if(*p=='-' && p[1]) {
258                 ++p;
259                 if(*p=='\\' && p[1]) {
260                         ++p;
261                         if(*p=='n')
262                                 b = '\n';
263                         else if(*p=='t')
264                                 b = '\t';
265                         else
266                                 b = *p;
267                         ++p;
268                 } else
269                         b = *p++;
270         } else
271                 b = a;
272         *first = a;
273         *second = b;
274         *pp = p;
275         return 0;
276 }