proto.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1990-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* proto - make prototyped C compatible with K&R, ANSI, C++
*
* output to stdout unless -r
*
* NOTE: coded for minimal library support
*/
#if !PROTO_STANDALONE
static const char usage[] =
"[-?\n@(#)$Id: proto (AT&T Research) 2012-02-20 $\n]"
"[+NAME?proto - make prototyped C source compatible with K&R, ANSI and C++]"
"[+DESCRIPTION?\bproto\b converts ANSI C prototype constructs in \afile\a"
" to constructs compatible with K&R C, ANSI C, and C++. Only files"
" with the line \b#pragma prototyped\b appearing in one of the first"
" 64 lines are processed; other files are silently ignored. Output is"
" written to the standard output unless the \b--replace\b option is"
" specified, in which case \afile\a is modified in-place.]"
"[c:comment?\ab[m[e]]]]\a are the beginning, middle, and end comment"
" characters. If \ae\a is omitted then it defaults to \ab\a. If \am\a is"
" omitted then it defaults to \ab\a. Use \"\b/*\b\" for C comments,"
" \"\b#\b\" for shell, and \"\b(*)\b\" for pascal. If \abme\a is \"\""
" (the empty string) then the comment style is determined from the"
" input \afile\a suffix; no notice is prepended if the comment"
" style cannot be determined.]:[bme:=\"/*\"]"
"[d:disable?Disable prototype conversion but still emit the identification"
" comment.]"
"[e:externs?All \bextern\b references are for \apackage\a. Some systems"
" require special attributes for imported and exported dll data symbols."
" If \b_BLD_\b\apackage\a is not defined then \bextern\b data references"
" will be assigned the dll import attribute when supported by the local"
" compiler.]:[package]"
"[f:force?Force conversion for files that do not contain"
" \b#pragma prototyped\b.]"
"[h!:header?Emit the \bproto\b header definition preamble.]"
"[i:inverse?Specifies inverse proto: classic function definitions are"
" converted to ANSI prototype form and non-ANSI directives are"
" commented out. In this case files with the line"
" \b#pragma noprototyped\b within the first 64 lines are silently"
" ignored. If \b--header\b is also specified then only \bextern\b"
" prototypes are emitted for each non-static function. This option"
" requires that all classic function formal arguments be declared,"
" i.e., omitted declarations for \bint\b formals will not generate"
" the correct prototype. Typical usage would be to first run"
" \bproto --inverse --header *.c\b to generate the external prototypes"
" that should be placed in a \b.h\b file shared by \b*.c\b and then"
" \bproto --inverse --replace *.c\b to convert the function prototypes"
" in place. Note that prototype code conditioned on \b__STDC__\b will"
" most likely confuse \b--inverse\b.]"
"[l:license?Generate a license notice comment at the top of the output"
" controlled by one or more \aname\a=\avalue\a pairs in \afile\a."
" If a \avalue\a contains space characters then it must be enclosed in"
" either single or double quotes. \aname\a may"
" be:]:[file]{"
" [+type?The license type:]{"
" [+bsd?The BSD open source license.]"
" [+cpl?The Common Public License.]"
" [+epl?The Eclipse Public License.]"
" [+gpl?The GNU Public License.]"
" [+mit?The MIT open source license.]"
" [+inline?License text already in source.]"
" [+none?No license.]"
" [+noncommercial?Non-commercial use.]"
" [+nonexclusive?Single person non-commercial use.]"
" [+open?Open source.]"
" [+proprietary?Only by individual agreement.]"
" [+special?License text in \bnotice\b.]"
" [+usage?License specific \boptget\b(3) usage strings.]"
" [+verbose?Include the disclaimer notice if any.]"
" [+zlib?The ZLIB open source license.]"
" }"
" [+author?A \b,\b separated list of \aname\a <\aemail\a> pairs.]"
" [+class?The license class. The default values are:]{"
" [+gpl?The GNU Public License.]"
" [+open?\bwww.opensource.org\b sanctioned open source.]"
" [+proprietary?Internal or non-disclosure use only.]"
" [+special?Nonstandard license text and notices.]"
" }"
" [+corporation?Within the parent, e.g., \bAT&T\b.]"
" [+company?Within the corporation, e.g., \bResearch\b.]"
" [+location?Company location.]"
" [+organization?Within the company, e.g., \bNetwork Services"
" Research Department\b.]"
" [+notice?\btype=special\b notice text with embedded newlines"
" or additional notice text listed by \btype=verbose\b.]"
" [+package?The generic software package name, e.g., \bast\b.]"
" [+parent?They own it all, e.g., \bAT&T\b.]"
" [+since?The year the software was first released.]"
" [+source?The year the input files was modified.]"
" [+start?The year the license was first applied to the software.]"
" [+url?The URL of the detailed license text, e.g.,"
" [+urlmd5?The \bmd5sum\b(1) of the downloaded URL data. Note that"
" the downloaded data may have embedded \b\\r\b not present"
" in the original source.]"
" [+query=\atext\a?If \atext\a is one of the \aname\as above"
" then its value is expanded, otherwise"
" \b${\b\aname\a\b}\b in \atext\a is expanded. The"
" result is printed as a line on the standard output"
" and \bproto\b exits. This should only be used via"
" \b--options\b.]"
"}"
"[n:sync?Output C style line syncs to retain the original line structure.]"
"[o:options?Additional space or \b,\b separated \aname=value\a \b--license\b"
" options.]:[name=value,...]"
"[p:pass?Pass input to output, even if not converted.]"
"[r:replace?Process the input files in place; original information is"
" replaced by \bproto\b output.]"
"[s:include?Output \b#include <prototyped.h>\b rather than expanding the"
" equivalent inline.]"
"[t:test?Enable test code. Use at your own risk.]"
"[v:verbose?List each file as it is processed.]"
"[x:externalize?Convert \bstatic\b function attributes to \bextern\b. Used"
" for analysis programs that only instrument \bextern\b functions.]"
"[z:zap?Disable conversion and remove \b#pragma prototyped\b.]"
"[C:copy?Convert each input \afile\a to \adirectory\a/\afile\a,"
" making intermediate directories as necessary.]:[directory]"
"[L:list?Input file names are read one per line from \afile\a.]:[file]"
"[P|+:plusplus?Convert \bextern()\b to \bextern(...)\b.]"
"[S:shell?Equivalent to \b--comment=\"#\".]"
"\n"
"\nfile ...\n"
"\n"
"[+SEE ALSO?\bcc\b(1), \bcpp\b(1)]"
;
#include <ast.h>
#include <error.h>
#include <times.h>
#endif
#define PROTOMAIN 1
/*DELAY_CONTROL*/
#ifndef __STDC__
#ifndef creat
#define creat _huh_creat
#endif
#if PROTO_STANDALONE
#ifndef access
#define access _huh_access
#endif
#ifndef ctime
#define ctime _huh_ctime
#endif
#ifndef mkdir
#define mkdir _huh_mkdir
#endif
#endif
#endif
#include <fcntl.h>
#if PROTO_STANDALONE
#include <stdio.h>
#else
#include <time.h>
#endif
#ifndef __STDC__
#endif
#ifndef O_RDONLY
#define O_RDONLY 0
#endif
#ifndef S_IRUSR
#define S_IRUSR 0400
#endif
#ifndef S_IWUSR
#define S_IWUSR 0200
#endif
#ifndef S_IXUSR
#define S_IXUSR 0100
#endif
#ifndef S_IRGRP
#define S_IRGRP 0040
#endif
#ifndef S_IWGRP
#define S_IWGRP 0020
#endif
#ifndef S_IXGRP
#define S_IXGRP 0010
#endif
#ifndef S_IROTH
#define S_IROTH 0004
#endif
#ifndef S_IWOTH
#define S_IWOTH 0002
#endif
#ifndef S_IXOTH
#define S_IXOTH 0001
#endif
#ifndef __STDC__
#endif
#if PROTO_STANDALONE
extern int access(const char*, int);
extern int mkdir(const char*, int);
#endif
#endif
#if PROTO_STANDALONE
#endif
/*
* rename newfile to oldfile
* preserve!=0 preserves atime,mtime
*/
int
{
{
if (preserve)
return -1;
}
return -1;
if (preserve)
{
}
return preserve;
}
#define utime ______utime
/*NODELAY_CONTROL*/
#include "ppproto.c"
#define PROTO_ERROR (PROTO_USER<<0)
static int
proto(char* file, char* license, char* options, char* package, char* copy, char* comment, int flags)
{
char* b;
char* e;
char* p;
int n;
int m;
int x;
int fd;
char buf[1024];
{
if (!file)
fd = 1;
else if (flags & PROTO_REPLACE)
{
x = *e;
*e = '_';
{
pppclose(b);
return flags | PROTO_ERROR;
}
*e = x;
}
else if (copy)
{
{
pppclose(b);
return flags | PROTO_ERROR;
}
e = buf + n;
if (*file != '/')
*e++ = '/';
{
for (e = buf; *e == '/'; e++);
do
{
if (*e == '/')
{
*e = 0;
{
pppclose(b);
return flags | PROTO_ERROR;
}
*e = '/';
}
} while (*e++);
{
pppclose(b);
return flags | PROTO_ERROR;
}
}
}
else
fd = 1;
while ((n = pppread(b)) > 0)
{
p = b;
for (;;)
{
{
flags |= PROTO_ERROR;
break;
}
if ((n -= m) <= 0)
break;
p += m;
}
if (m < 0)
break;
}
if (fd > 1)
{
*e = '_';
*e = x;
}
pppclose(b);
}
return flags;
}
#if !PROTO_STANDALONE
#endif
typedef struct Sufcom_s
{
char suffix[4];
char comment[4];
} Sufcom_t;
{
"c", "/*",
"cpp", "/*",
"cxx", "/*",
"c++", "/*",
"C", "/*",
"CPP", "/*",
"CXX", "/*",
"C++", "/*",
"f", "C",
"F", "C",
"h", "/*",
"hpp", "/*",
"hxx", "/*",
"H", "/*",
"HPP", "/*",
"HXX", "/*",
"ksh", "#",
"KSH", "#",
"l", "/*",
"L", "/*",
"p", "(*)",
"pas", "(*)",
"P", "(*)",
"PAS", "(*)",
"pl", "#",
"PL", "#",
"pl1", "/*",
"pli", "/*",
"PL1", "/*",
"PLI", "/*",
"sh", "#",
"SH", "#",
"sml", "(*)",
"SML", "(*)",
"y", "/*",
"Y", "/*",
};
/*
* if !comment || !*comment then return a value compatible with file
*/
static char*
{
register char* suffix;
register int i;
{
suffix = 0;
while (*file)
if (*file++ == '.')
}
return comment;
}
int
{
char* b;
char* file;
int fd;
int n;
char* op;
char* oe;
char* comment = 0;
char* copy = 0;
char* list = 0;
char* license = 0;
char* options = 0;
char* package = 0;
int flags = PROTO_HEADER;
char buf[1024];
#if PROTO_STANDALONE
{
for (;;)
{
switch (*++file)
{
case 0:
break;
case 'c':
break;
case 'd':
flags |= PROTO_DISABLE;
continue;
case 'e':
{
file = "??";
continue;
}
break;
case 'f':
flags |= PROTO_FORCE;
continue;
case 'h':
flags &= ~PROTO_HEADER;
continue;
case 'i':
flags |= PROTO_CLASSIC;
continue;
case 'l':
{
file = "??";
continue;
}
break;
case 'n':
flags |= PROTO_LINESYNC;
continue;
case 'o':
{
file = "??";
continue;
}
if (!options)
{
}
n = strlen(b);
else
{
*op++ = '\n';
op += n;
}
break;
case 'p':
flags |= PROTO_PASS;
continue;
case 'r':
flags |= PROTO_REPLACE;
continue;
case 's':
flags |= PROTO_INCLUDE;
continue;
case 't':
flags |= PROTO_TEST;
continue;
case 'v':
flags |= PROTO_VERBOSE;
continue;
case 'x':
continue;
case 'z':
continue;
case 'C':
{
file = "??";
continue;
}
break;
case 'L':
{
file = "??";
continue;
}
break;
case 'P':
case '+':
flags |= PROTO_PLUSPLUS;
continue;
case 'S':
comment = "#";
continue;
default:
/*FALLTHROUGH*/
case '?':
b = "Usage: proto [-dfhinprstvzP+S] [-C directory] [-e package] [-l file]\n [-o \"name='value' ...\"] [-L file] file ...\n";
return 2;
}
break;
}
}
#else
for (;;)
{
{
case 'c':
continue;
case 'd':
flags |= PROTO_DISABLE;
continue;
case 'e':
continue;
case 'f':
flags |= PROTO_FORCE;
continue;
case 'h':
flags &= ~PROTO_HEADER;
continue;
case 'i':
flags |= PROTO_CLASSIC;
continue;
case 'l':
continue;
case 'n':
flags |= PROTO_LINESYNC;
continue;
case 'o':
if (!options)
{
}
else
{
*op++ = '\n';
op += n;
}
continue;
case 'p':
flags |= PROTO_PASS;
continue;
case 'r':
flags |= PROTO_REPLACE;
continue;
case 's':
flags |= PROTO_INCLUDE;
continue;
case 't':
flags |= PROTO_TEST;
continue;
case 'v':
flags |= PROTO_VERBOSE;
continue;
case 'x':
continue;
case 'z':
continue;
case 'C':
continue;
case 'L':
continue;
case 'P':
flags |= PROTO_PLUSPLUS;
continue;
case 'S':
comment = "#";
continue;
case '?':
continue;
case ':':
continue;
}
break;
}
if (error_info.errors)
#endif
if (list)
{
fd = 0;
do
{
if (b > buf)
{
*b = 0;
}
} while (n > 0);
if (fd > 0)
}
if (file)
do flags = proto(file, license, options, package, copy, type(file, comment), flags); while (file = *++argv);
else if (!list)
}