summaryrefslogtreecommitdiffstats
path: root/lid.c
diff options
context:
space:
mode:
Diffstat (limited to 'lid.c')
-rw-r--r--lid.c1365
1 files changed, 0 insertions, 1365 deletions
diff --git a/lid.c b/lid.c
deleted file mode 100644
index 3ce5f85..0000000
--- a/lid.c
+++ /dev/null
@@ -1,1365 +0,0 @@
-/* lid.c -- primary query interface for mkid database
- Copyright (C) 1986, 1995 Greg McGary
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <assert.h>
-#include <limits.h>
-#include <regex.h>
-
-#include <config.h>
-#include "alloc.h"
-#include "idfile.h"
-#include "token.h"
-#include "bitops.h"
-#include "strxtra.h"
-#include "misc.h"
-#include "filenames.h"
-
-typedef void (*doit_t) __P((char const *name, char **argv));
-
-unsigned char *tree8_to_bits __P((unsigned char *bits_vec, unsigned char const *hits_tree8));
-void tree8_to_bits_1 __P((unsigned char **bits_vec, unsigned char const **hits_tree8, int level));
-char **tree8_to_argv __P((unsigned char const *hits_tree8));
-char **bits_to_argv __P((unsigned char const *bits_vec));
-
-static void usage __P((void));
-int common_prefix_suffix __P((char const *path1, char const *path2));
-void look_id __P((char const *name, char **argv));
-void grep_id __P((char const *name, char **argv));
-void edit_id __P((char const *name, char **argv));
-int skip_to_argv __P((char **argv));
-int find_plain __P((char const *arg, doit_t doit));
-int find_anchor __P((char const *arg, doit_t doit));
-int find_regexp __P((char const *arg, doit_t doit));
-int find_number __P((char const *arg, doit_t doit));
-int find_non_unique __P((unsigned int, doit_t doit));
-int find_apropos __P((char const *arg, doit_t doit));
-void parse_frequency_arg __P((char const *arg));
-int frequency_wanted __P((char const *tok));
-char const *strcpos __P((char const *s1, char const *s2));
-char const *file_regexp __P((char const *name0, char const *left_delimit, char const *right_delimit));
-off_t find_token __P((char const *token));
-int is_regexp __P((char *name));
-char **vec_to_argv __P((int const *vec));
-int file_name_wildcard __P((char const *re, char const *fn));
-int match_file_names __P((char const *re, doit_t doit));
-int word_match __P((char const *name0, char const *line));
-int radix __P((char const *name));
-int stoi __P((char const *name));
-int otoi __P((char const *name));
-int dtoi __P((char const *name));
-int xtoi __P((char const *name));
-void savetty __P((void));
-void restoretty __P((void));
-void linetty __P((void));
-void chartty __P((void));
-
-enum radix {
- RADIX_OCT = 1,
- RADIX_DEC = 2,
- RADIX_HEX = 4,
- RADIX_ALL = RADIX_DEC | RADIX_OCT | RADIX_HEX
-};
-
-#define TOLOWER(c) (isupper (c) ? tolower (c) : (c))
-#define IS_ALNUM(c) (isalnum (c) || (c) == '_')
-
-#ifndef BRACE_NOTATION_DEFAULT
-#define BRACE_NOTATION_DEFAULT 1
-#endif
-
-/* Sorry about all the globals, but it's really cleaner this way. */
-FILE *id_FILE;
-int merging;
-int radix_arg;
-int echo_on = 1;
-int brace_notation_on = BRACE_NOTATION_DEFAULT;
-int file_name_regexp = 0;
-int match_base = 0;
-char *anchor_dir;
-int tree8_levels;
-unsigned int bits_vec_size;
-char PWD_buf[MAXPATHLEN];
-struct idhead idh;
-int (*find_func) __P((char const *, doit_t));
-unsigned short frequency_low = 1;
-unsigned short frequency_high = USHRT_MAX;
-char *buf;
-char *buf2;
-unsigned char *bits_vec;
-
-char const *program_name;
-
-static void
-usage (void)
-{
- fprintf (stderr, "Usage: %s [-f<file>] [-u<n>] [-r<dir>] [-mewdoxaskncg] patterns...\n", program_name);
- exit (1);
-}
-
-int
-main (int argc, char **argv)
-{
- char const *id_file_name = IDFILE;
- doit_t doit = look_id;
- int force_merge = 0;
- unsigned int unique_limit = 0;
- int (*forced_find_func) __P((char const *, doit_t)) = NULL;
-
- program_name = basename ((argc--, *argv++));
-
- while (argc)
- {
- char const *arg = (argc--, *argv++);
- int op = *arg++;
- switch (op)
- {
- case '-':
- case '+':
- break;
- default:
- (argc++, --argv);
- goto argsdone;
- }
- while (*arg)
- switch (*arg++)
- {
- case 'f':
- id_file_name = arg;
- goto nextarg;
- case 'u':
- unique_limit = stoi (arg);
- goto nextarg;
- case 'm':
- force_merge = 1;
- break;
- case 'e':
- forced_find_func = find_regexp;
- file_name_regexp = 1;
- break;
- case 'w':
- forced_find_func = find_plain;
- break;
- case 'd':
- radix_arg |= RADIX_DEC;
- break;
- case 'o':
- radix_arg |= RADIX_OCT;
- break;
- case 'x':
- radix_arg |= RADIX_HEX;
- break;
- case 'a':
- radix_arg |= RADIX_ALL;
- break;
- case 'F':
- parse_frequency_arg (arg);
- goto nextarg;
- case 'k':
- brace_notation_on = 0;
- break;
- case 'g':
- brace_notation_on = 1;
- break;
- case 'n':
- echo_on = 0;
- break;
- case 'b':
- match_base = 1;
- break;
- case 'c':
- maybe_anchor_usage ();
- anchor_dir = PWD_buf;
- break;
- case 'r':
- maybe_anchor_usage ();
- anchor_dir = arg;
- goto nextarg;
- default:
- usage ();
- }
- nextarg:;
- }
-argsdone:
-
- get_PWD (PWD_buf);
- id_file_name = find_id_file (id_file_name);
-
- if (anchor_dir == NULL)
- anchor_dir = strdup (span_dir_name (PWD_buf, id_file_name));
- else if (anchor_dir != PWD_buf)
- anchor_dir = strdup (span_dir_name (PWD_buf, anchor_dir));
-
- id_FILE = init_id_file (id_file_name, &idh);
- bits_vec_size = (idh.idh_files + 7) >> 3;
- tree8_levels = tree8_count_levels (idh.idh_files);
-
- switch (program_name[0])
- {
- case 'a':
- forced_find_func = find_apropos;
- /*FALLTHROUGH*/
- case 'l':
- doit = look_id;
- break;
- case 'g':
- doit = grep_id;
- break;
- case 'e':
- doit = edit_id;
- break;
- case 'p':
- forced_find_func = match_file_names;
- doit = look_id;
- break;
- default:
- program_name = "[algep]id";
- usage ();
- }
-
- if (argc == 0)
- {
- (argc++, --argv);
- *(char const **)argv = ".";
- }
-
- while (argc)
- {
- long val = -1;
- char *arg = (argc--, *argv++);
-
- if (forced_find_func)
- find_func = forced_find_func;
- else if (radix (arg) && (val = stoi (arg)) >= 0)
- find_func = find_number;
- else if (is_regexp (arg))
- find_func = find_regexp;
- else if (arg[0] == '^')
- find_func = find_anchor;
- else
- find_func = find_plain;
-
- if ((doit == look_id && !force_merge)
- || (find_func == find_number
- && val > 7
- && radix_arg != RADIX_DEC
- && radix_arg != RADIX_OCT
- && radix_arg != RADIX_HEX))
- merging = 0;
- else
- merging = 1;
-
- buf = malloc (idh.idh_buf_size);
- buf2 = malloc (idh.idh_buf_size);
- bits_vec = MALLOC (unsigned char, bits_vec_size);
-
- if (unique_limit)
- {
- if (!find_non_unique (unique_limit, doit))
- fprintf (stderr, "All identifiers are unique within the first %d characters\n", unique_limit);
- exit (0);
- }
- else if (!(*find_func) (arg, doit))
- {
- fprintf (stderr, "%s: not found\n", arg);
- continue;
- }
- }
- exit (0);
-}
-
-/* common_prefix_suffix returns non-zero if two file names have a
- fully common directory prefix and a common suffix (i.e., they're
- eligible for coalescing with brace notation. */
-
-int
-common_prefix_suffix (char const *file_name_1, char const *file_name_2)
-{
- char const *slash_1;
- char const *slash_2;
-
- slash_1 = strrchr (file_name_1, '/');
- slash_2 = strrchr (file_name_2, '/');
-
- if (slash_1 == NULL && slash_2 == NULL)
- return strequ (suff_name (file_name_1), suff_name (file_name_2));
- if ((slash_1 - file_name_1) != (slash_2 - file_name_2))
- return 0;
- if (!strnequ (file_name_1, file_name_2, slash_1 - file_name_1))
- return 0;
- return strequ (suff_name (slash_1), suff_name (slash_2));
-}
-
-void
-look_id (char const *name, char **argv)
-{
- char const *arg;
- char const *dir;
- int using_braces = 0;
-
- if (echo_on)
- printf ("%-14s ", name);
- while (*argv)
- {
- arg = *argv++;
- if (*argv && brace_notation_on && common_prefix_suffix (arg, *argv))
- {
- if (using_braces)
- printf (",%s", root_name (arg));
- else
- {
- dir = dirname (arg);
- if (dir && !strequ (dir, "."))
- printf ("%s/", dir);
- printf ("{%s", root_name (arg));
- }
- using_braces = 1;
- }
- else
- {
- if (using_braces)
- printf (",%s}%s", root_name (arg), suff_name (arg));
- else
- fputs (arg, stdout);
- using_braces = 0;
- if (*argv)
- putchar (' ');
- }
- }
- putchar ('\n');
-}
-
-void
-grep_id (char const *name, char **argv)
-{
- char line[BUFSIZ];
- char const *re = NULL;
- int line_number;
-
- if (merging)
- {
- re = file_regexp (name, "[^a-zA-Z0-9_]_*", "[^a-zA-Z0-9_]");
- if (re)
- {
- char const *regexp_error = re_comp (re);
- if (regexp_error)
- {
- fprintf (stderr, "%s: Syntax Error: %s (%s)\n", program_name, re, regexp_error);
- return;
- }
- }
- }
-
- line[0] = ' '; /* sentry */
- while (*argv)
- {
- char const *file_name = *argv++;
- FILE *gid_FILE = fopen (file_name, "r");
-
- if (gid_FILE == NULL)
- {
- filerr ("open", file_name);
- continue;
- }
- line_number = 0;
- while (fgets (&line[1], sizeof (line), gid_FILE))
- {
- line_number++;
- if (re)
- {
- if (!re_exec (line))
- continue;
- }
- else if (!word_match (name, line))
- continue;
- printf ("%s:%d: %s", file_name, line_number, &line[1]);
- }
- fclose (gid_FILE);
- }
-}
-
-void
-edit_id (char const *name, char **argv)
-{
- char re_buffer[BUFSIZ];
- char ed_arg_buffer[BUFSIZ];
- char const *re;
- int c;
- int skip;
- static char const *editor;
- static char const *eid_arg;
- static char const *eid_right_del;
- static char const *eid_left_del;
-
- if (editor == NULL)
- {
- editor = getenv ("EDITOR");
- if (editor == NULL)
- {
- editor = "vi";
- eid_arg = "+1;/%s/";
- eid_left_del = "\\<";
- eid_right_del = "\\>";
- }
- }
- if (eid_left_del == NULL)
- {
- eid_arg = getenv ("EIDARG");
- eid_left_del = getenv ("EIDLDEL");
- if (eid_left_del == NULL)
- eid_left_del = "";
- eid_right_del = getenv ("EIDRDEL");
- if (eid_right_del == NULL)
- eid_right_del = "";
- }
-
- look_id (name, argv);
- savetty ();
- for (;;)
- {
- printf ("Edit? [y1-9^S/nq] ");
- fflush (stdout);
- chartty ();
- c = (getchar () & 0177);
- restoretty ();
- switch (TOLOWER (c))
- {
- case '/':
- case ('s' & 037):
- putchar ('/');
- skip = skip_to_argv (argv);
- if (skip < 0)
- continue;
- argv += skip;
- goto editit;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- putchar (c);
- skip = c - '0';
- break;
- case 'y':
- putchar (c);
- /*FALLTHROUGH*/
- case '\n':
- case '\r':
- skip = 0;
- break;
- case 'q':
- putchar (c);
- putchar ('\n');
- exit (0);
- case 'n':
- putchar (c);
- putchar ('\n');
- return;
- default:
- putchar (c);
- putchar ('\n');
- continue;
- }
-
- putchar ('\n');
- while (skip--)
- if (*++argv == NULL)
- continue;
- break;
- }
-editit:
-
- if (merging)
- re = file_regexp (name, eid_left_del, eid_right_del);
- else
- re = NULL;
- if (re == NULL)
- {
- re = re_buffer;
- sprintf (re_buffer, "%s%s%s", eid_left_del, name, eid_right_del);
- }
-
- switch (fork ())
- {
- case -1:
- fprintf (stderr, "%s: Cannot fork (%s)\n", program_name, strerror (errno));
- exit (1);
- case 0:
- argv--;
- if (eid_arg)
- {
- argv--;
- sprintf (ed_arg_buffer, eid_arg, re);
- argv[1] = ed_arg_buffer;
- }
- *(char const **) argv = editor;
- execvp (editor, argv);
- filerr ("exec", editor);
- default:
- {
- void (*oldint) __P((int)) = signal (SIGINT, SIG_IGN);
- void (*oldquit) __P((int)) = signal (SIGQUIT, SIG_IGN);
-
- while (wait (0) == -1 && errno == EINTR)
- ;
-
- signal (SIGINT, oldint);
- signal (SIGQUIT, oldquit);
- }
- break;
- }
-}
-
-int
-skip_to_argv (char **argv)
-{
- char pattern[BUFSIZ];
- unsigned int count;
-
- if (gets (pattern) == NULL)
- return -1;
-
- for (count = 0; *argv; count++, argv++)
- if (strcpos (*argv, pattern))
- return count;
- return -1;
-}
-
-int
-find_plain (char const *arg, doit_t doit)
-{
- if (find_token (arg) == 0)
- return 0;
- gets_past_00 (buf, id_FILE);
- assert (*buf);
- if (!frequency_wanted (buf))
- return 0;
- (*doit) (buf, tree8_to_argv (tok_hits_addr (buf)));
- return 1;
-}
-
-int
-find_anchor (char const *arg, doit_t doit)
-{
- int count;
- unsigned int length;
-
- if (find_token (++arg) == 0)
- return 0;
-
- length = strlen (arg);
- count = 0;
- if (merging)
- memset (bits_vec, 0, bits_vec_size);
- while (gets_past_00 (buf, id_FILE) > 0)
- {
- assert (*buf);
- if (!frequency_wanted (buf))
- continue;
- if (!strnequ (arg, buf, length))
- break;
- if (merging)
- tree8_to_bits (bits_vec, tok_hits_addr (buf));
- else
- (*doit) (buf, tree8_to_argv (tok_hits_addr (buf)));
- count++;
- }
- if (merging && count)
- (*doit) (--arg, bits_to_argv (bits_vec));
-
- return count;
-}
-
-int
-find_regexp (char const *re, doit_t doit)
-{
- int count;
- char const *regexp_error;
-
- regexp_error = re_comp (re);
- if (regexp_error)
- {
- fprintf (stderr, "%s: Syntax Error: %s (%s)\n", program_name, re, regexp_error);
- return 0;
- }
- fseek (id_FILE, idh.idh_tokens_offset, SEEK_SET);
-
- count = 0;
- if (merging)
- memset (bits_vec, 0, bits_vec_size);
- while (gets_past_00 (buf, id_FILE) > 0)
- {
- assert (*buf);
- if (!frequency_wanted (buf))
- continue;
- if (!re_exec (buf))
- continue;
- if (merging)
- tree8_to_bits (bits_vec, tok_hits_addr (buf));
- else
- (*doit) (buf, tree8_to_argv (tok_hits_addr (buf)));
- count++;
- }
- if (merging && count)
- (*doit) (re, bits_to_argv (bits_vec));
-
- return count;
-}
-
-int
-find_number (char const *arg, doit_t doit)
-{
- int count;
- int rdx;
- int val;
- int hit_digits = 0;
-
- rdx = (val = stoi (arg)) ? RADIX_ALL : radix (arg);
- fseek (id_FILE, idh.idh_tokens_offset, SEEK_SET);
-
- count = 0;
- if (merging)
- memset (bits_vec, 0, bits_vec_size);
- while (gets_past_00 (buf, id_FILE) > 0)
- {
- if (hit_digits)
- {
- if (!isdigit (*buf))
- break;
- }
- else
- {
- if (isdigit (*buf))
- hit_digits = 1;
- }
-
- if (!((radix_arg ? radix_arg : rdx) & radix (buf))
- || stoi (buf) != val)
- continue;
- if (merging)
- tree8_to_bits (bits_vec, tok_hits_addr (buf));
- else
- (*doit) (buf, tree8_to_argv (tok_hits_addr (buf)));
- count++;
- }
- if (merging && count)
- (*doit) (arg, bits_to_argv (bits_vec));
-
- return count;
-}
-
-/* Find identifiers that are non-unique within the first `count'
- characters. */
-int
-find_non_unique (unsigned int limit, doit_t doit)
-{
- char *old = buf;
- char *new = buf2;
- int consecutive = 0;
- int count = 0;
- char name[1024];
-
- if (limit <= 1)
- usage ();
- assert (limit < sizeof(name));
-
- name[0] = '^';
- *new = '\0';
- fseek (id_FILE, idh.idh_tokens_offset, SEEK_SET);
- while (gets_past_00 (old, id_FILE) > 0)
- {
- char *tmp;
- if (!(tok_flags (old) & TOK_NAME))
- continue;
- tmp = old;
- old = new;
- new = tmp;
- if (!strnequ (new, old, limit))
- {
- if (consecutive && merging)
- {
- strncpy (&name[1], old, limit);
- (*doit) (name, bits_to_argv (bits_vec));
- }
- consecutive = 0;
- continue;
- }
- if (!consecutive++)
- {
- if (merging)
- tree8_to_bits (bits_vec, tok_hits_addr (old));
- else
- (*doit) (old, tree8_to_argv (tok_hits_addr (old)));
- count++;
- }
- if (merging)
- tree8_to_bits (bits_vec, tok_hits_addr (new));
- else
- (*doit) (new, tree8_to_argv (tok_hits_addr (new)));
- count++;
- }
- if (consecutive && merging)
- {
- strncpy (&name[1], new, limit);
- (*doit) (name, bits_to_argv (bits_vec));
- }
- return count;
-}
-
-int
-find_apropos (char const *arg, doit_t doit)
-{
- int count;
-
- fseek (id_FILE, idh.idh_tokens_offset, SEEK_SET);
-
- count = 0;
- if (merging)
- memset (bits_vec, 0, bits_vec_size);
- while (gets_past_00 (buf, id_FILE) > 0)
- {
- assert (*buf);
- if (!frequency_wanted (buf))
- continue;
- if (strcpos (buf, arg) == NULL)
- continue;
- if (merging)
- tree8_to_bits (bits_vec, tok_hits_addr (buf));
- else
- (*doit) (buf, tree8_to_argv (tok_hits_addr (buf)));
- count++;
- }
- if (merging && count)
- (*doit) (arg, bits_to_argv (bits_vec));
-
- return count;
-}
-
-void
-parse_frequency_arg (char const *arg)
-{
- if (*arg == '-')
- frequency_low = 1;
- else
- {
- frequency_low = atoi (arg);
- while (isdigit (*arg))
- arg++;
- if (*arg == '-')
- arg++;
- }
- if (*arg)
- frequency_high = atoi (arg);
- else if (arg[-1] == '-')
- frequency_high = USHRT_MAX;
- else
- frequency_high = frequency_low;
- if (frequency_low > frequency_high)
- fprintf (stderr, "Bogus frequencies: %u > %u\n", frequency_low, frequency_high);
-}
-
-int
-frequency_wanted (char const *tok)
-{
- unsigned int count = tok_count (tok);
- return (frequency_low <= count && count <= frequency_high);
-}
-
-/* if string `s2' occurs in `s1', return a pointer to the first match.
- Ignore differences in alphabetic case. */
-char const *
-strcpos (char const *s1, char const *s2)
-{
- char const *s1p;
- char const *s2p;
- char const *s1last;
-
- for (s1last = &s1[strlen (s1) - strlen (s2)]; s1 <= s1last; s1++)
- for (s1p = s1, s2p = s2; TOLOWER (*s1p) == TOLOWER (*s2p); s1p++)
- if (*++s2p == '\0')
- return s1;
- return NULL;
-}
-
-/* Convert the regular expression that we used to locate identifiers
- in the id database into one suitable for locating the identifiers
- in files. */
-char const *
-file_regexp (char const *name0, char const *left_delimit, char const *right_delimit)
-{
- static char re_buffer[BUFSIZ];
- char *name = (char *) name0;
-
- if (find_func == find_number && merging)
- {
- sprintf (re_buffer, "%s0*[Xx]*0*%d[Ll]*%s", left_delimit, stoi (name), right_delimit);
- return re_buffer;
- }
-
- if (!is_regexp (name) && name[0] != '^')
- return NULL;
-
- if (name[0] == '^')
- name0++;
- else
- left_delimit = "";
- while (*++name)
- ;
- if (*--name == '$')
- *name = '\0';
- else
- right_delimit = "";
-
- sprintf (re_buffer, "%s%s%s", left_delimit, name0, right_delimit);
- return re_buffer;
-}
-
-off_t
-find_token (char const *token_0)
-{
- off_t offset = 0;
- off_t start = idh.idh_tokens_offset - 2;
- off_t end = idh.idh_end_offset;
- off_t anchor_offset = 0;
- int order = -1;
-
- while (start < end)
- {
- int c;
- int incr = 1;
- char const *token;
-
- offset = start + (end - start) / 2;
- fseek (id_FILE, offset, SEEK_SET);
- offset += skip_past_00 (id_FILE);
- if (offset >= end)
- {
- offset = start + 2;
- fseek (id_FILE, offset, SEEK_SET);
- }
-
- /* compare the token names */
- token = token_0;
- while (*token == (c = getc (id_FILE)) && *token && c)
- {
- token++;
- incr++;
- }
- if (c && !*token && find_func == find_anchor)
- anchor_offset = offset;
- order = *token - c;
-
- if (order < 0)
- end = offset - 2;
- else if (order > 0)
- start = offset + incr + skip_past_00 (id_FILE) - 2;
- else
- break;
- }
-
- if (order)
- {
- if (anchor_offset)
- offset = anchor_offset;
- else
- return 0;
- }
- fseek (id_FILE, offset, SEEK_SET);
- return offset;
-}
-
-/* Are there any regexp meta-characters in name?? */
-int
-is_regexp (char *name)
-{
- int backslash = 0;
-
- if (*name == '^')
- name++;
- while (*name)
- {
- if (*name == '\\')
- {
- if (strchr ("<>", name[1]))
- return 1;
- name++, backslash++;
- }
- else if (strchr ("[]{}().*+^$", *name))
- return 1;
- name++;
- }
- if (backslash)
- while (*name)
- {
- if (*name == '\\')
- strcpy (name, name + 1);
- name++;
- }
- return 0;
-}
-
-/* file_name_wildcard implements a simple pattern matcher that
- emulates the shell wild card capability.
-
- * - any string of chars
- ? - any char
- [] - any char in set (if first char is !, any not in set)
- \ - literal match next char */
-int
-file_name_wildcard (char const *re, char const *fn)
-{
- int c;
- int i;
- char set[256];
- int revset;
-
- while ((c = *re++) != '\0')
- {
- if (c == '*')
- {
- if (*re == '\0')
- return 1; /* match anything at end */
- while (*fn != '\0')
- {
- if (file_name_wildcard (re, fn))
- return 1;
- ++fn;
- }
- return 0;
- }
- else if (c == '?')
- {
- if (*fn++ == '\0')
- return 0;
- }
- else if (c == '[')
- {
- c = *re++;
- memset (set, 0, 256);
- if (c == '!')
- {
- revset = 1;
- c = *re++;
- }
- else
- revset = 0;
- while (c != ']')
- {
- if (c == '\\')
- c = *re++;
- set[c] = 1;
- if ((*re == '-') && (*(re + 1) != ']'))
- {
- re += 1;
- while (++c <= *re)
- set[c] = 1;
- ++re;
- }
- c = *re++;
- }
- if (revset)
- for (i = 1; i < 256; ++i)
- set[i] = !set[i];
- if (!set[(int)*fn++])
- return 0;
- }
- else
- {
- if (c == '\\')
- c = *re++;
- if (c != *fn++)
- return 0;
- }
- }
- return (*fn == '\0');
-}
-
-/* match_file_names implements the pid tool. This matches the *names*
- of files in the database against the input pattern rather than the
- *contents* of the files. */
-
-int
-match_file_names (char const *re, doit_t doit)
-{
- char const *abs_name;
- struct idarg *ida = id_args;
- int i;
- int count = 0;
- int matched;
-
- if (file_name_regexp)
- {
- char const *regexp_error = re_comp (re);
- if (regexp_error)
- {
- fprintf (stderr, "%s: Syntax Error: %s (%s)\n", program_name, re, regexp_error);
- return 0;
- }
- }
-
- for (i = 0; i < idh.idh_files; i++, ida++)
- {
- if (*ida->ida_arg == 0)
- continue;
- if (match_base)
- {
- abs_name = strrchr (ida->ida_arg, '/');
- if (abs_name == NULL)
- abs_name = ida->ida_arg;
- }
- else
- abs_name = span_file_name (anchor_dir, ida->ida_arg);
- if (file_name_regexp)
- matched = re_exec (abs_name);
- else
- matched = file_name_wildcard (re, abs_name);
- if (matched)
- {
- BITSET (bits_vec, i);
- ++count;
- }
- }
- if (count)
- (*doit) (re, bits_to_argv (bits_vec));
- return count;
-}
-
-/* Does `name' occur in `line' delimited by non-alphanumerics?? */
-int
-word_match (char const *name0, char const *line)
-{
- char const *name = name0;
-
- for (;;)
- {
- /* find an initial-character match */
- while (*line != *name)
- {
- if (*line == '\0' || *line == '\n')
- return 0;
- line++;
- }
- /* do we have a word delimiter on the left ?? */
- if (isalnum (line[-1]))
- {
- line++;
- continue;
- }
- /* march down both strings as long as we match */
- while (*++name == *++line)
- ;
- /* is this the end of `name', is there a word delimiter ?? */
- if (*name == '\0' && !IS_ALNUM (*line))
- return 1;
- name = name0;
- }
-}
-
-/* Use the C lexical rules to determine an ascii number's radix. The
- radix is returned as a bit map, so that more than one radix may
- apply. In particular, it is impossible to determine the radix of
- 0, so return all possibilities. */
-int
-radix (char const *name)
-{
- if (!isdigit (*name))
- return 0;
- if (*name != '0')
- return RADIX_DEC;
- name++;
- if (*name == 'x' || *name == 'X')
- return RADIX_HEX;
- while (*name && *name == '0')
- name++;
- return (RADIX_OCT | ((*name) ? 0 : RADIX_DEC));
-}
-
-/* Convert an ascii string number to an integer. Determine the radix
- before converting. */
-int
-stoi (char const *name)
-{
- switch (radix (name))
- {
- case RADIX_DEC:
- return (dtoi (name));
- case RADIX_OCT:
- return (otoi (&name[1]));
- case RADIX_HEX:
- return (xtoi (&name[2]));
- case RADIX_DEC | RADIX_OCT:
- return 0;
- default:
- return -1;
- }
-}
-
-/* Convert an ascii octal number to an integer. */
-int
-otoi (char const *name)
-{
- int n = 0;
-
- while (*name >= '0' && *name <= '7')
- {
- n *= 010;
- n += *name++ - '0';
- }
- if (*name == 'l' || *name == 'L')
- name++;
- return (*name ? -1 : n);
-}
-
-/* Convert an ascii decimal number to an integer. */
-int
-dtoi (char const *name)
-{
- int n = 0;
-
- while (isdigit (*name))
- {
- n *= 10;
- n += *name++ - '0';
- }
- if (*name == 'l' || *name == 'L')
- name++;
- return (*name ? -1 : n);
-}
-
-/* Convert an ascii hex number to an integer. */
-int
-xtoi (char const *name)
-{
- int n = 0;
-
- while (isxdigit (*name))
- {
- n *= 0x10;
- if (isdigit (*name))
- n += *name++ - '0';
- else if (islower (*name))
- n += 0xa + *name++ - 'a';
- else
- n += 0xA + *name++ - 'A';
- }
- if (*name == 'l' || *name == 'L')
- name++;
- return (*name ? -1 : n);
-}
-
-unsigned char *
-tree8_to_bits (unsigned char *bv_0, unsigned char const *hits_tree8)
-{
- unsigned char* bv = bv_0;
- tree8_to_bits_1 (&bv, &hits_tree8, tree8_levels);
- return bv_0;
-}
-
-void
-tree8_to_bits_1 (unsigned char **bv, unsigned char const **hits_tree8, int level)
-{
- int hits = *(*hits_tree8)++;
-
- if (--level)
- {
- int incr = 1 << ((level - 1) * 3);
- int bit;
- for (bit = 1; bit & 0xff; bit <<= 1)
- {
- if (bit & hits)
- tree8_to_bits_1 (bv, hits_tree8, level);
- else
- *bv += incr;
- }
- }
- else
- *(*bv)++ |= hits;
-}
-
-char **
-bits_to_argv (unsigned char const *bv)
-{
- int const reserved_argv_slots = 3;
- static char **argv_0;
- char **argv;
- struct idarg *ida = id_args;
- struct idarg *end = &id_args[idh.idh_files];
-
- if (argv_0 == NULL)
- argv_0 = MALLOC (char *, idh.idh_files + reserved_argv_slots + 2);
- argv = &argv_0[reserved_argv_slots];
-
- for (;;)
- {
- int hits;
- int bit;
-
- while (*bv == 0)
- {
- bv++;
- ida += 8;
- if (ida >= end)
- goto out;
- }
- hits = *bv++;
- for (bit = 1; bit & 0xff; bit <<= 1)
- {
- if (bit & hits)
- {
- if (!(ida->ida_flags & IDA_RELATIVE))
- {
- char const *abs_name = span_file_name (anchor_dir, ida->ida_arg);
- char const *rel_name = relative_file_name (PWD_buf, abs_name);
- char const *short_name = (strlen (rel_name) > strlen (abs_name)
- ? abs_name : rel_name);
- if (!strequ (short_name, ida->ida_arg))
- ida->ida_arg = strdup (short_name);
- ida->ida_flags |= IDA_RELATIVE;
- }
- *argv++ = ida->ida_arg;
- }
- if (++ida >= end)
- goto out;
- }
- }
-out:
- *argv = NULL;
- return &argv_0[reserved_argv_slots];
-}
-
-char **
-tree8_to_argv (unsigned char const *hits_tree8)
-{
- memset (bits_vec, 0, bits_vec_size);
- return bits_to_argv (tree8_to_bits (bits_vec, hits_tree8));
-}
-
-#if HAVE_TERMIOS_H
-
-#include <termios.h>
-struct termios linemode;
-struct termios charmode;
-struct termios savemode;
-#define GET_TTY_MODES(modes) tcgetattr (0, (modes))
-#define SET_TTY_MODES(modes) tcsetattr(0, TCSANOW, (modes))
-
-#else /* not HAVE_TERMIOS_H */
-
-# if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-# endif
-
-# if HAVE_TERMIO_H
-
-# include <termio.h>
-struct termio linemode;
-struct termio charmode;
-struct termio savemode;
-#define GET_TTY_MODES(modes) ioctl (0, TCGETA, (modes))
-#define SET_TTY_MODES(modes) ioctl (0, TCSETA, (modes))
-
-# else /* not HAVE_TERMIO_H */
-
-# if HAVE_SGTTY_H
-
-# include <sgtty.h>
-struct sgttyb linemode;
-struct sgttyb charmode;
-struct sgttyb savemode;
-
-# ifdef TIOCGETP
-#define GET_TTY_MODES(modes) ioctl (0, TIOCGETP, (modes))
-#define SET_TTY_MODES(modes) ioctl (0, TIOCSETP, (modes))
-# else
-#define GET_TTY_MODES(modes) gtty (0, (modes))
-#define SET_TTY_MODES(modes) stty (0, (modes))
-# endif
-
-void
-savetty (void)
-{
-# ifdef TIOCGETP
- ioctl(0, TIOCGETP, &savemode);
-# else
- gtty(0, &savemode);
-# endif
- charmode = linemode = savemode;
-
- charmode.sg_flags &= ~ECHO;
- charmode.sg_flags |= RAW;
-
- linemode.sg_flags |= ECHO;
- linemode.sg_flags &= ~RAW;
-}
-
-# endif /* not HAVE_SGTTY_H */
-# endif /* not HAVE_TERMIO_H */
-#endif /* not HAVE_TERMIOS_H */
-
-#if HAVE_TERMIOS_H || HAVE_TERMIO_H
-
-void
-savetty (void)
-{
- GET_TTY_MODES (&savemode);
- charmode = linemode = savemode;
-
- charmode.c_lflag &= ~(ECHO | ICANON | ISIG);
- charmode.c_cc[VMIN] = 1;
- charmode.c_cc[VTIME] = 0;
-
- linemode.c_lflag |= (ECHO | ICANON | ISIG);
- linemode.c_cc[VEOF] = 'd' & 037;
- linemode.c_cc[VEOL] = 0377;
-}
-
-#endif
-
-#if HAVE_TERMIOS_H || HAVE_TERMIO_H || HAVE_SGTTY_H
-
-void
-restoretty (void)
-{
- SET_TTY_MODES (&savemode);
-}
-
-void
-linetty (void)
-{
- SET_TTY_MODES (&linemode);
-}
-
-void
-chartty (void)
-{
- SET_TTY_MODES (&charmode);
-}
-
-#endif