Subject: ctags very slow when processing kernel (#179) Index: ucb/ctags.c 2.11BSD Description: The 'ctags' program slows very noticeably when creating the kernel tags file (/sys/sys/tags). Repeat-By: cd /sys/GENERIC make tags Fix: All updates are available via anonymous FTP to ftp.iipo.gtegsc.com in the directory /pub/2.11BSD. Most of the slow down is due to ctags running almost out of memory, there is not sufficient malloc'able memory left to allocate a buffer when 'fopen' is used to read the input files. The fix was to allocate a buffer on the stack and use 'setbuf' to assign the buffer before the first read or write. This speed up the ctags run for the kernel by a factor of 2 to 3. There were local routines to perform case insensitive string comaprison, character searching and dynamic string duplication. These were removed and the references to them changed to the system provided routines in libc.a (strcasecmp, rindex, and strdup respectively). Apply the patch below and reinstall 'ctags': 1) Save the patch to /tmp/patchfile 2) patch -p0 < /tmp/patchfile 3) cd /usr/src/ucb 4) make ctags 5) install -s ctags /usr/ucb ==============cut here *** /usr/src/ucb/ctags.c.old Mon Feb 16 22:11:08 1987 --- /usr/src/ucb/ctags.c Wed Feb 16 23:47:07 1994 *************** *** 4,27 **** * specifies the terms and conditions for redistribution. */ ! #ifndef lint char copyright[] = "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; - #endif not lint ! #ifndef lint ! static char sccsid[] = "@(#)ctags.c 5.1 (Berkeley) 5/31/85"; ! #endif not lint #include #include /* * ctags: create a tags file */ - #define reg register #define bool char #define TRUE (1) --- 4,25 ---- * specifies the terms and conditions for redistribution. */ ! #if !defined(lint) && defined(DOSCCS) char copyright[] = "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)ctags.c 5.1.1 (2.11BSD) 2/16/94"; ! #endif #include #include + #include /* * ctags: create a tags file */ #define bool char #define TRUE (1) *************** *** 94,101 **** NODE *head; /* the head of the sorted binary tree */ - char *savestr(); - char *rindex(), *index(); char *toss_comment(); main(ac,av) --- 92,97 ---- *************** *** 102,108 **** int ac; char *av[]; { ! char cmd[100]; int i; while (ac > 1 && av[1][0] == '-') { --- 98,104 ---- int ac; char *av[]; { ! char cmd[100], outfbuf[BUFSIZ]; int i; while (ac > 1 && av[1][0] == '-') { *************** *** 178,183 **** --- 174,181 ---- perror(outfile); exit(1); } + setbuf(outf, outfbuf); + put_entries(head); fclose(outf); if (uflag) { *************** *** 198,205 **** init() { ! reg char *sp; ! reg int i; for (i = 0; i < 0177; i++) { _wht[i] = _etk[i] = _itk[i] = _btk[i] = FALSE; --- 196,203 ---- init() { ! register char *sp; ! register int i; for (i = 0; i < 0177; i++) { _wht[i] = _etk[i] = _itk[i] = _btk[i] = FALSE; *************** *** 224,236 **** find_entries(file) char *file; { ! char *cp; if ((inf = fopen(file,"r")) == NULL) { perror(file); return; } ! curfile = savestr(file); lineno = 0; cp = rindex(file, '.'); /* .l implies lisp or lex source code */ --- 222,236 ---- find_entries(file) char *file; { ! char *cp, infbuf[BUFSIZ]; if ((inf = fopen(file,"r")) == NULL) { perror(file); return; } ! setbuf(inf, infbuf); ! ! curfile = strdup(file); lineno = 0; cp = rindex(file, '.'); /* .l implies lisp or lex source code */ *************** *** 300,306 **** *fp = 0; name = nbuf; } ! np->entry = savestr(name); np->file = curfile; np->f = f; np->lno = ln; --- 300,306 ---- *fp = 0; name = nbuf; } ! np->entry = strdup(name); np->file = curfile; np->f = f; np->lno = ln; *************** *** 310,316 **** strcat(lbuf, "$"); lbuf[50] = 0; } ! np->pat = savestr(lbuf); if (head == NULL) head = np; else --- 310,316 ---- strcat(lbuf, "$"); lbuf[50] = 0; } ! np->pat = strdup(lbuf); if (head == NULL) head = np; else *************** *** 447,453 **** char **lp,*token,*tp; int *f; { ! reg char c,*sp,*tsp; static bool found; bool firsttok; /* T if have seen first token in ()'s */ int bad; --- 447,453 ---- char **lp,*token,*tp; int *f; { ! register char c,*sp,*tsp; static bool found; bool firsttok; /* T if have seen first token in ()'s */ int bad; *************** *** 699,707 **** } put_entries(node) ! reg NODE *node; { ! reg char *sp; if (node == NULL) return; --- 699,707 ---- } put_entries(node) ! register NODE *node; { ! register char *sp; if (node == NULL) return; *************** *** 860,900 **** pfcnt++; } - char * - savestr(cp) - char *cp; - { - register int len; - register char *dp; - - len = strlen(cp); - dp = (char *)malloc(len+1); - strcpy(dp, cp); - return (dp); - } - /* - * Return the ptr in sp at which the character c last - * appears; NULL if not found - * - * Identical to v7 rindex, included for portability. - */ - - char * - rindex(sp, c) - register char *sp, c; - { - register char *r; - - r = NULL; - do { - if (*sp == c) - r = sp; - } while (*sp++); - return(r); - } - - /* * lisp tag functions * just look for (def or (DEF */ --- 860,866 ---- *************** *** 913,921 **** (dbp[2] == 'E' || dbp[2] == 'e') && (dbp[3] == 'F' || dbp[3] == 'f')) { dbp += 4; ! if (striccmp(dbp, "method") == 0 || ! striccmp(dbp, "wrapper") == 0 || ! striccmp(dbp, "whopper") == 0) special = TRUE; else special = FALSE; --- 879,887 ---- (dbp[2] == 'E' || dbp[2] == 'e') && (dbp[3] == 'F' || dbp[3] == 'f')) { dbp += 4; ! if (strcasecmp(dbp, "method") == 0 || ! strcasecmp(dbp, "wrapper") == 0 || ! strcasecmp(dbp, "whopper") == 0) special = TRUE; else special = FALSE; *************** *** 963,994 **** } /* - * striccmp: - * Compare two strings over the length of the second, ignoring - * case distinctions. If they are the same, return 0. If they - * are different, return the difference of the first two different - * characters. It is assumed that the pattern (second string) is - * completely lower case. - */ - striccmp(str, pat) - register char *str, *pat; - { - register int c1; - - while (*pat) { - if (isupper(*str)) - c1 = tolower(*str); - else - c1 = *str; - if (c1 != *pat) - return c1 - *pat; - pat++; - str++; - } - return 0; - } - - /* * first_char: * Return the first non-blank character in the file. After * finding it, rewind the input file so we start at the beginning --- 929,934 ---- *************** *** 1026,1029 **** return; } } - --- 966,968 ----