LCOV - code coverage report
Current view: directory - frmts/grib/degrib18/degrib - myutil.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 304 5 1.6 %
Date: 2010-01-09 Functions: 20 1 5.0 %

       1                 : /*****************************************************************************
       2                 :  * myutil.c
       3                 :  *
       4                 :  * DESCRIPTION
       5                 :  *    This file contains some simple utility functions.
       6                 :  *
       7                 :  * HISTORY
       8                 :  * 12/2002 Arthur Taylor (MDL / RSIS): Created.
       9                 :  *
      10                 :  * NOTES
      11                 :  *****************************************************************************
      12                 :  */
      13                 : #include <stdlib.h>
      14                 : #include <stdio.h>
      15                 : #include <ctype.h>
      16                 : #include <string.h>
      17                 : #include <math.h>
      18                 : #include <sys/stat.h>
      19                 : //#include <direct.h>
      20                 : //#include <dirent.h>
      21                 : #include "myutil.h"
      22                 : #include "myassert.h"
      23                 : 
      24                 : #ifdef MEMWATCH
      25                 : #include "memwatch.h"
      26                 : #endif
      27                 : 
      28                 : /*****************************************************************************
      29                 :  * reallocFGets() -- Arthur Taylor / MDL
      30                 :  *
      31                 :  * PURPOSE
      32                 :  *   Read in data from file until a \n is read.  Reallocate memory as needed.
      33                 :  * Similar to fgets, except we don't know ahead of time that the line is a
      34                 :  * specific length.
      35                 :  *   Assumes that Ptr is either NULL, or points to lenBuff memory.
      36                 :  *   Responsibility of caller to free the memory.
      37                 :  *
      38                 :  * ARGUMENTS
      39                 :  *     Ptr = An array of data that is of size LenBuff. (Input/Output)
      40                 :  * LenBuff = The Allocated length of Ptr. (Input/Output)
      41                 :  *      fp = Input file stream (Input)
      42                 :  *
      43                 :  * RETURNS: size_t
      44                 :  *   strlen (buffer)
      45                 :  *     0 = We read only EOF
      46                 :  *     1 = We have "\nEOF" or "<char>EOF"
      47                 :  *
      48                 :  * 12/2002 Arthur Taylor (MDL/RSIS): Created.
      49                 :  *
      50                 :  * NOTES
      51                 :  *  1) Based on getline (see K&R C book (2nd edition) p 29) and on the
      52                 :  *     behavior of Tcl's gets routine.
      53                 :  *  2) Chose MIN_STEPSIZE = 80 because pages are usually 80 columns.
      54                 :  *  3) Could switch lenBuff = i + 1 / lenBuff = i to always true.
      55                 :  *     Rather not... Less allocs... This way code behaves almost the
      56                 :  *     same as fgets except it can expand as needed.
      57                 :  *****************************************************************************
      58                 :  */
      59                 : #define MIN_STEPSIZE 80
      60               0 : size_t reallocFGets (char **Ptr, size_t *LenBuff, FILE *fp)
      61                 : {
      62               0 :    char *buffer = *Ptr; /* Local copy of Ptr. */
      63               0 :    size_t lenBuff = *LenBuff; /* Local copy of LenBuff. */
      64                 :    int c;               /* Current char read from stream. */
      65                 :    size_t i;            /* Where to store c. */
      66                 : 
      67                 :    myAssert (sizeof (char) == 1);
      68               0 :    for (i = 0; ((c = getc (fp)) != EOF) && (c != '\n'); ++i) {
      69               0 :       if (i >= lenBuff) {
      70               0 :          lenBuff += MIN_STEPSIZE;
      71               0 :          buffer = (char *) realloc ((void *) buffer, lenBuff);
      72                 :       }
      73               0 :       buffer[i] = (char) c;
      74                 :    }
      75               0 :    if (c == '\n') {
      76               0 :       if (lenBuff <= i + 1) {
      77               0 :          lenBuff = i + 2; /* Make room for \n\0. */
      78               0 :          buffer = (char *) realloc ((void *) buffer, lenBuff);
      79                 :       }
      80               0 :       buffer[i] = (char) c;
      81               0 :       ++i;
      82                 :    } else {
      83               0 :       if (lenBuff <= i) {
      84               0 :          lenBuff = i + 1; /* Make room for \0. */
      85               0 :          buffer = (char *) realloc ((void *) buffer, lenBuff);
      86                 :       }
      87                 :    }
      88               0 :    buffer[i] = '\0';
      89               0 :    *Ptr = buffer;
      90               0 :    *LenBuff = lenBuff;
      91               0 :    return i;
      92                 : }
      93                 : 
      94                 : #undef MIN_STEPSIZE
      95                 : 
      96                 : /*****************************************************************************
      97                 :  * mySplit() --
      98                 :  *
      99                 :  * Arthur Taylor / MDL
     100                 :  *
     101                 :  * PURPOSE
     102                 :  *   Split a character array according to a given symbol.
     103                 :  *   Responsibility of caller to free the memory.
     104                 :  *
     105                 :  * ARGUMENTS
     106                 :  *   data = character string to look through. (Input)
     107                 :  * symbol = character to split based on. (Input)
     108                 :  *   argc = number of groupings found. (Output)
     109                 :  *   argv = characters in each grouping. (Output)
     110                 :  * f_trim = True if we should white space trim each element in list. (Input)
     111                 :  *
     112                 :  * RETURNS: void
     113                 :  *
     114                 :  * HISTORY
     115                 :  *  5/2004 Arthur Taylor (MDL/RSIS): Created.
     116                 :  *
     117                 :  * NOTES
     118                 :  *****************************************************************************
     119                 :  */
     120               0 : void mySplit (const char *data, char symbol, size_t *Argc, char ***Argv,
     121                 :               char f_trim)
     122                 : {
     123                 :    const char *head;    /* The head of the current string */
     124                 :    const char *ptr;     /* a pointer to walk over the data. */
     125               0 :    size_t argc = 0;     /* Local copy of Argc */
     126               0 :    char **argv = NULL;  /* Local copy of Argv */
     127                 :    size_t len;          /* length of current string. */
     128                 : 
     129                 :    myAssert (*Argc == 0);
     130                 :    myAssert (*Argv == NULL);
     131                 :    myAssert (sizeof (char) == 1);
     132                 : 
     133               0 :    head = data;
     134               0 :    while (head != NULL) {
     135               0 :       argv = (char **) realloc ((void *) argv, (argc + 1) * sizeof (char *));
     136               0 :       ptr = strchr (head, symbol);
     137               0 :       if (ptr != NULL) {
     138               0 :          len = ptr - head;
     139               0 :          argv[argc] = (char *) malloc (len + 1);
     140               0 :          strncpy (argv[argc], head, len);
     141               0 :          argv[argc][len] = '\0';
     142               0 :          if (f_trim) {
     143               0 :             strTrim (argv[argc]);
     144                 :          }
     145               0 :          argc++;
     146               0 :          head = ptr + 1;
     147                 :          /* The following head != NULL is in case data is not '\0' terminated 
     148                 :           */
     149               0 :          if ((head != NULL) && (*head == '\0')) {
     150                 :             /* Handle a break character just before the \0 */
     151                 :             /* This results in not adding a "" to end of list. */
     152               0 :             head = NULL;
     153                 :          }
     154                 :       } else {
     155                 :          /* Handle from here to end of text. */
     156               0 :          len = strlen (head);
     157               0 :          argv[argc] = (char *) malloc (len + 1);
     158               0 :          strcpy (argv[argc], head);
     159               0 :          if (f_trim) {
     160               0 :             strTrim (argv[argc]);
     161                 :          }
     162               0 :          argc++;
     163               0 :          head = NULL;
     164                 :       }
     165                 :    }
     166               0 :    *Argc = argc;
     167               0 :    *Argv = argv;
     168               0 : }
     169                 : 
     170               0 : int myAtoI (const char *ptr, sInt4 *value)
     171                 : {
     172                 :    char *extra;         /* The data after the end of the double. */
     173                 : 
     174                 :    myAssert (ptr != NULL);
     175               0 :    *value = 0;
     176               0 :    while (*ptr != '\0') {
     177               0 :       if (isdigit (*ptr) || (*ptr == '+') || (*ptr == '-')) {
     178               0 :          *value = strtol (ptr, &extra, 10);
     179                 :          myAssert (extra != NULL);
     180               0 :          if (*extra == '\0') {
     181               0 :             return 1;
     182                 :          }
     183               0 :          break;
     184               0 :       } else if (!isspace ((unsigned char)*ptr)) {
     185               0 :          return 0;
     186                 :       }
     187               0 :       ptr++;
     188                 :    }
     189                 :    /* Check if all white space. */
     190               0 :    if (*ptr == '\0') {
     191               0 :       return 0;
     192                 :    }
     193                 :    myAssert (extra != NULL);
     194                 :    /* Allow first trailing char for ',' */
     195               0 :    if (!isspace ((unsigned char)*extra)) {
     196               0 :       if (*extra != ',') {
     197               0 :          *value = 0;
     198               0 :          return 0;
     199                 :       }
     200                 :    }
     201               0 :    extra++;
     202                 :    /* Make sure the rest is all white space. */
     203               0 :    while (*extra != '\0') {
     204               0 :       if (!isspace ((unsigned char)*extra)) {
     205               0 :          *value = 0;
     206               0 :          return 0;
     207                 :       }
     208               0 :       extra++;
     209                 :    }
     210               0 :    return 1;
     211                 : }
     212                 : 
     213                 : /*****************************************************************************
     214                 :  * myAtoF() -- used to be myIsReal()
     215                 :  *
     216                 :  * Arthur Taylor / MDL
     217                 :  *
     218                 :  * PURPOSE
     219                 :  *    Returns true if all char are digits except a leading + or -, or a
     220                 :  * trailing ','.  Ignores leading or trailing white space.  Value is set to
     221                 :  * atof (ptr).
     222                 :  *
     223                 :  * ARGUMENTS
     224                 :  *   ptr = character string to look at. (Input)
     225                 :  * value = the converted value of ptr, if ptr is a number. (Output)
     226                 :  *
     227                 :  * RETURNS: int
     228                 :  *   0 = Not a real number,
     229                 :  *   1 = Real number.
     230                 :  *
     231                 :  * HISTORY
     232                 :  *  7/2004 Arthur Taylor (MDL): Updated
     233                 :  *  4/2005 AAT (MDL): Did a code walk through.
     234                 :  *
     235                 :  * NOTES
     236                 :  *****************************************************************************
     237                 :  */
     238               0 : int myAtoF (const char *ptr, double *value)
     239                 : {
     240                 :    char *extra;         /* The data after the end of the double. */
     241                 : 
     242                 :    myAssert (ptr != NULL);
     243               0 :    *value = 0;
     244               0 :    while (*ptr != '\0') {
     245               0 :       if (isdigit (*ptr) || (*ptr == '+') || (*ptr == '-') || (*ptr == '.')) {
     246               0 :          *value = strtod (ptr, &extra);
     247                 :          myAssert (extra != NULL);
     248               0 :          if (*extra == '\0') {
     249               0 :             return 1;
     250                 :          }
     251               0 :          break;
     252               0 :       } else if (!isspace ((unsigned char)*ptr)) {
     253               0 :          return 0;
     254                 :       }
     255               0 :       ptr++;
     256                 :    }
     257                 :    /* Check if all white space. */
     258               0 :    if (*ptr == '\0') {
     259               0 :       return 0;
     260                 :    }
     261                 :    myAssert (extra != NULL);
     262                 :    /* Allow first trailing char for ',' */
     263               0 :    if (!isspace ((unsigned char)*extra)) {
     264               0 :       if (*extra != ',') {
     265               0 :          *value = 0;
     266               0 :          return 0;
     267                 :       }
     268                 :    }
     269               0 :    extra++;
     270                 :    /* Make sure the rest is all white space. */
     271               0 :    while (*extra != '\0') {
     272               0 :       if (!isspace ((unsigned char)*extra)) {
     273               0 :          *value = 0;
     274               0 :          return 0;
     275                 :       }
     276               0 :       extra++;
     277                 :    }
     278               0 :    return 1;
     279                 : }
     280                 : 
     281                 : /* Change of name was to deprecate usage... Switch to myAtoF */
     282               0 : int myIsReal_old (const char *ptr, double *value)
     283                 : {
     284                 :    size_t len, i;
     285                 : 
     286               0 :    *value = 0;
     287               0 :    if ((!isdigit (*ptr)) && (*ptr != '.'))
     288               0 :       if (*ptr != '-')
     289               0 :          return 0;
     290               0 :    len = strlen (ptr);
     291               0 :    for (i = 1; i < len - 1; i++) {
     292               0 :       if ((!isdigit (ptr[i])) && (ptr[i] != '.'))
     293               0 :          return 0;
     294                 :    }
     295               0 :    if ((!isdigit (ptr[len - 1])) && (ptr[len - 1] != '.')) {
     296               0 :       if (ptr[len - 1] != ',') {
     297               0 :          return 0;
     298                 :       } else {
     299                 : /*         ptr[len - 1] = '\0';*/
     300               0 :          *value = atof (ptr);
     301                 : /*         ptr[len - 1] = ',';*/
     302               0 :          return 1;
     303                 :       }
     304                 :    }
     305               0 :    *value = atof (ptr);
     306               0 :    return 1;
     307                 : }
     308                 : 
     309                 : /* Return:
     310                 :  * 0 if 'can't stat the file' (most likely not a file)
     311                 :  * 1 if it is a directory
     312                 :  * 2 if it is a file
     313                 :  * 3 if it doesn't understand the file
     314                 :  */
     315                 : /* mtime may behave oddly...
     316                 :  * stat appeared correct if I was in EST and the file was in EST,
     317                 :  * but was off by 1 hour if I was in EST and the file was in EDT.
     318                 :  * rddirlst.c solved this through use of "clock".
     319                 :  *
     320                 :  * Could return mode: RDCF___rwxrwxrwx where R is 1/0 based on regular file
     321                 :  * D is 1/0 based on directory, first rwx is user permissions...
     322                 :  */
     323               0 : int myStat (char *filename, char *perm, sInt4 *size, double *mtime)
     324                 : {
     325                 :    struct stat stbuf;
     326                 :    char f_cnt;
     327                 :    char *ptr;
     328                 :    int ans;
     329                 : 
     330                 :    myAssert (filename != NULL);
     331                 : 
     332                 :    /* Check for unmatched quotes (apparently stat on MS-Windows lets:
     333                 :     * ./data/ndfd/geodata\" pass, which causes issues later. */
     334               0 :    f_cnt = 0;
     335               0 :    for (ptr = filename; *ptr != '\0'; ptr++) {
     336               0 :       if (*ptr == '"')
     337               0 :          f_cnt = !f_cnt;
     338                 :    }
     339               0 :    if (f_cnt) {
     340                 :       /* unmatched quotes. */
     341               0 :       if (size)
     342               0 :          *size = 0;
     343               0 :       if (mtime)
     344               0 :          *mtime = 0;
     345               0 :       if (perm)
     346               0 :          *perm = 0;
     347               0 :       return 0;
     348                 :    }
     349                 : 
     350                 :    /* Try to stat file. */
     351               0 :    if ((ans = stat (filename, &stbuf)) == -1) {
     352               0 :       if ((filename[strlen (filename) - 1] == '/') ||
     353               0 :           (filename[strlen (filename) - 1] == '\\')) {
     354               0 :          filename[strlen (filename) - 1] = '\0';
     355               0 :          ans = stat (filename, &stbuf);
     356                 :       }
     357                 :    }
     358                 :    /* Can't stat */
     359               0 :    if (ans == -1) {
     360               0 :       if (size)
     361               0 :          *size = 0;
     362               0 :       if (mtime)
     363               0 :          *mtime = 0;
     364               0 :       if (perm)
     365               0 :          *perm = 0;
     366               0 :       return 0;
     367                 :    }
     368                 : 
     369               0 :    if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
     370                 :       /* Is a directory */
     371               0 :       if (size)
     372               0 :          *size = stbuf.st_size;
     373               0 :       if (mtime)
     374               0 :          *mtime = stbuf.st_mtime;
     375               0 :       if (perm) {
     376               0 :          *perm = (stbuf.st_mode & S_IREAD) ? 4 : 0;
     377               0 :          if (stbuf.st_mode & S_IWRITE)
     378               0 :             *perm += 2;
     379               0 :          if (stbuf.st_mode & S_IEXEC)
     380               0 :             *perm += 1;
     381                 :       }
     382               0 :       return MYSTAT_ISDIR;
     383               0 :    } else if ((stbuf.st_mode & S_IFMT) == S_IFREG) {
     384                 :       /* Is a file */
     385               0 :       if (size)
     386               0 :          *size = stbuf.st_size;
     387               0 :       if (mtime)
     388               0 :          *mtime = stbuf.st_mtime;
     389               0 :       if (perm) {
     390               0 :          *perm = (stbuf.st_mode & S_IREAD) ? 4 : 0;
     391               0 :          if (stbuf.st_mode & S_IWRITE)
     392               0 :             *perm += 2;
     393               0 :          if (stbuf.st_mode & S_IEXEC)
     394               0 :             *perm += 1;
     395                 :       }
     396               0 :       return MYSTAT_ISFILE;
     397                 :    } else {
     398                 :       /* unrecognized file type */
     399               0 :       if (size)
     400               0 :          *size = 0;
     401               0 :       if (mtime)
     402               0 :          *mtime = 0;
     403               0 :       if (perm)
     404               0 :          *perm = 0;
     405               0 :       return 3;
     406                 :    }
     407                 : }
     408                 : 
     409                 : /** 
     410                 : static int FileMatch (const char *filename, const char *filter)
     411                 : {
     412                 :    const char *ptr1;
     413                 :    const char *ptr2;
     414                 : 
     415                 :    ptr2 = filename;
     416                 :    for (ptr1 = filter; *ptr1 != '\0'; ptr1++) {
     417                 :       if (*ptr1 == '*') {
     418                 :          if (ptr1[1] == '\0') {
     419                 :             return 1;
     420                 :          } else {
     421                 :             ptr2 = strchr (ptr2, ptr1[1]);
     422                 :             if (ptr2 == NULL) {
     423                 :                return 0;
     424                 :             }
     425                 :          }
     426                 :       } else if (*ptr2 == '\0') {
     427                 :          return 0;
     428                 :       } else if (*ptr1 == '?') {
     429                 :          ptr2++;
     430                 :       } else {
     431                 :          if (*ptr1 == *ptr2) {
     432                 :             ptr2++;
     433                 :          } else {
     434                 :             return 0;
     435                 :          }
     436                 :       }
     437                 :    }
     438                 :    return (*ptr2 == '\0');
     439                 : }
     440                 : **/
     441                 : 
     442               0 : int myGlob (const char *dirName, const char *filter, size_t *Argc,
     443                 :             char ***Argv)
     444                 : {
     445               0 : return 0; // TODO: reimplement for Win32
     446                 : /*
     447                 :    size_t argc = 0;     // Local copy of Argc
     448                 :    char **argv = NULL;  // Local copy of Argv
     449                 :    struct dirent *dp;
     450                 :    DIR *dir;
     451                 : 
     452                 :    myAssert (*Argc == 0);
     453                 :    myAssert (*Argv == NULL);
     454                 : 
     455                 :    if ((dir = opendir (dirName)) == NULL)
     456                 :       return -1;
     457                 : 
     458                 :    while ((dp = readdir (dir)) != NULL) {
     459                 :       // Skip self and parent.
     460                 :       if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0)
     461                 :          continue;
     462                 :       if (FileMatch (dp->d_name, filter)) {
     463                 :          argv = (char **) realloc (argv, (argc + 1) * sizeof (char *));
     464                 :          argv[argc] = (char *) malloc ((strlen (dirName) + 1 +
     465                 :                                         strlen (dp->d_name) +
     466                 :                                         1) * sizeof (char));
     467                 :          sprintf (argv[argc], "%s/%s", dirName, dp->d_name);
     468                 :          argc++;
     469                 :       }
     470                 :    }
     471                 :    *Argc = argc;
     472                 :    *Argv = argv;
     473                 :    return 0;
     474                 : */
     475                 : }
     476                 : 
     477                 : /*****************************************************************************
     478                 :  * FileCopy() --
     479                 :  *
     480                 :  * Arthur Taylor / MDL
     481                 :  *
     482                 :  * PURPOSE
     483                 :  *   Copy a file from one location to another.
     484                 :  *
     485                 :  * ARGUMENTS
     486                 :  *  fileIn = source file to read from. (Input)
     487                 :  * fileOut = destation file to write to. (Input)
     488                 :  *
     489                 :  * RETURNS: int
     490                 :  *   0 = success.
     491                 :  *   1 = problems opening fileIn
     492                 :  *   2 = problems opening fileOut
     493                 :  *
     494                 :  * HISTORY
     495                 :  *  5/2004 Arthur Taylor (MDL/RSIS): Created.
     496                 :  *  4/2005 AAT (MDL): Did a code walk through.
     497                 :  *
     498                 :  * NOTES
     499                 :  *****************************************************************************
     500                 :  */
     501               0 : int FileCopy (const char *fileIn, const char *fileOut)
     502                 : {
     503                 :    FILE *ifp;           /* The file pointer to read from. */
     504                 :    FILE *ofp;           /* The file pointer to write to. */
     505                 :    int c;               /* temporary variable while reading / writing. */
     506                 : 
     507               0 :    if ((ifp = fopen (fileIn, "rb")) == NULL) {
     508                 : #ifdef DEBUG
     509                 :       printf ("Couldn't open %s for read\n", fileIn);
     510                 : #endif
     511               0 :       return 1;
     512                 :    }
     513               0 :    if ((ofp = fopen (fileOut, "wb")) == NULL) {
     514                 : #ifdef DEBUG
     515                 :       printf ("Couldn't open %s for write\n", fileOut);
     516                 : #endif
     517               0 :       fclose (ifp);
     518               0 :       return 2;
     519                 :    }
     520               0 :    while ((c = getc (ifp)) != EOF) {
     521               0 :       putc (c, ofp);
     522                 :    }
     523               0 :    fclose (ifp);
     524               0 :    fclose (ofp);
     525               0 :    return 0;
     526                 : }
     527                 : 
     528                 : /*****************************************************************************
     529                 :  * FileTail() --
     530                 :  *
     531                 :  * Arthur Taylor / MDL
     532                 :  *
     533                 :  * PURPOSE
     534                 :  *   Returns the characters in a filename after the last directory separator.
     535                 :  *   Responsibility of caller to free the memory.
     536                 :  *
     537                 :  * ARGUMENTS
     538                 :  * fileName = fileName to look at. (Input)
     539                 :  *     tail = Tail of the filename. (Output)
     540                 :  *
     541                 :  * RETURNS: void
     542                 :  *
     543                 :  * HISTORY
     544                 :  *  5/2004 Arthur Taylor (MDL/RSIS): Created.
     545                 :  *
     546                 :  * NOTES
     547                 :  *****************************************************************************
     548                 :  */
     549               0 : void FileTail (const char *fileName, char **tail)
     550                 : {
     551                 :    const char *ptr;     /* A pointer to last \ or // in fileName. */
     552                 : 
     553                 :    myAssert (fileName != NULL);
     554                 :    myAssert (sizeof (char) == 1);
     555                 : 
     556               0 :    ptr = strrchr (fileName, '/');
     557               0 :    if (ptr == NULL) {
     558               0 :       ptr = strrchr (fileName, '\\');
     559               0 :       if (ptr == NULL) {
     560               0 :          ptr = fileName;
     561                 :       } else {
     562               0 :          ptr++;
     563                 :       }
     564                 :    } else {
     565               0 :       ptr++;
     566                 :    }
     567               0 :    *tail = (char *) malloc (strlen (ptr) + 1);
     568               0 :    strcpy (*tail, ptr);
     569               0 : }
     570                 : 
     571                 : /*****************************************************************************
     572                 :  * myRound() --
     573                 :  *
     574                 :  * Arthur Taylor / MDL
     575                 :  *
     576                 :  * PURPOSE
     577                 :  *   Round a number to a given number of decimal places.
     578                 :  *
     579                 :  * ARGUMENTS
     580                 :  *  data = number to round (Input)
     581                 :  * place = How many decimals to round to (Input)
     582                 :  *
     583                 :  * RETURNS: double (rounded value)
     584                 :  *
     585                 :  * HISTORY
     586                 :  *  5/2003 Arthur Taylor (MDL/RSIS): Created.
     587                 :  *  2/2006 AAT: Added the (double) (.5) cast, and the mult by POWERS_OVER_ONE
     588                 :  *         instead of division.
     589                 :  *
     590                 :  * NOTES
     591                 :  *  1) It is probably inadvisable to make a lot of calls to this routine,
     592                 :  *     considering the fact that a context swap is made, so this is provided
     593                 :  *     primarily as an example, but it can be used for some rounding.
     594                 :  *****************************************************************************
     595                 :  */
     596                 : double POWERS_ONE[] = {
     597                 :    1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
     598                 :    1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17
     599                 : };
     600                 : 
     601               0 : double myRound (double data, uChar place)
     602                 : {
     603               0 :    if (place > 17)
     604               0 :       place = 17;
     605                 : 
     606               0 :    return (floor (data * POWERS_ONE[place] + 5e-1)) / POWERS_ONE[place];
     607                 : 
     608                 :    /* Tried some other options to see if I could fix test 40 on linux, but
     609                 :     * changing it appears to make other tests fail on other OS's. */
     610                 : /*
     611                 :    return (((sInt4) (data * POWERS_ONE[place] + .5)) / POWERS_ONE[place]);
     612                 : */
     613                 : /*
     614                 :    return (floor (data * POWERS_ONE[place] + .5)) / POWERS_ONE[place];
     615                 : */
     616                 : }
     617                 : 
     618                 : /*****************************************************************************
     619                 :  * strTrim() --
     620                 :  *
     621                 :  * Arthur Taylor / MDL
     622                 :  *
     623                 :  * PURPOSE
     624                 :  *   Trim the white space from both sides of a char string.
     625                 :  *
     626                 :  * ARGUMENTS
     627                 :  * str = The string to trim (Input/Output)
     628                 :  *
     629                 :  * RETURNS: void
     630                 :  *
     631                 :  * HISTORY
     632                 :  *  10/2003 Arthur Taylor (MDL/RSIS): Created.
     633                 :  *
     634                 :  * NOTES
     635                 :  *   See K&R p106 for strcpy part.
     636                 :  *****************************************************************************
     637                 :  */
     638               0 : void strTrim (char *str)
     639                 : {
     640                 :    size_t i;            /* loop counter for traversing str. */
     641                 :    size_t len;          /* The length of str. */
     642                 :    char *ptr;           /* Pointer to where first non-white space is. */
     643                 : 
     644                 :    /* str shouldn't be null, but if it is, we want to handle it. */
     645                 :    myAssert (str != NULL);
     646               0 :    if (str == NULL) {
     647               0 :       return;
     648                 :    }
     649                 : 
     650                 :    /* Remove the trailing white space before working on the leading ones. */
     651               0 :    len = strlen (str);
     652               0 :    for (i = len - 1; ((i >= 0) && (isspace ((unsigned char)str[i]))); i--) {
     653                 :    }
     654               0 :    len = i + 1;
     655               0 :    str[len] = '\0';
     656                 : 
     657                 :    /* Find first non-white space char. */
     658               0 :    for (ptr = str; (*ptr != '\0') && (isspace ((unsigned char)*ptr)); ptr++) {
     659                 :    }
     660                 : 
     661               0 :    if (ptr != str) {
     662                 :       /* Can't do a strcpy here since we don't know that they start at left
     663                 :        * and go right. */
     664               0 :       while ((*str++ = *ptr++) != '\0') {
     665                 :       }
     666               0 :       *str = '\0';
     667                 :    }
     668                 : }
     669                 : 
     670                 : /*****************************************************************************
     671                 :  * strTrimRight() --
     672                 :  *
     673                 :  * Arthur Taylor / MDL
     674                 :  *
     675                 :  * PURPOSE
     676                 :  *   Trim white space and a given char from the right.
     677                 :  *
     678                 :  * ARGUMENTS
     679                 :  * str = The string to trim (Input/Output)
     680                 :  *   c = The character to remove. (Input)
     681                 :  *
     682                 :  * RETURNS: void
     683                 :  *
     684                 :  * HISTORY
     685                 :  *  7/2004 Arthur Taylor (MDL/RSIS): Created.
     686                 :  *
     687                 :  * NOTES
     688                 :  *****************************************************************************
     689                 :  */
     690               4 : void strTrimRight (char *str, char c)
     691                 : {
     692                 :    size_t i;            /* loop counter for traversing str. */
     693                 : 
     694                 :    /* str shouldn't be null, but if it is, we want to handle it. */
     695                 :    myAssert (str != NULL);
     696               4 :    if (str == NULL) {
     697               0 :       return;
     698                 :    }
     699                 : 
     700              60 :    for (i = strlen (str) - 1;
     701              52 :         ((i >= 0) && ((isspace ((unsigned char)str[i])) || (str[i] == c))); i--) {
     702                 :    }
     703               4 :    str[i + 1] = '\0';
     704                 : }
     705                 : 
     706                 : /*****************************************************************************
     707                 :  * strCompact() --
     708                 :  *
     709                 :  * Arthur Taylor / MDL
     710                 :  *
     711                 :  * PURPOSE
     712                 :  *   Replace any multiple instances of 'c' in the string with 1 instance.
     713                 :  *
     714                 :  * ARGUMENTS
     715                 :  * str = The string to compact (Input/Output)
     716                 :  *   c = The character to look for. (Input)
     717                 :  *
     718                 :  * RETURNS: void
     719                 :  *
     720                 :  * HISTORY
     721                 :  * 10/2004 Arthur Taylor (MDL): Created.
     722                 :  *
     723                 :  * NOTES
     724                 :  *****************************************************************************
     725                 :  */
     726               0 : void strCompact (char *str, char c)
     727                 : {
     728                 :    char *ptr;           /* The next good value in str to keep. */
     729                 : 
     730                 :    /* str shouldn't be null, but if it is, we want to handle it. */
     731                 :    myAssert (str != NULL);
     732               0 :    if (str == NULL) {
     733               0 :       return;
     734                 :    }
     735                 : 
     736               0 :    ptr = str;
     737               0 :    while ((*str = *(ptr++)) != '\0') {
     738               0 :       if (*(str++) == c) {
     739               0 :          while ((*ptr != '\0') && (*ptr == c)) {
     740               0 :             ptr++;
     741                 :          }
     742                 :       }
     743                 :    }
     744                 : }
     745                 : 
     746                 : /*****************************************************************************
     747                 :  * strReplace() --
     748                 :  *
     749                 :  * Arthur Taylor / MDL
     750                 :  *
     751                 :  * PURPOSE
     752                 :  *   Replace all instances of c1 in str with c2.
     753                 :  *
     754                 :  * ARGUMENTS
     755                 :  * str = The string to trim (Input/Output)
     756                 :  *  c1 = The character(s) in str to be replaced. (Input)
     757                 :  *  c2 = The char to replace c1 with. (Input)
     758                 :  *
     759                 :  * RETURNS: void
     760                 :  *
     761                 :  * HISTORY
     762                 :  *  7/2004 Arthur Taylor (MDL/RSIS): Created.
     763                 :  *
     764                 :  * NOTES
     765                 :  *****************************************************************************
     766                 :  */
     767               0 : void strReplace (char *str, char c1, char c2)
     768                 : {
     769               0 :    char *ptr = str;
     770                 : 
     771                 :    /* str shouldn't be null, but if it is, we want to handle it. */
     772                 :    myAssert (str != NULL);
     773               0 :    if (str == NULL) {
     774               0 :       return;
     775                 :    }
     776                 : 
     777               0 :    for (ptr = str; *ptr != '\0'; ptr++) {
     778               0 :       if (*ptr == c1) {
     779               0 :          *ptr = c2;
     780                 :       }
     781                 :    }
     782                 : }
     783                 : 
     784                 : /*****************************************************************************
     785                 :  * strToUpper() --
     786                 :  *
     787                 :  * Arthur Taylor / MDL
     788                 :  *
     789                 :  * PURPOSE
     790                 :  *   Convert a string to all uppercase.
     791                 :  *
     792                 :  * ARGUMENTS
     793                 :  * str = The string to adjust (Input/Output)
     794                 :  *
     795                 :  * RETURNS: void
     796                 :  *
     797                 :  * HISTORY
     798                 :  *  10/2003 Arthur Taylor (MDL/RSIS): Created.
     799                 :  *
     800                 :  * NOTES
     801                 :  *****************************************************************************
     802                 :  */
     803               0 : void strToUpper (char *str)
     804                 : {
     805               0 :    char *ptr = str;     /* Used to traverse str. */
     806                 : 
     807                 :    /* str shouldn't be null, but if it is, we want to handle it. */
     808                 :    myAssert (str != NULL);
     809               0 :    if (str == NULL) {
     810               0 :       return;
     811                 :    }
     812                 : 
     813               0 :    while ((*ptr++ = toupper (*str++)) != '\0') {
     814                 :    }
     815                 : }
     816                 : 
     817                 : /*****************************************************************************
     818                 :  * strToLower() --
     819                 :  *
     820                 :  * Arthur Taylor / MDL
     821                 :  *
     822                 :  * PURPOSE
     823                 :  *   Convert a string to all lowercase.
     824                 :  *
     825                 :  * ARGUMENTS
     826                 :  * str = The string to adjust (Input/Output)
     827                 :  *
     828                 :  * RETURNS: void
     829                 :  *
     830                 :  * HISTORY
     831                 :  *  5/2004 Arthur Taylor (MDL/RSIS): Created.
     832                 :  *
     833                 :  * NOTES
     834                 :  *****************************************************************************
     835                 :  */
     836               0 : void strToLower (char *str)
     837                 : {
     838               0 :    char *ptr = str;     /* Used to traverse str. */
     839                 : 
     840                 :    /* str shouldn't be null, but if it is, we want to handle it. */
     841                 :    myAssert (str != NULL);
     842               0 :    if (str == NULL) {
     843               0 :       return;
     844                 :    }
     845                 : 
     846               0 :    while ((*ptr++ = tolower (*str++)) != '\0') {
     847                 :    }
     848                 : }
     849                 : 
     850                 : /*
     851                 :  * Returns: Length of the string.
     852                 :  * History: 1/29/98 AAT Commented.
     853                 :  *
     854                 : int str2lw (char *s) {
     855                 :   int i = 0, len = strlen (s);
     856                 :   while (i < len) {
     857                 :     s[i] = (char) tolower(s[i]);
     858                 :     i++;
     859                 :   }
     860                 :   return len;
     861                 : }
     862                 : */
     863                 : 
     864                 : /*****************************************************************************
     865                 :  * strcmpNoCase() --
     866                 :  *
     867                 :  * Arthur Taylor / MDL
     868                 :  *
     869                 :  * PURPOSE
     870                 :  *   Compare two strings without concern for case.
     871                 :  *
     872                 :  * ARGUMENTS
     873                 :  * str1 = String1 to compare (Input)
     874                 :  * str2 = String2 to compare (Input)
     875                 :  *
     876                 :  * RETURNS: int
     877                 :  *   -1 = (str1 < str2)
     878                 :  *    0 = (str1 == str2)
     879                 :  *    1 = (str1 > str2)
     880                 :  *
     881                 :  * HISTORY
     882                 :  *  5/2004 Arthur Taylor (MDL/RSIS): Created.
     883                 :  *
     884                 :  * NOTES
     885                 :  *   See K&R p 106
     886                 :  *****************************************************************************
     887                 :  */
     888               0 : int strcmpNoCase (const char *str1, const char *str2)
     889                 : {
     890                 :    /* str1, str2 shouldn't be null, but if it is, we want to handle it. */
     891                 :    myAssert (str1 != NULL);
     892                 :    myAssert (str2 != NULL);
     893               0 :    if (str1 == NULL) {
     894               0 :       if (str2 == NULL) {
     895               0 :          return 0;
     896                 :       } else {
     897               0 :          return -1;
     898                 :       }
     899                 :    }
     900               0 :    if (str2 == NULL) {
     901               0 :       return 1;
     902                 :    }
     903                 : 
     904               0 :    for (; tolower (*str1) == tolower (*str2); str1++, str2++) {
     905               0 :       if (*str1 == '\0')
     906               0 :          return 0;
     907                 :    }
     908               0 :    return (tolower (*str1) - tolower (*str2) < 0) ? -1 : 1;
     909                 : /*
     910                 :    strlen1 = strlen (str1);
     911                 :    strlen2 = strlen (str2);
     912                 :    min = (strlen1 < strlen2) ? strlen1 : strlen2;
     913                 :    for (i = 0; i < min; i++) {
     914                 :       c1 = tolower (str1[i]);
     915                 :       c2 = tolower (str2[i]);
     916                 :       if (c1 < c2)
     917                 :          return -1;
     918                 :       if (c1 > c2)
     919                 :          return 1;
     920                 :    }
     921                 :    if (strlen1 < strlen2) {
     922                 :       return -1;
     923                 :    }
     924                 :    if (strlen1 > strlen2) {
     925                 :       return 1;
     926                 :    }
     927                 :    return 0;
     928                 : */
     929                 : }
     930                 : 
     931                 :  /*****************************************************************************
     932                 :  * GetIndexFromStr() -- Review 12/2002
     933                 :  *
     934                 :  * Arthur Taylor / MDL
     935                 :  *
     936                 :  * PURPOSE
     937                 :  *   Looks through a list of strings (with a NULL value at the end) for a
     938                 :  * given string.  Returns the index where it found it.
     939                 :  *
     940                 :  * ARGUMENTS
     941                 :  *   str = The string to look for. (Input)
     942                 :  *   Opt = The list to look for arg in. (Input)
     943                 :  * Index = The location of arg in Opt (or -1 if it couldn't find it) (Output)
     944                 :  *
     945                 :  * RETURNS: int
     946                 :  *  # = Where it found it.
     947                 :  * -1 = Couldn't find it.
     948                 :  *
     949                 :  * HISTORY
     950                 :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
     951                 :  *  12/2002 (TK,AC,TB,&MS): Code Review.
     952                 :  *
     953                 :  * NOTES
     954                 :  *   Why not const char **Opt?
     955                 :  *****************************************************************************
     956                 :  */
     957               0 : int GetIndexFromStr (const char *str, char **Opt, int *Index)
     958                 : {
     959               0 :    int cnt = 0;         /* Current Count in Opt. */
     960                 : 
     961                 :    myAssert (str != NULL);
     962               0 :    if (str == NULL) {
     963               0 :       *Index = -1;
     964               0 :       return -1;
     965                 :    }
     966                 : 
     967               0 :    for (; *Opt != NULL; Opt++, cnt++) {
     968               0 :       if (strcmp (str, *Opt) == 0) {
     969               0 :          *Index = cnt;
     970               0 :          return cnt;
     971                 :       }
     972                 :    }
     973               0 :    *Index = -1;
     974               0 :    return -1;
     975                 : }
     976                 : 
     977                 : /*****************************************************************************
     978                 :  * Clock_GetTimeZone() --
     979                 :  *
     980                 :  * Arthur Taylor / MDL
     981                 :  *
     982                 :  * PURPOSE
     983                 :  *   Returns the time zone offset in hours to add to local time to get UTC.
     984                 :  * So EST is +5 not -5.
     985                 :  *
     986                 :  * ARGUMENTS
     987                 :  *
     988                 :  * RETURNS: sInt2
     989                 :  *
     990                 :  * HISTORY
     991                 :  *   6/2004 Arthur Taylor (MDL): Created.
     992                 :  *   3/2005 AAT: Found bug... Used to use 1/1/1970 00Z and find the local
     993                 :  *        hour.  If CET, this means use 1969 date, which causes it to die.
     994                 :  *        Switched to 1/2/1970 00Z.
     995                 :  *   3/2005 AAT: timeZone (see CET) can be < 0. don't add 24 if timeZone < 0
     996                 :  *
     997                 :  * NOTES
     998                 :  *****************************************************************************
     999                 :  */
    1000               0 : static sChar Clock_GetTimeZone ()
    1001                 : {
    1002                 :    struct tm time;
    1003                 :    time_t ansTime;
    1004                 :    struct tm *gmTime;
    1005                 :    static sChar timeZone = 127;
    1006                 : 
    1007               0 :    if (timeZone == 127) {
    1008                 :       /* Cheap method of getting global time_zone variable. */
    1009               0 :       memset (&time, 0, sizeof (struct tm));
    1010               0 :       time.tm_year = 70;
    1011               0 :       time.tm_mday = 2;
    1012               0 :       ansTime = mktime (&time);
    1013               0 :       gmTime = gmtime (&ansTime);
    1014               0 :       timeZone = gmTime->tm_hour;
    1015               0 :       if (gmTime->tm_mday != 2) {
    1016               0 :          timeZone -= 24;
    1017                 :       }
    1018                 :    }
    1019               0 :    return timeZone;
    1020                 : }
    1021                 : 
    1022                 : /*****************************************************************************
    1023                 :  * myParseTime() --
    1024                 :  *
    1025                 :  * Arthur Taylor / MDL
    1026                 :  *
    1027                 :  * PURPOSE
    1028                 :  *   Parse a string such as "19730724000000" and return time since the
    1029                 :  * beginning of the epoch.
    1030                 :  *
    1031                 :  * ARGUMENTS
    1032                 :  *      is = String to read the date from (Input)
    1033                 :  * AnsTime = Time to String2 to compare (Input)
    1034                 :  *
    1035                 :  * RETURNS: int
    1036                 :  *    0 = success
    1037                 :  *    1 = error
    1038                 :  *
    1039                 :  * HISTORY
    1040                 :  *  4/2005 Arthur Taylor (MDL): Commented
    1041                 :  *
    1042                 :  * NOTES
    1043                 :  *   Rename (myParseTime -> myParseTime2) because changed error return from
    1044                 :  *      -1 to 1
    1045                 :  *   Rename (myParseTime2 -> myParseTime3) because I'm trying to phase it out.
    1046                 :  *   Use: int Clock_ScanDateNumber (double *clock, char *buffer) instead.
    1047                 :  *****************************************************************************
    1048                 :  */
    1049               0 : int myParseTime3 (const char *is, time_t * AnsTime)
    1050                 : {
    1051                 :    char buffer[5];      /* A temporary variable for parsing "is". */
    1052                 :    sShort2 year;        /* The year. */
    1053                 :    uChar mon;           /* The month. */
    1054                 :    uChar day;           /* The day. */
    1055                 :    uChar hour;          /* The hour. */
    1056                 :    uChar min;           /* The minute. */
    1057                 :    uChar sec;           /* The second. */
    1058                 :    struct tm time;      /* A temporary variable to put the time info into. */
    1059                 : 
    1060               0 :    memset (&time, 0, sizeof (struct tm));
    1061                 :    myAssert (strlen (is) == 14);
    1062               0 :    if (strlen (is) != 14) {
    1063               0 :       printf ("%s is not formated correctly\n", is);
    1064               0 :       return 1;
    1065                 :    }
    1066               0 :    strncpy (buffer, is, 4);
    1067               0 :    buffer[4] = '\0';
    1068               0 :    year = atoi (buffer);
    1069               0 :    strncpy (buffer, is + 4, 2);
    1070               0 :    buffer[2] = '\0';
    1071               0 :    mon = atoi (buffer);
    1072               0 :    strncpy (buffer, is + 6, 2);
    1073               0 :    day = atoi (buffer);
    1074               0 :    strncpy (buffer, is + 8, 2);
    1075               0 :    hour = atoi (buffer);
    1076               0 :    strncpy (buffer, is + 10, 2);
    1077               0 :    min = atoi (buffer);
    1078               0 :    strncpy (buffer, is + 12, 2);
    1079               0 :    sec = atoi (buffer);
    1080               0 :    if ((year > 2001) || (year < 1900) || (mon > 12) || (mon < 1) ||
    1081                 :        (day > 31) || (day < 1) || (hour > 23) || (min > 59) || (sec > 60)) {
    1082               0 :       printf ("date %s is invalid\n", is);
    1083               0 :       printf ("%d %d %d %d %d %d\n", year, mon, day, hour, min, sec);
    1084               0 :       return 1;
    1085                 :    }
    1086               0 :    time.tm_year = year - 1900;
    1087               0 :    time.tm_mon = mon - 1;
    1088               0 :    time.tm_mday = day;
    1089               0 :    time.tm_hour = hour;
    1090               0 :    time.tm_min = min;
    1091               0 :    time.tm_sec = sec;
    1092               0 :    *AnsTime = mktime (&time) - (Clock_GetTimeZone () * 3600);
    1093               0 :    return 0;
    1094                 : }
    1095                 : 
    1096                 : #ifdef MYUTIL_TEST
    1097                 : int main (int argc, char **argv)
    1098                 : {
    1099                 :    char buffer[] = "Hello , World, This, is, a , test\n";
    1100                 :    char buffer2[] = "";
    1101                 :    size_t listLen = 0;
    1102                 :    char **List = NULL;
    1103                 :    size_t i;
    1104                 :    size_t j;
    1105                 :    char ans;
    1106                 :    double value;
    1107                 :    char *tail;
    1108                 : 
    1109                 : /*
    1110                 :    printf ("1 :: %f\n", clock() / (double) (CLOCKS_PER_SEC));
    1111                 :    for (j = 0; j < 25000; j++) {
    1112                 :       mySplit (buffer, ',', &listLen, &List, 1);
    1113                 :       for (i = 0; i < listLen; i++) {
    1114                 :          free (List[i]);
    1115                 :       }
    1116                 :       free (List);
    1117                 :       List = NULL;
    1118                 :       listLen = 0;
    1119                 :    }
    1120                 :    printf ("1 :: %f\n", clock() / (double) (CLOCKS_PER_SEC));
    1121                 : */
    1122                 :    mySplit (buffer, ',', &listLen, &List, 1);
    1123                 :    for (i = 0; i < listLen; i++) {
    1124                 :       printf ("%d:'%s'\n", i, List[i]);
    1125                 :       free (List[i]);
    1126                 :    }
    1127                 :    free (List);
    1128                 :    List = NULL;
    1129                 :    listLen = 0;
    1130                 : 
    1131                 :    mySplit (buffer2, ',', &listLen, &List, 1);
    1132                 :    for (i = 0; i < listLen; i++) {
    1133                 :       printf ("%d:'%s'\n", i, List[i]);
    1134                 :       free (List[i]);
    1135                 :    }
    1136                 :    free (List);
    1137                 :    List = NULL;
    1138                 :    listLen = 0;
    1139                 : 
    1140                 :    strcpy (buffer, "  0.95");
    1141                 :    ans = myAtoF (buffer, &value);
    1142                 :    printf ("%d %f : ", ans, value);
    1143                 :    ans = myIsReal_old (buffer, &value);
    1144                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1145                 : 
    1146                 :    strcpy (buffer, "0.95");
    1147                 :    ans = myAtoF (buffer, &value);
    1148                 :    printf ("%d %f : ", ans, value);
    1149                 :    ans = myIsReal_old (buffer, &value);
    1150                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1151                 : 
    1152                 :    strcpy (buffer, "+0.95");
    1153                 :    ans = myAtoF (buffer, &value);
    1154                 :    printf ("%d %f : ", ans, value);
    1155                 :    ans = myIsReal_old (buffer, &value);
    1156                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1157                 : 
    1158                 :    strcpy (buffer, "0.95,  ");
    1159                 :    ans = myAtoF (buffer, &value);
    1160                 :    printf ("%d %f : ", ans, value);
    1161                 :    ans = myIsReal_old (buffer, &value);
    1162                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1163                 : 
    1164                 :    strcpy (buffer, "0.95,");
    1165                 :    ans = myAtoF (buffer, &value);
    1166                 :    printf ("%d %f : ", ans, value);
    1167                 :    ans = myIsReal_old (buffer, &value);
    1168                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1169                 : 
    1170                 :    strcpy (buffer, "0.9.5");
    1171                 :    ans = myAtoF (buffer, &value);
    1172                 :    printf ("%d %f : ", ans, value);
    1173                 :    ans = myIsReal_old (buffer, &value);
    1174                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1175                 : 
    1176                 :    strcpy (buffer, "  alph 0.9.5");
    1177                 :    ans = myAtoF (buffer, &value);
    1178                 :    printf ("%d %f : ", ans, value);
    1179                 :    ans = myIsReal_old (buffer, &value);
    1180                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1181                 : 
    1182                 :    strcpy (buffer, "  ");
    1183                 :    ans = myAtoF (buffer, &value);
    1184                 :    printf ("%d %f : ", ans, value);
    1185                 :    ans = myIsReal_old (buffer, &value);
    1186                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1187                 : 
    1188                 :    strcpy (buffer, "");
    1189                 :    ans = myAtoF (buffer, &value);
    1190                 :    printf ("%d %f : ", ans, value);
    1191                 :    ans = myIsReal_old (buffer, &value);
    1192                 :    printf ("%d %f : '%s'\n", ans, value, buffer);
    1193                 : 
    1194                 :    tail = NULL;
    1195                 :    FileTail ("test\\me/now", &tail);
    1196                 :    printf ("%s \n", tail);
    1197                 :    free (tail);
    1198                 :    tail = NULL;
    1199                 :    FileTail ("test/me\\now", &tail);
    1200                 :    printf ("%s \n", tail);
    1201                 :    free (tail);
    1202                 : 
    1203                 :    strcpy (buffer, "  here  ");
    1204                 :    strTrim (buffer);
    1205                 :    printf ("%s\n", buffer);
    1206                 : 
    1207                 :    strcpy (buffer, "  here  ");
    1208                 :    strCompact (buffer, ' ');
    1209                 :    printf ("'%s'\n", buffer);
    1210                 :    return 0;
    1211                 : }
    1212                 : #endif

Generated by: LCOV version 1.7