lbl.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /* (C) C.D.F. Miller, Heriot-Watt University, March 1984
  2. *
  3. * Permission is hereby given to reproduce or modify this
  4. * software freely, provided that this notice be retained,
  5. * and that no use be made of the software for commercial
  6. * purposes without the express written permission of the
  7. * author.
  8. */
  9. /* lbl.c:
  10. * main program - decode switches and arguments
  11. * and process each input file.
  12. * usage:
  13. * lbl [ -d<char> ] [ -m<macro> ] [ -l ] [ -s ]
  14. * -d <char> delimits in-line occurrences of a tag
  15. * -m <macro> defines a tag value
  16. * -l list label definitions
  17. * -s suppress nroff output (implies -l)
  18. * defaults:
  19. * -d@ -mL=
  20. */
  21. #include <bsd/string.h>
  22. #include <unistd.h>
  23. #include <stdlib.h>
  24. #include <err.h>
  25. #include <sysexits.h>
  26. #include <limits.h>
  27. #include <assert.h>
  28. #include "lbl.h"
  29. #include "signals.h"
  30. #include "scan.h"
  31. #include "rescan.h"
  32. #include "list.h"
  33. #include "externs.h"
  34. int decode(int argc, char *argv[]);
  35. /** Size of macroname[] */
  36. static const int MACRONAME_MAX = 3;
  37. int
  38. main(int argc, char *argv[])
  39. {
  40. int nflags;
  41. int anydone = 0;
  42. static char standard[] = "standard input";
  43. if (argc != 0) {
  44. argc--;
  45. progname = *(argv++);
  46. }
  47. nflags = decode(argc, argv);
  48. argc -= nflags;
  49. argv += nflags;
  50. /*
  51. * Remaining arguments must be filenames; treat "-" specially as
  52. * standard input. If no arguments, use atandard input.
  53. */
  54. /*
  55. * Pass 1: copy to temp file, building table of tags
  56. */
  57. if (!sflag) {
  58. mktemp(tempname);
  59. if ((tempfile = fopen(tempname, "w")) == NULL)
  60. errx(EX_CANTCREAT, "%scannot make temporary file",
  61. maybe_loc());
  62. setsignals();
  63. }
  64. if (argc == 0) {
  65. scan(standard, stdin);
  66. anydone = 1;
  67. }
  68. else {
  69. while (argc != 0) {
  70. if (strcmp(argv[0], "-") == 0) {
  71. anydone = 1;
  72. scan(standard, stdin);
  73. }
  74. else {
  75. FILE *input;
  76. if ((input = fopen(argv[0], "r")) == NULL)
  77. warnx("%scannot open %s", maybe_loc(),
  78. argv[0]);
  79. else {
  80. anydone = 1;
  81. scan(argv[0], input);
  82. fclose(input);
  83. }
  84. }
  85. argc--;
  86. argv++;
  87. }
  88. }
  89. if (!sflag)
  90. fclose(tempfile);
  91. if (lflag)
  92. listdefs();
  93. /*
  94. * Pass 2: translate tags
  95. */
  96. if (!anydone) {
  97. unlink(tempname);
  98. exit(3);
  99. }
  100. if (!sflag) {
  101. if ((tempfile = fopen(tempname, "r")) == NULL)
  102. errx(EX_NOINPUT,
  103. "%stemporary file vanished before rescan!",
  104. maybe_loc());
  105. rescan();
  106. unlink(tempname);
  107. }
  108. exit(0);
  109. }
  110. /* Decode argument list */
  111. int
  112. decode(int argc, char *argv[])
  113. {
  114. int ch;
  115. int nflags = 0;
  116. while ((ch = getopt(argc, argv, ":d:m:ls")) != -1) {
  117. switch (ch) {
  118. case 'd':
  119. if (strlen(optarg) != 1)
  120. errx(EX_USAGE,
  121. "%sdelimiter must be 1 character",
  122. maybe_loc());
  123. delimiter = optarg[0];
  124. break;
  125. case 'm':
  126. if (strlen(optarg) != 2)
  127. errx(EX_USAGE,
  128. "%smacro name must be 2 characters",
  129. maybe_loc());
  130. strlcpy(macroname, optarg, MACRONAME_MAX);
  131. break;
  132. case 'l':
  133. lflag = 1;
  134. break;
  135. case 's':
  136. lflag = sflag = 1;
  137. break;
  138. case ':':
  139. assert(optopt == 'd' || optopt == 'm');
  140. switch (optopt) {
  141. case 'd':
  142. errx(EX_USAGE, "%smissing delimiter after -d",
  143. maybe_loc());
  144. /*
  145. * NOTREACHED
  146. */
  147. case 'm':
  148. errx(EX_USAGE,
  149. "%smacro name must be 2 characters",
  150. maybe_loc());
  151. /*
  152. * NOTREACHED
  153. */
  154. }
  155. break;
  156. case '?':
  157. default:
  158. errx(EX_USAGE, "%sunknown flag '%c'", maybe_loc(),
  159. optopt);
  160. /*
  161. * NOTREACHED
  162. */
  163. }
  164. nflags++;
  165. }
  166. return nflags;
  167. }
  168. char *
  169. maybe_loc(void)
  170. {
  171. static char result[LINE_MAX];
  172. if (filename != NULL)
  173. snprintf(result, LINE_MAX, "%s, line %ld - ", filename,
  174. fileline);
  175. else
  176. result[0] = '\x00';
  177. return result;
  178. }