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

📄 ccheck.c

📁 检查 C 源码中括号的匹配性
💻 C
📖 第 1 页 / 共 2 页
字号:
        }
        if (oddsinglequote)
            printf("\tOdd number of single quotes.\n");
        if (bracecnt)
            printf("\t%d too few %s braces.\n", abs(bracecnt), (bracecnt >
              0 ? "closing" : "opening"));
        if (sqbrakcnt)
            printf("\t%d too few %s square brackets.\n", abs(sqbrakcnt), (sqbrak
              > 0 ? "closing" : "opening"));
        if (parencnt)
            printf("\t%d too few %s parentheses.\n", abs(parencnt), (parencnt
              > 0 ? "closing" : "opening"));
        if (errstatus && !i)
            printf("\tPossible error(s), but no net delimiter imbalance.\n");
        putchar('\n');
    } while (++file_index < argc);

    exit(errstatus ? 2 : wstatus);
}

int mygetchar()
{
    register int c;

    c = fgetc(infile);

    /*
    if (c == ';') {
 ungetc(SPACE, infile);
 return(';');
    }
    */
    if (c == '/') {    /* open comment ? */
        c = fgetc(infile);
        if (c != '*') {
            ungetc(c, infile);
            return('/');
        }
        commln = ln;
        commindent = indent;

        while (1) {
            c = fgetc(infile);

            if (c == EOF) {   /* last comment never ended */
                if (pr(2))
                    printf
                      ("Comment opened line %d unclosed by end of file.\n",
                      commln);
                break; /* Get out of this loop! */
            } else if (c == '/') {  /* nested comment ? */
                if ((c = fgetc(infile)) == '*') {
                    if (pr(0))
                        fprintf(stdout,
                          "Nested comment: line %d, indent %d.  First open: line
                             ln, indent, commln, commindent);
                } else
                    ungetc(c, infile);
            } else if (c == '*') {  /* end comment ? */
                if ((c = fgetc(infile)) == '/') {
                    if (indent != commindent  &&  indent - 1 != commindent)
                        if (pr(0))
                            printf(
                              "Indent of comment close doesn't match open: lines
                                     commln, ln, commindent, indent);

                    break;    /* only exit from loop, except EOF */
                } else
                    ungetc(c, infile);
            } else if (c == '\n') {
                do {
                    if (c == SPACE)
                        indent++;
                    else if (c == '\t')
                        indent = ((indent + 8) / 8) * 8;
                    else if (c == '\n') {
                        ln++;
                        indent = 0;
                    }
                } while (isspace(c = fgetc(infile)));
                ungetc(c, infile);
            }
        }
        return(SPACE);

    }

    if (c == '\n'  ||  firsttime == 1) {
        firsttime = 0;
lf:
        while (1) {
            if (c == SPACE)
                indent++;
            else if (c == '\t')
                indent = ((indent + 8) / 8) * 8;
            else if (c == '\n') {
                ln++;
                indent = 0;
                singlequoterr = 0;
            } else {
                ungetc(c, infile);
                return('\n');
                /*NOTREACHED*/
                break;
            }
            c = fgetc(infile);
        }
    }

    if (c == SPACE  ||  c == '\t') {
        do
            c = fgetc(infile);
        while (c == SPACE  ||  c == '\t');
        if (c != '\n') {
            ungetc(c, infile);
            return(SPACE);
        } else
            goto lf;
    }
    return(c);
}

/*
 * administer count of error msgs. and suppress if too many
 * administer the status var.s
 * prepend file name to msg.
 * flag error msg.s (not warnings) with '*'
 */
int pr(error)
int error;
{
    int i;

    if (singlequoterr)
        return(0);

    if (verbose) {
        for (i = stackc; i > 0; i--) {
            printf("%d: type ", i);
            prtype(stack[i].type);
            printf(", indent %d, line %d.\n", stack[i].b_indent, stack[i].b_ln);
        }
    }

    if (error == 2) {
        errnmb = 0;
        errstatus = 1;
    } else if (error) {
        errstatus = 1;
        if (errnmb < 0)
            return(0);
        else if (errnmb >= 9) {
            errnmb = -1;
            printf("Other error messages being suppressed.\n");
            return(0);
        }
    } else {
        wstatus = 1;
        if (wnmb < 0)
            return(0);
        else if (errnmb + wnmb >= 9) {
            wnmb = -1;
            puts("Further warning messages being suppressed.\n");
            return(0);
        }
    }

    if (filename != NULL) {
        fputs(filename, stdout);
        fputs(": ", stdout);
    }
    if (error)
        putchar('*');
    if (error)
        errnmb++;
    else
        wnmb++;
    return(1);
}

void newbrak(newtype)
int newtype;
{
    if (newtype == 0) {
        top = stack;
        stackc = 0;
    } else {
        top++;
        stackc++;
    }
    if (stackc >= STACKSIZ) {
        if (pr(2))
            printf("***stack overflow, line %d.\n", ln);
        exit(3);
    }

    top->type = newtype;
    top->b_indent = indent;
    top->b_ln = ln;

}

void prtype(typ)
int typ;
{
    switch (typ) {
    case BRACE:
        putchar('}');
        break;
    case PAREN:
        putchar(')');
        break;
    case SQBRAK:
        putchar(']');
        break;
    case IF:
        fputs("if", stdout);
        break;
    case IFCOND:
        fputs("if-condition", stdout);
        break;
    case THEN:
        fputs("then", stdout);
        break;
    case ELSE:
        fputs("else", stdout);
        break;
    case WHLCOND:
        fputs("while-condition", stdout);
        break;
    default:
        fputs("'NULL'", stdout);
        break;
    }
}

void checkcloser(typ)
int (typ);
{
    int i, found;

    i = found = 0;
    if (typ == top->type  &&  top->b_indent == indent) {
        rmbrak(1);
        return;
    }

    while (!found  &&  ++i < stackc  &&  indent <= (top - i)->b_indent)
        if (typ == (top - i)->type  &&  (top - i)->b_indent == indent)
            found = 1;

    if (found) {
        if (pr(1))
            printf("Missing closer%s detected line %d:\n", (i > 1 ? "s" :
              ""), ln);
        while (i--) {
            if (pr(1)) {
                fputs("\tMissing closing ", stdout);
                prtype(top->type);
                printf(" opened line %d.\n", top->b_ln);
            }
            switch (top->type) {
            case BRACE:
                bracecnt++;
                break;
            case SQBRAK:
                sqbrakcnt++;
                break;
            case PAREN:
                parencnt++;
                break;
            default:
                break;
            }
            rmbrak(1);
        }
        rmbrak(1); /* the matching brak */
    } else if (typ == top->type) {
        if (indent != top->b_indent) {
            if (pr(0)) {
                fputs("Mismatched indent on closing ", stdout);
                prtype(typ);
                printf
                  (" lines %d, %d; indents %d, %d.\n",
                  top->b_ln, ln, top->b_indent, indent);
            }
        }
        rmbrak(1);
    }
      else {
        switch (typ) {
        case BRACE:
            bracecnt--;
            break;
        case SQBRAK:
            sqbrakcnt--;
            break;
        case PAREN:
            parencnt--;
            break;
        default:
            break;
        }

        if (pr(1)) {
            fputs("Muddle detected at unmatched closing ", stdout);
            prtype(typ);
            printf(" line %d.\n", ln);
        }
    }
}

/*
 * removes IF from stack
 * checks else's indent
 */
void checkelse()
{
    int c;

    while ((c = mygetchar()) == SPACE  || c == '\n')
        ;
    if (c == 'e'
      &&  (c = mygetchar()) == 'l'
      &&  (c = mygetchar()) == 's'
      &&  (c = mygetchar()) == 'e'
      &&  !isalpha(c = fgetc(infile))  &&  !isdigit(c)) {
        ungetc(c, infile);
        if (top->type == THEN)
            rmbrak(1);
        if (top->type != IF) {
            if (pr(1))
                printf("Else with no if line %d.\n", ln);
        }
          else if (indent + 2 < top->b_indent) {
            if (pr(1))
                printf("Dangling else -- bound to wrong if?  \"if\" line %d, \"e
                   top->b_ln, ln);
        }
          else if (indent != top->b_indent) {
            if (pr(0)) {
                fputs("Wrong indent for else", stdout);
                if (indent - 2 >  top->b_indent)
                    fputs(" (missing if?)", stdout);
                printf(".  \"if\" line %d, \"else\" line %d.\n", top->b_ln,
                   ln);
            }
        }

        if (top->type == IF)
            rmbrak(1);
        newbrak(ELSE);
    } else {
        myungetc(c);
        ungetc(SPACE, infile);  /* BUG?? */
        /* no else so terminate the IF */
        if (top->type == IF) {
            rmbrak(1);
            while (top->type == ELSE)
                rmbrak(1);
            if (top->type == THEN) {
                rmbrak(1);
                checkelse();
            }
        }
    }
}

/*  This function is included because Aztec C does not include an "abs"
    function.  If your library contains this function, this code can be
    deleted.
*/
int abs(i)
{
    int c;

    return((i < 0) ? -i : i);
}

⌨️ 快捷键说明

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