1 /* #includes */ /*{{{C}}}*//*{{{*/
2 #ifndef NO_POSIX_SOURCE
3 #undef _POSIX_SOURCE
4 #define _POSIX_SOURCE   1
5 #undef _POSIX_C_SOURCE
6 #define _POSIX_C_SOURCE 2
7 #endif
8 
9 #ifdef DMALLOC
10 #include "dmalloc.h"
11 #endif
12 
13 #include <assert.h>
14 #include <ctype.h>
15 #include <errno.h>
16 #include <float.h>
17 #include <math.h>
18 #include <stdlib.h>
19 #include <signal.h>
20 #include <stdio.h>
21 #include <string.h>
22 #ifdef NEED_BCOPY
23 #define memmove(dst,src,len) bcopy(src,dst,len)
24 #endif
25 
26 
27 #include "default.h"
28 #include "main.h"
29 #include "misc.h"
30 #include "utf8.h"
31 /*}}}*/
32 
33 /* posnumber   -- match positive integer */ /*{{{*/
posnumber(const char * s,const char ** endptr)34 long int posnumber(const char *s, const char **endptr)
35 {
36   unsigned int base=10;
37   unsigned char c;
38   register const char *nptr = s;
39   long int result = 0L;
40   int saw_a_digit = 0;
41 
42   if (*nptr == '0')
43   {
44     if ((c = *++nptr) == 'x' || c == 'X')
45     {
46       ++nptr;
47       base = 16;
48     }
49     else
50     {
51       saw_a_digit = 1;
52       base = 8;
53     }
54   }
55 
56   --nptr;
57   while ((c=*++nptr)!='\0')
58   {
59     if (isdigit(c)) c -= '0';
60     else if (isupper(c)) c -= ('A'-10);
61     else if (islower(c)) c -= ('a'-10);
62     else break;
63     if (c>=base) break;
64     saw_a_digit = 1;
65     result = result*base+c;
66   }
67 
68   *endptr=(saw_a_digit ? nptr : s);
69   return result;
70 }
71 /*}}}*/
72 /* posorder    -- sort two integers */ /*{{{*/
posorder(int * x,int * y)73 void posorder(int *x, int *y)
74 {
75   /* variables */ /*{{{*/
76   int t;
77   /*}}}*/
78 
79   assert(x!=(int*)0);
80   assert(*x>=0);
81   assert(y!=(int*)0);
82   assert(*y>=0);
83   if (*x>*y)
84   {
85     t=*x;
86     *x=*y;
87     *y=t;
88   }
89 }
90 /*}}}*/
91 /* mystrmalloc -- return malloced copy of string */ /*{{{*/
mystrmalloc(const char * str)92 char *mystrmalloc(const char *str)
93 {
94   return (strcpy(malloc(strlen(str)+1),str));
95 }
96 /*}}}*/
97 /* finite      -- return error message about number or null */ /*{{{*/
98 static volatile int caughtfpe;
99 
catchfpe(int n)100 static void catchfpe(int n)
101 {
102   caughtfpe=1;
103 }
104 
dblfinite(double x)105 const char *dblfinite(double x)
106 {
107   /*struct sigaction act;
108 
109   caughtfpe=0;
110   act.sa_handler=catchfpe;
111   act.sa_flags=0;
112   (void)sigemptyset(&act.sa_mask);
113   (void)sigaction(SIGFPE,&act,(struct sigaction*)0);*/
114   signal(SIGFPE, catchfpe);
115   if (x==0.0)
116   {
117     if (caughtfpe) return _("Not a (finite) floating point number"); /* who knows */
118     else return (const char*)0;
119   }
120   else
121   {
122     if (caughtfpe) return _("Not a (finite) floating point number");
123     /* If one comparison was allowed, more won't hurt either. */
124     if (x<0.0)
125     {
126       if (x<-DBL_MAX) return _("Not a (finite) floating point number"); /* -infinite */
127       else return (const char*)0;
128     }
129     else if (x>0.0)
130     {
131       if (x>DBL_MAX) return _("Not a (finite) floating point number"); /* +infinite */
132       else return (const char*)0;
133     }
134     else return _("Not a (finite) floating point number"); /* NaN */
135   }
136 }
137 /*}}}*/
138 /* fputc_close -- error checking fputc which closes stream on error */ /*{{{*/
fputc_close(char c,FILE * fp)139 int fputc_close(char c, FILE *fp)
140 {
141   int e;
142 
143   if ((e=fputc(c,fp))==EOF)
144   {
145     int oerrno;
146 
147     oerrno=errno;
148     (void)fclose(fp);
149     errno=oerrno;
150   }
151   return e;
152 }
153 
154 /* fputs_close -- error checking fputs which closes stream on error */ /*{{{*/
fputs_close(const char * s,FILE * fp)155 int fputs_close(const char *s, FILE *fp)
156 {
157   int e;
158 
159   if ((e=fputs(s,fp))==EOF)
160   {
161     int oerrno;
162 
163     oerrno=errno;
164     (void)fclose(fp);
165     errno=oerrno;
166   }
167   return e;
168 }
169 
170 /* adjust      -- readjust a left adjusted string in a buffer */ /*{{{*/
adjust(Adjust a,char * s,size_t n)171 void adjust(Adjust a, char *s, size_t n)
172 {
173   assert(s!=(char*)0);
174   assert(mbslen(s)<=n);
175   switch (a)
176   {
177     /* LEFT */ /*{{{*/
178     case LEFT: break;
179     /*}}}*/
180     /* RIGHT */ /*{{{*/
181     case RIGHT:
182     {
183       size_t len;
184 
185       len=mbslen(s);
186       if (len < n)
187       {
188         memmove(s+n-len, s, strlen(s)+1);
189         memset(s, ' ', n-len);
190       }
191       break;
192     }
193     /*}}}*/
194     /* CENTER */ /*{{{*/
195     case CENTER:
196     {
197       size_t len,pad;
198 
199       len=mbslen(s);
200       pad=(n-len)/2;
201       assert((pad+len)<=n);
202       memmove(s+pad, s, strlen(s)+1);
203       memset(s, ' ', pad);
204       //*(s+strlen(s)+n-pad-len)='\0';
205       //(void)memset(s+strlen(s),' ',n-pad-len-1);
206       break;
207     }
208     /*}}}*/
209     /* default */ /*{{{*/
210     default: assert(0);
211     /*}}}*/
212   }
213 }
214 /*}}}*/
215 /* strerror    -- strerror(3) */ /*{{{*/
216 #ifdef NEED_STRERROR
217 extern int sys_nerr;
218 extern const char *sys_errlist[];
219 
strerror(int errno)220 const char *strerror(int errno)
221 {
222   return (errno>=0 && errno<sys_nerr ? sys_errlist[errno] : "unknown error");
223 }
224 #endif
225 /*}}}*/
226 /* myrealloc   -- ANSI conforming realloc() */ /*{{{*/
227 #ifdef OLD_REALLOC
228 #undef realloc
myrealloc(void * p,size_t n)229 void *myrealloc(void *p, size_t n)
230 {
231   return (p==(void*)0 ? malloc(n) : realloc(p,n));
232 }
233 #endif
234 /*}}}*/
235 
striphtml(const char * in)236 char *striphtml(const char *in)
237 {
238     char *end, *stripped = malloc(strlen(in)), *out = stripped;
239     in--;
240 
241     while (in && (end = strchr(++in, '<'))) {
242         memcpy(out, in, end-in);
243         out += end-in;
244         in = strchr(end+1, '>');
245     }
246     if (in) strcpy(out, in);
247     else *out = 0;
248     return stripped;
249 }
250