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

📄 grep.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
字号:
/*---------------------------------------------------------------------------
 *           GREP.C    a generalized regular expression parser 
 *
 *
 *                Copyright (c) 1984 Allen Holub
 *      Copyright (c) 1984 Software Engineering Consultants
 *                      P.O. Box 5679
 *                   Berkeley, CA.  94705
 *
 *                     All rights reserved.
 *
 *      This program may be copied for personal, non-commmercial use
 *      only, provided that this copyright notice is included in all
 *      copies and that this program is not modified in any way.
 *      Copying for any other use without previously obtaining the 
 *      written permission of the author is prohibited.
 *
 *---------------------------------------------------------------------------
 */

/* 
 *      The algorithm used here is essentially the algorithm in
 *      Software Tools in Pascal (pp 145f.). Though the routines have  
 *      been changed somewhat to put them into good 'C'.
 *
 *      This program is a healthy subset of the UNIX program of the same
 *      name. The differences are as follows:
 *
 *              - the -s, -x, and -b options are not supported.
 *              - the meta-characters ()+? are not supported.
 *
 *      usage is:
 *              grep [-vclnhyef] [expression] files ...
 *
 */

#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include <string.h>
#include "tools.h"

#define MAXLINE 256             /* Maximum size of an input line        */

#define MAX_EXPR 64             /* Maximum number of regular expressions 
 * seperated by newlines or |  allowed
 */
/*      The following global flags are true if a switch was set
 *      on the command line, false otherwise.
 */

int vflag, yflag, cflag, lflag, nflag, hflag, fflag, iflag;
main(argc, argv)int argc;
char **argv;
{
    int i, j, linenum, count;
    char line[MAXLINE], displayline[MAXLINE];
    int numfiles;
    FILE *stream;
    int exprc;

    TOKEN *exprv[MAX_EXPR];

    i = 1;

    if (argc < 2)
        abort(pr_usage(1));
    if (*argv[i] == '-')
     /* command line switches ? */
    {
        expand_sw(argv[i++]);

        if (i == argc)
            abort(pr_usage(1));
    }

    /*      Pattern string          */

    if ((exprc = get_expr(exprv, MAX_EXPR, &argv[i++])) == 0)
        abort(pr_usage(2));

    numfiles = argc - i; /* number of files left to process  */

    fprintf(stderr, "                          \n"); /* opening message */
    while (i < argc)
    {
        if (numfiles)
        {
            stream = fopen(argv[i], "r");
            if (stream == NULL)
            {
                fprintf(stderr, "Can't open %s\n", argv[i++]);
                continue;
            }
        }
        else
            stream = stdin;

        count = 0;
        linenum = 1;

        while (fgets(line, MAXLINE, stream))
        {
            strcpy(displayline, line);
            if (yflag)
             /* MSC routine instead of */
                strupr(line);
             /* stoupper in tools.c    */

            for (j = exprc; --j >= 0;)
            {
                if (matchs(line, exprv[j]))
                {
                    count++;
                    pr_match(linenum, displayline, argv[i], 1, numfiles);
                }
                else
                    pr_match(linenum, displayline, argv[i], 0, numfiles);
                linenum++;
            }
            if (lflag && count)
                break;
        }
        pr_count(numfiles, argv[i], count);
        fclose(stream);
        i++;
    };
    abort();
}

/* ----------------------------------------------------------------------- */

pr_count(fcount, fname, count)int fcount, count;
char *fname;
{
    if (!cflag)
        return 0;
    if (fcount > 1)
        printf("%-12s: ", fname);
    printf("%d\n", count);
}

/* ----------------------------------------------------------------------- */

pr_match(linenum, line, fname, match, numfiles)int linenum, match, numfiles;
char *line,  *fname;
{
    char buf[80];

    if (cflag)
        return 0;
    if ((vflag && !match) || (!vflag && match))
    {
        if (!hflag && ((numfiles > 1) || lflag))
            printf("%s", fname);
        if (lflag)
            printf("\n");
        else
        {
            if (nflag)
                printf("(%03d)", linenum);
            printf(":%s", line);
        }
    }
}

/* ----------------------------------------------------------------------- */

pr_usage(num)int num;
{
    #ifdef DEBUG
        fprintf(stderr, "%d ", num);
    #endif 
    fprintf(stderr, "usage: grep [-cefhlnvy] [expression] <files...>\n");
}

/* ----------------------------------------------------------------------- */

abort()
{
    exit();
}

/* ----------------------------------------------------------------------- */

expand_sw(str)char *str;
{
    vflag = 0;
    cflag = 0;
    lflag = 0;
    nflag = 0;
    hflag = 0;
    fflag = 0;
    yflag = 0;

    while (*str)
    {
        switch (toupper(*str))
        {
            case '-':
            case 'E':
                break;
            case 'C':
                cflag = 1;
                break;
            case 'F':
                fflag = 1;
                break;
            case 'H':
                hflag = 1;
                break;
            case 'I':
                iflag = 1;
                break;
            case 'L':
                lflag = 1;
                break;
            case 'N':
                nflag = 1;
                break;
            case 'V':
                vflag = 1;
                break;
            case 'Y':
                yflag = 1;
                break;
            default:
                pr_usage(3);
                abort();
                break;
        }
        str++;
    }
}

/* ----------------------------------------------------------------------- */

int do_or(lp, expr, max)char *lp;
TOKEN **expr;
int max;
{
    int found;
    TOKEN *pat;
    char *op;

    found = 0;

    /* 
     *      Extract regular expressions seperated by OR_SYM's from
     *      lp and put them into expr. Extract only up to max 
     *      expressions. If yflag is true map string to uppercase first
     */


    if (yflag)
        strupr(lp);

    while (op = in_string(OR_SYM, lp))
    {
        if (found <= max && (pat = makepat(lp, OR_SYM, iflag)))
        {
            *expr++ = pat;
            found++;
        }
        lp = ++op;
        if (pat == 0)
            goto fatal_err;
    }

    if (found <= max && (pat = makepat(lp, OR_SYM, iflag)))
    {
        found++;
        *expr = pat;
    }

    if (pat == 0)
    {
        fatal_err: printf("Illegal expression\n");
        exit();
    }
    return (found);
}

/* ----------------------------------------------------------------------- */

get_expr(expr, max, defexpr)TOKEN *expr[];
int max;
char **defexpr;
{
    FILE *stream;
    int count;
    char line[MAXLINE];

    #ifdef DEBUG
        int i;
    #endif 
    /*      Get regular expressions seperated by | or newlines either
     *      out of a file or off the command line depending on whether
     *      the -f flag is set. The expressions are converted into 
     *      pattern templates and pointers to the templates are put into
     *      the array expr[] (which works similar to argv).
     *
     *      Return the number of expressions found (which can be used in
     *      a similar fashion to argc).
     */

    count = 0;

    if (fflag)
    {
        if ((stream = fopen(*defexpr, "r")) == NULL)
        {
            fprintf(stderr, "Can't open %s\n",  *defexpr);
            abort();
        }

        while ((max - count) && fgets(line, MAXLINE, stream))
            count += do_or(line, &expr[count], max - count);

        fclose(stream);
    }
    else
        if (count += do_or(*defexpr, &expr[count], max - count))
             *defexpr = " ";
    #ifdef DEBUG
        for (i = count; --i >= 0;)
        {
            pr_tok(expr[1]);
            printf("------------------------------------\n");
        }
    #endif 
    return (count);
}

//-------------------------------------------------------------------------

⌨️ 快捷键说明

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