allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (03/22/89)
Posting-number: Volume 6, Issue 73 Submitted-by: mnc@m10ux.UUCP (52171.3-Michael Condict-- MHx5911 (MH0000)M999) Archive-name: fdecs [My, there's a lot of this kind of thing floating around recently. ++bsa] This shell script (fdecs) extracts ANSI-C function prototype declarations, suitable for use in a .h file, from C source files that contain old-style function definitions. See the comment at the top of fdecs for more info. The only option is "-Idir", which causes the C source to be run through the C preprocessor before the prototype extraction is done. Mike Condict ---------------------------- cut here -------------------------------------- #!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # # fdecs fdecs1.sed fdecs2.sed fdecs3.sed # # To extract the files from this shell archive file simply # create a directory for this file, move the archive file # to it and enter the command # # sh filename # # The files will be extracted automatically. # Note: Do not use csh. # # Archive created: Tue Mar 14 10:29:50 EST 1989 # echo x - fdecs sed 's/^X//' > fdecs << '@FUNKY STUFF@' # This script, given C source files, finds all the function definitions # of the form "type_decl f(a,b,...) type_decl a; type_decl b; ... { body }", # and outputs a file of extern function declarations suitable for a .h file. # There need not be a type_decl for each argument (defaults to int) and the # type_decl's can be in a different order from the arg list. Multiple args # can be declared in the standard abbreviated fashion: "int a, *b;". # # The only restriction is that the type_decl's must be no more complicated # than what can be formed with type words, names, "*" and "[]". That is the # type_decl's may not contain "struct ... {...}" or "float (*x)()" although, # e.g., "struct A" is allowed. # # The output is one line of the form # # type_decl f(type_decl a, type_decl b, . . . ); # # for each function f defined in the source files, i.e. a legal ANSI-C # function prototype. SEDDIR=~mnc/src/fdecs Iflag="" while [ "$#" -gt 0 ]; do case "$1" in -I*) Iflag="$Iflag $1"; shift ;; -*) echo "Usage: $0 [ -Iincl_dir ] ... file ..." echo " (use -I only if C preprocessor is wanted)" exit 1 ;; *) break ;; esac done if [ "$#" -eq 0 ] ; then sed -f $SEDDIR/fdecs1.sed | sed -f $SEDDIR/fdecs2.sed | sed -f $SEDDIR/fdecs3.sed elif [ "X$Iflag" != X ] ; then # User wants to run the C files through the preprocessor, with # the specified -I flag. We delete the contents of the # .h files from the preprocessor's output. We also need to # delete any occurrences of '^$filename:', which some versions # of cc -E put out at the beginning of every file: cc -E $Iflag "$@" | \ sed -e '#n No automatic printing # Delete contents of included .h files: : chkhdr /^# [1-9][0-9]* ".*\.h"/{ : delhdr n /^#/!b delhdr b chkhdr } # Delete "filename:" inserted by "cc -E": /^[^ ]*\.[ch]:[ ]*$/d ' \ -f $SEDDIR/fdecs1.sed \ -e 'p' | sed -f $SEDDIR/fdecs2.sed | sed -f $SEDDIR/fdecs3.sed else sed -f $SEDDIR/fdecs1.sed "$@" | sed -f $SEDDIR/fdecs2.sed | sed -f $SEDDIR/fdecs3.sed fi @FUNKY STUFF@ ls -l fdecs echo x - fdecs1.sed sed 's/^X//' > fdecs1.sed << '@FUNKY STUFF@' : morebs /\\$/ { N s/\\\n// b morebs } /^[ ]*$/d : delcom /\/\*/{ s/@/ /g s:/\*:@: : morecm /\*\//!{ s/@.*/@/ N b morecm } s/\$/ /g s:\*/:$: s/@[^$]*\$/ / b delcom } /^#/d s/\\"/ /g s/"[^"]*"/0/g s/\\'/ /g s/'[^']*'/0/g /^[ ]*$/d @FUNKY STUFF@ ls -l fdecs1.sed echo x - fdecs2.sed sed 's/^X//' > fdecs2.sed << '@FUNKY STUFF@' : delcbrc /{/{ s/{[^{}]*/{/g : getcbrc /}/!{ N s/{[^{}]*/{/g b getcbrc } s/{[^{}]*}/#/g b delcbrc } s/#/{}/g @FUNKY STUFF@ ls -l fdecs2.sed echo x - fdecs3.sed sed 's/^X//' > fdecs3.sed << '@FUNKY STUFF@' : doline : getsbr /[;{]/!{ N b getsbr } s/\n/ /g s/[ ][ ]*/ /g /;/{ /^[^;]*) *[a-zA-Z_{]/!{ s/^[^;]*;// /^ *$/d b doline } } /[;)] *{}/!{ N b doline } s/^ *// s/( */(/g s/ *)/)/g s/ *, */, /g s/ *; */; /g s/ *\*/ \*/g s/\* */\*/g /() *{/b no_arg s/, /, %/g s/(/(, %/ t more_t : more_t s/, %\([A-Za-z_][A-Za-z0-9_]*\)\(.*[);] *\)\([A-Za-z_][A-Za-z0-9_{} ]*\)\( *\)\(\**\1[][]*\)\([,;]\)/, \3 \5\2\3\4@\6/ s/, %\([A-Za-z_][A-Za-z0-9_]*\)\(.*[);] *\)\([A-Za-z_][A-Za-z0-9_{} ]*\)\( [^;]*, %\)\(\**\1[][]*\)\([,;]\)/, \3 \5\2\3\4@\6/ t more_t s/(, /(/ s/%/int /g s?(\([^)]*\)).*?(\1);? / register/{ s/\([A-Za-z_0-9]\) register\([^A-Za-z0-9_]\)/\1\2/g s/ register\([^A-Za-z0-9_][^A-Za-z0-9_]*[A-Za-z_][A-Za-z0-9_]*\),/ int\1,/g s/ register\([^A-Za-z0-9_]\)/ \1/g } s/ */ /g b done_a : no_arg s/).*/void);/ : done_a @FUNKY STUFF@ ls -l fdecs3.sed # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0