1
0
mirror of https://github.com/cclassic/model-ghdl synced 2024-11-21 08:25:05 +01:00

Refactor indentation

This commit is contained in:
Markus Koch 2018-01-21 14:11:41 +01:00
parent bccb210a8f
commit 55105018aa
3 changed files with 498 additions and 500 deletions

144
gui.c
View File

@ -4,100 +4,98 @@
#define false 0 #define false 0
int gui_init(int *argc, char ***argv) { int gui_init(int *argc, char ***argv) {
gtk_init (argc, argv); gtk_init (argc, argv);
return 0; return 0;
} }
int showMessage(int message_type, char *text, char *defaultText, char **reply) { int showMessage(int message_type, char *text, char *defaultText, char **reply) {
GtkWidget *window; GtkWidget *window;
GtkWidget *entry; GtkWidget *entry;
GtkWidget *buttonOkay; GtkWidget *buttonOkay;
GtkWidget *buttonCancel; GtkWidget *buttonCancel;
GtkWidget *buttonBox; GtkWidget *buttonBox;
GtkWidget *mainBox; GtkWidget *mainBox;
GtkWidget *label; GtkWidget *label;
gboolean ret; gboolean ret;
char *entryText; char *entryText;
ret = true; ret = true;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "model-ghdl"); gtk_window_set_title(GTK_WINDOW(window), "model-ghdl");
label = gtk_label_new(text); label = gtk_label_new(text);
gtk_widget_show(label); gtk_widget_show(label);
entry = gtk_entry_new(); entry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry), (char*) defaultText); gtk_entry_set_text(GTK_ENTRY(entry), (char*) defaultText);
g_signal_connect (entry, "activate", g_signal_connect (entry, "activate",
G_CALLBACK(okay), entry); G_CALLBACK(okay), entry);
buttonOkay = gtk_button_new_with_label("Okay!"); buttonOkay = gtk_button_new_with_label("Okay!");
gtk_widget_show(buttonOkay); gtk_widget_show(buttonOkay);
if (MESSAGE_IS_INPUT(message_type)) { if (MESSAGE_IS_INPUT(message_type)) {
buttonCancel = gtk_button_new_with_label("Cancel"); buttonCancel = gtk_button_new_with_label("Cancel");
g_signal_connect (buttonCancel, "clicked", g_signal_connect (buttonCancel, "clicked",
G_CALLBACK(cancel), entry); G_CALLBACK(cancel), entry);
gtk_widget_show(buttonCancel); gtk_widget_show(buttonCancel);
gtk_widget_show(entry); gtk_widget_show(entry);
} }
buttonBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); buttonBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
if (MESSAGE_IS_INPUT(message_type)) { if (MESSAGE_IS_INPUT(message_type)) {
gtk_box_pack_start(GTK_BOX(buttonBox), buttonCancel, true, true, 0); gtk_box_pack_start(GTK_BOX(buttonBox), buttonCancel, true, true, 0);
} }
gtk_box_pack_start(GTK_BOX(buttonBox), buttonOkay, true, true, 0); gtk_box_pack_start(GTK_BOX(buttonBox), buttonOkay, true, true, 0);
g_signal_connect (buttonOkay, "clicked", g_signal_connect (buttonOkay, "clicked",
G_CALLBACK(okay), entry); G_CALLBACK(okay), entry);
gtk_widget_show(buttonBox); gtk_widget_show(buttonBox);
mainBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); mainBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
gtk_box_pack_start(GTK_BOX(mainBox), label, true, true, 10); gtk_box_pack_start(GTK_BOX(mainBox), label, true, true, 10);
if (MESSAGE_IS_INPUT(message_type)) { if (MESSAGE_IS_INPUT(message_type)) {
gtk_box_pack_start(GTK_BOX(mainBox), entry, true, true, 0); gtk_box_pack_start(GTK_BOX(mainBox), entry, true, true, 0);
} }
gtk_box_pack_start(GTK_BOX(mainBox), buttonBox, false, false, 0); gtk_box_pack_start(GTK_BOX(mainBox), buttonBox, false, false, 0);
gtk_widget_show(mainBox); gtk_widget_show(mainBox);
g_signal_connect (window, "destroy", g_signal_connect (window, "destroy",
G_CALLBACK (cancel), NULL); G_CALLBACK (cancel), NULL);
gtk_container_add(GTK_CONTAINER(window), mainBox); gtk_container_add(GTK_CONTAINER(window), mainBox);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 320, 10); gtk_window_set_default_size(GTK_WINDOW(window), 320, 10);
gtk_window_present(window); gtk_window_present(window);
gtk_main(); gtk_main();
if (MESSAGE_IS_INPUT(message_type)) { if (MESSAGE_IS_INPUT(message_type)) {
entryText = (char*) gtk_entry_get_text(GTK_ENTRY(entry)); entryText = (char*) gtk_entry_get_text(GTK_ENTRY(entry));
if (entryText[0] == 0) { if (entryText[0] == 0) {
ret = false; ret = false;
} }
else { else {
*reply = realloc(*reply, sizeof(char)*strlen(entryText)); *reply = realloc(*reply, sizeof(char)*strlen(entryText));
if (*reply != NULL) if (*reply != NULL)
strcpy(*reply, entryText); strcpy(*reply, entryText);
ret = true; ret = true;
} }
} }
gtk_widget_destroy(window); gtk_widget_destroy(window);
return ret; return ret;
} }
static void okay( GtkWidget *widget, static void okay(GtkWidget *widget, gpointer data)
gpointer data )
{ {
//g_print ("TEXT = %s\n", gtk_entry_get_text(GTK_ENTRY(data))); //g_print ("TEXT = %s\n", gtk_entry_get_text(GTK_ENTRY(data)));
gtk_main_quit(); gtk_main_quit();
} }
static void cancel( GtkWidget *widget, static void cancel(GtkWidget *widget, gpointer data)
gpointer data )
{ {
gtk_entry_set_text(GTK_ENTRY(data), ""); gtk_entry_set_text(GTK_ENTRY(data), "");
gtk_main_quit(); gtk_main_quit();
} }

4
gui.h
View File

@ -13,7 +13,7 @@ int gui_init(int *argc, char ***argv);
int showMessage(int message_type, char *text, char *defaultText, char **reply); int showMessage(int message_type, char *text, char *defaultText, char **reply);
// Slots // Slots
static void okay( GtkWidget *widget, gpointer data ); static void okay(GtkWidget *widget, gpointer data);
static void cancel ( GtkWidget *widget, gpointer data ); static void cancel(GtkWidget *widget, gpointer data);
#endif // GUI_H #endif // GUI_H

850
main.c
View File

@ -37,12 +37,12 @@ void debug( const char* format, ... );
void debug( const char* format, ... ) { void debug( const char* format, ... ) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
va_list args; va_list args;
// fprintf( stderr, "[D] " ); // fprintf( stderr, "[D] " );
va_start( args, format ); va_start( args, format );
vfprintf( stderr, format, args ); vfprintf( stderr, format, args );
va_end( args ); va_end( args );
// fprintf( stderr, "\n" ); // fprintf( stderr, "\n" );
#endif #endif
} }
@ -50,514 +50,514 @@ void debug( const char* format, ... ) {
// http://stackoverflow.com/questions/22802902/how-to-get-pid-of-process-executed-with-system-command-in-c // http://stackoverflow.com/questions/22802902/how-to-get-pid-of-process-executed-with-system-command-in-c
pid_t system2(const char * command, int * infp, int * outfp) pid_t system2(const char * command, int * infp, int * outfp)
{ {
int p_stdin[2]; int p_stdin[2];
int p_stdout[2]; int p_stdout[2];
pid_t pid; pid_t pid;
if (pipe(p_stdin) == -1) if (pipe(p_stdin) == -1)
return -1; return -1;
if (pipe(p_stdout) == -1) { if (pipe(p_stdout) == -1) {
close(p_stdin[0]); close(p_stdin[0]);
close(p_stdin[1]); close(p_stdin[1]);
return -1; return -1;
} }
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0) {
close(p_stdin[0]); close(p_stdin[0]);
close(p_stdin[1]); close(p_stdin[1]);
close(p_stdout[0]); close(p_stdout[0]);
close(p_stdout[1]); close(p_stdout[1]);
return pid; return pid;
} else if (pid == 0) { } else if (pid == 0) {
close(p_stdin[1]); close(p_stdin[1]);
dup2(p_stdin[0], 0); dup2(p_stdin[0], 0);
close(p_stdout[0]); close(p_stdout[0]);
dup2(p_stdout[1], 1); dup2(p_stdout[1], 1);
dup2(open("/dev/null", O_RDONLY), 2); dup2(open("/dev/null", O_RDONLY), 2);
/// Close all other descriptors for the safety sake. /// Close all other descriptors for the safety sake.
for (int i = 3; i < 4096; ++i) for (int i = 3; i < 4096; ++i)
close(i); close(i);
setsid(); setsid();
execl("/bin/sh", "sh", "-c", command, NULL); execl("/bin/sh", "sh", "-c", command, NULL);
_exit(1); _exit(1);
} }
} }
int run_ghdl(char *command, ...) { int run_ghdl(char *command, ...) {
FILE *proc; FILE *proc;
char buf[1 K]; char buf[1 K];
char cmd[1 K]; char cmd[1 K];
char *arr[5]; char *arr[5];
char *start; char *start;
char *ptr; char *ptr;
int arrc; int arrc;
int i; int i;
va_list argptr; va_list argptr;
va_start(argptr, command); va_start(argptr, command);
vsprintf(cmd, command, argptr); vsprintf(cmd, command, argptr);
va_end(argptr); va_end(argptr);
debug("RUN_GHDL: %s\n", cmd); debug("RUN_GHDL: %s\n", cmd);
proc = popen(cmd, "r"); proc = popen(cmd, "r");
if (proc == NULL) { if (proc == NULL) {
printf("Error: Could not invoke GHDL/GtkWave.\n"); printf("Error: Could not invoke GHDL/GtkWave.\n");
return 1; return 1;
} }
// ../blink/src/top.vhd:32:19: no declaration for "counter_i2" // ../blink/src/top.vhd:32:19: no declaration for "counter_i2"
// ../blink/src/abc.vhd:12:14:warning: package "mypack" does not require a body // ../blink/src/abc.vhd:12:14:warning: package "mypack" does not require a body
// v // v
// ** Error: /tmp/filename.vhd(32): (vcom-1136) Unknown identifier "counter_i2". // ** Error: /tmp/filename.vhd(32): (vcom-1136) Unknown identifier "counter_i2".
while(42){ while(42){
ptr = buf - 1; ptr = buf - 1;
do { do {
ptr++; ptr++;
*ptr = fgetc(proc); *ptr = fgetc(proc);
} while (*ptr != '\0' && *ptr != '\n' && *ptr != -1 && ptr < buf + sizeof(buf)); } while (*ptr != '\0' && *ptr != '\n' && *ptr != -1 && ptr < buf + sizeof(buf));
if (*ptr == -1) if (*ptr == -1)
break; break;
*ptr = '\0'; *ptr = '\0';
ptr = buf; ptr = buf;
start = buf; start = buf;
arrc = 0; arrc = 0;
//printf("** BUF: %s\n", buf); //printf("** BUF: %s\n", buf);
do { // Split into params do { // Split into params
if (*ptr == ' ') { if (*ptr == ' ') {
arr[arrc++] = start; arr[arrc++] = start;
break; break;
} }
if (arrc < 5 && (*ptr == ':' || *ptr == '\0')) { if (arrc < 5 && (*ptr == ':' || *ptr == '\0')) {
arr[arrc++] = start; arr[arrc++] = start;
if (*ptr == '\0') if (*ptr == '\0')
break; break;
else else
*ptr++ = 0; *ptr++ = 0;
start = ptr; start = ptr;
} }
} while (*ptr++ != '\0'); } while (*ptr++ != '\0');
if (arrc == 4) { if (arrc == 4) {
printf("** Error: %s(%s): (ghdl) %s\n", arr[0], arr[1], arr[3]); printf("** Error: %s(%s): (ghdl) %s\n", arr[0], arr[1], arr[3]);
} }
else if (arrc == 5) { else if (arrc == 5) {
printf("** Warning: %s(%s): (ghdl) %s\n", arr[0], arr[1], arr[4]); printf("** Warning: %s(%s): (ghdl) %s\n", arr[0], arr[1], arr[4]);
} }
else { else {
printf("** ghdl: "); printf("** ghdl: ");
for (i = 0; i < arrc; i++) { for (i = 0; i < arrc; i++) {
printf("%s", arr[i]); printf("%s", arr[i]);
} }
printf("\n"); printf("\n");
} }
fflush(stdout); fflush(stdout);
} }
return pclose(proc); return pclose(proc);
} }
int run_simulation(char *command, ...) { int run_simulation(char *command, ...) {
FILE *proc; FILE *proc;
char buf[1 K]; char buf[1 K];
char cmd[1 K]; char cmd[1 K];
va_list argptr; va_list argptr;
va_start(argptr, command); va_start(argptr, command);
vsprintf(cmd, command, argptr); vsprintf(cmd, command, argptr);
va_end(argptr); va_end(argptr);
debug("RUN_SIM: %s\n", cmd); debug("RUN_SIM: %s\n", cmd);
proc = popen(cmd, "r"); proc = popen(cmd, "r");
if (proc == NULL) { if (proc == NULL) {
printf("[E] Could not start the simulation.\n"); printf("[E] Could not start the simulation.\n");
return 1; return 1;
} }
while(fgets(buf, sizeof(buf), proc)!=NULL){ while(fgets(buf, sizeof(buf), proc)!=NULL){
printf("** sim: %s", buf); printf("** sim: %s", buf);
} }
printf("\n"); printf("\n");
return pclose(proc); return pclose(proc);
} }
int run_gtkwave(char *toplevel, char *command, ...) { int run_gtkwave(char *toplevel, char *command, ...) {
FILE *fp; FILE *fp;
pid_t pid; pid_t pid;
char cmd[1 K]; char cmd[1 K];
char lockpath[1 K]; char lockpath[1 K];
va_list argptr; va_list argptr;
sprintf(lockpath, "/tmp/model-ghdl-gtkw-%s.lock", toplevel); sprintf(lockpath, "/tmp/model-ghdl-gtkw-%s.lock", toplevel);
fp = fopen(lockpath,"r"); fp = fopen(lockpath,"r");
if (fp) { if (fp) {
fgets(cmd, sizeof(cmd), fp); // lets (ab)use the cmd variable here fgets(cmd, sizeof(cmd), fp); // lets (ab)use the cmd variable here
pid = atoi(cmd); pid = atoi(cmd);
fclose(fp); fclose(fp);
if (kill(pid, 0)) { // Check if the process still lives if (kill(pid, 0)) { // Check if the process still lives
pid = -1; pid = -1;
} }
/*else { /*else {
printf("GtkWave is already running.\n"); printf("GtkWave is already running.\n");
}*/ }*/
} }
else { else {
pid = -1; pid = -1;
} }
if (pid < 0) { if (pid < 0) {
va_start(argptr, command); va_start(argptr, command);
vsprintf(cmd, command, argptr); vsprintf(cmd, command, argptr);
va_end(argptr); va_end(argptr);
debug("RUN_GTKWAVE: %s\n", cmd); debug("RUN_GTKWAVE: %s\n", cmd);
pid = system2(cmd, NULL, NULL); pid = system2(cmd, NULL, NULL);
//debug("--> PID=%d\n", pid); //debug("--> PID=%d\n", pid);
// Prevent gtkw from starting again each time // Prevent gtkw from starting again each time
fp = fopen(lockpath,"w"); fp = fopen(lockpath,"w");
if (fp) { if (fp) {
fprintf(fp, "%d", pid); fprintf(fp, "%d", pid);
fclose(fp); fclose(fp);
} }
else { else {
printf("[W] Could not create temp file %s! Ignoring...", lockpath); printf("[W] Could not create temp file %s! Ignoring...", lockpath);
} }
} }
return 0; return 0;
} }
int vsim(int argc, char **argv) int vsim(int argc, char **argv)
{ {
int ret; int ret;
char *text = NULL; char *text = NULL;
char *work = NULL; char *work = NULL;
char *toplevel = NULL; char *toplevel = NULL;
char *gtkwPrefix = NULL; char *gtkwPrefix = NULL;
int i; int i;
char *ptr = NULL; char *ptr = NULL;
char *lastPtr; char *lastPtr;
char workdir[1 K]; char workdir[1 K];
char sourcedir[1 K]; char sourcedir[1 K];
char *params = NULL; char *params = NULL;
char *simtime = NULL; char *simtime = NULL;
char *simExt = NULL; char *simExt = NULL;
char *outFileType = NULL; char *outFileType = NULL;
char vhdlver[16] = ""; char vhdlver[16] = "";
int precompiled = 1; int precompiled = 1;
FILE *fp; FILE *fp;
append_string(&params,""); append_string(&params,"");
gui_init(&argc, &argv); gui_init(&argc, &argv);
if (!getcwd(sourcedir, sizeof(sourcedir))) { // Default compile dir is cwd if (!getcwd(sourcedir, sizeof(sourcedir))) { // Default compile dir is cwd
sourcedir[0] = 0; sourcedir[0] = 0;
printf("[W] Could not get cwd!\n"); printf("[W] Could not get cwd!\n");
} }
fp = fopen("/tmp/model-ghdl-vsim","r"); fp = fopen("/tmp/model-ghdl-vsim","r");
if (fp) { if (fp) {
fgets(workdir, sizeof(workdir), fp); // lets (ab)use the workdir variable here fgets(workdir, sizeof(workdir), fp); // lets (ab)use the workdir variable here
append_string(&simtime, workdir); append_string(&simtime, workdir);
fclose(fp); fclose(fp);
} }
else { else {
append_string(&simtime, "100ns"); append_string(&simtime, "100ns");
} }
fp = fopen("/tmp/model-ghdl-vcom","r"); fp = fopen("/tmp/model-ghdl-vcom","r");
if (fp) { if (fp) {
fgets(workdir, sizeof(workdir), fp); // (ab)use workdir variable as temp fgets(workdir, sizeof(workdir), fp); // (ab)use workdir variable as temp
if (!strcmp(workdir,"nopre\n")) if (!strcmp(workdir,"nopre\n"))
precompiled = 0; precompiled = 0;
fgets(workdir, sizeof(workdir), fp); fgets(workdir, sizeof(workdir), fp);
workdir[strlen(workdir)-1] = 0; workdir[strlen(workdir)-1] = 0;
fgets(vhdlver, sizeof(vhdlver), fp); fgets(vhdlver, sizeof(vhdlver), fp);
fclose(fp); fclose(fp);
} }
else { else {
printf("[E] Could not read temp file /tmp/model-ghdl-vcom! Aborting..."); printf("[E] Could not read temp file /tmp/model-ghdl-vcom! Aborting...");
} }
printf ("[I] Emulating vsim.\n"); printf ("[I] Emulating vsim.\n");
// -gui work.toplevel(RTL) // -gui work.toplevel(RTL)
for (i=1; i < argc; ++i) { for (i=1; i < argc; ++i) {
if (ptr == NULL && GETOPT("-gui")) { // only allow once if (ptr == NULL && GETOPT("-gui")) { // only allow once
append_string(&ptr, argv[i]); append_string(&ptr, argv[i]);
lastPtr = ptr; lastPtr = ptr;
for (; *ptr != 0; ptr++) { for (; *ptr != 0; ptr++) {
if (*ptr >= 'A' && *ptr <= 'Z') if (*ptr >= 'A' && *ptr <= 'Z')
*ptr = *ptr - ('A'-'a'); // convert to lower case *ptr = *ptr - ('A'-'a'); // convert to lower case
if (*ptr == '.') { if (*ptr == '.') {
*ptr++ = 0; *ptr++ = 0;
work = lastPtr; work = lastPtr;
lastPtr = ptr; lastPtr = ptr;
} }
else if (*ptr == '(') { else if (*ptr == '(') {
*ptr++ = 0; *ptr++ = 0;
toplevel = lastPtr; toplevel = lastPtr;
lastPtr = ptr; lastPtr = ptr;
} }
} }
// free(ptr); DO NOT FREE, we still need it. // free(ptr); DO NOT FREE, we still need it.
// ptr = NULL; // ptr = NULL;
} }
else if (GETOPT("-type")) { else if (GETOPT("-type")) {
append_string(&simExt, argv[i]); append_string(&simExt, argv[i]);
} }
else if (GETOPT("-ghdl")) { else if (GETOPT("-ghdl")) {
append_string(&params, " "); append_string(&params, " ");
append_string(&params, argv[i]); append_string(&params, argv[i]);
} }
else if (GETOPT("-gtkwprefix")) { else if (GETOPT("-gtkwprefix")) {
gtkwPrefix = argv[i]; gtkwPrefix = argv[i];
} }
else { else {
} }
} }
if (simExt == NULL) if (simExt == NULL)
append_string(&simExt, "ghw"); append_string(&simExt, "ghw");
if (!strcmp(simExt,"ghw")) { if (!strcmp(simExt,"ghw")) {
append_string(&outFileType, "wave"); append_string(&outFileType, "wave");
} }
else if (!strcmp(simExt,"vcd")) { else if (!strcmp(simExt,"vcd")) {
append_string(&outFileType, "vcd"); append_string(&outFileType, "vcd");
} }
else if (!strcmp(simExt,"fst")) { else if (!strcmp(simExt,"fst")) {
append_string(&outFileType, "fst"); append_string(&outFileType, "fst");
} }
else { else {
fprintf(stderr, "[E] Unknown output file type!"); fprintf(stderr, "[E] Unknown output file type!");
showMessage(MESSAGE_ERROR, "Error! Unknown output file type.", NULL, NULL); showMessage(MESSAGE_ERROR, "Error! Unknown output file type.", NULL, NULL);
return 127; return 127;
} }
chdir(workdir); chdir(workdir);
if (gtkwPrefix == NULL) { if (gtkwPrefix == NULL) {
append_string(&gtkwPrefix, ""); append_string(&gtkwPrefix, "");
} }
printf("[I] Compiling...\n"); printf("[I] Compiling...\n");
if (run_ghdl("ghdl -%c %s --work=%s --workdir=\"%s\" %s %s", (precompiled ? 'e' : 'm'), vhdlver, work, workdir, params, toplevel)) { if (run_ghdl("ghdl -%c %s --work=%s --workdir=\"%s\" %s %s", (precompiled ? 'e' : 'm'), vhdlver, work, workdir, params, toplevel)) {
fprintf(stderr, "[E] Compilation failed!"); fprintf(stderr, "[E] Compilation failed!");
showMessage(MESSAGE_ERROR, "Error! Compilation failed.", NULL, NULL); showMessage(MESSAGE_ERROR, "Error! Compilation failed.", NULL, NULL);
} }
else { else {
if (ret = showMessage(MESSAGE_INPUT, "Enter the simulation time: ", simtime, &text)) { if (ret = showMessage(MESSAGE_INPUT, "Enter the simulation time: ", simtime, &text)) {
free(simtime); free(simtime);
simtime = NULL; simtime = NULL;
append_string(&simtime, text); append_string(&simtime, text);
fp = fopen("/tmp/model-ghdl-vsim","w"); fp = fopen("/tmp/model-ghdl-vsim","w");
if (fp) { if (fp) {
fprintf(fp, "%s", simtime); fprintf(fp, "%s", simtime);
fclose(fp); fclose(fp);
} }
printf("[I] Simulating...\n"); printf("[I] Simulating...\n");
if (run_simulation("%s/%s --stop-time=%s --%s=%s.%s", workdir, toplevel, simtime, outFileType, toplevel, simExt)) { if (run_simulation("%s/%s --stop-time=%s --%s=%s.%s", workdir, toplevel, simtime, outFileType, toplevel, simExt)) {
fprintf(stderr, "[E] Simulation failed!"); fprintf(stderr, "[E] Simulation failed!");
showMessage(MESSAGE_ERROR, "Error! Simulation failed.", NULL, NULL); showMessage(MESSAGE_ERROR, "Error! Simulation failed.", NULL, NULL);
} }
else { else {
if (run_gtkwave(toplevel, "gtkwave %s/%s.%s --save=\"%s/%s%s.gtkw\"", workdir, toplevel, simExt, sourcedir, gtkwPrefix, toplevel)) { if (run_gtkwave(toplevel, "gtkwave %s/%s.%s --save=\"%s/%s%s.gtkw\"", workdir, toplevel, simExt, sourcedir, gtkwPrefix, toplevel)) {
fprintf(stderr, "[E] Could not open GtkWave!"); fprintf(stderr, "[E] Could not open GtkWave!");
showMessage(MESSAGE_ERROR, "Error! Could not open GtkWave!", NULL, NULL); showMessage(MESSAGE_ERROR, "Error! Could not open GtkWave!", NULL, NULL);
} }
printf("[I] DONE.\n"); printf("[I] DONE.\n");
} }
} }
return 0; return 0;
} }
free(ptr); // Now we can free it free(ptr); // Now we can free it
return 255; return 255;
} }
int vcom(int argc, char **argv) int vcom(int argc, char **argv)
{ {
int i; int i;
int slen = 0; int slen = 0;
char workdir[1 K]; char workdir[1 K];
char *params = NULL; char *params = NULL;
char *work = NULL; char *work = NULL;
char *files = NULL; char *files = NULL;
char vhdlver[16] = ""; char vhdlver[16] = "";
FILE *fp = NULL; FILE *fp = NULL;
int precompile = 1; int precompile = 1;
printf ("[I] Emulating vcom.\n"); printf ("[I] Emulating vcom.\n");
if (!getcwd(workdir, sizeof(workdir))) { // Default compile dir is cwd if (!getcwd(workdir, sizeof(workdir))) { // Default compile dir is cwd
fprintf(stderr, "[E] Could not get cwd!\n"); fprintf(stderr, "[E] Could not get cwd!\n");
return 1; return 1;
} }
for (i=1; i < argc; ++i) { for (i=1; i < argc; ++i) {
if (GETOPT("-work")) { if (GETOPT("-work")) {
work = argv[i]; work = argv[i];
} }
else if (GETOPT("-workdir")) { else if (GETOPT("-workdir")) {
strcpy(workdir, argv[i]); strcpy(workdir, argv[i]);
} }
else if (ISOPT("-87")) { else if (ISOPT("-87")) {
strcpy(vhdlver, "--std=87"); strcpy(vhdlver, "--std=87");
} }
else if (ISOPT("-93")) { else if (ISOPT("-93")) {
strcpy(vhdlver, "--std=93"); strcpy(vhdlver, "--std=93");
} }
else if (ISOPT("-93c")) { else if (ISOPT("-93c")) {
strcpy(vhdlver, "--std=93c"); strcpy(vhdlver, "--std=93c");
} }
else if (ISOPT("-2000")) { else if (ISOPT("-2000")) {
strcpy(vhdlver, "--std=00"); strcpy(vhdlver, "--std=00");
} }
else if (ISOPT("-2002")) { else if (ISOPT("-2002")) {
strcpy(vhdlver, "--std=02"); strcpy(vhdlver, "--std=02");
} }
else if (ISOPT("-2008")) { else if (ISOPT("-2008")) {
strcpy(vhdlver, "--std=08"); strcpy(vhdlver, "--std=08");
} }
else if (ISOPT("-no-precompile")) { else if (ISOPT("-no-precompile")) {
precompile = 0; precompile = 0;
} }
else if (GETOPT("-ghdl")) { else if (GETOPT("-ghdl")) {
append_string(&params, " "); append_string(&params, " ");
append_string(&params, argv[i]); append_string(&params, argv[i]);
} }
else if (argv[i][0] != '-'){ // VHDL file else if (argv[i][0] != '-'){ // VHDL file
slen += strlen(argv[i]) + 2; slen += strlen(argv[i]) + 2;
files = realloc(files, slen * sizeof(char)); files = realloc(files, slen * sizeof(char));
strcat(files, " "); strcat(files, " ");
strcat(files, argv[i]); strcat(files, argv[i]);
} }
} }
if (!params) if (!params)
append_string(&params, ""); append_string(&params, "");
if (!work) if (!work)
append_string(&work, "work"); append_string(&work, "work");
if (!files) { if (!files) {
fprintf(stderr, "[E] No input files specified.\n"); fprintf(stderr, "[E] No input files specified.\n");
return 2; return 2;
} }
// Info for vsim later on // Info for vsim later on
fp = fopen("/tmp/model-ghdl-vcom","w"); fp = fopen("/tmp/model-ghdl-vcom","w");
if (fp) { if (fp) {
fprintf(fp, "%s\n%s\n%s", (precompile ? "pre" : "nopre"), workdir, vhdlver); fprintf(fp, "%s\n%s\n%s", (precompile ? "pre" : "nopre"), workdir, vhdlver);
fclose(fp); fclose(fp);
} }
else { else {
printf("[W] Could not create temp file /tmp/model-ghdl-vcom! Ignoring..."); printf("[W] Could not create temp file /tmp/model-ghdl-vcom! Ignoring...");
} }
run_ghdl("ghdl -i --work=%s --workdir=%s %s %s %s 2>&1", run_ghdl("ghdl -i --work=%s --workdir=%s %s %s %s 2>&1",
work, workdir, vhdlver, params, files); work, workdir, vhdlver, params, files);
run_ghdl("ghdl -%c --work=%s --workdir=%s %s %s %s 2>&1", run_ghdl("ghdl -%c --work=%s --workdir=%s %s %s %s 2>&1",
(precompile ? 'a' : 's'), work, workdir, vhdlver, params, files); (precompile ? 'a' : 's'), work, workdir, vhdlver, params, files);
free(files); free(files);
printf("[I] DONE.\n"); printf("[I] DONE.\n");
return 0; return 0;
} }
char* append_string(char **dest, const char *src) { char* append_string(char **dest, const char *src) {
if (*dest == NULL) { if (*dest == NULL) {
*dest = malloc(strlen(src) * sizeof(char)); *dest = malloc(strlen(src) * sizeof(char));
if (*dest == NULL) if (*dest == NULL)
return NULL; return NULL;
*dest[0] = 0; *dest[0] = 0;
} }
else { else {
*dest = realloc(*dest, (strlen(*dest) + strlen(src) + 1) * sizeof(char)); *dest = realloc(*dest, (strlen(*dest) + strlen(src) + 1) * sizeof(char));
} }
strcat(*dest, src); strcat(*dest, src);
return *dest; return *dest;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
printf ("model-ghdl revision %s, compiled on %s.\n", PROGRAM_REVISION, __DATE__); printf ("model-ghdl revision %s, compiled on %s.\n", PROGRAM_REVISION, __DATE__);
switch (get_application(argv[0])) { switch (get_application(argv[0])) {
case PROG_VCOM: case PROG_VCOM:
return vcom(argc, argv); return vcom(argc, argv);
case PROG_VSIM: case PROG_VSIM:
return vsim(argc, argv); return vsim(argc, argv);
case PROG_VMAP: case PROG_VMAP:
case PROG_VLIB: case PROG_VLIB:
case PROG_VDEL: case PROG_VDEL:
return 0; return 0;
default: default:
return 255; return 255;
} }
} }
// Detects which function to call depending on the program name in argv[0] // Detects which function to call depending on the program name in argv[0]
int get_application(const char *call) { int get_application(const char *call) {
char *pos; char *pos;
pos = (char*) getAfter(call, "/"); pos = (char*) getAfter(call, "/");
if (strcmp(pos, "vcom") == 0) { if (strcmp(pos, "vcom") == 0) {
return PROG_VCOM; return PROG_VCOM;
} }
else if (strcmp(pos, "vsim") == 0) { else if (strcmp(pos, "vsim") == 0) {
return PROG_VSIM; return PROG_VSIM;
} }
else if (strcmp(pos, "vlib") == 0) { else if (strcmp(pos, "vlib") == 0) {
return PROG_VLIB; return PROG_VLIB;
} }
else if (strcmp(pos, "vmap") == 0) { else if (strcmp(pos, "vmap") == 0) {
return PROG_VMAP; return PROG_VMAP;
} }
else if (strcmp(pos, "vdel") == 0) { else if (strcmp(pos, "vdel") == 0) {
return PROG_VDEL; return PROG_VDEL;
} }
else { else {
fprintf(stderr, "[E] Program not recognized: %s\n", pos); fprintf(stderr, "[E] Program not recognized: %s\n", pos);
return PROG_UNKNOWN; return PROG_UNKNOWN;
} }
} }
// Returns the string after the last occurence of __needle // Returns the string after the last occurence of __needle
const char *getAfter (const char *__haystack, const char *__needle) { const char *getAfter (const char *__haystack, const char *__needle) {
char *pos, *realPos; char *pos, *realPos;
char *haystack; char *haystack;
haystack = (char*) __haystack; haystack = (char*) __haystack;
pos = (char*) __haystack; pos = (char*) __haystack;
while (pos != NULL) { while (pos != NULL) {
realPos = pos + 1; realPos = pos + 1;
pos = strstr(haystack, __needle); pos = strstr(haystack, __needle);
if (haystack == __haystack && pos == NULL) // If no __needle is present at all... if (haystack == __haystack && pos == NULL) // If no __needle is present at all...
realPos = (char*) __haystack; // Return the entire string realPos = (char*) __haystack; // Return the entire string
haystack = pos + 1; haystack = pos + 1;
} }
return realPos; return realPos;
} }