[comp.unix.questions] I need to create ANSI C function prototypes.

ljz@fxgrp.UUCP (Lloyd Zusman) (02/03/88)

I'm looking for a program that will take old-fashioned C code and
produce ANSI C function prototypes.

For example, consider the following program fragment ...

	char *foo(a, b, c)
	char *c;
	int b;
	{ ... }

	int bar(x, y)
	struct bonzo *x;
	MYTYPE *y;
	{ ... }

This program would produce something similar to the following:

	char *foo(char *a, int b, int c);

	int bar(struct bonzo *x, MYTYPE *y);

Musts:
------

(1) This program must run under unix.

(2) It mustn't alter the original source file, but must write its
    output to stdout, another file, etc.

(3) Notice that there is no explicit declaration for the 'c' argument
    in the foo() function in the above example, and hence the argument
    defaults to an 'int'.  The program must handle this case.

I know that there are C compilers that run under MSDOS which optionally
do this sort of thing, but these programs would violate "must" number 1.

It also would be nice if source code were available.

Any suggestions?


---
    Lloyd Zusman
    Master Byte Software
    Los Gatos, California		Internet:   fxgrp!ljz@ames.arpa
    "We take things well in hand."	UUCP:	    ...!ames!fxgrp!ljz

davidsen@steinmetz.steinmetz.UUCP (William E. Davidsen Jr) (02/10/88)

In article <201@fxgrp.UUCP> fxgrp!ljz@ames.arpa (Lloyd Zusman) writes:
>
>I'm looking for a program that will take old-fashioned C code and
>produce ANSI C function prototypes.

Microsoft C for MS-DOS, Xenix C for UNIX. There is an option to do this,
the output is sent to stdout. You may want to edit it for the global
variable declarations, but it works.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs | seismo}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

brianc@cognos.uucp (Brian Campbell) (02/11/88)

In article <201@fxgrp.UUCP> fxgrp!ljz@ames.arpa (Lloyd Zusman) writes:
! I'm looking for a program that will take old-fashioned C code and
! produce ANSI C function prototypes.
! 
! For example, consider the following program fragment ...
! 
! 	char *foo(a, b, c)
! 	char *c;
! 	int b;
! 	{ ... }
!
! This program would produce something similar to the following:
! 
! 	char *foo(char *a, int b, int c);

I'm sure you meant to say "char *a;" in the program fragment, but I
won't comment on that...

I tried to do this once before.  I failed.  I wanted to have lint
create a lint-library for each source file, but lint libraries are not
particularly readable (they're not textual).  Anyway, perhaps someone
who knows a little more about the format of lint libraries can post
the information, or better yet, write a program that takes a lint
library and produces function prototypes?

Presumably you won't have to generate the prototypes too often.
-- 
Brian Campbell        uucp: decvax!utzoo!dciem!nrcaer!cognos!brianc
Cognos Incorporated   mail: POB 9707, 3755 Riverside Drive, Ottawa, K1G 3Z4
(613) 738-1440        fido: (613) 731-2945 300/1200, sysop@1:163/8

clewis@spectrix.UUCP (Chris R. Lewis) (02/13/88)

In article <2273@cognos.UUCP> brianc@cognos.UUCP (Brian Campbell) writes:
>In article <201@fxgrp.UUCP> fxgrp!ljz@ames.arpa (Lloyd Zusman) writes:
>! I'm looking for a program that will take old-fashioned C code and
>! produce ANSI C function prototypes.
>! ...
>! This program would produce something similar to the following:
>! 
>! 	char *foo(char *a, int b, int c);

This is probably not to hard to do with awk.  Swallow a whole function
definition until the leading brace and then rewrite it.  With YACC (this
will probably work much better): find a yacc grammar for C.  In the
parameter declaration portion, insert actions to reformat the text and
spit it out.  Don't emit anything else.

>I tried to do this once before.  I failed.  I wanted to have lint
>create a lint-library for each source file, but lint libraries are not
>particularly readable (they're not textual).

An easy hack:

Take the lint shell file.  Make a copy.  Modify it so that it saves
the output of the "lint1" pass.  Delete the lint2 pass.  Run it on
the sources you want to have lint libraries for.  Viola!  The stuff
you saved is the lint library.  Only one idiosyncrasy: if any of the
library routines have lint errors, you'll see these lint errors on
every invocation lint you use these new lint libraries on.  And, I
expect that the libraries would be bigger than they could be.

Or, use my first suggestion, except that you'll have to emit the
function declaration in the order it comes in (rather than make it
look like ANSI) plus replace the body with:

	{	return(<dummy variable of the function's type>);	}
-- 
Chris Lewis, Spectrix Microsystems Inc,
UUCP: {uunet!mnetor, utcsri!utzoo, lsuc, yunexus}!spectrix!clewis
Phone: (416)-474-1955

michael@orcisi.UUCP (Michael Herman) (02/13/88)

> Take the lint shell file.  Make a copy.  Modify it so that it saves
> the output of the "lint1" pass.  Delete the lint2 pass.  Run it on
> the sources you want to have lint libraries for.  Viola!  The stuff
> you saved is the lint library.  Only one idiosyncrasy: if any of the
> library routines have lint errors, you'll see these lint errors on
> every invocation lint you use these new lint libraries on.  And, I
> expect that the libraries would be bigger than they could be.

As I remember, this would work for simple/basic types but fails for
typedefs and structs because the lint parser (usually the same code
used in the C compiler) doesn't keep the typedef names around.  To
compound matters, lint1 passes the length of structs and not their
names.  You have to internally modify lint1 and lint2 to pass the
actual names.

The easiest way of checking all this out is to turn on lint's internal
debug option (-m or -d or -z or somesuch).  This will give you a very
good idea of what lint is really (not) doing.

Under MS-DOS, the MS C compiler has a -Zg option which writes the prototypes
of the supplied source file to stdout.

ljz@ames.arpa (Lloyd Zusman, Master Byte Software) (02/16/88)

In article <1183@orcisi.UUCP> michael@orcisi.UUCP (Michael Herman) writes:
>> Take the lint shell file.  Make a copy.  Modify it so that it saves
>> the output of the "lint1" pass.  Delete the lint2 pass.  Run it on
>> the sources you want to have lint libraries for.  Viola!  The stuff
>> you saved is the lint library.  ...
>
> ...
>
>Under MS-DOS, the MS C compiler has a -Zg option which writes the prototypes
>of the supplied source file to stdout.

Thanks to all the people who responded to this question of mine.
Unfortunately, in my original question I mentioned the Microsoft C
compiler under MSDOS and rejected it, as this MUST run under Unix.

The purpose for my query was NOT to come up with an aid to building
lint libraries.  We want to be able to port our code from
"old-fashined" C to ANSI C, and that is what motivated my query.
But I will still explore this approach.

Judging from the responses I have gotten, this is a more difficult
problem than I had first imagined.

Something has occurred to me, however.  Recently, someone posted the a
yacc grammar for ANSI C to one of the comp.sources newsgroups.  After
scratching my head a while, I realized that a yacc grammar for
"old-fashioned" C could be very helpful for me in solving this
function-prototype problem: I could use it to positively locate
function definitions and then a relatively small amount of parsing
could isolate the rest of the information I need to generate the
function prototypes I desire.

So, does anyone have a yacc grammar for "old-fashioned" C that he or she
would be willing to send to me?  I'm very weak on grammars, but once
I have one, I could use it in creating a program that builds ANSI C
function prototypes from "old-fashioned" C code.  I would then gladly
post the finished product to comp.sources.whatever.


---
    Lloyd Zusman
    Master Byte Software
    Los Gatos, California		Internet:   fxgrp!ljz@ames.arpa
    "We take things well in hand."	UUCP:	    ...!ames!fxgrp!ljz

dcw@doc.ic.ac.uk (Duncan C White) (02/18/88)

Hi there everyone,

Several times in the last six months, in various newsgroups, there
have been requests such as Lloyd Zusman's ( fxgrp!ljz@ames.arpa ) :

> I'm looking for a program that will take old-fashioned C code and
> produce ANSI C function prototypes.
> ...
> This program would produce something similar to the following:
> 
> 	char *foo(char *a, int b, int c);

Sometime last year, I started using my Atari ST for weekend development -
for fairly small programs.
The compiler I have allows prototypes, so I thought that a tool to
automagically whip up suitable external declarations might be useful.

In consequence, over one such weekend [and subsequent spare time]
I have written a first approximation :-) of such a utility.

It has, however, the following restrictions:

1).	each line is parsed to see if it "looks like" a function
	declaration.... so the entire decln [return type, name,
	param list] must be placed all on one line...
	anything else was too complex for a weekend :-)

2).	I didn't bother putting in arrays cos I always use pointers..

3).	It will not accept "complex" declarations like
		char *(**f)()
	[ie. pointers to functions..]

4).	It will not accept something like:
		struct fred *zippo();
	because it scans for a SINGLE id, followed by any no of stars...
	[reason: I always typedef or #define struct fred as FRED]

In article <445@spectrix.UUCP> clewis@spectrix.UUCP (Chris R. Lewis) writes:
>This is probably not to hard to do with awk.  Swallow a whole function
>definition until the leading brace and then rewrite it.

Hmm... very UNIX specific...

>.... With YACC (this
>will probably work much better): find a yacc grammar for C.  In the
>parameter declaration portion, insert actions to reformat the text and
>spit it out.  Don't emit anything else.
>

This is obviously the way to go....  anyone got a PD grammar for C ?
YACC if necessary, recursive descent preferred...


If anyone's interested, I also wrote a makefile builder, which analyses the
sources of a multi-module C program, and attempts to build the relationships
contained therein:
it only works, of course, if you program in a MODULAR fashion ( ie. a file x.h
is an "interface" for module x, and all users of x - and x.c itself - must
#include x.h )

The tool emits makefiles for any one of UNIX, Lattice C on Atari ST, MicroSoft C
for IBM PC...

[ Don't tell me about make depend.... that's very UNIX specific ]


If anyone is interested in either of these, mail me: they're about 8k source
each.  They are public domain [in the non-strictly-legal, USENET sense, ie.
don't use it commercially, I accept no responsibility etc]

I should mention, however, that our mailer experiences difficulties sending mail
to people with UUCP mail addresses...  i think incoming mail is ok, but I may
not be able to reply to it!
Perhaps it would be better if I simply post either/both to the net ?

[Say ten more "yes, post it **please**" than "arrgh, no..." responses?]

	Duncan.

----------------------------------------------------------------------------
Duncan White,           |       Flying is the art of aiming oneself
Dept. Of Computing,     |       at the ground and missing.
Imperial College,       |               -- Douglas Adams, So Long and Thanks
London SW7, England     |                  for all the fish.

brianc@cognos.uucp (Brian Campbell) (02/18/88)

In article <201@fxgrp.UUCP> fxgrp!ljz@ames.arpa (Lloyd Zusman) writes:
! I'm looking for a program that will take old-fashioned C code and
! produce ANSI C function prototypes.

In article <2273@cognos.UUCP> brianc@cognos.UUCP (Brian Campbell) writes:
! I tried to do this once before.  I failed.  I wanted to have lint
! create a lint-library for each source file, but lint libraries are not
! particularly readable (they're not textual).

In article <445@spectrix.UUCP> clewis@spectrix.UUCP (Chris R. Lewis) writes:
! An easy hack:
! 
! Take the lint shell file.  Make a copy.  Modify it so that it saves
! the output of the "lint1" pass.  Delete the lint2 pass.  Run it on
! the sources you want to have lint libraries for.  Viola!  The stuff
! you saved is the lint library.

Not quite so simple.  The lint "shell file" on this system (Sun Unix 4.2
Release 3.2) is not a script but a binary executable.  Doesn't anyone know
the format of the compiled lint library?
-- 
Brian Campbell        uucp: decvax!utzoo!dciem!nrcaer!cognos!brianc
Cognos Incorporated   mail: POB 9707, 3755 Riverside Drive, Ottawa, K1G 3Z4
(613) 738-1440        fido: (613) 731-2945 300/1200, sysop@1:163/8