home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / sources / misc / 3779 < prev    next >
Encoding:
Text File  |  1992-07-26  |  12.8 KB  |  394 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: dmeggins@acadvm1.uottawa.ca (David Megginson)
  4. Subject:  v31i055:  petags - generate emacs TAGS for arbitrary file types, Part01/01
  5. Message-ID: <1992Jul27.022913.1152@sparky.imd.sterling.com>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: 1d9086f77a068e8dbf6fbc7ded3ac972
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: University of Toronto - EPAS
  10. Date: Mon, 27 Jul 1992 02:29:13 GMT
  11. Approved: kent@sparky.imd.sterling.com
  12. Lines: 380
  13.  
  14. Submitted-by: dmeggins@acadvm1.uottawa.ca (David Megginson)
  15. Posting-number: Volume 31, Issue 55
  16. Archive-name: petags/part01
  17. Environment: perl
  18.  
  19. Required to run: Gnu Emacs, Perl
  20.  
  21. I developed this program in an earlier version so that I could use the
  22. Gnu Emacs TAGS features with my 300-page thesis on Old English
  23. spelling, written in SGML using a modified version of the QWERTZ DTD.
  24. I decided to make the program more general and post it.
  25.  
  26. This is by no means the final word on TAGS -- it does not actually
  27. parse files, it only looks for regular-expression matches -- but it is
  28. effective for a surprisingly large range of files.  I have included a
  29. detailed README.
  30.  
  31. If no one else writes anything better, I would be happy to see this
  32. script appear in the etc/ directory for the next Gnu Emacs distribution 
  33. (I have released it under the Gnu license).  
  34.  
  35. Enjoy!
  36.  
  37. David Megginson
  38. dmeggins@acadvm1.uottawa.ca
  39.  
  40. ==============================CUT HERE==============================
  41. #! /bin/sh
  42. # This is a shell archive.  Remove anything before this line, then unpack
  43. # it by saving it into a file and typing "sh file".  To overwrite existing
  44. # files, type "sh file -c".  You can also feed this as standard input via
  45. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  46. # will see the following message at the end:
  47. #        "End of shell archive."
  48. # Contents:  README petags
  49. # Wrapped by meggin@epas on Fri Jul 24 10:36:50 1992
  50. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  51. if test -f 'README' -a "${1}" != "-c" ; then 
  52.   echo shar: Will not clobber existing file \"'README'\"
  53. else
  54. echo shar: Extracting \"'README'\" \(5279 characters\)
  55. sed "s/^X//" >'README' <<'END_OF_FILE'
  56. X                  -*-Text-*-
  57. X
  58. X             PETAGS Version 0.1:
  59. X
  60. X    A perl script to generate emacs TAGS for arbitrary file types.
  61. X
  62. X
  63. X  (c) Copyright 1992 by David Megginson (dmeggins@acadvm1.uottawa.ca)
  64. X
  65. X  Petags is free software; you can redistribute it and/or modify it
  66. X  under the terms of the GNU General Public License as published by the
  67. X  Free Software Foundation; either version 1, or (at your option) any
  68. X  later version.
  69. X
  70. X  Petags is distributed in the hope that it will be useful, but WITHOUT
  71. X  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  72. X  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  73. X  for more details.
  74. X
  75. X  The program Perl is required to run this program, and Gnu Emacs is
  76. X  required to use the TAGS file which it creates -- you should have
  77. X  received a copy of the GNU General Public License along with both of
  78. X  these programs; see the file COPYING.  If not, write to the Free
  79. X  Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  80. X
  81. X
  82. XINTRODUCTION
  83. X
  84. XThis is my first attempt at generating emacs TAGS for arbitrary file
  85. Xtypes.  Petags's usage is similar to that of tags or etags, except
  86. Xthat you must supply the program with a list of (perl-style)
  87. Xregular-expression patterns for the lines which you want tagged.  The
  88. Xusage is as follows:
  89. X
  90. X  petags [-e <pat> -f <file> -o <output> -d <dir>] FILES...
  91. X
  92. X  -e <pat>    Add all lines containing <pat> to the TAGS file.
  93. X  -f <file>   Like -e, but read patterns from <file>, one on each line.
  94. X  -o <output> Use <output> rather than TAGS for the tag file name.
  95. X  -d <dir>    With the -f option, look for pattern files in <dir>
  96. X              if they are not in the current directory.
  97. X  --          End options.
  98. X
  99. X
  100. XPATTERN FILES
  101. X
  102. XThere must be at least one -e or -f option on the command line, or the
  103. Xprogram will fail.  For general usage, it is probably best to make
  104. Xseveral pattern files and keep them in a central place, like
  105. X/usr/local/lib/perltags.  You may specify this directory on the
  106. Xcommand line using the -d option, or in the environment variable
  107. XPETAGSDIR -- in either case, you MUST omit the final slash.  The -d
  108. Xoption overrides the environment variable.  Using this method, you can
  109. Xcreate a file of regular-expression patterns for the programming
  110. Xlanguage /usr/local/lib/perltags/foo, set PETAGSDIR to
  111. X"/usr/local/lib/perltags", then simply use the command
  112. X
  113. X  petags -d foo *.pl
  114. X
  115. Xto create TAGS for every .pl file in the current directory.
  116. X
  117. X
  118. XUSING THE PROGRAM
  119. X
  120. XA _real_ tags program would actually parse its input files -- this
  121. Xprogram merely matches regular-expression patterns, so it is easy to
  122. Xconfuse.  Unfortunately, the Gnu emacs TAGS file format does not seem
  123. Xto allow multi-line tags, so this program is confined to regular
  124. Xexpressions which appear entirely on a single line.  Even with these
  125. Xlimitation (and depending on your formatting preferences), petags
  126. Xworks for a surprising number of file types.  For example, in an SGML
  127. Xfile using the QWERTZ DTD, which might contain text like this:
  128. X
  129. X  <chapt> Introduction
  130. X  <label id="ChIntro">
  131. X
  132. X  <sect> Background
  133. X
  134. X  blah blah blah
  135. X
  136. X  <sect1> History of the Background
  137. X
  138. X  blah blah blah
  139. X
  140. Xyou could create a pattern file with these three regular expressions
  141. X(one on each line)
  142. X
  143. X  <chapt
  144. X  <sect
  145. X  <label
  146. X
  147. Xto tag every chapter, section (and subsection) and label in the text.
  148. XOf course, if you have a label over a line break, like
  149. X
  150. X                   ...<label
  151. X  id="LookHere">...
  152. X
  153. Xthe system falls apart, but if you format carefully, you should be
  154. Xable to use this program (I used an earlier version for my 300-page
  155. Xthesis on Old English spelling, and it worked perfectly).  For Prolog,
  156. Xfor example, the pattern ":-" should guarantee that every regular
  157. Xpredicate appears in the TAGS file, and "-->" will also include
  158. Xgrammar rules.  For Perl, the pattern "\bsub\b" should include all
  159. Xsubroutine definitions for Perl libraries, as long as the subroutine
  160. Xname appears on the same line as "sub".
  161. X
  162. X
  163. XTROUBLESHOOTING
  164. X
  165. X1) Make sure that you edit the script to set the correct path to Perl
  166. X   (both in the #! line and in the "eval..." line).  If you are using
  167. X   MeSsyDOS, you must also change the value of the $dirsep variable
  168. X   from "/" to "\\".
  169. X
  170. X2) This is a Perl script, and Perl uses a slightly different
  171. X   regular-expression syntax than Gnu Emacs.  In particular, "("
  172. X   begins a group in Perl, while "\(" begins a group in Gnu Emacs.
  173. X
  174. X3) If you are using a Unix system, and your shell or kernel does not
  175. X   understand #! notation, this script will still run directly if you
  176. X   make it executable, but use of the -e command-line option is not
  177. X   recommended (the characters will confuse the shell).  In this case,
  178. X   always put your patterns in a file and use the -f option.
  179. X
  180. X4) If you have set PETAGSDIR and it does not work, make sure that the
  181. X   path does _not_ contain a trailing slash -- petags will add that
  182. X   automatically.
  183. X
  184. X
  185. XI will be losing my access to Usenet news in a few days, when I move
  186. Xto Ottawa to begin teaching with the English department.  I will,
  187. Xhowever, have an EMail account at dmeggins@acadvm1.uottawa.ca, and
  188. Xwould love to hear feedback.  I will also be subscribing to several
  189. Xmailing lists which echo newsgroups, including the comp.text.sgml
  190. Xlist.
  191. X
  192. X
  193. XEnjoy!
  194. X
  195. XDavid Megginson 
  196. X24 July, 1992
  197. X
  198. END_OF_FILE
  199. if test 5279 -ne `wc -c <'README'`; then
  200.     echo shar: \"'README'\" unpacked with wrong size!
  201. fi
  202. # end of 'README'
  203. fi
  204. if test -f 'petags' -a "${1}" != "-c" ; then 
  205.   echo shar: Will not clobber existing file \"'petags'\"
  206. else
  207. echo shar: Extracting \"'petags'\" \(4339 characters\)
  208. sed "s/^X//" >'petags' <<'END_OF_FILE'
  209. X#!/usr/gnu/bin/perl
  210. X
  211. X#  PETAGS Version 0.1
  212. X#  A perl script to generate emacs TAGS for arbitrary file types.
  213. X
  214. X#  (c) 1992 by David Megginson (dmeggins@acadvm1.uottawa.ca)
  215. X
  216. X#  Petags is free software; you can redistribute it and/or modify it
  217. X#  under the terms of the GNU General Public License as published by
  218. X#  the Free Software Foundation; either version 1, or (at your option)
  219. X#  any later version.
  220. X
  221. X#  Petags is distributed in the hope that it will be useful, but
  222. X#  WITHOUT ANY WARRANTY; without even the implied warranty of
  223. X#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  224. X#  General Public License for more details.
  225. X
  226. X# The program Perl is required to run this program, and Gnu Emacs is
  227. X# required to use the TAGS file which it creates -- you should have
  228. X# received a copy of the GNU General Public License along with both of
  229. X# these programs; see the file COPYING.  If not, write to the Free
  230. X# Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  231. X
  232. Xeval "exec /usr/gnu/bin/perl -S $0 $*"
  233. X    unless $running_under_some_shell;
  234. X
  235. X
  236. X#
  237. X# Configuration variables.
  238. X#
  239. X$dirsep = "/";            # Change for MeSsyDOS.
  240. X$pattern_dir = $ENV{"PETAGSDIR"} || '.';
  241. X                # May be modified by &get_options.
  242. X                # Note that environment variable overrides.
  243. X$tags_file = "TAGS";        # May be modified by &get_options.
  244. X
  245. X
  246. X#
  247. X# Startup stuff.
  248. X#
  249. X&get_options;            # Do that command-line stuff.
  250. X
  251. X&usage("no patterns specified (use '-e' or '-f')") if ($#patterns < 0);
  252. X&usage("$0: no files specified") if ($#ARGV < 0);
  253. X
  254. Xopen(TAGS,">$tags_file") || die "$0: cannot write to $tags_file.\n";
  255. X
  256. X
  257. X#
  258. X# Main program loop: open each file, store matching lines (and count
  259. X# characters), then print out the whole thing in etags format.
  260. X#
  261. Xforeach $file (@ARGV) {
  262. X    open(INPUT,$file) || die "$0: cannot open $file.\n";
  263. X    while (<INPUT>) {
  264. X      chop;
  265. X    ploop: foreach $pattern (@patterns) {
  266. X    if(/$pattern/) { 
  267. X        &add_line("$_\177$.,$position\n"); 
  268. X        last ploop; 
  269. X    }
  270. X    }
  271. X      $position += length($_) + 1;
  272. X  }
  273. X    close(INPUT);
  274. X    &flush_lines($file);
  275. X}
  276. X
  277. Xclose(TAGS);
  278. X
  279. X
  280. X#################################################################
  281. X# Subroutines to add information to the tags file.
  282. X#################################################################
  283. X
  284. X#
  285. X# Add a new line to the tags file.
  286. X#
  287. Xsub add_line {
  288. X    local ($line) = @_;
  289. X
  290. X    $total_characters += length($line);
  291. X    push(lines,$line);
  292. X}
  293. X
  294. X#
  295. X# Flush lines to the tags file, with the file name and total characters.
  296. X#
  297. Xsub flush_lines {
  298. X    local ($file) = @_;
  299. X
  300. X    print TAGS "\f\n$file,$total_characters\n";
  301. X    foreach $line (@lines) {
  302. X    print TAGS $line;
  303. X    }
  304. X    @lines = ();
  305. X    $total_characters = 0;
  306. X}
  307. X
  308. X
  309. X#################################################################
  310. X# Subroutines to initialise the program (arguments, options).
  311. X#################################################################
  312. X
  313. X#
  314. X# Get options from @ARGV array.
  315. X#
  316. Xsub get_options {
  317. X  opts: while ($ARGV[0] =~ /^-/) {
  318. X      $_ = shift(ARGV);
  319. X      {
  320. X      if (/^-e$/) { push(@patterns,shift(ARGV)); next opts; }
  321. X      if (/^-f$/) { &read_patterns_from_file(shift(ARGV)); next opts; }
  322. X      if (/^-o$/) { $tags_file = shift(ARGV); next opts; }
  323. X      if (/^-d$/) { $pattern_dir = shift(ARGV); next opts; }
  324. X      if (/^--$/) { last opts; }
  325. X      &usage("illegal option '$_'");
  326. X      }
  327. X  }
  328. X}
  329. X
  330. X#
  331. X# Read a list of patterns from a file: called by get_options().
  332. X#
  333. Xsub read_patterns_from_file {
  334. X    local ($file) = @_;
  335. X
  336. X    $file = "$pattern_dir$dirsep$file" unless -r $file;
  337. X
  338. X    open(FILE,$file) || die "$0: cannot open $file to read patterns.\n";
  339. X
  340. X    while (<FILE>) {
  341. X    chop;
  342. X    push(@patterns, $_);
  343. X    }
  344. X    close(FILE);
  345. X}
  346. X
  347. X#
  348. X# Print the program's usage and quit.
  349. X#
  350. Xsub usage {
  351. X    local ($errmsg) = @_;
  352. X
  353. X    print STDERR <<END_OF_USAGE;
  354. XUsage:
  355. X
  356. X  petags [-e <pat> -f <file> -o <output> -d <dir>] FILES...
  357. X
  358. X  -e <pat>    Add all lines containing <pat> to the TAGS file.
  359. X  -f <file>   Like -e, but read patterns from <file>, one on each line.
  360. X              File may be in the current directory or in $PETAGSDIR/.
  361. X  -o <output> Use <output> rather than TAGS for the tag file name.
  362. X  -d <dir>    With the -f option, look for pattern files in <dir>
  363. X              if they are not in the current directory (see also
  364. X              the environment variable PETAGSDIR.
  365. X  --          End options.
  366. X
  367. XEND_OF_USAGE
  368. X
  369. X    die "$0: $errmsg\n";
  370. X}
  371. END_OF_FILE
  372. if test 4339 -ne `wc -c <'petags'`; then
  373.     echo shar: \"'petags'\" unpacked with wrong size!
  374. fi
  375. # end of 'petags'
  376. fi
  377. echo shar: End of shell archive.
  378. exit 0
  379.  
  380. --
  381.                  o--------------- ---------------o
  382.                  |...            |meggin@vm.epas.|
  383.                  |.  .avid meggin|utoronto.ca on |
  384.                  |.  .son.centre |the internet.  |
  385.                  |... for mediev |               |
  386.                  |al studies.univ|               |
  387.                  |ersity of toron|  .explicit.   |
  388.                  |to             |               |
  389.                  |       ..meggin|               |
  390.                  o--------------- ---------------o
  391.  
  392.  
  393. exit 0 # Just in case...
  394.