ctags.rb 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. data/Gemfile +2 -0
  2. data/Rakefile +23 -0
  3. data/ctags.rb.gemspec +23 -0
  4. data/ext/.gitignore +3 -0
  5. data/ext/extconf.rb +15 -0
  6. data/ext/vendor/exuberant-ctags/.gitignore +6 -0
  7. data/ext/vendor/exuberant-ctags/.indent.pro +31 -0
  8. data/ext/vendor/exuberant-ctags/COPYING +340 -0
  9. data/ext/vendor/exuberant-ctags/EXTENDING.html +386 -0
  10. data/ext/vendor/exuberant-ctags/FAQ +371 -0
  11. data/ext/vendor/exuberant-ctags/INSTALL +215 -0
  12. data/ext/vendor/exuberant-ctags/INSTALL.oth +73 -0
  13. data/ext/vendor/exuberant-ctags/MAINTAINERS +88 -0
  14. data/ext/vendor/exuberant-ctags/Makefile.in +222 -0
  15. data/ext/vendor/exuberant-ctags/NEWS +871 -0
  16. data/ext/vendor/exuberant-ctags/README +73 -0
  17. data/ext/vendor/exuberant-ctags/ant.c +42 -0
  18. data/ext/vendor/exuberant-ctags/argproc.c +505 -0
  19. data/ext/vendor/exuberant-ctags/args.c +274 -0
  20. data/ext/vendor/exuberant-ctags/args.h +63 -0
  21. data/ext/vendor/exuberant-ctags/asm.c +387 -0
  22. data/ext/vendor/exuberant-ctags/asp.c +328 -0
  23. data/ext/vendor/exuberant-ctags/awk.c +81 -0
  24. data/ext/vendor/exuberant-ctags/basic.c +203 -0
  25. data/ext/vendor/exuberant-ctags/beta.c +321 -0
  26. data/ext/vendor/exuberant-ctags/c.c +2932 -0
  27. data/ext/vendor/exuberant-ctags/cobol.c +50 -0
  28. data/ext/vendor/exuberant-ctags/config.h.in +277 -0
  29. data/ext/vendor/exuberant-ctags/configure +7704 -0
  30. data/ext/vendor/exuberant-ctags/configure.ac +532 -0
  31. data/ext/vendor/exuberant-ctags/ctags.1 +1186 -0
  32. data/ext/vendor/exuberant-ctags/ctags.h +28 -0
  33. data/ext/vendor/exuberant-ctags/ctags.html +2087 -0
  34. data/ext/vendor/exuberant-ctags/ctags.spec +40 -0
  35. data/ext/vendor/exuberant-ctags/debug.c +113 -0
  36. data/ext/vendor/exuberant-ctags/debug.h +70 -0
  37. data/ext/vendor/exuberant-ctags/descrip.mms +68 -0
  38. data/ext/vendor/exuberant-ctags/dosbatch.c +42 -0
  39. data/ext/vendor/exuberant-ctags/e_amiga.h +24 -0
  40. data/ext/vendor/exuberant-ctags/e_djgpp.h +47 -0
  41. data/ext/vendor/exuberant-ctags/e_mac.h +143 -0
  42. data/ext/vendor/exuberant-ctags/e_msoft.h +76 -0
  43. data/ext/vendor/exuberant-ctags/e_os2.h +37 -0
  44. data/ext/vendor/exuberant-ctags/e_qdos.h +34 -0
  45. data/ext/vendor/exuberant-ctags/e_riscos.h +58 -0
  46. data/ext/vendor/exuberant-ctags/e_vms.h +31 -0
  47. data/ext/vendor/exuberant-ctags/eiffel.c +1352 -0
  48. data/ext/vendor/exuberant-ctags/entry.c +847 -0
  49. data/ext/vendor/exuberant-ctags/entry.h +103 -0
  50. data/ext/vendor/exuberant-ctags/erlang.c +189 -0
  51. data/ext/vendor/exuberant-ctags/flex.c +2243 -0
  52. data/ext/vendor/exuberant-ctags/fortran.c +2197 -0
  53. data/ext/vendor/exuberant-ctags/general.h +127 -0
  54. data/ext/vendor/exuberant-ctags/get.c +669 -0
  55. data/ext/vendor/exuberant-ctags/get.h +50 -0
  56. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/all-wcprops +47 -0
  57. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/entries +112 -0
  58. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/README.txt.svn-base +5 -0
  59. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regcomp.c.svn-base +3818 -0
  60. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.c.svn-base +74 -0
  61. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex.h.svn-base +575 -0
  62. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.c.svn-base +1713 -0
  63. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regex_internal.h.svn-base +773 -0
  64. data/ext/vendor/exuberant-ctags/gnu_regex/.svn/text-base/regexec.c.svn-base +4338 -0
  65. data/ext/vendor/exuberant-ctags/gnu_regex/README.txt +5 -0
  66. data/ext/vendor/exuberant-ctags/gnu_regex/regcomp.c +3818 -0
  67. data/ext/vendor/exuberant-ctags/gnu_regex/regex.c +74 -0
  68. data/ext/vendor/exuberant-ctags/gnu_regex/regex.h +575 -0
  69. data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.c +1713 -0
  70. data/ext/vendor/exuberant-ctags/gnu_regex/regex_internal.h +773 -0
  71. data/ext/vendor/exuberant-ctags/gnu_regex/regexec.c +4338 -0
  72. data/ext/vendor/exuberant-ctags/html.c +49 -0
  73. data/ext/vendor/exuberant-ctags/jscript.c +1572 -0
  74. data/ext/vendor/exuberant-ctags/keyword.c +258 -0
  75. data/ext/vendor/exuberant-ctags/keyword.h +34 -0
  76. data/ext/vendor/exuberant-ctags/lisp.c +139 -0
  77. data/ext/vendor/exuberant-ctags/lregex.c +704 -0
  78. data/ext/vendor/exuberant-ctags/lua.c +133 -0
  79. data/ext/vendor/exuberant-ctags/mac.c +273 -0
  80. data/ext/vendor/exuberant-ctags/magic.diff +21 -0
  81. data/ext/vendor/exuberant-ctags/main.c +584 -0
  82. data/ext/vendor/exuberant-ctags/main.h +32 -0
  83. data/ext/vendor/exuberant-ctags/maintainer.mak +476 -0
  84. data/ext/vendor/exuberant-ctags/make.c +217 -0
  85. data/ext/vendor/exuberant-ctags/matlab.c +44 -0
  86. data/ext/vendor/exuberant-ctags/mk_bc3.mak +46 -0
  87. data/ext/vendor/exuberant-ctags/mk_bc5.mak +49 -0
  88. data/ext/vendor/exuberant-ctags/mk_djg.mak +18 -0
  89. data/ext/vendor/exuberant-ctags/mk_manx.mak +65 -0
  90. data/ext/vendor/exuberant-ctags/mk_mingw.mak +31 -0
  91. data/ext/vendor/exuberant-ctags/mk_mpw.mak +130 -0
  92. data/ext/vendor/exuberant-ctags/mk_mvc.mak +40 -0
  93. data/ext/vendor/exuberant-ctags/mk_os2.mak +104 -0
  94. data/ext/vendor/exuberant-ctags/mk_qdos.mak +100 -0
  95. data/ext/vendor/exuberant-ctags/mk_sas.mak +63 -0
  96. data/ext/vendor/exuberant-ctags/mkinstalldirs +40 -0
  97. data/ext/vendor/exuberant-ctags/ocaml.c +1842 -0
  98. data/ext/vendor/exuberant-ctags/options.c +1842 -0
  99. data/ext/vendor/exuberant-ctags/options.h +155 -0
  100. data/ext/vendor/exuberant-ctags/parse.c +677 -0
  101. data/ext/vendor/exuberant-ctags/parse.h +129 -0
  102. data/ext/vendor/exuberant-ctags/parsers.h +63 -0
  103. data/ext/vendor/exuberant-ctags/pascal.c +267 -0
  104. data/ext/vendor/exuberant-ctags/perl.c +382 -0
  105. data/ext/vendor/exuberant-ctags/php.c +237 -0
  106. data/ext/vendor/exuberant-ctags/python.c +771 -0
  107. data/ext/vendor/exuberant-ctags/qdos.c +106 -0
  108. data/ext/vendor/exuberant-ctags/read.c +569 -0
  109. data/ext/vendor/exuberant-ctags/read.h +116 -0
  110. data/ext/vendor/exuberant-ctags/readtags.c +959 -0
  111. data/ext/vendor/exuberant-ctags/readtags.h +252 -0
  112. data/ext/vendor/exuberant-ctags/rexx.c +39 -0
  113. data/ext/vendor/exuberant-ctags/routines.c +891 -0
  114. data/ext/vendor/exuberant-ctags/routines.h +134 -0
  115. data/ext/vendor/exuberant-ctags/ruby.c +408 -0
  116. data/ext/vendor/exuberant-ctags/scheme.c +111 -0
  117. data/ext/vendor/exuberant-ctags/sh.c +115 -0
  118. data/ext/vendor/exuberant-ctags/slang.c +41 -0
  119. data/ext/vendor/exuberant-ctags/sml.c +212 -0
  120. data/ext/vendor/exuberant-ctags/sort.c +230 -0
  121. data/ext/vendor/exuberant-ctags/sort.h +32 -0
  122. data/ext/vendor/exuberant-ctags/source.mak +122 -0
  123. data/ext/vendor/exuberant-ctags/sql.c +2112 -0
  124. data/ext/vendor/exuberant-ctags/strlist.c +281 -0
  125. data/ext/vendor/exuberant-ctags/strlist.h +54 -0
  126. data/ext/vendor/exuberant-ctags/tcl.c +116 -0
  127. data/ext/vendor/exuberant-ctags/tex.c +524 -0
  128. data/ext/vendor/exuberant-ctags/verilog.c +340 -0
  129. data/ext/vendor/exuberant-ctags/vhdl.c +835 -0
  130. data/ext/vendor/exuberant-ctags/vim.c +636 -0
  131. data/ext/vendor/exuberant-ctags/vstring.c +232 -0
  132. data/ext/vendor/exuberant-ctags/vstring.h +85 -0
  133. data/ext/vendor/exuberant-ctags/yacc.c +40 -0
  134. data/lib/ctags/exuberant.rb +45 -0
  135. data/lib/ctags/version.rb +3 -0
  136. data/lib/ctags.rb +6 -0
  137. data/test/test_ctags.rb +24 -0
  138. metadata +233 -0
@@ -0,0 +1,73 @@
1
+ Exuberant Ctags
2
+ ===============
3
+ Author: Darren Hiebert <dhiebert at users.sourceforge.net>
4
+ http://ctags.sourceforge.net
5
+ Instant Messaging:
6
+ Yahoo! ID : dbhiebert
7
+ AIM ScreenName: darrenhiebert
8
+
9
+ Exuberant Ctags is a multilanguage reimplementation of the much-underused
10
+ ctags(1) program and is intended to be the mother of all ctags programs. It
11
+ generates indexes of source code definitions which are used by a number of
12
+ editors and tools. The motivation which drove the development of Exuberant
13
+ Ctags was the need for a ctags program which supported generation of tags
14
+ for all possible C language constructs (which no other ctags offers), and
15
+ because most were easily fooled by a number of preprocessor contructs.
16
+
17
+
18
+ Exuberant Ctags offers the following features:
19
+
20
+ 1. It supports the following languages: Assembler, AWK, ASP, BETA,
21
+ Bourne/Korn/Z Shell, C, C++, C#, COBOL, Eiffel, Erlang, Fortran, Java, Lisp,
22
+ Lua, Makefile, Pascal, Perl, PHP, PL/SQL, Python, REXX, Ruby, Scheme,
23
+ S-Lang, SML (Standard ML), Tcl, Vera, Verilog, VHDL, Vim, and YACC.
24
+
25
+ 2. It is capable of generating tags for virtually all C language constructs.
26
+
27
+ 3. It is very robust in parsing code. In particular, the C/C++ parser is
28
+ far less easily fooled by code containing #if preprocessor conditional
29
+ constructs, using a conditional path selection algorithm to resolve
30
+ complicated situations, and a fall-back algorithm when this one fails.
31
+
32
+ 4. Supports output of Emacs-style TAGS files (i.e. "etags").
33
+
34
+ 5. User-defined languages, using Posix regular expressions.
35
+
36
+ 6. Supports UNIX, MSDOS, Windows 95/98/NT/2000/XP, OS/2, QNX, Amiga, QDOS,
37
+ RISC OS, VMS, Macintosh, and Cray. Some pre-compiled binaries are
38
+ available on the web site.
39
+
40
+
41
+ Visit the Exuberant Ctags web site:
42
+
43
+ http://ctags.sourceforge.net
44
+
45
+
46
+ Which brings us to the most obvious question:
47
+
48
+ Q: Why is it called "Exuberant" ctags?
49
+ A: Because one of the meanings of the word is:
50
+
51
+ exuberant : produced in extreme abundance : PLENTIFUL syn see PROFUSE
52
+
53
+ Compare the tag file produced by Exuberant Ctags with that produced by any
54
+ other ctags and you will see how appropriate the name is.
55
+
56
+
57
+ This source code is distributed according to the terms of the GNU General
58
+ Public License. It is provided on an as-is basis and no responsibility is
59
+ accepted for its failure to perform as expected. It is worth at least as
60
+ much as you paid for it!
61
+
62
+ Exuberant Ctags was originally derived from and inspired by the ctags
63
+ program by Steve Kirkendall (kirkenda@cs.pdx.edu) that comes with the Elvis
64
+ vi clone (though almost none of the original code remains). This, too, is
65
+ freely available.
66
+
67
+ Please report any problems you find. The two problems I expect to be most
68
+ likely are either a tag which you expected but is missing, or a tag created
69
+ in error (shouldn't really be a tag). Please include a sample of code (the
70
+ definition) for the object which misbehaves.
71
+
72
+ --
73
+ vim:tw=76:sw=4:et:
@@ -0,0 +1,42 @@
1
+ /*
2
+ * $Id$
3
+ *
4
+ * Copyright (c) 2008, David Fishburn
5
+ *
6
+ * This source code is released for free distribution under the terms of the
7
+ * GNU General Public License.
8
+ *
9
+ * This module contains functions for generating tags for Ant language files.
10
+ */
11
+
12
+ /*
13
+ * INCLUDE FILES
14
+ */
15
+ #include "general.h" /* must always come first */
16
+
17
+ #include <string.h>
18
+ #include "parse.h"
19
+
20
+ /*
21
+ * FUNCTION DEFINITIONS
22
+ */
23
+
24
+ static void installAntRegex (const langType language)
25
+ {
26
+ addTagRegex (language,
27
+ "^[ \t]*<[ \t]*project.*name=\"([^\"]+)\".*", "\\1", "p,project,projects", NULL);
28
+ addTagRegex (language,
29
+ "^[ \t]*<[ \t]*target.*name=\"([^\"]+)\".*", "\\1", "t,target,targets", NULL);
30
+ }
31
+
32
+ extern parserDefinition* AntParser ()
33
+ {
34
+ static const char *const extensions [] = { "build.xml", NULL };
35
+ parserDefinition* const def = parserNew ("Ant");
36
+ def->extensions = extensions;
37
+ def->initialize = installAntRegex;
38
+ def->regex = TRUE;
39
+ return def;
40
+ }
41
+
42
+ /* vi:set tabstop=4 shiftwidth=4: */
@@ -0,0 +1,505 @@
1
+ /*
2
+ * $Id: argproc.c 443 2006-05-30 04:37:13Z darren $
3
+ *
4
+ * Copyright (c) 1989, Mark Pizzolato (mark@infopiz.uucp)
5
+ *
6
+ * This source code is released for free distribution under the terms of the
7
+ * GNU General Public License.
8
+ *
9
+ * Provided by Stephen P. Wall <swall@redcom.com>
10
+ * Extracted from the VMS port of GNU patch-2.1.
11
+ *
12
+ * This module provides redirection support for the VAX DECC port of
13
+ * Exuberant Ctags.
14
+ */
15
+ /*
16
+ * @(#)argproc.c 1.0 89/02/01 Mark Pizzolato (mark@infopiz.uucp)
17
+ */
18
+
19
+ #ifndef lint
20
+ char argproc_version [] = "@(#)argproc.c VMS uucp Version infopiz-1.0";
21
+ #endif
22
+
23
+ #include <ctype.h>
24
+ #include <descrip.h>
25
+ #include <dvidef.h>
26
+ #include <errno.h>
27
+ #include <iodef.h>
28
+ #include <lib$routines.h>
29
+ #include <starlet.h>
30
+ #include <stdlib.h>
31
+ #include <stdio.h>
32
+ #include <string.h>
33
+ #include <syidef.h> /* System Information Definitions */
34
+
35
+ #define EXIT_OK 1 /* image exit code */
36
+ #define EXIT_ERR 0x10000000 /* image exit code */
37
+
38
+ /*
39
+ * getredirection() is intended to aid in porting C programs
40
+ * to VMS (Vax-11 C) which does not support '>' and '<'
41
+ * I/O redirection, along with a command line pipe mechanism
42
+ * using the '|' AND background command execution '&'.
43
+ * The piping mechanism will probably work with almost any 'filter' type
44
+ * of program. With suitable modification, it may useful for other
45
+ * portability problems as well.
46
+ *
47
+ * Author: Mark Pizzolato mark@infopiz.UUCP
48
+ * Mods: Steve Wall Don't return a full path unless the
49
+ * original filename included a path.
50
+ */
51
+ struct list_item
52
+ {
53
+ struct list_item *next;
54
+ char *value;
55
+ };
56
+
57
+ static expand_wild_cards ();
58
+ static char *pipe_and_fork ();
59
+
60
+ int
61
+ getredirection (ac, av)
62
+ int *ac;
63
+ char ***av;
64
+ /*
65
+ * Process vms redirection arg's. Exit if any error is seen.
66
+ * If getredirection() processes an argument, it is erased
67
+ * from the vector. getredirection () returns a new argc and argv value.
68
+ * In the event that a background command is requested (by a trailing "&"),
69
+ * this routine creates a background subprocess, and simply exits the program.
70
+ *
71
+ * Warning: do not try to simplify the code for vms. The code
72
+ * presupposes that getredirection() is called before any data is
73
+ * read from stdin or written to stdout.
74
+ *
75
+ * Normal usage is as follows:
76
+ *
77
+ * main (argc, argv)
78
+ * int argc;
79
+ * char *argv [];
80
+ * {
81
+ * getredirection (&argc, &argv);
82
+ * }
83
+ */
84
+ {
85
+ int argc = *ac; /* Argument Count */
86
+ char **argv = *av; /* Argument Vector */
87
+ char *ap; /* Argument pointer */
88
+ int j; /* argv [] index */
89
+ extern int errno; /* Last vms i/o error */
90
+ int item_count = 0; /* Count of Items in List */
91
+ struct list_item *list_head = 0; /* First Item in List */
92
+ struct list_item *list_tail; /* Last Item in List */
93
+ char *in = NULL; /* Input File Name */
94
+ char *out = NULL; /* Output File Name */
95
+ char *outmode = "w"; /* Mode to Open Output File */
96
+ int cmargc = 0; /* Piped Command Arg Count */
97
+ char **cmargv = NULL;/* Piped Command Arg Vector */
98
+
99
+ /*
100
+ * First handle the case where the last thing on the line ends with
101
+ * a '&'. This indicates the desire for the command to be run in a
102
+ * subprocess, so we satisfy that desire.
103
+ */
104
+ {
105
+ extern background_process ();
106
+ ap = argv [argc-1];
107
+ if (0 == strcmp ("&", ap))
108
+ exit (background_process (--argc, argv));
109
+ if ('&' == ap [strlen (ap)-1])
110
+ {
111
+ ap [strlen (ap)-1] = '\0';
112
+ exit (background_process (argc, argv));
113
+ }
114
+ }
115
+ /*
116
+ * Now we handle the general redirection cases that involve '>', '>>',
117
+ * '<', and pipes '|'.
118
+ */
119
+ for (j = 0; j < argc; ++j)
120
+ {
121
+ if (0 == strcmp ("<", argv [j]))
122
+ {
123
+ if (j+1 >= argc)
124
+ {
125
+ errno = EINVAL;
126
+ perror ("No input file");
127
+ exit (EXIT_ERR);
128
+ }
129
+ in = argv [++j];
130
+ continue;
131
+ }
132
+ if ('<' == *(ap = argv [j]))
133
+ {
134
+ in = 1 + ap;
135
+ continue;
136
+ }
137
+ if (0 == strcmp (">", ap))
138
+ {
139
+ if (j+1 >= argc)
140
+ {
141
+ errno = EINVAL;
142
+ perror ("No output file");
143
+ exit (EXIT_ERR);
144
+ }
145
+ out = argv [++j];
146
+ continue;
147
+ }
148
+ if ('>' == *ap)
149
+ {
150
+ if ('>' == ap [1])
151
+ {
152
+ outmode = "a";
153
+ if ('\0' == ap [2])
154
+ out = argv [++j];
155
+ else
156
+ out = 2 + ap;
157
+ }
158
+ else
159
+ out = 1 + ap;
160
+ continue;
161
+ }
162
+ if (0 == strcmp ("|", argv [j]))
163
+ {
164
+ if (j+1 >= argc)
165
+ {
166
+ errno = EPIPE;
167
+ perror ("No command to Pipe to");
168
+ exit (EXIT_ERR);
169
+ }
170
+ cmargc = argc- (j+1);
171
+ cmargv = &argv [j+1];
172
+ argc = j;
173
+ continue;
174
+ }
175
+ if ('|' == *(ap = argv [j]))
176
+ {
177
+ ++argv [j];
178
+ cmargc = argc-j;
179
+ cmargv = &argv [j];
180
+ argc = j;
181
+ continue;
182
+ }
183
+ expand_wild_cards (ap, &list_head, &list_tail, &item_count);
184
+ }
185
+ /*
186
+ * Allocate and fill in the new argument vector, Some Unix's terminate
187
+ * the list with an extra null pointer.
188
+ */
189
+ argv = *av = calloc (item_count+1, sizeof (char *));
190
+ for (j = 0; j < item_count; ++j, list_head = list_head->next)
191
+ argv [j] = list_head->value;
192
+ *ac = item_count;
193
+ if (cmargv != NULL)
194
+ {
195
+ char subcmd [1024];
196
+
197
+ if (out != NULL)
198
+ {
199
+ errno = EINVAL;
200
+ perror ("Invalid '|' and '>' specified");
201
+ exit (EXIT_ERR);
202
+ }
203
+ strcpy (subcmd, cmargv [0]);
204
+ for (j = 1; j < cmargc; ++j)
205
+ {
206
+ strcat (subcmd, " \"");
207
+ strcat (subcmd, cmargv [j]);
208
+ strcat (subcmd, "\"");
209
+ }
210
+ out = pipe_and_fork (subcmd);
211
+ }
212
+ if ((in != NULL) && (NULL == freopen (in, "r", stdin, "mbc=32", "mbf=2")))
213
+ {
214
+ perror (in); /* Can't find file */
215
+ exit (EXIT_ERR); /* Is a fatal error */
216
+ }
217
+ if ((out != NULL) && (NULL == freopen (out, outmode, stdout, "mbc=32", "mbf=2")))
218
+ {
219
+ perror (ap); /* Error, can't write or append */
220
+ exit (EXIT_ERR); /* Is a fatal error */
221
+ }
222
+ #ifdef DEBUG
223
+ fprintf (stderr, "Arglist:\n");
224
+ for (j = 0; j < *ac; ++j)
225
+ fprintf (stderr, "argv[%d] = '%s'\n", j, argv [j]);
226
+ #endif
227
+ return 0;
228
+ }
229
+
230
+ static add_item (head, tail, value, count)
231
+ struct list_item **head;
232
+ struct list_item **tail;
233
+ char *value;
234
+ int *count;
235
+ {
236
+ if (*head == 0)
237
+ {
238
+ if (NULL == (*head = calloc (1, sizeof (**head))))
239
+ {
240
+ errno = ENOMEM;
241
+ perror ("");
242
+ exit (EXIT_ERR);
243
+ }
244
+ *tail = *head;
245
+ }
246
+ else
247
+ if (NULL == ((*tail)->next = calloc (1, sizeof (**head))))
248
+ {
249
+ errno = ENOMEM;
250
+ perror ("");
251
+ exit (EXIT_ERR);
252
+ }
253
+ else
254
+ *tail = (*tail)->next;
255
+ (*tail)->value = value;
256
+ ++ (*count);
257
+ }
258
+
259
+ static expand_wild_cards (item, head, tail, count)
260
+ char *item;
261
+ struct list_item **head;
262
+ struct list_item **tail;
263
+ int *count;
264
+ {
265
+ int expcount = 0;
266
+ int context = 0;
267
+ int status;
268
+ int status_value;
269
+ char *had_version;
270
+ int had_path;
271
+ $DESCRIPTOR (filespec, item);
272
+ /*$DESCRIPTOR (defaultspec, "SYS$DISK:[]*.*;");*/
273
+ $DESCRIPTOR (defaultspec, "");
274
+ $DESCRIPTOR (resultspec, "");
275
+
276
+ if (strcspn (item, "*%") == strlen (item))
277
+ {
278
+ add_item (head, tail, item, count);
279
+ return;
280
+ }
281
+ resultspec.dsc$b_dtype = DSC$K_DTYPE_T;
282
+ resultspec.dsc$b_class = DSC$K_CLASS_D;
283
+ resultspec.dsc$a_pointer = NULL;
284
+ filespec.dsc$w_length = strlen (item);
285
+ /*
286
+ * Only return version specs, if the caller specified a version
287
+ */
288
+ had_version = strchr (item, ';');
289
+ /*
290
+ * Only return full path if the caller specified a path
291
+ */
292
+ had_path = (strchr (item, ']') || strchr (item, ':'));
293
+ while (1 == (1&lib$find_file (&filespec, &resultspec, &context,
294
+ &defaultspec, 0, &status_value, &0)))
295
+ {
296
+ char *string;
297
+ char *c;
298
+
299
+ if (NULL == (string = calloc (1, resultspec.dsc$w_length+1)))
300
+ {
301
+ errno = ENOMEM;
302
+ perror ("");
303
+ exit (EXIT_ERR);
304
+ }
305
+ strncpy (string, resultspec.dsc$a_pointer, resultspec.dsc$w_length);
306
+ string [resultspec.dsc$w_length] = '\0';
307
+ if (NULL == had_version)
308
+ *((char *) strrchr (string, ';')) = '\0';
309
+ if (!had_path) {
310
+ char *s = strrchr (string, ']');
311
+ if ( s == NULL ) s = strrchr (string, ':');
312
+ if ( s != NULL ) strcpy (string, s+1);
313
+ }
314
+ /*
315
+ * Be consistent with what the C RTL has already done to the rest of
316
+ * the argv items and lowercase all of these names.
317
+ */
318
+ for (c = string; *c; ++c)
319
+ if (isupper (*c))
320
+ *c = tolower (*c);
321
+ add_item (head, tail, string, count);
322
+ ++expcount;
323
+ }
324
+ if (expcount == 0)
325
+ add_item (head, tail, item, count);
326
+ lib$sfree1_dd (&resultspec);
327
+ lib$find_file_end (&context);
328
+ }
329
+
330
+ static int child_st [2]; /* Event Flag set when child process completes */
331
+
332
+ static short child_chan;/* I/O Channel for Pipe Mailbox */
333
+
334
+ static exit_handler (status)
335
+ int *status;
336
+ {
337
+ short iosb [4];
338
+
339
+ if (0 == child_st [0])
340
+ {
341
+ #ifdef DEBUG
342
+ fprintf (stderr, "Waiting for Child Process to Finnish . . .\n");
343
+ #endif
344
+ sys$qiow (0, child_chan, IO$_WRITEOF, iosb, 0, 0, 0, 0, 0, 0, 0, 0);
345
+ sys$dassgn (child_chan);
346
+ fclose (stdout);
347
+ sys$synch (0, child_st);
348
+ }
349
+ }
350
+
351
+
352
+ static sig_child (chan)
353
+ int chan;
354
+ {
355
+ #ifdef DEBUG
356
+ fprintf (stderr, "Child Completion AST\n");
357
+ #endif
358
+ if (child_st [0] == 0)
359
+ child_st [0] = 1;
360
+ }
361
+
362
+ static struct exit_control_block
363
+ {
364
+ struct exit_control_block *flink;
365
+ int (*exit_routine) ();
366
+ int arg_count;
367
+ int *status_address;
368
+ int exit_status;
369
+ } exit_block =
370
+ {
371
+ 0,
372
+ exit_handler,
373
+ 1,
374
+ &exit_block.exit_status,
375
+ 0
376
+ };
377
+
378
+ static char *pipe_and_fork (cmd)
379
+ char *cmd;
380
+ {
381
+ $DESCRIPTOR (cmddsc, cmd);
382
+ static char mbxname [64];
383
+ $DESCRIPTOR (mbxdsc, mbxname);
384
+ short iosb [4];
385
+ int status;
386
+ int pid;
387
+ struct
388
+ {
389
+ short dna_buflen;
390
+ short dna_itmcod;
391
+ char *dna_buffer;
392
+ unsigned short *dna_retlen;
393
+ int listend;
394
+ } itmlst =
395
+ {
396
+ sizeof (mbxname),
397
+ DVI$_DEVNAM,
398
+ mbxname,
399
+ &mbxdsc.dsc$w_length,
400
+ 0
401
+ };
402
+ int mbxsize;
403
+ struct
404
+ {
405
+ short mbf_buflen;
406
+ short mbf_itmcod;
407
+ int *mbf_maxbuf;
408
+ unsigned short *mbf_retlen;
409
+ int listend;
410
+ } syiitmlst =
411
+ {
412
+ sizeof (mbxsize),
413
+ SYI$_MAXBUF,
414
+ &mbxsize,
415
+ 0,
416
+ 0
417
+ };
418
+
419
+ cmddsc.dsc$w_length = strlen (cmd);
420
+ /*
421
+ * Get the SYSGEN parameter MAXBUF, and the smaller of it and 2048 as
422
+ * the size of the 'pipe' mailbox.
423
+ */
424
+ if (1 == (1& (vaxc$errno = sys$getsyiw (0, 0, 0, &syiitmlst, iosb, 0, 0, 0))))
425
+ vaxc$errno = iosb [0];
426
+ if (0 == (1&vaxc$errno))
427
+ {
428
+ errno = EVMSERR;
429
+ perror ("Can't get SYSGEN parameter value for MAXBUF");
430
+ exit (EXIT_ERR);
431
+ }
432
+ if (mbxsize > 2048)
433
+ mbxsize = 2048;
434
+ if (0 == (1& (vaxc$errno = sys$crembx (0, &child_chan, mbxsize, mbxsize, 0, 0, 0))))
435
+ {
436
+ errno = EVMSERR;
437
+ perror ("Can't create pipe mailbox");
438
+ exit (EXIT_ERR);
439
+ }
440
+ if (1 == (1& (vaxc$errno = sys$getdviw (0, child_chan, 0, &itmlst, iosb,
441
+ 0, 0, 0))))
442
+ vaxc$errno = iosb [0];
443
+ if (0 == (1&vaxc$errno))
444
+ {
445
+ errno = EVMSERR;
446
+ perror ("Can't get pipe mailbox device name");
447
+ exit (EXIT_ERR);
448
+ }
449
+ mbxname [mbxdsc.dsc$w_length] = '\0';
450
+ #ifdef DEBUG
451
+ fprintf (stderr, "Pipe Mailbox Name = '%s'\n", mbxname);
452
+ #endif
453
+ if (0 == (1& (vaxc$errno = lib$spawn (&cmddsc, &mbxdsc, 0, &1,
454
+ 0, &pid, child_st, &0, sig_child,
455
+ &child_chan))))
456
+ {
457
+ errno = EVMSERR;
458
+ perror ("Can't spawn subprocess");
459
+ exit (EXIT_ERR);
460
+ }
461
+ #ifdef DEBUG
462
+ fprintf (stderr, "Subprocess's Pid = %08X\n", pid);
463
+ #endif
464
+ sys$dclexh (&exit_block);
465
+ return (mbxname);
466
+ }
467
+
468
+ background_process (argc, argv)
469
+ int argc;
470
+ char **argv;
471
+ {
472
+ char command [2048] = "$";
473
+ $DESCRIPTOR (value, command);
474
+ $DESCRIPTOR (cmd, "BACKGROUND$COMMAND");
475
+ $DESCRIPTOR (null, "NLA0:");
476
+ int pid;
477
+
478
+ strcat (command, argv [0]);
479
+ while (--argc)
480
+ {
481
+ strcat (command, " \"");
482
+ strcat (command, *(++argv));
483
+ strcat (command, "\"");
484
+ }
485
+ value.dsc$w_length = strlen (command);
486
+ if (0 == (1& (vaxc$errno = lib$set_symbol (&cmd, &value))))
487
+ {
488
+ errno = EVMSERR;
489
+ perror ("Can't create symbol for subprocess command");
490
+ exit (EXIT_ERR);
491
+ }
492
+ if (0 == (1& (vaxc$errno = lib$spawn (&cmd, &null, 0, &17, 0, &pid))))
493
+ {
494
+ errno = EVMSERR;
495
+ perror ("Can't spawn subprocess");
496
+ exit (EXIT_ERR);
497
+ }
498
+ #ifdef DEBUG
499
+ fprintf (stderr, "%s\n", command);
500
+ #endif
501
+ fprintf (stderr, "%08X\n", pid);
502
+ return (EXIT_OK);
503
+ }
504
+
505
+ /* vi:set tabstop=4 shiftwidth=4: */