home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / zoo141_c.lzh / PARSE.C < prev    next >
C/C++ Source or Header  |  1987-02-07  |  6KB  |  190 lines

  1. /* parse.c */
  2. /*
  3. The contents of this file are hereby released to the public domain.
  4.  
  5.                                  -- Rahul Dhesi 1986/11/14
  6.  
  7. */
  8.  
  9. #include "options.h"
  10. #include "zoo.h"
  11. #include <stdio.h>
  12. #include "various.h"
  13. #include "zoofns.h"
  14.  
  15. #include "parse.h"
  16. #include "assert.h"
  17.  
  18. /*
  19. parse() accepts a filename and return its component parts in a structure.
  20. The component parts are:  disk, path prefix, root name of filename, and
  21. extension.  
  22.  
  23. If the symbol PORTABLE is not defined, parsing assumes an MS-DOS syntax 
  24. pathspec.  All component parts listed above are looked for.
  25.  
  26. If the symbol PORTABLE is defined, a null string is returned in the
  27. disk field.
  28. */
  29. void parse (path_st, fname)
  30. register struct path_st *path_st;
  31. char *fname;
  32. {
  33.    char tempname[LFNAMESIZE];       /* working copy of supplied fname */
  34.    char *namep;                   /* points to relevant part of tempname */
  35.  
  36.    char *p;
  37.    strcpy (tempname, fname);
  38.  
  39. #ifdef DEBUG
  40. printf ("parse:  supplied name is [%s].\n", tempname);
  41. #endif
  42.  
  43. #ifdef PORTABLE
  44.    path_st->drive[0] = '\0';
  45.    namep = tempname;           /* points to pathname+filename */
  46. #else
  47.    path_st->drive[0] = '\0';
  48.    p = strchr (tempname, ':');      /* point to first ':' */
  49.  
  50.    if (p != NULL) {
  51.       path_st->drive[0] = *tempname;/* use only first char of drive name */
  52.       path_st->drive[1] = ':';
  53.       path_st->drive[2] = '\0';
  54.       namep = ++p;                /* point to pathname+filename */
  55.    } else {
  56.       path_st->drive[0] = '\0';
  57.       namep = tempname;           /* points to pathname+filename */
  58.    }
  59. #endif /* end of not PORTABLE */
  60.    
  61.    /* Note:  findlast() finds last occurrence in the subject string of 
  62.       any one of a set of chars */
  63.  
  64.    /* save the long filename */
  65.    p = findlast (namep, PATH_SEP);
  66.  
  67.    /* if path separator found, copy next char onwards; else entire string */
  68.    strncpy (path_st->lfname,
  69.                (p != NULL) ? p+1 : namep,
  70.                LFNAMESIZE);
  71.    path_st->lfname[LFNAMESIZE-1] = '\0';     /* force null termination */
  72.  
  73. #ifdef DEBUG
  74. printf ("parse:  path = [%s] long filename = [%s]\n", 
  75.          namep, path_st->lfname);
  76. #endif
  77.  
  78.    /* Separate out the extension */
  79.    {  
  80.       char extch[2];    /* not static to minimize data space */
  81.       extch[0] = EXT_CH;
  82.       extch[1] = '\0';
  83.       p = findlast (namep, extch);
  84.    }
  85.  
  86. #ifdef DEBUG
  87. if (p == NULL)
  88.    printf ("parse:  no extension found for [%s]\n", namep);
  89. else
  90.    printf ("parse:  extension for [%s] is [%s]\n", namep, p);
  91. #endif
  92.    
  93.    path_st->ext[0] = '\0';                      /* assume no extension  */
  94.    if (p != NULL) {                             /* found extension      */
  95.       strncpy (path_st->ext, (p+1), EXTLEN);    /* save extension       */
  96.       path_st->ext[EXTLEN] = '\0';              /* force termination    */
  97.       *p = '\0';                                /* null out extension   */
  98.    }
  99.  
  100.    /* separate out root of filename if any */
  101.    p = findlast (namep, PATH_SEP);
  102.  
  103.    if (p != NULL) {
  104.       ++p;
  105.       strncpy (path_st->fname, p, ROOTSIZE);  /* save filename        */
  106.       *p = '\0';               /* null out filename */
  107.    } else {
  108.       strncpy (path_st->fname, namep, ROOTSIZE);
  109.       *namep = '\0';                   /* null out filename    */
  110.    }
  111.    path_st->fname[ROOTSIZE] = '\0';           /* force termination    */
  112.  
  113.    /* what remains, whether null or not, is the path prefix */
  114.    path_st->dir[0] = '\0';             /* in case *namep is '\0' */
  115.  
  116.    strncpy (path_st->dir, namep, PATHSIZE);
  117.  
  118.    /* remove trailing path-separater from directory name, but don't
  119.       remove it if it is also the leading separater */
  120.    { 
  121.       int n;
  122.       n = strlen(path_st->dir);
  123.       if (n != 1)
  124.          path_st->dir[n-1] = '\0';
  125.    }
  126.  
  127. #ifdef DEBUG
  128. printf ("parse:  path prefix = [%s].\n", namep);
  129. #endif
  130.    /* if extension is null, and if long filename contains more than
  131.       ROOTSIZE  characters, transfer some of them to extension */
  132.    if (path_st->ext[0] == '\0' && strlen(path_st->lfname) > ROOTSIZE) {
  133.       strncpy(path_st->ext, &path_st->lfname[ROOTSIZE], EXTLEN);
  134.       path_st->ext[3] = '\0';
  135.    }
  136. }
  137.  
  138. /*******************/
  139. /* 
  140. findlast() finds last occurrence in provided string of any of the characters
  141. except the null character in the provided set.
  142.  
  143. If found, return value is pointer to character found, else it is NULL.
  144. */
  145.  
  146. char *findlast (str, set)
  147. register char *str;        /* subject string     */
  148. char *set;                 /* set of characters to look for */
  149.  
  150. {
  151.    register char *p;
  152.  
  153.    if (str == NULL || set == NULL || *str == '\0' || *set == '\0')
  154.       return (NULL);
  155.  
  156.    p = lastptr (str);   /* pointer to last char of string */
  157.    assert(p != NULL);
  158.  
  159.    while (p != str && strchr (set, *p) == NULL) {
  160.       --p;
  161.    }                 
  162.  
  163.    /* either p == str or we found a character or both */
  164.    if (strchr (set, *p) == NULL)
  165.       return (NULL);
  166.    else
  167.       return (p);
  168. }
  169.  
  170. /*******************/
  171. /*
  172. lastptr() returns a pointer to the last non-null character in the string, if
  173. any.  If the string is null it returns NULL
  174. */
  175.  
  176. char *lastptr (str)
  177. register char *str;                 /* string in which to find last char */
  178. {
  179.    register char *p;
  180.    if (str == NULL)
  181.       prterror ('f', "lastptr:  received null pointer\n");
  182.    if (*str == '\0')
  183.       return (NULL);
  184.    p = str;
  185.    while (*p != '\0')            /* find trailing null char */
  186.       ++p;
  187.    --p;                          /* point to just before it */
  188.    return (p);
  189. }
  190.