Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!fsg!skipnyc!skipsun!skip From: skip@skipnyc (Skip Gilbrech) Newsgroups: comp.emacs Subject: Re: etags should optionally tag all macros Message-ID: Date: 3 Jun 90 05:11:14 GMT References: Sender: skip@skipnyc.UUCP Organization: Fusion Systems Group, New York City Lines: 294 In-reply-to: brennan@rtp.dg.com's message of 31 May 90 00:16:23 GMT In article brennan@rtp.dg.com (Dave Brennan) writes: > I've been writing some code that uses a lot macros to hide structure >information from modules that need to know about specific data structures, >and often need to find the macro definitions to make additions or changes. > > But, alas, etags only generates tags for macros with paramaters. >I just couldn't live with this behavior, so I had to make some changes >to etags to make this work. I putting the patch here in the hope other >people will find it useful. To make etags generate tag entries for all >macros just use the "-d" flag when running it. > > I'd also be interested in any other etags enhancements. It'd be easy >to make etags recognize other tags (like struct, union and enum tags) but >macro tags are the only ones I feel like I have time to change right now. >I just use typedefs for my structs, unions, and enums - a case which is >already handled. Dave inspired me to post a change I made a while ago that I've found useful. It adds an `-L filename' flag to accept a list of files to process from another file. `Filename' can be `-' in which case the list is read from the standard input. This is useful for avoiding command-line size limits on some systems. The patch below includes Dave's, and is based on the etags.c distributed with emacs 18.54. *** etags.c-dist Thu Jun 23 08:45:37 1988 --- etags.c Sat Jun 2 20:47:29 1990 *************** *** 92,97 **** --- 92,113 ---- You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! */ + /* + * Local changes: + * + * Added `-L filename' flag to accept a list of files to process + * from a file. If `filename' is `-', the list is read from the + * standard input. This is useful for avoiding command-line + * size limits on some systems. + * skip@fsg.com (Skip Gilbrech) - Sun Jul 30 20:34:09 EDT 1990 + * + * Applied Dave Brennan's (brennan@rtp.dg.com) patch: `-d' flag makes + * etags generate tag entries for all macros, not just those with + * parameters. + * skip@fsg.com (Skip Gilbrech) - Sat Jun 2 18:37:16 EDT 1990 + * + */ + #include #include *************** *** 182,187 **** --- 198,204 ---- int file_num = 0; /* current file number */ int aflag = 0; /* -a: append to tags */ + int dflag = 0; /* -d: create tags for #define macros */ int tflag = 0; /* -t: create tags for typedefs */ int uflag = 0; /* -u: update tags */ int wflag = 0; /* -w: suppress warnings */ *************** *** 249,255 **** --- 266,275 ---- extern char *gfnames(); extern char *massage_name(); + #else + int lflag = 0; #endif + char *file_list = 0; progname = av[0]; *************** *** 288,293 **** --- 308,316 ---- case 'a': aflag++; break; + case 'd': + dflag++; + break; case 'e': eflag++; break; *************** *** 308,313 **** --- 331,355 ---- } outfile = av[1]; goto end_loop; + #ifndef VMS /* might work under vms, but I don't know, so... (sg) */ + case 'L': + if (lflag > 0) + { + fprintf(stderr, + "%s: -L flag may only be given once\n", progname); + goto usage; + } + lflag++, ac--; av++; + if (ac <= 1 || av[1][0] == '\0') + { + fprintf(stderr, + "%s: -L flag must be followed by a filename\n", + progname); + goto usage; + } + file_list = av[1]; + goto end_loop; + #endif case 't': tflag++; break; *************** *** 337,349 **** ac--; av++; } if (ac <= 1) { usage: #ifdef VMS ! fprintf (stderr, "Usage: %s [-aetwvx] [-f outfile] file ...\n", progname); #else ! fprintf (stderr, "Usage: %s [-BFaetuwvx] [-f outfile] file ...\n", progname); #endif exit(BAD); } --- 379,397 ---- ac--; av++; } + #ifdef VMS if (ac <= 1) + #else + if (ac <= 1 && ! file_list) + #endif { usage: #ifdef VMS ! fprintf (stderr, "Usage: %s [-adetwvx] [-f outfile] file ...\n", progname); #else ! fprintf (stderr, ! "Usage: %s [-BFadetuwvx] [-f outfile] [-L file-list | -] file ...\n", ! progname); #endif exit(BAD); } *************** *** 371,376 **** --- 419,465 ---- } } + #ifndef VMS + if (file_list) + { + FILE *flp; + struct linebuffer flbuf; + + if (file_list[0] == '-' && file_list[1] == '\0') + flp = stdin; + else + flp = fopen(file_list, "r"); + + if (flp == NULL) + { + fprintf (stderr, "%s: ", progname); + perror(file_list); + } + else + { + initbuffer (&flbuf); + while (!feof (flp)) + { + if (readline(&flbuf, flp) && flbuf.buffer[0] != '#') + { + this_file = flbuf.buffer; + find_entries (this_file); + if (eflag) + { + fprintf (outf, "\f\n%s,%d\n", + this_file, total_size_of_entries (head)); + put_entries (head); + free_tree (head); + head = NULL; + } + } + } + if (flp != stdin) + fclose(flp); + } + } + #endif + file_num = 1; #ifdef VMS for (ac--, av++; *************** *** 858,864 **** } continue; case '#': ! if (lp == lb.buffer + 1) number = 1; continue; case '{': --- 947,953 ---- } continue; case '#': ! if (lp == lb.buffer + 1) /* remember if the # is in column 1 */ number = 1; continue; case '{': *************** *** 947,953 **** { reg char *lp = *lpp; reg char c; ! static logical next_token_is_func; logical firsttok; /* T if have seen first token in ()'s */ int bad, win; --- 1036,1042 ---- { reg char *lp = *lpp; reg char c; ! static logical next_token_is_func = 0, next_token_is_define = 0; logical firsttok; /* T if have seen first token in ()'s */ int bad, win; *************** *** 967,977 **** } } /* the following tries to make it so that a #define a b(c) */ ! /* doesn't count as a define of b. */ } else { number++; if (number >= 4 || (number==2 && strncmp (token, "define", 6))) { gotone = TRUE; --- 1056,1082 ---- } } /* the following tries to make it so that a #define a b(c) */ ! /* doesn't count as a define of b. The token is bad if it */ ! /* is `define' and the first one after the #, or if it is */ ! /* not the second token on the line. However, if dflag is */ ! /* set, then the macro is valid no matter what. */ ! } else { number++; + if (number==2 && !strncmp (token, "define", 6) && dflag) + { + next_token_is_define = 1; + goto badone; + } + if (next_token_is_define) + { + next_token_is_define = 0; + *f = 0; + win = 1; + goto ret; + } if (number >= 4 || (number==2 && strncmp (token, "define", 6))) { gotone = TRUE; *************** *** 1014,1020 **** } /* Detect GNUmacs's function-defining macros. */ if (!number && !strncmp (token, "DEF", 3)) - { next_token_is_func = 1; goto badone; --- 1119,1124 ---- -- Skip Gilbrech email: skip@fsg.com Fusion Systems Group uunet!fsg!skip 225 Broadway, 35th Floor uunet!skipnyc!skip New York, NY 10007 phones: 212-285-8001 (work) 201-825-8732 (home)