home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume20
/
multi-include
< prev
next >
Wrap
Text File
|
1989-10-26
|
6KB
|
276 lines
Subject: v20i080: Modify files to help remove multiple #include's
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: "Fred J. E. Long" <flong@sdsu.edu>
Posting-number: Volume 20, Issue 80
Archive-name: multi-include
[ I believe this is a solution in search of a problem, but the ongoing
discussion in comp.lang.c and comp.lang.c++ indicates that lots of
people are interested in something like this. /r$ ]
Here is a very simple program I wrote after seeing the recent
controversy in comp.lang.c++ over "multiple inclusion". It just puts
#if FILENAME != 0
#define FILENAME 0
at the top of each file (if the -i option is specified) and puts
#endif /* FILENAME */
at the bottom. The -o option does likewise, but it puts the macros around
all the #includes:
#include "foobar.h"
goes to:
#ifndef FOOBAR_H
#define FOOBAR_H 1
#include "foobar.h"
#endif /* FOOBAR_H */
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# README
# include.1
# include.c
# makefile
# run_test
# test.c
# test.h
sed 's/^X//' << 'SHAR_EOF' > README
XHere is a very simple program I wrote after seeing the recent
Xcontroversy in comp.lang.c++ over "multiple inclusion". It just puts
X
X#if FILENAME != 0
X#define FILENAME 0
X
Xat the top of each file (if the -i option is specified) and puts
X
X#endif /* FILENAME */
X
Xat the bottom. The -o option does likewise, but it puts the macros around
Xall the #includes:
X
X#include "foobar.h"
X
Xgoes to:
X
X#ifndef FOOBAR_H
X#define FOOBAR_H 1
X#include "foobar.h"
X#endif /* FOOBAR_H */
X
XIt would be a good idea to backup your files before using this program.
XHave fun.
X
X----
XFred J. E. Long
Xflong@sdsu.edu, flong@midgard.ucsc.edu
X
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > include.1
X.TH INCLUDE 1 "26 October 1989"
X.UC 4
X.SH NAME
Xinclude \- eases multiple inclusion problems
X.SH SYNOPSIS
X\fBinclude \-\fR{\fBio\fR}[\fBb\fR] \fIfilename ...\fR
X.SH DESCRIPTION
X.PP
X.I Include
Xmodifies the specified files to help eliminate multiple inclusion problems.
X.PP
XOptions:
X.TP 8
X.B \-b
XThe named files are backed up. Each backup file will have the
X.B .bak
Xextension.
X.TP 8
X.B \-i
XEach file will have
X.sp
X#if FILENAME != 0
X.br
X#define FILENAME 0
X.sp
Xas the first two lines of the file, and
X.sp
X#endif /* FILENAME */
X.sp
Xwill be the last line in the file,
Xwhere FILENAME is the filename modified to be a legal macro.
X.TP 8
X.B \-o
XFor any file inclusion
X.sp
X#include "filename"
X.sp
Xyou will get
X.sp
X#ifndef FILENAME
X.br
X#define FILENAME 1
X.br
X#include "filename"
X.br
X#endif /* FILENAME */
X.sp
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > include.c
X/*
X * Fred J. E. Long
X *
X * flong@sdsu.edu
X */
X
X#include <stdio.h>
X
X#include <ctype.h>
X
Xextern char *optarg;
Xextern int optind, opterr;
X
Xint inside = 0, outside = 0, backup = 0;
X
Xvoid format(name)
Xchar *name;
X{
X printf("\n%s -{io}[b] files\n\n", name);
X printf("\ti\t#ifndef at the top, #endif at the bottom of each file\n");
X printf("\to\tPut #ifndef/#endif around all #include's\n");
X printf("\tb\tBackup all files\n");
X exit(0);
X}
X
Xvoid backup_file(name)
Xchar *name;
X{
X char tmp[200];
X
X sprintf(tmp, "cp %s %s.bak", name, name);
X if (system(tmp)) {
X printf("\nCould not make backup of %s\n", name);
X exit(1);
X }
X}
X
Xvoid update_file(tmp, name)
Xchar *tmp, *name;
X{
X char command[200];
X
X sprintf(command, "mv %s %s", tmp, name);
X if (system(command)) {
X printf("\nCould not update %s\n", name);
X exit(1);
X }
X}
X
Xchar *is_include(name)
Xchar *name;
X{
Xstatic char tmp[200];
X int i;
X
X i = sscanf(name, "#%*[ \t]include%*[ \t]%*1[\"<]%[^\">]%*1[\">]", tmp);
X if (i == 1) return(tmp);
X else return(0);
X}
X
Xchar *convert(name)
Xchar *name;
X{
Xstatic char tmp[200], *t;
X
X for (t = tmp; *name; name++, t++) {
X if (isalpha(*name)) {
X if (islower(*name)) *t = toupper(*name);
X else *t = *name;
X }
X else *t = '_';
X }
X *t = 0;
X return(tmp);
X}
X
Xvoid do_for(name)
Xchar *name;
X{
X char *tmp_name, line[500], *tmp, *mktemp();
X FILE *fi, *fo;
X
X if (backup) backup_file(name);
X
X if (!(fi = fopen(name, "r"))) {
X printf("\nCould not open %s\n", name);
X exit(1);
X }
X tmp_name = mktemp("/tmp/includeXXXXXX");
X if (!(fo = fopen(tmp_name, "w"))) {
X printf("\nCould not open %s\n", tmp_name);
X exit(1);
X }
X if (inside) {
X fprintf(fo, "#if %s != 0\n", convert(name));
X fprintf(fo, "#define %s 0\n\n", convert(name));
X }
X while (fgets(line, 500, fi)) {
X if (!outside || !(tmp = is_include(line))) {
X fputs(line, fo);
X continue;
X }
X fprintf(fo, "#ifndef %s\n", convert(tmp));
X fprintf(fo, "#define %s 1\n", convert(tmp));
X fputs(line, fo);
X fprintf(fo, "#endif /* %s */\n\n", tmp);
X }
X if (inside) {
X fprintf(fo, "\n#endif /* %s */\n", name);
X }
X fclose(fi);
X fclose(fo);
X update_file(tmp_name, name);
X}
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X int c;
X
X while ((c = getopt(argc, argv, "iob")) != EOF) {
X switch (c) {
X case 'i': inside = 1; break;
X case 'o': outside = 1; break;
X case 'b': backup = 1; break;
X default: format(argv[0]);
X }
X }
X if (inside + outside == 0) {
X printf("\nNothing to do; choose -i, -o, or both\n");
X format(argv[0]);
X }
X for (; optind < argc; optind++) do_for(argv[optind]);
X
X return(0);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > makefile
Xinclude: include.c
X cc -o include include.c
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > run_test
Xinclude -ib test.h
Xinclude -ob test.c
Xcc -c test.c
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > test.c
X#include "test.h"
Xint i = FOOBAR;
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > test.h
X#define FOOBAR 2
SHAR_EOF
exit