* Initial support of CMake
authorcarl <cecodere@yahoo.ca>
Mon, 18 Feb 2019 16:33:21 +0000 (00:33 +0800)
committercarl <cecodere@yahoo.ca>
Mon, 18 Feb 2019 16:54:23 +0000 (00:54 +0800)
+ Generation of header files is now made through a C program to make it more portable.

modules/src/em_data/CMakeLists.txt [new file with mode: 0644]
modules/src/em_data/makeem.c [new file with mode: 0644]

diff --git a/modules/src/em_data/CMakeLists.txt b/modules/src/em_data/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9e5cffe
--- /dev/null
@@ -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
+)
+
+
+
+
diff --git a/modules/src/em_data/makeem.c b/modules/src/em_data/makeem.c
new file mode 100644 (file)
index 0000000..5747247
--- /dev/null
@@ -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(&section_index, columns);
+        }
+        else
+        if (section == SECTION_MNEMONICS)
+        {
+                    columns = newrow(buffer, 3);
+                array_append(&section_mnemonics, columns);
+        } else
+        if (section == SECTION_OPCODES)
+        {
+            columns = newrow(buffer, 3);
+                array_append(&section_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;
+
+}