home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 157.lha / Arc_Src / arcdir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-27  |  7.5 KB  |  358 lines

  1. /*  ARC - Archive utility - ARCDIR
  2.  
  3. System V Version 1.0 based upon:
  4.     Version ?.??, created on ??/??/?? at ??:??:??
  5.  
  6. (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED
  7.  
  8.     By:  Thom Henderson
  9.  
  10.     Description:
  11.          This file contians ...
  12. */
  13. #include "arc.h"
  14.  
  15. #include <sys/types.h>
  16. #include <sys/dir.h>
  17.  
  18. char *pattern;                  /* global so that fmatch can use them */
  19. INT filemode;
  20.  
  21. char *dir(filename,mode,NameList)      /* get files, one by one */
  22. char *filename;                        /* template, or NULL */
  23. INT mode;                              /* search mode bits */
  24. char *(*NameList[]);
  25. {
  26.     return NULL;
  27. }
  28.  
  29.  
  30. #define ASTERISK '*'        /* The '*' metacharacter */
  31. #define QUESTION '?'        /* The '?' metacharacter */
  32. #define LEFT_BRACKET '['    /* The '[' metacharacter */
  33. #define RIGHT_BRACKET ']'    /* The ']' metacharacter */
  34.  
  35. #define IS_OCTAL(ch) (ch >= '0' && ch <= '7')
  36.  
  37. typedef INT BOOLEAN;
  38. #define VOID short
  39. #define TRUE 1
  40. #define FALSE 0
  41. #define EOS '\000'
  42.  
  43. static BOOLEAN do_list ();
  44. static char nextch ();
  45. static VOID list_parse ();
  46.  
  47.  
  48. /*
  49.  *  FUNCTION
  50.  *
  51.  *    match   test string for wildcard match
  52.  *
  53.  *  SYNOPSIS
  54.  *
  55.  *    BOOLEAN match (string, pattern)
  56.  *    register char *string;
  57.  *    register char *pattern;
  58.  *
  59.  *  DESCRIPTION
  60.  *
  61.  *    Test string for match using pattern.  The pattern may
  62.  *    contain the normal shell metacharacters for pattern
  63.  *    matching.  The '*' character matches any string,
  64.  *    including the null string.  The '?' character matches
  65.  *    any single character.  A list of characters enclosed
  66.  *    in '[' and ']' matches any character in the list.
  67.  *    If the first character following the beginning '['
  68.  *    is a '!' then any character not in the list is matched.
  69.  *
  70.  */
  71.  
  72.  
  73. /*
  74.  *  PSEUDO CODE
  75.  *
  76.  *    Begin match
  77.  *        Switch on type of pattern character
  78.  *        Case ASTERISK:
  79.  *            Attempt to match asterisk
  80.  *            Break
  81.  *        Case QUESTION MARK:
  82.  *            Attempt to match question mark
  83.  *            Break
  84.  *        Case EOS:
  85.  *            Match is result of EOS on string test
  86.  *            Break
  87.  *        Case default:
  88.  *            If explicit match then
  89.  *            Match is result of submatch
  90.  *            Else
  91.  *            Match is FALSE
  92.  *            End if
  93.  *            Break
  94.  *        End switch
  95.  *        Return result of match test
  96.  *    End match
  97.  *
  98.  */
  99.  
  100. static BOOLEAN match (string, pattern)
  101. register char *string;
  102. register char *pattern;
  103. {
  104.     register BOOLEAN ismatch;
  105.  
  106.     ismatch = FALSE;
  107.     switch (*pattern) {
  108.     case ASTERISK:
  109.         pattern++;
  110.         do {
  111.         ismatch = match (string, pattern);
  112.         } while (!ismatch && *string++ != EOS);
  113.         break;
  114.     case QUESTION:
  115.         if (*string != EOS) {
  116.         ismatch = match (++string, ++pattern);
  117.         }
  118.         break;
  119.     case EOS:
  120.         if (*string == EOS) {
  121.         ismatch = TRUE;
  122.         }
  123.         break;
  124.     case LEFT_BRACKET:
  125.         if (*string != EOS) {
  126.         ismatch = do_list (string, pattern);
  127.         }
  128.         break;
  129.     default:
  130.         if (tolower(*string) == tolower(*pattern))
  131.         {
  132.             string++;
  133.             pattern++;
  134.         ismatch = match (string, pattern);
  135.         } else {
  136.         ismatch = FALSE;
  137.         }
  138.         break;
  139.     }
  140.     return (ismatch);
  141. }
  142.  
  143.  
  144. /*
  145.  *  FUNCTION
  146.  *
  147.  *    do_list    process a list and following substring
  148.  *
  149.  *  SYNOPSIS
  150.  *
  151.  *    static BOOLEAN do_list (string, pattern)
  152.  *    register char *string;
  153.  *    register char *pattern;
  154.  *
  155.  *  DESCRIPTION
  156.  *
  157.  *    Called when a list is found in the pattern.  Returns
  158.  *    TRUE if the current character matches the list and
  159.  *    the remaining substring matches the remaining pattern.
  160.  *
  161.  *    Returns FALSE if either the current character fails to
  162.  *    match the list or the list matches but the remaining
  163.  *    substring and subpattern's don't.
  164.  *
  165.  *  RESTRICTIONS
  166.  *
  167.  *    The mechanism used to match characters in an inclusive
  168.  *    pair (I.E. [a-d]) may not be portable to machines
  169.  *    in which the native character set is not ASCII.
  170.  *
  171.  *    The rules implemented here are:
  172.  *
  173.  *        (1)    The backslash character may be
  174.  *            used to quote any special character.
  175.  *            I.E.  "\]" and "\-" anywhere in list,
  176.  *            or "\!" at start of list.
  177.  *
  178.  *        (2)    The sequence \nnn becomes the character
  179.  *            given by nnn (in octal).
  180.  *
  181.  *        (3)    Any non-escaped ']' marks the end of list.
  182.  *
  183.  *        (4)    A list beginning with the special character
  184.  *            '!' matches any character NOT in list.
  185.  *            The '!' character is only special if it
  186.  *            is the first character in the list.
  187.  *
  188.  */
  189.  
  190.  
  191. /*
  192.  *  PSEUDO CODE
  193.  *
  194.  *    Begin do_list
  195.  *        Default result is no match
  196.  *        Skip over the opening left bracket
  197.  *        If the next pattern character is a '!' then
  198.  *        List match gives FALSE
  199.  *        Skip over the '!' character
  200.  *        Else
  201.  *        List match gives TRUE
  202.  *        End if
  203.  *        While not at closing bracket or EOS
  204.  *        Get lower and upper bounds
  205.  *        If character in bounds then
  206.  *            Result is same as sense flag.
  207.  *            Skip over rest of list
  208.  *        End if
  209.  *        End while
  210.  *        If match found then
  211.  *        If not at end of pattern then
  212.  *            Call match with rest of pattern
  213.  *        End if
  214.  *        End if
  215.  *        Return match result
  216.  *    End do_list
  217.  *
  218.  */
  219.  
  220. static BOOLEAN do_list (string, pattern)
  221. register char *string;
  222. char *pattern;
  223. {
  224.     register BOOLEAN ismatch;
  225.     register BOOLEAN if_found;
  226.     register BOOLEAN if_not_found;
  227.     auto char lower;
  228.     auto char upper;
  229.  
  230.     pattern++;
  231.     if (*pattern == '!') {
  232.     if_found = FALSE;
  233.     if_not_found = TRUE;
  234.     pattern++;
  235.     } else {
  236.     if_found = TRUE;
  237.     if_not_found = FALSE;
  238.     }
  239.     ismatch = if_not_found;
  240.     while (*pattern != ']' && *pattern != EOS) {
  241.     list_parse (&pattern, &lower, &upper);
  242.     if (*string >= lower && *string <= upper) {
  243.         ismatch = if_found;
  244.         while (*pattern != ']' && *pattern != EOS) {pattern++;}
  245.     }
  246.     }
  247.     if (*pattern++ != ']') {
  248.     fprintf (stderr, "warning - character class error\n");
  249.     } else {
  250.     if (ismatch) {
  251.         ismatch = match (++string, pattern);
  252.     }
  253.     }
  254.     return (ismatch);
  255. }
  256.  
  257.  
  258. /*
  259.  *  FUNCTION
  260.  *
  261.  *    list_parse    parse part of list into lower and upper bounds
  262.  *
  263.  *  SYNOPSIS
  264.  *
  265.  *    static VOID list_parse (patp, lowp, highp)
  266.  *    char **patp;
  267.  *    char *lowp;
  268.  *    char *highp;
  269.  *
  270.  *  DESCRIPTION
  271.  *
  272.  *    Given pointer to a pattern pointer (patp), pointer to
  273.  *    a place to store lower bound (lowp), and pointer to a
  274.  *    place to store upper bound (highp), parses part of
  275.  *    the list, updating the pattern pointer in the process.
  276.  *
  277.  *    For list characters which are not part of a range,
  278.  *    the lower and upper bounds are set to that character.
  279.  *
  280.  */
  281.  
  282. static VOID list_parse (patp, lowp, highp)
  283. char **patp;
  284. char *lowp;
  285. char *highp;
  286. {
  287.     *lowp = nextch (patp);
  288.     if (**patp == '-') {
  289.     (*patp)++;
  290.     *highp = nextch (patp);
  291.     } else {
  292.     *highp = *lowp;
  293.     }
  294. }
  295.  
  296.  
  297. /*
  298.  *  FUNCTION
  299.  *
  300.  *    nextch    determine next character in a pattern
  301.  *
  302.  *  SYNOPSIS
  303.  *
  304.  *    static char nextch (patp)
  305.  *    char **patp;
  306.  *
  307.  *  DESCRIPTION
  308.  *
  309.  *    Given pointer to a pointer to a pattern, uses the pattern
  310.  *    pointer to determine the next character in the pattern,
  311.  *    subject to translation of backslash-char and backslash-octal
  312.  *    sequences.
  313.  *
  314.  *    The character pointer is updated to point at the next pattern
  315.  *    character to be processed.
  316.  *
  317.  */
  318.  
  319. static char nextch (patp)
  320. char **patp;
  321. {
  322.     register char ch;
  323.     register char chsum;
  324.     register INT count;
  325.  
  326.     ch = *(*patp)++;
  327.     if (ch == '\\') {
  328.     ch = *(*patp)++;
  329.     if (IS_OCTAL (ch)) {
  330.         chsum = 0;
  331.         for (count = 0; count < 3 && IS_OCTAL (ch); count++) {
  332.         chsum *= 8;
  333.         chsum += ch - '0';
  334.         ch = *(*patp)++;
  335.         }
  336.         (*patp)--;
  337.         ch = chsum;
  338.     }
  339.     }
  340.     return (ch);
  341. }
  342.  
  343. /*
  344.  *    Filename match - here, *.* matches everything
  345.  */
  346.  
  347. BOOLEAN fmatch (direntry)
  348. struct direct *direntry;
  349. {
  350.     char *ptr,*string;
  351.  
  352.     string = direntry->d_name;
  353.  
  354.     if(!strcmp(pattern, "") || !strcmp(pattern, "*.*"))
  355.         return(1);
  356.     return(match(string, pattern));
  357. }
  358.