/********************************************************/ /* Instrumentation library for Logiscope TestChecker */ /* June 2000 */ /********************************************************/ /********************************************************/ /* Included Files */ /********************************************************/ #ifdef WIN32 #include #include #include #endif #include #include #include #include #include #include #include #ifndef WIN32 #ifdef __STDC__ /* write prototype */ #include #endif #endif /********************************************************/ /* DEFINE */ /********************************************************/ #define MALLOC(size) (size ? malloc(size) : NULL) #define CALLOC(n, size) ((n && size) ? calloc(n, size) : NULL) #ifdef _DEBUG static FILE *logFd ; /* From Win32 */ #define _DBG(x) fprintf x #else #define _DBG(x) #endif #define LIBVER "V\n22\n" /* From Win32 */ #define CDD1 '1' #define CDDE 'E' #define CDDX 'X' #define CPP 'P' #define CM 'C' #define CM_INIT 'S' #define NODATE_MSG "D\n" #define ASSOC 'A' #define NODATE_OPTION "-nodate" #define NOSTRING_OPTION "-nostring" #ifdef WIN32 #define NOMC_OPTION "-nomcdc" #else #define NOMC_OPTION "-nomc" #endif #define NODATE 2 #define NOSTRING 4 #define NOMC 8 #define VLGTMP "VLGTMP" #define VLGMODE "VLGMODE" #define VLGTYP "VLGTYP" #define BOOLEAN short #define TRUE 1 #define FALSE 0 #define CDDTABSIZ 20 #define HCODE 1999 /********************************************************/ /* TYPEDEF */ /********************************************************/ typedef struct _CPP { short n; struct _COMPONENT *called; struct _CPP *next; } S_CPP, *T_CPP; typedef struct _CDD { short table[CDDTABSIZ]; struct _CDD *next; } S_CDD, *T_CDD; typedef struct _VECTOR { unsigned char *value; struct _VECTOR *next; #ifdef DEBUG char * sval; #endif } VECTOR, *T_VECTOR; typedef struct _TRACE_VECTOR { #ifdef GENV1 int cdd; int lg; char * data; #else int numdec; int lg; #endif T_VECTOR true_vector; int nb_true_vector; T_VECTOR false_vector; int nb_false_vector; struct _TRACE_VECTOR *next; } TRACE_VECTOR, *T_TRACE_VECTOR; typedef struct _COMPONENT { int number; char *date ; char *name; T_TRACE_VECTOR vector; T_CDD cdd_list; T_CPP cpp_list; struct _COMPONENT *next_order; struct _COMPONENT *next; } COMPONENT, *T_COMPONENT; typedef struct _FILE { struct _FILE *n; struct _FILE *p; char *name; int num; int last_number; FILE *desc; T_COMPONENT *h_table; T_COMPONENT first_component; T_COMPONENT last_component; } _FILE, *T_FILE; /********************************************************/ /* STATIC VARIABLES */ /********************************************************/ static _FILE filedef = { NULL, NULL, "", 0, 0, NULL, NULL, NULL, NULL }; static T_FILE filefirst = NULL; static T_FILE filelast = NULL; static T_FILE filecur = &filedef; static BOOLEAN trace_available = TRUE; /********************************************************/ /* STATIC FUNCTIONS */ /********************************************************/ #ifdef WIN32 static T_COMPONENT get_component (char * name); static BOOLEAN add_n_to_cdd (T_COMPONENT component, int cdd_number, int n); static BOOLEAN add_n_to_cpp (T_COMPONENT component, T_COMPONENT called, int n); static T_VECTOR vlgins_cm_create_vector(unsigned char *value #ifdef _DEBUG , char *vect #endif ); #else #ifdef __STDC__ static T_COMPONENT get_component (char * name); static BOOLEAN add_n_to_cdd (T_COMPONENT component, int cdd_number, int n); static BOOLEAN add_n_to_cpp (T_COMPONENT component, T_COMPONENT called, int n); /*static BOOLEAN add_to_vector(T_COMPONENT component, int cdd , char *vector);*/ static int hcode(char *name); static T_VECTOR vlgins_cm_create_vector(unsigned char *value #ifdef _DEBUG , char *vect #endif ); #else static T_COMPONENT get_component(); static BOOLEAN add_n_to_cdd (); static BOOLEAN add_n_to_cpp (); static BOOLEAN add_to_vector(); static int hcode(); #endif /* __STDC__*/ #endif /* WIN32 */ #ifdef GENV1 static T_TRACE_VECTOR vlgins_cm_create_trace_vector(int cdd, int ln, char *data); #else static T_TRACE_VECTOR vlgins_cm_create_trace_vector(int num, int nb_cond); #endif #ifdef WIN32 static int hcode(char *name); #endif static void vlg_write_result (); static void set_component_date(T_COMPONENT component, char *date); #if defined(_DLL) #define VLG_DECL __declspec(dllexport) __cdecl #else #define VLG_DECL #endif void VLG_DECL vlg_c_cd1(char *name, char *date, char *file); void VLG_DECL vlg_c_cde(char *name, int cdd_number, char *date, char *file); void VLG_DECL vlg_c_cdx(char *name, int cdd_number, char *file); void VLG_DECL vlg_c_app(char *name, char *called, char *file); void VLG_DECL vlg_c_cdf(char *name, char *file); #ifdef GENV1 void VLG_DECL vlg_c_cm_init(char *name, char **data, char *file); void VLG_DECL vlg_c_cm(char *name, int cdd_number, int value, char *vector, char *file); #else void VLG_DECL vlg_c_cm(char *name, int numdec, int nb_cond, int value, char *vector, char *file); #endif /********************************************************/ /* COMMUNICATION PART */ /********************************************************/ /********************************************************/ /* DEFINE and STATIC VARIABLES */ /********************************************************/ #define PIPE_STD 1 static int write_pipe = 0 ; static int Pipe = 0 ; static BOOLEAN Tracks = FALSE ; #ifdef WIN32 #define PIPE_NMD 2 static HANDLE hPipe = NULL; static DWORD nb = 0; static BOOLEAN WinNT = FALSE; /* Communication macro */ #ifndef SEND #define SEND(name,buffer) _DBG((logFd, "%s\n", (buffer))); \ if (Pipe == PIPE_NMD) \ WriteFile(hPipe, (buffer), strlen(buffer), &nb, NULL); \ else if (Pipe == PIPE_STD) \ _write(write_pipe, (buffer), strlen(buffer)); \ else if (Tracks) \ fprintf(get_write_file(name), "%s", (buffer)) #endif /* SEND */ #else /* WIN32 */ #ifndef SEND #define SEND(name,buffer) _DBG((logFd, "%s\n", (buffer))); \ if (Pipe == PIPE_STD) \ write(write_pipe, (buffer), strlen(buffer)); \ else if (Tracks) \ fprintf(get_write_file(name), "%s", (buffer)) #endif /* SEND */ #endif /* WIN32 */ #if defined (_MT) || defined (_DLL) static CRITICAL_SECTION vlgCriticalSection; static HANDLE hIOMutex; #define STARTLOK InitializeCriticalSection(&vlgCriticalSection) #define LOCK EnterCriticalSection(&vlgCriticalSection) #define UNLOCK LeaveCriticalSection(&vlgCriticalSection) #define STOPLOK DeleteCriticalSection(&vlgCriticalSection) #define WAITMUTEX if (hIOMutex) WaitForSingleObject(hIOMutex, INFINITE) #define REALMUTEX if (hIOMutex) ReleaseMutex(hIOMutex) #define CREAMUTEX hIOMutex = CreateMutex(NULL, FALSE, "VlgDll.mtx") #else #define STARTLOK #define LOCK #define UNLOCK #define STOPLOK #define WAITMUTEX #define REALMUTEX #define CREAMUTEX #endif /* _MT || _DLL */ static BOOLEAN nodate_mode; static BOOLEAN nomc_mode; static BOOLEAN nostring_mode; static char *com_buffer = NULL; /* From Win32 */ static int com_buffer_len = 0; /* From Win32 */ /* Following Macro From Win32 */ #define GROW_COM_BUFFER(l) \ if (((int)(l))+1 > com_buffer_len) {\ char *com_new = (char*) malloc((((int)(l))+100)*sizeof(*com_new));\ free(com_buffer);\ com_buffer = com_new;\ com_buffer_len = ((int)(l))+100;\ } static void vlg_write_result (); static FILE *open_dyn_file(char *a_name, int *test_num) { FILE *file; char buffer[BUFSIZ]; char num[200]; char *p; int i = 0; /* Formated file name has not been given */ /* Default file name is computed */ /* Path is suppressed */ p = strrchr(a_name,'/'); if (p != (char *) 0) strcpy(buffer,p+1); else strcpy(buffer,a_name); /* Dot "." is suppressed */ p = strrchr(buffer,'.'); if ((p != buffer) && (p != (char *) 0)) *p='\0'; /* p at the end of string */ p = &buffer[strlen(buffer)]; /* the file was already opened : the number is known */ if (*test_num != -1) { if (*test_num > 0) { sprintf(num, "%d", i); *p = '\0'; strcat(buffer, num); /* i */ } /* i.dyn or i.trc for raw traces*/ strcat(buffer, Tracks ? ".trc" : ".dyn"); return (FILE *) fopen (buffer, "a"); } /* ".dyn" extension is added */ /* or .trc for raw traces */ strcat(buffer, Tracks ? ".trc" : ".dyn"); /* because other process can create the same file */ WAITMUTEX; /* Because of "fork", search of first file not used */ if ((file = (FILE *) fopen (buffer, "r")) != NULL) { /* If "result.dyn" file already exists, another file name must be choosen */ fclose(file); for (i = 1; i < 10000; i++) { sprintf(num, "%d", i); *p = '\0'; strcat(buffer, num); strcat(buffer, Tracks ? ".trc" : ".dyn"); if ((file = (FILE *) fopen (buffer, "r")) == NULL) { break; } else { /* This file already exists, another file must be choosen */ fclose(file); } } } /* other process freedom */ REALMUTEX; *test_num = i; return (FILE *) fopen (buffer, "a"); } static FILE *get_write_file(char* name) { T_FILE c; T_FILE o; if (!name) name = "result"; _DBG((logFd, "get_write_file: %s\n", name)); for(c=filefirst; c && strcmp(c->name,name); c=c->n); /* the file exists */ if (c) { _DBG((logFd, "get_write_file: %s\n", c->name)); /* passed the file on top */ if (filefirst != c) { if (filelast == c) filelast = c->p; else c->n->p = c->p; c->p->n = c->n; c->n = filefirst; c->p = NULL; filefirst->p = c; filefirst = c; } /* the file exists and was opened */ if (c->desc) { _DBG((logFd, "get_write_file : file %s%d already opened\n", c->name, c->num)); filecur = c; return c->desc; } } else { /* the file does not exist */ c = CALLOC(1, sizeof(*c)); c->name = strdup(name); c->n = filefirst; c->p = NULL; c->num = -1; c->h_table = (T_COMPONENT *) CALLOC(HCODE, sizeof(T_COMPONENT)); if (filefirst) filefirst->p = c; filefirst = c; if (!filelast) filelast = c; } /* the file is not opened */ while (! (c->desc = open_dyn_file(c->name, &(c->num)))) { for(o=filelast; o && !o->desc; o=o->p); if (o) { fclose(o->desc); o->desc = NULL; } } _DBG((logFd, "get_write_file : file %s%d not opened\n", c->name, c->num)); filecur = c; return c->desc; } static void com_end(void) /* Close the communication */ { LOCK; _DBG((logFd, "%s\n", "com_end")); if (!trace_available) return; #ifdef WIN32 if (hPipe) CloseHandle(hPipe); #endif if (!Pipe) { T_FILE c; while(filefirst) { _DBG((logFd, "close %s\n", filefirst->name)); get_write_file(filefirst->name); if (! Tracks) { vlg_write_result(); } if (filefirst->desc) fclose(filefirst->desc); c = filefirst; filefirst = filefirst->n; free(c); } } #ifdef _DEBUG fclose(logFd); #endif UNLOCK; STOPLOK; } static BOOLEAN com_init () /* Initialize the communication with TestChecker. */ { char *vlgtmp=getenv(VLGTMP); char *vlgtyp=getenv(VLGTYP); com_buffer = (char*) malloc(BUFSIZ*sizeof(*com_buffer)); #if !defined(_DLL) atexit(com_end); #endif #ifdef WIN32 WinNT = (BOOLEAN) ((DWORD) GetVersion() >= 0x80000000); #endif if (vlgtyp && !strcmp(vlgtyp, "TRACKS")) { /* generated direct tracks : replace pipe by file */ Tracks = TRUE; } if (!vlgtmp) { Pipe = FALSE; _DBG((logFd, "%s\n", "com_init : file")); return TRUE; } #ifdef WIN32 if (vlgtyp && (!strcmp(vlgtyp, "PIPE_STD") || (!strcmp(vlgtyp, "PIPE_NAMED") && WinNT))) { /* name pipe or standard pipe for NT and standard pipe for 95 or 98 */ _DBG((logFd, "%s\n", "com_init : anonymous pipe")); write_pipe=(atoi(vlgtmp)); Pipe = PIPE_STD; return TRUE; } if (vlgtyp && !strcmp(vlgtyp, "PIPE_NAMED")) { hPipe = CreateFile(vlgtmp, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hPipe == INVALID_HANDLE_VALUE) { /* No communication established */ _DBG((logFd, "%s\n", "com_init : INVALID_HANDLE_VALUE")); return FALSE; } _DBG((logFd, "%s\n", "com_init : named pipe")); Pipe = PIPE_NMD; return TRUE; } #else if (vlgtmp) { write_pipe=(atoi(vlgtmp)); Pipe = PIPE_STD ; return TRUE; } #endif return FALSE; } static short vlgmode_request() { short res = 0; char *tmp, *s, *mode = getenv(VLGMODE); if (mode && *mode) { tmp = strdup(mode); for (s = (char *) strtok(tmp, " "); s; s = (char *) strtok((char *) 0, " ")) { if (!strcmp(s, NODATE_OPTION)) res |= NODATE; if (!strcmp(s, NOSTRING_OPTION)) res |= NOSTRING; if (!strcmp(s, NOMC_OPTION)) res |= NOMC; } } return res; } /********************************************************/ /* WRITING FILES FUNCTIONS */ /********************************************************/ #define MAX_FILE_POS 80 #define MAX_FILE_ESSAI 64 #define write_rexbuf(params) sprintf params; print_rexfile(); rexbuf[0]='\0'; #define is_parsed(component) (char *) ((component)->date) static int rexfile_index = 0; static char rexbuf[BUFSIZ]; static int file_pos = 1; /* Next character position in file */ static char current_date[BUFSIZ]; /* Test date */ static int print_rexfile() { return (fprintf (filecur->desc, "%s", rexbuf)); } static void vlg_set_date () { struct tm *ptm; long vtime; time( &vtime); ptm = (struct tm *)localtime( &vtime); sprintf( current_date, "%02.2d/%02.2d/%02.2d-%02d:%02.2d:%02.2d", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_year % 100, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); } static void vlg_write_string (char *a_string) { int len; len = strlen(a_string); if (file_pos + len + 1 > MAX_FILE_POS) { write_rexbuf((rexbuf, "\\\n%s", a_string)); file_pos = len + 1; } else { if (file_pos > 1) { write_rexbuf((rexbuf," ")); } write_rexbuf((rexbuf,"%s", a_string)); file_pos += len + 1; } } static void vlg_write_value (int n) { char ch_number[BUFSIZ]; sprintf(ch_number,"%d",n); vlg_write_string(ch_number); } static void vlg_write_3value (int n1, int n2, int n3) { char ch_number[BUFSIZ]; sprintf(ch_number,"%d %d %d",n1, n2, n3); vlg_write_string(ch_number); } static void vlg_next_line(char *a_string) { write_rexbuf((rexbuf,"%s\n", a_string)); file_pos = 1; } static int write_component_cpp_list (T_COMPONENT component) /* Returns true if at least one dpp exists */ { T_CPP cpp; int ok = 0; for (cpp = component->cpp_list; cpp;cpp = cpp -> next) { ok = 1; vlg_write_3value(component -> number, cpp -> called -> number, cpp -> n); } return ok; } static void write_component_cdd_list (T_COMPONENT component) { T_CDD cdd; int i,j, current_cdd_number = 1; vlg_write_value(component -> number); for (cdd = component->cdd_list; cdd -> next;) { for(i=0;i table[i]); cdd = cdd -> next; } /* Results are written until 0 is found */ for(i=CDDTABSIZ-1;!(cdd -> table[i]);i--); for(j=0;j<=i;j++) vlg_write_value(cdd -> table[j]); vlg_next_line(""); } /********************************************************/ /* WRITING IN THE FORMATED FILE FUNCTIONS */ /********************************************************/ static void vlg_write_header () { #ifdef GENV1 write_rexbuf((rexbuf, "\n")); #else write_rexbuf((rexbuf, "\n")); #endif write_rexbuf((rexbuf, "*NA*\n")); write_rexbuf((rexbuf, "DEFAULT_ARCHIVE\n")); write_rexbuf((rexbuf, "*CV*\n")); write_rexbuf((rexbuf, "DEFAULT_SUITE\n")); write_rexbuf((rexbuf, "*CM*\n")); write_rexbuf((rexbuf, "DEFAULT_SUITE\n")); write_rexbuf((rexbuf, "DEFAULT_TEST %s\n", current_date)); write_rexbuf((rexbuf, "*MO*\n")); write_rexbuf((rexbuf, "DEFAULT_TEST %s\n", current_date)); } static void vlg_write_footer () { vlg_next_line(".SA."); vlg_next_line("*FI*"); } static int vlg_write_component_list() { int number = 1; int nb_component=0; T_COMPONENT component; vlg_next_line(".NM."); for(component=filecur->first_component;component;component =component->next_order) { write_rexbuf((rexbuf, "%d %s", component -> number, component -> name)); if (is_parsed (component)) { nb_component ++; write_rexbuf((rexbuf," %s\n", component -> date)); } else { write_rexbuf((rexbuf," %s\n", "UNKNOWN_DATE")); } } return nb_component; } static void vlg_write_cdd_list() { T_COMPONENT component; vlg_next_line(".CC."); for(component=filecur->first_component;component;component =component->next_order) { if (is_parsed (component)) { write_component_cdd_list(component); } } } static void vlg_write_cpp_list() { T_COMPONENT component; int ok = 0; vlg_next_line(".CA."); for(component=filecur->first_component;component;component=component->next_order) { if (is_parsed (component)) { if (write_component_cpp_list(component)) { ok = 1; } } } /* If at least one dpp, a line is skipped */ if (ok) vlg_next_line(""); } #define DIM(nc) ((nc + 3) / 4) /* faster */ #define UN 1 #define ZERO_CODE 0 #define ONE_CODE 1 #define DASH_CODE 2 static void set_area (unsigned char *v, int num_cond, unsigned char value, int per_char, int sz_in_byte) { unsigned char UNc = (unsigned char) ~0; int i = num_cond % per_char; assert (v); v[num_cond / per_char] &= ((~0 << ((i + 1) * sz_in_byte)) | (UNc >> (8 - (i * sz_in_byte)))); v[num_cond / per_char] |= (value << i * sz_in_byte); } static unsigned char get_area (unsigned char *v, int num_cond, int per_char, int sz_in_byte) { unsigned char res; unsigned char UNc = (unsigned char) ~0; assert (v); res = (v[num_cond / per_char] >> ((num_cond % per_char) * sz_in_byte)) & (UNc >> (8 - sz_in_byte)); return res; } static unsigned char *vlgins_cm_vector2USC(char *vector) { char *s; int i; int len = strlen(vector); int sz = DIM(len); unsigned char *res = (unsigned char*) CALLOC(sz, sizeof(char)); for (s = vector, i = 0; *s; s++, i++) { switch (*s) { case '0' : set_area(res, i, 0, 4, 2); break; case '1' : set_area(res, i, 1, 4, 2); break; case '-' : set_area(res, i, 2, 4, 2); break; default : break; } } return res; } static char *vlgins_cm_USC2vector(unsigned char *v, int len) { int i; char *t, *s = (char *) CALLOC(len + 1, sizeof(char)); for (i = 0, t = s; i < len; i++, t++) { switch (get_area(v, i, 4, 2)) { case 0 : *t = '0'; break; case 1 : *t = '1'; break; case 2 : *t = '-'; break; default : /* error : unexpected value */ /* DEBUG : Give the position of the error int the dyn file (#) *t = '#';*/ break; } } return s; } static int vlgins_cm_compare_values(unsigned char *v1, unsigned char *v2, int len) { int i, k = DIM(len); for (i = 0; i < k && (v1[i] == v2[i]); i++) ; if (i == k) return 0; return 1; } static char *vlgins_cm_write_vector(T_VECTOR vector, int len, int nb) { T_VECTOR v; char *s, *k; s = (char *) CALLOC((len * nb) + 1, sizeof(char)); for (v = vector; v; v = v ->next) { k = vlgins_cm_USC2vector(v ->value, len); strcat(s, k); free(k); } return s; } static void write_component_trace_vector_list(T_COMPONENT component) { T_TRACE_VECTOR tv; char *s; for (tv = component ->vector; tv; tv = tv ->next) { vlg_write_value(component -> number); vlg_write_value(tv ->nb_true_vector); if (tv ->nb_true_vector) { s = vlgins_cm_write_vector(tv ->true_vector, tv ->lg, tv ->nb_true_vector); vlg_write_string(s); free(s); } vlg_write_value(tv ->nb_false_vector); if (tv ->nb_false_vector) { s = vlgins_cm_write_vector(tv ->false_vector, tv ->lg, tv ->nb_false_vector); vlg_write_string(s); free(s); } #ifdef GENV1 vlg_write_string(tv -> data); #else vlg_write_value(tv -> numdec); #endif vlg_next_line(""); } } static void vlg_write_trace_vector_list() { T_COMPONENT component; vlg_next_line(".MC."); for(component=filecur->first_component;component;component=component->next_order) { if (is_parsed (component)) write_component_trace_vector_list(component); } } static void vlg_write_result () { vlg_write_header(); vlg_write_component_list(); vlg_write_cdd_list(); vlg_next_line(".SC."); vlg_write_trace_vector_list(); vlg_write_cpp_list(); vlg_write_footer(); } /********************************************************/ /* TRACK FUNCTIONS */ /********************************************************/ static BOOLEAN is_initialized = FALSE; /* Following functions starting and initialize from Win32 */ static BOOLEAN starting () { #ifdef _DEBUG char buffer[BUFSIZ]; char num[200]; char *p; int i = 0; char *logFile; #endif STARTLOK; LOCK; CREAMUTEX; #ifdef WIN32 #ifdef _DEBUG logFile = getenv("LOGFILE"); if (!logFile) { #define DEFAULT_TMPDIR "c:\\temp\\" #define DEFAULT_DLLOUT "dll.out" char *tmpDir = getenv("TEMP"); logFile = CALLOC(strlen((tmpDir ? tmpDir : DEFAULT_TMPDIR)) +strlen(DEFAULT_DLLOUT)+2, sizeof(*logFile)); strcpy(logFile, (tmpDir ? tmpDir : DEFAULT_TMPDIR)); if (logFile[strlen(logFile)-1]!='\\') strcat(logFile, "\\"); strcat(logFile, DEFAULT_DLLOUT); strcpy(buffer, logFile); free (logFile); } else strcpy(buffer, logFile); /* Dot is suppressed */ p = strrchr(buffer,'.'); if ((p != buffer) && (p != (char *) 0)) *p='\0'; /* p at the end of string */ p = &buffer[strlen(buffer)]; /* .out extension is added */ strcat(buffer, ".out"); /* because other process can create the same file */ WAITMUTEX; /* Because of "fork", search of first file not used */ if ((logFd = (FILE *) fopen (buffer, "r")) != NULL) { /* If "dll.out" file already exists, another file name must be choosen */ fclose(logFd); for (i = 1; i < 10000; i++) { sprintf(num, "%d", i); *p = '\0'; strcat(buffer, num); /* i */ strcat(buffer, ".out"); /* i.out */ if ((logFd = (FILE *) fopen (buffer, "r")) == NULL) { break; } else { /* This file already exists, another file must be choosen */ fclose(logFd); } } } /* other process freedom */ REALMUTEX; if ((logFd = fopen(buffer, "w")) == (FILE *) 0) logFd = stdout; #endif /* _DEBUG */ #endif /* WIN32 */ trace_available = com_init(); _DBG((logFd, "%s: trace: %s\n", "starting", trace_available ? "true" : "false")); if (!trace_available) { UNLOCK; return FALSE; } UNLOCK ; return TRUE; } static BOOLEAN initialize (char *file) { short mode; _DBG((logFd, "%s\n", "initialize")); #ifndef _DLL if (! starting()) { _DBG((logFd, "%s\n", "not dll: starting false")); return FALSE; } #endif LOCK; is_initialized = TRUE; #ifndef GENV1 if (Pipe || Tracks) { SEND(file, LIBVER); } #endif mode = vlgmode_request(); if ((Pipe || Tracks) && (nodate_mode = mode & NODATE)) { SEND(file, NODATE_MSG); } nostring_mode = mode & NOSTRING; nomc_mode = mode & NOMC; filedef.h_table = (T_COMPONENT *) CALLOC(HCODE, sizeof(T_COMPONENT)); vlg_set_date(); UNLOCK; return TRUE; } #if defined(_DLL) /* To generate a lib and dll instead of an alone lib */ BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH : // Initialize once for each new process. // Return FALSE to fail DLL load. starting(); _DBG((logFd, "%s, %d\n", "DLL_PROCESS_ATTACH", lpReserved)); break; case DLL_PROCESS_DETACH : // Perform any necessary cleanup. _DBG((logFd, "%s, %d\n", "DLL_PROCESS_DETACH", lpReserved)); com_end(); break; case DLL_THREAD_ATTACH: // Do thread-specific initialization. _DBG((logFd, "%s, %d\n", "DLL_THREAD_ATTACH", lpReserved)); break; case DLL_THREAD_DETACH: // Do thread-specific cleanup. _DBG((logFd, "%s, %d\n", "DLL_THREAD_DETACH", lpReserved)); break; } return TRUE; } #endif #ifdef WIN32 void vlg_c_cd1 (char * name, char * date, char *file) #else #ifdef __STDC__ void vlg_c_cd1 (char * name, char * date, char *file) #else void vlg_c_cd1(name, date, file) char *name; char *date; char *file; #endif #endif /* WIN32 */ { T_COMPONENT component; LOCK; #ifndef WIN32 #ifdef _DEBUG logFd = fopen ("Exec_Trace", "w") ; if (!logFd) printf("Unable to open trace file...\n") ; #endif /* _DEBUG */ #endif _DBG((logFd, "vlg_c_cd1\n")); if (!trace_available) { UNLOCK; return; } if(!is_initialized) { if (!initialize (file)) { UNLOCK; return; } } if (!Pipe && !Tracks) get_write_file(file); component = get_component(name); if (!component -> date) { /* The component date is not updated */ set_component_date(component, date); } if (add_n_to_cdd(component, 1, 1)) { if (Pipe || Tracks) { GROW_COM_BUFFER(strlen(name)+strlen(date)+100) sprintf(com_buffer,"%c\n%s\n%s\n", CDD1, name, date); SEND(file, com_buffer); } } UNLOCK; } #ifdef WIN32 void vlg_c_cde(char *name, int cdd_number, char *date, char *file) #else #ifdef __STDC__ void vlg_c_cde(char *name, int cdd_number, char *date,char *file) #else void vlg_c_cde(name, cdd_number, date, file) char *name; int cdd_number; char *date; char *file ; #endif #endif /* WIN32 */ { T_COMPONENT component; LOCK; _DBG((logFd, "vlg_c_cde\n")); if (!trace_available) { UNLOCK; return; } if(!is_initialized) { if (!initialize (file)) { UNLOCK; return; } } if (!Pipe && !Tracks) get_write_file(file); component = get_component(name); if (add_n_to_cdd(component, cdd_number, 1)) { if (Pipe || Tracks) { GROW_COM_BUFFER(strlen(name)+strlen(date)+200) sprintf(com_buffer,"%c\n%s\n%d\n%s\n", CDDE, name, cdd_number, date); SEND(file, com_buffer); } } UNLOCK; } #ifdef WIN32 void vlg_c_cdx(char *name, int cdd_number, char *file) #else #ifdef __STDC__ void vlg_c_cdx(char *name, int cdd_number, char *file) #else void vlg_c_cdx(name, cdd_number, file) char *name; int cdd_number; char *file ; #endif #endif /* WIN32 */ { T_COMPONENT component; LOCK; _DBG((logFd, "vlg_c_cdx\n")); if (!trace_available) { UNLOCK; return; } if(!is_initialized) { if (!initialize (file)) { UNLOCK; return; } } if (!Pipe && !Tracks) get_write_file(file); component = get_component(name); if (add_n_to_cdd(component, cdd_number, 1)) { if (Pipe || Tracks) { GROW_COM_BUFFER(strlen(name)+100) sprintf(com_buffer,"%c\n%s\n%d\n", CDDX, name, cdd_number); SEND(file, com_buffer); } } UNLOCK; } #ifdef GENV1 #ifdef WIN32 void vlg_c_cm_init(char *name, char *data[], char *file) #ifdef __STDC__ void vlg_c_cm_init(char *name, char *data[], char *file) #else void vlg_c_cm_init(name, data, file) char *name; char *data[]; char *file ; #endif #endif /* WIN32 */ { char *s; int i; T_COMPONENT component; LOCK; _DBG((logFd, "vlg_c_cm_init\n")); if (!trace_available) { UNLOCK; return; } if(!is_initialized) { if (!initialize (file)) { UNLOCK; return; } } if (!Pipe && !Tracks) get_write_file(file); if (!data[0]) return; component = get_component(name); for (i = 0, s = data[i]; s; i++, s = data[i]) { T_TRACE_VECTOR tv; char *r = strdup(s); char *fin; char *num_cond; char *nb_cond; if (Pipe || Tracks) { GROW_COM_BUFFER(strlen(name)+strlen(s)+100) sprintf(com_buffer, "%c\n%s\n%s\n", CM_INIT, name, s); SEND(file, com_buffer); } /* condition number */ num_cond = r; /* number of vectors */ nb_cond = strchr(num_cond, ':'); *nb_cond = '\0'; /* \0 at the end */ fin = strchr(++nb_cond, ':'); *fin = '\0'; for (tv = component->vector; tv && tv->cdd != atoi(num_cond); tv = tv->next); if (!tv) { /* DDP not found -> Add the vector */ tv = vlgins_cm_create_trace_vector(atoi(num_cond), atoi(nb_cond), s); tv ->next = component ->vector; component ->vector = tv; } } data[0] = (char *) 0; UNLOCK; } #ifdef WIN32 void vlg_c_cm(char *name, int cdd, int val, char *vector, char *file) #else #ifdef __STDC__ void vlg_c_cm(char *name, int cdd, int val, char *vector, char *file) #else void vlg_c_cm(name, cdd, val, vector, file) char *name; int cdd; int val; char *vector; char *file; #endif #endif /* WIN32 */ { T_COMPONENT component; T_TRACE_VECTOR tv; T_VECTOR v; unsigned char *value; int ln; LOCK; _DBG((logFd, "vlg_c_cm\n")); if (!trace_available) { UNLOCK; return; } if(!is_initialized) { if (!initialize (file)) { UNLOCK; return; } } if (!Pipe && !Tracks) get_write_file(file); component = get_component(name); value = vlgins_cm_vector2USC(vector); ln = strlen(vector); for (tv = component ->vector; tv && tv ->cdd != cdd; tv = tv ->next) ; if (tv) { for (v = val ? tv ->true_vector : tv ->false_vector; v && vlgins_cm_compare_values(v ->value, value, ln); v = v ->next); if (!v) { #ifdef DEBUG T_VECTOR nv = vlgins_cm_create_vector(value, vector); #else T_VECTOR nv = vlgins_cm_create_vector(value); #endif if (Pipe || Tracks) { GROW_COM_BUFFER(strlen(name)+strlen(vector)+200) sprintf(com_buffer, "%c\n%s\n%d\n%d\n%s\n", CM, name, cdd, val, vector); SEND(file, com_buffer); } if (val) { nv ->next = tv ->true_vector; tv ->true_vector = nv; tv ->nb_true_vector++; } else { nv ->next = tv ->false_vector; tv ->false_vector = nv; tv ->nb_false_vector++; } } else free(value); } else free(value); UNLOCK; } #else /* GENV1 */ #ifdef WIN32 void vlg_c_cm(char *name, int numdec, int nb_cond, int val, char *vector, char *file) #else #ifdef __STDC__ void vlg_c_cm(char *name, int numdec, int nb_cond, int val, char *vector, char *file) #else void vlg_c_cm(name, numdec, nb_cond, val, vector, file) char *name; int numdec; int nb_cond ; int val; char *vector; char *file; #endif #endif /* WIN32 */ { T_COMPONENT component; T_TRACE_VECTOR tv; T_VECTOR v; unsigned char *value; int ln; LOCK; _DBG((logFd, "vlg_c_cm\n")); if (!trace_available) { UNLOCK; return; } if(!is_initialized) { if (!initialize (file)) { UNLOCK; return; } } if (!Pipe && !Tracks) get_write_file(file); component = get_component(name); value = vlgins_cm_vector2USC(vector); ln = strlen(vector); for (tv = component ->vector; tv && tv ->numdec != numdec; tv = tv ->next) ; if (! tv) { tv = vlgins_cm_create_trace_vector(numdec, nb_cond); tv ->next = component ->vector; component ->vector = tv; } for (v = val ? tv ->true_vector : tv ->false_vector; v && vlgins_cm_compare_values(v ->value, value, ln); v = v ->next); if (!v) { #ifdef _DEBUG T_VECTOR nv = vlgins_cm_create_vector(value, vector); #else T_VECTOR nv = vlgins_cm_create_vector(value); #endif if (Pipe || Tracks) { GROW_COM_BUFFER(strlen(name)+strlen(vector)+200) sprintf(com_buffer, "%c\n%s\n%d\n%d\n%s\n", CM, name, numdec, val, vector); SEND(file, com_buffer); } if (val) { nv ->next = tv ->true_vector; tv ->true_vector = nv; tv ->nb_true_vector++; } else { nv ->next = tv ->false_vector; tv ->false_vector = nv; tv ->nb_false_vector++; } } else free(value); UNLOCK; } #endif /* GENV1 */ #ifdef WIN32 void vlg_c_app(char *name, char *called, char *file) #else #ifdef __STDC__ void vlg_c_app(char *name, char *called, char *file) #else void vlg_c_app(name, called, file) char *name; char *called; char *file ; #endif #endif /* WIN32 */ { T_COMPONENT component, component_called; LOCK; _DBG((logFd, "vlg_c_app\n")); if (!trace_available) { UNLOCK; return; } if(!is_initialized) { if (!initialize (file)) { UNLOCK; return; } } if (!Pipe && !Tracks) get_write_file(file); component = get_component(name); component_called = get_component(called); if (add_n_to_cpp(component, component_called, 1)) { if (Pipe || Tracks) { GROW_COM_BUFFER(strlen(name)+strlen(called)+100) sprintf(com_buffer,"%c\n%s\n%s\n", CPP, name, called); SEND(file, com_buffer); } } UNLOCK; } #ifdef WIN32 void vlg_c_cdf(char * name, char *file) #else #ifdef __STDC__ void vlg_c_cdf(char * name, char *file) #else void vlg_c_cdf(name, file) char *name; char *file; #endif #endif /* WIN32 */ { LOCK; _DBG((logFd, "vlg_c_cdx\n")); if (!trace_available) { UNLOCK; return; } if(!is_initialized) { if (!initialize (file)) { UNLOCK; return; } } #ifndef _WIN32 if (!Pipe && !Tracks) get_write_file(file); #endif UNLOCK; } /********************************************************/ /* END TRACKS FUNCTIONS */ /********************************************************/ /* ---------------------------- */ /* INTERNAL MANAGEMENT FUNCTION */ /* ---------------------------- */ static void set_component_date(T_COMPONENT component, char *date) { component->date = (char*) strdup(date); } static T_CDD new_cdd () { T_CDD cdd; int i; cdd = (T_CDD) CALLOC(1, sizeof(*cdd)); /* RB */ for(i=0;i table[i]= FALSE; cdd -> next = (T_CDD) 0; return cdd; } #ifdef WIN32 static T_CPP new_cpp (T_COMPONENT component) { T_CPP cpp; cpp = (T_CPP) CALLOC(1, sizeof(*cpp)); cpp -> called = component; cpp -> next = (T_CPP) 0; return cpp; } #else #ifdef __STDC__ static T_CPP new_cpp (T_COMPONENT component) #else static T_CPP new_cpp (component) T_COMPONENT component; #endif { T_CPP cpp; cpp = (T_CPP) malloc(sizeof(S_CPP)); cpp -> called = component; cpp -> next = (T_CPP) 0; return cpp; } #endif /* WIN32 */ /* From Win32 */ static T_VECTOR vlgins_cm_create_vector(unsigned char *value #ifdef _DEBUG , char *vect #endif ) { T_VECTOR res = (T_VECTOR) CALLOC(1, sizeof(VECTOR)); res ->value = value; #ifdef DEBUG res ->sval = vect; #endif return res; } #ifdef GENV1 static T_TRACE_VECTOR vlgins_cm_create_trace_vector(int cdd, int ln, char *data) { T_TRACE_VECTOR res = (T_TRACE_VECTOR) CALLOC(1, sizeof(TRACE_VECTOR)); res ->data = data; res ->cdd = cdd; res ->lg = ln; return res; } #else static T_TRACE_VECTOR vlgins_cm_create_trace_vector(int num, int nb_cond) { T_TRACE_VECTOR res = (T_TRACE_VECTOR) CALLOC(1, sizeof(TRACE_VECTOR)); res ->numdec = num; res->lg = nb_cond; return res; } #endif #ifdef WIN32 static T_COMPONENT new_component (char * name) { T_COMPONENT component; component = (T_COMPONENT) CALLOC(1, sizeof(*component)); component -> name = strdup(name); component -> number = ++(filecur->last_number); component -> date = (char*) 0; component -> cdd_list = new_cdd(); component -> cpp_list = (T_CPP) 0; component -> next = (T_COMPONENT) 0; component -> next_order = (T_COMPONENT) 0; return component; } #else #ifdef __STDC__ static T_COMPONENT new_component (char * name) #else static T_COMPONENT new_component (name) char *name; #endif { T_COMPONENT component; component = (T_COMPONENT) malloc(sizeof(COMPONENT)); component -> name = (char *) strdup(name); component -> number = ++(filecur->last_number); component -> date = (char*) 0; component -> vector = (T_TRACE_VECTOR) 0 ; component -> cdd_list = new_cdd(); component -> cpp_list = (T_CPP) 0; component -> next = (T_COMPONENT) 0; component -> next_order = (T_COMPONENT) 0; return component; } #endif /* WIN32 */ /********************************************************/ /* H-CODE TABLE MANAGEMENT */ /********************************************************/ #ifdef WIN32 static int hcode (char *name) { char *p; int h = 0; for (p = name; *p; p++) { h = (h + *p) % HCODE; } return h; } #else #ifdef __STDC__ static int hcode (char *name) #else static int hcode (name) char *name; #endif { char *p; int h = 0; for (p = name; *p; p++) { h = (h + *p) % HCODE; } return h; } #endif /* WIN 32 */ #ifdef WIN32 static T_COMPONENT search (char * name) #else #ifdef __STDC__ static T_COMPONENT search (char * name) #else static T_COMPONENT search (name) char *name; #endif #endif /* WIN32 */ /* Search a component in the table */ /* Return the component or NULL if it's not in the table */ { int hcde; T_COMPONENT component; hcde = hcode(name); component = filecur->h_table[hcde]; for (component = filecur->h_table[hcde];component;component = component->next) { if (!strcmp(component->name, name)) { /* Found the component */ return component; } } return component; } #ifdef WIN32 static T_COMPONENT add_component (char *name) #else #ifdef __STDC__ static T_COMPONENT add_component (char *name) #else static T_COMPONENT add_component (name) char *name; #endif #endif /* WIN32 */ /* Add a component in the table */ { int hcde; T_COMPONENT component; component = new_component(name); hcde = hcode(name); component -> next = filecur->h_table[hcde]; filecur->h_table[hcde] = component; /* List update */ if (filecur->last_component) { _DBG((logFd, "add_component: insertion de %s\n", name)); filecur->last_component -> next_order = component; filecur->last_component = component; } else { _DBG((logFd, "add_component: init de %s\n", name)); filecur->first_component = component; filecur->last_component = component; } return component; } #ifdef WIN32 static T_COMPONENT get_component (char * name) #else #ifdef __STDC__ static T_COMPONENT get_component (char * name) #else static T_COMPONENT get_component(name) char *name; #endif #endif /* WIN32 */ /* Return component descriptor */ { register T_COMPONENT component; component = search(name); if (!component) { component = add_component(name); } return component; } #define MAX_CUMUL 10000 #define cumul(value,n) if((value)!=(-1)) {\ (value)+=(n);\ if((value)>MAX_CUMUL)\ (value)=-1;\ } #ifdef WIN32 static BOOLEAN add_n_to_cdd (T_COMPONENT component, int cdd_number, int n) #else #ifdef __STDC__ static BOOLEAN add_n_to_cdd (T_COMPONENT component, int cdd_number, int n) #else static BOOLEAN add_n_to_cdd (component, cdd_number, n) T_COMPONENT component; int cdd_number; int n; #endif #endif /* WIN32 */ { T_CDD cdd, previous_cdd; int current_max_cdd = 0; int i; BOOLEAN ret = FALSE; _DBG((logFd, "add_n_to_cdd: %s %d\n", component->name, cdd_number)); cdd = component -> cdd_list; /* There is always at least one ddp */ previous_cdd = (T_CDD) 0; current_max_cdd = CDDTABSIZ; while (cdd_number > current_max_cdd ) { if (!cdd -> next) { cdd -> next = new_cdd(); } cdd = cdd -> next; current_max_cdd += CDDTABSIZ; } i = (cdd_number-1) % CDDTABSIZ; if (!(cdd -> table[i])) { /* Number of times in the ddp is incremented */ /* if equal to 0 */ cumul(cdd -> table[i] , n); ret = TRUE; } return ret; } #ifdef WIN32 static BOOLEAN add_n_to_cpp (T_COMPONENT component, T_COMPONENT called, int n) #else #ifdef __STDC__ static BOOLEAN add_n_to_cpp (T_COMPONENT component, T_COMPONENT called, int n) #else static BOOLEAN add_n_to_cpp (component, called, n) T_COMPONENT component; T_COMPONENT called; int n; #endif #endif /* WIN32 */ { T_CPP cpp; int ok; cpp = component -> cpp_list; ok = 0; while ((cpp) && (!ok)) { if (cpp -> called == called) { ok = 1; } else { cpp = cpp -> next; } } if (!ok) { /* the cpp does not exist */ cpp = new_cpp(called); cpp->n = 1; cpp -> next = component -> cpp_list; component -> cpp_list = cpp; } /* Number of times in the ppp is incremented */ /* if equal to 0 */ if (!cpp -> n) cumul(cpp -> n, n); return !ok; }