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.
112 #define PROGNAME "DTSRHAN"
114 #define RECS_PER_DOT 10L
116 /*-- Numerical codes for storing "undefined items" --*/
120 /*-- Codes for "modes" of text buffering --*/
128 /*-- codes for abstract mode --*/
133 /*-- Exit codes for errors --*/
136 #define SYNTAX_ERROR 4
139 #define BAD_PROFILE 7
142 /*-- Token types --*/
147 /****#define WORDS 4*****/
153 #define TEXTINCLUDE 10
154 #define TEXTEXCLUDE 11
155 #define TFIELDINCLUDE 12
156 #define TFIELDEXCLUDE 13
157 #define DELBLANKLINES 14
158 #define IMAGEINCLUDE 15
159 #define IMAGEEXCLUDE 16
165 /*-- General Defines --*/
169 #define MAX_ALPHABET_SIZE 256
171 /*-- definitions of various data structures --*/
172 struct line_comp { /*-- Individual components for line ids --*/
175 int d[MAX_ALPHABET_SIZE];
177 struct line_comp *next;
180 struct line_id { /*-- list of line ids to be handled --*/
182 struct line_comp *comp;
183 struct line_comp *head;
184 struct line_id *next;
191 struct field_id { /*-- list of field ids to be used --*/
192 struct field_id *next;
194 struct line_id *line;
199 int d[MAX_ALPHABET_SIZE];
210 struct rec { /*-- holds a complete image of a record --*/
212 struct line_id *line;
219 struct date_id *next;
220 struct field_id *field;
226 struct field_id *field;
232 struct finclude *next;
238 struct include *next;
241 /************************************************/
245 /************************************************/
246 char abstracter[100];
247 int abstract = GENERATE;
248 struct key_id *abstract_table = NULL;
249 /***nl_catd dtsearch_catd = (nl_catd) -1;***/
250 int bad_parm = FALSE;
251 int bad_profile = FALSE;
252 int bot_defined = FALSE;
253 struct date_id *date_table = NULL;
254 int date_pos_defined = FALSE;
255 static char *del_string = " +=,\t\n";
256 /****static char *del_string = " +-=,\t\n";**allow neg nums***/
257 int del_blanklines = FALSE;
258 char dicname[10] = {0};
259 char dicpath[_POSIX_PATH_MAX] = {0};
261 int discard_record = FALSE;
262 struct finclude *finclude_tab = NULL;
263 struct field_id *field_table = NULL;
264 struct include *i_i_t = NULL;
265 int imagemode = INCLUDE;
266 int imageflag = INCLUDE;
267 struct include *include_tab = NULL;
269 static FILE *instream = NULL;
270 static long key_count = 0;
271 struct key_id *key_table = NULL;
272 int key_defined = FALSE;
273 int key_pos_defined = FALSE;
276 static char *line_mode = "
\f\ 2\ 6CTHULHU TOCOMA ZYYXY UTOPIA";
277 struct line_id *line_table = NULL;
281 static int null_date_specified = FALSE;
282 struct tm *objdate_tmptr;
284 char outmode[8] = "w";
285 int outmode_specified = FALSE;
287 static FILE *outstream = NULL;
289 static long rec_count = 0L; /* for err msgs */
290 struct rec *record_head = NULL;
292 int screen_width = 79;
293 int shutdown_now = FALSE;
295 int textflag = INCLUDE;
296 int textmode = INCLUDE;
297 int top_defined = FALSE;
298 struct line_id *top_rec;
299 char top_rec_name[80];
300 int uppercase = FALSE;
301 int uninit_line = TRUE;
302 int uninit_field = TRUE;
304 int wordmode = INCLUDE;
307 /****************************************************************
308 VALIDATE_ID - validates an indentifier (first character a
309 letter, then alpha-numeric, etc)
310 ****************************************************************/
311 int validate_id (char *s)
317 if (!isalpha (s[0])) {
320 for (i = 1; i < strlen (s); i++)
321 if (!isalnum (s[i]) && s[i] != '_') {
328 /****************************************************************
329 OPEN_OUTFILE - open outputfile - if the file already exists,
330 and no mode was specified by the user, ask the user what to do.
331 ****************************************************************/
337 if (!outmode_specified)
338 if ((temp = fopen (outfile, "r")) != NULL) {
340 printf ( catgets(dtsearch_catd, MS_chandel, 3,
341 "Output file '%s' already exists.\n") ,
343 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 4,
344 "Append, overwrite, or quit? [a,o,q] ") );
345 i = tolower (getchar ());
348 strcpy (outmode, "a");
350 strcpy (outmode, "w");
354 if (!strcmp (outfile, "-"))
357 if ((outstream = fopen (outfile, outmode)) == NULL) {
358 printf ( catgets(dtsearch_catd, MS_chandel, 7,
359 "Unable to open output file '%s'.\n") , outfile);
367 /****************************************************************
368 IS_TIME - returns TRUE if the passed string contains the
369 string "time" in any case (upper/lower) - without destroying the
370 original string, in case it was a field name.
371 ****************************************************************/
372 int is_time (char *orig)
376 /* copy original string to temp buffer, so we can manipulate */
377 s = (char *) malloc (sizeof (char) * strlen (orig) +5);
379 for (i = 0; i < strlen (s); i++)
380 s[i] = tolower (s[i]);
382 if (strcmp (s, "time") == 0)
388 /****************************************************************
389 IS_COUNT - returns TRUE if the passed string contains the
390 string "count" in any case (upper/lower) - without destroying the
391 original string, in case it was a field name.
392 ****************************************************************/
393 int is_count (char *orig)
397 /* copy original string to temp buffer, so we can manipulate */
398 s = (char *) malloc (sizeof(char) * strlen(orig) +5);
400 for (i = 0; i < strlen (s); i++)
401 s[i] = tolower (s[i]);
403 if (strcmp (s, "count") == 0)
409 /****************************************************************
410 MY_STRTOK - my own version of strtok - why? Because I need
411 a little flexibility when parsing out the string component -
412 what if it has quotes embedded?
414 s1 = the line to be parsed (= start at beginning)
415 or NULL (= start where we last left off).
417 s2 = the 'delete' string or array of token separators.
418 Usually it is either the global 'del_string' (" +-=,\t\n")
419 or a string consisting of a single double-quote char.
420 ****************************************************************/
421 char *my_strtok (char *s1, const char *s2)
424 static char stringbuf[100];
425 static char *ssave = "";
428 memset (stringbuf, 0, sizeof(stringbuf));
429 sbegin = (s1) ? s1 : ssave; /* start of string or where we last left off */
431 if (strcmp (s2, "\"") == 0) { /* parsing for a string */
432 if (*sbegin == '\0') {
436 while (*sbegin != '"' && *sbegin != '\0') {/*-- look for first " --*/
439 if (*sbegin == '\0') {
443 sbegin++; /*-- skip past " --*/
445 while (*sbegin != '"') {/*-- until other " --*/
446 if (*sbegin == '\\') /*-- escape sequence --*/
448 if (*sbegin == '\0') { /*-- end of line --*/
452 stringbuf[i++] = (*sbegin);
463 else { /* not parsing for a string */
464 sbegin += strspn (sbegin, s2);
465 if (*sbegin == '\0') {
469 send = strpbrk (sbegin, s2);
475 } /*-- my_strtok --*/
477 /****************************************************************
478 IS_BLANK - determines if a string contains nothing but
480 *****************************************************************/
481 int is_blank (char *s)
484 for (i = 0; i < strlen (s); i++)
491 /***********************************************************************
492 TOKEN - returns a numerical token for the defined identifier types
493 ************************************************************************/
501 /*-- make token all lowercase --*/
502 for (i = 0; i < strlen (s); i++)
503 s[i] = tolower (s[i]);
505 if (!strcmp (s, "line"))
507 if (!strcmp (s, "field"))
509 if (!strcmp (s, "key"))
511 if (!strcmp (s, "date"))
513 if (!strcmp (s, "text"))
515 if (!strcmp (s, "keychar"))
517 if (!strcmp (s, "delimiter"))
519 if (!strcmp (s, "textinclude"))
521 if (!strcmp (s, "textexclude"))
523 if (!strcmp (s, "tfieldinclude"))
524 return TFIELDINCLUDE;
525 if (!strcmp (s, "tfieldexclude"))
526 return TFIELDEXCLUDE;
527 if (!strcmp (s, "delblanklines"))
528 return DELBLANKLINES;
529 if (!strcmp (s, "abstract"))
531 if (!strcmp (s, "user"))
533 if (!strcmp (s, "fields"))
535 if (!strcmp (s, "generate"))
537 if (!strcmp (s, "image"))
539 if (!strcmp (s, "imageinclude"))
541 if (!strcmp (s, "imageexclude"))
543 if (!strcmp (s, "discard"))
545 if (!strcmp (s, "constant"))
547 if (!strcmp (s, "upper"))
552 /***********************************************************************
553 PROCESS_PROFILE - process 'profile' file.
554 ************************************************************************/
555 void process_profile ()
562 struct line_id *line_current;
563 struct field_id *field_current;
564 struct key_id *key_current;
565 struct date_id *date_current;
566 struct key_id *abstract_current;
567 struct finclude *finclude_current;
568 struct include *include_current;
569 struct include *i_i_current;
574 if ((prof = fopen (profile, "r")) == NULL) {
575 printf ( catgets(dtsearch_catd, MS_chandel, 11,
576 "\nError - unable to open profile file '%s'.\n") , profile);
579 /*-- Get next line --*/
581 fgets (prof_line, 200, prof);
585 if (prof_line[0] == '#' || is_blank (prof_line))
587 tok = my_strtok (prof_line, del_string);
589 continue; /* ignore blank line */
590 tok_type = token (tok);
598 if (line_table == NULL) {
599 line_table = (struct line_id *) malloc (
600 sizeof (struct line_id));
601 line_current = line_table;
602 line_table->next = NULL;
603 line_table->comp = (struct line_comp *) malloc (
604 sizeof (struct line_comp));
605 line_table->head = line_table->comp;
606 line_table->comp->next = NULL;
610 line_current->next = (struct line_id *) malloc (
611 sizeof (struct line_id));
612 line_current = line_current->next;
613 line_current->next = NULL;
614 line_current->comp = (struct line_comp *) malloc (
615 sizeof (struct line_comp));
616 line_current->head = line_current->comp;
617 line_current->comp->next = NULL;
619 line_current->image_action = NONE;
620 line_current->word_action = NONE;
621 line_current->text_action = NONE;
622 line_current->line = NULL;
623 line_current->name[0] = 0;
624 /*-- get identifier --*/
625 tok = my_strtok ('\0', del_string);
626 if (validate_id (tok))
627 strcpy (line_current->name, tok);
629 printf ( catgets(dtsearch_catd, MS_chandel, 12,
630 "Error line %d: invalid identifier '%s'.\n") ,
631 line_num, NULLORSTR(tok));
635 /*-- get first value token --*/
636 tok = my_strtok ('\0', del_string);
638 printf ( catgets(dtsearch_catd, MS_chandel, 13,
639 "Error line %d - identifier '%s' missing value(s).\n") ,
640 line_num, line_current->name);
644 if (!strcmp (tok, "*"))
645 line_current->comp->column_number = ANY;
647 line_current->comp->column_number = atoi (tok);
648 if (line_current->comp->column_number == 0) {
649 printf ( catgets(dtsearch_catd, MS_chandel, 14,
650 "Error line %d - zero or bad value for '%s'.\n"
651 " offensive token: %s.\n") ,
652 line_num, line_current->name, tok);
656 /* d d d-- get second token of pair -- */
657 tok = my_strtok ('\0', "\"");
659 if (line_current->comp->column_number == ANY) {
660 printf ( catgets(dtsearch_catd, MS_chandel, 15,
661 "Error line %d - for identifier '%s', column has "
662 "been set to ANY\n but there is no "
663 "identifying signature string.\n") ,
664 line_num, line_current->name);
670 strcpy (line_current->comp->text, line_mode);
676 strcpy (line_current->comp->text, tok);
677 line_current->comp->text_length =
678 strlen (line_current->comp->text);
680 /*-- check for more tokens for LINE type of line --*/
682 tok = my_strtok ('\0', del_string);
685 /*-- build component node --*/
686 line_current->comp->next = (struct line_comp *) malloc (
687 sizeof (struct line_comp));
688 line_current->comp = line_current->comp->next;
689 line_current->comp->next = NULL;
690 /*-- check # and store --*/
691 if (!strcmp (tok, "*"))
692 line_current->comp->column_number = ANY;
694 line_current->comp->column_number = atoi (tok);
695 if (line_current->comp->column_number == 0) {
696 printf ( catgets(dtsearch_catd, MS_chandel, 16,
697 "Error line %d - zero or bad value for "
698 "identifier '%s'\n offensive token: %s.\n") ,
699 line_num, line_current->name, tok);
703 /* - --- get second of pair -- */
704 tok = my_strtok ('\0', "\"");
706 if (line_current->comp->column_number == ANY)
707 printf ( catgets(dtsearch_catd, MS_chandel, 15,
708 "Error line %d - for identifier '%s', column has "
709 "been set to ANY\n but there is no "
710 "identifying signature string.\n") ,
711 line_num, line_current->name);
713 printf ( catgets(dtsearch_catd, MS_chandel, 18,
714 "Error line %d - missing value for "
715 "identifier '%s'\n") ,
716 line_num, line_current->name);
720 strcpy (line_current->comp->text, tok);
721 line_current->comp->text_length =
722 strlen (line_current->comp->text);
723 } /* end for(;;) loop for continuing LINE token pairs */
724 break; /* end case LINE */
728 if (field_table == NULL) {
729 field_table = (struct field_id *)
730 malloc (sizeof (struct field_id));
731 field_current = field_table;
732 field_table->next = NULL;
735 field_current->next = (struct field_id *) malloc (
736 sizeof (struct field_id));
737 field_current = field_current->next;
738 field_current->next = NULL;
740 memset (field_current, 0, sizeof(struct field_id));
741 field_current->word_action = NONE;
742 field_current->image_action = NONE;
743 field_current->text_action = NONE;
744 if (tok_type == CONSTANT)
745 field_current->constant = TRUE;
747 /*-- get identifier --*/
748 tok = my_strtok ('\0', del_string);
749 if (validate_id (tok)) {
750 strcpy (field_current->name, tok);
751 if (strncmp (tok, "MMM", 3) == 0)
752 field_current->is_month = TRUE;
755 printf ( catgets(dtsearch_catd, MS_chandel, 12,
756 "Error line %d: invalid identifier '%s'.\n") ,
757 line_num, NULLORSTR(tok));
761 if (field_current->constant) {
762 /*-- get constant value --*/
763 tok = my_strtok (NULL, "\"");
765 printf ( catgets(dtsearch_catd, MS_chandel, 93,
766 "Error line %d - '%s' string not "
767 "enclosed in double quotes.\n"),
768 line_num, field_current->name);
772 strcpy (field_current->value, tok);
775 else { /* ...must be FIELD */
776 /*-- get line id --*/
777 tok = my_strtok ('\0', del_string);
779 printf ( catgets(dtsearch_catd, MS_chandel, 13,
780 "Error line %d - identifier '%s' missing value(s).\n") ,
781 line_num, line_current->name);
785 strcpy (field_current->line_id, tok);
787 /*-- get "string" --*/
788 tok = my_strtok ('\0', "\"");
790 printf ( catgets(dtsearch_catd, MS_chandel, 93,
791 "Error line %d - '%s' string not "
792 "enclosed in double quotes.\n"),
793 line_num, field_current->name);
797 strcpy (field_current->text, tok);
798 field_current->text_length = strlen (field_current->text);
801 tok = my_strtok ('\0', del_string);
803 printf ( catgets(dtsearch_catd, MS_chandel, 13,
804 "Error line %d - identifier '%s' missing value(s).\n") ,
805 line_num, line_current->name);
809 field_current->offset = atoi (tok);
812 tok = my_strtok ('\0', del_string);
813 /*******if (!tok && field_current->length == ANY) ************/
815 printf ( catgets(dtsearch_catd, MS_chandel, 13,
816 "Error line %d - identifier '%s' missing value(s).\n") ,
817 line_num, line_current->name);
821 if (!strcmp (tok, "eoln"))
822 field_current->defined_length = EOLN;
823 else if (!strcmp (tok, "eow"))
824 field_current->defined_length = EOW;
826 field_current->defined_length = atoi (tok);
831 /*-- get next token - should be name of line --*/
832 if (warnings &&(bot_defined || top_defined))
833 printf ( catgets(dtsearch_catd, MS_chandel, 23,
834 "Warning line %d: Delimiter redefined.\n") ,
836 tok = my_strtok ('\0', del_string);
837 if (validate_id (tok))
838 strcpy (top_rec_name, tok);
840 printf ( catgets(dtsearch_catd, MS_chandel, 12,
841 "Error line %d: invalid identifier '%s'.\n"),
842 line_num, NULLORSTR(tok));
845 tok = my_strtok ('\0', del_string);
848 /* convert tok to lowercase */
849 for (i = 0; i < strlen (tok); i++)
850 tok[i] = tolower (tok[i]);
851 if (!strcmp (tok, "top")) {
854 } else if (!strcmp (tok, "bottom")) {
859 printf ( catgets(dtsearch_catd, MS_chandel, 25,
860 "Error line %d: delimiter not specified as "
861 "'top' or 'bottom'.\n") ,
868 tok = my_strtok ('\0', del_string);
869 if (validate_id (tok)) {
870 if (finclude_tab == NULL) {
871 finclude_tab = (struct finclude *) malloc (
872 sizeof (struct finclude));
873 finclude_current = finclude_tab;
875 finclude_current->next = (struct finclude *) malloc (
876 sizeof (struct finclude));
877 finclude_current = finclude_current->next;
879 finclude_current->next = NULL;
880 strcpy (finclude_current->field_id, tok);
881 finclude_current->value = EXCLUDE;
883 /* if it was a valid token */
885 printf ( catgets(dtsearch_catd, MS_chandel, 26,
886 "Error line %d: invalid token '%s'.\n") ,
887 line_num, NULLORSTR(tok));
893 tok = my_strtok ('\0', del_string);
894 if (validate_id (tok)) {
895 if (finclude_tab == NULL) {
896 finclude_tab = (struct finclude *) malloc (
897 sizeof (struct finclude));
898 finclude_tab->next = NULL;
899 finclude_current = finclude_tab;
903 finclude_current->next = (struct finclude *) malloc (
904 sizeof (struct finclude));
905 finclude_current = finclude_current->next;
906 finclude_current->next = NULL;
908 strcpy (finclude_current->field_id, tok);
909 finclude_current->value = INCLUDE;
911 /* if it was a valid token */
913 printf ( catgets(dtsearch_catd, MS_chandel, 27,
914 "Error line %d: invalid token '%s'.\n") ,
915 line_num, NULLORSTR(tok));
921 tok = my_strtok ('\0', del_string);
922 if (validate_id (tok)) {
923 if (include_tab == NULL) {
924 include_tab = (struct include *) malloc (
925 sizeof (struct include));
926 include_tab->next = NULL;
927 include_current = include_tab;
931 include_current->next = (struct include *) malloc (
932 sizeof (struct include));
933 include_current = include_current->next;
934 include_current->next = NULL;
935 } /* else in valid */
936 strcpy (include_current->line_id, tok);
937 tok = my_strtok ('\0', del_string);
939 include_current->value = EXCLUDE;
941 if (validate_id (tok)) {
942 include_current->value = SET;
943 include_current->next = (struct include *) malloc (
944 sizeof (struct include));
945 include_current = include_current->next;
946 include_current->next = NULL;
947 strcpy (include_current->line_id, tok);
948 include_current->value = DEFAULT;
952 printf ( catgets(dtsearch_catd, MS_chandel, 12,
953 "Error line %d: invalid identifier '%s'.\n") ,
957 } /* else tok wasn't NULL */
961 printf (catgets(dtsearch_catd, MS_chandel, 12,
962 "Error line %d: invalid identifier '%s'.\n") ,
963 line_num, NULLORSTR(tok));
965 } /* else not a valid token */
969 tok = my_strtok ('\0', del_string);
970 if (validate_id (tok)) {
972 i_i_t = (struct include *) malloc (
973 sizeof (struct include));
979 i_i_current->next = (struct include *) malloc (
980 sizeof (struct include));
981 i_i_current = i_i_current->next;
982 i_i_current->next = NULL;
983 } /* else in valid */
984 strcpy (i_i_current->line_id, tok);
985 tok = my_strtok ('\0', del_string);
987 i_i_current->value = EXCLUDE;
989 if (validate_id (tok)) {
990 i_i_current->value = SET;
991 i_i_current->next = (struct include *) malloc (
992 sizeof (struct include));
993 i_i_current = i_i_current->next;
994 i_i_current->next = NULL;
995 strcpy (i_i_current->line_id, tok);
996 i_i_current->value = DEFAULT;
1000 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1001 "Error line %d: invalid identifier '%s'.\n") ,
1004 } /* else in else */
1005 } /* else tok wasn't NULL */
1007 /* if validate... */
1009 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1010 "Error line %d: invalid identifier '%s'.\n") ,
1011 line_num, NULLORSTR(tok));
1013 } /* else not a valid token */
1017 tok = my_strtok ('\0', del_string);
1018 if (validate_id (tok)) {
1019 if (i_i_t == NULL) {
1020 i_i_t = (struct include *) malloc (
1021 sizeof (struct include));
1023 i_i_current = i_i_t;
1027 i_i_current->next = (struct include *) malloc (
1028 sizeof (struct include));
1029 i_i_current = i_i_current->next;
1030 i_i_current->next = NULL;
1031 } /* else in valid */
1032 strcpy (i_i_current->line_id, tok);
1033 tok = my_strtok ('\0', del_string);
1035 i_i_current->value = INCLUDE;
1037 if (validate_id (tok)) {
1038 i_i_current->value = CLEAR;
1039 i_i_current->next = (struct include *) malloc (
1040 sizeof (struct include));
1041 i_i_current = i_i_current->next;
1042 i_i_current->next = NULL;
1043 strcpy (i_i_current->line_id, tok);
1044 i_i_current->value = DEFAULT;
1048 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1049 "Error line %d: invalid identifier '%s'.\n") ,
1052 } /* else in else */
1053 } /* else tok wasn't NULL */
1055 /* if validate... */
1057 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1058 "Error line %d: invalid identifier '%s'.\n") ,
1059 line_num, NULLORSTR(tok));
1061 } /* else not a valid token */
1065 tok = my_strtok ('\0', del_string);
1066 if (validate_id (tok)) {
1067 if (include_tab == NULL) {
1068 include_tab = (struct include *) malloc (
1069 sizeof (struct include));
1070 include_tab->next = NULL;
1071 include_current = include_tab;
1075 include_current->next = (struct include *) malloc (
1076 sizeof (struct include));
1077 include_current = include_current->next;
1078 include_current->next = NULL;
1079 } /* else in valid */
1080 strcpy (include_current->line_id, tok);
1081 tok = my_strtok ('\0', del_string);
1083 include_current->value = INCLUDE;
1085 if (validate_id (tok)) {
1086 include_current->value = CLEAR;
1087 include_current->next = (struct include *) malloc (
1088 sizeof (struct include));
1089 include_current = include_current->next;
1090 include_current->next = NULL;
1091 strcpy (include_current->line_id, tok);
1092 include_current->value = DEFAULT;
1096 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1097 "Error line %d: invalid identifier '%s'.\n") ,
1100 } /* else in else */
1101 } /* else tok wasn't NULL */
1103 /* if validate... */
1105 printf ( catgets(dtsearch_catd, MS_chandel, 12,
1106 "Error line %d: invalid identifier '%s'.\n") ,
1107 line_num, NULLORSTR(tok));
1109 } /* else not a valid token */
1113 tok = my_strtok ('\0', del_string);
1116 for (i = 0; i < strlen (tok); i++)
1117 tok[i] = tolower (tok[i]);
1118 if (strcmp (tok, catgets (dtsearch_catd, MS_chandel, 34,"all")) == 0)
1119 imagemode = INCLUDE;
1120 else if (strcmp (tok, catgets (dtsearch_catd, MS_chandel, 35, "none")) == 0)
1121 imagemode = EXCLUDE;
1124 printf ( catgets(dtsearch_catd, MS_chandel, 36,
1125 "Error line %d: image mode must be 'all' or "
1126 "'none' -'%s' not recognized.\n") ,
1130 imageflag = imagemode;
1134 tok = my_strtok ('\0', del_string);
1137 for (i = 0; i < strlen (tok); i++)
1138 tok[i] = tolower (tok[i]);
1139 if (strcmp (tok, "all") == 0)
1141 else if (strcmp (tok, "none") == 0)
1145 printf ( catgets(dtsearch_catd, MS_chandel, 37,
1146 "Error line %d: text mode must be 'all' or "
1147 "'none' - '%s' not recognized.\n") , NULLORSTR(tok));
1150 textflag = textmode;
1154 /*-- get next token - should be character for key type --*/
1155 if (warnings && key_defined)
1156 printf ( catgets(dtsearch_catd, MS_chandel, 38,
1157 "Warning line %d: Key character redefined.\n") ,
1159 tok = my_strtok ('\0', del_string);
1160 if (validate_id (tok))
1163 printf ( catgets(dtsearch_catd, MS_chandel, 39,
1164 "Error line %d: invalid Key Character:'%c'.\n") ,
1165 line_num, (tok)?tok[0]:'?');
1173 if (date_pos_defined) {
1174 printf ( catgets(dtsearch_catd, MS_chandel, 110,
1175 "Warning line %d - date field redefined.\n") ,
1177 null_date_specified = FALSE;
1179 date_table = (struct date_id *) malloc
1180 (sizeof (struct date_id));
1181 date_current = date_table;
1182 date_current->next = NULL;
1183 tok = my_strtok ('\0', del_string);
1184 /* validate_id() just does syntax chk on name string */
1185 if (validate_id (tok))
1186 strcpy (date_current->field_id, tok);
1188 /* Msg #111 used two places */
1189 printf ( catgets(dtsearch_catd, MS_chandel, 111,
1190 "Error line %d - bad identifier '%s' for date.\n") ,
1191 line_num, NULLORSTR(tok));
1196 /* Test for special "null" date value */
1197 if (strcmp (date_current->field_id, "null") == 0) {
1198 date_pos_defined = TRUE;
1199 null_date_specified = TRUE;
1203 tok = my_strtok ('\0', del_string);
1204 while (tok != NULL) {
1205 date_current->next = (struct date_id *) malloc
1206 (sizeof (struct date_id));
1207 date_current = date_current->next;
1208 date_current->next = NULL;
1209 if (validate_id (tok))
1210 strcpy (date_current->field_id, tok);
1212 /* Msg #111 used two places */
1213 printf ( catgets(dtsearch_catd, MS_chandel, 111,
1214 "Error line %d - bad identifier '%s' for date.\n"),
1215 line_num, NULLORSTR(tok));
1219 tok = my_strtok ('\0', del_string);
1221 date_pos_defined = TRUE;
1222 break; /* end case DATEFLD */
1225 /*-- building the key --*/
1226 if (warnings && key_pos_defined)
1227 printf ( catgets(dtsearch_catd, MS_chandel, 40,
1228 "Warning line %d - key field redefined.\n") ,
1230 key_table = (struct key_id *) malloc (sizeof (struct key_id));
1231 key_current = key_table;
1232 key_current->next = NULL;
1233 tok = my_strtok ('\0', del_string);
1234 if (validate_id (tok)) {
1235 if (is_time (tok)) {
1236 strcpy (key_current->field_id, "time");
1237 key_pos_defined = TRUE;
1239 } else if (is_count (tok)) {
1240 strcpy (key_current->field_id, "count");
1241 key_pos_defined = TRUE;
1244 strcpy (key_current->field_id, tok);
1247 printf ( catgets(dtsearch_catd, MS_chandel, 43,
1248 "Error line %d - bad identifier '%s' for key.\n") ,
1249 line_num, NULLORSTR(tok));
1253 tok = my_strtok ('\0', del_string);
1254 while (tok != NULL) {
1255 key_current->next = (struct key_id *) malloc (
1256 sizeof (struct key_id));
1257 key_current = key_current->next;
1258 key_current->next = NULL;
1259 if (validate_id (tok))
1260 strcpy (key_current->field_id, tok);
1262 printf ( catgets(dtsearch_catd, MS_chandel, 43,
1263 "Error line %d - bad identifier '%s' for key.\n") ,
1268 tok = my_strtok ('\0', del_string);
1270 key_pos_defined = TRUE;
1274 tok = my_strtok ('\0', del_string);
1277 for (i = 0; i < strlen (tok); i++)
1278 tok[i] = toupper (tok[i]);
1279 if (!strcmp (tok, "TRUE"))
1281 else if (!strcmp (tok, "FALSE"))
1285 printf ( catgets(dtsearch_catd, MS_chandel, 45,
1286 "Error line %d: unknown option for 'discard': "
1287 "'%s'.\n") , line_num, NULLORSTR(tok));
1293 tok = my_strtok ('\0', del_string);
1295 goto BAD_DELBLANKLINES;
1296 for (i = 0; i < strlen (tok); i++)
1297 tok[i] = toupper (tok[i]);
1298 if (!strcmp (tok, "TRUE"))
1299 del_blanklines = TRUE;
1300 else if (!strcmp (tok, "FALSE"))
1301 del_blanklines = FALSE;
1304 printf ( catgets(dtsearch_catd, MS_chandel, 46,
1305 "Error line %d: unknown option for "
1306 "'delblanklines': '%s'.\n") ,
1307 line_num, NULLORSTR(tok));
1313 tok = my_strtok ('\0', del_string);
1314 abstract = token (tok);
1319 tok = my_strtok ('\0', del_string);
1322 strcpy (abstracter, tok);
1325 tok = my_strtok ('\0', del_string);
1326 while (tok != NULL) {
1327 if (abstract_table == NULL) {
1328 abstract_table = (struct key_id *) malloc
1329 (sizeof (struct key_id));
1330 abstract_current = abstract_table;
1332 abstract_current->next =
1333 (struct key_id *) malloc (
1334 sizeof (struct key_id));
1335 abstract_current = abstract_current->next;
1337 strcpy (abstract_current->field_id, tok);
1338 abstract_current->next = NULL;
1339 tok = my_strtok ('\0', del_string);
1344 printf ( catgets(dtsearch_catd, MS_chandel, 47,
1345 "Error line %d: Unknown option for abstract :'%s'\n"),
1346 line_num, NULLORSTR(tok));
1349 } /* 'abstract' subswitch */
1353 printf ( catgets(dtsearch_catd, MS_chandel, 48,
1354 "Error line %d -unknown identifier type '%s'.\n") ,
1355 line_num, NULLORSTR(tok));
1358 } /* main switch for each line in profile */
1359 } while (TRUE); /* read-a-line do loop */
1360 if (!date_pos_defined)
1361 fprintf (aa_stderr, catgets(dtsearch_catd, MS_chandel, 115,
1362 "%s Default object dates will be '%s'.\n") ,
1363 PROGNAME"1288", now_str);
1367 /*---- Process tables, and check for identifiers referenced ----*/
1368 if (!top_defined && !bot_defined) {
1370 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 49,
1371 "Error - delimiter not defined.\n") );
1375 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 50,
1376 "Error - key-type character never defined.\n") );
1378 if (!key_pos_defined) {
1380 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 51,
1381 "Error - key never defined.\n") );
1387 line_current = line_table;
1388 while (line_current != NULL) {
1389 if (strcmp (line_current->name, top_rec_name) == 0)
1390 top_rec = line_current;
1391 line_current = line_current->next;
1393 if (top_rec_name[0] != 0 && top_rec == NULL) {
1394 printf ( catgets(dtsearch_catd, MS_chandel, 52,
1395 "Error - delimiter defined as '%s' was never found.\n") ,
1398 } else if (strcmp (top_rec->head->text, line_mode) == 0) {
1399 printf ( catgets(dtsearch_catd, MS_chandel, 53,
1400 "Error - delimiter defined as '%s' references a physical "
1401 "line in the record.\n Since the delimiter defines the "
1402 "physical lines\n it cannot be referenced as a physical line.\n"),
1406 field_current = field_table;
1407 while (field_current != NULL) {
1409 line_current = line_table;
1410 while (line_current != NULL) {
1411 if (!strcmp (field_current->line_id, line_current->name)) {
1413 field_current->line = line_current;
1415 line_current = line_current->next;
1417 if (!found && !field_current->constant) {
1418 printf ( catgets(dtsearch_catd, MS_chandel, 54,
1419 "Error - for field '%s', no line identifer matches '%s'.\n") ,
1420 field_current->name, field_current->line_id);
1423 field_current = field_current->next;
1425 finclude_current = finclude_tab;
1426 while (finclude_current != NULL) {
1427 /* find field, and set text_value */
1428 field_current = field_table;
1430 while (field_current != NULL) {
1431 if (!strcmp (field_current->name, finclude_current->field_id)) {
1432 field_current->text_action = finclude_current->value;
1435 field_current = field_current->next;
1438 printf ( catgets(dtsearch_catd, MS_chandel, 55,
1439 "Error - field include/exclude list included\n"
1440 " the field '%s', which was never defined.\n") ,
1441 finclude_current->field_id);
1444 finclude_current = finclude_current->next;
1446 i_i_current = i_i_t;
1447 while (i_i_current != NULL) {
1448 /* find line, and set text_action */
1449 line_current = line_table;
1451 while (line_current != NULL) {
1452 if (!strcmp (line_current->name, i_i_current->line_id)) {
1453 line_current->image_action = i_i_current->value;
1456 line_current = line_current->next;
1459 printf ( catgets(dtsearch_catd, MS_chandel, 56,
1460 "Error - image include/exclude list included\n"
1461 " the line '%s', which was never defined.\n") ,
1462 include_current->line_id);
1465 i_i_current = i_i_current->next;
1467 include_current = include_tab;
1468 while (include_current != NULL) {
1469 /* find line, and set text_action */
1470 line_current = line_table;
1472 while (line_current != NULL) {
1473 if (!strcmp (line_current->name, include_current->line_id)) {
1474 line_current->text_action = include_current->value;
1477 line_current = line_current->next;
1480 printf ( catgets(dtsearch_catd, MS_chandel, 57,
1481 "Error - text include/exclude list included\n"
1482 " the line '%s', which was never defined.\n") ,
1483 include_current->line_id);
1486 include_current = include_current->next;
1489 /* If "null" dates specified, no need to look for other date fields */
1490 if (null_date_specified)
1491 goto END_DATE_TABLE;
1493 /* loop thru date table and link each field id to its structure */
1494 for (date_current = date_table; date_current != NULL;
1495 date_current = date_current->next) {
1498 for (field_current = field_table; field_current != NULL;
1499 field_current = field_current->next) {
1500 if (strcmp (field_current->name, date_current->field_id) == 0) {
1501 date_current->field = field_current;
1507 printf ( catgets(dtsearch_catd, MS_chandel, 116,
1508 "Error - date references undefined field '%s'.\n"),
1509 date_current->field_id);
1515 key_current = key_table;
1516 while (key_current != NULL) {
1517 field_current = field_table;
1519 if (!strcmp ("time", key_current->field_id)) {
1521 key_current->field = NULL;
1522 } else if (!strcmp ("count", key_current->field_id)) {
1524 key_current->field = NULL;
1526 while (field_current != NULL) {
1527 if (!strcmp (field_current->name, key_current->field_id)) {
1529 key_current->field = field_current;
1530 } else if (!strcmp ("time", key_current->field_id)) {
1532 key_current->field = NULL;
1533 } else if (!strcmp ("count", key_current->field_id)) {
1535 key_current->field = NULL;
1537 field_current = field_current->next;
1540 printf ( catgets(dtsearch_catd, MS_chandel, 58,
1541 "Error - key definition references field '%s'\n"
1542 " which was never defined.\n") ,
1543 key_current->field_id);
1546 key_current = key_current->next;
1548 abstract_current = abstract_table;
1549 while (abstract_current != NULL) {
1550 field_current = field_table;
1552 while (field_current != NULL) {
1553 if (!strcmp (field_current->name, abstract_current->field_id)) {
1555 abstract_current->field = field_current;
1557 field_current = field_current->next;
1560 printf ( catgets(dtsearch_catd, MS_chandel, 59,
1561 "Error - abstract definition references field '%s'\n"
1562 " which was never defined.\n") ,
1563 abstract_current->field_id);
1566 abstract_current = abstract_current->next;
1569 } /*--process_profile--*/
1571 /**********************************************************************
1572 CLEANUP - frees memory used by record
1573 ***********************************************************************/
1576 struct line_id *line_current;
1577 struct field_id *field_current;
1580 /*-- Reset line_table --*/
1581 line_current = line_table;
1582 while (line_current != NULL) {
1583 line_current->line = UNDEFINED;
1584 line_current = line_current->next;
1587 /*-- Reset field table --*/
1588 field_current = field_table;
1589 while (field_current != NULL) {
1590 if (field_current->constant == FALSE)
1591 field_current->value[0] = 0;
1592 field_current = field_current->next;
1595 /*-- clean up record, free memory for reuse --*/
1596 record = record_head;
1597 while (record_head != NULL) {
1598 record_head = record->next;
1600 record = record_head;
1604 /**************************************************************************
1605 WRITE_RECORD - writes the final form of the record - key, fzkey, abstract,
1607 **************************************************************************/
1608 void write_record ()
1610 static int dotcount = 0;
1612 struct key_id *abst;
1620 /* Line #1 is fzkey */
1621 fprintf (outstream, " 0,2\n"); /* hardcoded null fzkey */
1623 /* Line #2 is abstract */
1625 if (abstract == FIELDS) {
1626 abst = abstract_table;
1627 while (abst != NULL) {
1628 strcat (value, abst->field->value);
1631 for (i = 0; i < strlen (value); i++)
1632 if (value[i] == '\n')
1635 fprintf (outstream, "ABSTRACT: %s\n", value);
1637 /* Line #3 is unique database key */
1638 if (key_value[strlen (key_value) - 1] == '\n')
1639 key_value[strlen (key_value) - 1] = 0;
1642 fprintf (outstream, "%c%s\n", key_char, key_value);
1644 /* Line #4 is object date in objdate string format.
1645 * Prior to version 2.0.8 this would be the first line of text.
1647 if (null_date_specified)
1648 fputs (NULLDATESTR"\n", outstream);
1650 fprintf (outstream, "%s\n",
1651 objdate2fzkstr (tm2objdate (objdate_tmptr)));
1653 /* Lines #5 and thereafter (text) of .fzk rec */
1654 record = record_head;
1655 while (record != NULL) {
1657 * Strip out any control-l's, as we put our own later,
1658 * and any extras might freak out something that wants
1659 * a control-l as a delimeter.
1661 for (i = 0; i < strlen (record->text); i++)
1662 if (record->text[i] == CNTRL_L)
1663 record->text[i] = ' ';
1665 lvalue = (record->line)? record->line->image_action : 0;
1668 imageflag = INCLUDE;
1671 imageflag = EXCLUDE;
1676 if ((imageflag == INCLUDE && lvalue != EXCLUDE)
1677 || (lvalue == INCLUDE)) {
1678 /* trim to fit in screen */
1679 strcpy (buffer, record->text);
1680 if (strlen (buffer) > screen_width) {
1681 buffer[screen_width] = '\n';
1682 buffer[screen_width + 1] = 0;
1684 fprintf (outstream, "%s", buffer);
1686 record = record->next;
1687 if (lvalue == DEFAULT)
1688 imageflag = imagemode;
1691 /* Test final record write to check for full filesystem */
1692 if (fprintf (outstream, "%c\n", CNTRL_L) <= 0) {
1693 printf ( catgets(dtsearch_catd, MS_chandel, 124,
1694 "%s Unable to write to output file '%s':\n %s\n") ,
1695 PROGNAME"1663", outfile, strerror(errno));
1699 } /* write_record */
1702 /************************************************/
1706 /************************************************/
1707 /* Translates a field value which is a recognizable month
1708 * name string into a two-char digit string from "01" to "12".
1710 static void mmm_to_digits (struct field_id *fld)
1712 static char valbuf[8];
1713 static char *months = NULL;
1717 months = strdup (catgets(dtsearch_catd, MS_chandel, 125,
1718 "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"));
1720 valbuf[i] = toupper (fld->value[i]);
1721 for (i=0; i<12; i++)
1722 if (strncmp (valbuf, months + (i*3), 3) == 0) {
1723 sprintf (fld->value, "%02d", ++i);
1727 } /* mmm_to_digits() */
1730 /************************************************/
1732 /* process_record */
1734 /************************************************/
1735 /* PROCESS_RECORD - does all processing for the record currently stored
1736 * in the data structure pointed to by record_head. If record_head points
1737 * to NULL, it can safely be assumed that no record is currently awaiting
1740 void process_record (void)
1754 char date_value[256];
1757 static int dotcount = 0;
1759 if (record_head == NULL)
1762 /* Print progress dots and messages */
1764 if (rec_count % RECS_PER_DOT == 0L) {
1766 if (++dotcount % 10 == 0)
1768 if (dotcount % 50 == 0) {
1775 discard_record = FALSE;
1776 meaningless = FALSE;
1778 /* Main loop on every line in record */
1779 record = record_head;
1780 while (record != NULL) {
1781 lvalue = (record->line)? record->line->text_action : 0;
1793 field_current = field_table;
1794 while (field_current != NULL) {
1795 if (field_current->line == record->line) {
1796 /* this field is defined within this line */
1797 memset (value, 0, sizeof(value));
1799 /* If profile pattern str was empty ("") ...*/
1800 if (field_current->text[0] == 0) {
1801 if (field_current->defined_length == EOLN)
1802 strncpy (value, record->text +
1803 (field_current->offset - 1), sizeof(value)-1);
1804 else if (field_current->defined_length == EOW)
1805 /* copy until end of word only */
1807 (!isspace ((record->text +
1808 (field_current->offset - 1))[dummy]))
1809 && dummy < sizeof(value);
1812 value[dummy] = (record->text +
1813 (field_current->offset - 1))[dummy];
1815 i = (field_current->defined_length < sizeof(value))?
1816 field_current->defined_length : sizeof(value)-1;
1818 record->text + (field_current->offset - 1),
1823 /* ...else if profile pattern str was not empty ("xxx") */
1825 pos = strstr (record->text, field_current->text);
1826 if (pos != NULL) { /* pattern found... */
1827 if (field_current->defined_length == EOLN)
1829 pos + (field_current->offset - 1),
1831 else if (field_current->defined_length == EOW)
1832 /* copy until end of word only */
1835 (field_current->offset - 1))[dummy]))
1836 && dummy < sizeof(value);
1839 value[dummy] = (pos +
1840 (field_current->offset - 1))[dummy];
1842 i = (field_current->defined_length<sizeof(value))?
1843 field_current->defined_length : sizeof(value)-1;
1845 pos + (field_current->offset - 1),
1848 } /* end pattern found */
1849 } /* end else where pattern str not empty */
1851 /* strip \n's out of value */
1852 for (i = 0; i < strlen (value); i++)
1853 if (value[i] == '\n')
1855 if (field_current->constant == FALSE) {
1856 strncpy (field_current->value, value,
1857 sizeof(field_current->value));
1858 field_current->value [sizeof(field_current->value)-1] = 0;
1859 field_current->length = strlen (field_current->value);
1860 if (field_current->is_month)
1861 mmm_to_digits (field_current);
1864 field_current = field_current->next;
1865 } /* end while loop on each field within each line */
1867 if (lvalue == DEFAULT)
1868 textflag = textmode;
1869 record = record->next;
1870 } /* end while loop on each record line */
1873 /* Build a handel date_value string from specified fields.
1874 * If 'date' was not specified, uses current date/time.
1875 * If 'date = null' was specified, uses special constant string.
1876 * If value error in specified date fields,
1877 * uses current date/time and prints err msg.
1879 objdate_tmptr = &nowtm; /* default */
1880 if (date_pos_defined && !null_date_specified) {
1882 for (date_current = date_table; date_current != NULL;
1883 date_current = date_current->next) {
1884 if (date_current->field->value[0] != 0) {
1885 strcat (date_value, date_current->field->value);
1888 date_value[0] = 0; /* flags error msg */
1894 * Validate format for date_value of this record.
1895 * Date value format: YYYYMMDDhhmm (exactly 12 digits).
1896 * The area at date_value + 100 is just a little atoi buffer.
1898 if (date_value[0] == 0)
1899 goto BAD_DATE_VALUE;
1900 if (strlen (date_value) != 12)
1901 goto BAD_DATE_VALUE;
1902 for (i = 0; i < 12; i++)
1903 if (!isdigit (date_value[i]))
1904 goto BAD_DATE_VALUE;
1907 strncpy (date_value + 100, date_value, 4);
1908 date_value[104] = 0;
1909 i = atoi (date_value + 100);
1910 if (i < 1900 || i > 5995) /* valid OBJDATE years */
1911 goto BAD_DATE_VALUE;
1913 rectm.tm_year = i - 1900;
1916 strncpy (date_value + 100, date_value + 4, 2);
1917 date_value[102] = 0;
1918 i = atoi (date_value + 100);
1919 if (i < 1 || i > 12)
1920 goto BAD_DATE_VALUE;
1922 rectm.tm_mon = i - 1; /* tm values = 0 - 11 */
1925 strncpy (date_value + 100, date_value + 6, 2);
1926 date_value[102] = 0;
1927 i = atoi (date_value + 100);
1928 if (i < 1 || i > 31)
1929 goto BAD_DATE_VALUE;
1934 strncpy (date_value + 100, date_value + 8, 2);
1935 date_value[102] = 0;
1936 i = atoi (date_value + 100);
1937 if (i < 0 || i > 23)
1938 goto BAD_DATE_VALUE;
1943 strncpy (date_value + 100, date_value + 10, 2);
1944 date_value[102] = 0;
1945 i = atoi (date_value + 100);
1946 if (i < 0 || i > 59)
1947 goto BAD_DATE_VALUE;
1951 objdate_tmptr = &rectm;
1952 goto GOOD_DATE_VALUE;
1955 objdate_tmptr = &nowtm;
1956 printf ( catgets(dtsearch_catd, MS_chandel, 133,
1957 "Warning - '%s' is invalid date specification.\n"
1958 " Using '%s' date for record number %ld that began: %.30s\n") ,
1959 date_value, now_str, rec_count, record_head->text);
1962 } /* end if (date_pos_defined) */
1964 key_current = key_table;
1966 for (dummy = 0; dummy < 80; dummy++)
1967 key_value[dummy] = 0;
1969 while (key_current != NULL) {
1970 if (key_current->field == NULL) {
1971 if (strcmp (key_current->field_id, "time") == 0)
1972 sprintf (key_value, "%ld%06ld", now, key_count);
1973 else /* must be 'count' */
1974 sprintf (key_value, "%09ld", key_count);
1975 } else if (key_current->field->value[0] != 0) {
1976 strcat (key_value, key_current->field->value);
1980 key_current = key_current->next;
1982 if (dummy && warnings) {
1983 printf ( catgets(dtsearch_catd, MS_chandel, 68,
1984 "Warning - fields necessary for key not found.\n"
1985 " discarding record #%ld that began:\n %s\n") ,
1986 rec_count, record_head->text);
1987 } else if (discard && meaningless && warnings) {
1988 printf ( catgets(dtsearch_catd, MS_chandel, 69,
1989 "Warning - record #ld deemed meaningless, discarding...\n"
1990 " record began: %.60s\n") ,
1991 rec_count, record_head->text);
1997 } /*--process_record--*/
2000 /**************************************************************************
2001 NEW_REC - determines if the string sent represents a new record or
2003 **************************************************************************/
2004 int new_rec (char *buffer)
2006 int cant_be = FALSE;
2007 top_rec->comp = top_rec->head;
2008 while (top_rec->comp != NULL) {
2009 if (strcmp (top_rec->comp->text, line_mode) != 0) {
2010 if (top_rec->comp->column_number == ANY) {
2011 if (strstr(buffer,top_rec->comp->text)==NULL)
2015 else if (strncmp (buffer + (top_rec->comp->column_number - 1),
2016 top_rec->comp->text,
2017 strlen (top_rec->comp->text)) != 0)
2020 top_rec->comp = top_rec->comp->next;
2022 if (cant_be == FALSE) {
2028 /**************************************************************************
2029 IS_WHITESPACE - returns true if the string passed contains only
2031 **************************************************************************/
2032 int is_whitespace (char *s)
2035 for (i = 0; i < strlen (s); i++)
2036 if (!isspace (s[i]) || s[i] == 12)
2041 /**************************************************************************
2042 PROCESS_INFILE - processes the input file, 1 record at a time. For each
2043 record, the lines must first be compared against the line id's we have, to
2044 try and identify each line. Then fields are processed against these lines,
2045 and finally fzk processing can begin on any lines that are indicated being
2047 ***************************************************************************/
2048 void process_infile ()
2051 struct line_id *line_current;
2055 time_t startime = 0L;
2059 if (!strcmp (infile, "-"))
2062 if ((instream = fopen (infile, "rt")) == NULL) {
2063 printf ( catgets(dtsearch_catd, MS_chandel, 70,
2064 " Unable to open input file '%s'.\n") , infile);
2071 while (fgets (buffer, sizeof (buffer) - 1, instream) != NULL) {
2072 /* clean any non ASCII characters out of buffer */
2073 delete_whitespace (buffer);
2074 if (feof (instream))
2075 continue; /*-* end of file *-*/
2076 if (del_blanklines && is_whitespace (buffer))
2078 if (new_rec (buffer)) {
2080 if (record_head == NULL) {
2081 record_head = (struct rec *) malloc (sizeof (struct rec));
2082 record = record_head;
2084 record->next = (struct rec *) malloc (sizeof (struct rec));
2085 record = record->next;
2087 record->next = NULL;
2089 record->line_num = line_num;
2090 strcpy (record->text, buffer);
2091 record->line = NULL;
2092 /*-- search list of line_id's for a possible match --*/
2093 line_current = line_table;
2094 while (line_current != NULL) {
2096 line_current->comp = line_current->head;
2097 while (line_current->comp != NULL) {
2098 if (strcmp (line_current->comp->text, line_mode) != 0) {
2099 if (line_current->comp->column_number == ANY) {
2100 if (strstr(buffer,line_current->comp->text)
2105 (line_current->comp->column_number - 1),
2106 line_current->comp->text,
2107 strlen (line_current->comp->text)) != 0)
2109 } else if (line_current->comp->column_number
2112 line_current->comp = line_current->comp->next;
2114 if (cant_be == FALSE) {
2115 /* found a hit, set pointers */
2116 line_current->line = record;
2117 record->line = line_current;
2119 line_current = line_current->next;
2120 } /* while - line_current loop */
2121 } /* if bot_defined */
2130 if (record_head == NULL) {
2131 record_head = (struct rec *) malloc (sizeof (struct rec));
2132 record = record_head;
2134 record->next = (struct rec *) malloc (sizeof (struct rec));
2135 record = record->next;
2137 record->next = NULL;
2139 record->line_num = line_num;
2140 strcpy (record->text, buffer);
2141 record->line = NULL;
2142 /*-- search list of line_id's for a possible match --*/
2143 line_current = line_table;
2144 while (line_current != NULL) {
2146 line_current->comp = line_current->head;
2147 while (line_current->comp != NULL) {
2148 if (strcmp (line_current->comp->text, line_mode) != 0) {
2149 if (line_current->comp->column_number == ANY) {
2150 if (strstr(buffer,line_current->comp->text)==NULL){
2153 } else if (strncmp (buffer +
2154 (line_current->comp->column_number - 1),
2155 line_current->comp->text,
2156 strlen (line_current->comp->text)) != 0) {
2159 } else if (line_current->comp->column_number != line_num) {
2162 line_current->comp = line_current->comp->next;
2164 if (cant_be == FALSE) {
2165 /* found a hit, set pointers */
2166 line_current->line = record;
2167 record->line = line_current;
2169 line_current = line_current->next;
2170 } /* while - line_current loop */
2171 for (rc = 0; rc < 200; rc++)
2173 } /* while - buffer read loop */
2174 /*- check for any leftover records -*/
2176 } /*-- process_infile --*/
2179 /************************************************/
2183 /************************************************/
2184 static void usage_msg (void)
2186 static char *default_text =
2187 "\nUSAGE: %s [options] <profile> <infile> [<outfile>]\n"
2188 " -m Turn off all but error messages.\n"
2189 " -wN Change target screen width to <N>.\n"
2190 " -oo Preapprove overwrite of outfile.\n"
2191 " -oa Preapprove append to outfile.\n"
2192 " <profile> Input file containing profile of records\n"
2193 " to be processed.\n"
2194 " <infile> Input file containing actual records.\n"
2195 " <outfile> Output file name, .fzk format (%s).\n\n";
2199 printf (catgets (dtsearch_catd, MS_chandel, 71, default_text),
2200 aa_argv0, EXT_FZKEY);
2205 /************************************************/
2207 /* user_arg_processor */
2209 /************************************************/
2210 /* Process any user arguments passed thru the command line parameters. */
2211 static void user_arg_processor (int argc, char **argv)
2213 char *cptr, *argptr;
2220 while (--argc > 0 && (*++argv)[0] == '-') {
2222 argptr[1] = tolower (argptr[1]);
2223 switch (argptr[1]) {
2226 if ((screen_width = atoi (argptr + 2)) == 0) {
2227 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 72,
2228 "Invalid screen width specified.\n") );
2238 argptr[2] = tolower (argptr[2]);
2239 if (argptr[2] == 'o')
2240 strcpy (outmode, "w");
2241 else if (argptr[2] == 'a')
2242 strcpy (outmode, "a");
2244 printf ( catgets(dtsearch_catd, MS_chandel, 75,
2245 "'%s' is invalid output mode.\n") , argptr);
2248 outmode_specified = TRUE;
2252 printf ( catgets(dtsearch_catd, MS_chandel, 76,
2253 "Unknown command line argument '%s'.\n") , argptr);
2259 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 77,
2260 "Missing required profile-file name.\n") );
2266 strcpy(profile,argv[0]);
2269 profile = (char *) malloc (sizeof (char) * (strlen (argv[0])) +10);
2270 strcpy (profile, argv[0]);
2271 if (strchr (profile, '.') == NULL)
2272 strcat (profile, EXT_HANDEL);
2276 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 78,
2277 "Missing required input-file name.\n") );
2282 /******** strcpy(infile,argv[1]); ********/
2287 strcpy(outfile,infile);
2288 if (strchr(outfile,'.')!=NULL)
2289 strcpy(strchr(outfile,'.'), EXT_FZKEY);
2291 strcat(outfile,EXT_FZKEY);
2293 if (strcmp (infile, "-") == 0) {
2294 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 79, "Error - using "
2295 "stdin as input, output filename is required!\n") );
2298 outfile = (char *) malloc (sizeof (char) * (strlen (infile) + 10));
2299 strcpy (outfile, infile);
2300 pos = strrchr (outfile, (int) '.');
2302 strcat (outfile, EXT_FZKEY);
2317 /* strcpy(outfile,argv[2]); */
2320 /*-- Sanity checks --*/
2321 /*-- duplicates? --*/
2322 if (strcmp (infile, profile) == 0) {
2323 printf ( catgets(dtsearch_catd, MS_chandel, 80,
2324 "Profile file and input file have same name:'%s'.\n") ,
2328 if (strcmp (infile, outfile) == 0 && strcmp (infile, "-")) {
2329 printf ( catgets(dtsearch_catd, MS_chandel, 81,
2330 "Input file and output file have same name:'%s'.\n") ,
2334 if (strcmp (profile, outfile) == 0) {
2335 printf ( catgets(dtsearch_catd, MS_chandel, 82,
2336 "Profile file and output file have same name:'%s'.\n") ,
2342 printf ( catgets(dtsearch_catd, MS_chandel, 83,
2343 " Profile file: %s\n") , profile);
2344 if (strcmp (infile, "-") == 0)
2345 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 84,
2346 " Input file: stdin\n") );
2348 printf ( catgets(dtsearch_catd, MS_chandel, 85,
2349 " Input file: %s\n") , infile);
2350 if (strcmp (outfile, "-") == 0)
2351 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 86,
2352 " Output file: stdout\n") );
2354 printf ( catgets(dtsearch_catd, MS_chandel, 87,
2355 " Output file: %s\n") , outfile);
2357 } /*--user_args_processor--*/
2359 /****************************************************************************
2360 FLAG_SHUTDOWN - signal handler - to allow for graceful exiting
2361 ****************************************************************************/
2362 static void flag_shutdown (int sig)
2364 shutdown_now = TRUE;
2367 /****************************************************************************
2368 MAIN - Body of Handel. Checks user parameters, processes the profile
2369 file, and then goes into the main loop, running each record from the input
2370 file against the profile and thru the text processor.
2371 *****************************************************************************/
2372 int main (int argc, char **argv)
2376 /*-- Initialization --*/
2378 setlocale (LC_ALL, "");
2379 dtsearch_catd = catopen (FNAME_DTSRCAT, 0);
2380 printf ( catgets(dtsearch_catd, MS_chandel, 88,
2381 "%s. %s %s Text Filter.\n") ,
2382 aa_argv0, PRODNAME, DtSrVERSION);
2385 memcpy (&nowtm, localtime(&now), sizeof(struct tm));
2386 strftime (now_str, sizeof(now_str), "%y/%m/%d~%H:%M", &nowtm);
2387 memset (&rectm, 0, sizeof(struct tm));
2389 /* check user arguments */
2390 user_arg_processor (argc, argv);
2397 if (warnings && !bad_profile) {
2398 signal (SIGINT, flag_shutdown);
2399 signal (SIGTERM, flag_shutdown);
2401 printf ( catgets(dtsearch_catd, MS_chandel, 89,
2402 "\nInterrupt with CTRL-C to exit gracefully "
2403 "at record boundary.\n Each dot is %ld records...\n"),
2405 process_infile (); /* process the input file */
2406 oops = fclose (outstream);
2409 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 90,
2410 "\nError closing output file - disk full?\n") );
2415 printf ( "%s", catgets(dtsearch_catd, MS_chandel, 91,
2416 "Quitting due to errors in profile file.\n") );
2419 printf ( catgets(dtsearch_catd, MS_chandel, 92,
2420 "\n%s: Normal completion. %ld records processed. Exit code = 0.\n"),
2421 aa_argv0, rec_count);
2424 /*************** DTSRHAN.C ****************/