#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef winnt
#define strdup _strdup
#endif
#define DEFAULT_GTX_SERVERNAME "localhost"
#define MAX_HOSTNAME_LEN 1024
#define MAX_PATH_LEN 1024
#define MAX_ITEM_LEN 50
#define MODE_INIT 0
#define MODE_STUDY 1
#define MODE_DIR 2
#define MODE_FILE 3
#define MODE_VAR 4
#define NONE_STRING "None"
char current_study[MAX_ITEM_LEN];
char current_dir[MAX_ITEM_LEN];
char current_file[MAX_ITEM_LEN];
char current_var[MAX_ITEM_LEN];
char current_sel[MAX_ITEM_LEN];
int current_indice;
char **current_list = NULL;
char nb_current_list = 0;
char host[MAX_HOSTNAME_LEN];
unsigned short port;
char data_path[MAX_PATH_LEN];
static void st_action_list(int index);
static void st_action_set(int index);
static void st_action_indice(int index);
static void st_action_set_sel(int index);
static void st_action_info(int index);
static void st_action_stat(int index);
static void st_action_connect(int index);
static void st_action_run(int index);
static void st_action_exit(int index);
struct act
{
int visible;
char *action;
int need_index;
char *title;
void (*action_func)(int number);
}
Actions[] =
{
{0, "LIST", 0, "Retrieve current list", st_action_list},
{0, "SET", 1, "Set item as current", st_action_set},
{0, "IND", 1, "Set indice as current", st_action_indice},
{0, "SEL", 1, "Set item as selection", st_action_set_sel},
{0, "INFO", 1, "Information on item", st_action_info},
{0, "STAT", 0, "Statistics on item", st_action_stat},
{0, "RUN", 0, "Run & Connect", st_action_run},
{0, "CONN", 0, "Connect", st_action_connect},
{0, "DISC", 0, "Disconnect", st_action_connect},
{0, "EXIT", 0, "Exit", st_action_exit},
};
int nb_Action = sizeof (Actions) / sizeof (struct act);
#define ACTION_LIST 0
#define ACTION_SET 1
#define ACTION_IND 2
#define ACTION_SEL 3
#define ACTION_INFO 4
#define ACTION_STAT 5
#define ACTION_RUN 6
#define ACTION_CONN 7
#define ACTION_DISC 8
#define ACTION_EXIT 9
int mode;
char *GTXfile_types[] =
{
"Points",
"Lines",
"Grid"
};
char *GTXvar_types[] =
{
"Float",
"Character",
"X gravity center",
"Y gravity center",
"Z gravity center",
"Macro"
};
static void st_usage(char *exe_name,
int help)
{
(void)printf("Usage: %s [-help] [-host hostname] [-port port_number]\n",
exe_name);
(void)printf(" [-path data_path]\n");
if (help)
{
(void)printf(" -help : Print this message.\n");
(void)printf(" -debug : Print client/server messages.\n");
(void)printf(" -host hostname : Server's hostname.\n");
(void)printf(" -port port_number: Port used between client and server\n");
(void)printf(" -path data_path : Initialize connection with given data_path.\n");
}
}
static void st_action_list(int number)
{
int i,first;
#define end_label &label_str[strlen(label_str)]
char label_str[300];
(void)printf("#*#*#*#*#*#*#*#*#*#*#*#\n");
if (!strcmp(current_study,NONE_STRING))
{
(void)strcpy(label_str, "Study list:\n");
goto label_end;
}
else
(void)strcpy(label_str, current_study);
if (!strcmp(current_dir,NONE_STRING))
{
(void)sprintf(end_label, "\nDirectory list:\n");
goto label_end;
}
else
(void)sprintf(end_label, ": %s", current_dir);
if (!strcmp(current_file,NONE_STRING))
{
(void)sprintf(end_label, "\nFile list:\n");
goto label_end;
}
else
(void)sprintf(end_label, "/%s", current_file);
if (strcmp(current_sel,NONE_STRING))
(void)sprintf(end_label, "/%s", current_sel);
(void)sprintf(end_label, "\nVariable list:\n");
label_end:
(void)printf(label_str);
first = (nb_current_list > 0 && !strcmp(current_list[0], ".."))? 0 : 1;
for (i=0; i<nb_current_list; i++)
(void)printf("%d. %s\n", i+first, current_list[i]);
(void)printf("#*#*#*#*#*#*#*#*#*#*#*#\n");
#undef end_label
}
static void st_status_mess(char *format, ...)
{
va_list ap;
char buffer[1024];
va_start(ap, format);
(void)vsprintf(buffer, format, ap);
va_end(ap);
(void)printf("Status: %s\n",buffer);
}
static char *st_get_selected_item(int index)
{
int first;
char *sel_str = NULL;
first = (nb_current_list > 0 && !strcmp(current_list[0], ".."))? 0 : 1;
if (index < first || index >= nb_current_list+first)
{
(void)fprintf(stderr,"index (%d) must be in [%d,%d]",
index,first,nb_current_list+first-1);
goto label_end;
}
sel_str = (char*)strdup(current_list[index-first]);
label_end:
return(sel_str);
}
static int st_get_study_list()
{
int i,error,nb_study;
char **studies,**new_list;
error = 1;
studies = NULL;
(void)strcpy(current_study,NONE_STRING);
new_list = (char **)malloc(sizeof(char*) * (nb_study));
if (new_list == NULL)
{
(void)fprintf(stderr,"Cannot allocate %d bytes",
(int)(sizeof(char*)*(nb_study)));
goto label_end;
}
for (i=0; i<nb_study; i++)
new_list[i] = NULL;
for (i=0; i<nb_study; i++)
new_list[i] = (char*)strdup(studies[i]);
for (i=0; i<nb_current_list; i++)
if (current_list[i] != NULL) free(current_list[i]);
if (current_list != NULL) free(current_list);
current_list = new_list;
nb_current_list = nb_study;
mode = MODE_STUDY;
st_action_list(0);
Actions[ACTION_LIST].visible = 1;
Actions[ACTION_SET ].visible = 1;
error = 0;
label_end:
return(error);
}
static int st_get_dir_list(char *study)
{
int i,error,nb_dir;
char **new_list;
char **dirs;
error = 1;
dirs = NULL;
new_list = NULL;
if (mode == MODE_STUDY)
{
(void)strcpy(current_study,study);
}
else
(void)strcpy(current_dir, NONE_STRING);
new_list = (char **)malloc(sizeof(char*) * (nb_dir+1));
if (new_list == NULL)
{
(void)fprintf(stderr,"Cannot allocate %d bytes",
(int)(sizeof(char*)*(nb_dir+1)));
goto label_end;
}
for (i=0; i<=nb_dir; i++)
new_list[i] = NULL;
new_list[0] = (char*)strdup("..");
if (new_list[0] == NULL) goto label_end;
for (i=0; i<nb_dir; i++)
new_list[i+1] = (char*)strdup(dirs[i]);
Actions[ACTION_INFO].visible = 0;
for (i=0; i<nb_current_list; i++)
if (current_list[i] != NULL) free(current_list[i]);
if (current_list != NULL) free(current_list);
current_list = new_list;
nb_current_list = nb_dir+1;
mode = MODE_DIR;
st_action_list(0);
error = 0;
label_end:
return(error);
}
static int st_get_file_list(char *dir)
{
int i,error,nb_file;
char **new_list;
char **files;
error = 1;
files = NULL;
new_list = NULL;
if (mode == MODE_DIR)
{
(void)strcpy(current_dir,dir);
}
else
{
(void)strcpy(current_file, NONE_STRING);
(void)strcpy(current_var, NONE_STRING);
(void)strcpy(current_sel, NONE_STRING);
current_indice = -1;
}
new_list = (char **)malloc(sizeof(char*) * (nb_file+1));
if (new_list == NULL)
{
(void)fprintf(stderr,"Cannot allocate %d bytes",
(int)(sizeof(char*)*(nb_file+1)));
goto label_end;
}
for (i=0; i<=nb_file; i++)
new_list[i] = NULL;
new_list[0] = (char*)strdup("..");
if (new_list[0] == NULL) goto label_end;
for (i=0; i<nb_file; i++)
new_list[i+1] = (char*)strdup(files[i]);
Actions[ACTION_IND ].visible = 0;
Actions[ACTION_INFO].visible = 1;
Actions[ACTION_STAT].visible = 0;
Actions[ACTION_SEL ].visible = 0;
for (i=0; i<nb_current_list; i++)
if (current_list[i] != NULL) free(current_list[i]);
if (current_list != NULL) free(current_list);
current_list = new_list;
nb_current_list = nb_file+1;
mode = MODE_FILE;
st_action_list(0);
error = 0;
label_end:
return(error);
}
static int st_get_var_list(char *file)
{
int i,error,nb_var;
char **new_list;
char **vars;
error = 1;
vars = NULL;
new_list = NULL;
if (mode == MODE_FILE)
{
(void)strcpy(current_file,file);
}
else
{
(void)strcpy(current_var, NONE_STRING);
(void)strcpy(current_sel, NONE_STRING);
}
new_list = (char **)malloc(sizeof(char*) * (nb_var+1));
if (new_list == NULL)
{
(void)fprintf(stderr,"Cannot allocate %d bytes",
(int)(sizeof(char*)*(nb_var+1)));
goto label_end;
}
for (i=0; i<=nb_var; i++)
new_list[i] = NULL;
new_list[0] = (char*)strdup("..");
if (new_list[0] == NULL) goto label_end;
for (i=0; i<nb_var; i++)
new_list[i+1] = (char*)strdup(vars[i]);
Actions[ACTION_SEL ].visible = 1;
for (i=0; i<nb_current_list; i++)
if (current_list[i] != NULL) free(current_list[i]);
if (current_list != NULL) free(current_list);
current_list = new_list;
nb_current_list = nb_var+1;
mode = MODE_VAR;
st_action_list(0);
error = 0;
label_end:
return(error);
}
static void st_action_set_sel(int index)
{
char *sel_str = NULL;
if (mode != MODE_VAR) goto label_end;
if (strcmp(current_sel, NONE_STRING))
{
st_status_mess("Unsetting selection...");
(void)strcpy(current_sel, NONE_STRING);
}
else
{
sel_str = st_get_selected_item(index);
if (sel_str == NULL) goto label_end;
if (!strcmp(sel_str, ".."))
{
st_status_mess("Cannot set \"..\" as the selection");
goto label_end;
}
st_status_mess("Setting selection %s...", sel_str);
(void)strcpy(current_sel, sel_str);
st_status_mess("Selection %s... set", sel_str);
}
st_action_list(0);
label_end:
if (sel_str != NULL) free(sel_str);
return;
}
static void st_action_set(int index)
{
char *sel_str;
sel_str = st_get_selected_item(index);
if (sel_str == NULL) goto label_end;
if (!strcmp(sel_str, ".."))
{
switch (mode)
{
case MODE_DIR:
st_status_mess("Retrieving Study List");
if (st_get_study_list()) goto label_end;
break;
case MODE_FILE:
st_status_mess("Retrieving Directory List");
if (st_get_dir_list(NULL)) goto label_end;
break;
case MODE_VAR:
st_status_mess("Retrieving File List");
if (st_get_file_list(NULL)) goto label_end;
mode = MODE_FILE;
break;
default:
st_status_mess("Unknown Mode");
goto label_end;
}
}
else
{
switch (mode)
{
case MODE_STUDY:
st_status_mess("Setting Study %s", sel_str);
if (st_get_dir_list(sel_str)) goto label_end;
st_status_mess("Study %s set",sel_str);
break;
case MODE_DIR:
st_status_mess("Setting Directory %s", sel_str);
if (st_get_file_list(sel_str)) goto label_end;
st_status_mess("Directory %s set",sel_str);
break;
case MODE_FILE:
st_status_mess("Setting File %s", sel_str);
if (st_get_var_list(sel_str)) goto label_end;
st_status_mess("File %s set",sel_str);
break;
case MODE_VAR:
st_status_mess("Setting Variable %s", sel_str);
current_indice = -1;
st_status_mess("Variable %s set",sel_str);
Actions[ACTION_IND ].visible =
Actions[ACTION_STAT].visible =
break;
default:
st_status_mess("Unknown Mode");
goto label_end;
}
}
label_end:
if (sel_str != NULL) free(sel_str);
return;
}
static void st_action_indice(int index)
{
if (mode != MODE_VAR) goto label_end;
st_status_mess("Setting Indice %d", index);
Actions[ACTION_STAT].visible = 1;
current_indice = index;
label_end:
return;
}
static void st_action_connect(int number)
{
if (mode == MODE_INIT)
{
st_status_mess("Trying to connect to %s:%d",host,port);
if (st_get_study_list()) goto label_end;
Actions[ACTION_RUN ].visible = 0;
Actions[ACTION_CONN].visible = 0;
Actions[ACTION_DISC].visible = 1;
st_status_mess("Connected");
}
else
{
mode = MODE_INIT;
Actions[ACTION_LIST].visible = 0;
Actions[ACTION_SET ].visible = 0;
Actions[ACTION_IND ].visible = 0;
Actions[ACTION_INFO].visible = 0;
Actions[ACTION_STAT].visible = 0;
Actions[ACTION_SEL ].visible = 0;
Actions[ACTION_RUN ].visible = 1;
Actions[ACTION_CONN].visible = 1;
Actions[ACTION_DISC].visible = 0;
st_status_mess("Disconnected");
}
label_end:
return;
}
static void st_action_run(int number)
{
port = 0;
st_status_mess("Running GTXserver on a random port");
st_action_connect(number);
label_end:
return;
}
static void st_action_exit(int number)
{
switch (mode)
{
case MODE_INIT:
exit(0);
case MODE_STUDY:
case MODE_DIR:
case MODE_FILE:
case MODE_VAR:
exit(0);
default:
st_status_mess("Unknown mode!!");
}
return;
}
static void st_action_info(int index)
{
#define end_buffer &buffer[strlen(buffer)]
int i,j,len,nb_indices, *indices;
char buffer[2000];
char **alpha_indices;
char *sel_str,*comment;
indices = NULL;
nb_indices = 0;
alpha_indices = NULL;
sel_str = st_get_selected_item(index);
if (sel_str == NULL) goto label_end;
if (!strcmp(sel_str, ".."))
{
st_status_mess("Cannot get Information on \"..\"");
goto label_end;
}
switch (mode)
{
case MODE_FILE:
st_status_mess("Getting File Information...");
if (strcmp(sel_str, current_file))
{
(void)strcpy(current_file, sel_str);
}
(void)sprintf(buffer,"File: %s\n", sel_str);
(void)sprintf(end_buffer,"Type: %s\n",
GTXfile_types[file_info.
type]);
(void)sprintf(end_buffer,
"Dimension: %dD\n", file_info.
dimension);
(void)sprintf(end_buffer,"Number of Samples: %"GTXLONG_FORMAT"\n",
(void)sprintf(end_buffer,"Number of Lines: %d\n",
{
{
(void)sprintf(end_buffer, "Number of Nodes: (%d,%d)\n",
file_info.
NX,file_info.
NY);
(void)sprintf(end_buffer, "Origin : (%g,%g)\n",
file_info.
X0,file_info.
Y0);
(void)sprintf(end_buffer, "Mesh Dimensions: (%g,%g)\n",
file_info.
DX,file_info.
DY);
(void)sprintf(end_buffer, "Rotation Angle : %g\n",
else
(void)sprintf(end_buffer, "No Rotation\n");
}
{
(void)sprintf(end_buffer, "Number of Nodes: (%d,%d,%d)\n",
file_info.
NX,file_info.
NY,file_info.
NZ);
(void)sprintf(end_buffer, "Origin : (%g,%g,%g)\n",
file_info.
X0,file_info.
Y0,file_info.
Z0);
(void)sprintf(end_buffer, "Mesh Dimensions: (%g,%g,%g)\n",
file_info.
DX,file_info.
DY,file_info.
DZ);
{
(void)sprintf(end_buffer, "Rotation Angle around Z: %g\n",
(void)sprintf(end_buffer, "Rotation Angle around Y: %g\n",
(void)sprintf(end_buffer, "Rotation Angle around X: %g\n",
}
else
(void)sprintf(end_buffer, "No Rotation\n");
}
}
(void)sprintf(end_buffer, "Sample Number variable : %s\n",
{
(void)sprintf(end_buffer, "Line Number variable : %s\n",
(void)sprintf(end_buffer, "Relative Number variable : %s\n",
}
(void)sprintf(end_buffer, "X Gravity Center variable: %s\n",
(void)sprintf(end_buffer, "Y Gravity Center variable: %s\n",
(void)sprintf(end_buffer, "Z Gravity Center variable: %s\n",
{
(void)sprintf(end_buffer, "\nFaulted File:\n");
(void)sprintf(end_buffer, "2D Faults : %c\n",
(void)sprintf(end_buffer, "Auxiliary Variable Used: %c\n",
(void)sprintf(end_buffer, "Number of faults : %d\n",
(void)sprintf(end_buffer, "Number of segments : %d\n",
(void)sprintf(end_buffer, "Minimum Used Priority : %d\n",
(void)sprintf(end_buffer, "Maximum Used Priority : %d\n",
(void)sprintf(end_buffer, "Authorized Priority : %d\n",
goto label_end;
}
break;
case MODE_VAR:
st_status_mess("Getting Variable Information...");
if (strcmp(sel_str, current_var))
{
(void)strcpy(current_var, sel_str);
current_indice = -1;
}
(void)sprintf(buffer, "Variable : %s\n", sel_str);
(void)sprintf(end_buffer,"Type : %s\n",
GTXvar_types[var_info.
type]);
(void)sprintf(end_buffer,
"Alpha Length : %d\n", var_info.
alpha_length);
else
{
(void)sprintf(end_buffer, "Precision : 1 bit (selection)\n");
else
(void)sprintf(end_buffer, "Precision : %d bits\n",
(void)sprintf(end_buffer,
"Unit : %s\n", var_info.
unit);
}
if (comment[0] != '\0')
(void)sprintf(end_buffer,"Comment : %s\n", comment);
{
&alpha_indices)) goto label_end;
(void)sprintf(end_buffer, "Number of Indices : %d\n", nb_indices);
if (nb_indices != 0)
{
if (alpha_indices)
(void)sprintf(end_buffer, "Index -> Alpha Index\n");
else
(void)sprintf(end_buffer, "Indices:\n");
len = (int)strlen(buffer);
for (i=0, j=0; i<nb_indices; i++)
{
if (len > 1000)
{
(void)strcat(&buffer[len], "...\n");
break;
}
(void)sprintf(&buffer[len], "%06d", indices[i]);
len += 6;
if (alpha_indices)
{
(void)sprintf(&buffer[len], " -> %s\n", alpha_indices[i]);
len += (int)strlen(&buffer[len]);
}
else
{
if (++j == 5)
{
buffer[len++] = '\n';
buffer[len] = '\0';
j = 0;
}
}
}
}
}
break;
default:
(void)fprintf(stderr, "Unknown Mode!!");
exit(1);
}
(void)printf(buffer);
label_end:
if (sel_str != NULL) free(sel_str);
return;
#undef end_buffer
}
static void st_action_stat(int index)
{
#define end_buffer &buffer[strlen(buffer)]
char buffer[2000];
int compress;
gtx_long i,nech,n_kept,nb_def;
double dbl_test_val;
double *dbl_data = NULL;
double min,max,mean;
char *char_test_val = NULL;
char **char_data = NULL;
compress = 1;
nb_def = 0;
(void)sprintf(buffer, "Variable: %s\n",current_var);
st_status_mess("Reading variable...");
{
goto label_end;
}
else
goto label_end;
if (n_kept != nech)
(void)sprintf(end_buffer, "Total Number of Samples: %"GTXLONG_FORMAT
"/%"GTXLONG_FORMAT"\n",n_kept,nech);
else
(void)sprintf(end_buffer, "Total Number of Samples: %"GTXLONG_FORMAT"\n",nech);
{
for (i=0; i<n_kept; i++)
if (strcmp(char_data[i],char_test_val))
nb_def++;
(void)sprintf(end_buffer, "Number of Defined Samples: %"GTXLONG_FORMAT"\n",nb_def);
}
{
for (i=0; i<n_kept; i++)
if (dbl_data[i] == 1)
nb_def++;
(void)sprintf(end_buffer, "Number of Selected Samples: %"GTXLONG_FORMAT"\n",nb_def);
}
else
{
min = 1.e300;
max = -1.e300;
mean = 0.;
for (i=0; i<n_kept; i++)
if (dbl_data[i] != dbl_test_val)
{
nb_def++;
mean += dbl_data[i];
min = (dbl_data[i] < min)? dbl_data[i]: min;
max = (dbl_data[i] > max)? dbl_data[i]: max;
}
mean /= nb_def;
(void)sprintf(end_buffer, "Number of Defined Samples: %"GTXLONG_FORMAT"\n",nb_def);
(void)sprintf(end_buffer, "Minimum Value: %g\n",min);
(void)sprintf(end_buffer, "Maximum Value: %g\n",max);
(void)sprintf(end_buffer, "Mean Value: %g\n",mean);
}
(void)printf(buffer);
label_end:
#undef end_buffer
}
static void st_menu()
{
struct act *act_ptr;
int i,nb,index;
char line[80];
char cur_act[20];
Actions[ACTION_RUN ].visible = 1;
Actions[ACTION_CONN].visible = 1;
Actions[ACTION_EXIT].visible = 1;
while (1)
{
(void)printf("\n#*#*#*#*#*#*#*#*#*#*#*#*#\n");
(void)printf("#* Available actions *#\n");
(void)printf("#*#*#*#*#*#*#*#*#*#*#*#*#\n");
for (i=0; i<nb_Action; i++)
{
act_ptr = &Actions[i];
if (act_ptr->visible)
(void)printf("%-4s%7s %s\n", act_ptr->action,
(act_ptr->need_index)? "index:": ":", act_ptr->title);
}
(void)printf("\nYour choice: ");
fflush(stdout);
if (fgets(line,80,stdin) == NULL) break;
if (sscanf(line, "%19s%n",cur_act,&nb) != 1) continue;
for (i=0; i<nb_Action; i++)
{
act_ptr = &Actions[i];
#if defined(winnt)
if (act_ptr->visible && !_stricmp(cur_act, Actions[i].action))
#else
if (act_ptr->visible && !strcasecmp(cur_act, Actions[i].action))
#endif
{
index = 0;
if (act_ptr->need_index && sscanf(&line[nb], "%d", &index) != 1)
{
(void)fprintf(stderr,"action must be followed by a number");
break;
}
act_ptr->action_func(index);
break;
}
}
if (i == nb_Action)
(void)fprintf(stderr,"Not a valid action: \"%s\"", cur_act);
}
}
int main(int argc,
char *argv[])
{
char *tmp_str;
int i,error;
error = 1;
(void)strcpy(current_study,NONE_STRING);
(void)strcpy(current_dir, NONE_STRING);
(void)strcpy(current_file, NONE_STRING);
(void)strcpy(current_sel, NONE_STRING);
(void)strcpy(current_var, NONE_STRING);
current_indice = -1;
(void)strcpy(host, DEFAULT_GTX_SERVERNAME);
(void)strcpy(data_path, "");
for (i=1; i<argc; i++)
{
if (!strcmp(argv[i], "-port"))
{
i++;
if (i<argc)
{
port = (unsigned short)strtol(argv[i], &tmp_str, 10);
if (port == 0 && tmp_str == argv[i])
{
(void)fprintf(stderr,"Invalid Port Number.\n");
exit(1);
}
}
else
{
st_usage(argv[0], 0);
exit(1);
}
}
else if (!strcmp(argv[i], "-host"))
{
i++;
if (i<argc)
{
if (strlen(argv[i]) > MAX_HOSTNAME_LEN-1)
{
(void)fprintf(stderr,"Host Name must contain less than %d characters.\n",
MAX_HOSTNAME_LEN);
exit(1);
}
(void)strcpy(host, argv[i]);
}
else
{
st_usage(argv[0], 0);
exit(1);
}
}
else if (!strcmp(argv[i], "-path"))
{
i++;
if (i<argc)
{
if (strlen(argv[i]) >= MAX_PATH_LEN)
{
(void)fprintf(stderr,"Path must contain less than %d characters.\n",
MAX_PATH_LEN);
exit(1);
}
(void)strcpy(data_path, argv[i]);
}
else
{
st_usage(argv[0], 0);
exit(1);
}
}
else if (!strcmp(argv[i], "-debug"))
else if (!strcmp(argv[i], "-help"))
{
st_usage(argv[0], 1);
exit(0);
}
}
st_status_mess("Disconnected");
mode = MODE_INIT;
st_menu();
error = 0;
return(error);
}