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