summaryrefslogtreecommitdiffstats
path: root/fid.c
diff options
context:
space:
mode:
Diffstat (limited to 'fid.c')
-rw-r--r--fid.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/fid.c b/fid.c
new file mode 100644
index 0000000..a2cb1a2
--- /dev/null
+++ b/fid.c
@@ -0,0 +1,191 @@
+/* fid.c -- list all tokens in the given file(s)
+ 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 "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "idfile.h"
+#include "idarg.h"
+#include "bitops.h"
+#include "filenames.h"
+#include "misc.h"
+#include "strxtra.h"
+#include "alloc.h"
+#include "token.h"
+
+int get_idarg_index (char const *file_name);
+int is_hit (unsigned char const *hits, int file_number);
+int is_hit_1 (unsigned char const **hits, int level, int file_number);
+void skip_hits (unsigned char const **hits, int level);
+
+FILE *id_FILE;
+struct idhead idh;
+struct idarg *idarg_0;
+int tree8_levels;
+char const *program_name;
+
+static void
+usage (void)
+{
+ fprintf (stderr, "Usage: %s [-f<file>] file1 file2\n", program_name);
+ exit (1);
+}
+
+int
+main (int argc, char **argv)
+{
+ char const *id_file = IDFILE;
+ char *buf;
+ int op;
+ int i;
+ int index_1 = -1;
+ int index_2 = -1;
+
+ program_name = basename (GETARG (argc, argv));
+
+ while (argc)
+ {
+ char const *arg = GETARG (argc, argv);
+ switch (op = *arg++)
+ {
+ case '-':
+ case '+':
+ break;
+ default:
+ UNGETARG (argc, argv);
+ goto argsdone;
+ }
+ while (*arg)
+ switch (*arg++)
+ {
+ case 'f':
+ id_file = arg;
+ goto nextarg;
+ default:
+ usage ();
+ }
+ nextarg:;
+ }
+argsdone:
+
+ id_file = look_up (id_file);
+ if (id_file == NULL)
+ {
+ filerr ("open", id_file);
+ return 1;
+ }
+ id_FILE = init_idfile (id_file, &idh, &idarg_0);
+ if (id_FILE == NULL)
+ {
+ filerr ("open", id_file);
+ return 1;
+ }
+ switch (argc)
+ {
+ case 2:
+ index_2 = get_idarg_index (argv[1]);
+ /* fall through */
+ case 1:
+ index_1 = get_idarg_index (argv[0]);
+ break;
+ default:
+ usage ();
+ }
+
+ if (index_1 < 0)
+ return 1;
+
+ buf = MALLOC (char, idh.idh_buf_size);
+ fseek (id_FILE, idh.idh_tokens_offset, 0);
+ tree8_levels = tree8_count_levels (idh.idh_paths);
+
+ for (i = 0; i < idh.idh_tokens; i++)
+ {
+ unsigned char const *hits;
+
+ gets_past_00 (buf, id_FILE);
+ hits = tok_hits_addr (buf);
+ if (is_hit (hits, index_1) && (index_2 < 0 || is_hit (hits, index_2)))
+ printf ("%s\n", tok_string (buf));
+ }
+
+ return 0;
+}
+
+int
+get_idarg_index (char const *file_name)
+{
+ struct idarg *idarg;
+ int file_name_length = strlen (file_name);
+ struct idarg *end = &idarg_0[idh.idh_paths];
+
+ for (idarg = idarg_0; idarg < end; ++idarg)
+ {
+ int arg_length = strlen (idarg->ida_arg);
+ int prefix_length = arg_length - file_name_length;
+ if (prefix_length < 0
+ || (prefix_length > 0 && idarg->ida_arg[prefix_length - 1] != '/'))
+ continue;
+ if (strequ (&idarg->ida_arg[prefix_length], file_name))
+ return idarg->ida_index;
+ }
+ fprintf (stderr, "%s: not found\n", file_name);
+ return -1;
+}
+
+int
+is_hit (unsigned char const *hits, int file_number)
+{
+ return is_hit_1 (&hits, tree8_levels, file_number);
+}
+
+int
+is_hit_1 (unsigned char const **hits, int level, int file_number)
+{
+ int file_hit = 1 << ((file_number >> (3 * --level)) & 7);
+ int hit = *(*hits)++;
+ int bit;
+
+ if (!(file_hit & hit))
+ return 0;
+ if (level == 0)
+ return 1;
+
+ for (bit = 1; (bit < file_hit) && (bit & 0xff); bit <<= 1)
+ {
+ if (hit & bit)
+ skip_hits (hits, level);
+ }
+ return is_hit_1 (hits, level, file_number);
+}
+
+void
+skip_hits (unsigned char const **hits, int level)
+{
+ int hit = *(*hits)++;
+ int bit;
+
+ if (--level == 0)
+ return;
+ for (bit = 1; bit & 0xff; bit <<= 1)
+ {
+ if (hit & bit)
+ skip_hits (hits, level);
+ }
+}