/* Copyright (C) 1993 Bell-Northern Research This file is part of vmkr. Vmkr is distributed in the hope that it will be useful, but without any warranty. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Everyone is granted permission to copy, modify and redistribute vmkr, but only under the conditions described in the document "vmkr copying permission notice". An exact copy of the document is supposed to have been given to you along with vmkr so that you can know how you may redistribute it all. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ #include "typedef.h" /* * Author : Himanshu M. Thaker * Date : March 5, 1991 * Compiling : * After uncompressing and untaring, you should have * the following files. * Makefile * README * back_ann.c * create_make.c * get_tokens.c * makegen.c * typedef.h * update.c * vmkr.l * This program can be compiled with the provided makefile, * by the command "make all". It will create an executable called * vmkr, which can then be moved to the appropriate bin. Additionally, * the file vmkr.l which contains a troff man page listing, can be * moved to the appropriate directory where the local man pages * are kept (eg. /usr/local/man). * * Usage : * See the man page for information. * * Comments : * Vmkr is a makefile maker program for VHDL source code. It * will examine the source code, and from them, determine the inter- * dependencies, as well as the order of compilation required. The * document "Internal Workings of vmkr", by H. M. Thaker describes * how vmkr works. This document also includes a complete list of * dependency rules, for vhdl source code. * * If you have any questions or suggestions, you can reach * the author by email to hemi@bnr.ca * * NOTE NOTE NOTE NOTE NOTE !!!!!!! * Vmkr EXPECTS that every design unit (eg. entity, architecture * configuration, package, package body) be placed in a separate file. * If this convention is NOT adheared to, vmkr may NOT be able to * always give the optimal order of compilation required. * The only exception to this rule is that a top level entity * and architecture MAY reside in the same file. * Note that you can use the program vsplit to split your files into the * appropriate sub files. */ /* * hashtab is a table that holds the keywords that we will look for * in the vhdl source files. It is initialized, and used in the * source file get_tokens.c */ struct names *hashtab[BASE]; /* * The following definitions define the head pointers for the * five MAIN linked lists, of the units found while parsing * the source codes. */ struct entity_struct *header_entity; struct arch_struct *header_arch; struct packages *header_package; struct config_struct *header_config; struct lib_names *header_lib; /* * GLOBAL FLAGS : * return_code - if an error is encountered, return_code is set to -1 * print_libs - used to indicate if the user wishes depencencies * on other libraries to be printed. VERY usefull if * designing large VHDL models, split across multiple * directories, and multiple VHDL libraries * all_flag_set - used to indicate if all "loose" units should have * makefile code generated for them. This flag is * set by default. * state_files_in_current_directory - used to indicate if the user wants * the state information files to be created in the * current directory (note that vmkr does not create them * directly... they are created by the makefile that * vmkr creates). */ int return_code; int print_libs; int all_flag_set; int state_files_in_current_directory; int tool_set; main(argc, argv) int argc; char *argv[]; { char file_name[MAXTOKEN]; char token[MAXTOKEN]; struct token_holder *tokens, *get_tokens(), *tmp_tokens, *tmp_tokens2; /* --- can be deleted struct names *tmp_name; struct entity_struct *tmp_entity; struct arch_struct *tmp_arch; struct package_ptrs *tmp_use; struct config_struct *tmp_config; struct binding_struct *tmp_binding; int i; */ int err; char *s; int c; int errflg; extern int optind, opterr; extern char *optarg; char *m2l(); print_libs = FALSE; all_flag_set = TRUE; state_files_in_current_directory = FALSE; return_code = 0; /* * the default toolset is currently synopsys */ tool_set = NONE; err = FALSE; errflg = 0; /* * print out the banner... */ fprintf(stderr, "BNR vmkr version %s (%s)\n", VERSION, CREATE_DATE); fprintf(stderr, "Copyright (C) 1993 Bell-Northern Research.\n"); fprintf(stderr, "Please email bugs/suggestions to hemi@bnr.ca\n"); /* * First, get all the options that the user has specified. */ /* * Added ifdef because apollos don't have the -p option for mkdir * Thus to keep one source code, apollos can only have the * state variables in the current directory. */ #ifdef apollo state_files_in_current_directory = TRUE; while ((c = getopt (argc, argv, "alt?")) != EOF) #else while ((c = getopt (argc, argv, "aclt:?")) != EOF) #endif switch (c) { /* * the -a option now prevents making of loose entity/architectures */ case 'a': all_flag_set = FALSE; break; #ifndef apollo case 'c': state_files_in_current_directory = TRUE; break; #endif case 'l': print_libs = TRUE; break; case 't': strcpy(token, optarg); if ( (stringcmp(token, "VANTAGE") == 0) || (stringcmp(token, "V") == 0) ) tool_set = VANTAGE; else if ( (stringcmp(token, "INTERMETRICS") == 0) || (stringcmp(token, "I") == 0) ) tool_set = INTERMETRICS; else if ( (stringcmp(token, "MODELTECH") == 0) || (stringcmp(token, "M") == 0) ) tool_set = MODELTECH; else if ( (stringcmp(token, "SYNOPSYS") == 0) || (stringcmp(token, "S") == 0) ) tool_set = SYNOPSYS; else if ( (stringcmp(token, "XL") == 0) || (stringcmp(token, "X") == 0) ) tool_set = XL; else if ( (stringcmp(token, "DASIX") == 0) || (stringcmp(token, "D") == 0) ) tool_set = DASIX; else if ( (stringcmp(token, "REDAC") == 0) || (stringcmp(token, "R") == 0) ) tool_set = REDAC; else fprintf(stderr, "ERROR : no such toolset %s\n", optarg); break; case '?': errflg++; } if (tool_set == NONE) { fprintf(stderr, "no toolset specified... you must specify one.\n"); errflg++; } if (errflg) { fprintf (stderr, "usage: vmkr [-aclt] file1 [file2]...\n"); fprintf (stderr, " -a prevent all loose units from analyzed\n"); fprintf (stderr, " -c keeps vmkr state files in current directory\n"); fprintf (stderr, " -l print libraries\n"); fprintf (stderr, " -t alternate toolset\n"); fprintf (stderr, " v for Vantage, i for Intermetrics,\n"); fprintf (stderr, " m for Modeltech, s for Synopsys (default),\n"); fprintf (stderr, " x for XL, d for Dasix, or r for Racal-Redac\n"); exit (2); } /* * Create the database of keywords. */ create_database(); /* * now, initialize headers for the dependancy database */ header_entity = NULL; header_arch = NULL; header_package = NULL; header_config = NULL; /* * for all the files... */ for ( ; optind < argc; optind++) { sprintf(file_name, "%s", argv[optind]); /* * parse the tokens... */ tokens = get_tokens(file_name); /* * now, use the data generated to update the dependancies * database. */ update_dependancies(tokens, file_name); /* * Now, free up the tokens from the file just parsed. */ while (tokens != NULL) { tmp_tokens = tokens->next; tmp_tokens2 = tokens; if (tokens->keywrd != NULL) free(tokens->keywrd); if (tokens->var1 != NULL) free(tokens->var1); if (tokens->var2 != NULL) free(tokens->var2); if (tokens->token != NULL) free(tokens->token); free(tokens); tokens = tmp_tokens; } } /* * After reading in all the files, we must now back annotate * the databases to link architectures to entities, etc. */ back_annotate(); /* * Finally, create the make file, based on the dependances * created above. */ create_make(); exit(return_code); }