📄 wildmat.c
字号:
/*** Do shell-style pattern matching for ?, \, [], and * characters.** Might not be robust in face of malformed patterns; e.g., "foo[a-"** could cause a segmentation violation. It is 8bit clean.**** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.** Special thanks to Lars Mathiesen for the ABORT code. This can greatly** speed up failing wildcard patterns. For example:** pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*** text 1: -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1** text 2: -adobe-courier-bold-o-normal--12-120-75-75-p-70-iso8859-1** Text 1 matches with 51 calls, while text 2 fails with 54 calls. Without** the ABORT, then it takes 22310 calls to fail. Ugh.**** bernie 613-01 91/01/04 19:34** Fixed problem with terminating * not matching with (null)**** bernie 597-00 91/01/08 11:24** Fixed shell glob negate from '^' to '!'**** bernie 597-02 91/01/21 13:43** Fixed . matching * or ? on first char.**** jseymour 91/02/05 22:56 ** Fixed problems with ill-formed sets in pattern yielding false** matches. Should now be robust in such cases (not all possibilities** tested - standard disclaimer). Added stand-alone debug code.**** jseymour 91/03/28 20:50** Re-fixed problems with ill-formed sets in pattern yielding false** matches - one hopes correctly this time.**** jseymour 1998/04/04 17:45 EST** Before adding this to minicom (as part of my "getsdir()" addition),** I emailed a request to Rich $alz, asking if I could "GPL" it. Here** is his reply:**** Date: Mon, 30 Mar 1998 10:50:06 -0500 (EST)** Message-Id: <199803301550.KAA14018@<anonymized>.com>** From: Rich Salz <salzr@<anonymized>.com>** To: jseymour@jimsun.LinxNet.com** Subject: Re: A Little Thing Named "Wildmat"**** Wildmat is in the public domain -- enjoy it.**** I would rather it not get encumbered with various licenses,** but since it is in the public domain you can do what you want...**** So there you go. (I anonymized his email address as I don't know** that he was particularly interested in having it "advertised".)*/#include "port.h" /* from minicom: for needed for _PROTO macro only */#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endif#define ABORT -1_PROTO(static int Star, (char *, char *));_PROTO(static int DoMatch, (char *, char *));_PROTO(extern int wildmat, (char *, char *)); /* pattern matcher */static intStar(s, p)register char *s;register char *p;{ int retval; while ((retval = DoMatch(s, p)) == FALSE) /* gobble up * match */ if (*++s == '\0') return ABORT; return retval;}static intDoMatch(s, p) /* match string "s" to pattern "p" */register char *s;register char *p;{ register int last; register int matched; register int reverse; char *ss; int escaped; for (; *p; s++, p++) { /* parse the string to end */ if (*s == '\0') return *p == '*' && *++p == '\0' ? TRUE : ABORT; switch (*p) { /* parse pattern */ case '\\': /* Literal match with following character. */ p++; /* FALLTHROUGH */ default: /*literal match*/ if (*s != *p) return FALSE; continue; case '?': /* Match anything. */ continue; case '*': /* Trailing star matches everything. */ return (*++p ? Star(s, p) : TRUE); case '[': /* [!....] means inverse character class. */ if ((reverse = (p[1] == '!'))) p++; ss = p + 1; /* set start point */ for (last = 0400, escaped = matched = FALSE; *++p; last = *p) { if (*p == ']' && !(escaped || p == ss)) break; if (escaped) escaped = FALSE; else if (*p == '\\') { escaped = TRUE; continue; } /* This next line requires a good C compiler. */ /* range? (in bounds) (equal) */ if ((*p == '-') ? (*s <= *++p && *s >= last) : (*s == *p)) matched = TRUE; } if (matched == reverse) return FALSE; continue; } } return *s == '\0';}/* * usage: wildmat(string, pattern) * * returns: non-0 on match */int wildmat(s, p)char *s;char *p;{ if ((*p == '?' || *p == '*') && *s == '.') { return FALSE; } else { return DoMatch(s, p) == TRUE; }}#ifdef STAND_ALONE_TEST#include <stdio.h>/* * usage: wildmat <pattern> <test arg(s)> */voidmain(argc, argv)int argc;char *argv[];{ int index; int status = FALSE; for (index = 2; index < argc; ++index) { if (wildmat(argv[index], argv[1])) { if (status) fputs(" ", stdout); printf("%s", argv[index]); status = TRUE; } } printf("%s\n", status ? "" : argv[1]);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -