2 static char *RCSid() { return RCSid("$Id: stdfn.c,v 1.17 2005/07/26 04:24:16 sfeam Exp $"); }
5 /* GNUPLOT - stdfn.c */
8 * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
10 * Permission to use, copy, and distribute this software and its
11 * documentation for any purpose with or without fee is hereby granted,
12 * provided that the above copyright notice appear in all copies and
13 * that both that copyright notice and this permission notice appear
14 * in supporting documentation.
16 * Permission to modify the software is granted, but not the right to
17 * distribute the complete modified source code. Modifications are to
18 * be distributed as patches to the released version. Permission to
19 * distribute binaries produced by compiling modified sources is granted,
21 * 1. distribute the corresponding source modifications from the
22 * released version in the form of a patch file along with the binaries,
23 * 2. add special version identification to distinguish your version
24 * in addition to the base release version number,
25 * 3. provide your name and address as the primary contact for the
26 * support of your modified version, and
27 * 4. retain our contact information in regard to use of the base
29 * Permission to distribute the released version of the source code along
30 * with corresponding source modifications in the form of a patch file is
31 * granted with same provisions 2 through 4 for binary distributions.
33 * This software is provided "as is" without express or implied warranty
34 * to the extent permitted by applicable law.
38 /* This module collects various functions, which were previously scattered
39 * all over the place. In a future implementation of gnuplot, each of
40 * these functions will probably reside in their own file in a subdirectory.
47 /* the WIN32 API has a Sleep function that does not consume CPU cycles */
61 * cheap and slow version of memcpy() in case you don't have one
65 memcpy(char *dest, char *src, size_t len)
72 # endif /* !HAVE_BCOPY */
73 #endif /* HAVE_MEMCPY */
76 * Simple and portable version, conforming to Plauger.
77 * Would this be more efficient as a macro?
83 strchr(const char *s, int c)
88 } while (*s++ != (char) 0);
92 # endif /* !HAVE_INDEX */
93 #endif /* HAVE_STRCHR */
98 * Since we want to use memset, we have to map a possibly nonzero fill byte
99 * to the bzero function. The following defined might seem a bit odd, but I
100 * think this is the only possible way.
105 # define memset(s, b, l) \
111 # define memset NO_MEMSET_OR_BZERO
112 # endif /* HAVE_BZERO */
113 #endif /* HAVE_MEMSET */
117 #ifndef HAVE_STRERROR
122 static char res_str[30];
125 sprintf(res_str, "unknown errno %d", no);
128 return sys_errlist[no];
131 #endif /* HAVE_STRERROR */
138 strstr(const char *cs, const char *ct)
150 if (strncmp(cs, ct, len) == 0)
157 #endif /* HAVE_STRSTR */
162 * a substitute for PureC's buggy sscanf.
163 * this uses the normal sscanf and fixes the following bugs:
164 * - whitespace in format matches whitespace in string, but doesn't
165 * require any. ( "%f , %f" scans "1,2" correctly )
166 * - the ignore value feature works (*). this created an address error
173 purec_sscanf(const char *string, const char *format,...)
179 const char *f = format;
180 const char *s = string;
188 va_start(args, format);
192 if (isspace((unsigned char) ch)) {
193 /* match any number of whitespace */
194 while (isspace((unsigned char) *s))
197 /* match exactly the character ch */
203 /* we have got a '%' */
206 /* match exactly % */
219 while (isdigit((unsigned char) ch)) {
222 if (ch == 'l' || ch == 'L' || ch == 'h') {
227 while (ch && ch != ']') {
244 case 'n': /* special case handled below */
254 p = va_arg(args, void *);
256 switch (sscanf(s, onefmt, p, &pos)) {
267 ip = va_arg(args, int *);
268 *ip = (int) (s - string);
285 /* use the substitute now. I know this is dirty trick, but it works. */
286 #define sscanf purec_sscanf
288 #endif /* __PUREC__ */
296 /* The implementation below does not even come close
297 * to what is required by POSIX.1, but I suppose
298 * it doesn't really matter on these systems. lh
303 #include <proto/dos.h>
307 sleep(unsigned int delay)
309 #if defined(MSDOS) || defined(_Windows) || defined(DOS386) || defined(AMIGA_AC_5)
310 # if !(defined(__TURBOC__) || defined(__EMX__) || defined(DJGPP)) || defined(_Windows) /* Turbo C already has sleep() */
311 /* kludge to provide sleep() for msc 5.1 */
312 unsigned long time_is_up;
314 time_is_up = time(NULL) + (unsigned long) delay;
315 while (time(NULL) < time_is_up)
317 # endif /* !__TURBOC__ ... */
318 #endif /* MSDOS ... */
325 Sleep((DWORD) delay * 1000);
331 #endif /* HAVE_SLEEP */
335 * Other common functions
338 /*****************************************************************
339 portable implementation of strnicmp (hopefully)
340 *****************************************************************/
341 #ifndef HAVE_STRCASECMP
342 # ifndef HAVE_STRICMP
344 /* return (see MSVC documentation and strcasecmp()):
350 gp_stricmp(const char *s1, const char *s2)
352 unsigned char c1, c2;
361 } while (c1 == c2 && c1 && c2);
365 if (c1 == '\0' || c1 > c2)
369 # endif /* !HAVE_STRCASECMP */
370 #endif /* !HAVE_STRNICMP */
372 /*****************************************************************
373 portable implementation of strnicmp (hopefully)
374 *****************************************************************/
376 #ifndef HAVE_STRNCASECMP
377 # ifndef HAVE_STRNICMP
380 gp_strnicmp(const char *s1, const char *s2, size_t n)
382 unsigned char c1, c2;
394 } while (c1 == c2 && c1 && c2 && --n > 0);
396 if (n == 0 || c1 == c2)
398 if (c1 == '\0' || c1 > c2)
402 # endif /* !HAVE_STRNCASECMP */
403 #endif /* !HAVE_STRNICMP */
406 /* Safe, '\0'-terminated version of strncpy()
407 * safe_strncpy(dest, src, n), where n = sizeof(dest)
408 * This is basically the old fit.c(copy_max) function
411 safe_strncpy(char *d, const char *s, size_t n)
415 ret = strncpy(d, s, n);
417 d[n > 0 ? n - 1 : 0] = NUL;
424 * our own substitute for strcspn()
425 * return the length of the inital segment of str1
426 * consisting of characters not in str2
427 * returns strlen(str1) if none of the characters
428 * from str2 are in str1
429 * based in misc.c(instring) */
431 gp_strcspn(const char *str1, const char *str2)
440 if (s = strchr(str1, *str2))
441 if ((s - str1) < pos)
445 #endif /* !HAVE_STRCSPN */
448 gp_strtod(const char *str, char **endptr)
450 #if (0) /* replace with test for platforms with broken strtod() */
453 int n = sscanf(str, "%lf%n", &d, &used);
455 *endptr = (char *)str;
457 *endptr = (char *)(str + used);
460 return strtod(str,endptr);