home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
EFFO
/
forum7.lzh
/
C
/
RDOC
/
rdoc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-07-15
|
21KB
|
555 lines
/****************************************************************************
* Progrmname : rdoc.c *
* Programmierer : W. Reese aus C't 1988 Heft 7 *
* Projekt : Rueckdocumentation *
* Datum : 11. 05. 1988 *
* *
****************************************************************************/
# include <stdio.h>
/* Definition der Codes fuer Zeilenteiltypen */
#define ZEILENENDE 0 /* Ende der Zeile */
#define REST 1 /* Rest-Wort */
#define KOMSTART 2 /* Kommentarstart */
#define KOMRUMPF 3 /* Kommentarrumpf */
#define KOMENDE 4 /* Kommentarende */
#define BLOCKSTART 10 /* Blockstart = "{" */
#define BLOCKENDE 11 /* Blockende = "}" */
#define IF 20 /* Schluesselwort if */
#define ELSE 21 /* Schluesselwort else */
#define WHILE 22 /* Schluesselwort while */
#define FOR 23 /* Schluesselwort for */
#define DO 24 /* Schluesselwort do */
#define CONTINUE 25 /* Schluesselwort continue */
#define BREAK 26 /* Schluesselwort break */
#define RETURN 27 /* Schluesselwort return */
#define GOTO 28 /* Schluesselwort goto */
#define CASE 29 /* Schluesselwort case */
#define SWITCH 30 /* Schluesselwort switch */
#define DEFAULT 31 /* Schluesselwort default */
#define LABEL 32 /* Schluesselwort label */
#define TAB 0x09 /* Horizontaler Tabulator */
/* Lesen bis \n einschl. c Zeichen */
#define readline(a,b,c) fgets(b,c,a)
/* Schreiben aus dem Puffer a bis \n maximal b Zeichen auf */
#define writeline(a,b) writeln(1,a,b)
#define ERRFNAM "rdoc.err" /* Filename Errorfile */
/* ======================= main ==================================== */
main(argc,argv)
int argc;
char *argv[];
{
char buf[200];
int nschlw,nkomm,nrest,nblockst;
static int bold=0,altblock=0,zakt=0,blockerr=0,schlerr=0,sumkom=0;
int i;
FILE *file,*fopen(),*errfile;
/* -------- Filename und Optionen aus Kommandozeile */
if(argc < 2) { /* Filename nicht vorhanden */
/* Abbruch mit Fehlermeldung */
fprintf(stdout,"Parameter Filename fehlt\n");
exit(10);
}
if((file=fopen(argv[1],"r")) == NULL) { /* Open error */
/* -------Abbruch mit Fehlermeldung */
fprintf(stdout,"File kann nicht geoeffnet werden\n");
exit(10);
}
if((errfile=fopen(ERRFNAM,"w")) == NULL) { /* Open error */
/* -------- Abbruch mit Fehlermeldung */
fprintf(stdout,"Error-File kann nicht geoeffnet werden\n");
exit(10);
}
if(argc>=3 && scomp("-b",argv[2]) ==0) /* Option -b vorhanden */
bold = 1; /* Merker Fettdruck Schluesselworte setzen */
/* -------- Textrumpf bearbeiten */
while(readline(file,buf,200) != NULL) { /* nicht Fileende */
/* -----Zeile bearbeiten */
zakt++; /* Zeilenzaehler aktualisieren */
nschlw=nkomm=nrest=nblockst=0;
zeile(buf,bold,&nschlw,&nkomm,&nrest,&nblockst);
/* ------- Update Statistik */
if(altblock == 1) /* Blockstart in letzter Zeile */
if(nkomm == 0) { /* Kein Kommentar in aktueller Zeile */
/* ---- Fehlerbearbeitung : Blockstart ohne Kommentar */
fprintf(errfile,
"%d : Kein Kommentar nach Blockstart\n",zakt);
blockerr++;
}
if(nblockst != 0) /* Blockstart in Zeile */
altblock = 1; /* Merker Blockstart setzen */
else /* Kein Blockstart in Zeile */
altblock = 0; /* Merker Blockstart ruecksetzen */
if(nschlw!=0 && nkomm==0) { /* Schluesselw. ohne Kommentar */
/* --------- Fehlerbearbeitung : Schluesselwort ohne Kommentar */
fprintf(errfile,"%d : Schluesselwort ohne Kommentar\n",zakt);
schlerr++;
}
if(nkomm != 0) /* Kommentar in Zeile */
sumkom++; /* Update Kommentarzeilenzaehler */
}
/* ------ Statistik bearbeiten */
fprintf(errfile,
"******** Statistische Informationen *********\n\n");
fprintf(errfile,
" Anzahl der Programmzeilen ............... : %d\n",zakt);
fprintf(errfile,
" Davon Zeilen mit Kommentar .............. : %d\n",sumkom);
fprintf(errfile,
" Anzahl der Blockstarts ohne Kommentar ... : %d\n",blockerr);
fprintf(errfile,
" Anzahl der Schluesselworte ohne Kommentar : %d\n",schlerr);
}
/* ==================== Zeile ============================================ */
/* Funktionsumfang:
Zeilenrumpf suchen, bearbeiten (Schluesselworte und Kommentare
herausziehen) und -- wenn noch Reste vorhanden ausgeben.
Eingabedaten:
*zstart = Zeiger (char *) auf Start der Orginalzeile
bold = Fettdruck Schluesselworte 0/1
Ausgabedaten:
*nschlw = Anzahl (int *) der Schluesselworte in der Zeile
*nkomm = Anzahl (int *) der Kommentare in der Zeile
*nrest = Anzahl (int *) der Restelemente in der Zeile
*blockst = Anzahl (int *) der Blckstarts in der Zeile
Rueckgabe : 0, wenn Zeile nicht leer, sonst -1 */
zeile(zstart,bold,nschlw,nkomm,nrest,nblockst)
char *zstart;
int bold;
int *nschlw,*nkomm,*nrest,*nblockst;
{
char *z,*z1, *zrumpf();
int lang;
/* ----------- Zeilenstart suchen */
z = zstart;
while(*z==TAB || *z==' ') /* Zeichen gleich TAB oder SPACE */
z++;
lang = z-zstart; /* Laenge Zeilenstart */
/* Zeilenrumpf bearbeiten */
z1 = zrumpf(z,bold,nschlw,nkomm,nrest,nblockst);
if(z1 != (char *)NULL) { /* Zeile nicht leer */
/* Ausgabe der Zeile */
writeline(zstart,lang); /* Ausgabe Zeilenstart */
writeline(z1,200); /* Ausgabe Zeilenrumpf */
return(0); /* Return: keine Leerzeile */
}
else /* Leerzeile */
return(-1); /* Return: Leerzeile */
}
/* ===================== zrumpf ========================================== */
/* Funktionumfang:
Der Zeilenrumpf wird in Zeilenbreite aufgespalten. Schluesselworte
und Kommentare werden mit einem Zwischenraum von zwei Leerzeichen
zu einem neuen Zeilenrumpf zusammengesetzt. Ev. Steuerzeichen fuer
Fettdruck der Schluesselworte werden eingefuegt. zrumpf merkt sich,
ob ein Kommentar in einer Zeile beeindet wurde.
Eingabedaten:
*rstart = Zeiger auf Start Zeilenrumpf in Orgi.zeile
bold = Fettdruck Schluesselworte 0/1
Ausgabedaten:
*nschlw = Anzahl (int *) der Schluesselworte
*nkomm = Anzahl (int *) der Kommentarruempfe
*nrest = Anzahl (int *) der Restelemente
*nblockst= Anzahl (int *) der Blockstarts
Rueckgabe :
OK : Zeiger auf Start des bearbeiteten Zeilenrumpfs
Leerrumpf : Zeiger (char * auf NULL */
char *zrumpf(rstart,bold,nschlw,nkomm,nrest,nblockst)
char *rstart;
int bold,*nschlw,*nkomm,*nrest,*nblockst;
{
register int i; /* schneller Schleifenzaehler */
static int altkom = 0; /* Merker alter Kommentar nicht beendet */
static char buf[200]; /* Puffer bearbeiteter Zeilenrumpf */
char *bp; /* Pufferzeiger bearbeiteter Zeilenrumpf */
int leerrumpf,laenge,code;
/* ------ Initialisierung von Variablen */
bp = buf;
leerrumpf = 1; /* Leerrumpfmerker setzen */
*nschlw = *nkomm = *nrest = *nblockst = 0; /* Zaehler ruecksetzen */
/* ----- Zeilenrumpf abarbeiten */
while((code = zeilenteil(rstart,altkom,&laenge))!=ZEILENENDE) {
/* ---- Zeilenteil bearbeiten */
if(code == KOMSTART) { /* Kommentarstart */
/* ----Bypass, Merker setzen */
leerrumpf = 0; /* Leerrumpfmerker ruecksetzen */
altkom = 1; /* Kommentarstart merken */
rstart += laenge; /* Bypass Kommentarstart */
}
else if(code == KOMENDE) { /* Kommentarende */
/* ----- Bypass, Merker setzen */
altkom = 0; /* Merker Kommentarstart zuruecksetzen */
rstart += laenge; /* Bypass Kommentarende */
*(bp++) = ' '; *(bp++) = ' '; /* Space einkopieren */
}
else if(code == KOMRUMPF) { /* Kommentarrumpf */
/* ----- Kommentarrumpf einkopieren */
leerrumpf = 0; /* Leerrumpfmerker ruecksetzen */
/* Kommentarrumpf einkopieren */
while(*rstart == ' ') { /* Fuehrendes Leerzeichen */
/* --------- Bypass fuehrendes Leerzeichen */
rstart++;
laenge--;
}
for(i=0;i<laenge;i++) /* Ganzen Kommentarrumpf */
*(bp++) = *(rstart++); /* Kopieren */
*(bp++) = ' '; *(bp++) = ' '; /* Space einkopieren */
(*nkomm)++; /* Inkrement Kommentarzaehler */
}
else if(code == BLOCKSTART) { /* Blockstart */
/* -------- Blockstart einkopieren */
if (bold == 1) /* Breitschrift */
boldface(&bp,1); /* Code Bold-On einkopieren */
for(i=0;i<laenge;i++) *(bp++) = *(rstart++); /* Kopie { */
if(bold == 1) /* Breitschrift */
boldface(&bp,0); /* Code Bold-Off einkopieren */
*(bp++) = ' ';*(bp++) = ' '; /* Space einkopieren */
(*nblockst)++; /* Inkrement Blockstartzaehl */
leerrumpf = 0; /* Leerrumpfmerker ruecksetzen */
}
else if(code == BLOCKENDE) { /* Blockende */
/* ------- Blockende einkopieren */
if(bold == 1) /* Breitschrift */
boldface(&bp,1); /* Code Bold-on einkopieren */
for (i=0;i<laenge;i++) /* Blockendezeichenlaenge */
*(bp++) = *(rstart++); /* Kopie } */
if(bold == 1) /* Breitschrift */
boldface(&bp,0); /* Code Bold-Off einkopieren */
leerrumpf = 0; /* Leerrumpfmerker ruecksetzen */
*(bp++) = ' '; *(bp++) = ' '; /* Space einkopieren */
}
else if(code>=IF && code <=LABEL) { /* Schluesselwort */
/* -------- Schluesselwort einkopieren */
if(bold == 1) /* Breitschrift */
boldface(&bp,1); /* Code Bold-On einkopieren */
for(i=0;i<laenge;i++) /* Laenge Schluesselwort */
*(bp++) = *(rstart++); /* Schluesselwort einkopieren */
if(bold == 1) /* Breitschrift */
boldface(&bp,0); /* Code Bold-Off einkopieren */
*(bp++) = ' ';*(bp++) = ' '; /* Space einkopieren */
(*nschlw)++; /* Inkrement Schluesselwortzaehler */
leerrumpf = 0; /* Leerrumpfmerker ruecksetzen */
}
else { /* Rest-Element */
/* ------ Bypass Rest-Element */
rstart += laenge;
(*nrest)++;
}
}
if(leerrumpf==1 && *nrest!=0) /* Leerrumpfmerker u. Restelement */
return((char *)NULL); /* Rueckgabe : Leerrumpf */
else { /* Kein Leerrumpf */
/* ------ Zeilenende einkopieren, Return: Buffer */
*bp = '\n';
return(buf); /* Rueckgabe : Buffer */
}
}
/* ==================== zeilenteil ==================================== */
/* Funktionsumfang:
Suchen des naecsten Zeilenteils.
- Schluesselworte werden von einem Zeichen ungleich
"letter" beendet.
- Kommentarstart und Kommentarende C-Standard
- Restworte werden durch "letter" beendet, wenn sie
mit ungleich "letter" begonnen haben, und durch
ungleich "letter" beendet, wenn sie mit "letter"
begonnen haben.
Eingabedaten:
*tstart = Zeiger (char *) auf Start Suche im Zeilenrumpf
altkomm = Alter Kommentar beendet (int) 0/1
Ausgabedaten:
*laenge = Anzahl der Bytes (int *) des Zeilenteils
Rueckgabe:
Code fuer Zeilenteil (int) */
zeilenteil(tstart,altkomm,laenge)
char *tstart;
int altkomm,*laenge;
{
register int i;
int code;
char *c1;
static char aletter = '\n'; /* Endekennung eines Schluesselwortes */
if(altkomm != 0) { /* Unbekannter Kommentar */
/* Kommentarende suchen */
if(scomp("*/",tstart) == 0) { /* Kommentarende erkannt */
/* ------ Code und Laenge uebergeben */
code = KOMENDE;
*laenge = 2;
}
else if(*tstart == '\n') { /* Zeilenende erkannt */
/* ----- Code und Laenge uebergeben */
code = ZEILENENDE;
*laenge = 1;
}
else { /* Kommentarrumpf erkannt */
/* ------- Kommentarende oder Zeilenende suchen */
c1 = tstart;
while(*(++c1) != '\n') { /* Ungleich Zeilenende */
/* ---- Bis ev. Zeilenende suchen */
if(scomp("*",c1) == 0) /* Kommentarende */
break; /* Scleifenabbruch */
}
*laenge = c1-tstart;
code = KOMRUMPF; /* Kommentarrumpfmerker */
}
}
else { /* Kein unbeendeter Kommentar */
/* ------- Schluesselworte und Kommentare suchen */
if(*tstart == '\n') { /* Zeilenende erkannt */
/* ----- Code und Laenge uebergeben */
code = ZEILENENDE;
*laenge = 1;
aletter = '\n';
}
else if(scomp("/*",tstart) == 0) { /* Kommentarstart erkannt */
/* ---- Code und Laenge uebergeben */
code = KOMSTART;
*laenge = 2;
aletter = '*';
}
else if(*tstart == '{') { /* Klammer "{" erkannt */
/* ---- Code und Laenge uebergeben */
code = BLOCKSTART;
*laenge = 1;
aletter = '{';
}
else if(*tstart == '}') { /* Klammer "}" erkannt */
/* Code und Laenge uebergeben */
code = BLOCKENDE;
*laenge = 1;
aletter = '}';
}
else if(*tstart=='"' && aletter!='\'') { /* Stringstart */
/* ------ String als Rest-Zeichenkette abarbeiten */
c1 = tstart+1;
aletter = '"';
while(*c1 !='"') { /* Kein zweites Anfuehrungszeichen */
/* --- Bzpass String */
if(*c1 == '\n') { /* Zeilenende erkant */
/* ---- Sonderbehandlung durch unbeendeten String */
c1--;
aletter = '\n';
break; /* Schleifenabbruch */
}
c1++;
}
code = REST; /* Rest-Merker */
*laenge = c1-tstart+1; /* Laenge des Strings */
}
else if(letter(aletter)!=0 /* Letz. Zeichen nicht Typ letter */
&&(i=schlwort(tstart,&code))!=0) { /* Scl.-Wort erkannt */
/* ------ Laenge uebergeben */
*laenge = i; /* Laenge Schluesselwort */
aletter = *(tstart+i-1);
}
else { /* Rest-Yeichen, Laenge immer 1 */
/* ---- Code und Laenge uebergeben */
code = REST;
*laenge = 1;
aletter = *tstart;
}
}
return(code); /* Rueckgabe : Code fuer Zeilenteil */
}
/* ===================== schlwort ====================================== */
/* Funktionsumfang:
Test auf c-Schluesselwort in einem String
Eingabedaten:
*str = Zeiger auf den zu untersuchenden String (char *)
Ausgabedaten:T
T *code = code des gefundenen Schluesselwortes (int *)
Rueckgabe:
Laenge des gefundenen Schluesselwortes (int)
0, wenn kein Schluesselwort gefunden wurde. In diesem
Fall wird *code auch nicht veraendert. */
schlwort(str,code)
char *str;
int *code;
{
static char *schlw[] = {"if","else","while","for","do",
"continue","break","return","goto","case",
"switch","default","main"};
register int i,match,lang;
char *c1;
match = 0; /* Merker kein Schluesselwort */
for(i=0;i<13;i++) { /* Alle Schluesselworte /
/* --- Test auf Uebereinstimmung mit Schluesselwort */
lang = strlen(schlw[i]); /* laenge Schluesselwort */
if(scomp(schlw[i],str)==0 && letter(*(str+lang))!=0) { /* Schluesselw. */
/* ------ Merker und Code setzen */
match =1; /* merker schluesselwort setzen */
*code = i+20; /* Offset 20 in defines fuer Codes */
break; /*Schleifenabbruch */
}
}
if(match == 0) { /* Bisher kein Schluesselwort gefunden */
/* ---- Testauf Label */
if(letter(*str) == 0) { /* 1.Zeichen Typ letter */
/* ------ Auf Label untersuchen */
for(i=2,c1=str+1;*c1!='\n';i++,c1++) { /* Bis Z.Ende */
/* ----- Bis ev. \n suchen */
if(*c1 == ':') { /* Ende Label */
/* ----- Merker Label und Code setzen */
match = 1; /* Merker Schluesselwort */
*code = LABEL;
lang = i;
break; /* Schleifenabbruch */
}
if(letter(*c1) != 0) /* Typ ungleich letter */
break; /* Schleifenabbruch */
}
}
}
if(match == 1) /* Schluesselwort gefunden */
return(lang); /* returns: Laenge des Schluesselwortes */
else /* Kein Schluesselwort gefunden */
return(0); /* returns: 0, wenn kein Schluesselwort */
}
/* ========================= letter ============================== */
/* Funktionsumfang:
Erkennen der Zeichen vom Typ letter :
_, a..z, A..Z, 0..9
Eingabedaten:
z (char) = Zu untersuchendes Zeichen
Ausgabedaten:
Rueckgabe :
0 (int) wenn Zeichen vom Typ "letter"
-1(int) wenn Zeichen nicht vom Typ "letter" */
letter(z)
char z;
{
if(z=='_' || (z>='a'&&z<='z') || (z>='A'&&z<='Z') || (z>='0'&&z<='9'))
/* Zeichentyp "letter" */
return(0); /* Rueckgabe : Typ letter */
else /* Zeichen nicht vom Typ "letter" */
return(-1); /* Rueckgabe : Nicht Letter */
}
/* ===================== scomp ========================================== */
/* Funktionsumfang:
Vergleich eines Strings mit einem zweiten String.
Der erste String muss nullterminiert sein.
Eingangsdaten:
*str1 = Zeiger vom Typ (char *) auf den ersten String
*str2 = Zeiger vom Typ (char *) auf den zweiten String
Ausgangsdaten:
-
Rueckgabe :
(int) 0 = Strings identisch
(int)-1 = Strings nicht identisch */
scomp(str1,str2)
char *str1,*str2;
{
char c;
while((c=*(str1++)) != 0) { /* KeinStringende */
/* ------ Strings zeichenweise vergleichen */
if(c != *(str2++)) /* String1 ungleich String2 */
return(-1); /* Return: Strings ungleich */
}
return(0); /* Return: Strings gleich */
}
/* ========================= boldface =============================== */
/* Funktionsumfang:
In einen String werden SteuerZeichen zum Ein- bzw Ausschalten des
hervorgehobenen Drucks beim Drucker STAR SR-XX einkopiert
Eingabedaten:
start = 0/1 (int) 0: Stop-, 1: Startsequenz
Ausgabedaten:
**str : Veraenderter Zeiger auf einen Zeiger auf den String
Rueckgabe :
- */
boldface(str,start)
char **str;
int start;
{
if(start == 1) { /* Startsequenz */
/* ------- Startsequenz einkopieren */
*((*str)++) = 0x1B;
*((*str)++) = 'G';
}
else { /* Stoppsequenz */
/* ---- Stoppsequenz einkopieren */
*((*str)++) = 0x1b;
*((*str)++) = 'H';
}
}