Annotation of OpenXM_contrib/gnuplot/stdfn.c, Revision 1.1.1.3
1.1 maekawa 1: #ifndef lint
1.1.1.3 ! ohara 2: static char *RCSid = "$Id: stdfn.c,v 1.7.2.1 2002/03/11 16:05:25 lhecking Exp $";
1.1 maekawa 3: #endif
4:
5:
6: /* GNUPLOT - stdfn.c */
7:
8: /*[
9: * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
10: *
11: * Permission to use, copy, and distribute this software and its
12: * documentation for any purpose with or without fee is hereby granted,
13: * provided that the above copyright notice appear in all copies and
14: * that both that copyright notice and this permission notice appear
15: * in supporting documentation.
16: *
17: * Permission to modify the software is granted, but not the right to
18: * distribute the complete modified source code. Modifications are to
19: * be distributed as patches to the released version. Permission to
20: * distribute binaries produced by compiling modified sources is granted,
21: * provided you
22: * 1. distribute the corresponding source modifications from the
23: * released version in the form of a patch file along with the binaries,
24: * 2. add special version identification to distinguish your version
25: * in addition to the base release version number,
26: * 3. provide your name and address as the primary contact for the
27: * support of your modified version, and
28: * 4. retain our contact information in regard to use of the base
29: * software.
30: * Permission to distribute the released version of the source code along
31: * with corresponding source modifications in the form of a patch file is
32: * granted with same provisions 2 through 4 for binary distributions.
33: *
34: * This software is provided "as is" without express or implied warranty
35: * to the extent permitted by applicable law.
36: ]*/
37:
38:
39: /* This module collects various functions, which were previously scattered
40: * all over the place. In a future implementation of gnuplot, each of
41: * these functions will probably reside in their own file in a subdirectory.
42: * - Lars Hecking
43: */
44:
45: #include "plot.h"
46:
47: /*
48: * ANSI C functions
49: */
50:
51: /* memcpy() */
52:
53: #ifdef NO_MEMCPY
54: # ifndef HAVE_BCOPY
55: /*
56: * cheap and slow version of memcpy() in case you don't have one
57: */
58: int memcpy __PROTO((char *, char *, size_t));
59:
60: int
61: memcpy (dest, src, len)
62: char *dest, *src;
63: size_t len;
64: {
65: while (len--)
66: *dest++ = *src++;
67: }
68: # endif /* !HAVE_BCOPY */
69: #endif /* NO_MEMCPY */
70:
71: /* strchr()
72: * Simple and portable version, conforming to Plauger.
73: * Would this be more efficient as a macro?
74: */
75: #ifdef NO_STRCHR
76: # ifndef HAVE_INDEX
77: char *strchr __PROTO((const char *, int));
78:
79: char *
80: strchr (s, c)
81: const char *s;
82: int c;
83: {
84: do {
85: if (*s == (char)c)
86: return s;
87: } while (*s++ != (char)0);
88:
89: return NULL;
90: }
91: # endif /* !HAVE_INDEX */
92: #endif /* NO_STRCHR */
93:
94:
95: /* memset ()
96: *
97: * Since we want to use memset, we have to map a possibly nonzero fill byte
98: * to the bzero function. The following defined might seem a bit odd, but I
99: * think this is the only possible way.
100: */
101:
102: #ifdef NO_MEMSET
103: # ifdef HAVE_BZERO
104: # define memset(s, b, l) \
105: do { \
106: assert((b)==0); \
107: bzero((s), (l)); \
108: } while(0)
109: # else
110: # error You must have either memset or bzero
111: # endif /* HAVE_BZERO */
112: #endif /* NO_MEMSET */
113:
114:
115: /* strerror() */
116: #ifdef NO_STRERROR
117:
118: extern int sys_nerr;
119: extern char *sys_errlist[];
120:
121: char *strerror __PROTO((int));
122:
123: char *strerror(no)
124: int no;
125: {
126: static char res_str[30];
127:
128: if(no>sys_nerr) {
129: sprintf(res_str, "unknown errno %d", no);
130: return res_str;
131: } else {
132: return sys_errlist[no];
133: }
134: }
135: #endif /* NO_STRERROR */
136:
137:
138: /* strstr() */
139: #ifdef NO_STRSTR
140: char *strstr __PROTO((const char *, const char *));
141:
142: char *strstr (cs, ct)
143: const char *cs, *ct;
144: {
145: size_t len;
146:
147: if (!cs || !ct)
148: return NULL;
149:
150: if (!*ct)
151: return (char *)cs;
152:
153: len = strlen(ct);
154: while (*cs)
155: {
156: if (strncmp(cs, ct, len)==0)
157: return (char *)cs;
158: cs++;
159: }
160:
161: return NULL;
162: }
163: #endif /* NO_STRSTR */
164:
165:
166: #ifdef __PUREC__
167: /*
168: * a substitute for PureC's buggy sscanf.
169: * this uses the normal sscanf and fixes the following bugs:
170: * - whitespace in format matches whitespace in string, but doesn't
171: * require any. ( "%f , %f" scans "1,2" correctly )
172: * - the ignore value feature works (*). this created an address error
173: * in PureC.
174: */
175:
176: #include <stdarg.h>
177:
178: int purec_sscanf( const char *string, const char *format, ... )
179: {
180: va_list args;
181: int cnt=0;
182: char onefmt[256];
183: char buffer[256];
184: const char *f=format;
185: const char *s=string;
186: char *f2;
187: char ch;
188: int ignore;
189: void *p;
190: int *ip;
191: int pos;
192:
193: va_start(args,format);
194: while( *f && *s ) {
195: ch=*f++;
196: if( ch!='%' ) {
197: if(isspace(ch)) {
198: /* match any number of whitespace */
199: while(isspace(*s)) s++;
200: } else {
201: /* match exactly the character ch */
202: if( *s!=ch ) goto finish;
203: s++;
204: }
205: } else {
206: /* we have got a '%' */
207: ch=*f++;
208: if( ch=='%' ) {
209: /* match exactly % */
210: if( *s!=ch ) goto finish;
211: s++;
212: } else {
213: f2=onefmt;
214: *f2++='%';
215: *f2++=ch;
216: ignore=0;
217: if( ch=='*' ) {
218: ignore=1;
219: ch=f2[-1]=*f++;
220: }
221: while( isdigit(ch) ) {
222: ch=*f2++=*f++;
223: }
224: if( ch=='l' || ch=='L' || ch=='h' ) {
225: ch=*f2++=*f++;
226: }
227: switch(ch) {
228: case '[':
229: while( ch && ch!=']' ) {
230: ch=*f2++=*f++;
231: }
232: if( !ch ) goto error;
233: break;
234: case 'e':
235: case 'f':
236: case 'g':
237: case 'd':
238: case 'o':
239: case 'i':
240: case 'u':
241: case 'x':
242: case 'c':
243: case 's':
244: case 'p':
245: case 'n': /* special case handled below */
246: break;
247: default:
248: goto error;
249: }
250: if( ch!='n' ) {
251: strcpy(f2,"%n");
252: if( ignore ) {
253: p=buffer;
254: } else {
255: p=va_arg(args,void *);
256: }
257: switch( sscanf( s, onefmt, p, &pos ) ) {
258: case EOF: goto error;
259: case 0 : goto finish;
260: }
261: if( !ignore ) cnt++;
262: s+=pos;
263: } else {
264: if( !ignore ) {
265: ip=va_arg(args,int *);
266: *ip=(int)(s-string);
267: }
268: }
269: }
270: }
271: }
272:
273: if( !*f ) goto finish;
274:
275: error:
276: cnt=EOF;
277: finish:
278: va_end(args);
279: return cnt;
280: }
281:
282: /* use the substitute now. I know this is dirty trick, but it works. */
283: #define sscanf purec_sscanf
284:
285: #endif /* __PUREC__ */
286:
287:
288: /*
289: * POSIX functions
290: */
291:
292: #ifndef HAVE_SLEEP
293: /* The implementation below does not even come close
294: to what is required by POSIX.1, but I suppose
295: it doesn't really matter on these systems. lh
296: */
297:
298: unsigned int sleep __PROTO((unsigned int));
299:
300: #ifdef AMIGA_SC_6_1
301: #include <proto/dos.h>
302: #endif
303:
304: #ifdef WIN32
305: /* the WIN32 API has a Sleep function that does not consume CPU cycles */
306: #include <windows.h>
307: #endif
308:
309: unsigned int
310: sleep(delay)
311: unsigned int delay;
312: {
313: #if defined(MSDOS) || defined(_Windows) || defined(DOS386) || defined(AMIGA_AC_5)
314: #if !(defined(__TURBOC__) || defined(__EMX__) || defined(DJGPP)) || defined(_Windows) /* Turbo C already has sleep() */
315: /* kludge to provide sleep() for msc 5.1 */
316: unsigned long time_is_up;
317:
318: time_is_up = time(NULL) + (unsigned long) delay;
319: while (time(NULL) < time_is_up)
320: /* wait */ ;
321: #endif /* !__TURBOC__ ... */
322: #endif /* MSDOS ... */
323:
324: #ifdef AMIGA_SC_6_1
325: Delay(50 * delay);
326: #endif
327:
328: #ifdef WIN32
329: Sleep( (DWORD) delay*1000 );
330: #endif
331:
332: return (unsigned int)0;
333: }
334: #endif /* HAVE_SLEEP */
335:
336:
337: /*
338: * Other common functions
339: */
340:
341: /*****************************************************************
342: portable implementation of strnicmp (hopefully)
343: *****************************************************************/
1.1.1.3 ! ohara 344:
! 345: #ifndef HAVE_STRCASECMP
! 346: # ifndef HAVE_STRICMP
! 347:
! 348: /* return (see MSVC documentation and strcasecmp()):
! 349: * -1 if str1 < str2
! 350: * 0 if str1 == str2
! 351: * 1 if str1 > str2
! 352: */
! 353: int
! 354: gp_stricmp(s1, s2)
! 355: const char *s1;
! 356: const char *s2;
! 357: {
! 358: unsigned char c1, c2;
! 359:
! 360: do {
! 361: c1 = *s1++;
! 362: if (islower(c1))
! 363: c1 = toupper(c1);
! 364: c2 = *s2++;
! 365: if (islower(c2))
! 366: c2 = toupper(c2);
! 367: } while (c1 == c2 && c1 && c2);
! 368:
! 369: if (c1 == c2)
! 370: return 0;
! 371: if (c1 == '\0' || c1 > c2)
! 372: return 1;
! 373: return -1;
! 374: }
! 375: # endif /* !HAVE_STRICMP */
! 376: #endif /* !HAVE_STRCASECMP */
1.1 maekawa 377:
378: #ifndef HAVE_STRNICMP
379: # ifndef HAVE_STRNCASECMP
380: int strnicmp __PROTO((char *, char *, int));
381:
382: int strnicmp (s1, s2, n)
383: char *s1;
384: char *s2;
385: int n;
386: {
387: char c1,c2;
388:
389: if(n==0) return 0;
390:
391: do {
392: c1 = *s1++; if(islower(c1)) c1=toupper(c1);
393: c2 = *s2++; if(islower(c2)) c2=toupper(c2);
394: } while(c1==c2 && c1 && c2 && --n>0);
395:
396: if(n==0 || c1==c2) return 0;
397: if(c1=='\0' || c1<c2) return 1;
398: return -1;
399: }
400: # endif /* !HAVE_STRNCASECMP */
401: #endif /* !HAVE_STRNICMP */
402:
403:
404: /* Safe, '\0'-terminated version of strncpy()
405: * safe_strncpy(dest, src, n), where n = sizeof(dest)
406: * This is basically the old fit.c(copy_max) function
407: */
408:
409: char *safe_strncpy(d, s, n)
410: char *d, *s;
411: size_t n;
412: {
413: char *ret;
414:
415: ret = strncpy(d, s, n);
416: if (strlen(s) >= n)
417: d[ n > 0 ? n-1 : 0] = NUL;
418:
419: return ret;
420: }
421:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>