2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * COMPONENT_NAME: austext
50 * (C) COPYRIGHT International Business Machines Corp. 1993,1996
52 * Licensed Materials - Property of IBM
53 * US Government Users Restricted Rights - Use, duplication or
54 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
56 /************** DTSRHAN.C ***************
57 * $XConsortium: dtsrhan.c /main/9 1996/09/23 21:02:27 cde-ibm $
59 * Modification of handel.c for CDE system.
60 * Converts free form text in accordance with a profile file
61 * into a formal .fzk file.
64 * Revision 2.8 1996/04/10 22:55:27 miker
65 * Removed ref to BETA.
67 * Revision 2.7 1996/04/10 19:48:52 miker
68 * Added support for null dates.
70 * Revision 2.6 1996/03/25 18:53:56 miker
71 * Changed FILENAME_MAX to _POSIX_PATH_MAX.
73 * Revision 2.5 1996/02/01 18:20:02 miker
74 * Changed parser/stemmer calls to new readchar format.
76 * Revision 2.4 1995/11/07 17:51:46 miker
77 * Fixed bug in progress dot processing.
78 * Added rec count to err msgs to facilitate finding bad recs.
80 * Revision 2.3 1995/10/25 18:57:27 miker
81 * Renamed from chandel.c. Added prolog.
84 * Revision 2.2 1995/10/02 20:00:51 miker
85 * Added semantic analysis so original handel.c no longer required.
87 * Revision 2.1 1995/09/22 19:20:45 miker
88 * Freeze DtSearch 0.1, AusText 2.1.8
90 * Revision 1.7 1995/09/19 21:49:22 miker
91 * ifdef DTSEARCH, use DtSrVERSION instead of AUSAPI_VERSION in banner.
93 * Revision 1.6 1995/08/31 22:15:33 miker
94 * Added MMM fields for date processing like handel.c.
95 * Minor changes for DtSearch, mostly msg sets changes..
96 * Executable module renamed dtsrload for DtSearch.
98 * Revision 1.5 1995/06/08 00:32:43 miker
99 * 2.1.5f: Bug fix. Segfault if constant string not enclosed in quotes.
100 * Enable negative field offsets.
111 #define PROGNAME "DTSRHAN"
113 #define RECS_PER_DOT 10L
115 /*-- Numerical codes for storing "undefined items" --*/
119 /*-- Codes for "modes" of text buffering --*/
127 /*-- codes for abstract mode --*/
132 /*-- Exit codes for errors --*/
135 #define SYNTAX_ERROR 4
138 #define BAD_PROFILE 7
141 /*-- Token types --*/
146 /****#define WORDS 4*****/
152 #define TEXTINCLUDE 10
153 #define TEXTEXCLUDE 11
154 #define TFIELDINCLUDE 12
155 #define TFIELDEXCLUDE 13
156 #define DELBLANKLINES 14
157 #define IMAGEINCLUDE 15
158 #define IMAGEEXCLUDE 16
164 /*-- General Defines --*/
168 #define MAX_ALPHABET_SIZE 256
170 /*-- definitions of various data structures --*/
171 struct line_comp { /*-- Individual components for line ids --*/
174 int d[MAX_ALPHABET_SIZE];
176 struct line_comp *next;
179 struct line_id { /*-- list of line ids to be handled --*/
181 struct line_comp *comp;
182 struct line_comp *head;
183 struct line_id *next;
190 struct field_id { /*-- list of field ids to be used --*/
191 struct field_id *next;
193 struct line_id *line;
198 int d[MAX_ALPHABET_SIZE];
209 struct rec { /*-- holds a complete image of a record --*/
211 struct line_id *line;
218 struct date_id *next;
219 struct field_id *field;
225 struct field_id *field;
231 struct finclude *next;
237 struct include *next;
240 /************************************************/
244 /************************************************/
245 char abstracter[100];
246 int abstract = GENERATE;
247 struct key_id *abstract_table = NULL;
248 /***nl_catd dtsearch_catd = (nl_catd) -1;***/
249 int bad_parm = FALSE;
250 int bad_profile = FALSE;
251 int bot_defined = FALSE;
252 struct date_id *date_table = NULL;
253 int date_pos_defined = FALSE;
254 static char *del_string = " +=,\t\n";
255 /****static char *del_string = " +-=,\t\n";**allow neg nums***/
256 int del_blanklines = FALSE;
257 char dicname[10] = {0};
258 char dicpath[_POSIX_PATH_MAX] = {0};
260 int discard_record = FALSE;
261 struct finclude *finclude_tab = NULL;
262 struct field_id *field_table = NULL;
263 struct include *i_i_t = NULL;
264 int imagemode = INCLUDE;
265 int imageflag = INCLUDE;
266 struct include *include_tab = NULL;
268 static FILE *instream = NULL;
269 static long key_count = 0;
270 struct key_id *key_table = NULL;
271 int key_defined = FALSE;
272 int key_pos_defined = FALSE;
275 static char *line_mode = "
\f\ 2\ 6CTHULHU TOCOMA ZYYXY UTOPIA";
276 struct line_id *line_table = NULL;
280 static int null_date_specified = FALSE;
281 struct tm *objdate_tmptr;
283 char outmode[8] = "w";
284 int outmode_specified = FALSE;
286 static FILE *outstream = NULL;
288 static long rec_count = 0L; /* for err msgs */
289 struct rec *record_head = NULL;
291 int screen_width = 79;
292 int shutdown_now = FALSE;
294 int textflag = INCLUDE;
295 int textmode = INCLUDE;
296 int top_defined = FALSE;
297 struct line_id *top_rec;
298 char top_rec_name[80];
299 int uppercase = FALSE;
300 int uninit_line = TRUE;
301 int uninit_field = TRUE;
303 int wordmode = INCLUDE;
306 /****************************************************************
307 VALIDATE_ID - validates an indentifier (first character a
308 letter, then alpha-numeric, etc)
309 ****************************************************************/
310 int validate_id (char *s)
316 if (!isalpha (s[0])) {
319 for (i = 1; i < strlen (s); i++)
320 if (!isalnum (s[i]) && s[i] != '_') {
327 /****************************************************************
328 OPEN_OUTFILE - open outputfile - if the file already exists,
329 and no mode was specified by the user, ask the user what to do.
330 ****************************************************************/
336 if (!outmode_specified)
337 if ((temp = fopen (outfile, "r")) != NULL) {
339 printf ( catgets(dtsearch_catd, MS_chandel, 3,
340 "Output file '%s' already exists.\n") ,
342 printf ( catgets(dtsearch_catd, MS_chandel, 4,
343 "Append, overwrite, or quit? [a,o,q] ") );
344 i = tolower (getchar ());
347 strcpy (outmode, "a");
349 strcpy (outmode, "w");
353 if (!strcmp (outfile, "-"))
356 if ((outstream = fopen (outfile, outmode)) == NULL) {
357 printf ( catgets(dtsearch_catd, MS_chandel, 7,
358 "Unable to open output file '%s'.\n") , outfile);
366 /****************************************************************
367 IS_TIME - returns TRUE if the passed string contains the
368 string "time" in any case (upper/lower) - without destroying the
369 original string, in case it was a field name.
370 ****************************************************************/
371 int is_time (char *orig)
375 /* copy original string to temp buffer, so we can manipulate */
376 s = (char *) malloc (sizeof (char) * strlen (orig) +5);
378 for (i = 0; i < strlen (s); i++)
379 s[i] = tolower (s[i]);
381 if (strcmp (s, "time") == 0)
387 /****************************************************************
388 IS_COUNT - returns TRUE if the passed string contains the
389 string "count" in any case (upper/lower) - without destroying the
390 original string, in case it was a field name.
391 ****************************************************************/
392 int is_count (char *orig)
396 /* copy original string to temp buffer, so we can manipulate */
397 s = (char *) malloc (sizeof(char) * strlen(orig) +5);
399 for (i = 0; i < strlen (s); i++)
400 s[i] = tolower (s[i]);
402 if (strcmp (s, "count") == 0)
408 /****************************************************************
409 MY_STRTOK - my own version of strtok - why? Because I need
410 a little flexibility when parsing out the string component -
411 what if it has quotes embedded?
413 s1 = the line to be parsed (= start at beginning)
414 or NULL (= start where we last left off).
416 s2 = the 'delete' string or array of token separators.
417 Usually it is either the global 'del_string' (" +-=,\t\n")
418 or a string consisting of a single double-quote char.
419 ****************************************************************/
420 char *my_strtok (char *s1, const char *s2)
423 static char stringbuf[100];
424 static char *ssave = "";
427 memset (stringbuf, 0, sizeof(stringbuf));
428 sbegin = (s1) ? s1 : ssave; /* start of string or where we last left off */
430 if (strcmp (s2, "\"") == 0) { /* parsing for a string */
431 if (*sbegin == '\0') {
435 while (*sbegin != '"' && *sbegin != '\0') {/*-- look for first " --*/
438 if (*sbegin == '\0') {
442 sbegin++; /*-- skip past " --*/
444 while (*sbegin != '"') {/*-- until other " --*/
445 if (*sbegin == '\\') /*-- escape sequence --*/
447 if (*sbegin == '\0') { /*-- end of line --*/
451 stringbuf[i++] = (*sbegin);
462 else { /* not parsing for a string */
463 sbegin += strspn (sbegin, s2);
464 if (*sbegin == '\0') {
468 send = strpbrk (sbegin, s2);
474 } /*-- my_strtok --*/
476 /****************************************************************
477 IS_BLANK - determines if a string contains nothing but
479 *****************************************************************/
480 int is_blank (char *s)
483 for (i = 0; i < strlen (s); i++)
490 /***********************************************************************
491 TOKEN - returns a numerical token for the defined identifier types
492 ************************************************************************/
500 /*-- make token all lowercase --*/
501 for (i = 0; i < strlen (s); i++)
502 s[i] = tolower (s[i]);
504 if (!strcmp (s, "line"))
506 if (!strcmp (s, "field"))
508 if (!strcmp (s, "key"))
510 if (!strcmp (s, "date"))
512 if (!strcmp (s, "text"))
514 if (!strcmp (s, "keychar"))
516 if (!strcmp (s, "delimiter"))
518 if (!strcmp (s, "textinclude"))
520 if (!strcmp (s, "textexclude"))
522 if (!strcmp (s, "tfieldinclude"))
523 return TFIELDINCLUDE;
524 if (!strcmp (s, "tfieldexclude"))
525 return TFIELDEXCLUDE;
526 if (!strcmp (s, "delblanklines"))
527 return DELBLANKLINES;
528 if (!strcmp (s, "abstract"))
530 if (!strcmp (s, "user"))
532 if (!strcmp (s, "fields"))
534 if (!strcmp (s, "generate"))
536 if (!strcmp (s, "image"))
538 if (!strcmp (s, "imageinclude"))
540 if (!strcmp (s, "imageexclude"))
542 if (!strcmp (s, "discard"))
544 if (!strcmp (s, "constant"))
546 if (!strcmp (s, "upper"))
551 /***********************************************************************
552 PROCESS_PROFILE - process 'profile' file.
553 ************************************************************************/
554 void process_profile ()
561 struct line_id *line_current;
562 struct field_id *field_current;
563 struct key_id *key_current;
564 struct date_id *date_current;
565 struct key_id *abstract_current;
566 struct finclude *finclude_current;
567 struct include *include_current;
568 struct include *i_i_current;
573 if ((prof = fopen (profile, "r")) == NULL) {
574 printf ( catgets(dtsearch_catd, MS_chandel, 11,
575 "\nError - unable to open profile file '%s'.\n") , profile);
578 /*-- Get next line --*/
580 fgets (prof_line, 200, prof);
584 if (prof_line[0] == '#' || is_blank (prof_line))
586 tok = my_strtok (prof_line, del_string);
588 continue; /* ignore blank line */
589 tok_type = token (tok);
597 if (line_table == NULL) {
598 line_table = (struct line_id *) malloc (
599 sizeof (struct line_id));
600 line_current = line_table;
601 line_table->next = NULL;
602 line_table->comp = (struct line_comp *) malloc (
603 sizeof (struct line_comp));
604 line_table->head = line_table->comp;
605 line_table->comp->next = NULL;
609 line_current->next = (struct line_id *) malloc (
610 sizeof (struct line_id));
611 line_current = line_current->next;
612 line_current->next = NULL;
613 line_current->comp = (struct line_comp *) malloc (
614 sizeof (struct line_comp));
615 line_current->head = line_current->comp;
616 line_current->comp->next = NULL;
618 line_current->image_action = NONE;
619 line_current->word_action = NONE;
620 line_current->text_action = NONE;
621 line_current->line = NULL;
622 line_current->name[0] = 0;
623 /*-- get identifier --*/
624 tok = my_strtok ('\0', del_string);
625 if (validate_id (tok))
626 strcpy (line_current->name, tok);
628 printf ( catgets(dtsearch_catd, MS_chandel, 12,
629 "Error line %d: invalid identifier '%s'.\n") ,
630 line_num, NULLORSTR(tok));
634 /*-- get first value token --*/
635 tok = my_strtok ('\0', del_string);
637 printf ( catgets(dtsearch_catd, MS_chandel, 13,
638 "Error line %d - identifier '%s' missing value(s).\n") ,
639 line_num, line_current->name);
643 if (!strcmp (tok, "*"))
644 line_current->comp->column_number = ANY;
646 line_current->comp->column_number = atoi (tok);
647 if (line_current->comp->column_number == 0) {
648 printf ( catgets(dtsearch_catd, MS_chandel, 14,
649 "Error line %d - zero or bad value for '%s'.\n"
650 " offensive token: %s.\n") ,
651 line_num, line_current->name, tok);
655 /* d d d-- get second token of pair -- */
656 tok = my_strtok ('\0', "\"");
658 if (line_current->comp->column_number == ANY) {
659 printf ( catgets(dtsearch_catd, MS_chandel, 15,
660 "Error line %d - for identifier '%s', column has "
661 "been set to ANY\n but there is no "
662 "identifying signature string.\n") ,
663 line_num, line_current->name);
669 strcpy (line_current->comp->text, line_mode);
675 strcpy (line_current->comp->text, tok);
676 line_current->comp->text_length =
677 strlen (line_current->comp->text);
679 /*-- check for more tokens for LINE type of line --*/
681 tok = my_strtok ('\0', del_string);
684 /*-- build component node --*/
685 line_current->comp->next = (struct line_comp *) malloc (
686 sizeof (struct line_comp));
687 line_current->comp = line_current->comp->next;
688 line_current->comp->next = NULL;
689 /*-- check # and store --*/
690 if (!strcmp (tok, "*"))
691 line_current->comp->column_number = ANY;
693 line_current->comp->column_number = atoi (tok);
694 if (line_current->comp->column_number == 0) {
695 printf ( catgets(dtsearch_catd, MS_chandel, 16,
696 "Error line %d - zero or bad value for "
697 "identifier '%s'\n offensive token: %s.\n") ,
698 line_num, line_current->name, tok);
702 /* - --- get second of pair -- */
703 tok = my_strtok ('\0', "\"");
705 if (line_current->comp->column_number == ANY)
706 printf ( catgets(dtsearch_catd, MS_chandel, 15,
707 "Error line %d - for identifier '%s', column has "
708 "been set to ANY\n but there is no "
709 "identifying signature string.\n") ,
710 line_num, line_current->name);
712 printf ( catgets(dtsearch_catd, MS_chandel, 18,
713 "Error line %d - missing value for "
714 "identifier '%s'\n") ,
715 line_num, line_current->name);
719 strcpy (line_current->comp->text, tok);
720 line_current->comp->text_length =
721 strlen (line_current->comp->text);
722 } /* end for(;;) loop for continuing LINE token pairs */
723 break; /* end case LINE */
727 if (field_table == NULL) {
728 field_table = (struct field_id *)
729 malloc (sizeof (struct field_id));
730 field_current = field_table;
731 field_table->next = NULL;
734 field_current->next = (struct field_id *) malloc (
735 sizeof (struct field_id));
736 field_current = field_current->next;
737 field_current->next = NULL;
739 memset (field_current, 0, sizeof(struct field_id));
740 field_current->word_action = NONE;
741 field_current->image_action = NONE;
742 field_current->text_action = NONE;
743 if (tok_type == CONSTANT)
744 field_current->constant = TRUE;
746 /*-- get identifier --*/
747 tok = my_strtok ('\0', del_string);
748 if (validate_id (tok)) {
749 strcpy (field_current->name, tok);
750 if (strncmp (tok, "MMM", 3) == 0)
751 field_current->is_month = TRUE;
754 printf ( catgets(dtsearch_catd, MS_chandel, 12,
755 "Error line %d: invalid identifier '%s'.\n") ,
756 line_num, NULLORSTR(tok));
760 if (field_current->constant) {
761 /*-- get constant value --*/
762 tok = my_strtok (NULL, "\"");
764 printf ( catgets(dtsearch_catd, MS_chandel, 93,
765 "Error line %d - '%s' string not "
766 "enclosed in double quotes.\n"),
767 line_num, field_current->name);
771 strcpy (field_current->value, tok);
774 else { /* ...must be FIELD */
775 /*-- get line id --*/
776 tok = my_strtok ('\0', del_string);
778 printf ( catgets(dtsearch_catd, MS_chandel, 13,
779 "Error line %d - identifier '%s' missing value(s).\n") ,
780 line_num, line_current->name);
784 strcpy (field_current->line_id, tok);
786 /*-- get "string" --*/
787 tok = my_strtok ('\0', "\"");
789 printf ( catgets(dtsearch_catd, MS_chandel, 93,
790 "Error line %d - '%s' string not "
791 "enclosed in double quotes.\n"),
792 line_num, field_current->name);
796 strcpy (field_current->text, tok);
797 field_current->text_length = strlen (field_current->text);
800 tok = my_strtok ('\0', del_string);
802 printf ( catgets(dtsearch_catd, MS_chandel, 13,
803 "Error line %d - identifier '%s' missing value(s).\n") ,
804 line_num, line_current->name);
808 field_current->offset = atoi (tok);
811 tok = my_strtok ('\0', del_string);
812 /*******if (!tok && field_current->length == ANY) ************/
814 printf ( catgets(dtsearch_catd, MS_chandel, 13,
815 "Error line %d - identifier '%s' missing value(s).\n") ,
816 line_num, line_current->name);
820 if (!strcmp (tok, "eoln"))
821 field_current->defined_length = EOLN;
822 else if (!strcmp (tok, "eow"))
823 field_current->defined_length = EOW;
825 field_current->defined_length = atoi (tok);
830 /*-- get next token - should be name of line --*/
831 if (warnings &&(bot_defined || top_defined))
832 printf ( catgets(dtsearch_catd, MS_chandel, 23,
833 "Warning line %d: Delimiter redefined.\n") ,
835 tok = my_strtok ('\0', del_string);
836 if (validate_id (tok))
837 strcpy (top_rec_name, tok);
839 printf ( catgets(dtsearch_catd, MS_chandel, 12,
840 "Error line %d: invalid identifier '%s'.\n"),
841 line_num, NULLORSTR(tok));
844 tok = my_strtok ('\0', del_string);
847 /* convert tok to lowercase */
848 for (i = 0; i < strlen (tok); i++)
849 tok[i] = tolower (tok[i]);
850 if (!strcmp (tok, "top")) {
853 } else if (!strcmp (tok, "bottom")) {
858 printf ( catgets(dtsearch_catd, MS_chandel, 25,
859 "Error line %d: delimiter not specified as "
860 "'top' or 'bottom'.\n") ,
867 tok = my_strtok ('\0', del_string);
868 if (validate_id (tok)) {
869 if (finclude_tab == NULL) {
870 finclude_tab = (struct finclude *) malloc (
871 sizeof (struct finclude));
872 finclude_current = finclude_tab;
874 finclude_current->next = (struct finclude *) malloc (
875 sizeof (struct finclude));
876 finclude_current = finclude_current->next;
878 finclude_current->next = NULL;
879 strcpy (finclude_current->field_id, tok);
880 finclude_current->value = EXCLUDE;
882 /* if it was a valid token */
884 printf ( catgets(dtsearch_catd, MS_chandel, 26,
885 "Error line %d: invalid token '%s'.\n") ,
886 line_num, NULLORSTR(tok));
892 tok = my_strtok ('\0', del_string);
893 if (validate_id (tok)) {
894 if (finclude_tab == NULL) {
895 finclude_tab = (struct finclude *) malloc (
896 sizeof (struct finclude));
897 finclude_tab->next = NULL;
898 finclude_current = finclude_tab;
902 finclude_current->next = (struct finclude *) malloc (
903 sizeof (struct finclude));
904 finclude_current = finclude_current->next;
905 finclude_current->next = NULL;
907 strcpy (finclude_current->field_id, tok);
908 finclude_current->value = INCLUDE;
910 /* if it was a valid token */
912 printf ( catgets(dtsearch_catd, MS_chandel, 27,
913 "Error line %d: invalid token '%s'.\n") ,
914 line_num, NULLORSTR(tok));
920 tok = my_strtok ('\0', del_string);
921 if (validate_id (tok)) {
922 if (include_tab == NULL) {
923 include_tab = (struct include *) malloc (
924 sizeof (struct include));
925 include_tab->next = NULL;
926 include_current = include_tab;
930 include_current->next = (struct include *) malloc (
931 sizeof (struct include));
932 include_current = include_current->next;
933 include_current->next = NULL;
934 } /* else in valid */
935 strcpy (include_current->line_id, tok);
936 tok = my_strtok ('\0', del_string);
938 include_current->value = EXCLUDE;
940 if (validate_id (tok)) {
941 include_current->value = SET;
942 include_current->next = (struct include *) malloc (
943 sizeof (struct include));
944 include_current = include_current->next;
945 include_current->next = NULL;
946 strcpy (include_current->line_id, tok);
947 include_current->value = DEFAULT;
951 printf ( catgets(dtsearch_catd, MS_chandel, 12,
952 "Error line %d: invalid identifier '%s'.\n") ,
956 } /* else tok wasn't NULL */
960 printf (catgets(dtsearch_catd, MS_chandel, 12,
961 "Error line %d: invalid identifier '%s'.\n") ,
962 line_num, NULLORSTR(tok));
964 } /* else not a valid token */
968 tok = my_strtok ('\0', del_string);
969 if (validate_id (tok)) {
971 i_i_t = (struct include *) malloc (
972 sizeof (struct include));
978 i_i_current->next = (struct include *) malloc (
979 sizeof (struct include));
980 i_i_current = i_i_current->next;
981 i_i_current->next = NULL;
982 } /* else in valid */
983 strcpy (i_i_current->line_id, tok);
984 tok = my_strtok ('\0', del_string);
986 i_i_current->value = EXCLUDE;
988 if (validate_id (tok)) {
989 i_i_current->value = SET;
990 i_i_current->next = (struct include *) malloc (
991 sizeof (struct include));
992 i_i_current = i_i_current->next;
993 i_i_current->next = NULL;
994 strcpy (i_i_current->line_id, tok);
995 i_i_current->value = DEFAULT;
999 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1000 "Error line %d: invalid identifier '%s'.\n") ,
1003 } /* else in else */
1004 } /* else tok wasn't NULL */
1006 /* if validate... */
1008 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1009 "Error line %d: invalid identifier '%s'.\n") ,
1010 line_num, NULLORSTR(tok));
1012 } /* else not a valid token */
1016 tok = my_strtok ('\0', del_string);
1017 if (validate_id (tok)) {
1018 if (i_i_t == NULL) {
1019 i_i_t = (struct include *) malloc (
1020 sizeof (struct include));
1022 i_i_current = i_i_t;
1026 i_i_current->next = (struct include *) malloc (
1027 sizeof (struct include));
1028 i_i_current = i_i_current->next;
1029 i_i_current->next = NULL;
1030 } /* else in valid */
1031 strcpy (i_i_current->line_id, tok);
1032 tok = my_strtok ('\0', del_string);
1034 i_i_current->value = INCLUDE;
1036 if (validate_id (tok)) {
1037 i_i_current->value = CLEAR;
1038 i_i_current->next = (struct include *) malloc (
1039 sizeof (struct include));
1040 i_i_current = i_i_current->next;
1041 i_i_current->next = NULL;
1042 strcpy (i_i_current->line_id, tok);
1043 i_i_current->value = DEFAULT;
1047 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1048 "Error line %d: invalid identifier '%s'.\n") ,
1051 } /* else in else */
1052 } /* else tok wasn't NULL */
1054 /* if validate... */
1056 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1057 "Error line %d: invalid identifier '%s'.\n") ,
1058 line_num, NULLORSTR(tok));
1060 } /* else not a valid token */
1064 tok = my_strtok ('\0', del_string);
1065 if (validate_id (tok)) {
1066 if (include_tab == NULL) {
1067 include_tab = (struct include *) malloc (
1068 sizeof (struct include));
1069 include_tab->next = NULL;
1070 include_current = include_tab;
1074 include_current->next = (struct include *) malloc (
1075 sizeof (struct include));
1076 include_current = include_current->next;
1077 include_current->next = NULL;
1078 } /* else in valid */
1079 strcpy (include_current->line_id, tok);
1080 tok = my_strtok ('\0', del_string);
1082 include_current->value = INCLUDE;
1084 if (validate_id (tok)) {
1085 include_current->value = CLEAR;
1086 include_current->next = (struct include *) malloc (
1087 sizeof (struct include));
1088 include_current = include_current->next;
1089 include_current->next = NULL;
1090 strcpy (include_current->line_id, tok);
1091 include_current->value = DEFAULT;
1095 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1096 "Error line %d: invalid identifier '%s'.\n") ,
1099 } /* else in else */
1100 } /* else tok wasn't NULL */
1102 /* if validate... */
1104 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1105 "Error line %d: invalid identifier '%s'.\n") ,
1106 line_num, NULLORSTR(tok));
1108 } /* else not a valid token */
1112 tok = my_strtok ('\0', del_string);
1115 for (i = 0; i < strlen (tok); i++)
1116 tok[i] = tolower (tok[i]);
1117 if (strcmp (tok, catgets (dtsearch_catd, MS_chandel, 34,"all")) == 0)
1118 imagemode = INCLUDE;
1119 else if (strcmp (tok, catgets (dtsearch_catd, MS_chandel, 35, "none")) == 0)
1120 imagemode = EXCLUDE;
1123 printf ( catgets(dtsearch_catd, MS_chandel, 36,
1124 "Error line %d: image mode must be 'all' or "
1125 "'none' -'%s' not recognized.\n") ,
1129 imageflag = imagemode;
1133 tok = my_strtok ('\0', del_string);
1136 for (i = 0; i < strlen (tok); i++)
1137 tok[i] = tolower (tok[i]);
1138 if (strcmp (tok, "all") == 0)
1140 else if (strcmp (tok, "none") == 0)
1144 printf ( catgets(dtsearch_catd, MS_chandel, 37,
1145 "Error line %d: text mode must be 'all' or "
1146 "'none' - '%s' not recognized.\n") , NULLORSTR(tok));
1149 textflag = textmode;
1153 /*-- get next token - should be character for key type --*/
1154 if (warnings && key_defined)
1155 printf ( catgets(dtsearch_catd, MS_chandel, 38,
1156 "Warning line %d: Key character redefined.\n") ,
1158 tok = my_strtok ('\0', del_string);
1159 if (validate_id (tok))
1162 printf ( catgets(dtsearch_catd, MS_chandel, 39,
1163 "Error line %d: invalid Key Character:'%c'.\n") ,
1164 line_num, (tok)?tok[0]:'?');
1172 if (date_pos_defined) {
1173 printf ( catgets(dtsearch_catd, MS_chandel, 110,
1174 "Warning line %d - date field redefined.\n") ,
1176 null_date_specified = FALSE;
1178 date_table = (struct date_id *) malloc
1179 (sizeof (struct date_id));
1180 date_current = date_table;
1181 date_current->next = NULL;
1182 tok = my_strtok ('\0', del_string);
1183 /* validate_id() just does syntax chk on name string */
1184 if (validate_id (tok))
1185 strcpy (date_current->field_id, tok);
1187 /* Msg #111 used two places */
1188 printf ( catgets(dtsearch_catd, MS_chandel, 111,
1189 "Error line %d - bad identifier '%s' for date.\n") ,
1190 line_num, NULLORSTR(tok));
1195 /* Test for special "null" date value */
1196 if (strcmp (date_current->field_id, "null") == 0) {
1197 date_pos_defined = TRUE;
1198 null_date_specified = TRUE;
1202 tok = my_strtok ('\0', del_string);
1203 while (tok != NULL) {
1204 date_current->next = (struct date_id *) malloc
1205 (sizeof (struct date_id));
1206 date_current = date_current->next;
1207 date_current->next = NULL;
1208 if (validate_id (tok))
1209 strcpy (date_current->field_id, tok);
1211 /* Msg #111 used two places */
1212 printf ( catgets(dtsearch_catd, MS_chandel, 111,
1213 "Error line %d - bad identifier '%s' for date.\n"),
1214 line_num, NULLORSTR(tok));
1218 tok = my_strtok ('\0', del_string);
1220 date_pos_defined = TRUE;
1221 break; /* end case DATEFLD */
1224 /*-- building the key --*/
1225 if (warnings && key_pos_defined)
1226 printf ( catgets(dtsearch_catd, MS_chandel, 40,
1227 "Warning line %d - key field redefined.\n") ,
1229 key_table = (struct key_id *) malloc (sizeof (struct key_id));
1230 key_current = key_table;
1231 key_current->next = NULL;
1232 tok = my_strtok ('\0', del_string);
1233 if (validate_id (tok)) {
1234 if (is_time (tok)) {
1235 strcpy (key_current->field_id, "time");
1236 key_pos_defined = TRUE;
1238 } else if (is_count (tok)) {
1239 strcpy (key_current->field_id, "count");
1240 key_pos_defined = TRUE;
1243 strcpy (key_current->field_id, tok);
1246 printf ( catgets(dtsearch_catd, MS_chandel, 43,
1247 "Error line %d - bad identifier '%s' for key.\n") ,
1248 line_num, NULLORSTR(tok));
1252 tok = my_strtok ('\0', del_string);
1253 while (tok != NULL) {
1254 key_current->next = (struct key_id *) malloc (
1255 sizeof (struct key_id));
1256 key_current = key_current->next;
1257 key_current->next = NULL;
1258 if (validate_id (tok))
1259 strcpy (key_current->field_id, tok);
1261 printf ( catgets(dtsearch_catd, MS_chandel, 43,
1262 "Error line %d - bad identifier '%s' for key.\n") ,
1267 tok = my_strtok ('\0', del_string);
1269 key_pos_defined = TRUE;
1273 tok = my_strtok ('\0', del_string);
1276 for (i = 0; i < strlen (tok); i++)
1277 tok[i] = toupper (tok[i]);
1278 if (!strcmp (tok, "TRUE"))
1280 else if (!strcmp (tok, "FALSE"))
1284 printf ( catgets(dtsearch_catd, MS_chandel, 45,
1285 "Error line %d: unknown option for 'discard': "
1286 "'%s'.\n") , line_num, NULLORSTR(tok));
1292 tok = my_strtok ('\0', del_string);
1294 goto BAD_DELBLANKLINES;
1295 for (i = 0; i < strlen (tok); i++)
1296 tok[i] = toupper (tok[i]);
1297 if (!strcmp (tok, "TRUE"))
1298 del_blanklines = TRUE;
1299 else if (!strcmp (tok, "FALSE"))
1300 del_blanklines = FALSE;
1303 printf ( catgets(dtsearch_catd, MS_chandel, 46,
1304 "Error line %d: unknown option for "
1305 "'delblanklines': '%s'.\n") ,
1306 line_num, NULLORSTR(tok));
1312 tok = my_strtok ('\0', del_string);
1313 abstract = token (tok);
1318 tok = my_strtok ('\0', del_string);
1321 strcpy (abstracter, tok);
1324 tok = my_strtok ('\0', del_string);
1325 while (tok != NULL) {
1326 if (abstract_table == NULL) {
1327 abstract_table = (struct key_id *) malloc
1328 (sizeof (struct key_id));
1329 abstract_current = abstract_table;
1331 abstract_current->next =
1332 (struct key_id *) malloc (
1333 sizeof (struct key_id));
1334 abstract_current = abstract_current->next;
1336 strcpy (abstract_current->field_id, tok);
1337 abstract_current->next = NULL;
1338 tok = my_strtok ('\0', del_string);
1343 printf ( catgets(dtsearch_catd, MS_chandel, 47,
1344 "Error line %d: Unknown option for abstract :'%s'\n"),
1345 line_num, NULLORSTR(tok));
1348 } /* 'abstract' subswitch */
1352 printf ( catgets(dtsearch_catd, MS_chandel, 48,
1353 "Error line %d -unknown identifier type '%s'.\n") ,
1354 line_num, NULLORSTR(tok));
1357 } /* main switch for each line in profile */
1358 } while (TRUE); /* read-a-line do loop */
1359 if (!date_pos_defined)
1360 fprintf (aa_stderr, catgets(dtsearch_catd, MS_chandel, 115,
1361 "%s Default object dates will be '%s'.\n") ,
1362 PROGNAME"1288", now_str);
1366 /*---- Process tables, and check for identifiers referenced ----*/
1367 if (!top_defined && !bot_defined) {
1369 printf ( catgets(dtsearch_catd, MS_chandel, 49,
1370 "Error - delimiter not defined.\n") );
1374 printf ( catgets(dtsearch_catd, MS_chandel, 50,
1375 "Error - key-type character never defined.\n") );
1377 if (!key_pos_defined) {
1379 printf ( catgets(dtsearch_catd, MS_chandel, 51,
1380 "Error - key never defined.\n") );
1386 line_current = line_table;
1387 while (line_current != NULL) {
1388 if (strcmp (line_current->name, top_rec_name) == 0)
1389 top_rec = line_current;
1390 line_current = line_current->next;
1392 if (top_rec_name[0] != 0 && top_rec == NULL) {
1393 printf ( catgets(dtsearch_catd, MS_chandel, 52,
1394 "Error - delimiter defined as '%s' was never found.\n") ,
1397 } else if (strcmp (top_rec->head->text, line_mode) == 0) {
1398 printf ( catgets(dtsearch_catd, MS_chandel, 53,
1399 "Error - delimiter defined as '%s' references a physical "
1400 "line in the record.\n Since the delimiter defines the "
1401 "physical lines\n it cannot be referenced as a physical line.\n"),
1405 field_current = field_table;
1406 while (field_current != NULL) {
1408 line_current = line_table;
1409 while (line_current != NULL) {
1410 if (!strcmp (field_current->line_id, line_current->name)) {
1412 field_current->line = line_current;
1414 line_current = line_current->next;
1416 if (!found && !field_current->constant) {
1417 printf ( catgets(dtsearch_catd, MS_chandel, 54,
1418 "Error - for field '%s', no line identifer matches '%s'.\n") ,
1419 field_current->name, field_current->line_id);
1422 field_current = field_current->next;
1424 finclude_current = finclude_tab;
1425 while (finclude_current != NULL) {
1426 /* find field, and set text_value */
1427 field_current = field_table;
1429 while (field_current != NULL) {
1430 if (!strcmp (field_current->name, finclude_current->field_id)) {
1431 field_current->text_action = finclude_current->value;
1434 field_current = field_current->next;
1437 printf ( catgets(dtsearch_catd, MS_chandel, 55,
1438 "Error - field include/exclude list included\n"
1439 " the field '%s', which was never defined.\n") ,
1440 finclude_current->field_id);
1443 finclude_current = finclude_current->next;
1445 i_i_current = i_i_t;
1446 while (i_i_current != NULL) {
1447 /* find line, and set text_action */
1448 line_current = line_table;
1450 while (line_current != NULL) {
1451 if (!strcmp (line_current->name, i_i_current->line_id)) {
1452 line_current->image_action = i_i_current->value;
1455 line_current = line_current->next;
1458 printf ( catgets(dtsearch_catd, MS_chandel, 56,
1459 "Error - image include/exclude list included\n"
1460 " the line '%s', which was never defined.\n") ,
1461 include_current->line_id);
1464 i_i_current = i_i_current->next;
1466 include_current = include_tab;
1467 while (include_current != NULL) {
1468 /* find line, and set text_action */
1469 line_current = line_table;
1471 while (line_current != NULL) {
1472 if (!strcmp (line_current->name, include_current->line_id)) {
1473 line_current->text_action = include_current->value;
1476 line_current = line_current->next;
1479 printf ( catgets(dtsearch_catd, MS_chandel, 57,
1480 "Error - text include/exclude list included\n"
1481 " the line '%s', which was never defined.\n") ,
1482 include_current->line_id);
1485 include_current = include_current->next;
1488 /* If "null" dates specified, no need to look for other date fields */
1489 if (null_date_specified)
1490 goto END_DATE_TABLE;
1492 /* loop thru date table and link each field id to its structure */
1493 for (date_current = date_table; date_current != NULL;
1494 date_current = date_current->next) {
1497 for (field_current = field_table; field_current != NULL;
1498 field_current = field_current->next) {
1499 if (strcmp (field_current->name, date_current->field_id) == 0) {
1500 date_current->field = field_current;
1506 printf ( catgets(dtsearch_catd, MS_chandel, 116,
1507 "Error - date references undefined field '%s'.\n"),
1508 date_current->field_id);
1514 key_current = key_table;
1515 while (key_current != NULL) {
1516 field_current = field_table;
1518 if (!strcmp ("time", key_current->field_id)) {
1520 key_current->field = NULL;
1521 } else if (!strcmp ("count", key_current->field_id)) {
1523 key_current->field = NULL;
1525 while (field_current != NULL) {
1526 if (!strcmp (field_current->name, key_current->field_id)) {
1528 key_current->field = field_current;
1529 } else if (!strcmp ("time", key_current->field_id)) {
1531 key_current->field = NULL;
1532 } else if (!strcmp ("count", key_current->field_id)) {
1534 key_current->field = NULL;
1536 field_current = field_current->next;
1539 printf ( catgets(dtsearch_catd, MS_chandel, 58,
1540 "Error - key definition references field '%s'\n"
1541 " which was never defined.\n") ,
1542 key_current->field_id);
1545 key_current = key_current->next;
1547 abstract_current = abstract_table;
1548 while (abstract_current != NULL) {
1549 field_current = field_table;
1551 while (field_current != NULL) {
1552 if (!strcmp (field_current->name, abstract_current->field_id)) {
1554 abstract_current->field = field_current;
1556 field_current = field_current->next;
1559 printf ( catgets(dtsearch_catd, MS_chandel, 59,
1560 "Error - abstract definition references field '%s'\n"
1561 " which was never defined.\n") ,
1562 abstract_current->field_id);
1565 abstract_current = abstract_current->next;
1568 } /*--process_profile--*/
1570 /**********************************************************************
1571 CLEANUP - frees memory used by record
1572 ***********************************************************************/
1575 struct line_id *line_current;
1576 struct field_id *field_current;
1579 /*-- Reset line_table --*/
1580 line_current = line_table;
1581 while (line_current != NULL) {
1582 line_current->line = UNDEFINED;
1583 line_current = line_current->next;
1586 /*-- Reset field table --*/
1587 field_current = field_table;
1588 while (field_current != NULL) {
1589 if (field_current->constant == FALSE)
1590 field_current->value[0] = 0;
1591 field_current = field_current->next;
1594 /*-- clean up record, free memory for reuse --*/
1595 record = record_head;
1596 while (record_head != NULL) {
1597 record_head = record->next;
1599 record = record_head;
1603 /**************************************************************************
1604 WRITE_RECORD - writes the final form of the record - key, fzkey, abstract,
1606 **************************************************************************/
1607 void write_record ()
1609 static int dotcount = 0;
1611 struct key_id *abst;
1619 /* Line #1 is fzkey */
1620 fprintf (outstream, " 0,2\n"); /* hardcoded null fzkey */
1622 /* Line #2 is abstract */
1624 if (abstract == FIELDS) {
1625 abst = abstract_table;
1626 while (abst != NULL) {
1627 strcat (value, abst->field->value);
1630 for (i = 0; i < strlen (value); i++)
1631 if (value[i] == '\n')
1634 fprintf (outstream, "ABSTRACT: %s\n", value);
1636 /* Line #3 is unique database key */
1637 if (key_value[strlen (key_value) - 1] == '\n')
1638 key_value[strlen (key_value) - 1] = 0;
1641 fprintf (outstream, "%c%s\n", key_char, key_value);
1643 /* Line #4 is object date in objdate string format.
1644 * Prior to version 2.0.8 this would be the first line of text.
1646 if (null_date_specified)
1647 fputs (NULLDATESTR"\n", outstream);
1649 fprintf (outstream, "%s\n",
1650 objdate2fzkstr (tm2objdate (objdate_tmptr)));
1652 /* Lines #5 and thereafter (text) of .fzk rec */
1653 record = record_head;
1654 while (record != NULL) {
1656 * Strip out any control-l's, as we put our own later,
1657 * and any extras might freak out something that wants
1658 * a control-l as a delimeter.
1660 for (i = 0; i < strlen (record->text); i++)
1661 if (record->text[i] == CNTRL_L)
1662 record->text[i] = ' ';
1664 lvalue = (record->line)? record->line->image_action : 0;
1667 imageflag = INCLUDE;
1670 imageflag = EXCLUDE;
1675 if ((imageflag == INCLUDE && lvalue != EXCLUDE)
1676 || (lvalue == INCLUDE)) {
1677 /* trim to fit in screen */
1678 strcpy (buffer, record->text);
1679 if (strlen (buffer) > screen_width) {
1680 buffer[screen_width] = '\n';
1681 buffer[screen_width + 1] = 0;
1683 fprintf (outstream, "%s", buffer);
1685 record = record->next;
1686 if (lvalue == DEFAULT)
1687 imageflag = imagemode;
1690 /* Test final record write to check for full filesystem */
1691 if (fprintf (outstream, "%c\n", CNTRL_L) <= 0) {
1692 printf ( catgets(dtsearch_catd, MS_chandel, 124,
1693 "%s Unable to write to output file '%s':\n %s\n") ,
1694 PROGNAME"1663", outfile, strerror(errno));
1698 } /* write_record */
1701 /************************************************/
1705 /************************************************/
1706 /* Translates a field value which is a recognizable month
1707 * name string into a two-char digit string from "01" to "12".
1709 static void mmm_to_digits (struct field_id *fld)
1711 static char valbuf[8];
1712 static char *months = NULL;
1716 months = strdup (catgets(dtsearch_catd, MS_chandel, 125,
1717 "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"));
1719 valbuf[i] = toupper (fld->value[i]);
1720 for (i=0; i<12; i++)
1721 if (strncmp (valbuf, months + (i*3), 3) == 0) {
1722 sprintf (fld->value, "%02d", ++i);
1726 } /* mmm_to_digits() */
1729 /************************************************/
1731 /* process_record */
1733 /************************************************/
1734 /* PROCESS_RECORD - does all processing for the record currently stored
1735 * in the data structure pointed to by record_head. If record_head points
1736 * to NULL, it can safely be assumed that no record is currently awaiting
1739 void process_record (void)
1753 char date_value[256];
1756 static int dotcount = 0;
1758 if (record_head == NULL)
1761 /* Print progress dots and messages */
1763 if (rec_count % RECS_PER_DOT == 0L) {
1765 if (++dotcount % 10 == 0)
1767 if (dotcount % 50 == 0) {
1774 discard_record = FALSE;
1775 meaningless = FALSE;
1777 /* Main loop on every line in record */
1778 record = record_head;
1779 while (record != NULL) {
1780 lvalue = (record->line)? record->line->text_action : 0;
1792 field_current = field_table;
1793 while (field_current != NULL) {
1794 if (field_current->line == record->line) {
1795 /* this field is defined within this line */
1796 memset (value, 0, sizeof(value));
1798 /* If profile pattern str was empty ("") ...*/
1799 if (field_current->text[0] == 0) {
1800 if (field_current->defined_length == EOLN)
1801 strncpy (value, record->text +
1802 (field_current->offset - 1), sizeof(value)-1);
1803 else if (field_current->defined_length == EOW)
1804 /* copy until end of word only */
1806 (!isspace ((record->text +
1807 (field_current->offset - 1))[dummy]))
1808 && dummy < sizeof(value);
1811 value[dummy] = (record->text +
1812 (field_current->offset - 1))[dummy];
1814 i = (field_current->defined_length < sizeof(value))?
1815 field_current->defined_length : sizeof(value)-1;
1817 record->text + (field_current->offset - 1),
1822 /* ...else if profile pattern str was not empty ("xxx") */
1824 pos = strstr (record->text, field_current->text);
1825 if (pos != NULL) { /* pattern found... */
1826 if (field_current->defined_length == EOLN)
1828 pos + (field_current->offset - 1),
1830 else if (field_current->defined_length == EOW)
1831 /* copy until end of word only */
1834 (field_current->offset - 1))[dummy]))
1835 && dummy < sizeof(value);
1838 value[dummy] = (pos +
1839 (field_current->offset - 1))[dummy];
1841 i = (field_current->defined_length<sizeof(value))?
1842 field_current->defined_length : sizeof(value)-1;
1844 pos + (field_current->offset - 1),
1847 } /* end pattern found */
1848 } /* end else where pattern str not empty */
1850 /* strip \n's out of value */
1851 for (i = 0; i < strlen (value); i++)
1852 if (value[i] == '\n')
1854 if (field_current->constant == FALSE) {
1855 strncpy (field_current->value, value,
1856 sizeof(field_current->value));
1857 field_current->value [sizeof(field_current->value)-1] = 0;
1858 field_current->length = strlen (field_current->value);
1859 if (field_current->is_month)
1860 mmm_to_digits (field_current);
1863 field_current = field_current->next;
1864 } /* end while loop on each field within each line */
1866 if (lvalue == DEFAULT)
1867 textflag = textmode;
1868 record = record->next;
1869 } /* end while loop on each record line */
1872 /* Build a handel date_value string from specified fields.
1873 * If 'date' was not specified, uses current date/time.
1874 * If 'date = null' was specified, uses special constant string.
1875 * If value error in specified date fields,
1876 * uses current date/time and prints err msg.
1878 objdate_tmptr = &nowtm; /* default */
1879 if (date_pos_defined && !null_date_specified) {
1881 for (date_current = date_table; date_current != NULL;
1882 date_current = date_current->next) {
1883 if (date_current->field->value[0] != 0) {
1884 strcat (date_value, date_current->field->value);
1887 date_value[0] = 0; /* flags error msg */
1893 * Validate format for date_value of this record.
1894 * Date value format: YYYYMMDDhhmm (exactly 12 digits).
1895 * The area at date_value + 100 is just a little atoi buffer.
1897 if (date_value[0] == 0)
1898 goto BAD_DATE_VALUE;
1899 if (strlen (date_value) != 12)
1900 goto BAD_DATE_VALUE;
1901 for (i = 0; i < 12; i++)
1902 if (!isdigit (date_value[i]))
1903 goto BAD_DATE_VALUE;
1906 strncpy (date_value + 100, date_value, 4);
1907 date_value[104] = 0;
1908 i = atoi (date_value + 100);
1909 if (i < 1900 || i > 5995) /* valid OBJDATE years */
1910 goto BAD_DATE_VALUE;
1912 rectm.tm_year = i - 1900;
1915 strncpy (date_value + 100, date_value + 4, 2);
1916 date_value[102] = 0;
1917 i = atoi (date_value + 100);
1918 if (i < 1 || i > 12)
1919 goto BAD_DATE_VALUE;
1921 rectm.tm_mon = i - 1; /* tm values = 0 - 11 */
1924 strncpy (date_value + 100, date_value + 6, 2);
1925 date_value[102] = 0;
1926 i = atoi (date_value + 100);
1927 if (i < 1 || i > 31)
1928 goto BAD_DATE_VALUE;
1933 strncpy (date_value + 100, date_value + 8, 2);
1934 date_value[102] = 0;
1935 i = atoi (date_value + 100);
1936 if (i < 0 || i > 23)
1937 goto BAD_DATE_VALUE;
1942 strncpy (date_value + 100, date_value + 10, 2);
1943 date_value[102] = 0;
1944 i = atoi (date_value + 100);
1945 if (i < 0 || i > 59)
1946 goto BAD_DATE_VALUE;
1950 objdate_tmptr = &rectm;
1951 goto GOOD_DATE_VALUE;
1954 objdate_tmptr = &nowtm;
1955 printf ( catgets(dtsearch_catd, MS_chandel, 133,
1956 "Warning - '%s' is invalid date specification.\n"
1957 " Using '%s' date for record number %ld that began: %.30s\n") ,
1958 date_value, now_str, rec_count, record_head->text);
1961 } /* end if (date_pos_defined) */
1963 key_current = key_table;
1965 for (dummy = 0; dummy < 80; dummy++)
1966 key_value[dummy] = 0;
1968 while (key_current != NULL) {
1969 if (key_current->field == NULL) {
1970 if (strcmp (key_current->field_id, "time") == 0)
1971 sprintf (key_value, "%ld%06ld", now, key_count);
1972 else /* must be 'count' */
1973 sprintf (key_value, "%09ld", key_count);
1974 } else if (key_current->field->value[0] != 0) {
1975 strcat (key_value, key_current->field->value);
1979 key_current = key_current->next;
1981 if (dummy && warnings) {
1982 printf ( catgets(dtsearch_catd, MS_chandel, 68,
1983 "Warning - fields necessary for key not found.\n"
1984 " discarding record #%ld that began:\n %s\n") ,
1985 rec_count, record_head->text);
1986 } else if (discard && meaningless && warnings) {
1987 printf ( catgets(dtsearch_catd, MS_chandel, 69,
1988 "Warning - record #ld deemed meaningless, discarding...\n"
1989 " record began: %.60s\n") ,
1990 rec_count, record_head->text);
1996 } /*--process_record--*/
1999 /**************************************************************************
2000 NEW_REC - determines if the string sent represents a new record or
2002 **************************************************************************/
2003 int new_rec (char *buffer)
2005 int cant_be = FALSE;
2006 top_rec->comp = top_rec->head;
2007 while (top_rec->comp != NULL) {
2008 if (strcmp (top_rec->comp->text, line_mode) != 0) {
2009 if (top_rec->comp->column_number == ANY) {
2010 if (strstr(buffer,top_rec->comp->text)==NULL)
2014 else if (strncmp (buffer + (top_rec->comp->column_number - 1),
2015 top_rec->comp->text,
2016 strlen (top_rec->comp->text)) != 0)
2019 top_rec->comp = top_rec->comp->next;
2021 if (cant_be == FALSE) {
2027 /**************************************************************************
2028 IS_WHITESPACE - returns true if the string passed contains only
2030 **************************************************************************/
2031 int is_whitespace (char *s)
2034 for (i = 0; i < strlen (s); i++)
2035 if (!isspace (s[i]) || s[i] == 12)
2040 /**************************************************************************
2041 PROCESS_INFILE - processes the input file, 1 record at a time. For each
2042 record, the lines must first be compared against the line id's we have, to
2043 try and identify each line. Then fields are processed against these lines,
2044 and finally fzk processing can begin on any lines that are indicated being
2046 ***************************************************************************/
2047 void process_infile ()
2050 struct line_id *line_current;
2054 time_t startime = 0L;
2058 if (!strcmp (infile, "-"))
2061 if ((instream = fopen (infile, "rt")) == NULL) {
2062 printf ( catgets(dtsearch_catd, MS_chandel, 70,
2063 " Unable to open input file '%s'.\n") , infile);
2070 while (fgets (buffer, sizeof (buffer) - 1, instream) != NULL) {
2071 /* clean any non ASCII characters out of buffer */
2072 delete_whitespace (buffer);
2073 if (feof (instream))
2074 continue; /*-* end of file *-*/
2075 if (del_blanklines && is_whitespace (buffer))
2077 if (new_rec (buffer)) {
2079 if (record_head == NULL) {
2080 record_head = (struct rec *) malloc (sizeof (struct rec));
2081 record = record_head;
2083 record->next = (struct rec *) malloc (sizeof (struct rec));
2084 record = record->next;
2086 record->next = NULL;
2088 record->line_num = line_num;
2089 strcpy (record->text, buffer);
2090 record->line = NULL;
2091 /*-- search list of line_id's for a possible match --*/
2092 line_current = line_table;
2093 while (line_current != NULL) {
2095 line_current->comp = line_current->head;
2096 while (line_current->comp != NULL) {
2097 if (strcmp (line_current->comp->text, line_mode) != 0) {
2098 if (line_current->comp->column_number == ANY) {
2099 if (strstr(buffer,line_current->comp->text)
2104 (line_current->comp->column_number - 1),
2105 line_current->comp->text,
2106 strlen (line_current->comp->text)) != 0)
2108 } else if (line_current->comp->column_number
2111 line_current->comp = line_current->comp->next;
2113 if (cant_be == FALSE) {
2114 /* found a hit, set pointers */
2115 line_current->line = record;
2116 record->line = line_current;
2118 line_current = line_current->next;
2119 } /* while - line_current loop */
2120 } /* if bot_defined */
2129 if (record_head == NULL) {
2130 record_head = (struct rec *) malloc (sizeof (struct rec));
2131 record = record_head;
2133 record->next = (struct rec *) malloc (sizeof (struct rec));
2134 record = record->next;
2136 record->next = NULL;
2138 record->line_num = line_num;
2139 strcpy (record->text, buffer);
2140 record->line = NULL;
2141 /*-- search list of line_id's for a possible match --*/
2142 line_current = line_table;
2143 while (line_current != NULL) {
2145 line_current->comp = line_current->head;
2146 while (line_current->comp != NULL) {
2147 if (strcmp (line_current->comp->text, line_mode) != 0) {
2148 if (line_current->comp->column_number == ANY) {
2149 if (strstr(buffer,line_current->comp->text)==NULL){
2152 } else if (strncmp (buffer +
2153 (line_current->comp->column_number - 1),
2154 line_current->comp->text,
2155 strlen (line_current->comp->text)) != 0) {
2158 } else if (line_current->comp->column_number != line_num) {
2161 line_current->comp = line_current->comp->next;
2163 if (cant_be == FALSE) {
2164 /* found a hit, set pointers */
2165 line_current->line = record;
2166 record->line = line_current;
2168 line_current = line_current->next;
2169 } /* while - line_current loop */
2170 for (rc = 0; rc < 200; rc++)
2172 } /* while - buffer read loop */
2173 /*- check for any leftover records -*/
2175 } /*-- process_infile --*/
2178 /************************************************/
2182 /************************************************/
2183 static void usage_msg (void)
2185 static char *default_text =
2186 "\nUSAGE: %s [options] <profile> <infile> [<outfile>]\n"
2187 " -m Turn off all but error messages.\n"
2188 " -wN Change target screen width to <N>.\n"
2189 " -oo Preapprove overwrite of outfile.\n"
2190 " -oa Preapprove append to outfile.\n"
2191 " <profile> Input file containing profile of records\n"
2192 " to be processed.\n"
2193 " <infile> Input file containing actual records.\n"
2194 " <outfile> Output file name, .fzk format (%s).\n\n";
2198 printf (catgets (dtsearch_catd, MS_chandel, 71, default_text),
2199 aa_argv0, EXT_FZKEY);
2204 /************************************************/
2206 /* user_arg_processor */
2208 /************************************************/
2209 /* Process any user arguments passed thru the command line parameters. */
2210 static void user_arg_processor (int argc, char **argv)
2212 char *cptr, *argptr;
2219 while (--argc > 0 && (*++argv)[0] == '-') {
2221 argptr[1] = tolower (argptr[1]);
2222 switch (argptr[1]) {
2225 if ((screen_width = atoi (argptr + 2)) == 0) {
2226 printf ( catgets(dtsearch_catd, MS_chandel, 72,
2227 "Invalid screen width specified.\n") );
2237 argptr[2] = tolower (argptr[2]);
2238 if (argptr[2] == 'o')
2239 strcpy (outmode, "w");
2240 else if (argptr[2] == 'a')
2241 strcpy (outmode, "a");
2243 printf ( catgets(dtsearch_catd, MS_chandel, 75,
2244 "'%s' is invalid output mode.\n") , argptr);
2247 outmode_specified = TRUE;
2251 printf ( catgets(dtsearch_catd, MS_chandel, 76,
2252 "Unknown command line argument '%s'.\n") , argptr);
2258 printf ( catgets(dtsearch_catd, MS_chandel, 77,
2259 "Missing required profile-file name.\n") );
2265 strcpy(profile,argv[0]);
2268 profile = (char *) malloc (sizeof (char) * (strlen (argv[0])) +10);
2269 strcpy (profile, argv[0]);
2270 if (strchr (profile, '.') == NULL)
2271 strcat (profile, EXT_HANDEL);
2275 printf ( catgets(dtsearch_catd, MS_chandel, 78,
2276 "Missing required input-file name.\n") );
2281 /******** strcpy(infile,argv[1]); ********/
2286 strcpy(outfile,infile);
2287 if (strchr(outfile,'.')!=NULL)
2288 strcpy(strchr(outfile,'.'), EXT_FZKEY);
2290 strcat(outfile,EXT_FZKEY);
2292 if (strcmp (infile, "-") == 0) {
2293 printf ( catgets(dtsearch_catd, MS_chandel, 79, "Error - using "
2294 "stdin as input, output filename is required!\n") );
2297 outfile = (char *) malloc (sizeof (char) * (strlen (infile) + 10));
2298 strcpy (outfile, infile);
2299 pos = strrchr (outfile, (int) '.');
2301 strcat (outfile, EXT_FZKEY);
2316 /* strcpy(outfile,argv[2]); */
2319 /*-- Sanity checks --*/
2320 /*-- duplicates? --*/
2321 if (strcmp (infile, profile) == 0) {
2322 printf ( catgets(dtsearch_catd, MS_chandel, 80,
2323 "Profile file and input file have same name:'%s'.\n") ,
2327 if (strcmp (infile, outfile) == 0 && strcmp (infile, "-")) {
2328 printf ( catgets(dtsearch_catd, MS_chandel, 81,
2329 "Input file and output file have same name:'%s'.\n") ,
2333 if (strcmp (profile, outfile) == 0) {
2334 printf ( catgets(dtsearch_catd, MS_chandel, 82,
2335 "Profile file and output file have same name:'%s'.\n") ,
2341 printf ( catgets(dtsearch_catd, MS_chandel, 83,
2342 " Profile file: %s\n") , profile);
2343 if (strcmp (infile, "-") == 0)
2344 printf ( catgets(dtsearch_catd, MS_chandel, 84,
2345 " Input file: stdin\n") );
2347 printf ( catgets(dtsearch_catd, MS_chandel, 85,
2348 " Input file: %s\n") , infile);
2349 if (strcmp (outfile, "-") == 0)
2350 printf ( catgets(dtsearch_catd, MS_chandel, 86,
2351 " Output file: stdout\n") );
2353 printf ( catgets(dtsearch_catd, MS_chandel, 87,
2354 " Output file: %s\n") , outfile);
2356 } /*--user_args_processor--*/
2358 /****************************************************************************
2359 FLAG_SHUTDOWN - signal handler - to allow for graceful exiting
2360 ****************************************************************************/
2361 static void flag_shutdown (int sig)
2363 shutdown_now = TRUE;
2366 /****************************************************************************
2367 MAIN - Body of Handel. Checks user parameters, processes the profile
2368 file, and then goes into the main loop, running each record from the input
2369 file against the profile and thru the text processor.
2370 *****************************************************************************/
2371 int main (int argc, char **argv)
2375 /*-- Initialization --*/
2377 setlocale (LC_ALL, "");
2378 dtsearch_catd = catopen (FNAME_DTSRCAT, 0);
2379 printf ( catgets(dtsearch_catd, MS_chandel, 88,
2380 "%s. %s %s Text Filter.\n") ,
2381 aa_argv0, PRODNAME, DtSrVERSION);
2384 memcpy (&nowtm, localtime(&now), sizeof(struct tm));
2385 strftime (now_str, sizeof(now_str), "%y/%m/%d~%H:%M", &nowtm);
2386 memset (&rectm, 0, sizeof(struct tm));
2388 /* check user arguments */
2389 user_arg_processor (argc, argv);
2396 if (warnings && !bad_profile) {
2397 signal (SIGINT, flag_shutdown);
2398 signal (SIGTERM, flag_shutdown);
2400 printf ( catgets(dtsearch_catd, MS_chandel, 89,
2401 "\nInterrupt with CTRL-C to exit gracefully "
2402 "at record boundary.\n Each dot is %ld records...\n"),
2404 process_infile (); /* process the input file */
2405 oops = fclose (outstream);
2408 printf ( catgets(dtsearch_catd, MS_chandel, 90,
2409 "\nError closing output file - disk full?\n") );
2414 printf ( catgets(dtsearch_catd, MS_chandel, 91,
2415 "Quitting due to errors in profile file.\n") );
2418 printf ( catgets(dtsearch_catd, MS_chandel, 92,
2419 "\n%s: Normal completion. %ld records processed. Exit code = 0.\n"),
2420 aa_argv0, rec_count);
2423 /*************** DTSRHAN.C ****************/