1 saw 1.1 /*-----------------------------------------------------------------------------
2 * Copyright (c) 1993 Southeastern Universities Research Association,
3 * Continuous Electron Beam Accelerator Facility
4 *
5 * This software was developed under a United States Government license
6 * described in the NOTICE file included as part of this distribution.
7 *
8 * Stephen A. Wood, 12000 Jefferson Ave., Newport News, VA 23606
9 * Email: saw@cebaf.gov Tel: (804) 249-7367 Fax: (804) 249-5800
10 *-----------------------------------------------------------------------------
11 *
12 * Description:
13 * Book tests, execute or operate on tests.
14 *
15 * Author: Stephen Wood, CEBAF Hall C
16 *
17 * Revision History:
18 * $Log: thTest.c,v $
|
19 saw 1.2 * Revision 1.1 1998/12/07 22:11:13 saw
20 * Initial setup
21 *
|
22 saw 1.1 * Revision 1.7 1996/07/31 20:30:17 saw
23 * (SAW) List line number of booking errors. Add code in support of groups.
24 *
25 * Revision 1.6 1995/04/10 15:42:35 saw
26 * Handle ctp file registration (#int, #real, ...)
27 * No defined test blocks is not an error in thTestExecute
28 *
29 * Revision 1.5 1995/01/09 15:55:25 saw
30 * On fprintf, indicate block type and well as name.
31 *
32 * Revision 1.4 1994/08/31 13:05:02 saw
33 * Add code for WALK_CLEAR_FLAGS to thWalkTree
34 *
35 * Revision 1.3 1994/06/03 18:51:22 saw
36 * Replace stderr with STDERR
37 *
38 * Revision 1.2 1993/05/11 17:56:37 saw
39 * Fix header
40 *
41 */
42
43 saw 1.1 /*
44 Need to add means of accessing scalers. Two ways. 1 Register the
45 scaler array, 2 make a call with the name and a pointer to an array.
46 */
47
48 /*An argument is a variable name, an array, or a number. Numbers are not
49 allowed for test result. Arrays start at 0 if []'s are used and start
50 at 1 if ()'s are used. Arrays may only be used for test results if they
51 are already registered by the analyzer. (May add option to declare them
52 in the test package.)*/
53
54 #include <stdio.h>
55 #include <string.h>
56 #include <math.h>
57 #include "daVar.h"
58 #include "th.h"
59 #include "thInternal.h"
60 #include "thUtils.h"
61 #include "thTestParse.h"
62 #include "cfortran.h"
63 #define max(a,b) (a<b ? b : a)
64 saw 1.1 #define min(a,b) (a>b ? b : a)
65
66 #define MAXLINELENGTH 512
67
68 struct thTBOpaque {
69 CODEPTR code;
70 CODEPTR end;
71 daVarStructList *vlisthead;
72 };
73 typedef struct thTBOpaque thTBOpaque;
74
75 struct thTBlockList {
76 struct thTBlockList *next;
77 char *blockname; /* Block name with out the "block.test" */
78 daVarStruct *var; /* Pointer to variable that describes block */
79 /* Block execution counter, pointer to list of test names and results */
80 };
81 typedef struct thTBlockList thTBlockList;
82
83 thTBlockList *thTBlockListP = NULL;
84
85 saw 1.1 /* End of newstuff */
86
87 thStatus thBookTests(daVarStruct *var)
88 {
89 char *lines,*eol;
90 int line_count;
91 thTBOpaque *opqptr;
92 CODEPTR codehead, codenext, codelimit;
93
94 /* Need to zero out the count. Make sure variable for count is
95 created */
96
97 /* printf("Booking tests %s\n",var->name);*/
98
99 if(var->opaque == 0) {
100 opqptr = (thTBOpaque *) malloc(sizeof(thTBOpaque));
101 var->opaque = (void *) opqptr;
102 codehead = codenext = (CODEPTR) malloc(sizeof(CODE)*CODESTARTSIZE);
103 codelimit = codehead + CODESTARTSIZE;
104 opqptr->vlisthead = 0;
105 } else {
106 saw 1.1 daVarStructList *next,*this;
107
108 opqptr = (thTBOpaque *) var->opaque;
109 codehead = codenext = opqptr->code;
110 codelimit = opqptr->end;
111 this = opqptr->vlisthead;
112 while(this) {
113 next = this->next;
114 free(this);
115 this = next;
116 }
117 opqptr->vlisthead = 0;
118 }
119
120 lines = var->title;
121 line_count = 0;
122 while(*lines){
123 char *lcopy;
124
125 line_count++;
126 eol = strchr(lines,'\n');
127 saw 1.1 if(!eol) {
128 fprintf(STDERR,"L %d: Last line of test block %s has no newline\n"
129 ,line_count,var->name);
130 break;
131 }
132 /* {
133 *eol = 0;
134 printf("L %d:%s\n",line_count,lines);
135 *eol = '\n';
136 }*/
137
138 /* printf("Next char = %d\n",*(eol+1));*/
139 if(*(eol+1)=='\0'){ /* This is the last line */
140 if(strcasestr(lines,ENDSTR) == 0) {
141 fprintf(STDERR,"L %d: Last line of test block %s is not an END\n"
142 ,line_count,var->name);
143 /* fprintf(STDERR,"%s",var->title);*/
144 }
145 break;
146 }
147 if(line_count == 1)
148 saw 1.1 if(strcasestr(lines,BEGINSTR) != 0){
149 /* printf("Is a begin\n");*/
150 lines = eol + 1;
151 continue;
152 } else
153 fprintf(STDERR,"First line of test block %s is not a BEGIN\n",var->name);
154 /* Ready to book the line, Add continuation lines later */
155 lcopy = (char *) malloc(eol-lines+1);
156 strncpy(lcopy,lines,(eol-lines));
157 *(lcopy + (eol-lines)) = '\0';
158 /* printf("Passing|%s|\n",lcopy);*/
159 if(!thSpecial(lcopy,TESTSTR)) {
160 if(!thCleanLine(lcopy)){
161 if(thBookaTest(lcopy,&codehead,&codenext,&codelimit,0,
162 &(opqptr->vlisthead))==S_SUCCESS) {
163 /* {
164 daVarStructList *walk;
165 walk = opqptr->vlisthead;
166 while(walk){
167 walk = walk->next;
168 }*/
169 saw 1.1 /* {
170 CODEPTR code;
171 for(code=codehead;code < codenext; code++)
172 printf(" %x\n",*code);
173 }*/
174 } else {
175 fprintf(STDERR,"(%s): Test booking error in line %d\n",var->name,line_count);
176 }
177 }
178 }
179 free(lcopy);
180 lines = eol+1;
181 }
182
183 { /* */
184 CODEPTR src,dst;
185 dst = opqptr->code = (CODEPTR) malloc(sizeof(CODE)*(codenext-codehead));
186 src = codehead;
187 while(src < codenext) *dst++ = *src++;
188 opqptr->end = dst;
189 free(codehead);
190 saw 1.1 /* printf("%x %x\n",opqptr->code,opqptr->end);*/
191 }
192 /* Update internal table of test blocks. */
193 {
194 thTBlockList *thisblock,*nextblock,**lastblockp;
195 nextblock = thTBlockListP;
196 lastblockp = &thTBlockListP;
197 thisblock = thTBlockListP;
198 while(thisblock){
199 if((strcmp(thisblock->var->name,var->name)) == 0){
200 /* Replacing a block with a new definition */
201 fprintf(STDERR,"Replacing %s with new definition\n",var->name);
202 if(thisblock->var != var){
203 fprintf(STDERR,"ERR: Same name, different var pointer\n");
204 }
205 break;
206 }
207 lastblockp = &thisblock->next;
208 thisblock = thisblock->next;
209 }
210 if(!thisblock){ /* Create entry for New block */
211 saw 1.1 char *s;
212 int i;
213 *lastblockp = thisblock = (thTBlockList *) malloc(sizeof(thTBlockList));
214 thisblock->var = var;
215 thisblock->next = (thTBlockList *) NULL;
216 /* Get the name without the block.test on it */
217 s = var->name; /* If name doesn't fit pattern, use whole */
218 if(strcasestr(var->name,BLOCKSTR)==var->name){
219 i = strlen(BLOCKSTR) + 1;
220 if(strcasestr((var->name + i),TESTSTR)==(var->name + i)){
221 i += strlen(TESTSTR);
222 if(*(var->name + i) == '.'){
223 s += i + 1;
224 }
225 }
226 }
227 thisblock->blockname = (char *) malloc(strlen(s) + 1);
228 strcpy(thisblock->blockname,s);
229 }
230 }
231 return(S_SUCCESS);
232 saw 1.1 }
233
234 thStatus thClearTestFlagsV(daVarStruct *var)
235 {
236 thTBOpaque *opqptr;
237 thStatus status;
238 daVarStructList *vlist;
239
240 opqptr = (thTBOpaque *) var->opaque;
241 vlist = opqptr->vlisthead;
242 while(vlist){
243 daVarStruct *varp;
244 varp = vlist->varp;
245 if(varp->type == DAVARINT) { /* Only clear when flag is integer */
246 int i;
247 for(i=0;i<varp->size;i++)
248 ((DAINT *) varp->varptr)[i] = 0;
249 }
250 vlist = vlist->next;
251 }
252 }
253 saw 1.1 thStatus thClearTestScalersV(daVarStruct *var)
254 {
255 thTBOpaque *opqptr;
256 thStatus status;
257 daVarStructList *vlist;
258
259 opqptr = (thTBOpaque *) var->opaque;
260 vlist = opqptr->vlisthead;
261 while(vlist){
262 daVarStruct *varp;
263 varp = vlist->varp;
264 if(varp->type == DAVARINT) { /* Only clear when flag is integer */
265 int i;
266 for(i=0;i<varp->size;i++)
267 ((DAINT *) varp->opaque)[i] = 0;
268 }
269 vlist = vlist->next;
270 }
271 }
272 thStatus thIncTestScalersV(daVarStruct *var)
273 {
274 saw 1.1 thTBOpaque *opqptr;
275 thStatus status;
276 daVarStructList *vlist;
277
278 opqptr = (thTBOpaque *) var->opaque;
279 vlist = opqptr->vlisthead;
280 while(vlist){
281 daVarStruct *varp;
282 varp = vlist->varp;
283 if(varp->type == DAVARINT) { /* Only clear when flag is integer */
284 int i;
285 for(i=0;i<varp->size;i++)
286 ((DAINT *) varp->opaque)[i] += (((DAINT *) varp->varptr)[i] != 0);
287
288 }
289 vlist = vlist->next;
290 }
291 }
292 thStatus thExecuteTestsV(daVarStruct *var)
293 {
294 thTBOpaque *opqptr;
295 saw 1.1 thStatus status;
296
297 CODEPTR codehead, codenext, codelimit;
298
299 opqptr = (thTBOpaque *) var->opaque;
300 status = thExecuteCode(var->name,opqptr->code,opqptr->end);
301 if(status == S_SUCCESS)
302 (*((DAINT *)var->varptr))++; /* Increment block counter */
303 return(status);
304 }
305
306 thStatus thWalkTree(char *block_name, WALKOP walkop)
307 {
308 thTBlockList *thisblock,*nextblock,**lastblockp;
309 int *result;
310 thTBOpaque *opqptr;
311
312 if(block_name)
313 if(*block_name=='\0')
314 block_name = 0;
315 else
316 saw 1.1 lastblockp = &thTBlockListP; /* If no block specified, do default group */
317
318 if(thTBlockListP == 0){
319 return(S_SUCCESS); /* No tests defined */
320 } else {
321 thisblock = thTBlockListP;
322 while(thisblock){
323 if(block_name)
324 if(strcasecmp(block_name,thisblock->blockname)!=0) {
325 lastblockp = &thisblock->next;
326 thisblock = thisblock->next;
327 continue;
328 }
329 if(walkop == WALK_DISPLAY)
330 fprintf(STDERR," /%s\n",thisblock->blockname);
331 else {
332 opqptr = thisblock->var->opaque;
333 if(walkop == WALK_EXECUTE) {
334 thExecuteCode(thisblock->var->name,opqptr->code,opqptr->end);
335 (*((DAINT *)thisblock->var->varptr))++; /* Increment block counter */
336 } else if(walkop == WALK_CLEAR_SCALERS
337 saw 1.1 || walkop == WALK_INCREMENT_SCALERS
338 || walkop == WALK_CLEAR_FLAGS) {
339 daVarStructList *vlist;
340 vlist = opqptr->vlisthead;
341 while(vlist) {
342 daVarStruct *varp;
343 varp = vlist->varp;
344 if(varp->type == DAVARINT) {
345 int i;
346 if(walkop == WALK_CLEAR_SCALERS) {
347 if(varp->opaque)
348 for(i=0;i<varp->size;i++)
349 ((DAINT *) varp->opaque)[i] = 0;
350 } else if(walkop == WALK_INCREMENT_SCALERS) {
351 if(varp->opaque)
352 for(i=0;i<varp->size;i++)
353 ((DAINT *) varp->opaque)[i]
354 += (((DAINT *) varp->varptr)[i] != 0);
355 } else { /* WALK_CLEAR_FLAGS */
356 if(varp->type == DAVARINT) {
357 for(i=0;i<varp->size;i++)
358 saw 1.1 ((DAINT *) varp->varptr)[i] = 0;
359 }
360 }
361 }
362 vlist = vlist->next;
363 }
364 } else
365 fprintf(STDERR,"Unimplimented WALK code\n");
366 }
367 nextblock = thisblock->next;
368 if(block_name) {
369 if(strcasecmp(block_name,thisblock->blockname)==0) {
370 if(walkop == WALK_REMOVE){
371 *lastblockp = nextblock;
372 free(thisblock);
373 }
374 return(S_SUCCESS);
375 }
376 } else if (walkop == WALK_REMOVE){
377 free(thisblock);
378 }
379 saw 1.1 thisblock = nextblock;
380 }
381 if(block_name) {
382 fprintf(STDERR,"Test block %s not found\n",block_name);
383 return(S_FAILURE);
384 }
385 if(walkop == WALK_REMOVE)
386 thTBlockListP = (thTBlockList *) NULL;
387 }
388 return(S_SUCCESS);
389 }
390
391 /* Fortran callable versions of the various test walk routines */
392
393 #ifdef NOF77extname
|
394 saw 1.2 int thtstexe()
|
395 saw 1.1 #else
|
396 saw 1.2 int thtstexe_()
|
397 saw 1.1 #endif
398 {
|
399 saw 1.2 int A0;
|
400 saw 1.1 A0 = thWalkTree(0,WALK_EXECUTE);
401 return A0;
402 }
403 #ifdef NOF77extname
|
404 saw 1.2 int thtstexeb
|
405 saw 1.1 #else
|
406 saw 1.2 int thtstexeb_
|
407 saw 1.1 #endif
408 (char *A1,unsigned C1)
409 {
|
410 saw 1.2 int A0;
|
411 saw 1.1 char *B1;
412 A0 = thWalkTree((!*(int *)A1)?0:memchr(A1,'\0',C1)?A1:
413 (memcpy(B1=malloc(C1+1),A1,C1),B1[C1]='\0'
414 ,kill_trailing(B1,' ')),WALK_EXECUTE);
415 if(B1) free(B1);
416 return A0;
417 }
418 #ifdef NOF77extname
|
419 saw 1.2 int thtstdis()
|
420 saw 1.1 #else
|
421 saw 1.2 int thtstdis_()
|
422 saw 1.1 #endif
423 {
|
424 saw 1.2 int A0;
|
425 saw 1.1 A0 = thWalkTree(0,WALK_DISPLAY);
426 return A0;
427 }
428 #ifdef NOF77extname
|
429 saw 1.2 int thtstdisb
|
430 saw 1.1 #else
|
431 saw 1.2 int thtstdisb_
|
432 saw 1.1 #endif
433 (char *A1,unsigned C1)
434 {
|
435 saw 1.2 int A0;
|
436 saw 1.1 char *B1;
437 A0 = thWalkTree((!*(int *)A1)?0:memchr(A1,'\0',C1)?A1:
438 (memcpy(B1=malloc(C1+1),A1,C1),B1[C1]='\0'
439 ,kill_trailing(B1,' ')),WALK_DISPLAY);
440 if(B1) free(B1);
441 return A0;
442 }
443 #ifdef NOF77extname
|
444 saw 1.2 int thtstclr()
|
445 saw 1.1 #else
|
446 saw 1.2 int thtstclr_()
|
447 saw 1.1 #endif
448 {
|
449 saw 1.2 int A0;
|
450 saw 1.1 A0 = thWalkTree(0,WALK_CLEAR_FLAGS);
451 return A0;
452 }
453 #ifdef NOF77extname
|
454 saw 1.2 int thtstclrb
|
455 saw 1.1 #else
|
456 saw 1.2 int thtstclrb_
|
457 saw 1.1 #endif
458 (char *A1,unsigned C1)
459 {
|
460 saw 1.2 int A0;
|
461 saw 1.1 char *B1;
462 A0 = thWalkTree((!*(int *)A1)?0:memchr(A1,'\0',C1)?A1:
463 (memcpy(B1=malloc(C1+1),A1,C1),B1[C1]='\0'
464 ,kill_trailing(B1,' ')),WALK_CLEAR_FLAGS);
465 if(B1) free(B1);
466 return A0;
467 }
468 #ifdef NOF77extname
|
469 saw 1.2 int thtstins()
|
470 saw 1.1 #else
|
471 saw 1.2 int thtstins_()
|
472 saw 1.1 #endif
473 {
|
474 saw 1.2 int A0;
|
475 saw 1.1 A0 = thWalkTree(0,WALK_INCREMENT_SCALERS);
476 return A0;
477 }
478 #ifdef NOF77extname
|
479 saw 1.2 int thtstinsb
|
480 saw 1.1 #else
|
481 saw 1.2 int thtstinsb_
|
482 saw 1.1 #endif
483 (char *A1,unsigned C1)
484 {
|
485 saw 1.2 int A0;
|
486 saw 1.1 char *B1;
487 A0 = thWalkTree((!*(int *)A1)?0:memchr(A1,'\0',C1)?A1:
488 (memcpy(B1=malloc(C1+1),A1,C1),B1[C1]='\0'
489 ,kill_trailing(B1,' ')),WALK_INCREMENT_SCALERS);
490 if(B1) free(B1);
491 return A0;
492 }
493 #ifdef NOF77extname
|
494 saw 1.2 int thtstcls()
|
495 saw 1.1 #else
|
496 saw 1.2 int thtstcls_()
|
497 saw 1.1 #endif
498 {
|
499 saw 1.2 int A0;
|
500 saw 1.1 A0 = thWalkTree(0,WALK_CLEAR_SCALERS);
501 return A0;
502 }
503 #ifdef NOF77extname
|
504 saw 1.2 int thtstclsb
|
505 saw 1.1 #else
|
506 saw 1.2 int thtstclsb_
|
507 saw 1.1 #endif
508 (char *A1,unsigned C1)
509 {
|
510 saw 1.2 int A0;
|
511 saw 1.1 char *B1;
512 A0 = thWalkTree((!*(int *)A1)?0:memchr(A1,'\0',C1)?A1:
513 (memcpy(B1=malloc(C1+1),A1,C1),B1[C1]='\0'
514 ,kill_trailing(B1,' ')),WALK_CLEAR_SCALERS);
515 if(B1) free(B1);
516 return A0;
517 }
518 thStatus thExecuteTests(char *block_name)
519 {
520 return(thWalkTree(block_name,WALK_EXECUTE));
521 }
522 thStatus thClearTestFlags(char *block_name)
523 {
524 return(thWalkTree(block_name,WALK_CLEAR_FLAGS));
525 }
526 thStatus thClearTestScalers(char *block_name)
527 {
528 return(thWalkTree(block_name,WALK_CLEAR_SCALERS));
529 }
530 thStatus thIncTestScalers(char *block_name)
531 {
532 saw 1.1 return(thWalkTree(block_name,WALK_INCREMENT_SCALERS));
533 }
|