blob: d1dee3acdf23d0f8ed5cc429b51f927f51235968 [file] [log] [blame]
alaffinf5589902000-09-21 21:35:06 +00001/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080020 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
alaffinf5589902000-09-21 21:35:06 +000022 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31 *
32 */
33/* $Id: reporter.c,v 1.1 2000/09/21 21:35:06 alaffin Exp $ */
34/*
35 * This is the report generator half of the scanner program.
36 */
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <time.h>
42#include <unistd.h>
alaffinf5589902000-09-21 21:35:06 +000043#include "reporter.h"
44#include "symbol.h"
45#include "tag_report.h"
46#include "splitstr.h"
47
48/************************************************************************
49 * Report Generation *
50 ************************************************************************/
51
Wanlong Gao354ebb42012-12-07 10:10:04 +080052static int scanner_reporter(SYM);
53static int iscanner_reporter(SYM);
54static int scanner_test_end(SYM, SYM, SYM);
55static int iscanner_test_end(SYM, SYM, SYM);
alaffinf5589902000-09-21 21:35:06 +000056
Wanlong Gao354ebb42012-12-07 10:10:04 +080057static int (*reporter_func) (SYM) = scanner_reporter;
58static int (*test_end_func) (SYM, SYM, SYM) = scanner_test_end;
alaffinf5589902000-09-21 21:35:06 +000059
60/*
61 * Do the report generation.
62 *
63 * A problem: I really need multiple cursors. I'd rather not look into
64 * the depths of the current symbol table implimentation (there are the
65 * cursors there that I could use) so that a different (faster!) symbol
66 * table can be used in the future.
Garrett Cooper1e6f5a62010-12-19 09:58:10 -080067 *
alaffinf5589902000-09-21 21:35:06 +000068 * I could get a key (tag), get it's sub-keys (TCIDs), then get the key
69 * again to reset to the top level, _then_ get the next key. That would
70 * be very inefficient.
Garrett Cooper1e6f5a62010-12-19 09:58:10 -080071 *
alaffinf5589902000-09-21 21:35:06 +000072 * The solution I chose is to extract all tags into a list (char array),
73 * then go thru that list with the cursor free for other levels to use.
74 *
75 * (1) make a list (2d char array) of all Tags
76 * (2) search for the first tag that has a "stime" record, and use that as
77 * the date (MMDDYY) that the tests were run.
78 * (3) print the report header
Garrett Cooper1e6f5a62010-12-19 09:58:10 -080079 * (4) go thru all tags and report each as described at the beginning of
alaffinf5589902000-09-21 21:35:06 +000080 * this file
81 */
Wanlong Gao354ebb42012-12-07 10:10:04 +080082static int scanner_reporter(tags)
83SYM tags;
alaffinf5589902000-09-21 21:35:06 +000084{
Wanlong Gao354ebb42012-12-07 10:10:04 +080085 DBT Key, Data;
86 SYM Tag, Keys;
alaffinf5589902000-09-21 21:35:06 +000087
Wanlong Gao354ebb42012-12-07 10:10:04 +080088 time_t clock;
89 struct tm *tm;
alaffinf5589902000-09-21 21:35:06 +000090
Wanlong Gao354ebb42012-12-07 10:10:04 +080091 /* a list of tags, a count of the number of tags allocated to the list,
92 and a pointer to go thru the list */
93 char **taglist, **tl;
94 int ntags;
95 int tagcount; /* how many tags used */
alaffinf5589902000-09-21 21:35:06 +000096
Wanlong Gao354ebb42012-12-07 10:10:04 +080097 char key_get[KEYSIZE];
98 char *info;
alaffinf5589902000-09-21 21:35:06 +000099
Wanlong Gao354ebb42012-12-07 10:10:04 +0800100 /*
101 * extract tag names from data
102 */
103 ntags = NTAGS_START;
104 taglist = (char **)malloc(sizeof(char *) * ntags);
105 tagcount = 0;
alaffinf5589902000-09-21 21:35:06 +0000106
Wanlong Gao354ebb42012-12-07 10:10:04 +0800107 tl = taglist;
108 sym_seq(tags, &Key, &Data, R_FIRST);
109 do {
110 if (tagcount == ntags) {
111 /* exceeded tag array size -- realloc */
112 ntags += NTAGS_START;
113 taglist =
114 (char **)realloc(taglist, sizeof(char *) * ntags);
115 tl = taglist + tagcount;
116 }
alaffinf5589902000-09-21 21:35:06 +0000117
Wanlong Gao354ebb42012-12-07 10:10:04 +0800118 *tl++ = Key.data;
119 tagcount++;
120 } while (sym_seq(tags, &Key, &Data, R_NEXT) == 0);
alaffinf5589902000-09-21 21:35:06 +0000121
Wanlong Gao354ebb42012-12-07 10:10:04 +0800122 if (tagcount == ntags) {
123 /* exceeded tag array size -- realloc */
124 ntags += NTAGS_START;
125 taglist = (char **)realloc(taglist, sizeof(char *) * ntags);
126 tl = taglist + tagcount;
127 }
alaffinf5589902000-09-21 21:35:06 +0000128
Wanlong Gao354ebb42012-12-07 10:10:04 +0800129 *tl++ = NULL;
130 ntags = tagcount;
131 /* Retrieve one "stime" to get the date. */
132 for (tl = taglist; *tl != NULL; tl++) {
133 strcpy(key_get, *tl);
134 strcat(key_get, ",_keys,stime");
135 if ((info = (char *)sym_get(tags, key_get)) != NULL) {
136 clock = atoi(info);
137 tm = gmtime(&clock);
138 strftime(key_get, KEYSIZE, "%x", tm);
139 sym_put(tags, strdup("_RTS,date"), strdup(key_get), 0);
140 break;
141 }
142 }
alaffinf5589902000-09-21 21:35:06 +0000143
Wanlong Gao354ebb42012-12-07 10:10:04 +0800144 print_header(tags);
alaffinf5589902000-09-21 21:35:06 +0000145
Wanlong Gao354ebb42012-12-07 10:10:04 +0800146 /*
147 * The way that I am using 'Keys' and 'Tag' makes assumptions about the
148 * internals of the sym_* data structure.
149 */
150 /* dump 'em all */
151 for (tl = taglist; *tl != NULL; tl++) {
152 if (!strcmp(*tl, "_RTS"))
153 continue;
alaffinf5589902000-09-21 21:35:06 +0000154
Wanlong Gao354ebb42012-12-07 10:10:04 +0800155 strcpy(key_get, *tl);
156 strcat(key_get, ",_keys");
157 if ((Keys = sym_get(tags, key_get)) == NULL) {
158 return 0;
159 }
alaffinf5589902000-09-21 21:35:06 +0000160
Wanlong Gao354ebb42012-12-07 10:10:04 +0800161 strcpy(key_get, *tl);
162 if ((Tag = sym_get(tags, key_get)) != NULL) {
163 tag_report(NULL, Tag, Keys);
164 }
165 }
166 free(taglist);
alaffinf5589902000-09-21 21:35:06 +0000167
Wanlong Gao354ebb42012-12-07 10:10:04 +0800168 return 0;
alaffinf5589902000-09-21 21:35:06 +0000169}
170
171/*
172 * End-Of-Test seen, insert this tag into the global tag data.
173 * (1) Get the test's tag
174 * (2) insert the keywords in the "_keys" tag
175 * (3) insert it into the global data under this tag, replacing any existing
176 * data.
177 *
Garrett Cooper1e6f5a62010-12-19 09:58:10 -0800178 * a "feature" of the key implimentation: I can insert a key tree
alaffinf5589902000-09-21 21:35:06 +0000179 * under another key tree with almost zero brainwork because a SYM
180 * is what the DATA area points to.
181 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800182static int scanner_test_end(alltags, ctag, keys)
183SYM alltags, ctag, keys;
alaffinf5589902000-09-21 21:35:06 +0000184{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800185 static int notag = 0; /* counter for records with no tag (error) */
186 char tagname[KEYSIZE]; /* used when creating name (see above) */
187 char *tag; /* tag name to look things up in */
188 char *status; /* initiation status of old tag */
189 SYM rm; /* pointer to old tag -- to remove it */
alaffinf5589902000-09-21 21:35:06 +0000190
Wanlong Gao354ebb42012-12-07 10:10:04 +0800191 if (alltags == NULL || keys == NULL || ctag == NULL)
192 return -1; /* for really messed up test output */
alaffinf5589902000-09-21 21:35:06 +0000193
Wanlong Gao354ebb42012-12-07 10:10:04 +0800194 /* insert keys into tag */
195 sym_put(ctag, "_keys", (void *)keys, 0);
alaffinf5589902000-09-21 21:35:06 +0000196
Wanlong Gao354ebb42012-12-07 10:10:04 +0800197 /* get the tag, or build a new one */
198 if ((tag = (char *)sym_get(keys, "tag")) == NULL) {
199 /* this is an "impossible" situation: test_output checks for this
200 * and creates a dummy tag. */
201 sprintf(tagname, "no_tag_%d", notag++);
202 fprintf(stderr, "No TAG key! Using %s\n", tagname);
203 sym_put(keys, "tag", strdup(tagname), 0);
204 tag = strdup(tagname);
205 }
alaffinf5589902000-09-21 21:35:06 +0000206
Wanlong Gao354ebb42012-12-07 10:10:04 +0800207 /*
208 * Special case: duplicate tag that has an initiation_status failure
209 * is thrown away.
210 */
211 if ((rm = (SYM) sym_get(alltags, tag)) != NULL) {
212 if ((status =
213 (char *)sym_get(keys, "initiation_status")) != NULL) {
214 if (strcmp(status, "ok")) {
215 /* do not take new data. remove new data */
216 sym_rm(ctag, RM_KEY | RM_DATA);
217 return 1;
218 } else {
219 /* remove old data in alltags */
220 sym_rm(rm, RM_KEY | RM_DATA);
221 }
222 } else {
223 /* new data does not have an initiation_status -- throw it away */
224 sym_rm(ctag, RM_KEY | RM_DATA);
225 return 1;
226 }
227 }
alaffinf5589902000-09-21 21:35:06 +0000228
Wanlong Gao354ebb42012-12-07 10:10:04 +0800229 /* put new data.. replaces existing "tag" key if it exists
230 * (it's data should have been removed above) */
231 sym_put(alltags, tag, ctag, PUT_REPLACE);
alaffinf5589902000-09-21 21:35:06 +0000232
Wanlong Gao354ebb42012-12-07 10:10:04 +0800233 return 0;
alaffinf5589902000-09-21 21:35:06 +0000234}
235
Wanlong Gao354ebb42012-12-07 10:10:04 +0800236static int iscanner_reporter(tags)
237SYM tags;
alaffinf5589902000-09-21 21:35:06 +0000238{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800239 return 0;
alaffinf5589902000-09-21 21:35:06 +0000240}
241
Wanlong Gao354ebb42012-12-07 10:10:04 +0800242static int iscanner_test_end(alltags, ctag, keys)
243SYM alltags, ctag, keys;
alaffinf5589902000-09-21 21:35:06 +0000244{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800245 if (alltags == NULL || keys == NULL || ctag == NULL)
246 return -1; /* for really messed up test output */
alaffinf5589902000-09-21 21:35:06 +0000247
Wanlong Gao354ebb42012-12-07 10:10:04 +0800248 /* insert keys into tag */
249 sym_put(ctag, "_keys", (void *)keys, 0);
alaffinf5589902000-09-21 21:35:06 +0000250
Wanlong Gao354ebb42012-12-07 10:10:04 +0800251 return tag_report(alltags, ctag, keys);
alaffinf5589902000-09-21 21:35:06 +0000252}
253
Wanlong Gao354ebb42012-12-07 10:10:04 +0800254int reporter(SYM s)
alaffinf5589902000-09-21 21:35:06 +0000255{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800256 return reporter_func(s);
alaffinf5589902000-09-21 21:35:06 +0000257}
258
Wanlong Gao354ebb42012-12-07 10:10:04 +0800259int test_end(SYM a, SYM b, SYM c)
alaffinf5589902000-09-21 21:35:06 +0000260{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800261 return test_end_func(a, b, c);
alaffinf5589902000-09-21 21:35:06 +0000262}
263
264void set_scanner(void)
265{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800266 reporter_func = scanner_reporter;
267 test_end_func = scanner_test_end;
alaffinf5589902000-09-21 21:35:06 +0000268}
269
270void set_iscanner(void)
271{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800272 reporter_func = iscanner_reporter;
273 test_end_func = iscanner_test_end;
Garrett Cooper6ea8c5b2011-02-23 00:14:59 -0800274}