* 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
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…
Reference in a new issue