lq-text Full Text Retrieval Database Part 03/13
Liam R. E. Quin
lee at sq.sq.com
Mon Mar 4 12:01:49 AEST 1991
: cut here --- cut here --
: To unbundle, sh this file
#! /bin/sh
: part 03
echo x - lq-text/src/UseHash
cat > lq-text/src/UseHash << 'barefoot_choirboy'
# Run this if you want to use the BSD hash package (ozmahash)
cd src
cp ozmahash/*.h h
cp ozmahash/ndbm.h h/ozmahash.h
barefoot_choirboy
chmod +x UseHash
echo x - lq-text/src/liblqtext/Defaults.c 1>&2
sed 's/^X//' >lq-text/src/liblqtext/Defaults.c <<'@@@End of lq-text/src/liblqtext/Defaults.c'
X/* Defaults.c -- Copyright 1989 Liam R. Quin. All Rights Reserved.
X * This code is NOT in the public domain.
X * See the file COPYRIGHT for full details.
X *
X * $Id: Defaults.c,v 1.7 90/10/06 00:11:37 lee Rel1-10 $
X *
X * $Log: Defaults.c,v $
X * Revision 1.7 90/10/06 00:11:37 lee
X * Prepared for first beta release.
X *
X * Revision 1.6 90/08/29 21:46:25 lee
X * Alpha release.
X *
X * Revision 1.5 90/08/09 19:16:08 lee
X * *** empty log message ***
X *
X * Revision 1.4 90/04/21 17:26:26 lee
X * now passes gcc -W (before Canada...)
X *
X * Revision 1.3 90/03/23 17:58:57 lee
X * Integrated with globals.h and added a few more comments.
X * Also fixed a bug whereby the configuration file over-rode both
X * command-line options and environment variables!
X *
X * Revision 1.2 90/03/20 20:52:38 lee
X * removed some globals...
X *
X *
X */
X
X#define DefineThem /* turn externs off so we do initialisations here */
X# include "globals.h" /* defines and declarations for database filenames */
X#undef DefineThem
X#undef EXTERN
X#include <fcntl.h>
X#include <errno.h>
X#ifdef SYSV
Xextern int _filbuf(); /* this must appear before stdio.h is included... */
X#endif
X#include <stdio.h>
X#include <malloc.h>
X#include <ctype.h>
X#include "emalloc.h"
X#include <sys/types.h>
X#include "fileinfo.h"
X#include "wordinfo.h"
X#include "phrase.h"
X
X/* $Id: Defaults.c,v 1.7 90/10/06 00:11:37 lee Rel1-10 $
X *
X * This file is part of nx-text, Liam Quin's text retrieval package.
X *
X * Defaults.c -- set up filenames etc. from defaults + cmd line + env.
X *
X * -DUNDERHOME is used here, as is DEFAULTCOMMONWORDS, etc. from Makefile.
X * See comments in Makefile.
X *
X * $Log: Defaults.c,v $
X * Revision 1.7 90/10/06 00:11:37 lee
X * Prepared for first beta release.
X *
X * Revision 1.6 90/08/29 21:46:25 lee
X * Alpha release.
X *
X * Revision 1.5 90/08/09 19:16:08 lee
X * *** empty log message ***
X *
X * Revision 1.4 90/04/21 17:26:26 lee
X * now passes gcc -W (before Canada...)
X *
X * Revision 1.3 90/03/23 17:58:57 lee
X * Integrated with globals.h and added a few more comments.
X * Also fixed a bug whereby the configuration file over-rode both
X * command-line options and environment variables!
X *
X * Revision 1.2 90/03/20 20:52:38 lee
X * removed some globals...
X *
X *
X */
X
X/* System and Library calls used in this function:
X *
X */
Xextern int open(), close();
Xextern void exit();
X
Xextern int atoi(), strcmp(), strlen();
X#ifndef tolower
X extern int tolower();
X#endif
Xextern char *strcpy();
Xextern void perror();
Xextern int ReadCommonWords(), IsDir();
Xint cknatstr();
Xstatic int NextChar();
Xstatic void ReadDefaultFile();
X
X
Xtypedef enum {
X FW_Cmdline,
X FW_Envvar,
X FW_Default, /* use the default */
X FW_File, /* from the config file */
X FW_None /* don't use any at all */
X} t_FromWhere;
X
Xstatic t_FromWhere DirFromWhere = FW_Default;
Xstatic t_FromWhere CommonFromWhere = FW_Default;
Xstatic t_FromWhere DocFromWhere = FW_Default;
X
Xextern int MakeDocPath(); /* hand it DOCPATH... */
Xextern int AsciiTrace;
X
Xchar *mkdbm();
Xchar *joinstr3();
X
X/* should PCM_HalfCase be in globals.h??? */
Xt_PhraseCaseMatch PhraseMatchLevel = PCM_HalfCase;
X
Xvoid
XSetDefaults(argc, argv)
X int argc;
X char **argv;
X{
X extern char *getenv();
X extern char *progname;
X char *p;
X
X /* main() should have set progname. If it didn't. we don't strip
X * the leading / as this is (I hope!) a testing and not a production
X * version... and an early test at that!
X */
X if (!progname || !*progname) progname = argv[0];
X
X /* loop over arguments, looking for
X * -d -- set directory for database
X * -c -- common words file
X *
X * don't use getopts, as we'll be using that later in main(),
X * and it doesn't like being called twice.
X * As a result, main() should ignore the z: option.
X */
X while (--argc > 0) {
X if (**++argv == '-' || **argv == '+') {
X char TurnOn = (**argv == '-');
X
X switch((*argv)[1]) {
X case 'm': /* precise matching */
X argv[0][1] = 'z'; /* so it gets ignored by getopt */
X
X if (!*(p = &argv[0][2])) {
X if (argc > 1) {
X argc--; argv++;
X p = (*argv);
X } else {
X fprintf(stderr,
X "%s: -m must be followed by a, h or p; see -x\n",
X progname);
X exit(1);
X }
X }
X if (p[1]) {
X fprintf(stderr,
X "%s: -m must be followed by a, h or p, not \"%s\"\n",
X progname, p);
X }
X
X switch (*p) {
X case 'p': /* precise */
X PhraseMatchLevel = PCM_SameCase;
X break;
X case 'h': /* heuristic */
X PhraseMatchLevel = PCM_HalfCase;
X break;
X case 'a': /* any, approxmate */
X PhraseMatchLevel = PCM_AnyCase;
X break;
X default:
X fprintf(stderr,
X "%s: -m must be followed by \"p\", \"h\" or \"a\";\n",
X progname);
X fprintf(stderr,
X "use %s -xv for more explanation.\n", progname);
X exit(1);
X }
X break;
X
X case 'v': /* -v is the same as -t1 */
X argv[0][1] = 'Z'; /* so it gets ignored by getopt */
X ++AsciiTrace;
X break;
X case 't': /* trace level */
X argv[0][1] = 'z'; /* so it gets ignored by getopt */
X if (argv[0][2] != '\0') {
X p = &argv[0][2];
X } else {
X if (argc > 1) {
X argc--;
X p = (*++argv);
X } else {
X p = "1";
X }
X }
X if (cknatstr(p)) {
X AsciiTrace = atoi(p);
X } else {
X fprintf(stderr, "%s: -t: \"%s\" is not a number\n",
X progname, p);
X exit(1);
X }
X if (AsciiTrace <= 0) AsciiTrace = 1;
X fprintf(stderr, "%s: trace level set to %d\n",
X progname, AsciiTrace);
X
X break;
X case 'c': /* common file */
X if (TurnOn) {
X CommonFromWhere = FW_Cmdline;
X argv[0][1] = 'z'; /* so it gets ignored by getopt */
X if ((*argv)[2] != '\0') {
X CommonWordFile = &(*argv[2]);
X } else {
X if (argc > 1) {
X CommonWordFile = argv[1];
X argc--; argv++;
X } else {
X fprintf(stderr,
X "%s: -c option must be followed by a filename",
X progname);
X exit(1);
X }
X }
X } else { /* Turn off, +c, may be undocumented right now */
X CommonFromWhere = FW_None;
X break;
X }
X break;
X case 'd':
X argv[0][1] = 'z'; /* so it gets ignored by getopt */
X DirFromWhere = FW_Cmdline;
X if (argv[0][2] != '\0') {
X DatabaseDir = &argv[0][2];
X } else {
X if (argc > 1) {
X DatabaseDir = argv[1];
X argc--; argv++;
X } else {
X /* @error */
X fprintf(stderr,
X "%s: %cd must be followed by a directory name",
X progname, TurnOn ? '-' : '+');
X exit(1);
X }
X }
X break;
X } /* end switch */
X } else {
X /* not an option, so stop looking */
X break;
X }
X } /* end while */
X
X /* now we have parsed the command line arguments, so look for the
X * default directory
X */
X if (DirFromWhere == FW_Default) {
X char *t;
X
X if ((t = getenv("LQTEXTDIR")) != (char *) 0) {
X DatabaseDir = emalloc(strlen(t) + 1);
X (void) strcpy(DatabaseDir, t);
X DirFromWhere = FW_Envvar;
X } else {
X#ifdef UNDERHOME
X char *home = getenv("HOME");
X
X if (home) {
X DatabaseDir = joinstr3(home, "/", UNDERHOME);
X if (!IsDir(DatabaseDir)) {
X fprintf(stderr,
X "%s: database directory \"%s\" inaccessible.\n",
X progname, DatabaseDir);
X exit(1);
X }
X } else {
X fprintf(stderr, "%s: can't find your login directory ($HOME)\n",
X progname);
X exit(1);
X }
X#endif /* UNDERHOME*/
X /* in either case it's the default... */
X DirFromWhere = FW_Default;
X }
X }
X
X if (!DatabaseDir || !*DatabaseDir) {
X /* This can happen if there is no default, or if the user types
X * lqword -d ""
X * just to be malicious :-)
X */
X fprintf(stderr,
X "%s: You must give a database directory with -d or $LQTEXTDIR\n",
X progname);
X fprintf(stderr, " use %s -xv for more details.\n", progname);
X exit(1);
X }
X
X /* IsDir is in DocPath.c -- perhaps this should be, too. */
X if (!IsDir(DatabaseDir)) {
X char *msg = (char *) 0;
X
X switch (DirFromWhere) {
X case FW_Cmdline:
X msg = " (specified with the -d option)";
X break;
X case FW_Envvar:
X msg = " (from $LQTEXTDIR)";
X break;
X }
X fprintf(stderr, "%s: \"%s\"%s is not a directory.\n",
X progname, DatabaseDir, msg ? msg : " ");
X exit(1);
X }
X
X /* set default filenames */
X#define IfNot(x, y) ((x) ? (x) : (y))
X
X FileIndex = mkdbm(DatabaseDir, IfNot(FileIndex, FILEINDEX));
X WordIndex = mkdbm(DatabaseDir, IfNot(WordIndex, WORDINDEX));
X
X DataBase = joinstr3(DatabaseDir, "/", IfNot(DataBase, DATABASE));
X FidFile = joinstr3(DatabaseDir, "/", IfNot(FidFile, FIDFILE));
X WidFile = joinstr3(DatabaseDir, "/", IfNot(WidFile, WIDFILE));
X WidIndexFile =
X joinstr3(DatabaseDir, "/", IfNot(WidIndexFile, WIDINDEXFILE));
X
X ReadDefaultFile();
X
X if (AsciiTrace) {
X fprintf(stderr, "%s: lqtext directory \"%s\"\n",progname,DatabaseDir);
X }
X
X if (CommonFromWhere == FW_Default) {
X char *c = getenv("LQCOMMON");
X
X if (c) {
X CommonWordFile = emalloc(strlen(c) + 1);
X (void) strcpy(CommonWordFile, c);
X CommonFromWhere = FW_Envvar;
X }
X }
X
X if (CommonFromWhere != FW_None && CommonWordFile && *CommonWordFile) {
X extern int errno;
X int c;
X
X if (*CommonWordFile != '/') {
X CommonWordFile = joinstr3(DatabaseDir, "/", CommonWordFile);
X }
X
X if ((c = open(CommonWordFile, O_RDONLY, 0)) < 0) {
X if (CommonFromWhere != FW_Default) {
X int e = errno;
X char *msg = " ";
X
X switch (CommonFromWhere) {
X case FW_Cmdline:
X msg = " (from the -c option)";
X break;
X case FW_Envvar:
X msg = " (from $COMMONWORDS)";
X break;
X }
X
X fprintf(stderr,"%s: can't read common-word file%s ",progname,msg);
X errno = e;
X if (errno) {
X perror(CommonWordFile);
X } else {
X fprintf(stderr, "\"%s\"\n", CommonWordFile);
X }
X exit(1);
X }
X CommonWordFile = (char *) 0;
X } else {
X (void) close(c); /* it's OK */
X }
X }
X
X if ((p = getenv("DOCPATH")) != (char *) 0) {
X switch (DocFromWhere) {
X case FW_File:
X if (AsciiTrace > 1) {
X fprintf(stderr, "%s: DOCPATH (%s) overrides %s (%s)\n",
X#ifdef CONFIGFILE
X progname, p, CONFIGFILE, DocPath
X#else
X progname, p, "README", DocPath
X#endif
X );
X }
X efree(DocPath);
X /* FALL THROUGH */
X case FW_Default:
X default: /* ? */
X DocPath = emalloc((unsigned) (strlen(p) + 1));
X (void) strcpy(DocPath, p);
X DocFromWhere = FW_Envvar;
X break;
X }
X }
X
X if (!DocPath || !*DocPath) {
X DocPath = ".";
X }
X
X#define SetOrNot(s) ( (s && *s) ? s : (s ? "[empty]" : "[null]" ) )
X
X /* this is always here -- it's only checked once, and is actually
X * rather useful.
X */
X if (AsciiTrace > 2) {
X fprintf(stderr, "%s: CommonWordFile = \"%s\"\n", progname,
X SetOrNot(CommonWordFile));
X fprintf(stderr, "%s: DatabaseDir = \"%s\"\n", progname,
X SetOrNot(DatabaseDir));
X fprintf(stderr, "%s: DocPath = \"%s\"\n", progname,
X SetOrNot(DocPath));
X fprintf(stderr, "%s: FileIndex = \"%s\"\n", progname,
X SetOrNot(FileIndex));
X fprintf(stderr, "%s: WordIndex = \"%s\"\n", progname,
X SetOrNot(WordIndex));
X fprintf(stderr, "%s: DataBase = \"%s\"\n", progname,
X SetOrNot(DataBase));
X fprintf(stderr, "%s: FidFile = \"%s\"\n", progname,
X SetOrNot(FidFile));
X fprintf(stderr, "%s: WidFile = \"%s\"\n", progname,
X SetOrNot(WidFile));
X fprintf(stderr, "%s: WidIndexFile = \"%s\"\n", progname,
X SetOrNot(WidIndexFile));
X }
X
X (void) MakeDocPath(DocPath);
X /* DocPath is no longer needed, so getenv() can be called again now */
X
X if (CommonWordFile && *CommonWordFile) {
X (void) ReadCommonWords(CommonWordFile);
X }
X}
X
Xvoid
XDefaultUsage()
X{
X fprintf(stderr, "\
X -c file -- ignore words that are listed in the namd file\n\
X -d dir -- use the lq-text database in the named directory\n\
X -m c -- set matching criteria -- c is \"p\", \"h\" or \"a\"\n");
X if (AsciiTrace) {
X fprintf(stderr, "\
X -m p uses precise matching, where CaSe is significant;\n\
X -m h uses heuristic matching, which is the default, and\n\
X -m a uses approximate matching.\n");
X }
X
X fprintf(stderr, "\n\
X -t N -- set trace level t N (default is zero)\n\
X -x -- print %s explanation\n\
X -xv -- print %s explanation\n\
X -V -- print version information\n\
X -v -- be verbose (same as -t 1)\n",
X AsciiTrace ? "a shorter" : "this",
X AsciiTrace ? "this" : "a longer");
X if (AsciiTrace) {
X fprintf(stderr, "\
XThe current database directory is \"%s\";\n\
X%s will search the path \"%s\" for documents.\n", DatabaseDir, progname, DocPath);
X }
X}
X
X/* This should be in smalldb.c I think */
Xchar *
Xmkdbm(root, prefix)
X char *root; /* /tmp/lqtext */
X char *prefix; /* wordlist, --> /tmp/lqtext.{dir,pag} for dbm */
X{
X#if DBMCREAT == 0
X extern int errno;
X#endif
X /* Although ndbm will create files automatically, gdbm and dbm will
X * not, so we do that here.
X * Also, it might take a while to get to here, so it will be a lot
X * better if we get an error message now.
X */
X char *p = joinstr3(root, "/", prefix);
X
X#if DBMCREAT == 0
X q = joinstr3(p, ".", "dir");
X errno = 0; /* paranoia */
X
X if ((i = open(q)) < 0 && errno == ENOENT) {
X i = open(q, O_CREAT|O_RDWR, 0666); /* rw-rw-rw & umask */
X
X if (i < 0) {
X fprintf(stderr, "%s: can't create \"%s\"\n", progname, q);
X (void) exit(1);
X }
X
X (void) close(i);
X }
X (void) strcpy(&q[strlen(q) - 3], "pag");
X
X if ((i = open(q)) < 0 && errno == ENOENT) {
X i = open(q, O_CREAT|O_RDWR, 0666); /* rw-rw-rw & umask */
X
X if (i < 0) {
X fprintf(stderr, "%s: can't create \"%s\"\n", progname, q);
X (void) exit(1);
X }
X
X (void) close(i);
X }
X
X (void) efree(q);
X
X#endif /*DBMCREAT*/
X
X return p; /* the prefix for dbm, not the whole path */
X}
X
X/* this belongs in string.c or something */
Xchar *
Xjoinstr3(a, b, c)
X char *a, *b, *c;
X{
X char *p;
X int i = strlen(a), j = (b[0] != '\0' && b[1] == '\0') ? 1 : strlen(b);
X
X p = emalloc(i + j + strlen(c) + 1);
X /* ASSERT: p != 0 */
X (void) strcpy(p, a);
X (void) strcpy(&p[i], b);
X (void) strcpy(&p[i + j], c);
X
X return p;
X}
X
X#define LCNOMAP 0 /* Token -- leave case alone */
X#define LCMAP 1 /* map to lower case */
X
Xstatic int RMLine = 0;
X
Xstatic void
XReadDefaultFile()
X{
X extern int errno;
X
X static char *NextToken(); /* see below */
X#ifdef CONFIGFILE
X char *ReadMe = joinstr3(DatabaseDir, "/", CONFIGFILE);
X#else
X char *ReadMe = joinstr3(DatabaseDir, "/", "README");
X#endif
X FILE *fp;
X char *Token;
X
X
X /* This is paranoid... */
X if (!ReadMe || !*ReadMe) {
X fprintf(stderr, "%s: Internal: %s: %d: ReadMe %s\n",
X progname, __FILE__, __LINE__, SetOrNot(ReadMe));
X exit(1);
X }
X
X errno = 0;
X if ((fp = fopen(ReadMe, "r")) == (FILE *) 0) {
X if (errno == EPERM) {
X fprintf(stderr,
X "%s: Warning: you don't have permission to read \"%s\"\n",
X progname, ReadMe);
X } else if (AsciiTrace) {
X int e = errno;
X
X fprintf(stderr, "%s: warning: can't open config file ", progname);
X errno = e;
X perror(ReadMe);
X }
X return;
X }
X
X /* Read README up to an "end" line, ignoring lines starting with # */
X
X while ((Token = NextToken(fp, ReadMe, LCMAP)) != (char *) 0) {
X if (STREQ(Token, "end")) goto finish;
X if (STREQ(Token, "common")) {
X if (!(Token = NextToken(fp, ReadMe, LCNOMAP))) {
X fprintf(stderr, "%s: %s %d: unexpected eof at common file\n",
X progname, ReadMe, RMLine);
X exit(1);
X } else if (CommonFromWhere == FW_Default) {
X CommonWordFile = emalloc((unsigned) (strlen(Token) + 1));
X (void) strcpy(CommonWordFile, Token);
X CommonFromWhere = FW_File;
X }
X } else if (STREQ(Token, "path") || STREQ(Token, "docpath")) {
X if (!(Token = NextToken(fp, ReadMe, LCNOMAP))) {
X fprintf(stderr, "%s: %s: %d: unexpected eof at common file\n",
X progname, ReadMe, RMLine);
X exit(1);
X } else {
X DocPath = emalloc((unsigned) (strlen(Token) + 1));
X (void) strcpy(DocPath, Token);
X DocFromWhere = FW_File;
X }
X } else {
X fprintf(stderr, "%s: \"%s\": %d: token(\"%s\") unexpected\n",
X progname, ReadMe, RMLine, Token);
X exit(1);
X }
X } /* while */
X
Xfinish:
X (void) fclose(fp);
X return;
X}
X
Xstatic char *
XNextToken(fd, Name, Map)
X FILE *fd;
X char *Name;
X int Map;
X{
X int ch;
X static char buf[50];
X register char *q = buf;
X int InQuote = 0;
X int OriginalMap = Map;
X
X while ((ch = NextChar(fd, Name, Map)) != EOF) {
X switch (ch) {
X case '"': case '\'':
X if (q == buf && !InQuote) InQuote = ch;
X else if (ch == InQuote) {
X *q = '\0';
X if (AsciiTrace > 10) {
X fprintf(stderr, "RM[%s] ", buf);
X }
X return buf;
X }
X Map = 0; /* no case conversion inside strings */
X break;
X case '\\':
X if ((ch = NextChar(fd, Name, Map)) == EOF) {
X fprintf(stderr, "%s: %s; %d: EOF after \\ unexpected!\n",
X progname, Name, RMLine);
X exit(1);
X }
X *q++ = ch;
X break;
X case ' ':
X case '\n':
X if (InQuote) {
X fprintf(stderr, "%s: %s: %d: missing quote -->%s<--\n",
X progname, Name, RMLine, InQuote);
X exit(1);
X }
X *q = '\0';
X if (q > buf) return buf;
X else return NextToken(fd, Name, OriginalMap);
X /*NOTREACHED*/
X break;
X default:
X *q++ = ch;
X }
X }
X if (q > buf) {
X fprintf(stderr, "%s: %s: %d: unexpected end of file\n",
X progname, Name, RMLine);
X exit(1);
X }
X return (char *) 0;
X}
X
Xstatic int
XNextChar(fd, Name, Map)
X FILE *fd;
X char *Name;
X int Map;
X{
X int ch;
X
X while ((ch = getc(fd)) != EOF) {
X switch (ch) {
X case '#':
X do {
X if ((ch = getc(fd)) == EOF) {
X fprintf(stderr, "%s: %s: %d: unexpected end of file\n",
X progname, Name, RMLine);
X exit(1);
X }
X } while (ch != '\n');
X /* ASSERT: ch == '\n' */
X ++RMLine;
X break;
X case '\n':
X ++RMLine;
X if (!Map) return ch;
X /* else FALL THROUGH */
X case ' ': case '\t': case '\f': case '\r':
X if (!Map) {
X return ' ';
X }
X
X default:
X return (Map && isupper(ch)) ? tolower(ch) : ch;
X }
X } /* while */
X return EOF;
X}
X
Xint
Xcknatstr(str)
X char *str;
X{
X /* check that a string represents a positive or 0 number */
X register char *p = str;
X
X /* skip leading white space */
X while (isspace(*p)) p++;
X if (!*p) return 0;
X
X /* allow a leading sign */
X if (*p == '-' || *p == '+') p++;
X if (!*p) return 0;
X
X /* now skip digits... */
X while (isdigit(*p)) p++;
X
X return (p > str && *p == '\0');
X}
X
X/* you can tell I am tired by the extra end-while etc. comments.
X * wonder if it will work?
X * perhaps if I took my socks off too.
X *
X * Hmm, yeah, that worked.
X */
@@@End of lq-text/src/liblqtext/Defaults.c
echo x - lq-text/src/liblqtext/DocPath.c 1>&2
sed 's/^X//' >lq-text/src/liblqtext/DocPath.c <<'@@@End of lq-text/src/liblqtext/DocPath.c'
X/* DocPath.c -- Copyright 1989 Liam R. Quin. All Rights Reserved.
X * This code is NOT in the public domain.
X * See the file COPYRIGHT for full details.
X *
X * $Id: DocPath.c,v 1.5 90/10/06 00:11:53 lee Rel1-10 $
X *
X *
X * $Log: DocPath.c,v $
X * Revision 1.5 90/10/06 00:11:53 lee
X * Prepared for first beta release.
X *
X * Revision 1.4 90/10/05 23:43:19 lee
X * Put the debugging in isfile() within ASCIITRACE ifdefs.
X *
X * Revision 1.3 90/08/29 21:46:32 lee
X * Alpha release.
X *
X * Revision 1.2 90/08/09 19:16:12 lee
X * *** empty log message ***
X *
X *
X */
X
X#include "globals.h" /* defines and declarations for database filenames */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef BSD
X# include <sys/param.h>
X# define PATH_MAX MAXPATHLEN
X#else /*not BSD*/
X# include <limits.h> /* for PATH_MAX */
X#endif
X#include <stdio.h>
X#include "emalloc.h"
X#include "fileinfo.h"
X
X/** Unix system calls: **/
Xextern int stat();
X/** C Library functions: **/
Xextern int strlen();
Xextern char *strcpy();
X/** Within this file: **/
Xextern int IsDir();
X/** **/
X
X#ifdef ASCIITRACE
Xextern int AsciiTrace;
X#endif
X
Xtypedef struct s_DocPath {
X char *DirName;
X struct s_DocPath *Next;
X} t_DocPath;
X
Xstatic t_DocPath *XDocPath = 0;
X
X#ifndef PATH_MAX
X# define PATH_MAX 2048
X#endif
X
Xchar *
X_FindFile(Name)
X char *Name;
X{
X int IsFile();
X
X t_DocPath *p;
X static char Buffer[PATH_MAX + 3]; /* +1 for "\0" */
X
X if (!XDocPath) {
X#ifdef ASCIITRACE
X if (AsciiTrace > 4) {
X fprintf(stderr, "FindFile(%s) --> %s\n", Name,
X IsFile(Name) ? Name : (char *) 0);
X }
X#endif
X return IsFile(Name) ? Name : (char *) 0;
X }
X
X for (p = XDocPath; p; p = p->Next) {
X (void) sprintf(Buffer, "%s/%s", p->DirName, Name);
X if (IsFile(Buffer)) {
X#ifdef ASCIITRACE
X if (AsciiTrace > 4) {
X fprintf(stderr, "FindFile(%s) --> %s\n", Name, Buffer);
X }
X#endif
X return Buffer;
X }
X }
X
X return (char*) 0;
X}
X
Xint
XMakeDocPath(Path)
X char *Path;
X{
X extern char *getenv();
X
X char *Start, *End;
X t_DocPath **dpp;
X
X if (XDocPath == (t_DocPath *) 0) {
X dpp = &XDocPath;
X *dpp = (t_DocPath *) 0;
X
X /* For each element in DocPath, */
X for (Start = Path; Start && *Start; Start = End) {
X char SaveEnd;
X
X /* find the end of this bit of the path */
X for (End = Start; *End && *End != ':'; End++)
X ;
X
X if (End == Start) break;
X
X SaveEnd = (*End);
X *End = '\0';
X
X /* if not a directory, delete from path */
X if (!IsDir(Start)) {
X *End = SaveEnd;
X continue;
X }
X
X /* add to the linked list */
X *dpp = (t_DocPath *) emalloc(sizeof(t_DocPath));
X (*dpp)->DirName = emalloc(strlen(Start) + 1);
X (void) strcpy((*dpp)->DirName, Start);
X dpp = &(*dpp)->Next;
X (*dpp) = (t_DocPath *) 0;
X if ((*End = SaveEnd) != '\0') {
X End++;
X }
X }
X }
X return 0;
X}
X
Xint
XIsDir(Dir)
X char *Dir;
X{
X struct stat statbuf;
X
X if (!Dir || !*Dir) return 0;
X if (stat(Dir, &statbuf) < 0) return 0;
X if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
X return 0;
X }
X return 1;
X}
X
Xint
XIsFile(Path)
X char *Path;
X{
X struct stat statbuf;
X
X#ifdef ASCIITRACE
X if (AsciiTrace > 20) {
X fprintf(stderr, "IsFile(%s)\n", Path);
X }
X#endif
X if (stat(Path, &statbuf) < 0) return 0;
X if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
X return 0;
X }
X#ifdef ASCIITRACE
X if (AsciiTrace > 20) {
X fprintf(stderr, "\t\tIsFile(%s) returns true.\n", Path);
X }
X#endif
X return 1;
X}
@@@End of lq-text/src/liblqtext/DocPath.c
echo x - lq-text/src/liblqtext/FileList.c 1>&2
sed 's/^X//' >lq-text/src/liblqtext/FileList.c <<'@@@End of lq-text/src/liblqtext/FileList.c'
X/* FileList.c -- Copyright 1989 Liam R. Quin. All Rights Reserved.
X * This code is NOT in the public domain.
X * See the file COPYRIGHT for full details.
X */
X
X/*
X *
X * FileList -- operations on the list of files. This is the Document
X * Directory part of NX-Text.
X *
X * $Id: FileList.c,v 1.8 90/10/13 02:39:05 lee Rel1-10 $
X *
X * $Log: FileList.c,v $
X * Revision 1.8 90/10/13 02:39:05 lee
X * deleted some incorrect code.
X *
X * Revision 1.7 90/10/13 02:21:03 lee
X * NEEDALIGN stuff
X *
X * Revision 1.6 90/10/07 20:37:18 lee
X * changed ifdef sparc to ifdef NEEDALIGN
X *
X * Revision 1.5 90/10/06 00:11:55 lee
X * Prepared for first beta release.
X *
X * Revision 1.4 90/09/29 23:46:14 lee
X * very minor speedup, and changed a free() to efree().
X *
X * Revision 1.3 90/09/20 19:11:05 lee
X * deleted unused locking code.
X * removed a sun4-specific memory leak. Other minor changes.
X *
X * Revision 1.2 90/08/29 21:46:33 lee
X * Alpha release.
X *
X * Revision 1.1 90/08/09 19:16:15 lee
X * Initial revision
X *
X * Revision 2.2 89/10/08 20:29:10 lee
X * Working version of nx-text engine. Addfile and wordinfo work OK.
X *
X * Revision 2.1 89/10/02 01:12:08 lee
X * New index format, with Block/WordInBlock/Flags/BytesSkipped info.
X *
X * Revision 1.2 89/09/16 21:15:54 lee
X * First demonstratable version.
X *
X * Revision 1.1 89/09/07 21:01:36 lee
X * Initial revision
X *
X *
X */
X
X#include "globals.h" /* defines and declarations for database filenames */
X
X#include <stdio.h>
X#include <malloc.h>
X#include <unistd.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <signal.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <string.h>
X
X#include "smalldb.h"
X#include "fileinfo.h"
X#include "emalloc.h"
X
X/** Unix system calls that need to be declared: **/
Xextern int stat();
Xextern int open(), close(), creat();
Xextern void exit();
Xextern int read(), write();
Xextern unsigned alarm();
X/** library functions that need to be declared: */
Xextern int lockf();
Xextern unsigned sleep();
Xextern void perror();
Xextern long atol();
X
X/** other (lqtext) functions **/
Xt_FID GetNextFID();
Xt_FileInfo *GetFileInfo();
X/** **/
X
Xt_FID
XGetMaxFID()
X{
X extern int errno;
X
X int fd;
X struct stat StatBuf;
X char Buffer[20];
X
X /* ensure that the file is there */
X if (stat(FidFile, &StatBuf) == -1) {
X return 0;
X }
X
X if ((fd = open(FidFile, O_RDWR, 0)) < 0) {
X fprintf(stderr, "Warning: Can't open FID file");
X return 0;
X }
X
X /* Read the file */
X if (read(fd, Buffer, (unsigned int) StatBuf.st_size) < 0) {
X fprintf(stderr, "Can't read from \"%s\"\n", FidFile);
X exit(1);
X }
X
X (void) close(fd);
X
X Buffer[StatBuf.st_size] = '\0';
X
X return atol(Buffer);
X}
X
X/*ARGSUSED*/
Xt_FID
XGetNextFID(Size)
X long Size; /* to let it keep short FIDs for huge files, execpt I don't */
X{
X extern int errno;
X extern long atol();
X extern long lseek();
X
X int fd;
X char Buffer[21];
X struct stat StatBuf;
X t_FID Result;
X
X /* ensure that the file is there */
X if (stat(FidFile, &StatBuf) == -1) {
X fprintf(stderr, "Creating FID file \"%s\"\n", FidFile);
X if ((fd = creat(FidFile, 02666)) < 0) {
X fprintf(stderr, "Can't create FID file \"%s\"\n", FidFile);
X exit(1);
X }
X (void) close(fd);
X return GetNextFID(Size);
X
X /*NOTREACHED*/
X }
X
X if ((fd = open(FidFile, O_RDWR, 0)) < 0) {
X fprintf(stderr, "Can't open FID file");
X perror(FidFile);
X exit(1);
X }
X
X errno = 0;
X
X /* Read the file */
X if (read(fd, Buffer, (unsigned int) StatBuf.st_size) < 0) {
X fprintf(stderr, "Can't read from \"%s\"\n", FidFile);
X exit(1);
X }
X
X Buffer[StatBuf.st_size] = '\0';
X
X Result = atol(Buffer);
X
X if (Result == 0L || *Buffer == '-') {
X Result = 1L;
X }
X
X (void) sprintf(Buffer, "%lu\n", Result + 1);
X
X /* Move to the start of the file and write the now value.
X * No need to truncate the file, because it didn't shrink!
X */
X (void) lseek(fd, 0, 0L);
X (void) write(fd, Buffer, (unsigned int) strlen(Buffer));
X (void) close(fd);
X
X return Result;
X}
X
Xtypedef struct {
X t_FID FID;
X time_t DateLastIndexed;
X int FilterType;
X unsigned NameLength;
X char CurrentLocation[1];
X} t_PhysicalIndexEntry;
X
Xt_PhysicalIndexEntry *
XFileInfo2Phys(FileInfo)
X t_FileInfo *FileInfo;
X{
X t_PhysicalIndexEntry *PIE;
X register int NameLength;
X
X if (!FileInfo || !FileInfo->Name) return (t_PhysicalIndexEntry *) 0;
X
X NameLength = strlen(FileInfo->Name);
X
X PIE = (t_PhysicalIndexEntry *) emalloc(
X sizeof(t_PhysicalIndexEntry) + NameLength + 1);
X
X if (!PIE) return (t_PhysicalIndexEntry *) 0;
X
X PIE->FID = FileInfo->FID;
X PIE->DateLastIndexed = FileInfo->Date;
X PIE->FilterType = FileInfo->FilterType;
X PIE->NameLength = NameLength;
X (void) strcpy(PIE->CurrentLocation, FileInfo->Name);
X return PIE;
X}
X
Xt_FileInfo *
XPhys2FileInfo(PIE)
X t_PhysicalIndexEntry *PIE;
X{
X t_FileInfo *FileInfo;
X
X if (!PIE || !PIE->NameLength) return (t_FileInfo *) 0;
X
X FileInfo = (t_FileInfo *) emalloc(sizeof(t_FileInfo));
X FileInfo->FID = PIE->FID;
X FileInfo->Date = PIE->DateLastIndexed;
X FileInfo->FilterType = PIE->FilterType;
X FileInfo->Stream = (FILE *) 0;
X if (PIE->NameLength) {
X#if 0
X char *doc;
X#endif
X
X FileInfo->Name = emalloc(PIE->NameLength + 1);
X (void) strncpy(FileInfo->Name, PIE->CurrentLocation,
X PIE->NameLength);
X FileInfo->Name[PIE->NameLength] = '\0';
X
X#if 0
X /* with this in place, wordinfo spends over 40% of its time
X * in stat!
X */
X if ((doc = FindFile(FileInfo->Name)) != (char *) 0) {
X /* hence, we never retrieve non-existent files */
X FileInfo->Name = erealloc(FileInfo->Name, strlen(doc) + 1);
X (void) strcpy(FileInfo->Name, doc);
X }
X#endif
X } else {
X FileInfo->Name = (char *) 0;
X }
X
X return FileInfo;
X}
X
Xint
XSaveFileInfo(FileInfo)
X t_FileInfo *FileInfo;
X{
X t_PhysicalIndexEntry *PIE;
X datum key, data;
X DBM *db;
X int RetVal;
X char Buffer[20];
X
X if (!FileInfo) return -1;
X
X if ((PIE = FileInfo2Phys(FileInfo)) == (t_PhysicalIndexEntry *) 0) {
X return -1;
X }
X
X if ((db = startdb(FileIndex)) == (DBM *) 0) {
X return -1;
X }
X
X if (FileInfo->Name && *(FileInfo->Name)) {
X /* For the reverse mapping, FileName --> FID ... store an
X * entry of the form ([\377]317, "hello").
X * This scheme simply has to go.
X * I favour a btree, but that may be needlessly complex.
X */
X int KeyLen = strlen(FileInfo->Name);
X key.dptr = emalloc(KeyLen + 2); /* +2: "\375" and \0 */
X /* Note: the N= is so that a file called "123" does not cause
X * confusion with the reverse mapping
X */
X *(key.dptr) = '\375';
X (void) strcpy(&(key.dptr[1]), FileInfo->Name);
X key.dsize = KeyLen + 1;
X /* length of name + length of "\375" -- the nul at the end
X * is not included.
X */
X
X (void) sprintf(Buffer, "%lu", FileInfo->FID);
X data.dptr = Buffer;
X data.dsize = strlen(Buffer);
X (void) dbm_store(db, key, data, DBM_REPLACE);
X (void) efree(key.dptr);
X }
X
X (void) sprintf(Buffer, "F%lu", FileInfo->FID);
X
X key.dptr = Buffer;
X key.dsize = strlen(Buffer);
X
X data.dptr = (char *) PIE;
X data.dsize = sizeof(t_PhysicalIndexEntry) + PIE->NameLength;
X
X RetVal = dbm_store(db, key, data, DBM_REPLACE);
X
X enddb(db);
X
X return RetVal;
X}
X
Xt_FID
XName2FID(Name)
X char *Name;
X{
X DBM *db;
X datum key, result;
X extern long atol();
X
X key.dsize = strlen(Name);
X /* see previous routine for comments about this +2 ugliness */
X key.dptr = emalloc(key.dsize + 2);
X *(key.dptr) = '\375';
X (void) strcpy(&(key.dptr[1]), Name);
X key.dsize += 1; /* for the cookie; we don't include the \0 */
X
X if ((db = startdb(FileIndex)) == (DBM *) 0) {
X fprintf(stderr, "Name2FID can't get FID for %s (database \"%s\"\n", Name, FileIndex);
X (void) efree(key.dptr);
X return -1;
X }
X result = dbm_fetch(db, key);
X enddb(db);
X
X (void) efree(key.dptr);
X
X return (result.dsize == 0) ? (t_FID) 0 : atol(result.dptr);
X}
X
Xt_FileInfo *
XGetFileInfo(FID)
X t_FID FID;
X{
X t_FileInfo *FileInfo;
X datum key, data;
X DBM *db;
X char Buffer[20];
X#ifdef NEEDALIGN
X t_PhysicalIndexEntry *PIE;
X#endif
X
X (void) sprintf(Buffer, "F%lu", FID);
X key.dptr = Buffer;
X key.dsize = strlen(Buffer);
X
X if ((db = startdb(FileIndex)) == (DBM *) 0) {
X return (t_FileInfo *) 0;
X }
X
X data = dbm_fetch(db, key);
X enddb(db);
X
X if (data.dsize == 0) {
X return (t_FileInfo *) 0;
X }
X
X#ifdef NEEDALIGN
X PIE = (t_PhysicalIndexEntry *) emalloc(data.dsize + 1);
X (void) memcpy((char *) PIE, data.dptr, data.dsize);
X FileInfo = Phys2FileInfo(PIE);
X (void) efree((char *) PIE);
X#else
X
X /* Now we have a PIE, so we need a FileInfo... */
X FileInfo = Phys2FileInfo(/*NOSTRICT*/(t_PhysicalIndexEntry *) data.dptr);
X#endif
X
X return FileInfo;
X}
X
Xint
Xstrcontains(ShortString, LongString)
X char *ShortString;
X char *LongString;
X{
X register char *p;
X
X int strprefix();
X
X for (p = LongString; *p; p++) {
X if (*p == *ShortString && strprefix(ShortString, p)) {
X return 1;
X }
X }
X return 0;
X}
X
Xint
Xstrprefix(Prefix, String)
X register char *Prefix;
X register char *String;
X{
X while (*String++ == *Prefix++)
X if (!*Prefix) return 1;
X return 0;
X}
@@@End of lq-text/src/liblqtext/FileList.c
echo x - lq-text/src/liblqtext/FilterType.c 1>&2
sed 's/^X//' >lq-text/src/liblqtext/FilterType.c <<'@@@End of lq-text/src/liblqtext/FilterType.c'
X/* FilterType.c -- Copyright 1989 Liam R. Quin. All Rights Reserved.
X * This code is NOT in the public domain.
X * See the file COPYRIGHT for full details.
X */
X
X/* FilterType -- determine how to deal with a given file.
X * Part of Liam Quin's NX-Text text retrieval package.
X *
X * $Id: FilterType.c,v 1.6 90/10/06 00:11:56 lee Rel1-10 $
X *
X * $Log: FilterType.c,v $
X * Revision 1.6 90/10/06 00:11:56 lee
X * Prepared for first beta release.
X *
X * Revision 1.5 90/09/24 21:20:31 lee
X * changed a free() to an efree() -- the last one!
X *
X * Revision 1.4 90/09/20 20:07:35 lee
X * fixed a tiny memory hole...
X *
X * Revision 1.3 90/08/29 21:46:35 lee
X * Alpha release.
X *
X * Revision 1.2 90/08/09 19:16:18 lee
X * BSD lint and fixes...
X *
X * Revision 2.2 89/10/08 20:44:34 lee
X * Working version of nx-text engine. Addfile and wordinfo work OK.
X *
X *
X */
X
X#include <stdio.h>
X#include <malloc.h>
X#include "emalloc.h"
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <string.h>
X#include <ctype.h>
X
X#include "fileinfo.h"
X#define FILTERDEF /* see filter.h */
X#include "filter.h"
X#include "wordrules.h" /* for min word length -- don't index files shorter */
X
X#define Prefix(pref,str) ((*(pref)==(*str))&&!strncmp(pref,str,strlen(pref)))
X
Xextern int open(), close();
Xextern int read();
Xextern int strcontains();
X
X/* The current filter types are:
X * FTYPE_NEWS 1
X * FTYPE_MAIL 2
X * FTYPE_CDMS 3
X * FTYPE_MOSTLYASCII 4
X * FTYPE_C_SOURCE 5
X */
X
X/* InitFilterTable might one day be called from Defaults.c....
X * At which point, it will read an ascii file that describes the
X * various filters, I suppose.
X *
X * For,now, it does nothing. It is only called once, and should return 0
X * for success or -1 for failure.
X */
Xint
XInitFilterTable()
X{
X return 0;
X}
X
Xint
XGetFilterType(FileInfo, StatBuf)
X t_FileInfo *FileInfo;
X struct stat *StatBuf;
X{
X int Type = MaxFilterType + 1;
X char Buffer[1024];
X int fd = (-1); /* initialised for lint */
X int AmountRead = 0; /* initialised for lint */
X int ch;
X int Length;
X FILE *fp = (FILE *) 0;
X
X /* GetFilterType() is called to determine which input filter (if any)
X * should be used to read a given file.
X * This routine should know about compressed files.
X *
X * It currently knows about mail, news and C files.
X * There are also hooks for CDMS files (a word-processing package).
X *
X * If the file should not be indexed at all (e.g. it's a core dump),
X * we return -1.
X */
X
X if (!FileInfo || !FileInfo->Name || !*(FileInfo->Name)) return (-1);
X
X if (StatBuf->st_size < MinWordLength) return (-1);
X
X Length = strlen(FileInfo->Name);
X
X if (FileInfo->Name[Length - 1] == 'Z' && Length > 2 &&
X FileInfo->Name[Length - 2] == '.') {
X char *Buf = emalloc(Length + 10);
X
X (void) sprintf(Buf, "zcat < \"%s\"", FileInfo->Name);
X
X fp = popen(Buf, "r");
X (void) efree(Buf);
X if (fp == (FILE *) 0) {
X return (-1);
X }
X }
X
X if (fp) {
X if ((AmountRead = fread(fp, Buffer, sizeof(Buffer))) < MinWordLength) {
X (void) pclose(fp);
X fp = (FILE *) 0; /* try again with read() */
X }
X }
X
X if (!fp) {
X if ((fd = open(FileInfo->Name, O_RDONLY, 0)) < 0) {
X return -1;
X }
X if ((AmountRead = read(fd, Buffer, sizeof(Buffer)-1)) < MinWordLength) {
X (void) close(fd);
X return -1;
X }
X }
X if (fp) {
X (void) pclose(fp);
X } else {
X (void) close(fd);
X }
X
X /* Check the magic table for CDMS: */
X if ((unsigned char) Buffer[0] == 128 && Buffer[1] == 'M') {
X if (AmountRead > 35) { /* size of CDMS file header */
X Type = FTYPE_CDMS;
X return (FileInfo->FilterType = Type);
X }
X }
X
X if (AmountRead < 30) {
X register char *p = Buffer;
X
X /* who cares if it's this small? */
X for (; p - Buffer < AmountRead; p++) {
X if (!isascii(*p)) {
X return (-1);
X }
X }
X return 0;
X }
X
X /* Not cdms -- try news/mail;
X * mail files start with From;
X * news starts with From, Path or Relay-Version
X */
X if (isupper(Buffer[0])) {
X Buffer[AmountRead] = '\0';
X AmountRead--;
X if (Prefix("Xref: ", Buffer)) {
X return (FileInfo->FilterType = FTYPE_NEWS);
X } else if (Prefix("Newsgroups: ", Buffer)) {
X return (FileInfo->FilterType = FTYPE_NEWS);
X } else if (Prefix("Relay-Version: ", Buffer)) {
X return (FileInfo->FilterType = FTYPE_NEWS);
X } else if (Prefix("From", Buffer)) {
X if (strcontains("\nPath: ", Buffer)) {
X /* bug: should only check header, not body! */
X return FTYPE_NEWS;
X } else {
X return FTYPE_MAIL;
X }
X } else if (Prefix("Path: ", Buffer)) {
X if (strcontains("\nNewsgroups: ", Buffer)) {
X return FTYPE_NEWS;
X } else {
X return FTYPE_MAIL;
X }
X } else if (Prefix("Return-Path: ", Buffer)) {
X return FTYPE_MAIL; /* MH-style mail */
X }
X }
X
X /* look for C, trying not to get muddled up with shell scripts */
X ch = FileInfo->Name[Length - 1];
X
X if ((ch == 'c' || ch == 'h') && (Length > 2) &&
X FileInfo->Name[Length - 2] == '.') {
X /* We could require one of
X * . a comment
X * . a #[ ^i]*(include|define|ifn?def|if)[ ^i]+
X * . main[ ^i\n]*(
X * . a declaration -- int, char, long, unsigned, static
X * in the first block of the file.
X * Can't be bothered today.
X */
X if (strcontains("#line", Buffer)) {
X return (-1); /* preprocessed already, index the original! */
X /* we ought to say why we are not indexing it! */
X }
X
X /* we are very predisposed to thinking of this as C... */
X if (Prefix("#include", Buffer) ||
X strcontains("/*", Buffer) ||
X strcontains("#define", Buffer) ||
X strcontains("argc", Buffer) ||
X strcontains("()", Buffer) ||
X strcontains("#include", Buffer)) {
X return FTYPE_C_SOURCE;
X }
X }
X
X /* if still not done, choose between Don't Index and Ascii Filter
X * (which simply strips non-ascii characters).
X */
X if (Type >= MaxFilterType) {
X register char *p;
X int AsciiCount = 0;
X int OtherCount = 0;
X
X for (p = Buffer; p - Buffer < AmountRead; p++) {
X if (isascii(*p)) AsciiCount++;
X else OtherCount++;
X if (!*p) {
X /* If it has nulls in it, it isn't a normal file,
X * and we have no idea what to do with it!
X * (if we did know, it would have had a magic number,
X * so we wouldn't have got here)
X */
X Type = (-1);
X break;
X }
X if (Type > 0) {
X if (AsciiCount > OtherCount * 5) {
X Type = (OtherCount) ? FTYPE_MOSTLYASCII : 0;
X } else {
X Type = (-1); /* too much garbage */
X }
X }
X }
X }
X
X if (Type > MaxFilterType) Type = -1; /* don't index */
X return Type;
X}
@@@End of lq-text/src/liblqtext/FilterType.c
echo x - lq-text/src/liblqtext/Makefile 1>&2
sed 's/^X//' >lq-text/src/liblqtext/Makefile <<'@@@End of lq-text/src/liblqtext/Makefile'
X# Makefile for LQ-Text, a full text retrieval package by Liam R. Quin
X#
X# This Makefile belongs in the src/liblqtext directory.
X# Note that most of the actual configuration is done in ../Makefile and
X# in ../h/global.h, and not here. This file is for representing the
X# dependancies between source components and specifying the steps
X# required to build the library $(DESTDIR)/$(TEXTLIB)
X#
X# $Id: Makefile,v 1.3 90/10/06 00:06:22 lee Rel1-10 $
X#
X# $Log: Makefile,v $
X# Revision 1.3 90/10/06 00:06:22 lee
X# deleted mkdep output.
X#
X# Revision 1.2 90/09/29 23:48:33 lee
X# does cmp on the right file now...
X#
X# Revision 1.1 90/08/09 19:17:07 lee
X# Initial revision
X#
X#
X#
X
XPWD=liblqtext
X
XTEXTLIB=liblqtext.a
XLIAMLIB=liblq.a
XDESTDIR=../lib
XRANLIB=ranlib
XTEXTLINTLIB=llib-llqtext.ln
XLIAMLINTLIB=llib-llq.ln
XLINT=lint
XLINTFLAGS=-a -b -c -h -x
X
XEXTRA=-I../h
X
Xall: $(DESTDIR)/$(TEXTLIB) $(DESTDIR)/$(LIAMLIB)
X
Xinstall: all
X
Xlint: $(DESTDIR)/$(TEXTLINTLIB) $(DESTDIR)/$(LIAMLINTLIB)
X -echo The lint libraries are up to date.
X
X$(DESTDIR)/$(TEXTLINTLIB): $(TEXTLINTLIB)
X mv $(TEXTLINTLIB) $(DESTDIR)/$(TEXTLINTLIB)
X
X$(DESTDIR)/$(LIAMLINTLIB): $(LIAMLINTLIB)
X mv $(LIAMLINTLIB) $(DESTDIR)/$(LIAMLINTLIB)
X
XNDBMCFILES=
XNDBMOFILES=
X
X## keep all of the following consistent: ###################################
X
XTEXTOBJS = WordInfo.o DocPath.o Defaults.o FileList.o Phrase.o Root.o \
X numbers.o pblock.o smalldb.o system.o FilterType.o \
X asciitrace.o $(NDBMOFILES)
X
XTEXTSRC = DocPath.c Defaults.c FileList.c Phrase.c Root.c WordInfo.c \
X malloc.c numbers.c pblock.c smalldb.c system.c FilterType.c \
X asciitrace.c $(NDBMCFILES)
X
XLIAMOBJS = malloc.o progname.o cmdname.o
XLIAMSRC = malloc.c progname.c cmdname.c
X
X## end of mutually related stuff ##########################################
X
X$(TEXTLINTLIB): $(TEXTSRC)
X $(LINT) -Clqtext $(LINTFLAGS) $(CFLAGS) $(TEXTSRC)
X
Xsaber_src:
X #cd $(PWD)
X #load $(CFLAGS) $(TEXTSRC) $(LIAMSRC)
X #cd ..
X
Xsaber_obj:
X #cd $(PWD)
X #load $(CFLAGS) $(TEXTOBJS) $(LIAMOBJS)
X #cd ..
X
X$(LIAMLINTLIB): $(LIAMSRC)
X $(LINT) -Clq $(LINTFLAGS) $(CFLAGS) $(LIAMSRC)
X
X$(DESTDIR)/$(TEXTLIB): $(TEXTLIB)
X -test -d $(DESTDIR) || mkdir $(DESTDIR)
X -test -f $(DESTDIR)/$(TEXTLIB) || cp /dev/null $(DESTDIR)/$(TEXTLIB)
X -( cmp $(TEXTLIB) $(DESTDIR)/$(TEXTLIB) || cp $(TEXTLIB) $(DESTDIR) )
X -/bin/rm -f $(TEXTLIB)
X
X$(DESTDIR)/$(LIAMLIB): $(LIAMLIB)
X -test -d $(DESTDIR) || mkdir $(DESTDIR)
X -test -f $(DESTDIR)/$(LIAMLIB) || cp /dev/null $(DESTDIR)/$(LIAMLIB)
X -( cmp $(LIAMLIB) $(DESTDIR)/$(LIAMLIB) || cp $(LIAMLIB) $(DESTDIR) )
X -/bin/rm -f $(LIAMLIB)
X
X$(TEXTLIB): $(TEXTOBJS)
X rm -f $(TEXTLIB)
X ar rv $(TEXTLIB) $(TEXTOBJS)
X $(RANLIB) $(TEXTLIB)
X
X$(LIAMLIB): $(LIAMOBJS)
X rm -f $(LIAMLIB)
X ar rv $(LIAMLIB) $(LIAMOBJS)
X $(RANLIB) $(LIAMLIB)
X
Xtidy:
X /bin/rm -f *.o core
X
Xclean: tidy
X /bin/rm -f $(TARGETS) $(TEST)
X
Xdepend:
X mkdep $(CFLAGS) *.c
X
X# DO NOT DELETE THIS LINE -- mkdep uses it.
X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
X
X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
@@@End of lq-text/src/liblqtext/Makefile
echo end of part 03
--
Liam R. E. Quin, lee at sq.com, SoftQuad Inc., Toronto, +1 (416) 963-8337
More information about the Alt.sources
mailing list