1 /************************************************************************
2 * Collection of standard library substitute routines *
3 * *
4 * Copyright (c) 1990-2001, S.R. van den Berg, The Netherlands *
5 * Copyright (c) 1999-2001, Philip Guenther, The United States *
6 * of America *
7 * #include "../README" *
8 ************************************************************************/
9 #ifdef RCS
10 static /*const*/char rcsid[]=
11 "$Id: sublib.c,v 1.32 2001/08/31 04:54:15 guenther Exp $";
12 #endif
13 #include "includes.h"
14 #include "sublib.h"
15
16 #ifdef NOmemmove
smemmove(To,From,count)17 void*smemmove(To,From,count)void*To;const void*From;register size_t count;
18 #ifdef NObcopy /* silly compromise, throw */
19 { register char*to=To;register const char*from=From;/*void*old;*/
20 /*old=to;*/count++;to--;from--; /* away space to be syntactically correct */
21 if(to<=from)
22 { goto jiasc;
23 do
24 { *++to= *++from; /* copy from above */
25 jiasc:;
26 }
27 while(--count);
28 }
29 else
30 { to+=count;from+=count;
31 goto jidesc;
32 do
33 { *--to= *--from; /* copy from below */
34 jidesc:;
35 }
36 while(--count);
37 }
38 return To/*old*/;
39 #else
40 { bcopy(From,To,count);
41 return To;
42 #endif /* NObcopy */
43 }
44 #endif /* NOmemmove */
45
46 #include "shell.h"
47
48 #ifdef NOstrpbrk
sstrpbrk(st,del)49 char*sstrpbrk(st,del)const char*const st,*del;
50 { const char*f=0,*t;
51 for(f=0;*del;)
52 if((t=strchr(st,*del++))&&(!f||t<f))
53 f=t;
54 return (char*)f;
55 }
56 #endif
57
58 #ifdef BENCHSIZE /* for autoconf */
59 #ifndef SLOWstrstr
60 #define SLOWstrstr
61 #else
62 #undef BENCHSIZE
63 #endif
64 #endif
65 #ifdef SLOWstrstr
66 /*
67 * My personal strstr() implementation that beats most other algorithms.
68 * Until someone tells me otherwise, I assume that this is the
69 * fastest implementation of strstr() in C.
70 * I deliberately chose not to comment it. You should have at least
71 * as much fun trying to understand it, as I had to write it :-).
72 */
73 typedef unsigned chartype;
74
sstrstr(phaystack,pneedle)75 char*sstrstr(phaystack,pneedle)const char*const phaystack;
76 const char*const pneedle;
77 { register const uchar*haystack,*needle;register chartype b;
78 const uchar*rneedle;
79 haystack=(const uchar*)phaystack;
80 if(b= *(needle=(const uchar*)pneedle))
81 { register chartype c;
82 haystack--; /* possible ANSI violation */
83 ;{ register chartype a;
84 do
85 if(!(a= *++haystack))
86 goto ret0;
87 while(a!=b);
88 }
89 if(!(c= *++needle))
90 goto foundneedle;
91 ++needle;
92 goto jin;
93 for(;;)
94 { ;{ register chartype a;
95 if(0)
96 jin: { if((a= *++haystack)==c)
97 goto crest;
98 }
99 else
100 a= *++haystack;
101 do
102 { for(;a!=b;a= *++haystack)
103 { if(!a)
104 goto ret0;
105 if((a= *++haystack)==b)
106 break;
107 if(!a)
108 goto ret0;
109 }
110 }
111 while((a= *++haystack)!=c);
112 }
113 crest: ;{ register chartype a;
114 ;{ register const uchar*rhaystack;
115 if(*(rhaystack=haystack--+1)==(a= *(rneedle=needle)))
116 do
117 { if(!a)
118 goto foundneedle;
119 if(*++rhaystack!=(a= *++needle))
120 break;
121 if(!a)
122 goto foundneedle;
123 }
124 while(*++rhaystack==(a= *++needle));
125 needle=rneedle; /* took the register-poor aproach */
126 }
127 if(!a)
128 break;
129 }
130 }
131 }
132 foundneedle:
133 return (char*)haystack;
134 ret0:
135 return 0;
136 }
137 #endif
138
139 #ifdef NEEDbbzero /* NObzero && NOmemset */
bbzero(s,n)140 void bbzero(s,n)void *s;size_t n;
141 { register char*p=s;
142 while(n-->0)
143 *p++='\0';
144 }
145 #endif
146
147 #ifdef NOstrlcat
sstrlcat(dst,src,size)148 size_t sstrlcat(dst,src,size)char *dst;const char*src;size_t size;
149 { const char*start=dst;
150 if(size>0)
151 { size--; /* reserve space for the NUL */
152 while(size>0&&*dst) /* skip to the end */
153 size--,dst++;
154 while(size>0&&*src) /* copy over characters */
155 size--,*dst++= *src++;
156 *dst='\0'; /* hasta la vista, baby! */
157 }
158 return dst-start+strlen(src);
159 }
160
sstrlcpy(dst,src,size)161 size_t sstrlcpy(dst,src,size)char *dst;const char*src;size_t size;
162 { const char*start=dst;
163 if(size>0)
164 { size--; /* reserve space for the NUL */
165 while(size>0&&*src) /* copy over characters */
166 size--,*dst++= *src++;
167 *dst='\0'; /* hasta la vista, baby! */
168 }
169 return dst-start+strlen(src);
170 }
171 #endif
172
173 #ifdef NOstrerror
sstrerror(int err)174 char *sstrerror(int err)
175 {
176 #ifndef NOsys_errlist
177 extern int sys_nerr;extern char*sys_errlist[];
178 if(err>=0&&err<sys_nerr)
179 return sys_errlist[err];
180 #endif
181 return "Unknown error";
182 }
183 #endif
184 /* strtol replacement which lacks range checking */
185 #ifdef NOstrtol
sstrtol(start,ptr,base)186 long sstrtol(start,ptr,base)const char*start,**const ptr;int base;
187 { long result;const char*str=start;unsigned i;int sign,found;
188 if(base<(sign=found=result=0)||base>=36)
189 goto fault;
190 for(;;str++) /* skip leading whitespace */
191 { switch(*str)
192 { case '\t':case '\n':case '\v':case '\f':case '\r':case ' ':
193 continue;
194 }
195 break;
196 }
197 switch(*str) /* any signs? */
198 { case '-':sign=1;
199 case '+':str++;
200 }
201 if(*str=='0') /* leading zero(s)? */
202 { start++;
203 if((i= *++str)=='x'||i=='X') /* leading 0x or 0X? */
204 if(!base||base==16)
205 base=16,str++; /* hexadecimal all right */
206 else
207 goto fault;
208 else if(!base)
209 base=8; /* then it is octal */
210 }
211 else if(!base)
212 base=10; /* or else decimal */
213 goto jumpin;
214 do
215 { found=1;result=result*base+i;str++; /* start converting */
216 jumpin:
217 if((i=(unsigned)*str-'0')<10);
218 else if(i-'A'+'0'<='Z'-'A')
219 i-='A'-10-'0'; /* collating sequence dependency! */
220 else if(i-'a'+'0'<='z'-'a')
221 i-='a'-10-'0'; /* collating sequence dependency! */
222 else
223 break; /* not of this world */
224 }
225 while(i<base); /* still of this world */
226 fault:
227 if(ptr)
228 *ptr=found?str:start; /* how far did we get */
229 return sign?-result:result;
230 }
231 #else /* NOstrtol */
232 #ifndef NOstrerror
233 #ifndef NOstrlcat
234 #ifndef NEEDbbzero
235 #ifndef SLOWstrstr
236 #ifndef NOstrpbrk
237 #ifndef NOmemmove
238 int sublib_dummy_var; /* to prevent insanity in some linkers */
239 #endif
240 #endif
241 #endif
242 #endif
243 #endif
244 #endif
245 #endif /* NOstrtol */
246