home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume20 / multincl.ude < prev    next >
Encoding:
Text File  |  1989-10-27  |  5.9 KB  |  283 lines

  1. Path: wuarchive!uwm.edu!cs.utexas.edu!uunet!bbn.com!rsalz
  2. From: rsalz@uunet.uu.net (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v20i080:  Modify files to help remove multiple #include's
  5. Message-ID: <2096@papaya.bbn.com>
  6. Date: 27 Oct 89 17:19:39 GMT
  7. Lines: 273
  8. Approved: rsalz@uunet.UU.NET
  9.  
  10. Submitted-by: "Fred J. E. Long" <flong@sdsu.edu>
  11. Posting-number: Volume 20, Issue 80
  12. Archive-name: multi-include
  13.  
  14. [  I believe this is a solution in search of a problem, but the ongoing
  15.    discussion in comp.lang.c and comp.lang.c++ indicates that lots of
  16.    people are interested in something like this.  /r$ ]
  17.  
  18. Here is a very simple program I wrote after seeing the recent
  19. controversy in comp.lang.c++ over "multiple inclusion".  It just puts
  20.     #if FILENAME != 0
  21.     #define FILENAME 0
  22. at the top of each file (if the -i option is specified) and puts
  23.     #endif /* FILENAME */
  24. at the bottom.  The -o option does likewise, but it puts the macros around
  25. all the #includes:
  26.     #include "foobar.h"
  27. goes to:
  28.     #ifndef FOOBAR_H
  29.     #define FOOBAR_H 1
  30.     #include "foobar.h"
  31.     #endif /* FOOBAR_H */
  32.     
  33. #!/bin/sh
  34. # shar:    Shell Archiver
  35. #    Run the following text with /bin/sh to create:
  36. #    README
  37. #    include.1
  38. #    include.c
  39. #    makefile
  40. #    run_test
  41. #    test.c
  42. #    test.h
  43. sed 's/^X//' << 'SHAR_EOF' > README
  44. XHere is a very simple program I wrote after seeing the recent
  45. Xcontroversy in comp.lang.c++ over "multiple inclusion".  It just puts
  46. X
  47. X#if FILENAME != 0
  48. X#define FILENAME 0
  49. X
  50. Xat the top of each file (if the -i option is specified) and puts
  51. X
  52. X#endif /* FILENAME */
  53. X
  54. Xat the bottom.  The -o option does likewise, but it puts the macros around
  55. Xall the #includes:
  56. X
  57. X#include "foobar.h"
  58. X
  59. Xgoes to:
  60. X
  61. X#ifndef FOOBAR_H
  62. X#define FOOBAR_H 1
  63. X#include "foobar.h"
  64. X#endif /* FOOBAR_H */
  65. X
  66. XIt would be a good idea to backup your files before using this program.
  67. XHave fun.
  68. X
  69. X----
  70. XFred J. E. Long
  71. Xflong@sdsu.edu, flong@midgard.ucsc.edu
  72. X
  73. SHAR_EOF
  74. sed 's/^X//' << 'SHAR_EOF' > include.1
  75. X.TH INCLUDE 1 "26 October 1989"
  76. X.UC 4
  77. X.SH NAME
  78. Xinclude \- eases multiple inclusion problems
  79. X.SH SYNOPSIS
  80. X\fBinclude \-\fR{\fBio\fR}[\fBb\fR] \fIfilename ...\fR
  81. X.SH DESCRIPTION
  82. X.PP
  83. X.I Include
  84. Xmodifies the specified files to help eliminate multiple inclusion problems.
  85. X.PP
  86. XOptions:
  87. X.TP 8
  88. X.B \-b
  89. XThe named files are backed up.  Each backup file will have the
  90. X.B .bak
  91. Xextension.
  92. X.TP 8
  93. X.B \-i
  94. XEach file will have
  95. X.sp
  96. X#if FILENAME != 0
  97. X.br
  98. X#define FILENAME 0
  99. X.sp
  100. Xas the first two lines of the file, and
  101. X.sp
  102. X#endif /* FILENAME */
  103. X.sp
  104. Xwill be the last line in the file,
  105. Xwhere FILENAME is the filename modified to be a legal macro.
  106. X.TP 8
  107. X.B \-o
  108. XFor any file inclusion
  109. X.sp
  110. X#include "filename"
  111. X.sp
  112. Xyou will get
  113. X.sp
  114. X#ifndef FILENAME
  115. X.br
  116. X#define FILENAME 1
  117. X.br
  118. X#include "filename"
  119. X.br
  120. X#endif /* FILENAME */
  121. X.sp
  122. SHAR_EOF
  123. sed 's/^X//' << 'SHAR_EOF' > include.c
  124. X/*
  125. X *    Fred J. E. Long
  126. X *
  127. X *    flong@sdsu.edu
  128. X */
  129. X
  130. X#include <stdio.h>
  131. X
  132. X#include <ctype.h>
  133. X
  134. Xextern    char    *optarg;
  135. Xextern    int    optind, opterr;
  136. X
  137. Xint    inside = 0, outside = 0, backup = 0;
  138. X
  139. Xvoid    format(name)
  140. Xchar    *name;
  141. X{
  142. X    printf("\n%s -{io}[b] files\n\n", name);
  143. X    printf("\ti\t#ifndef at the top, #endif at the bottom of each file\n");
  144. X    printf("\to\tPut #ifndef/#endif around all #include's\n");
  145. X    printf("\tb\tBackup all files\n");
  146. X    exit(0);
  147. X}
  148. X
  149. Xvoid    backup_file(name)
  150. Xchar    *name;
  151. X{
  152. X    char    tmp[200];
  153. X
  154. X    sprintf(tmp, "cp %s %s.bak", name, name);
  155. X    if (system(tmp)) {
  156. X        printf("\nCould not make backup of %s\n", name);
  157. X        exit(1);
  158. X    }
  159. X}
  160. X
  161. Xvoid    update_file(tmp, name)
  162. Xchar    *tmp, *name;
  163. X{
  164. X    char    command[200];
  165. X
  166. X    sprintf(command, "mv %s %s", tmp, name);
  167. X    if (system(command)) {
  168. X        printf("\nCould not update %s\n", name);
  169. X        exit(1);
  170. X    }
  171. X}
  172. X
  173. Xchar    *is_include(name)
  174. Xchar    *name;
  175. X{
  176. Xstatic    char    tmp[200];
  177. X    int    i;
  178. X
  179. X    i = sscanf(name, "#%*[ \t]include%*[ \t]%*1[\"<]%[^\">]%*1[\">]", tmp);
  180. X    if (i == 1) return(tmp);
  181. X    else return(0);
  182. X}
  183. X
  184. Xchar    *convert(name)
  185. Xchar    *name;
  186. X{
  187. Xstatic    char    tmp[200], *t;
  188. X
  189. X    for (t = tmp; *name; name++, t++) {
  190. X        if (isalpha(*name)) {
  191. X            if (islower(*name)) *t = toupper(*name);
  192. X            else *t = *name;
  193. X        }
  194. X        else *t = '_';
  195. X    }
  196. X    *t = 0;
  197. X    return(tmp);
  198. X}
  199. X
  200. Xvoid    do_for(name)
  201. Xchar    *name;
  202. X{
  203. X    char    *tmp_name, line[500], *tmp, *mktemp();
  204. X    FILE    *fi, *fo;
  205. X
  206. X    if (backup) backup_file(name);
  207. X
  208. X    if (!(fi = fopen(name, "r"))) {
  209. X        printf("\nCould not open %s\n", name);
  210. X        exit(1);
  211. X    }
  212. X    tmp_name = mktemp("/tmp/includeXXXXXX");
  213. X    if (!(fo = fopen(tmp_name, "w"))) {
  214. X        printf("\nCould not open %s\n", tmp_name);
  215. X        exit(1);
  216. X    }
  217. X    if (inside) {
  218. X        fprintf(fo, "#if %s != 0\n", convert(name));
  219. X        fprintf(fo, "#define %s 0\n\n", convert(name));
  220. X    }
  221. X    while (fgets(line, 500, fi)) {
  222. X        if (!outside || !(tmp = is_include(line))) {
  223. X            fputs(line, fo);
  224. X            continue;
  225. X        }
  226. X        fprintf(fo, "#ifndef %s\n", convert(tmp));
  227. X        fprintf(fo, "#define %s 1\n", convert(tmp));
  228. X        fputs(line, fo);
  229. X        fprintf(fo, "#endif /* %s */\n\n", tmp);
  230. X    }
  231. X    if (inside) {
  232. X        fprintf(fo, "\n#endif /* %s */\n", name);
  233. X    }
  234. X    fclose(fi);
  235. X    fclose(fo);
  236. X    update_file(tmp_name, name);
  237. X}
  238. X
  239. Xmain(argc, argv)
  240. Xint    argc;
  241. Xchar    **argv;
  242. X{
  243. X    int    c;
  244. X
  245. X    while ((c = getopt(argc, argv, "iob")) != EOF) {
  246. X        switch (c) {
  247. X        case 'i':    inside = 1; break;
  248. X        case 'o':    outside = 1; break;
  249. X        case 'b':    backup = 1; break;
  250. X        default:    format(argv[0]);
  251. X        }
  252. X    }
  253. X    if (inside + outside == 0) {
  254. X        printf("\nNothing to do; choose -i, -o, or both\n");
  255. X        format(argv[0]);
  256. X    }
  257. X    for (; optind < argc; optind++) do_for(argv[optind]);
  258. X
  259. X    return(0);
  260. X}
  261. SHAR_EOF
  262. sed 's/^X//' << 'SHAR_EOF' > makefile
  263. Xinclude:    include.c
  264. X        cc -o include include.c
  265. SHAR_EOF
  266. sed 's/^X//' << 'SHAR_EOF' > run_test
  267. Xinclude -ib test.h
  268. Xinclude -ob test.c
  269. Xcc -c test.c
  270. SHAR_EOF
  271. sed 's/^X//' << 'SHAR_EOF' > test.c
  272. X#include "test.h"
  273. Xint    i = FOOBAR;
  274. SHAR_EOF
  275. sed 's/^X//' << 'SHAR_EOF' > test.h
  276. X#define    FOOBAR 2
  277. SHAR_EOF
  278. exit
  279.  
  280. -- 
  281. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  282. Use a domain-based address or give alternate paths, or you may lose out.
  283.