⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filmatch.c

📁 一个开源著名的TDE编辑器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* EPSHeader   File: filmatch.c   Author: J. Kercheval   Created: Thu, 03/14/1991  22:22:01*//* EPSRevision History   J. Kercheval  Wed, 02/20/1991  22:29:01  Released to Public Domain   J. Kercheval  Fri, 02/22/1991  15:29:01  fix '\' bugs (two :( of them)   J. Kercheval  Sun, 03/10/1991  19:31:29  add error return to matche()   J. Kercheval  Sun, 03/10/1991  20:11:11  add is_valid_pattern code   J. Kercheval  Sun, 03/10/1991  20:37:11  beef up main()   J. Kercheval  Tue, 03/12/1991  22:25:10  Released as V1.1 to Public Domain   J. Kercheval  Thu, 03/14/1991  22:22:25  remove '\' for DOS file parsing   J. Kercheval  Thu, 03/28/1991  20:58:27  include filmatch.h   Jason Hood, 1 August, 1997 - removed error testing in matche()               4 August, 1997 - included TDE stuff, case testing                                renamed match() to wildcard()              10 August, 1997 - case testing in [] (oops)              31 July, 2005   - match multiple patterns and exclusions*//*   Wildcard Pattern Matching*/#include "tdestr.h"#include "tdefunc.h"#include "common.h"/* * jmh 990505: Make UNIX always case sensitive, DOS always case insensitive. */#if defined( __UNIX__ )#define bj_tolower( ch ) ch#endifint matche_after_star (register char *pattern, register char *text);/*----------------------------------------------------------------------------** Return TRUE if PATTERN has any special wildcard characters*----------------------------------------------------------------------------*/BOOLEAN is_pattern (char *p){    while ( *p ) {        switch ( *p++ ) {            case '?':            case '*':            case '[':            case '!':            case ';':#if defined( __UNIX__ )            case ':':#endif                return TRUE;        }    }    return FALSE;}/*----------------------------------------------------------------------------** Return TRUE if PATTERN has is a well formed regular expression according* to the above syntax** error_type is a return code based on the type of pattern error.  Zero is* returned in error_type if the pattern is a valid one.  error_type return* values are as follows:**   PATTERN_VALID - pattern is well formed*   PATTERN_RANGE - [..] construct has a no end range in a '-' pair (ie [a-])*   PATTERN_CLOSE - [..] construct has no end bracket (ie [abc-g )*   PATTERN_EMPTY - [..] construct is empty (ie [])*----------------------------------------------------------------------------*/BOOLEAN is_valid_pattern (char *p, int *error_type){        /* init error_type */    *error_type = PATTERN_VALID;        /* loop through pattern to EOS */    while( *p ) {        /* determine pattern type */        switch( *p ) {            /* the [..] construct must be well formed */            case '[':                p++;                /* if the next character is ']' then bad pattern */                if ( *p == ']' ) {                    *error_type = PATTERN_EMPTY;                    return FALSE;                }                                /* if end of pattern here then bad pattern */                if ( !*p ) {                    *error_type = PATTERN_CLOSE;                    return FALSE;                }                /* loop to end of [..] construct */                while( *p != ']' ) {                    /* check for literal escape */                    if( *p == '\\' ) {                        p++;                        /* if end of pattern here then bad pattern */                        if ( !*p++ ) {                            *error_type = PATTERN_ESC;                            return FALSE;                        }                    }                    else                        p++;                    /* if end of pattern here then bad pattern */                    if ( !*p ) {                        *error_type = PATTERN_CLOSE;                        return FALSE;                    }                    /* if this a range */                    if( *p == '-' ) {                        /* we must have an end of range */                        if ( !*++p || *p == ']' ) {                            *error_type = PATTERN_RANGE;                            return FALSE;                        }                        else {                            /* check for literal escape */                            if( *p == '\\' )                                p++;                            /* if end of pattern here then bad pattern */                            if ( !*p++ ) {                                *error_type = PATTERN_ESC;                                return FALSE;                            }                        }                    }                }                break;            /* all other characters are valid pattern elements */            case '*':            case '?':            default:                p++;                              /* "normal" character */                break;         }     }     return TRUE;}/*----------------------------------------------------------------------------**  Match the pattern PATTERN against the string TEXT;**  returns MATCH_VALID if pattern matches, or an errorcode as follows*  otherwise:**            MATCH_PATTERN  - bad pattern*            MATCH_RANGE    - match failure on [..] construct*            MATCH_ABORT    - premature end of text string*            MATCH_END      - premature end of pattern string*            MATCH_VALID    - valid match***  A match means the entire string TEXT is used up in matching.**  In the pattern string:*       `*' matches any sequence of characters (zero or more)*       `?' matches any character*       [SET] matches any character in the specified set,*       [!SET] or [^SET] matches any character not in the specified set.*       \ is allowed within a set to escape a character like ']' or '-'**  A set is composed of characters or ranges; a range looks like*  character hyphen character (as in 0-9 or A-Z).  [0-9a-zA-Z_] is the*  minimal set of characters allowed in the [..] pattern construct.*  Other characters are allowed (ie. 8 bit characters) if your system*  will support them.**  To suppress the special syntactic significance of any of `[]*?!^-\',*  within a [..] construct and match the character exactly, precede it*  with a `\'.*----------------------------------------------------------------------------*/int matche ( register char *p, register char *t ){    register char range_start, range_end;  /* start and end in range */    BOOLEAN invert;             /* is this [..] or [!..] */    BOOLEAN member_match;       /* have I matched the [..] construct? */    for ( ; *p; p++, t++ ) {        /* if this is the end of the text then this is the end of the match */        if (!*t) {            return ( *p == '*' && *++p == '\0' ) ? MATCH_VALID : MATCH_ABORT;        }        /* determine and react to pattern type */        switch ( *p ) {            /* single any character match */            case '?':                break;            /* multiple any character match */            case '*':                return matche_after_star (p, t);            /* [..] construct, single member/exclusion character match */            case '[': {                /* move to beginning of range */                p++;                /* check if this is a member match or exclusion match */                invert = FALSE;                if ( *p == '!' || *p == '^') {                    invert = TRUE;                    p++;                }                member_match = FALSE;                for ( ;; ) {                    /* if end of construct then loop is done */                    if (*p == ']') {                        break;                    }                    /* matching a '!', '^', '-', '\' or a ']' */                    if ( *p == '\\' ) {                        ++p;                    }                    range_start = range_end = *p;                    /* check for range bar */                    if (*++p == '-') {                        /* special character range end */                        if (*p == '\\') {                            ++p;                        }                        /* get the range end */                        range_end = *++p;                        /* move just beyond this range */                        p++;                    }                    range_start = bj_tolower( range_start );                    range_end   = bj_tolower( range_end   );                    /* make sure the range letters have the proper                       relationship to one another before comparison */                    if (range_start > range_end) {                        char temp   = range_start;                        range_start = range_end;                        range_end   = temp;                    }                    /* if the text character is in range then match found. */                    if (bj_tolower( *t ) >= range_start &&                        bj_tolower( *t ) <= range_end) {                        member_match = TRUE;                        break;                    }                }                /* if there was a match in an exclusion set then no match */                /* if there was no match in a member set then no match */                if ((invert && member_match) ||                   !(invert || member_match))                    return MATCH_RANGE;                /* if this is not an exclusion then skip the rest of the [...]                    construct that already matched. */                if (member_match) {                    while (*p != ']') {                        /* skip exact match */                        if (*p == '\\') {                            p++;                        }                        /* move to next pattern char */                        p++;                    }                }                break;            }            /* must match this character exactly */            default:                if (bj_tolower( *p ) != bj_tolower( *t ))                    return MATCH_LITERAL;        }    }    /* if end of text not reached then the pattern fails */    if ( *t )        return MATCH_END;    else        return MATCH_VALID;}/*----------------------------------------------------------------------------** recursively call matche() with final segment of PATTERN and of TEXT.*----------------------------------------------------------------------------*/int matche_after_star (register char *p, register char *t){    register int match = 0;    register char nextp;    /* pass over existing ? and * in pattern */    while ( *p == '?' || *p == '*' ) {        /* take one char for each ? */        if ( *p == '?' ) {            /* if end of text then no match */            if ( !*t++ ) {                return MATCH_ABORT;            }        }        /* move to next char in pattern */        p++;    }    /* if end of pattern we have matched regardless of text left */    if ( !*p ) {        return MATCH_VALID;    }    /* get the next character to match which must be a literal or '[' */    nextp = bj_tolower( *p );    /* Continue until we run out of text or definite result seen */    do {        /* a precondition for matching is that the next character           in the pattern match the next character in the text or that           the next pattern char is the beginning of a range.  Increment           text pointer as we go here */        if (nextp == bj_tolower( *t ) || nextp == '[' )            match = matche(p, t);        /* if the end of text is reached then no match */        if ( !*t++ ) match = MATCH_ABORT;    } while ( match != MATCH_VALID &&               match != MATCH_ABORT);    /* return result */    return match;}/*----------------------------------------------------------------------------** match() is a shell to matche() to return only BOOLEAN values.** jmh 050731: allow it to match multiple patterns, separated by ';', and*              exclusions, separated by '!'.  Use the set notation to treat*              the character literally.*             eg: "!*.exe;*.com" will match all files except .EXE & .COM.*                 "!*.*" will match files with no extension.*                 "*.txt;*.doc!read*" will match all .TXT & .DOC files,*                 except those starting with READ.*                 "[\!]*" will match all files starting with '!'.*----------------------------------------------------------------------------*/BOOLEAN wildcard( char *p, char *t ){int  error_type;char *alt;                      /* alternative */char *exc;                      /* exclusion */int  falt, fexc;                /* found ... */BOOLEAN inverted = FALSE;       /* matching exclusion rather than pattern */int  rc;   if (!is_valid_pattern( p, &rc ))      return( FALSE );   for (exc = p; *exc && *exc != '!'; ++exc) {      if (*exc == '[') {         do {            if (*++exc == '\\')               exc += 2;         } while (*exc != ']');      }   }   fexc = *exc;   *exc = '\0';   if (exc == p && fexc)      p = "*";   rc = FALSE;   do {      for (alt = p; *alt && *alt != ';'#if defined( __UNIX__)                                        && *alt != ':'#endif                                                      ; ++alt) {         if (*alt == '[') {            do {               if (*++alt == '\\')                  alt += 2;            } while (*alt != ']');         }      }      falt = *alt;      if (falt)                 /* prevent modifying the static string */         *alt = '\0';      error_type = matche( p, t );      if (falt)         *alt = falt;      if (error_type == MATCH_VALID) {         if (inverted) {            rc = FALSE;            break;         }         rc = TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -