home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / multi-include < prev    next >
Text File  |  1989-10-26  |  6KB  |  276 lines

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