* Initial support of CMake
+ Generation of header files is now made through a C program to make it more portable.
This commit is contained in:
		
							parent
							
								
									0ac16f6116
								
							
						
					
					
						commit
						a4650360a3
					
				
					 2 changed files with 352 additions and 0 deletions
				
			
		
							
								
								
									
										43
									
								
								modules/src/em_data/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								modules/src/em_data/CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| cmake_minimum_required (VERSION 2.9) | ||||
| project(em_data) | ||||
| 
 | ||||
| set(SRC | ||||
|  em_spec.h | ||||
|  em_pseu.h | ||||
|  em_pseu.c | ||||
|  em_mnem.h | ||||
|  em_mnem.c | ||||
|  em_flag.c | ||||
|  em_ptyp.c | ||||
| ) | ||||
| 
 | ||||
| set(INCLUDE_DIRS  | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/../../h  | ||||
|  ${CMAKE_CURRENT_SOURCE_DIR}/../../../h | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| add_library(${PROJECT_NAME} ${SRC}) | ||||
| target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${INCLUDE_DIRS}) | ||||
| target_link_libraries(${PROJECT_NAME} emheaders emh) | ||||
| 
 | ||||
| add_executable(makeem makeem.c) | ||||
| target_link_libraries(makeem data) | ||||
| 
 | ||||
| add_custom_command( | ||||
|   OUTPUT em_spec.h em_pseu.h em_pseu.c em_mnem.h em_mnem.c em_flag.c | ||||
|   COMMAND makeem  ${CMAKE_CURRENT_SOURCE_DIR}/../../../h/em_table | ||||
|   COMMENT "Generating em_data files" | ||||
|   DEPENDS makeem | ||||
| ) | ||||
| 
 | ||||
| install(TARGETS ${PROJECT_NAME}  | ||||
|         RUNTIME DESTINATION bin | ||||
|         LIBRARY DESTINATION lib | ||||
|         ARCHIVE DESTINATION lib | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										309
									
								
								modules/src/em_data/makeem.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								modules/src/em_data/makeem.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,309 @@ | |||
| /** A utility to convert the em definition table to generated code.
 | ||||
|  *  This is more portable than the shell scripts that currently | ||||
|  *  exist. | ||||
|  * | ||||
|  *  This tool should only be called if the em_table is changeed, it creates | ||||
|  *  the following files: | ||||
|  *   em_spec.h | ||||
|  *   em_pseu.h | ||||
|  *   em_pseu.c | ||||
|  *   em_mnem.h | ||||
|  *   em_mnem.c | ||||
|  *   em_flag.c | ||||
|  * | ||||
|  * | ||||
|  */ | ||||
| #include <ctype.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <stdbool.h> | ||||
| #include "array.h" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| size_t trimwhitespace(char *out, size_t len, const char *str) | ||||
| { | ||||
|   if(len == 0) | ||||
|     return 0; | ||||
| 
 | ||||
|   const char *end; | ||||
|   size_t out_size; | ||||
| 
 | ||||
|   // Trim leading space
 | ||||
|   while(isspace((unsigned char)*str)) str++; | ||||
| 
 | ||||
|   if(*str == 0)  // All spaces?
 | ||||
|   { | ||||
|     *out = 0; | ||||
|     return 1; | ||||
|   } | ||||
| 
 | ||||
|   // Trim trailing space
 | ||||
|   end = str + strlen(str) - 1; | ||||
|   while(end > str && isspace((unsigned char)*end)) end--; | ||||
|   end++; | ||||
| 
 | ||||
|   // Set output size to minimum of trimmed string length and buffer size minus 1
 | ||||
|   out_size = (end - str) < len-1 ? (end - str) : len-1; | ||||
| 
 | ||||
|   // Copy trimmed string and add null terminator
 | ||||
|   memcpy(out, str, out_size); | ||||
|   out[out_size] = 0; | ||||
| 
 | ||||
|   return out_size; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #define BUFFER_SIZE 4096 | ||||
| 
 | ||||
| /** This section contains indexes to the different limits as well as important
 | ||||
|  *  constant values */ | ||||
| #define SECTION_INDEXES  0 | ||||
| /** This section contains the "opcodes" for the different mnemonics */ | ||||
| #define SECTION_MNEMONICS SECTION_INDEXES+1 | ||||
| /** This section contains the "opcodes" for the em machine */ | ||||
| #define SECTION_OPCODES SECTION_MNEMONICS+1 | ||||
| 
 | ||||
| 
 | ||||
| static char inbuffer[BUFFER_SIZE]; | ||||
| static char buffer[BUFFER_SIZE]; | ||||
| 
 | ||||
| static struct array section_index; | ||||
| static struct array section_mnemonics; | ||||
| static struct array section_opcodes; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** Separates the string into its separate tokens,
 | ||||
|  *  and fills up the column data structure accordingly. | ||||
|  * | ||||
|  *  maxcolumns indicates the maximum number of columns | ||||
|  *  allowed in the text file. | ||||
|  * | ||||
|  */ | ||||
| struct array *newrow(char* buffer, int maxcolumns) | ||||
| { | ||||
| 	char* pch = NULL; | ||||
| 	int i = 0; | ||||
| 	int count = 0; | ||||
| 	struct array *columns = NULL; | ||||
| 
 | ||||
| 	 columns = calloc(1,sizeof(struct array)); | ||||
| 	 if (columns == NULL) | ||||
| 	 { | ||||
| 		   fprintf(stderr,"Cannot allocate memory.\n"); | ||||
| 		   exit(EXIT_FAILURE); | ||||
| 	 } | ||||
| 
 | ||||
| 
 | ||||
| 	   pch = strtok (buffer,"\t "); | ||||
| 	   if (pch == NULL) | ||||
| 	   { | ||||
| 		   fprintf(stderr,"Expecting %d columns for indexes.\n",maxcolumns); | ||||
| 		   exit(EXIT_FAILURE); | ||||
| 	   } | ||||
| 	   array_append(columns,strdup(pch)); | ||||
| 	   count++; | ||||
| 	   for (i = count; i < maxcolumns; i++) | ||||
| 	   { | ||||
| 		   pch = strtok (NULL, "\t "); | ||||
| 		   if (pch == NULL) | ||||
| 		   { | ||||
| 			   fprintf(stderr,"Expecting %d columns for indexes.\n",maxcolumns); | ||||
| 			   exit(EXIT_FAILURE); | ||||
| 
 | ||||
| 		   } | ||||
| 		   count++; | ||||
| 		   array_append(columns,strdup(pch)); | ||||
| 	   } | ||||
| 	return columns; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void disposerow(struct array *row) | ||||
| { | ||||
| 	int i = 0; | ||||
| 	char* str; | ||||
| 	for (i = 0; i < row->count; i++) | ||||
| 	{ | ||||
| 		 str = (char*)row->item[i]; | ||||
| 		 free(str); | ||||
| 		 row->item[i] = NULL; | ||||
| 	} | ||||
| 	free(row); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** Copies a null terminated string,
 | ||||
|  *  but allocates the memory. | ||||
|  * | ||||
|  */ | ||||
| char* strdup(const char* s) | ||||
| { | ||||
| 	int length = strlen(s)+1; | ||||
| 	char* ptr = malloc(length); | ||||
| 	memcpy(ptr, s, length); | ||||
| 	return ptr; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
|  int i = 0; | ||||
|  struct array *columns; | ||||
|  int value; | ||||
|  char *str; | ||||
| 
 | ||||
|  char c1; | ||||
|  char c2; | ||||
|  FILE* hfile; | ||||
|  FILE* cfile; | ||||
|  char str1[3] = {0,0,0}; | ||||
|  char str2[3] = {0,0,0}; | ||||
|  /** First opcode value, -1 is invalid. */ | ||||
|  int fmnem = -1; | ||||
|  /** First pseudocode value, -1 is invalid. */ | ||||
|  int fpseu = -1; | ||||
|  if (argc != 2) | ||||
|  { | ||||
| 	 fprintf(stdout,"Requires em_table file and pathname\n"); | ||||
| 	 return EXIT_FAILURE; | ||||
|  } | ||||
| 
 | ||||
|  FILE *fd = fopen(argv[1],"r"); | ||||
|  int section = SECTION_INDEXES; | ||||
|  fprintf(stdout,"Opening : %s\n",argv[1]); | ||||
|  if (fd == NULL) | ||||
|  { | ||||
| 	 fprintf(stderr,"Cannot find file.\n"); | ||||
| 	 return EXIT_FAILURE; | ||||
|  } | ||||
|  while (fgets(inbuffer,BUFFER_SIZE,fd)!=NULL) | ||||
|  { | ||||
| 	 /* First section, opcode limits. */ | ||||
| 	 trimwhitespace(buffer,BUFFER_SIZE,inbuffer); | ||||
| 	 /** Next section */ | ||||
| 	 if (strlen(buffer)==0) | ||||
| 	 { | ||||
| 		 section++; | ||||
| 		 continue; | ||||
| 	 } | ||||
| 
 | ||||
| 
 | ||||
| 	 if (section == SECTION_INDEXES) | ||||
| 	 { | ||||
| 		   /* Split the row text into columns. */ | ||||
| 		   columns = newrow(buffer, 2); | ||||
| 	       array_append(§ion_index, columns); | ||||
| 	 } | ||||
| 	 else | ||||
| 	 if (section == SECTION_MNEMONICS) | ||||
| 	 { | ||||
| 		     columns = newrow(buffer, 3); | ||||
| 	         array_append(§ion_mnemonics, columns); | ||||
| 	 } else | ||||
| 	 if (section == SECTION_OPCODES) | ||||
| 	 { | ||||
| 	     columns = newrow(buffer, 3); | ||||
| 		 array_append(§ion_opcodes, columns); | ||||
| 	 } | ||||
|  } | ||||
|  fclose(fd); | ||||
| 
 | ||||
|  /* process the indexes */ | ||||
|  hfile = fopen("em_spec.h","w"); | ||||
|  for (i = 0; i < section_index.count; i++) | ||||
|  { | ||||
| 	 columns = (struct array*)section_index.item[i]; | ||||
| 	 str = columns->item[0]; | ||||
| 	 if (strcmp("fpseu",columns->item[0])==0) | ||||
| 	 { | ||||
| 		 fpseu = atoi(columns->item[1]); | ||||
| 
 | ||||
| 	 } | ||||
| 	 if (strcmp("fmnem",columns->item[0])==0) | ||||
| 	 { | ||||
| 		 fmnem = atoi(columns->item[1]); | ||||
| 
 | ||||
| 	 } | ||||
| 	 fprintf(hfile,"#define sp_%s\t %s\n",columns->item[0],columns->item[1]); | ||||
|  } | ||||
|  fprintf(hfile,"#define sp_lpseu\t% d\n",fpseu+section_mnemonics.count - 1); | ||||
|  fprintf(hfile,"#define sp_lmnem\t %d\n",fmnem+section_opcodes.count - 1); | ||||
|  fclose(hfile); | ||||
| 
 | ||||
| 
 | ||||
|  /** Check validity of first indexes. */ | ||||
|  if ((fpseu == -1) || (fmnem == -1)) | ||||
|  { | ||||
| 	 fprintf(stderr,"Error fpseu or fmnem first index values are not defined.\n"); | ||||
| 	 exit(EXIT_FAILURE); | ||||
|  } | ||||
| 
 | ||||
|  /* process the pseudocodes */ | ||||
|  hfile = fopen("em_pseu.h","w"); | ||||
|  cfile = fopen("em_pseu.c","w"); | ||||
|  fprintf(cfile,"char em_pseu[][4] = {\n"); | ||||
|  for (i = 0; i < section_mnemonics.count; i++) | ||||
|  { | ||||
| 	 columns = (struct array*)section_mnemonics.item[i]; | ||||
| 	 str = columns->item[1]; | ||||
| 	 value = atoi(str); | ||||
| 	 fprintf(hfile,"#define ps_%s\t%d\n",columns->item[0],value+fpseu); | ||||
| 	 fprintf(cfile,"  \"%s\",\n",columns->item[0]); | ||||
|  } | ||||
|  fprintf(cfile,"};\n"); | ||||
|  fclose(hfile); | ||||
|  fclose(cfile); | ||||
| 
 | ||||
|  /* process the opcodes */ | ||||
|  hfile = fopen("em_mnem.h","w"); | ||||
|  cfile = fopen("em_mnem.c","w"); | ||||
|  fprintf(cfile,"char em_mnem[][4] = {\n"); | ||||
|  for (i = 0; i < section_opcodes.count; i++) | ||||
|  { | ||||
| 	 columns = (struct array*)section_opcodes.item[i]; | ||||
| 	 fprintf(hfile,"#define op_%s\t%d\n",columns->item[0],i+fmnem); | ||||
| 	 fprintf(cfile,"  \"%s\",\n",columns->item[0]); | ||||
|  } | ||||
|  fprintf(cfile,"};\n"); | ||||
|  fclose(hfile); | ||||
|  fclose(cfile); | ||||
| 
 | ||||
|  /* Create the flag files from opcodes */ | ||||
|  cfile = fopen("em_flag.c","w"); | ||||
|  fprintf(cfile,"#include \"em_flag.h\"\n"); | ||||
|  fprintf(cfile,"char em_flag[] = {\n"); | ||||
|  for (i = 0; i < section_opcodes.count; i++) | ||||
|  { | ||||
| 	 columns = (struct array*)section_opcodes.item[i]; | ||||
| 	 /* 2nd column indicate the parameter format, always on 2 columns. */ | ||||
| 	 if (strlen(columns->item[1])!=2) | ||||
| 	 { | ||||
| 		 fprintf(stderr,"Error opcode type characterstic should be on 2 characters.\n"); | ||||
| 		 exit(EXIT_FAILURE); | ||||
| 	 } | ||||
| 	 str = (char*)columns->item[1]; | ||||
| 	 c1 = toupper(str[0]); | ||||
| 	 c2 = toupper(str[1]); | ||||
| 	 str1[0] = c1; | ||||
| 	 str1[1] = '\0'; | ||||
| 	 str2[0] = c2; | ||||
| 	 str2[1] = '\0'; | ||||
| 	 if (c1 == '-') | ||||
| 		strcpy(str1,"NO"); | ||||
| 	 if (c2 == '-') | ||||
| 	    strcpy(str2,"NO"); | ||||
| 	 fprintf(cfile, "PAR_%s | FLO_%s,\n",str1,str2); | ||||
|  } | ||||
|  fprintf(cfile,"};\n"); | ||||
|  fclose(cfile); | ||||
| 
 | ||||
| 
 | ||||
|  return EXIT_SUCCESS; | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue