source: trunk/gsdl/src/mgpp/text/grbIndex.cpp@ 711

Last change on this file since 711 was 711, checked in by cs025, 25 years ago

Changes to eradicate Xmalloc

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 36.2 KB
Line 
1/**************************************************************************
2 *
3 * mgquery.c -- The M G Q U E R Y program
4 * Copyright (C) 1994 Neil Sharman
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id: grbIndex.cpp 711 1999-10-17 23:43:31Z cs025 $
21 *
22 **************************************************************************/
23
24/*
25 $Log$
26 Revision 1.4 1999/10/17 23:43:24 cs025
27 Changes to eradicate Xmalloc
28
29 Revision 1.3 1999/10/12 04:13:11 cs025
30 Changes made to eradicate use of GetEnv elsewhere.
31
32 Revision 1.2 1999/10/11 22:01:40 cs025
33 Got rid of regular expression calls.
34
35 Revision 1.1 1999/10/11 02:57:15 cs025
36 Base install of MG-PP
37
38 Revision 1.1 1999/08/10 21:18:18 sjboddie
39 renamed mg-1.3d directory mg
40
41 Revision 1.3 1999/01/08 00:33:46 rjmcnab
42
43 Enabled mg and the library software to read in more than one index
44 at a time.
45
46 Revision 1.2 1998/11/25 07:55:49 rjmcnab
47
48 Modified mg to that you can specify the stemmer you want
49 to use via a command line option. You specify it to
50 mg_passes during the build process. The number of the
51 stemmer that you used is stored within the inverted
52 dictionary header and the stemmed dictionary header so
53 the correct stemmer is used in later stages of building
54 and querying.
55
56 Revision 1.1 1998/11/17 09:35:29 rjmcnab
57 *** empty log message ***
58
59 * Revision 1.3 1994/10/20 03:57:02 tes
60 * I have rewritten the boolean query optimiser and abstracted out the
61 * components of the boolean query.
62 *
63 * Revision 1.2 1994/09/20 04:41:58 tes
64 * For version 1.1
65 *
66 */
67
68static char *RCSID = "$Id: grbIndex.cpp 711 1999-10-17 23:43:31Z cs025 $";
69
70#include "sysfuncs.h"
71
72#if defined(HAVE_SYS_PROCFS_H) && defined(HAVE_PR_BRKSIZE) && \
73 (__STDC__ == 0)
74/* STDC test was included to allow cc -Xc on SunOS 5 to work */
75#define USE_PROCESS_MEM
76#endif
77
78#ifdef USE_PROCESS_MEM
79# include <sys/procfs.h>
80#endif
81
82#ifdef HAVE_GETRUSAGE
83# ifdef HAVE_SYS_TIME_H
84# include <sys/time.h>
85# endif
86# include <sys/resource.h>
87#endif
88
89#ifndef HAVE_GETPAGESIZE
90# include "getpagesize.h"
91#endif
92
93extern "C" {
94#if WITH_REGEX
95# include <regex.h>
96#else
97# include <rx.h>
98#endif
99#include <stdio.h>
100}
101
102#include "non_ansi.h"
103
104#include <stdarg.h>
105#include <signal.h>
106#include <unistd.h>
107
108#include "messages.h"
109#include "timing.h"
110#include "memlib.h"
111#include "local_strings.h" /* [RPAP - Feb 97: Term Frequency] */
112
113#include "filestats.h"
114#include "invf.h"
115#include "text.h"
116#include "mg.h"
117#include "lists.h"
118#include "backend.h"
119#include "DocEntry.h"
120#include "environment.h"
121#include "globals.h"
122#include "read_line.h"
123#include "mg_errors.h"
124#include "commands.h"
125#include "text_get.h"
126#include "term_lists.h"
127#include "query_term_list.h"
128
129FILE *OutFile = NULL, *InFile = NULL;
130int OutPipe = 0, InPipe = 0;
131int Quitting = 0;
132
133/* [RPAP - Feb 97: NZDL Additions] */
134#if defined(PARADOCNUM) || defined(NZDL)
135int GetDocNumFromParaNum(query_data *qd, int paranum) {
136 int Documents = qd->td->cth.num_of_docs;
137 int *Paragraph = qd->paragraph;
138 int low = 1, high = Documents;
139 int mid = (low+high)/2;
140
141 while ((mid = (low+high)/2) >=1 && mid <= Documents)
142 {
143 if (paranum > Paragraph[mid])
144 low = mid+1;
145 else if (paranum <= Paragraph[mid-1])
146 high = mid-1;
147 else
148 return mid;
149 }
150 FatalError(1, "Bad paragraph number.\n");
151}
152#endif
153
154#ifdef TREC_MODE
155char *trec_ids = NULL;
156long *trec_paras = NULL;
157#endif
158
159static volatile int PagerRunning = 0;
160static volatile int Ctrl_C = 0;
161
162
163/*****************************************************************************/
164
165typedef enum
166 {
167 S_Time, S_Mem, S_Size, S_File
168 }
169S_Type;
170
171static struct Stat
172 {
173 S_Type typ;
174 char *name;
175 char *text;
176 }
177 *Stats = NULL;
178static int NumStats = 0;
179
180static void
181Clear_Stats (void)
182{
183 if (Stats)
184 {
185 int i;
186 for (i = 0; i < NumStats; i++)
187 {
188 if (Stats[i].name)
189 delete Stats[i].name;
190 if (Stats[i].text)
191 delete Stats[i].text;
192 }
193 Xfree (Stats);
194 Stats = NULL;
195 NumStats = 0;
196 }
197}
198
199static void
200Add_Stats (S_Type typ, char *name, char *fmt,...)
201{
202 char buf[1024];
203 va_list args;
204 va_start (args, fmt);
205 vsprintf (buf, fmt, args);
206 if (Stats)
207 Stats = (struct Stat *) Xrealloc (Stats, (++NumStats) * sizeof (*Stats));
208 else
209 Stats = (struct Stat *) Xmalloc ((++NumStats) * sizeof (*Stats));
210 Stats[NumStats - 1].typ = typ;
211 Stats[NumStats - 1].name = Xstrdup (name);
212 Stats[NumStats - 1].text = Xstrdup (buf);
213}
214
215static void
216Display_Stats (FILE * f)
217{
218 static char *sep = "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
219 "-=-=-=-=-=-=-=-=-=-=-";
220 char *names[] =
221 {"Time: ", "Memory:", "Sizes: ", "Disk: ", " "};
222 int i, last_typ = -1;
223 size_t len = 0;
224 if (NumStats == 0)
225 return;
226 fprintf (f, "%s\n", sep);
227 for (i = 0; i < NumStats; i++)
228 if (strlen (Stats[i].name) > len)
229 len = strlen (Stats[i].name);
230 for (i = 0; i < NumStats; i++)
231 {
232 int typ = 4;
233 if (Stats[i].typ != last_typ)
234 typ = last_typ = Stats[i].typ;
235 fprintf (f, "%s %-*s %s\n", names[typ], (int) len, Stats[i].name, Stats[i].text);
236 }
237 fprintf (f, "%s\n", sep);
238}
239
240/*****************************************************************************/
241
242
243static void
244QueryTimeStats (ProgTime * Start, ProgTime * invf, ProgTime * text)
245{
246 if (!BooleanEnv (GetEnv ("briefstats"), 0))
247 {
248 Add_Stats (S_Time, "invf", ElapsedTime (Start, invf));
249 Add_Stats (S_Time, "text", ElapsedTime (invf, text));
250 }
251 Add_Stats (S_Time, "total", ElapsedTime (Start, text));
252}
253
254static void
255StartUpTimeStats (InitQueryTimes * iqt)
256{
257 if (!BooleanEnv (GetEnv ("briefstats"), 0))
258 {
259 Add_Stats (S_Time, "dict [stem]", ElapsedTime (&iqt->Start,
260 &iqt->StemDict));
261 Add_Stats (S_Time, "weights", ElapsedTime (&iqt->StemDict,
262 &iqt->ApproxWeights));
263 Add_Stats (S_Time, "dict [text]", ElapsedTime (&iqt->ApproxWeights,
264 &iqt->CompDict));
265 Add_Stats (S_Time, "Inverted", ElapsedTime (&iqt->CompDict,
266 &iqt->Invf));
267 Add_Stats (S_Time, "Compressed", ElapsedTime (&iqt->Invf,
268 &iqt->Text));
269 }
270 Add_Stats (S_Time, "total", ElapsedTime (&iqt->Start, &iqt->Text));
271}
272
273
274
275
276#ifdef USE_PROCESS_MEM
277static u_long
278process_mem (void)
279{
280 prstatus_t pr;
281 static int fd = -1;
282 if (fd == -1)
283 {
284 char buf[128];
285 sprintf (buf, "/proc/%ld", (long) getpid ());
286 fd = open (buf, O_RDONLY);
287 }
288 if (fd == -1 || ioctl (fd, PIOCSTATUS, &pr) == -1)
289 return 0;
290 return pr.pr_brksize;
291}
292#endif
293
294
295
296
297static void
298MemStats (query_data * qd)
299{
300 if (!BooleanEnv (GetEnv ("briefstats"), 0))
301 {
302#ifdef HAVE_GETRUSAGE
303 struct rusage rusage;
304 getrusage (RUSAGE_SELF, &rusage);
305
306 Add_Stats (S_Mem, "process mem", "%7.3f Mb",
307 (double) (rusage.ru_maxrss * getpagesize () / 1024.0 / 1024.0));
308#endif
309#ifdef USE_PROCESS_MEM
310 Add_Stats (S_Mem, "process mem", "%7.3f Mb",
311 (double) (process_mem () / 1024.0 / 1024.0));
312#endif
313 Add_Stats (S_Mem, "dict [stem]", "%7.1f kB",
314 (double) qd->sd->MemForStemDict / 1024);
315 Add_Stats (S_Mem, "dict [text]", "%7.1f kB",
316 (double) qd->cd->MemForCompDict / 1024);
317 if (qd->awd)
318 Add_Stats (S_Mem, "weights", "%7.1f kB",
319 (double) qd->awd->MemForWeights / 1024);
320 }
321 if (qd->awd)
322 Add_Stats (S_Mem, "total [peak]", "%7.1f kB",
323 (double) (qd->max_mem_in_use + qd->sd->MemForStemDict +
324 qd->cd->MemForCompDict + qd->awd->MemForWeights) / 1024);
325 else
326 Add_Stats (S_Mem, "total [peak]", "%7.1f kB",
327 (double) (qd->max_mem_in_use + qd->sd->MemForStemDict +
328 qd->cd->MemForCompDict) / 1024);
329
330}
331
332
333
334static void
335SizeStats (query_data * qd)
336{
337 Add_Stats (S_Size, "skips", "%7d", qd->hops_taken);
338 Add_Stats (S_Size, "pointers", "%7d", qd->num_of_ptrs);
339 Add_Stats (S_Size, "accumulators", "%7d", qd->num_of_accum);
340 Add_Stats (S_Size, "terms", "%7d", qd->num_of_terms);
341 Add_Stats (S_Size, "answers", "%7d", qd->num_of_ans);
342 Add_Stats (S_Size, "index lookups", "%7d", qd->text_idx_lookups);
343}
344
345static void
346TotalSizeStats (query_data * qd)
347{
348 Add_Stats (S_Size, "skips", "%7d", qd->tot_hops_taken);
349 Add_Stats (S_Size, "pointers", "%7d", qd->tot_num_of_ptrs);
350 Add_Stats (S_Size, "accumulators", "%7d", qd->tot_num_of_accum);
351 Add_Stats (S_Size, "terms", "%7d", qd->tot_num_of_terms);
352 Add_Stats (S_Size, "answers", "%7d", qd->tot_num_of_ans);
353 Add_Stats (S_Size, "index lookups", "%7d", qd->tot_text_idx_lookups);
354}
355
356
357static void
358StatFile (File * F)
359{
360 static unsigned long NumBytes = 0, NumSeeks = 0, NumReads = 0;
361 if (F)
362 if ((int) F != -1)
363 {
364 if (!BooleanEnv (GetEnv ("briefstats"), 0))
365 Add_Stats (S_File, F->name, "%7.1f kB (%3d seeks, %7d reads)",
366 (double) F->Current.NumBytes / 1024, F->Current.NumSeeks,
367 F->Current.NumReads);
368 NumBytes += F->Current.NumBytes;
369 NumSeeks += F->Current.NumSeeks;
370 NumReads += F->Current.NumReads;
371 }
372 else
373 {
374 Add_Stats (S_File, "total", "%7.1f kB (%3d seeks, %7d reads)",
375 (double) NumBytes / 1024, NumSeeks, NumReads);
376 NumSeeks = NumReads = NumBytes = 0;
377 }
378
379}
380
381
382static void
383File_Stats (query_data * qd)
384{
385 StatFile (qd->File_comp_dict);
386 StatFile (qd->File_fast_comp_dict);
387 StatFile (qd->File_text_idx_wgt);
388 StatFile (qd->File_text);
389 StatFile (qd->File_stem);
390
391 /* [RPAP - Jan 97: Stem Index Change] */
392 if (qd->sd->sdh.indexed)
393 {
394 StatFile (qd->File_stem1);
395 StatFile (qd->File_stem2);
396 StatFile (qd->File_stem3);
397 }
398
399 StatFile (qd->File_invf);
400 StatFile (qd->File_weight_approx);
401 StatFile (qd->File_text_idx);
402 StatFile ((File *) (-1));
403}
404
405
406char *
407get_query (query_data * qd)
408{
409 char *line, *LinePtr;
410 WritePrompt ();
411 do
412 {
413 do
414 {
415 line = GetMultiLine ();
416 if (line == NULL)
417 {
418 if (stdin == InFile)
419 return (NULL); /* EOF */
420 if (InPipe)
421/* [RPAP - Feb 97: WIN32 Port] */
422#ifdef __WIN32__
423 _pclose (InFile);
424#else
425 pclose (InFile);
426#endif
427 else
428 fclose (InFile);
429 InPipe = 0;
430 InFile = stdin;
431 }
432 }
433 while (line == NULL);
434 LinePtr = ProcessCommands (line, qd);
435 if (CommandsErrorStr)
436 fprintf (stderr, "%s\n", CommandsErrorStr);
437 }
438 while (*LinePtr == '\0' && !Quitting);
439 return (LinePtr);
440}
441
442
443/* This is executed when a SIGPIPE is detected
444 i.e. If some one quits out of the PAGER, this is executed */
445#ifdef HAVE_SIGCONTEXT
446static RETSIGTYPE
447SIGPIPE_handler (int sig, int code,
448 struct sigcontext *scp, char *addr)
449#else
450static RETSIGTYPE
451SIGPIPE_handler (int sig)
452#endif
453{
454 /* [RPAP - Feb 97: WIN32 Port] */
455#ifdef __WIN32__
456 signal (sig, SIG_IGN);
457#else
458 signal (SIGPIPE, SIG_IGN);
459#endif
460 PagerRunning = 0;
461}
462
463/* This is executed when a SIGINT (i.e. CTRL-C) is detected */
464#ifdef HAVE_SIGCONTEXT
465static RETSIGTYPE
466SIGINT_handler (int sig, int code,
467 struct sigcontext *scp, char *addr)
468#else
469static RETSIGTYPE
470SIGINT_handler (int sig)
471#endif
472{
473 Ctrl_C = 1;
474}
475
476
477
478static char *post_proc = NULL;
479
480
481
482void
483GetPostProc (char *line)
484{
485 char *start, *finish;
486 if (post_proc)
487 {
488 delete post_proc;
489 post_proc = NULL;
490 }
491 start = strchr (line, '\"');
492 finish = strrchr (line, '\"');
493 if (start != finish)
494 {
495 /* found a pattern */
496 *finish = '\0';
497 post_proc = Xstrdup (start + 1);
498 strcpy (start, finish + 1);
499 }
500 else if (start != NULL)
501 {
502 /* found a single speech mark. Delete It. */
503 strcpy (start, start + 1);
504 }
505}
506
507int
508PostProc (char *UDoc, int verbatim)
509{
510 if (!post_proc)
511 return 1;
512
513 return (strstr (UDoc, post_proc) != NULL);
514}
515
516
517
518static DocEntry *
519in_chain (int para, int ip, DocEntry * dc)
520{
521 while (dc)
522 {
523 if (dc->DocNum - ip == para)
524 return dc;
525 dc = dc->Next;
526 }
527 return NULL;
528}
529
530/* num should be greater than or equal to 1 */
531int
532RawDocOutput (query_data * qd, u_long num, FILE * Output)
533{
534 static int last_pos = 0;
535 static u_char *c_buffer = 0;
536 static int buf_len = -1;
537 static u_char *uc_buffer = 0;
538 u_long pos, len;
539 int ULen;
540
541 FetchDocStart (qd, num, &pos, &len);
542
543 if ((int) len > buf_len)
544 {
545 if (c_buffer)
546 {
547 Xfree (c_buffer);
548 Xfree (uc_buffer);
549 }
550 if (!(c_buffer = (u_char *) Xmalloc (len)))
551 return -1;
552 if (!(uc_buffer = (u_char *) Xmalloc ((int) (qd->td->cth.ratio * 1.01 *
553 len) + 100)))
554 return -1;
555 buf_len = len;
556 }
557 if (last_pos != pos)
558 Fseek (qd->td->TextFile, pos, 0);
559 Fread (c_buffer, 1, len, qd->td->TextFile);
560 last_pos = pos + len;
561 DecodeText (qd->cd, c_buffer, len, uc_buffer, &ULen);
562 fwrite (uc_buffer, ULen, sizeof (u_char), Output);
563 return 0;
564}
565
566
567void
568StringOut (FILE * Output, char *string,
569 int intvalid, unsigned long intval,
570 int floatvalid, double floatval)
571{
572 char *s;
573 for (s = string; *s; s++)
574 if (*s == '%' &&
575 (*(s + 1) == 'n' || *(s + 1) == 'w' || *(s + 1) == '%'))
576 {
577 s++;
578 switch (*s)
579 {
580 case 'n':
581 if (intvalid)
582 fprintf (Output, "%lu", intval);
583 else
584 fprintf (Output, "%%n");
585 break;
586 case 'w':
587 if (floatvalid)
588 fprintf (Output, "%f", floatval);
589 else
590 fprintf (Output, "%%w");
591 break;
592 case '%':
593 fputc ('%', Output);
594 }
595 }
596 else
597 fputc (*s, Output);
598}
599
600
601void
602HeaderOut (FILE * Output, u_char * UDoc, unsigned long ULen, int heads_length)
603{
604 int i, space = 1, num = 0;
605 for (i = 0; i < ULen && num < heads_length; i++)
606 {
607 char c = UDoc[i];
608 if (c == '\02')
609 break;
610
611 if (isspace (c) || c == '\01' || c == '\03')
612 {
613 if (!space)
614 {
615 fputc (' ', Output);
616 num++;
617 }
618 space = 1;
619 }
620 else
621 {
622 space = 0;
623 fputc (c, Output);
624 num++;
625 }
626 }
627}
628
629/* [RPAP - Feb 97: NZDL Additions] */
630#if defined(PARADOCNUM) || defined(NZDL)
631void PrintDocNum(FILE *output, char query_type,
632 int docnum, int indexnum, float weight)
633{
634 if (query_type == 'R' || query_type == 'A')
635 fprintf(output, "%7d.%-7d %6.4f\n", docnum, indexnum, weight);
636 else
637 fprintf(output, "%7d.%-7d\n", docnum, indexnum);
638}
639#endif
640
641/* --
642 -- George Buchanan - August 1999
643 --
644
645 ProcessDocs prints out the results of a query to the output
646 stream, respecting the configuration choices for display
647 format etc.
648*/
649static int
650ProcessDocs (query_data * qd, int num, int verbatim,
651 char OutputType, FILE * Output)
652{
653 int max_buf = 0;
654 int DocCount = 0;
655 char *doc_sepstr = NULL;
656 char *para_sepstr = NULL;
657 char *para_start = NULL;
658 int heads_length = atoi (GetDefEnv ("heads_length", "50"));
659 char QueryType = get_query_type ();
660 int need_text = (OutputType == OUTPUT_TEXT || OutputType == OUTPUT_HILITE ||
661 OutputType == OUTPUT_HEADERS || OutputType == OUTPUT_SILENT ||
662 post_proc); /* [RJM June 1997 -- fixing post retrieval scan] */
663
664 if (OutputType == OUTPUT_TEXT || OutputType == OUTPUT_HILITE)
665 {
666 if (QueryType == QUERY_APPROX || QueryType == QUERY_RANKED)
667 {
668 doc_sepstr = de_escape_string (
669 Xstrdup (GetDefEnv ("ranked_doc_sepstr",
670 "---------------------------------- %n %w\\n")));
671 }
672 else
673 {
674 doc_sepstr = de_escape_string (
675 Xstrdup (GetDefEnv ("doc_sepstr",
676 "---------------------------------- %n\\n")));
677 }
678 para_sepstr = de_escape_string (
679 Xstrdup (GetDefEnv ("para_sepstr",
680 "\\n######## PARAGRAPH %n ########\\n")));
681
682 para_start = de_escape_string (
683 Xstrdup (GetDefEnv ("para_start",
684 "***** Weight = %w *****\\n")));
685 }
686
687 if (need_text)
688 {
689 max_buf = atoi (GetDefEnv ("buffer", "1048576"));
690 }
691
692 do
693 {
694 u_char *UDoc = NULL;
695 unsigned long ULen;
696
697 if (need_text)
698 {
699 /* load the compressed text */
700 int _status;
701
702 _status = LoadCompressedText (qd, max_buf);
703 if (_status == -2)
704 { /**
705 * GRB: fallback wihen text requested, but text was not
706 * loaded
707 * 17/09/99
708 */
709 Message("Compressed text not loaded - falling back to Document numbers.");
710 UDoc = NULL;
711 OutputType = OUTPUT_DOCNUMS;
712 need_text = 0;
713 }
714 else if (_status != 0)
715 {
716 Message ("Unable to load compressed text.");
717 FatalError (1, "This is probably due to lack of memory.");
718 }
719 else
720 {
721 /* uncompress the loaded text */
722 UDoc = GetDocText (qd, &ULen);
723 if (UDoc == NULL)
724 {
725 FatalError (1, "UDoc is unexpectedly NULL");
726 }
727 }
728 }
729
730 if (!UDoc || PostProc ((char *) UDoc, verbatim))
731 {
732 switch (OutputType)
733 {
734 case OUTPUT_COUNT:
735 case OUTPUT_SILENT:
736 break;
737 case OUTPUT_DOCNUMS: /* This prints out the docnums string */
738 if (PagerRunning)
739 {
740
741/* [RPAP - Feb 97: NZDL Additions] */
742#if defined(PARADOCNUM) || defined(NZDL)
743 int doc_num = GetDocNum(qd);
744
745 if (qd->paragraph)
746 {
747 if (qd->id->ifh.InvfLevel == 3 &&
748 (QueryType == 'R' || QueryType == 'A'))
749 {
750 /* Print weights for each paragraph in document */
751
752
753 int true_doc_num = GetDocNumFromParaNum(qd, doc_num);
754
755 /* Get number of paragraphs in this document */
756
757 int num_paragraphs =
758 qd->paragraph[true_doc_num]-qd->paragraph[true_doc_num-1];
759
760 int init_para = FetchInitialParagraph(qd->td,
761 doc_num);
762 DocEntry *de, *doc_chain = GetDocChain(qd);
763 int i;
764
765 for (i = 0; i < num_paragraphs; i++)
766 {
767 if ((de = in_chain(i, init_para, doc_chain)))
768 PrintDocNum(Output, QueryType,
769 true_doc_num, init_para+i,
770 de->Weight);
771 }
772 }
773 else
774 PrintDocNum(Output, QueryType,
775 GetDocNumFromParaNum(qd, GetDocNum(qd)),
776 GetDocNum(qd),
777 GetDocWeight(qd));
778 }
779 else
780 {
781 PrintDocNum(Output, QueryType,
782 doc_num, doc_num, GetDocWeight(qd));
783 }
784#else
785 fprintf (Output, "%8d %6.4f %7lu\n", GetDocNum (qd),
786 GetDocWeight (qd), GetDocCompLength (qd));
787#endif
788 }
789 break;
790 case OUTPUT_HEADERS: /* This prints out the headers of the documents */
791 if (PagerRunning)
792 fprintf (Output, "%d ", GetDocNum (qd));
793 HeaderOut (Output, UDoc, ULen, heads_length);
794 if (PagerRunning)
795 fputc ('\n', Output);
796 break;
797#if TREC_MODE
798 case OUTPUT_EXTRAS: /* This prints out the docnums string */
799 if (PagerRunning && trec_ids)
800 {
801 long DN, PN = GetDocNum (qd) - 1;
802 if (trec_paras)
803 DN = trec_paras[PN];
804 else
805 DN = PN;
806 fprintf (Output, "%-14.14s %8ld %10.5f\n",
807 &trec_ids[DN * 14], PN + 1, GetDocWeight (qd));
808 }
809 break;
810#endif
811 case OUTPUT_TEXT:
812 case OUTPUT_HILITE:
813 {
814 int j, para = -1, curr_para = 0;
815 int init_para = -1;
816 DocEntry *de, *doc_chain = NULL;
817 register char ch = ' ';
818 register char lch = '\n';
819
820/* [RPAP - Feb 97: NZDL Additions] */
821#if defined(PARADOCNUM) || defined(NZDL)
822 if (qd->id->ifh.InvfLevel == 3)
823 {
824 init_para = FetchInitialParagraph(qd->td, GetDocNum(qd));
825
826 StringOut(Output, para_sepstr,
827 1, init_para+curr_para,
828 0, 0);
829
830 }
831 else
832 StringOut(Output, doc_sepstr,
833 1, GetDocNum(qd),
834 QueryType == 'A' || QueryType == 'R',
835 GetDocWeight(qd));
836
837#else
838 int p_on = 0;
839
840 if (PagerRunning)
841 {
842 StringOut (Output, doc_sepstr,
843 1, GetDocNum (qd),
844 QueryType == 'A' || QueryType == 'R',
845 GetDocWeight (qd));
846 }
847 if (qd->id->ifh.InvfLevel == 3)
848 {
849 init_para = FetchInitialParagraph (qd->td, GetDocNum (qd));
850 doc_chain = GetDocChain (qd);
851 para = GetDocNum (qd) - init_para;
852
853 StringOut (Output, para_sepstr,
854 1, curr_para + 1,
855 0, 0);
856
857 if ((de = in_chain (0, init_para, doc_chain)))
858 StringOut (Output, para_start,
859 0, 0,
860 1, de->Weight);
861
862 if (doc_chain->DocNum - init_para == 0)
863 p_on = 1;
864 }
865#endif
866 for (j = 0; j < ULen; j++)
867 {
868 ch = UDoc[j];
869 switch (ch)
870 {
871 case '\02':
872 break;
873 case '\01':
874 ch = '\n';
875 case '\03':
876/* [RPAP - Feb 97: NZDL Additions] */
877#if defined(PARADOCNUM) || defined(NZDL)
878 /* print paragraph numbers only if this is
879 a level 3 index */
880 if (qd->id->ifh.InvfLevel == 3)
881 {
882 curr_para++;
883 StringOut(Output, para_sepstr,
884 1, init_para+curr_para,
885 0, 0);
886 }
887#else
888 p_on = 0;
889 curr_para++;
890 StringOut (Output, para_sepstr,
891 1, curr_para + 1,
892 0, 0);
893 lch = *(strchr (para_sepstr, '\0') - 1);
894 if ((de = in_chain (curr_para, init_para, doc_chain)))
895 StringOut (Output, para_start,
896 0, 0,
897 1, de->Weight);
898 if (doc_chain &&
899 doc_chain->DocNum - init_para == curr_para)
900 p_on = 1;
901#endif
902 break;
903 default:
904 {
905 if (PagerRunning)
906 {
907 fputc (ch, Output);
908/* [RPAP - Feb 97: NZDL Additions] */
909#if !defined(PARADOCNUM) && !defined(NZDL)
910 if (p_on && isprint (ch))
911 {
912 fputc ('\b', Output);
913 fputc ('_', Output);
914 }
915#endif
916 }
917
918 lch = ch;
919 }
920 }
921 }
922 if (PagerRunning && lch != '\n')
923 fputc ('\n', Output);
924/* [RPAP - Feb 97: NZDL Additions] */
925#if !defined(PARADOCNUM) && !defined(NZDL)
926 p_on = 0;
927#endif
928 }
929 }
930 if (PagerRunning)
931 fflush (Output);
932
933 DocCount++; /* moved within if statement [RJM June 1997 -- fixing post retrieval scan] */
934 }
935 }
936 while (NextDoc (qd) && PagerRunning && (!Ctrl_C));
937
938 if (need_text)
939 {
940 QueryData_FreeTextBuffer (qd);
941 }
942
943 if (OutputType == OUTPUT_TEXT || OutputType == OUTPUT_HILITE)
944 {
945 delete doc_sepstr;
946 delete para_sepstr;
947 delete para_start;
948 }
949
950 return (DocCount);
951}
952
953
954void
955output_terminator (FILE * out)
956{
957 char *terminator = Xstrdup (GetDefEnv ("terminator", ""));
958 de_escape_string (terminator);
959 fputs (terminator, out);
960 delete terminator;
961}
962
963
964
965
966/* MoreDocs () */
967/* Displays all documents in list DocList. */
968/* Documents are fetched, then decompressed and displayed according to the */
969/* format implied in FormString(). */
970
971/* [RPAP - Feb 97: WIN32 Port] */
972#ifdef __WIN32__
973# define HILITE_PAGER "mg_hilite_words.exe"
974#else
975# define HILITE_PAGER "mg_hilite_words"
976#endif
977
978#define MAX_HILITE_PAGER_STR 80 /* for command & its options */
979
980static void
981MoreDocs (query_data * qd, char *Query, char OutputType)
982{
983 static char terms_str[MAXTERMSTRLEN + 1];
984 int DocCount = 0; /* number of actual matches */
985 FILE *Output = NULL;
986 int using_pipe = 0;
987 char *pager = NULL;
988
989 Ctrl_C = 0;
990
991 qd->num_of_ans = qd->DL->size();
992
993 /* [RPAP - Feb 97: WIN32 Port] */
994#ifndef __WIN32__
995 signal (SIGPIPE, SIGPIPE_handler);
996#endif
997 signal (SIGINT, SIGINT_handler);
998
999 PagerRunning = 1;
1000 if (isatty (fileno (OutFile)) && GetEnv ("pager") &&
1001 OutputType != OUTPUT_HILITE &&
1002 OutputType != OUTPUT_SILENT && OutputType != OUTPUT_COUNT)
1003 {
1004 pager = GetEnv ("pager");
1005 }
1006 else if (isatty (fileno (OutFile)) && OutputType == OUTPUT_HILITE)
1007 {
1008 /* concat the pager and its word argument strings */
1009 TermList_toString (qd->TL, terms_str);
1010 pager = (char *) Xmalloc (MAX_HILITE_PAGER_STR + strlen (terms_str) + 1);
1011 if (!pager)
1012 {
1013 fprintf (stderr, "Unable to allocate memory for highlighting\n");
1014 return;
1015 }
1016 sprintf (pager, "%s --style=%s --pager=%s --stem_method=%ld --stemmer=%ld %s",
1017 HILITE_PAGER,
1018 GetEnv ("hilite_style"),
1019 GetEnv ("pager"),
1020 qd->sd->sdh.stem_method,
1021 qd->sd->sdh.stemmer_num,
1022 terms_str);
1023
1024 }
1025 else
1026 {
1027 Output = OutFile;
1028 }
1029
1030/* [RPAP - Feb 97: NZDL Additions] */
1031#if defined(OUTPUTSTEMMEDWORDS) || defined(NZDL)
1032 if (!isatty(fileno(OutFile)) && get_query_type() != QUERY_DOCNUMS)
1033 {
1034 TermList_toString(qd->TL, terms_str);
1035 fprintf(Output, "%s\n", terms_str);
1036 }
1037#endif
1038 if (pager)
1039 {
1040/* [RPAP - Feb 97: WIN32 Port] */
1041#ifdef __WIN32__
1042 Output = _popen (pager, "w");
1043#else
1044 Output = (FILE *) popen (pager, "w");
1045#endif
1046 using_pipe = (Output != NULL);
1047 if (!using_pipe)
1048 {
1049 fprintf (stderr, "Unable to run \"%s\"\n", pager);
1050 return;
1051 }
1052 }
1053
1054
1055 if (qd->DL->size() > 0)
1056 {
1057 if (OutputType == OUTPUT_COUNT && !post_proc)
1058 DocCount = qd->DL->size();
1059 else {
1060 DocCount = ProcessDocs (qd, qd->DL->size(),
1061 BooleanEnv (GetEnv ("verbatim"), 1),
1062 OutputType, Output);
1063 }
1064 }
1065
1066 if (PagerRunning)
1067 {
1068 output_terminator (Output);
1069 fflush (Output);
1070 }
1071
1072 if (OutputType == OUTPUT_HILITE && pager)
1073 free (pager); /* as needed to malloc to create the pager string */
1074
1075 if (using_pipe)
1076/* [RPAP - Feb 97: WIN32 Port] */
1077#ifdef __WIN32__
1078 _pclose (Output);
1079#else
1080 pclose (Output);
1081#endif
1082
1083 if (qd->DL->size() == 0)
1084 fprintf (stderr, "No entries correspond to that query.\n");
1085 else
1086 {
1087 if (OutputType == OUTPUT_COUNT)
1088 fprintf (stderr, "%d documents match.\n", DocCount);
1089 else
1090 fprintf (stderr, "%d documents retrieved.\n", DocCount);
1091 }
1092
1093 signal (SIGINT, SIG_DFL);
1094}
1095
1096
1097void
1098start_up_stats (query_data * qd, InitQueryTimes iqt)
1099{
1100 Clear_Stats ();
1101 if (BooleanEnv (GetEnv ("timestats"), 0) ||
1102 BooleanEnv (GetEnv ("briefstats"), 0))
1103 StartUpTimeStats (&iqt);
1104
1105 if (BooleanEnv (GetEnv ("diskstats"), 0) ||
1106 BooleanEnv (GetEnv ("briefstats"), 0))
1107 File_Stats (qd);
1108
1109 if (BooleanEnv (GetEnv ("memstats"), 0) ||
1110 BooleanEnv (GetEnv ("briefstats"), 0))
1111 MemStats (qd);
1112
1113}
1114
1115
1116void
1117shut_down_stats (query_data * qd, ProgTime * start,
1118 ProgTime * invf, ProgTime * text)
1119{
1120 Clear_Stats ();
1121 if (BooleanEnv (GetEnv ("timestats"), 0) ||
1122 BooleanEnv (GetEnv ("briefstats"), 0))
1123 QueryTimeStats (start, invf, text);
1124
1125 if (BooleanEnv (GetEnv ("diskstats"), 0) ||
1126 BooleanEnv (GetEnv ("briefstats"), 0))
1127 {
1128 TransFileStats (qd);
1129 File_Stats (qd);
1130 }
1131
1132 if (BooleanEnv (GetEnv ("sizestats"), 0))
1133 TotalSizeStats (qd);
1134}
1135
1136
1137
1138char *wordfreqword2str (u_char * s)
1139{
1140 static char buf[1024];
1141 int i, len = (int) *s++;
1142
1143 for (i = 0; i < len; i++)
1144 {
1145 buf[i] = (char)s[i];
1146 }
1147 buf[len] = '\0';
1148
1149 return buf;
1150}
1151
1152
1153/* [RPAP - Feb 97: Term Frequency] */
1154/*********************************
1155 * PrintQueryTermFreq
1156 *
1157 * Prints the query terms and their respective frequencies within the collection
1158 *********************************/
1159void
1160PrintQueryTermFreqs (QueryTermList *qtl)
1161{
1162 int i;
1163
1164 /* Print the number of terms */
1165 fprintf (OutFile, "%d\n", qtl->num);
1166
1167 /* Print the terms and their respective frequency within the collection */
1168 for (i = 0; i < qtl->num; i++)
1169 if (qtl->QTE[i].stem_method == -1)
1170 /* Using default stem method - don't print stem method beside term */
1171 fprintf (OutFile, "%s %d\n", wordfreqword2str (qtl->QTE[i].Term), qtl->QTE[i].Count);
1172 else
1173 /* Term was forced with a stem, print stem method with term */
1174 fprintf (OutFile, "%s#%d %d\n", wordfreqword2str (qtl->QTE[i].Term), qtl->QTE[i].stem_method, qtl->QTE[i].Count);
1175}
1176
1177
1178void
1179query (void)
1180{
1181 ProgTime TotalStartTime, TotalInvfTime, TotalTextTime;
1182 InitQueryTimes iqt;
1183 query_data *qd;
1184
1185 TotalStartTime.RealTime = TotalStartTime.CPUTime = 0;
1186 TotalInvfTime.RealTime = TotalInvfTime.CPUTime = 0;
1187 TotalTextTime.RealTime = TotalTextTime.CPUTime = 0;
1188
1189/* [RPAP - Feb 97: WIN32 Port] */
1190#ifdef __WIN32__
1191 qd = InitQuerySystemNT (GetDefEnv ("mgdir", ".\\"),
1192 GetDefEnv ("mgname", ""),
1193 GetDefEnv ("textname", NULL), /* [RJM 06/97: text filename] */
1194 &iqt);
1195#else
1196 qd = InitQuerySystemNT (GetDefEnv ("mgdir", "./"),
1197 GetDefEnv ("mgname", ""),
1198 GetDefEnv ("textname", NULL), /* [RJM 06/97: text filename] */
1199 &iqt);
1200#endif
1201
1202 if (!qd)
1203 FatalError (1, mg_errorstrs[mg_errno], mg_error_data);
1204
1205 start_up_stats (qd, iqt);
1206
1207 /*
1208 FinishQuerySystem(qd);
1209
1210 return;
1211 */
1212 while (1)
1213 {
1214 ProgTime StartTime, InvfTime, TextTime;
1215 char QueryType;
1216 char OutputType;
1217 char *line;
1218 ResetFileStats (qd);
1219 qd->max_mem_in_use = qd->mem_in_use = 0;
1220
1221 qd->tot_hops_taken += qd->hops_taken;
1222 qd->tot_num_of_ptrs += qd->num_of_ptrs;
1223 qd->tot_num_of_accum += qd->num_of_accum;
1224 qd->tot_num_of_terms += qd->num_of_terms;
1225 qd->tot_num_of_ans += qd->num_of_ans;
1226 qd->tot_text_idx_lookups += qd->text_idx_lookups;
1227 qd->hops_taken = qd->num_of_ptrs = 0;
1228 qd->num_of_accum = qd->num_of_ans = qd->num_of_terms = 0;
1229 qd->text_idx_lookups = 0;
1230
1231 Display_Stats (stderr);
1232 Clear_Stats ();
1233 line = get_query (qd);
1234 if (!line || Quitting)
1235 break;
1236
1237 GetPostProc (line);
1238
1239 GetTime (&StartTime);
1240
1241 QueryData_FreeQueryDocs (qd);
1242
1243 QueryType = get_query_type ();
1244 OutputType = get_output_type ();
1245 /* No point in hiliting words on a docnum query */
1246 if (OutputType == OUTPUT_HILITE && QueryType == QUERY_DOCNUMS)
1247 OutputType = OUTPUT_TEXT;
1248
1249 switch (QueryType)
1250 {
1251 case QUERY_BOOLEAN:
1252 {
1253 char *maxdocs;
1254 BooleanQueryInfo bqi;
1255
1256 maxdocs = GetDefEnv ("maxdocs", "all");
1257 bqi.MaxDocsToRetrieve = strcmp (maxdocs, "all") ? atoi (maxdocs) : -1;
1258
1259 /* [RPAP - Jan 97: Stem Index Change] */
1260 if (qd->sd->sdh.indexed)
1261 bqi.setWordActions(BooleanEnv(GetEnv("casefold"), 0),
1262 BooleanEnv(GetEnv("stem"), 0));
1263 else
1264 bqi.setWordActions(0, qd->sd->sdh.stem_method);
1265
1266 bqi.OptimiseType = atoi (GetEnv ("optimise_type"));
1267
1268 BooleanQuery (qd, line, &bqi);
1269 break;
1270 }
1271 case QUERY_APPROX:
1272 case QUERY_RANKED:
1273 {
1274 char *maxdocs;
1275 char *maxterms;
1276 char *maxaccum;
1277 RankedQueryInfo rqi;
1278 maxdocs = GetDefEnv ("maxdocs", "all");
1279 maxterms = GetDefEnv ("max_terms", "all");
1280 maxaccum = GetDefEnv ("max_accumulators", "all");
1281 rqi.Sort = BooleanEnv (GetEnv ("sorted_terms"), 0);
1282 rqi.QueryFreqs = BooleanEnv (GetEnv ("qfreq"), 1);
1283 rqi.Exact = QueryType == QUERY_RANKED;
1284 rqi.MaxDocsToRetrieve = strcmp (maxdocs, "all") ? atoi (maxdocs) : -1;
1285 rqi.MaxTerms = strcmp (maxterms, "all") ? atoi (maxterms) : -1;
1286 rqi.MaxParasToRetrieve = rqi.MaxDocsToRetrieve;
1287 if (qd->id->ifh.InvfLevel == 3 && GetEnv ("maxparas"))
1288 rqi.MaxParasToRetrieve = atoi (GetEnv ("maxparas"));
1289 rqi.AccumMethod = toupper (*GetDefEnv ("accumulator_method", "A"));
1290 rqi.MaxAccums = strcmp (maxaccum, "all") ? atoi (maxaccum) : -1;
1291 rqi.HashTblSize = IntEnv (GetEnv ("hash_tbl_size"), 1000);
1292 rqi.StopAtMaxAccum = BooleanEnv (GetEnv ("stop_at_max_accum"), 0);
1293 rqi.skip_dump = GetEnv ("skip_dump");
1294 RankedQuery (qd, line, &rqi);
1295 break;
1296 }
1297 case QUERY_DOCNUMS:
1298 {
1299 DocnumsQuery (qd, line);
1300 break;
1301 }
1302 }
1303
1304 GetTime (&InvfTime);
1305
1306 /* [RPAP - Feb 97: Term Frequency] */
1307 if (qd->QTL && BooleanEnv (GetEnv ("term_freq"), 0))
1308 PrintQueryTermFreqs (qd->QTL);
1309
1310 if (qd->DL)
1311 MoreDocs (qd, line, OutputType);
1312
1313 GetTime (&TextTime);
1314
1315 if (BooleanEnv (GetEnv ("timestats"), 0) ||
1316 BooleanEnv (GetEnv ("briefstats"), 0))
1317 QueryTimeStats (&StartTime, &InvfTime, &TextTime);
1318
1319 if (BooleanEnv (GetEnv ("diskstats"), 0) ||
1320 BooleanEnv (GetEnv ("briefstats"), 0))
1321 File_Stats (qd);
1322
1323 if (BooleanEnv (GetEnv ("memstats"), 0) ||
1324 BooleanEnv (GetEnv ("briefstats"), 0))
1325 MemStats (qd);
1326
1327 if (BooleanEnv (GetEnv ("sizestats"), 0))
1328 SizeStats (qd);
1329
1330 TotalInvfTime.RealTime += InvfTime.RealTime - StartTime.RealTime;
1331 TotalInvfTime.CPUTime += InvfTime.CPUTime - StartTime.CPUTime;
1332 TotalTextTime.RealTime += TextTime.RealTime - StartTime.RealTime;
1333 TotalTextTime.CPUTime += TextTime.CPUTime - StartTime.CPUTime;
1334 }
1335
1336 if (isatty (fileno (InFile)) && !Quitting)
1337 fprintf (stderr, "\n");
1338
1339 shut_down_stats (qd, &TotalStartTime, &TotalInvfTime, &TotalTextTime);
1340
1341 Display_Stats (stderr);
1342
1343}
1344
1345
1346void
1347search_for_collection (char *name)
1348{
1349/* [RPAP - Feb 97: WIN32 Port] */
1350#ifdef __WIN32__
1351 char *dir = GetDefEnv ("mgdir", ".\\");
1352#else
1353 char *dir = GetDefEnv ("mgdir", "./");
1354#endif
1355 char buffer[512];
1356 struct stat stat_buf;
1357 if (strrchr (dir, '/') && *(strrchr (dir, '/') + 1) != '\0')
1358 {
1359/* [RPAP - Feb 97: WIN32 Port] */
1360#ifdef __WIN32__
1361 sprintf (buffer, "%s", dir);
1362#else
1363 sprintf (buffer, "%s/", dir);
1364#endif
1365 SetEnv ("mgdir", buffer, NULL);
1366 dir = GetEnv ("mgdir");
1367 }
1368
1369 sprintf (buffer, "%s.text", name);
1370 if (stat (buffer, &stat_buf) != -1)
1371 {
1372 if (S_ISREG(stat_buf.st_mode))
1373 {
1374 /* The name is a regular file */
1375 SetEnv ("mgname", name, NULL);
1376/* [RPAP - Feb 97: WIN32 Port] */
1377#ifdef __WIN32__
1378 SetEnv ("mgdir", ".\\", NULL);
1379#else
1380 SetEnv ("mgdir", "./", NULL);
1381#endif
1382 return;
1383 }
1384 }
1385
1386 sprintf (buffer, "%s%s", dir, name);
1387 if (stat (buffer, &stat_buf) != -1)
1388 {
1389 if (S_ISDIR(stat_buf.st_mode))
1390 {
1391 /* The name is a directory */
1392/* [RPAP - Feb 97: WIN32 Port] */
1393#ifdef __WIN32__
1394 sprintf (buffer, "%s%s", name, name);
1395#else
1396 sprintf (buffer, "%s/%s", name, name);
1397#endif
1398 SetEnv ("mgname", buffer, NULL);
1399 return;
1400 }
1401 }
1402
1403 /* Look in the current directory last */
1404 if (stat (name, &stat_buf) != -1)
1405 {
1406 if (S_ISDIR(stat_buf.st_mode))
1407 {
1408 /* The name is a directory */
1409/* [RPAP - Feb 97: WIN32 Port] */
1410#ifdef __WIN32__
1411 sprintf (buffer, "%s%s", name, name);
1412 SetEnv ("mgdir", ".\\", NULL);
1413#else
1414 sprintf (buffer, "%s/%s", name, name);
1415 SetEnv ("mgdir", "./", NULL);
1416#endif
1417 SetEnv ("mgname", buffer, NULL);
1418 return;
1419 }
1420 }
1421
1422 SetEnv ("mgname", name, NULL);
1423}
1424
1425/* main () */
1426/* Initialises global variables based on command line switches, and opens */
1427/* files. Then calls query () to perform the querying. */
1428int main (int argc, char **argv)
1429{
1430 ProgTime StartTime;
1431 int decomp = 0;
1432 int ch;
1433
1434 msg_prefix = argv[0];
1435 GetTime (&StartTime);
1436
1437 /* Initialise the environment with default values */
1438
1439 InitEnv ();
1440
1441 read_mgrc_file ();
1442
1443 OutFile = stdout;
1444 InFile = stdin;
1445
1446 opterr = 0;
1447 /* [RJM 06/97: text filename] */
1448 while ((ch = getopt (argc, argv, "Df:d:t:h")) != -1) {
1449 switch (ch) {
1450 case 'f':
1451 SetEnv ("mgname", optarg, NULL);
1452 break;
1453 case 'd':
1454 SetEnv ("mgdir", optarg, NULL);
1455 break;
1456 case 't': /* [RJM 06/97: text filename] */
1457 SetEnv ("textname", optarg, NULL);
1458 break;
1459 case 'D':
1460 decomp = 1;
1461 break;
1462 case 'h':
1463 case '?':
1464 fprintf (stderr, "usage: %s [-D] [-f base name of collection] "
1465 "[-t base name of files for text] " /* [RJM 06/97: text filename] */
1466 "[-d data directory] [collection]\n", argv[0]);
1467 exit (1);
1468 }
1469 }
1470
1471 PushEnv ();
1472
1473 if (decomp == 0)
1474 {
1475
1476 Init_ReadLine ();
1477
1478 /* write a first prompt, let the user start thinking */
1479 if (!BooleanEnv (GetEnv ("expert"), 0) && isatty (fileno (InFile)))
1480 {
1481 fprintf (stderr, "\n\n\t FULL TEXT RETRIEVAL QUERY PROGRAM\n");
1482 fprintf (stderr, "%24s%s\n\n", "", *"21 Mar 1994" == '%' ? __DATE__ : "21 Mar 1994");
1483 fprintf (stderr, "\n");
1484 fprintf (stderr, " mgquery version " VERSION ", Copyright (C) 1994 Neil Sharman\n");
1485 fprintf (stderr, " mgquery comes with ABSOLUTELY NO WARRANTY; for details type `.warranty'\n");
1486 fprintf (stderr, " This is free software, and you are welcome to redistribute it\n");
1487 fprintf (stderr, " under certain conditions; type `.conditions' for details.\n");
1488 fprintf (stderr, "\n");
1489 }
1490 }
1491 if (optind < argc)
1492 search_for_collection (argv[optind]);
1493
1494 if (decomp == 0)
1495 {
1496 query ();
1497 }
1498 else
1499 { int i;
1500 InitQueryTimes iqt;
1501 query_data *qd;
1502
1503/* [RPAP - Feb 97: WIN32 Port] */
1504#ifdef __WIN32__
1505 qd = InitQuerySystemNT (GetDefEnv ("mgdir", ".\\"),
1506 GetDefEnv ("mgname", ""),
1507 GetDefEnv ("textname", NULL), /* [RJM 06/97: text filename] */
1508 &iqt);
1509#else
1510 qd = InitQuerySystemNT (GetDefEnv ("mgdir", "./"),
1511 GetDefEnv ("mgname", ""),
1512 GetDefEnv ("textname", NULL), /* [RJM 06/97: text filename] */
1513 &iqt);
1514#endif
1515 if (!qd)
1516 FatalError (1, mg_errorstrs[mg_errno], mg_error_data);
1517
1518
1519 start_up_stats (qd, iqt);
1520
1521 Display_Stats (stderr);
1522 for (i = 0; i < qd->td->cth.num_of_docs; i++)
1523 {
1524 RawDocOutput (qd, i + 1, stdout);
1525 putc ('\2', stdout);
1526 }
1527 Message ("%s", ElapsedTime (&StartTime, NULL));
1528
1529 FinishQuerySystem (qd);
1530 }
1531
1532 UninitEnv ();
1533 return 0;
1534}
Note: See TracBrowser for help on using the repository browser.