1% tags.sl	-*- SLang -*-
2%
3% read a tags file produced by ctags/etags programs
4%
5% By default, the file "tags" is used.  However, setting the variable
6% `Tag_File' as in
7%	global_variable Tag_File = "mytag.file";
8% will override this.
9
10!if (is_defined ("Tag_File"))
11{
12   variable Tag_File = "tags";
13}
14
15% ctags format:
16%  function-name\tfilename\t/^function-prototype/
17%  typedef-name\tfilename\tline-number
18define ctags_find (tag)
19{
20   variable n, file, proto, msg = "Tag file needs updated?";
21
22   !if ((n = re_fsearch (strcat ("^", tag, "\t+\\([^\t]+\\)\t+"))), n)
23     error (msg);
24   file = regexp_nth_match (1);
25
26   go_right (--n, n);
27   if (looking_at ("/^"))
28     {
29	go_right (2);
30	push_mark (); eol (); bskip_chars ("\\\\$/");
31	proto = str_replace_all (bufsubstr (), "\\/", "/");
32	n = 0;
33     }
34   else
35     {
36	push_mark ();
37	eol ();
38	n = integer (bufsubstr ());
39     }
40
41   !if (read_file (file)) error ("File not found.");
42
43   if (n)
44     {
45	goto_line (n);
46	return;
47     }
48
49   bob ();
50   !if (bol_fsearch (proto))
51     {
52        () = fsearch (tag);
53        message (msg);
54     }
55   % message (Sprintf ("Tag: <%s>", proto, 1));
56}
57
58% etags format:
59%  ^L
60%  filename,some-number
61%  [function-type] function-name ^?line-name,some-number
62define etags_find (tag)
63{
64   variable file, line, tmptag, msg = "Tag file needs updated?";
65
66   % we do the re_fsearch in order of preference: user->function->array
67   tmptag = strcat ("[: ]", tag);
68   !if (re_fsearch (strcat (tmptag, "[\t ]+\x7F\\(\\d+\\),")))
69     !if (re_fsearch (strcat (tmptag, "[\t \\(]+\x7F\\(\\d+\\),")))
70       !if (re_fsearch (strcat (tmptag, "[\t \\[]+\x7F\\(\\d+\\),")))
71	 error (msg);
72   line = integer (regexp_nth_match (1));
73
74   () = bol_bsearch (char (014));	% previous ^L
75   go_down_1 ();
76   push_mark (); skip_chars ("^,");
77   file = bufsubstr ();
78
79   !if (read_file (file)) error ("File not found.");
80   goto_line (line);
81}
82
83define find_tag ()
84{
85   variable tag = "0-9A-Z_a-z", tbuf = " *tags*", cbuf = whatbuf ();
86#ifdef VMS
87   tag = strcat (tag, "$");
88#endif
89   push_spot ();
90   skip_white ();
91   bskip_chars (tag);
92   push_mark ();
93   skip_chars (tag);
94   tag = bufsubstr ();		% leave on the stack
95   pop_spot ();
96
97   tag = strtrim (read_mini ("Find tag:", tag, Null_String));
98
99   !if (strlen (tag)) return;	% later I will treat this better
100   !if (bufferp (tbuf), setbuf (tbuf))
101     {
102        if (insert_file (Tag_File) < 0)
103          error ("File tags not found!");
104     }
105
106   bob ();
107   if (looking_at_char (014))	% if first char is ^L (etags)
108     etags_find (tag);
109   else
110     ctags_find (tag);
111   pop2buf (whatbuf ());
112   pop2buf (cbuf);
113}
114