fptools.c

Go to the documentation of this file.
00001 /*
00002  * fptools.c, some helper functions for getcgi.c and uu(en|de)view
00003  *
00004  * Distributed under the terms of the GNU General Public License.
00005  * Use and be happy.
00006  */
00007 
00008 #ifdef HAVE_CONFIG_H
00009 #ifdef _MSC_VER
00010 #include "config.h.win32"
00011 #else
00012 #include "config.h"
00013 #endif
00014 #endif
00015 
00016 #ifdef SYSTEM_WINDLL
00017 #include 
00018 #endif
00019 #ifdef SYSTEM_OS2
00020 #include 
00021 #endif
00022 
00023 /*
00024  * This file provides replacements for some handy functions that aren't
00025  * available on all systems, like most of the  functions. They
00026  * should behave exactly as their counterparts. There are also extensions
00027  * that aren't portable at all (like strirstr etc.).
00028  * The proper behaviour in a configure script is as follows:
00029  * AC_CHECK_FUNC(strrchr,AC_DEFINE(strrchr,_FP_strrchr))
00030  * This way, the (probably less efficient) replacements will only be used
00031  * where it is not provided by the default libraries. Be aware that this
00032  * does not work with replacements that just shadow wrong behaviour (like
00033  * _FP_free) or provide extended functionality (_FP_gets).
00034  * The above is not used in the uuenview/uudeview configuration script,
00035  * since both only use the replacement functions in non-performance-cri-
00036  * tical sections (except for _FP_tempnam and _FP_strerror, where some
00037  * functionality of the original would be lost).
00038  */
00039 
00040 #include 
00041 #include 
00042 
00043 #ifdef STDC_HEADERS
00044 #include 
00045 #include 
00046 #endif
00047 #ifdef HAVE_MALLOC_H
00048 #include 
00049 #endif
00050 #ifdef HAVE_UNISTD_H
00051 #ifndef _MSC_VER
00052 #include 
00053 #endif
00054 #endif
00055 #ifdef HAVE_MEMORY_H
00056 #include 
00057 #endif
00058 
00059 #include <fptools.h>
00060 
00061 #if 0
00062 #ifdef SYSTEM_WINDLL
00063 BOOL _export WINAPI
00064 DllEntryPoint (HINSTANCE hInstance, DWORD seginfo,
00065                LPVOID lpCmdLine)
00066 {
00067   /* Don't do anything, so just return true */
00068   return TRUE;
00069 }
00070 #endif
00071 #endif
00072 
00073 char * fptools_id = "$Id: fptools.c 173 2007-02-10 06:27:27Z csk $";
00074 
00075 /*
00076  * some versions of free can't handle a NULL pointer properly
00077  * (ANSI says, free ignores a NULL pointer, but some machines
00078  * prefer to SIGSEGV on it)
00079  */
00080 
00081 void TOOLEXPORT
00082 _FP_free (void *ptr)
00083 {
00084   if (ptr) free (ptr);
00085 }
00086 
00087 /*
00088  * This is non-standard, so I'm defining my own
00089  */
00090 
00091 char * TOOLEXPORT
00092 _FP_strdup (char *string)
00093 {
00094   char *result;
00095 
00096   if (string == NULL)
00097     return NULL;
00098 
00099   if ((result = (char *) malloc (strlen (string) + 1)) == NULL)
00100     return NULL;
00101 
00102   strcpy (result, string);
00103   return result;
00104 }
00105 
00106 /*
00107  * limited-length string copy. this function behaves differently from
00108  * the original in that the dest string is always terminated with a
00109  * NULL character.
00110  */
00111 
00112 char * TOOLEXPORT
00113 _FP_strncpy (char *dest, char *src, int length)
00114 {
00115   char *odest=dest;
00116   if (src == NULL || dest == NULL || length-- <= 0)
00117     return dest;
00118 
00119   while (length-- && *src)
00120     *dest++ = *src++;
00121 
00122   *dest++ = '\0';
00123   return odest;
00124 }
00125 
00126 /*
00127  * duplicate a memory area
00128  */
00129 
00130 void * TOOLEXPORT
00131 _FP_memdup (void *ptr, int len)
00132 {
00133   void *result;
00134 
00135   if (ptr == NULL)
00136     return NULL;
00137 
00138   if ((result = malloc (len)) == NULL)
00139     return NULL;
00140 
00141   memcpy (result, ptr, len);
00142   return result;
00143 }
00144 
00145 /*
00146  * case-insensitive compare
00147  */
00148 
00149 int TOOLEXPORT
00150 _FP_stricmp (char *str1, char *str2)
00151 {
00152   if (str1==NULL || str2==NULL)
00153     return -1;
00154 
00155   while (*str1) {
00156     if (tolower(*str1) != tolower(*str2))
00157       break;
00158     str1++;
00159     str2++;
00160   }
00161   return (tolower (*str1) - tolower (*str2));
00162 }
00163 
00164 int TOOLEXPORT
00165 _FP_strnicmp (char *str1, char *str2, int count)
00166 {
00167   if (str1==NULL || str2==NULL)
00168     return -1;
00169 
00170   while (*str1 && count) {
00171     if (tolower(*str1) != tolower(*str2))
00172       break;
00173     str1++;
00174     str2++;
00175     count--;
00176   }
00177   return count ? (tolower (*str1) - tolower (*str2)) : 0;
00178 }
00179 
00180 /*
00181  * autoconf says this function might be a compatibility problem
00182  */
00183 
00184 char * TOOLEXPORT
00185 _FP_strstr (char *str1, char *str2)
00186 {
00187   char *ptr1, *ptr2;
00188 
00189   if (str1==NULL)
00190     return NULL;
00191   if (str2==NULL)
00192     return str1;
00193 
00194   while (*(ptr1=str1)) {
00195     for (ptr2=str2;
00196          *ptr1 && *ptr2 && *ptr1==*ptr2;
00197          ptr1++, ptr2++)
00198       /* empty loop */ ;
00199 
00200     if (*ptr2 == '\0')
00201       return str1;
00202     str1++;
00203   }
00204   return NULL;
00205 }
00206 
00207 char * TOOLEXPORT
00208 _FP_strpbrk (char *str, char *accept)
00209 {
00210   char *ptr;
00211 
00212   if (str == NULL)
00213     return NULL;
00214   if (accept == NULL || *accept == '\0')
00215     return str;
00216 
00217   for (; *str; str++)
00218     for (ptr=accept; *ptr; ptr++)
00219       if (*str == *ptr)
00220         return str;
00221 
00222   return NULL;
00223 }
00224 
00225 /*
00226  * autoconf also complains about this one
00227  */
00228 
00229 char * TOOLEXPORT
00230 _FP_strtok (char *str1, char *str2)
00231 {
00232   static char *optr;
00233   char *ptr;
00234 
00235   if (str2 == NULL)
00236     return NULL;
00237 
00238   if (str1) {
00239     optr = str1;
00240   }
00241   else {
00242     if (*optr == '\0')
00243       return NULL;
00244   }
00245 
00246   while (*optr && strchr (str2, *optr)) /* look for beginning of token */
00247     optr++;
00248 
00249   if (*optr == '\0')                    /* no token found */
00250     return NULL;
00251 
00252   ptr = optr;
00253   while (*optr && strchr (str2, *optr) == NULL) /* look for end of token */
00254     optr++;
00255 
00256   if (*optr) {
00257     *optr++ = '\0';
00258   }
00259   return ptr;
00260 }
00261 
00262 /*
00263  * case insensitive strstr.
00264  */
00265 
00266 char * TOOLEXPORT
00267 _FP_stristr (char *str1, char *str2)
00268 {
00269   char *ptr1, *ptr2;
00270 
00271   if (str1==NULL)
00272     return NULL;
00273   if (str2==NULL)
00274     return str1;
00275 
00276   while (*(ptr1=str1)) {
00277     for (ptr2=str2;
00278          *ptr1 && *ptr2 && tolower(*ptr1)==tolower(*ptr2);
00279          ptr1++, ptr2++)
00280       /* empty loop */ ;
00281 
00282     if (*ptr2 == '\0')
00283       return str1;
00284     str1++;
00285   }
00286   return NULL;
00287 }
00288 
00289 /*
00290  * Nice fake of the real (non-standard) one
00291  */
00292 
00293 char * TOOLEXPORT
00294 _FP_strrstr (char *ptr, char *str)
00295 {
00296   char *found=NULL, *new, *iter=ptr;
00297 
00298   if (ptr==NULL || str==NULL)
00299     return NULL;
00300 
00301   if (*str == '\0')
00302     return ptr;
00303 
00304   while ((new = _FP_strstr (iter, str)) != NULL) {
00305     found = new;
00306     iter  = new + 1;
00307   }
00308   return found;
00309 }
00310 
00311 char * TOOLEXPORT
00312 _FP_strirstr (char *ptr, char *str)
00313 {
00314   char *found=NULL, *iter=ptr, *new;
00315 
00316   if (ptr==NULL || str==NULL)
00317     return NULL;
00318   if (*str == '\0')
00319     return ptr;
00320 
00321   while ((new = _FP_stristr (iter, str)) != NULL) {
00322     found = new;
00323     iter  = new + 1;
00324   }
00325   return found;
00326 }
00327 
00328 /*
00329  * convert whole string to case
00330  */
00331 
00332 char * TOOLEXPORT
00333 _FP_stoupper (char *input)
00334 {
00335   char *iter = input;
00336 
00337   if (input == NULL)
00338     return NULL;
00339 
00340   while (*iter) {
00341     *iter = toupper (*iter);
00342     iter++;
00343   }
00344   return input;
00345 }
00346 
00347 char * TOOLEXPORT
00348 _FP_stolower (char *input)
00349 {
00350   char *iter = input;
00351 
00352   if (input == NULL)
00353     return NULL;
00354 
00355   while (*iter) {
00356     *iter = tolower (*iter);
00357     iter++;
00358   }
00359   return input;
00360 }
00361 
00362 /*
00363  * string matching with wildcards
00364  */
00365 
00366 int TOOLEXPORT
00367 _FP_strmatch (char *string, char *pattern)
00368 {
00369   char *p1 = string, *p2 = pattern;
00370 
00371   if (pattern==NULL || string==NULL)
00372     return 0;
00373 
00374   while (*p1 && *p2) {
00375     if (*p2 == '?') {
00376       p1++; p2++;
00377     }
00378     else if (*p2 == '*') {
00379       if (*++p2 == '\0')
00380         return 1;
00381       while (*p1 && *p1 != *p2)
00382         p1++;
00383     }
00384     else if (*p1 == *p2) {
00385       p1++; p2++;
00386     }
00387     else
00388       return 0;
00389   }
00390   if (*p1 || *p2)
00391     return 0;
00392 
00393   return 1;
00394 }
00395 
00396 char * TOOLEXPORT
00397 _FP_strrchr (char *string, int tc)
00398 {
00399   char *ptr;
00400 
00401   if (string == NULL || !*string)
00402     return NULL;
00403 
00404   ptr = string + strlen (string) - 1;
00405 
00406   while (ptr != string && *ptr != tc)
00407     ptr--;
00408 
00409   if (*ptr == tc)
00410     return ptr;
00411 
00412   return NULL;
00413 }
00414 
00415 /*
00416  * strip directory information from a filename. Works only on DOS and
00417  * Unix systems so far ...
00418  */
00419 
00420 char * TOOLEXPORT
00421 _FP_cutdir (char *filename)
00422 {
00423   char *ptr;
00424 
00425   if (filename == NULL)
00426     return NULL;
00427 
00428   if ((ptr = _FP_strrchr (filename, '/')) != NULL)
00429     ptr++;
00430   else if ((ptr = _FP_strrchr (filename, '\\')) != NULL)
00431     ptr++;
00432   else
00433     ptr = filename;
00434 
00435   return ptr;
00436 }
00437 
00438 /*
00439  * My own fgets function. It handles all kinds of line terminators
00440  * properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the
00441  * terminator is replaced by a single LF
00442  *
00443  * Pan change: sysprof says this function is standard uulib's biggest
00444  * hotspot, and with the per-char fgetc and feof it's easy to see why.
00445  * Pan doesn't run on OS 9 anyway, so don't bother with that.
00446  * Looking for CRLF and LF will get us Unix, OS X, and Windows.
00447  * In all cases, the terminator is replaced by a single LF.
00448  */
00449 
00450 char * TOOLEXPORT
00451 _FP_fgets (char *buf, int n, FILE *stream)
00452 {
00453   int len;
00454 
00455   if (!fgets (buf, n, stream))
00456     return NULL;
00457 
00458   // unless the string is so full we don't even have room for a \n,
00459   // ensure that buf ends in \n, rather than nothing or \r\n.
00460   buf[n-1] = '\0'; // ensure zero termination
00461   len = strlen (buf);
00462   if (len && buf[len-1]=='\n') --len;
00463   if (len && buf[len-1]=='\r') --len;
00464   if (len<=n-2) memcpy (buf+len, "\n", 2);
00465 
00466   return buf;
00467 }
00468 
00469 /*
00470  * A replacement strerror function that just returns the error code
00471  */
00472 
00473 char * TOOLEXPORT
00474 _FP_strerror (int errcode)
00475 {
00476   static char number[8];
00477 
00478   sprintf (number, "%03d", errcode);
00479 
00480   return number;
00481 }

Generated on Sun Oct 12 01:45:29 2008 for NNTPGrab by  1.5.4