home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / smapp100.zip / sm10.zip / smggenrl.c < prev    next >
C/C++ Source or Header  |  2000-05-14  |  35KB  |  1,336 lines

  1. /* ------------------------------------------------------------------------
  2.  *
  3.  *        File: smggenrl.c
  4.  *     Project: Source Mapper.
  5.  *     Created: Mai 20, 1994.
  6.  * Description: This module implements a number of general helper
  7.  *              functions.
  8.  *
  9.  * Copyright (C) 2000 Leif-Erik Larsen.
  10.  * This file is part of the Source Mapper source package.
  11.  * Source Mapper is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published
  13.  * by the Free Software Foundation, in version 2 as it comes in the
  14.  * "COPYING" file of the XWorkplace main distribution.
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * ------------------------------------------------------------------------ */
  21.  
  22.  
  23.  
  24.  
  25. #include "smg.h"
  26.  
  27.  
  28.  
  29.  
  30. #define MAXFILES 16
  31. typedef struct
  32. {
  33.    char name[MAXPATH + 1];             /* Navn til fil */
  34.    int  handle;                        /* Handle nr til aktuelt filnavn */
  35.    int  open;                          /* TRUE hvis record er åpen fil */
  36. }
  37.    FnamesTYPE;
  38.  
  39.  
  40.  
  41.  
  42. static FnamesTYPE Fnames[MAXFILES];
  43.  
  44.  
  45.  
  46.  
  47. static int FILEc = 0;                  /* Antall åpne filer for ¢yeblikket */
  48.  
  49.  
  50.  
  51.  
  52. int ResetFNames ( FILE *stream )
  53. /* Opprettet: Tirsdag 2. mars 1993.
  54.    Parameter: "stream" Fil som skal resettes fra struktur for filnavn.
  55.    Retur    : E/O.
  56.    Beskriv  : Nullstiller oppgitt element til global statisk struktur for
  57.               lagring av filnavn.
  58. */
  59. {
  60.    int c1 = MAXFILES;
  61.  
  62.    while (c1--)                        /* Test alle filnavn i struktur */
  63.    {
  64.       if (Fnames[c1].open   == TRUE &&
  65.           Fnames[c1].handle == fileno (stream)) /* Hvis aktuell fil */
  66.       {
  67.          Fnames[c1].open    =  FALSE;  /* TRUE hvis filhandle er åpen */
  68.          FILEc--;
  69.          return (OK);
  70.       }
  71.    }
  72.  
  73.    return (ERROR);
  74. } /* ResetFNames (); */
  75.  
  76.  
  77.  
  78.  
  79. void ResetAllFNames ( void )
  80. /* Opprettet: Tirsdag 2. mars 1993.
  81.    Parameter:
  82.    Retur    :
  83.    Beskriv  : Nullstiller global statisk struktur for lagring av
  84.               filnavn.
  85. */
  86. {
  87.    int c1 = MAXFILES;
  88.  
  89.    while (c1--)                        /* Alle filnavn i struktur */
  90.       Fnames[c1].open = FALSE;         /* TRUE hvis filhandle er åpen */
  91.  
  92.    FILEc = 0;
  93. } /* ResetAllFNames (); */
  94.  
  95.  
  96.  
  97.  
  98. int SetFNames ( const char *fname, FILE *stream )
  99. /* Opprettet: Tirsdag 2. mars 1993.
  100.    Parameter: "fnames" Navn til fil.
  101.               "stream" Fil som oppgitt filnavn tilh¢rer.
  102.    Retur    : E/O.
  103.    Beskriv  : Lagrer oppgitt filnavn m/handle til global statisk struktur
  104.               for dette.
  105. */
  106. {
  107.    int c1 = MAXFILES;
  108.  
  109.    while (c1--)                        /* Alle filnavn i struktur */
  110.    {
  111.       if (Fnames[c1].open == FALSE)    /* Hvis ledig element her */
  112.       {
  113.          strcpy (Fnames[c1].name, fname); /* Lagre filnavn */
  114.          Fnames[c1].handle = fileno (stream); /* Filhandle til åpen fil */
  115.          Fnames[c1].open   = TRUE;     /* Bekrefter at element er opptatt */
  116.          FILEc++;
  117.          return (OK);                  /* Vellykket lagring av filnavn */
  118.       }
  119.    }
  120.  
  121.    /* Ikke plass til filnavn i struktur */
  122.    return (ERROR);
  123. } /* SetFNames (); */
  124.  
  125.  
  126.  
  127.  
  128. char *GetFNames ( FILE *stream )
  129. /* Opprettet: Tirsdag 2. mars 1993.
  130.    Parameter: "stream" Fil som det skal finnes filnavn til.
  131.    Retur    : NULL hvis feil, ellers aktuelt filnavn.
  132.    Beskriv  : Finner og returnerer filnavn til oppgitt fil.
  133. */
  134. {
  135.    int c1 = MAXFILES;
  136.  
  137.    while (c1--)                        /* Sjekk alle filnavn i struktur */
  138.    {
  139.       if (Fnames[c1].open == TRUE &&   /* Hvis elementet tilh¢rer åpen fil */
  140.           Fnames[c1].handle == fileno (stream)) /* Hvis riktig fil */
  141.       {
  142.          return (Fnames[c1].name);     /* Returner navn til aktuell handle */
  143.       }
  144.    }
  145.  
  146.    return (NULL);                      /* Ulovlig handle */
  147. } /* GetFNames (); */
  148.  
  149.  
  150.  
  151.  
  152. long FLength ( FILE *stream )
  153. /* Opprettet: Onsdag 10. juni 1992.
  154.    Parameter: "stream"  Fil som funksjonen skal finne st¢rrelsen til.
  155.    Retur    : Lengden (antall byte) i oppgitt fil, eller -1L ved feil.
  156.    Beskriv  : Finner og returnerer lengden (antall byte) i oppgitt fil.
  157.               Aktiv filposisjon vil forbli uforandret ved retur.
  158. */
  159. {
  160.    long curpos, length;
  161.  
  162.    errno = 0;
  163.    if ((curpos = FTell (stream)) == -1L ||
  164.        !FSeek (stream, 0L, SEEK_END)    ||
  165.        (length = FTell (stream)) == -1L ||
  166.        !FSeek (stream, curpos, SEEK_SET))
  167.    {
  168.       _iErrNo = errno;                 /* Remember error message from system */
  169.       return (-1L);
  170.    }
  171.  
  172.    return (length);
  173. } /* FLength (); */
  174.  
  175.  
  176.  
  177.  
  178. FILE *FOpen ( const char *filename, char *mode )
  179. /* Opprettet: Mandag 8. juni 1992.
  180.    Beskriv  : Se standard funksjon: fopen ();
  181. */
  182. {
  183.    FILE *ret;
  184.    char cMode[6];
  185.  
  186.    #if __IBMC__ || __IBMCPP__
  187.    if (strcmp (mode, "rt") == 0)
  188.       strcpy (cMode, "r");
  189.    else
  190.    if (strcmp (mode, "wt") == 0)
  191.       strcpy (cMode, "w");
  192.    else
  193.       strcpy (cMode, mode);
  194.    #else
  195.    strcpy (cMode, mode);
  196.    #endif
  197.  
  198.    errno = 0;
  199.  
  200.    if ((ret = fopen (filename, cMode)) == NULL)
  201.    {
  202.       _iErrNo = errno;                 /* Remember error message from system */
  203.       return (NULL);
  204.    }
  205.  
  206.    /* Lagre navn til fil som herved er åpnet: */
  207.    if (!SetFNames (filename, ret))
  208.    {
  209.       fclose (ret);
  210.       return NULL;
  211.    }
  212.  
  213.    return (ret);
  214. } /* FOpen (); */
  215.  
  216.  
  217.  
  218.  
  219. int FClose ( FILE *stream )
  220. /* Opprettet: Onsdag 10. juni 1992.
  221.    Beskriv  : Stenger oppgitt stream.
  222.    Return   : E/O.
  223. */
  224. {
  225.    ResetFNames (stream);               /* Fjern filnavn fra filnavn-lager */
  226.  
  227.    errno = 0;
  228.    if (fclose (stream) == 0)
  229.       return (OK);
  230.  
  231.    _iErrNo = errno;                    /* Remember error message from system */
  232.  
  233.    return (ERROR);
  234. } /* FClose (); */
  235.  
  236.  
  237.  
  238.  
  239. int FCloseAll ( void )
  240. /* Opprettet: Fredag 16. oktober 1992.
  241.    Beskriv  : Stenger alle åpne filer, untatt stdin, stdout, stderr, stdaux.
  242.               Returnerer antall filer som ble stengt, eller -1 ved feil.
  243.               Se ellers standard funksjon: fcloseall ();
  244. */
  245. {
  246.    int c1 = MAXFILES;
  247.    int ret = 0;
  248.  
  249.    errno = 0;
  250.    while (c1--)
  251.    {
  252.       if (Fnames[c1].open == TRUE)
  253.       {
  254.          Fnames[c1].open  = FALSE;     /* TRUE hvis filhandle er åpen */
  255.          FILEc--;
  256.          if (close (Fnames[c1].handle) == -1) /* If error */
  257.          {
  258.             _iErrNo = errno;           /* Remember error message from system */
  259.             ret = -1;
  260.          }
  261.       }
  262.    }
  263.  
  264.    return (ret);
  265. } /* FCloseall (); */
  266.  
  267.  
  268.  
  269.  
  270. int FPrintF ( FILE *stream, const char *format, ... )
  271. /* Opprettet: Onsdag 10. juni 1992.
  272.    Beskriv  : Se standard funksjon: fprintf ();
  273.    Return   : E/O.
  274. */
  275. {
  276.    int     ret = OK;
  277.    va_list argp;
  278.  
  279.    va_start (argp, format);
  280.  
  281.    errno = 0;
  282.  
  283.    if ((vfprintf (stream, format, argp) == EOF &&
  284.         errno != 0))
  285.    {
  286.       _iErrNo = errno;                 /* Remember error message from system */
  287.       ret = ERROR;
  288.    }
  289.  
  290.    va_end   (argp);
  291.  
  292.    return (ret);
  293. } /* FPrintF (); */
  294.  
  295.  
  296.  
  297.  
  298. size_t FWrite ( const void *ptr, size_t size, size_t n, FILE *stream )
  299. /* Opprettet: Onsdag 10. juni 1992.
  300.    Beskriv  : Se standard funksjon: fwrite ();
  301. */
  302. {
  303.    size_t Ret;
  304.  
  305.    errno = 0;
  306.  
  307.    if ((Ret = fwrite (ptr, size, n, stream)) != n)
  308.       _iErrNo = errno;                 /* Remember error message from system */
  309.  
  310.    return Ret;
  311. } /* FWrite (); */
  312.  
  313.  
  314.  
  315.  
  316. size_t FRead ( void *ptr, size_t size, size_t n, FILE *stream )
  317. /* Opprettet: Onsdag 10. juni 1992.
  318.    Beskriv  : Se standard funksjon: fread ();
  319. */
  320. {
  321.    size_t Ret;
  322.  
  323.    errno = 0;
  324.  
  325.    if ((Ret = fread (ptr, size, n, stream)) != n)
  326.    {
  327.       if (feof (stream))
  328.       {
  329.          errno = 0;
  330.          _iErrNo = 0;
  331.       }
  332.       else
  333.       {
  334.          _iErrNo = errno;              /* Remember error message from system */
  335.       }
  336.    }
  337.  
  338.    return Ret;
  339. } /* FRead (); */
  340.  
  341.  
  342.  
  343.  
  344. int FGetS ( char *string, int maxlen, FILE *stream )
  345. /* Opprettet: Fredag 16. oktober 1992.
  346.    Beskriv  : Leser en karakterstreng fra stream.
  347.               Karakterer leses inntill en ny-linje karakter, eller inntill
  348.               maxlen antall tegn.
  349.    Return   : E/O.
  350. */
  351. {
  352.    errno = 0;
  353.    if (fgets (string, maxlen, stream) == NULL)
  354.    {
  355.       if (feof (stream))
  356.       {
  357.          errno = 0;
  358.          _iErrNo = 0;
  359.       }
  360.       else
  361.       {
  362.          _iErrNo = errno;   /* Remember error message from system */
  363.       }
  364.       return (ERROR);
  365.    }
  366.  
  367.    return (OK);
  368. } /* FGetS (); */
  369.  
  370.  
  371.  
  372.  
  373. int FGetS0 ( char *string, int maxlen, FILE *stream )
  374. /*
  375.     Function: Get a null-terminated string from stream.
  376.      Created: April, 22. 1993. 02:40. By Leif-Erik Larsen.
  377.    Interface: string = Buffer of where to store the string.
  378.               maxlen = Max number of characters to read.
  379.               stream = Stream of where to do the reading.
  380.      Returns: E/O.
  381.      Comment: The string will be terminated with a null-character.
  382.               Therefore, the max number of characters actually read into
  383.               string buffer will be 'maxlen' - 1. This because
  384.               the null-character it self allso is stored in the string.
  385. */
  386. {
  387.    char chr;                           /* To temporary store the red char    */
  388.  
  389.    errno = 0;
  390.    while (--maxlen)                    /* Read max 'maxlen' - 1 characters   */
  391.    {
  392.       /* Read next character from stream */
  393.       if (fread (&chr, sizeof (char), 1, stream) != 1)
  394.       {
  395.          _iErrNo = errno;              /* Remember error message from system */
  396.          return (ERROR);
  397.       }
  398.  
  399.       *string++ = chr;                 /* Copy the red character into string */
  400.  
  401.       if (chr == '\0')                 /* The red character a null-char?     */
  402.          break;                        /* Yes, so stop reading string        */
  403.    }
  404.  
  405.    return (OK);
  406. } /* FGetS0 (); */
  407.  
  408.  
  409.  
  410.  
  411. int Remove ( const char *filename )
  412. /* Opprettet: Onsdag 10. juni 1992.
  413.    Beskriv  : Sletter oppgitt fil.
  414.    Return   : E/O.
  415. */
  416. {
  417.    errno = 0;
  418.  
  419.    if (unlink (filename) == -1)
  420.    {
  421.       _iErrNo = errno;                 /* Remember error message from system */
  422.       return (ERROR);
  423.    }
  424.  
  425.    return (OK);
  426. } /* Remove (); */
  427.  
  428.  
  429.  
  430.  
  431. long FTell ( FILE *stream )
  432. /* Opprettet: Onsdag 10. juni 1992.
  433.    Beskriv  : Se standard funksjon: ftell ();
  434.               Returnerer -1L ved feil, ellers aktiv filposisjon til "stream".
  435. */
  436. {
  437.    long lRet;
  438.  
  439.    errno = 0;
  440.  
  441.    if ((lRet = ftell (stream)) == -1L)
  442.       _iErrNo = errno;                 /* Remember error message from system */
  443.  
  444.    return lRet;
  445. } /* FTell (); */
  446.  
  447.  
  448.  
  449.  
  450. int FSeek ( FILE *stream, long offset, int whence )
  451. /* Opprettet: Onsdag 10. juni 1992.
  452.    Beskriv  : Se standard funksjon: fseek ();
  453.    Return   : E/O.
  454. */
  455. {
  456.    errno = 0;
  457.    if (fseek (stream, offset, whence) != 0)
  458.    {
  459.       _iErrNo = errno;                 /* Remember error message from system */
  460.       return (ERROR);
  461.    }
  462.  
  463.    return (OK);
  464. } /* FSeek (); */
  465.  
  466.  
  467.  
  468.  
  469. int Rewind ( FILE *stream )
  470. /* Opprettet: Onsdag 10. juni 1992.
  471.    Beskriv  : Plasserer filpeker til stream tilbake til f¢rste byte.
  472.    Return   : E/O.
  473. */
  474. {
  475.    return FSeek (stream, 0, SEEK_SET);
  476. } /* Rewind (); */
  477.  
  478.  
  479.  
  480.  
  481. int FPutC ( FILE *stream, char c )
  482. /* Opprettet: L¢rdag 12. september 1992.
  483.    Beskriv  : Skriver en karakter til stream.
  484.    Return   : E/O.
  485. */
  486. {
  487.    errno = 0;
  488.    if (fwrite (&c, sizeof (char), 1, stream) != 1)
  489.    {
  490.       _iErrNo = errno;                 /* Remember error message from system */
  491.       return (ERROR);
  492.    }
  493.  
  494.    return (OK);
  495. } /* FPutC (); */
  496.  
  497.  
  498.  
  499.  
  500. int FGetL ( FILE *stream, long *l )
  501. /*
  502.         Function: Read a long integer from stream.
  503.    Programmed by: LEL
  504.             Date: April, 22. 1993. 00:50.
  505.        Interface: stream = Stream to read from.
  506.                   l      = Store red long here.
  507.          Returns: E/O.
  508. */
  509. {
  510.    errno = 0;
  511.    if (fread (l, sizeof (long), 1, stream) != 1)
  512.    {
  513.       _iErrNo = errno;                 /* Remember error message from system */
  514.       return (ERROR);
  515.    }
  516.  
  517.    return (OK);
  518. } /* FGetL (); */
  519.  
  520.  
  521.  
  522.  
  523. int FPutL ( FILE *stream, long l )
  524. /*
  525.     Function: Write a long integer to stream.
  526.      Created: April 22, 1993. 00:50. By Leif-Erik Larsen.
  527.    Interface: stream = Stream to write to.
  528.               l      = Write this long integer.
  529.      Returns: E/O.
  530. */
  531. {
  532.    errno = 0;
  533.    if (fwrite (&l, sizeof (long), 1, stream) != 1)
  534.    {
  535.       _iErrNo = errno;                 /* Remember error message from system */
  536.       return (ERROR);
  537.    }
  538.  
  539.    return (OK);
  540. } /* FPutL (); */
  541.  
  542.  
  543.  
  544.  
  545. int WritFLine ( FILE *file, int count, char chr )
  546. /*
  547.     Function: Write 'count' number of 'chr' to open 'file'.
  548.      Created: September 12, 1992. By Leif-Erik Larsen.
  549.    Interface: file  = File of where to write.
  550.               count = Number of characters to write.
  551.               char  = Character to write.
  552.      Returns: Number of actual written characters (== 'count' on success).
  553. */
  554. {
  555.    register int c1;
  556.  
  557.    errno = 0;
  558.    for (c1 = 0; count > 0; count--, c1++)
  559.    {
  560.       if (fwrite (&chr, sizeof (char), 1, file) != 1)
  561.       {
  562.          _iErrNo = errno;              /* Remember error message from system */
  563.          return (c1);
  564.       }
  565.    }
  566.    return (c1);
  567. } /* WritFLine (); */
  568.  
  569.  
  570.  
  571.  
  572. int WritFLineLn ( FILE *file, int count, char chr )
  573. /* Opprettet den 12/09/92, av LEL.
  574. Beskrivelse:
  575.    Skriver "count" antall av "chr" til den åpne filen "file", og
  576.    avslutter med linjeskift.
  577.    Returnerer antall faktiske skrivde tegn ("count" + 2). */
  578. {
  579.    int c;
  580.  
  581.    if ((c = WritFLine (file, count, chr)) != count)
  582.       return (c);
  583.  
  584.    FPrintF (file, "\n");
  585.  
  586.    return (c + 2);
  587. } /* WritFLineLn (); */
  588.  
  589.  
  590.  
  591.  
  592. int GetFileTime ( const char *filename, timeTYPE *_time )
  593. /* Opprettet den 12/09/92, av LEL.
  594. Beskrivelse:
  595.    Leser dato/tid-stempel til oppgitt fil. Det leste stempelet returneres
  596.    i "_time".
  597. Return:
  598.    E/O. */
  599. {
  600.    #if __IBMC__ || __IBMCPP__
  601.  
  602.    APIRET rc;
  603.    HDIR FindHandle = HDIR_CREATE;
  604.    ULONG ulFindCount = 1;              /* Don't read more than one filename at once */
  605.    FILEFINDBUF3 FFBuff;                /* File Info including size of EA's */
  606.  
  607.    memset (_time, 0, sizeof (*_time));
  608.    rc = DosFindFirst ((char *) filename, &FindHandle,
  609.                       FILE_ARCHIVED | FILE_SYSTEM | FILE_READONLY | FILE_HIDDEN,
  610.                      (PVOID) &FFBuff,
  611.                       sizeof (FFBuff), &ulFindCount, FIL_STANDARD);
  612.    DosFindClose (FindHandle);
  613.    if (rc != NO_ERROR)
  614.       RETURN_ERR;
  615.  
  616.    _time->hund  = 0;
  617.    _time->sec   = FFBuff.ftimeLastWrite.twosecs;
  618.    _time->min   = FFBuff.ftimeLastWrite.minutes;
  619.    _time->hour  = FFBuff.ftimeLastWrite.hours;
  620.    _time->day   = FFBuff.fdateLastWrite.day;
  621.    _time->month = FFBuff.fdateLastWrite.month;
  622.    _time->year  = FFBuff.fdateLastWrite.year;
  623.  
  624.    #else
  625.  
  626.    FILE  *file;
  627.    struct ftime ftime;
  628.  
  629.    memset (_time, 0, sizeof (*_time));
  630.    if ((file = FOpen (filename, "r")) == NULL)
  631.       RETURN_ERR;
  632.    getftime (fileno (file), &ftime);
  633.    FClose (file);
  634.    _time->hund  = 0;
  635.    _time->sec   = ftime.ft_tsec;
  636.    _time->min   = ftime.ft_min;
  637.    _time->hour  = ftime.ft_hour;
  638.    _time->day   = ftime.ft_day;
  639.    _time->month = ftime.ft_month;
  640.    _time->year  = ftime.ft_year;
  641.  
  642.    #endif
  643.  
  644.    return (OK);
  645. } /* GetFileTime (); */
  646.  
  647.  
  648.  
  649.  
  650. int PrintStrTab ( FILE *file, const char *str, int tabw )
  651. /* Opprettet: Mandag 19. april 1993.
  652.    Parameter: "file" Fil hvor den konverterte strengen skal lagres.
  653.               "str"  Streng som skal konverteres f¢r lagring.
  654.               "tabw" Tabulatorbredde.
  655.    Retur    : E/O.
  656.    Beskriv  : F¢r lagring konverteres alle tabulatorer i oppgitt streng til
  657.               vanlige mellomrom.
  658. */
  659. {
  660.    int  tabc = 1;                      /* Count active tab-offset (1..)      */
  661.    char chr;                           /* Store active character             */
  662.  
  663.    while ((chr = *str++) != 0)         /* Loop trough whole string           */
  664.    {
  665.       if (chr == '\t')
  666.       {
  667.          /* Replace spaces with tabs, and write rest of tab-width */
  668.          if (!WritFLine (file, tabw - tabc + 1, ' '))
  669.             return (ERROR);
  670.          tabc = 0;                     /* Reset, since passed a tab-column   */
  671.       }
  672.  
  673.       else                             /* Any character but tab              */
  674.       if (!FPutC (file, chr))          /* Write the character                */
  675.          return (ERROR);
  676.  
  677.       if (tabc++ >= tabw)              /* Tab-offset passed width of tab?    */
  678.          tabc = 1;                     /* Yes, so reset tab-offset           */
  679.    }
  680.  
  681.    return (OK);
  682. } /* PrintStrTab (); */
  683.  
  684.  
  685.  
  686.  
  687. int IsItemInFile ( FILE *file, const char *item, int itlen,
  688.                    long itnr, long *res )
  689. /*
  690.         Date: April, 22. 1993. 17:40. By LEL.
  691.    Interface: file  = File to seek for item.
  692.               item  = Item to se if in file.
  693.               itlen = Number of characters in each block of an item
  694.                       in file (Max 80).
  695.               itnr  = Number of items in file.
  696.               res   = Returns result of the test. 0 if item is not in
  697.                       file, else index number of where the item was
  698.                       found (1..).
  699.      Returns: E/O.
  700.      Comment: Filepointer to 'file' is restored to the same position
  701.               as it was before this function was called.
  702. */
  703. {
  704.    long oldpos;                        /* Original file position             */
  705.    long index = 0;                     /* Count index to active item         */
  706.    char str[81];                       /* Buffer of where to store red item  */
  707.  
  708.    if ((oldpos = FTell (file)) == -1L) /* Get original file position         */
  709.       return (ERROR);
  710.  
  711.    *res = 0;                           /* Default is that item not exist     */
  712.  
  713.    FSeek (file, 0, SEEK_SET);          /* Place file pointer at start of file*/
  714.  
  715.    while (itnr--)                      /* Seek trough all items in file      */
  716.    {
  717.       /* Get next item from file */
  718.       if (FRead (str, itlen, 1, file) != 1)
  719.          return (ERROR);
  720.  
  721.       index += 1;                      /* Count index to active item         */
  722.  
  723.       if (strcmp (item, str) == 0)     /* Compare to see if equal item in fil*/
  724.       {
  725.          *res = index;                 /* Yes, item exist in file            */
  726.          break;                        /* So break seek loop                 */
  727.       }
  728.    }
  729.  
  730.    FSeek (file, oldpos, SEEK_SET);     /* Restore original file position     */
  731.  
  732.    return (OK);
  733. } /* IsItemInFile (); */
  734.  
  735.  
  736.  
  737.  
  738. int FAddDummy ( FILE *file, long chrnr, char value )
  739. /*
  740.         Date: April, 22. 1993. 20:55. By LEL.
  741.    Interface: file  = File to add dummy characters.
  742.               chrnr = Number of characters to add.
  743.               value = Value of characters to add.
  744.      Returns: E/O.
  745. */
  746. {
  747.    while (chrnr-- > 0)
  748.    {
  749.       if (!FPutC (file, value))
  750.          return (ERROR);
  751.    }
  752.  
  753.    return (OK);
  754. } /* FAddDummy (); */
  755.  
  756.  
  757.  
  758.  
  759. char *BigStr ( int nr, ... )
  760. /*
  761.     Function: Join several strings into one single big string.
  762.      Created: Februar, 12. 1991. By LEL.
  763.    Interface: nr  = Number of argument strings in ...
  764.               ... = List of strings to join.
  765.      Returns: A pointer to a buffer holding the joined strings.
  766. */
  767. {
  768.           va_list argp;                /* Pointer to argument                */
  769.    static char    buff[200];
  770.           char   *str;
  771.           int     len = 0;
  772.  
  773.    buff[0] = '\0';
  774.  
  775.    va_start (argp, nr);
  776.  
  777.    for (; nr > 0; nr--)
  778.    {
  779.       str = (char *) va_arg (argp, char*);
  780.  
  781.       len += strlen (str);
  782.       if (len >= 200)
  783.          break;
  784.  
  785.       strcat (buff, str);
  786.    }
  787.  
  788.    va_end (argp);
  789.  
  790.    return (buff);
  791. } /* BigStr (); */
  792.  
  793.  
  794.  
  795.  
  796. char *GetFName ( const char *path )
  797. /*
  798.     Function: Fetch out filename part of specified path.
  799.      Created: June 11, 1992. By Leif-Erik Larsen.
  800.    Interface: path = Path to use.
  801.      Returns: A pointer to the fetched out filename.
  802. */
  803. {
  804.    static char buffer [MAXFILE + MAXEXT + 1];
  805.  
  806.    char file[MAXFILE  + 1];
  807.    char ext [MAXEXT   + 1];
  808.  
  809.    FNSplit (path, NULL, NULL, file, ext);
  810.    strcpy  (buffer, file);
  811.    strcat  (buffer, ext);
  812.  
  813.    return buffer;
  814. } /* GetFName (); */
  815.  
  816.  
  817.  
  818.  
  819. char *GetPath ( const char *path )
  820. /*
  821.     Function: Fetch out directory part of specified path.
  822.               The dir will be returned with an ending backslash (if needed).
  823.      Created: June 11, 1992. By Leif-Erik Larsen.
  824.    Interface: path = Path to use.
  825.      Returns: A pointer to the fetched out directory.
  826. */
  827. {
  828.    static char buffer [MAXDRIVE + MAXDIR + 1];
  829.  
  830.    char drive [MAXDRIVE + 1];
  831.    char dir   [MAXDIR   + 1];
  832.  
  833.    FNSplit (path, drive, dir, NULL, NULL);
  834.    strcpy  (buffer, drive);
  835.    strcat  (buffer, dir);
  836.  
  837.    return buffer;
  838. } /* GetPath (); */
  839.  
  840.  
  841.  
  842.  
  843. int IsWild ( const char *path )
  844. /* Opprettet den 14/09/92, av LEL.
  845.    Beskrivelse:
  846.    Returnerer sann verdi (1) hvis "path" inneholder DOS jokertegn. */
  847. {
  848.    int flags;
  849.  
  850.    flags = FNSplit (path, NULL, NULL, NULL, NULL);
  851.  
  852.    return (flags & WILDCARDS) ? TRUE : FALSE;
  853. } /* IsWild (); */
  854.  
  855.  
  856.  
  857.  
  858. char *Slash ( char *dir )
  859. /*
  860.     Function: Add an ending slash to dir, if neccessary.
  861.      Created: Mai, 26. 1992. By Leif-Erik Larsen.
  862.    Interface: dir = Directory to update.
  863.      Returns: A pointer to dir.
  864. */
  865. {
  866.    if (!*dir)
  867.       return (dir);
  868.  
  869.    if (strlen (dir) >= MAXDIR)
  870.       return (dir);
  871.  
  872.    if (*(dir + strlen (dir) - 1) != DIRSPLITCHR)
  873.       strcat (dir, DIRSPLITSTR);
  874.  
  875.    return (dir);
  876. } /* Slash (); */
  877.  
  878.  
  879.  
  880.  
  881. char *CutFName ( char *path )
  882. /*
  883.     Function: Cut filename (w/extention), if any, from specified path.
  884.      Created: Mai, 27. 1992. By Leif-Erik Larsen.
  885.    Interface: path = Path from where we shall cut the filename and extention.
  886.      Returns: A pointer to the processed path.
  887. */
  888. {
  889.    char drive [MAXDRIVE];
  890.    char dir   [MAXDIR];
  891.  
  892.    FNSplit (path, drive, dir, NULL, NULL);
  893.    strcpy  (path, drive);
  894.    strcat  (path, dir);
  895.    Slash   (path);
  896.  
  897.    return (path);
  898. } /* CutFName (); */
  899.  
  900.  
  901.  
  902.  
  903. char *CutFExt ( char *path )
  904. /* Opprettet den 10/09/92, av LEL.
  905.    Beskrivelse:
  906.    Kutter etternavn-delen av katalogen/filnavnet "path".
  907.    Eventuell gjennværende katalog (m/filnavn) returneres uten '.'.
  908. */
  909. {
  910.    char drive [MAXDRIVE];
  911.    char dir   [MAXDIR];
  912.    char file  [MAXFILE];
  913.  
  914.    FNSplit (path, drive, dir, file, NULL);
  915.    strcpy  (path, drive);
  916.    strcat  (path, dir);
  917.    strcat  (path, file);
  918.  
  919.    return (path);
  920. } /* CutFExt (); */
  921.  
  922.  
  923.  
  924.  
  925. int StrPart ( int nr, int maxlen, char *dest, const char *src, const char *sep )
  926. /*
  927.     Function: Fetch out a string part from specified string. Each part of the
  928.               string must be separated by one or more of the characters
  929.               specified by 'sep', to be identified as a part of the string.
  930.      Created: April, 7. 1992. By LEL.
  931.    Interface: nr     = Index of the string part to fetch out (1..).
  932.               maxlen = Max length of the string to fetch out.
  933.               dest   = Buffer of where to store the fetched string.
  934.               src    = The original string, of where to fetch from.
  935.               sep    = List of separating characters.
  936.      Returns: 0 if we didn't find the indexed string part, or else 1.
  937. */
  938. {
  939.    *dest = 0;
  940.  
  941.    if (nr < 1)                   /* Index must be within legal range (1..) */
  942.       return 0;
  943.  
  944.    maxlen--;                           /* Make room for terminating '\0'   */
  945.  
  946.    while (*src)                        /* Seach for actual string-part     */
  947.    {
  948.       while (nr--)
  949.       {
  950.          while (strchr (sep, *src))    /* Ignore separating characters     */
  951.          {
  952.             if (*src++ == 0)
  953.                 return 0;
  954.          }
  955.  
  956.          if (nr)                       /* Active string is not requested   */
  957.          {
  958.             while (!strchr (sep, *src))
  959.             {
  960.                if (*src++ == 0)
  961.                   return 0;
  962.             }
  963.          }
  964.  
  965.          else                          /* This is the requested string     */
  966.          {
  967.             while (maxlen-- &&         /* Fetch out actual string-part     */
  968.                   !strchr (sep, *src))
  969.             {
  970.                if (*src == 0)
  971.                {
  972.                   *dest = 0;
  973.                   return 1;
  974.                }
  975.                *dest++ = *src++;
  976.             }
  977.  
  978.             *dest = 0;                 /* String-part was too long, so cut */
  979.             return 1;
  980.          }
  981.       }
  982.    }
  983.  
  984.    return 0;                            /* Didn't find requested string    */
  985. } /* StrPart (); */
  986.  
  987.  
  988.  
  989.  
  990. int IsExt ( const char *path )
  991. /*
  992.     Function: Test if filename in path has an extention.
  993.      Created: September, 14. 1992. By Leif-Erik Larsen.
  994.    Interface: path = Path to test.
  995.      Returns: TRUE if path has extention, or else FALSE.
  996. */
  997. {
  998.    return (FNSplit (path, 0, 0, 0, 0) & EXTENSION) ? TRUE : FALSE;
  999. } /* IsExt (); */
  1000.  
  1001.  
  1002.  
  1003.  
  1004. int FNSplit ( const char *path,
  1005.               char *drive, char *dir, char *file, char *ext )
  1006. /*
  1007.     Function: Split path into its components.
  1008.      Created: Juni, 1. 1993. 17:03. By Leif-Erik Larsen.
  1009.    Interface: path  = Path to split.
  1010.               drive = Drive part ("C:").
  1011.               dir   = Dir part ("\TEST\DIR\").
  1012.               file  = File part ("NAME").
  1013.               ext   = Extention part (".EXT").
  1014.      Returns: Flags: DIRECTORY, DRIVE, EXTENSION, FILENAME, WILDCARDS.
  1015. */
  1016. {
  1017.    char  _Drive[MAXDRIVE];
  1018.    char  _Dir  [MAXDIR];
  1019.    char  _File [MAXFILE];
  1020.    char  _Ext  [MAXEXT];
  1021.    char *ptr;
  1022.    char *fileptr;
  1023.    int   c1;
  1024.    int   flag = 0;
  1025.    int   len  = strlen (path);
  1026.  
  1027.    if (drive == NULL) drive = _Drive;
  1028.    if (dir   == NULL) dir   = _Dir;
  1029.    if (file  == NULL) file  = _File;
  1030.    if (ext   == NULL) ext   = _Ext;
  1031.  
  1032.    *drive = *dir = *file = *ext = 0;   /* Empty all strings                  */
  1033.  
  1034.    if (len <= 0 ||                     /* If no path to split                */
  1035.        len >= MAXPATH)
  1036.    {
  1037.       return (0);
  1038.    }
  1039.  
  1040.    if (strchr (path, '*') ||           /* Test if wildchars in path          */
  1041.        strchr (path, '?'))
  1042.    {
  1043.       flag |= WILDCARDS;
  1044.    }
  1045.  
  1046.    if (*(path+len-1) != DIRSPLITCHR && /* Filename if not an ending '\'      */
  1047.        *(path+len-1) != ':')           /* Path can be "C:" (no filename)     */
  1048.    {
  1049.       flag |= FILENAME;
  1050.  
  1051.       /* Seach for the last character before name of file:                   */
  1052.       for (fileptr = (char *) path+len-1;
  1053.            fileptr > path && *(fileptr-1) != DIRSPLITCHR &&
  1054.                              *(fileptr-1) != ':';
  1055.            fileptr--);
  1056.  
  1057.       /* Copy name of file, but do not include the extention:                */
  1058.       for (c1 = 0, ptr = fileptr;
  1059.            c1 < MAXFILE-1 && *ptr && *ptr != '.';
  1060.            c1++)
  1061.       {
  1062.          *file++ = *ptr++;
  1063.       }
  1064.       *file = 0;                       /* Terminate filename with 0-character*/
  1065.  
  1066.       /* Seach to start of extesion, in case filename was to long:           */
  1067.       while (*ptr && *ptr != '.')
  1068.          ptr++;
  1069.  
  1070.       /* Copy extention of file, if any:                                     */
  1071.       if (*ptr == '.')
  1072.       {
  1073.          flag |= EXTENSION;
  1074.          for (c1 = 0; c1 < MAXEXT-1 && *ptr; c1++)
  1075.             *ext++ = *ptr++;
  1076.       }
  1077.       *ext = 0;                        /* Terminate extention with 0-char.   */
  1078.    }
  1079.  
  1080.    else
  1081.    {
  1082.       fileptr = (char *) path + len;
  1083.    }
  1084.  
  1085.    if (fileptr == path)                /* If path consist of only filename   */
  1086.       return (flag);
  1087.  
  1088.    /* Now, we are sure that 'fileptr' points to start of name-part (if any,
  1089.       else 'fileptr' point to the null-terminating character in path.        */
  1090.  
  1091.    if (*(path + 1) == ':')             /* If path specify drive              */
  1092.    {
  1093.       flag |= DRIVE;
  1094.       memcpy (drive, path, 2);
  1095.       *(drive + 2) = 0;                /* Terminate drive with 0-character   */
  1096.       path += 2;
  1097.    }
  1098.  
  1099.    /* Copy dir, if any:                                                      */
  1100.    for (c1 = 0; c1 < MAXDIR-1 && path < fileptr; c1++)
  1101.    {
  1102.       *dir++ = *path++;
  1103.       flag |= DIRECTORY;
  1104.    }
  1105.    *dir = 0;                           /* Terminate dir with 0-character     */
  1106.  
  1107.    return (flag);
  1108. } /* FNSplit (); */
  1109.  
  1110.  
  1111.  
  1112.  
  1113. int StrLenSL ( long value )
  1114. /*
  1115.     Function: Calculate numbers of ascii characters neccessary to display
  1116.               specified long integer value.
  1117.      Created: May 26, 1994. 13:50. By Leif-Erik Larsen.
  1118.    Interface: value = Value to test.
  1119.               radix = 2, 8, 10 or 16.
  1120.      Returns: The calculated number of charactrs.
  1121. */
  1122. {
  1123.    int ret = 1;
  1124.  
  1125.    if (value < 0)
  1126.       ret += 1;                        /* Allso '-' take one character       */
  1127.  
  1128.    while (value /= 10)
  1129.       ret++;
  1130.  
  1131.    return (ret);
  1132. } /* StrLenSL (); */
  1133.  
  1134.  
  1135.  
  1136.  
  1137. int StrLenSI ( int value )
  1138. /*
  1139.     Function: Calculate numbers of ascii characters neccessary to display
  1140.               specified integer value.
  1141.      Created: May 26, 1994. 13:54. By Leif-Erik Larsen.
  1142.    Interface: value = Value to test.
  1143.      Returns: The calculated number of charactrs.
  1144. */
  1145. {
  1146.    int ret = 1;
  1147.  
  1148.    if (value < 0)
  1149.       ret += 1;                        /* Allso '-' take one character       */
  1150.  
  1151.    while (value /= 10)
  1152.       ret++;
  1153.  
  1154.    return (ret);
  1155. } /* StrLenSI (); */
  1156.  
  1157.  
  1158.  
  1159.  
  1160. int CopyNBytes ( FILE *dest, FILE *source, long nr )
  1161. /*
  1162.     Function: Copy specified number of characters from one file to
  1163.               another.
  1164.      Created: April, 21. 1993. 17:20. By Leif-Erik Larsen.
  1165.    Interface: dest   = Copy characters to this file.
  1166.               source = Copy characters from this file.
  1167.               nr     = Number of characters to copy.
  1168.      Returns: E/O.
  1169. */
  1170. {
  1171.    int   readc;
  1172.    void *buff = malloc (4096);         /* Temporary read/write buffer        */
  1173.  
  1174.    if (buff == NULL)                   /* Not enough memory for malloc       */
  1175.    {
  1176.       _iErrNo = errno;                 /* Remember error message from system */
  1177.       return ERROR;
  1178.    }
  1179.  
  1180.    while (nr > 0)
  1181.    {
  1182.       /* Number of bytes to read next */
  1183.       readc = (int) ((nr >= 4096) ? 4096 : nr);
  1184.  
  1185.       /* Read next block from source file */
  1186.       if (FRead (buff, readc, 1, source) != 1)
  1187.       {
  1188.          free (buff);
  1189.          return ERROR;
  1190.       }
  1191.  
  1192.       /* Write read block to destination */
  1193.       if (FWrite (buff, readc, 1, dest) != 1)
  1194.       {
  1195.          free (buff);
  1196.          return ERROR;
  1197.       }
  1198.  
  1199.       nr -= readc;
  1200.    }
  1201.  
  1202.    free (buff);                        /* Give allocated memory back to heap */
  1203.  
  1204.    return (OK);
  1205. } /* CopyNBytes (); */
  1206.  
  1207.  
  1208.  
  1209.  
  1210. int CopyNBytesP ( FILE *dest, FILE *source, long spos, long nr )
  1211. /*
  1212.         Function: Copy specified number of characters from specified
  1213.                   position on source file to another file.
  1214.    Programmed by: LEL
  1215.             Date: April, 21. 1993. 17:20.
  1216.        Interface: dest   = Copy characters to this file.
  1217.                   source = Copy characters from this file.
  1218.                   spos   = Position in source file to start copy from.
  1219.                   nr     = Number of characters to copy.
  1220.          Returns: E/O.
  1221. */
  1222. {
  1223.    /* Place pointer to start copy from */
  1224.    if (!FSeek (source, spos, SEEK_SET))
  1225.       return (ERROR);
  1226.  
  1227.    /* Do the copy */
  1228.    if (!CopyNBytes (dest, source, nr))
  1229.       return (ERROR);
  1230.  
  1231.    return (OK);
  1232. } /* CopyNBytesP (); */
  1233.  
  1234.  
  1235.  
  1236.  
  1237. int GetDisk ( void )
  1238. /*
  1239.     Function: Get the current drive number
  1240.      Created: August, 17. 1993. 10:48. By Leif-Erik Larsen.
  1241.      Returns: The current drive number (0 = A, 1 = B, 2 = C, etc.)
  1242. */
  1243. {
  1244.    #ifdef __BORLANDC__
  1245.    return getdisk ();
  1246.    #elif __IBMC__ || __IBMCPP__
  1247.    return (_getdrive () - 1);
  1248.    #else
  1249.    union REGS regs;
  1250.    regs.h.ah = 0x19;                   /* DOS: Get current disk */
  1251.    int86 (0x21, ®s, ®s);         /* Call DOS */
  1252.    return (regs.h.al);
  1253.    #endif
  1254. } /* GetDisk (); */
  1255.  
  1256.  
  1257.  
  1258.  
  1259. void SetDisk ( int disk )
  1260. /*
  1261.     Function: Set default drive number
  1262.      Created: August, 17. 1993. 16:08. By Leif-Erik Larsen.
  1263.    Interface: disk = Drive number (0 = A, 1 = B, 2 = C, etc.)
  1264.      Returns:
  1265.      Comment:
  1266. */
  1267. {
  1268.    #ifdef __BORLANDC__
  1269.    setdisk (disk);
  1270.    #elif __IBMC__ || __IBMCPP__
  1271.    _chdrive (disk + 1);
  1272.    #else
  1273.    union REGS regs;
  1274.    regs.h.ah = 0x0E;                   /* DOS: Select disk                   */
  1275.    regs.h.dl = disk;
  1276.    int86 (0x21, ®s, ®s);         /* Call DOS                           */
  1277.    #endif
  1278. } /* SetDisk (); */
  1279.  
  1280.  
  1281.  
  1282.  
  1283. void Randomize ( void )
  1284. /*
  1285.     Function: Initializes random number generator.
  1286.      Created: Jule, 6. 1993. 11:55. By Leif-Erik Larsen.
  1287. */
  1288. {
  1289.    time_t t;
  1290.  
  1291.    srand ((unsigned) time (&t));
  1292. } /* Randomize (); */
  1293.  
  1294.  
  1295.  
  1296.  
  1297. int GetCurDir ( int drive, char *directory )
  1298. /*
  1299.     Function: Gets current directory for specified drive.
  1300.      Created: August, 17. 1993. 10:50. By Leif-Erik Larsen.
  1301.    Interface: drive     = Specifies a drive number (0 = default, 1 = A, etc.)
  1302.               directory = Points to an area of memory (of length MAXDIR)
  1303.                           where the null-terminated directory name will be
  1304.                           placed. The name does not contain the drive
  1305.                           specification but it begin and end with a backslash.
  1306.      Returns: On success, returns 0, else returns -1.
  1307. */
  1308. {
  1309.    #ifdef __GNUC__
  1310.    int olddisk = GetDisk ();           /* Remember default drive             */
  1311.  
  1312.    SetDisk (drive ? (drive - 1) : olddisk);
  1313.  
  1314.    if (!getwd (directory))             /* Get current directory              */
  1315.    #elif defined (__BORLANDC__)
  1316.    if (getcurdir (drive, directory) == -1)
  1317.    #endif
  1318.    {
  1319.       strcpy (directory, DIRSPLITSTR);
  1320.       #ifdef __GNUC__
  1321.       SetDisk (olddisk);               /* Restore default drive              */
  1322.       #endif
  1323.       return (-1);
  1324.    }
  1325.  
  1326.    Slash (directory);                  /* Be sure that it is an ending backsl*/
  1327.  
  1328.    #ifdef __GNUC__
  1329.    SetDisk (olddisk);                  /* Restore default drive              */
  1330.    #endif
  1331.  
  1332.    return (0);
  1333. } /* GetCurDir (); */
  1334.  
  1335.  
  1336.