232 lines
4.5 KiB
C++
232 lines
4.5 KiB
C++
|
/* CBCHECK.C -- Dumb Curley Brace Checker for C Programs
|
||
|
Usage: A>cbcheck program
|
||
|
|
||
|
This program really checks indentation. It ignores
|
||
|
#include and #define and has a lot of other
|
||
|
limitations. If it does not work for your style
|
||
|
of programs, change it. */
|
||
|
|
||
|
#define TAB 9
|
||
|
#define LF 10
|
||
|
#define CR 13
|
||
|
#define CONTZ 26
|
||
|
|
||
|
char *nextin,*line_start,lastch,switch_level;
|
||
|
int indentat[10],line,numcb;
|
||
|
|
||
|
|
||
|
main(argc,argv)
|
||
|
int argc;
|
||
|
char *argv[]; {
|
||
|
int ch;
|
||
|
char col;
|
||
|
|
||
|
if (argc < 2) error("no file name","");
|
||
|
read_file(argv[1]);
|
||
|
|
||
|
while (1) {
|
||
|
line_start=nextin;
|
||
|
line++;
|
||
|
col=countcol();
|
||
|
if (index("{}/#\r\n",*nextin) == 0 && (lastch == '{' || lastch == ';')
|
||
|
&& col != indentat[numcb] && switch_level == 0) {
|
||
|
if (indentat[numcb]) lerror("questionable indent");
|
||
|
indentat[numcb]=col;
|
||
|
}
|
||
|
if (skipl() == -1) break;
|
||
|
}
|
||
|
printf("%d lines",line);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* READ_FILE -- open the input file and read. */
|
||
|
|
||
|
read_file(fil)
|
||
|
char *fil; {
|
||
|
int i,filenum;
|
||
|
unsigned max,numin;
|
||
|
char filename[65];
|
||
|
|
||
|
/* get the file name. default is .C */
|
||
|
|
||
|
strcpy(filename,fil);
|
||
|
i=0;
|
||
|
while (filename[i] && filename[i] != '.') i++;
|
||
|
if (filename[i] == 0) strcat(filename,".C");
|
||
|
|
||
|
/* open the filename */
|
||
|
|
||
|
if ((filenum=open(filename,0)) == -1) error("cannot open",filename);
|
||
|
|
||
|
/* read file in */
|
||
|
|
||
|
nextin=_memory(); /* first free memory */
|
||
|
max=_showsp()-nextin-1000; /* size of memory */
|
||
|
if ((numin=read(filenum,nextin,max)) == -1)
|
||
|
error("cannot read",filename);
|
||
|
if (numin == max) error("file too big","");
|
||
|
nextin[numin]=CONTZ; /* plant a control Z for EOF */
|
||
|
close(filenum);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* COUNTCOL -- count indentation */
|
||
|
|
||
|
countcol() {
|
||
|
int col;
|
||
|
|
||
|
col=0;
|
||
|
while (*nextin == ' ' || *nextin == TAB) {
|
||
|
if (*nextin == ' ') col++; else col+=4;
|
||
|
nextin++;
|
||
|
}
|
||
|
return col;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* SKIPL -- skip the rest of the line. take care of comments etc. */
|
||
|
|
||
|
skipl() {
|
||
|
|
||
|
lastch=0;
|
||
|
while (*nextin != LF) {
|
||
|
if (*nextin != CR) lastch=*nextin;
|
||
|
|
||
|
switch (*nextin++) {
|
||
|
|
||
|
/* control Z means EOF */
|
||
|
case CONTZ: return -1;
|
||
|
|
||
|
/* " means string */
|
||
|
case '"': while (*nextin != '"') {
|
||
|
if (*nextin == '\\') {
|
||
|
nextin++;
|
||
|
if (*nextin == CR) {
|
||
|
nextin++;
|
||
|
line++;
|
||
|
}
|
||
|
}
|
||
|
if (*nextin == LF || *nextin == CONTZ) {
|
||
|
lerror("missing \"");
|
||
|
nextin--;
|
||
|
break;
|
||
|
}
|
||
|
nextin++;
|
||
|
}
|
||
|
nextin++;
|
||
|
break;
|
||
|
|
||
|
/* ' means character constant */
|
||
|
case '\'': skip_char();
|
||
|
break;
|
||
|
|
||
|
/* / may mean comment */
|
||
|
case '/': if (*nextin == '*') {
|
||
|
while (*++nextin != '*' || *++nextin != '/') {
|
||
|
if (*nextin == LF) line++;
|
||
|
if (*nextin == '/' && *(nextin+1) == '*')
|
||
|
lerror("comments may be nested");
|
||
|
if (*nextin == CONTZ) {
|
||
|
lerror("missing */");
|
||
|
nextin--;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
nextin++;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
/* a switch statement adds extra indentation */
|
||
|
case 's': if ((*(nextin-2) == ' ' || *(nextin-2) == TAB)
|
||
|
&& *nextin == 'w' && *++nextin == 'i' &&
|
||
|
*++nextin == 't' && *++nextin == 'c' &&
|
||
|
*++nextin == 'h' && (*++nextin == '(' ||
|
||
|
*nextin == ' ')) {
|
||
|
if (switch_level == 0) switch_level=numcb;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
/* { adds to curley brace count */
|
||
|
case '{': numcb++;
|
||
|
break;
|
||
|
|
||
|
/* } subtracts form curley brace count */
|
||
|
case '}': if (numcb) {
|
||
|
numcb--;
|
||
|
if (switch_level == numcb) switch_level=0;
|
||
|
}
|
||
|
else lerror("too many '}'s");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
nextin++;
|
||
|
return *nextin == CONTZ ? -1: 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* SKIP_CHAR -- skip a character constant. */
|
||
|
|
||
|
skip_char() {
|
||
|
|
||
|
while (*nextin != '\'') {
|
||
|
if (*nextin == '\\') nextin++;
|
||
|
if (*nextin == LF || *nextin == CONTZ) {
|
||
|
lerror("missing '");
|
||
|
return;
|
||
|
}
|
||
|
nextin++;
|
||
|
}
|
||
|
nextin++;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* LERROR -- print an line error */
|
||
|
|
||
|
lerror(str)
|
||
|
char *str; {
|
||
|
char *ptr,col;
|
||
|
|
||
|
printf("%5d ",line);
|
||
|
col=0;
|
||
|
do {
|
||
|
if (*line_start != TAB) {
|
||
|
putchar(*line_start);
|
||
|
col++;
|
||
|
}
|
||
|
else do {
|
||
|
putchar(' ');
|
||
|
}
|
||
|
while (++col % 4);
|
||
|
}
|
||
|
while (*line_start != CONTZ && *line_start++ != LF);
|
||
|
puts("error: ");
|
||
|
puts(str);
|
||
|
puts("\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ERROR -- print an error and bail out */
|
||
|
|
||
|
error(stra,strb)
|
||
|
char *stra,*strb; {
|
||
|
|
||
|
puts("error: ");
|
||
|
puts(stra);
|
||
|
puts(" ");
|
||
|
puts(strb);
|
||
|
exit(2);
|
||
|
}
|