nitin@ur-laser.UUCP (04/03/87)
# This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by ur-lle!nitin on Fri Apr 3 11:09:16 EST 1987 # Contents: README shred.1 Makefile shred.l echo x - README sed 's/^@//' > "README" <<'@//E*O*F README//' Program to break a C program into their individual functions: This program "tries" to do this. It is not 100% effective. Nevertheless, it can prove to be a very useful tool. The following files should be available: README This file Makefile Makefile for shred shred.l lex source code for shred shred.1 manual page (-man macros) shred.man (nroffed) manual page DIRECTIONS FOR CREATING/MAKING SOURCE: 1. Edit the Makefile to reflect the correct path for the binary and the manual page * 2. Type "make" 3. Check to make sure the executable "shred" was made 4. Type "make install" to install the program 5. Type "make clean" to clean the directory * you can also set the environment variable "MAKE_ROOT" to reflect the the root path for the binary file and the manual pages. This avoids editing the Makefiles everytime the sources are moved around on the system. If all files follow this system, one need only change the environment variable when files are moved around. e.g. % setenv MAKE_ROOT /usr/local @//E*O*F README// chmod u=rw,g=rw,o=r README echo x - shred.1 sed 's/^@//' > "shred.1" <<'@//E*O*F shred.1//' @.TH shred 1L "April Fool's Day, 1987" @.SH NAME shred - Program to break a C program into subroutines. @.SH SYNOPSIS @.B shred @.B [\-u] [\-h @.I <header file> @.B ] @.I <file.c> ... @.SH DESCRIPTION @.I shred is a (and i quote) @.nf @.ps 8 \fIkrufty hack to rip large \fB(C)\fI source modules into subroutine modules. This program is only semi-intelligent and should be treated as such. M.J.R.\fR @.ps 10 @.fi @.PP Some more intelligence, and options have been added here at LLE. In particular, shred recognizes functions with types out front, or on the previous line(s). Also, it prefixes each subroutine with an 'include' line for the @.I header file and with the comments which appeared before this subroutine, but after the previous subroutine, if any. It now can tell the difference between a function declaration and a function definition. Declarations are left in the @.I header file. And, finally, you can now get the file names to be prefixed by an underscore as an option, rather than always, as was previously the case. @.SH OPTIONS @.B \-u - prefix file names with underscore. (this was the old default) @.br @.B \-h @.I <header file> - use this as the name of the file containing header (non-subroutine) lines. (default is _header.h) @.SH EXAMPLES % \fBshred messy.c\fR @.br hopefully the result is a bunch of subroutines in separate files. @.SH BUGS As mentioned, shed is not too smart. There is little hope of shred working on files with C syntax errors. Also, shred doesn't know about #ifdef's, so any weirdness in #ifdef's, or even syntax errors inside #ifdef's will confuse it. However, if it gets confused, the worst that seems to happen is all of your file(s) end up in the @.I header file. At the moment, strange things happen if the subroutine files already exist. The new file is appended to the existing one, however, no comments will be prepended. In any event, this usually results in garbage, but at least nothing gets lost. There is a check to make sure you're not writing over the file you're reading from, which could be ugly. @.SH AUTHOR Copyright, 1987, Marcus J Ranum @.br All rights reserved. This code can be distributed, modified, or altered at will, but it or versions of it may not be sold for profit. @.sp 2 Local extensions by S Swales, Lab. for Laser Energetics (LLE) @//E*O*F shred.1// chmod u=rwx,g=rwx,o=r shred.1 echo x - Makefile sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//' # Makefile for shred # # To use this change MAKE_ROOT to reflect the correct path. # You can also do this at the shell level by setting the enviroment: # % setenv MAKE_ROOT the_path_to_follow # The latter is advisable since if ever the directory is moved, only # the environment need change for all Makefiles # DEST = ${MAKE_ROOT}/bin MAN = ${MAKE_ROOT}/man/man1 LD = ${CC} CFLAGS = -fsingle -O LDFLAGS = -fsingle DEBUG = -O STRIP = -s INCLUDES = LIBS = PROGRAM = shred EXECUTABLES = ${PROGRAM} OBJS = ${PROGRAM}.o SRCS = $(PROGRAM).l all: ${PROGRAM} ${PROGRAM}: ${OBJS} ${LIBS} ${LD} ${LDFLAGS} ${OBJS} ${LIBS} -o ${PROGRAM} clean:; @rm -f core junk foo *.out *.o *.lint @rm -f ${EXECUTABLES} install: ${EXECUTABLES} ${SCRIPTS} manual cp ${EXECUTABLES} ${SCRIPTS} ${DEST} man: manual manual: -cp ${PROGRAM}.[12345678]* ${MAN} print: .print @.print: ${SRCS} ${MENU} ${SCRIPTS} itroff -t -ms -man ${PROGRAM}.[1234]? | catimp -h vgrind -t $? | catimp -h touch .print lint: ${SRCS} lint ${INCLUDES} $? @//E*O*F Makefile// chmod u=rw,g=rw,o=r Makefile echo x - shred.l sed 's/^@//' > "shred.l" <<'@//E*O*F shred.l//' shred.l: %{ /* %e 2000 %p 5000 %n 1000 %k 500 %a 4000 %o 2000 */ /* Copyright, 1987, Marcus J Ranum */ /* All rights reserved. This code can be distributed, modified, */ /* or altered at will, but it or versions of it may not be sold */ /* for profit */ /* krufty hack to rip large source modules into subroutine modules */ /* this program is only semi-intelligent and should be treated as such */ /* April 1, 1987 Steve Swales (Lab. for Laser Energetics) */ /* added features/options and a manual page (see this for details) */ /* added a Makefile */ #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> int trigger =0; int bracelev =0; int incomment =0; int infunction =0; int ininclude =0; int junkint =0; char *junkp =0; struct stat stbuf; char jfname[512]; char jfname2[512]; char *curfile; char *strcat(); char headerfile[512] = "_header.h"; int use_underscore = 0; char tempcom[] = "shed_tempXXXXXX"; FILE *tempfp = 0; %} %% ^[a-zA-Z1-9*_ \t\n]+"("[ \t\n]*")"[ \t\n]*";" { /* declaration only*/ printout(yytext); } ^[a-zA-Z1-9*_ \t\n]+"("[a-zA-Z1-9_, ]*")" { /* found a function definition ! */ if (!bracelev && !incomment && !ininclude) { infunction = 1; (void) sprintf(jfname2, "%s", yytext); for (junkint = 0; junkint < strlen(jfname2); junkint++) { if (jfname2[junkint] == '(') { jfname2[junkint] = '\0'; while (jfname2[--junkint] <= ' ') jfname2[junkint] = '\0'; break; } } junkp = jfname2 + strlen(jfname2) - 1; while (junkp >= jfname2) { if (*junkp <= ' ' || *junkp == '*') { break; } --junkp; } junkp++; (void) sprintf(jfname, "%s%s", (use_underscore) ? "_" : "", junkp); (void) strcat(jfname, ".c"); if (!strncmp(jfname, curfile)) { fprintf(stderr, "Cant write over the file you're reading from!!\n"); if (tempfp) { fclose(tempfp); unlink(tempcom); tempfp = 0; } printout(yytext); } else { if (tempfp) { fclose(tempfp); link(tempcom, jfname); unlink(tempcom); tempfp = 0; } fprintf(stderr, "writing %s\n", jfname); (void) fclose(yyout); if ((yyout = fopen(jfname, "a")) == NULL) { perror("shred"); unlink(tempcom); exit(9); } fprintf(yyout, "\n#include \"%s\"\n\n", headerfile); fprintf(yyout, "%s", yytext); } } else { printout(yytext); } } "{" { if(!incomment) ++bracelev; fprintf(yyout,"%s",yytext); } "}" { if(!incomment) --bracelev; fprintf(yyout,"%s",yytext); if(bracelev <0) { fprintf(stderr,"too many \"}\" ! unmatched \"{\"\n"); exit(1); } /* if we're not in braces, anything goes to header file */ if(!bracelev) { fprintf(yyout,"\n"); (void)fclose(yyout); infunction = 0; if((yyout = fopen(headerfile,"a")) ==NULL) { perror("shred"); exit(9); } } } \*\/ { printout(yytext); if(incomment) incomment--; } \/\* { incomment++; if(bracelev == 0) { if(!tempfp) tempfp = fopen(tempcom,"w"); } printout(yytext); } ^[]*"#" { ininclude++; /* flush includes */ fprintf(yyout,"%s",yytext); } \n { ininclude =0; printout(yytext); } @. {printout(yytext); } /* default action */ %% /* beginning of MAIN */ main(argc,argv) int argc; char *argv[]; { int index =0; char *s; /* used by command line parser */ /* * Parse command line for options */ while ( --argc > 0 && ( *++argv) [0] == '-' ) for( s = argv[0]+1; *s != '\0'; s++) switch(*s) { case 'u': use_underscore = 1; break; case 'h': strcpy(headerfile,*++argv); --argc; break; default: fprintf(stderr,"'-%c' is not a legal option\n",*s); usage(); break; } if(argc == 0) usage(); mktemp(tempcom); if(!stat(headerfile,&stbuf)) { printf("%d braces\n",bracelev); fprintf(stderr,"will not overwrite existing %s\n",headerfile); exit(1); } else { if((yyout = fopen(headerfile,"w")) ==NULL) { perror("shred"); exit(9); } } for(index = 0; index <argc; index++) { if((yyin = fopen(argv[index],"r")) ==NULL) { perror("shred"); unlink(tempcom); exit(1); } else { curfile = argv[index]; yylex(); } } unlink(tempcom); } usage() { fprintf(stderr,"Usage: shred [-u] [-h <header file>] <file.c>...\n"); fprintf(stderr," -u - prefix subroutine file names with underscore\n"); fprintf(stderr," -h <header file> - use this name for include file.\n"); exit(1); } yywrap() { /*yywrap returns a 1. It can be used to detect end of file, and whether to provide more input to yyinput. I get rid of it like this. If you have some desire to frob the input, here is one place to do it. -mjr */ return(1); } printout(yytext) char *yytext; { fprintf(yyout,"%s",yytext); if(bracelev == 0 && !infunction && incomment) { if(tempfp) fprintf(tempfp,"%s",yytext); } } @//E*O*F shred.l// chmod u=rw,g=rw,o=r shred.l exit 0 -- {seismo,allegra}!rochester!ur-laser!nitin