Lexer actually lexes filenames now, and odats are made out of mapvariants
[henge/webcc.git] / src / apc / lexer.c
index f11c6a2..b6c6ca3 100644 (file)
 #include <uniname.h>
 #include <unistdio.h>
 #include <stdlib.h>
-#include <limits.h> //realpath, NAME_MAX, PATH_MAX
+#include <limits.h> //realpath, NAME_MAX, FPATH_MAX
 #include <dirent.h>
-/* Redefinitions of NAME_MAX and PATH_MAX */
-//#define NAME_MAX NAME_MAX/4
-//#define PATH_MAX PATH_MAX/4
 
 /* Local */
 #include "parser.tab.h"
 #ifndef MAX_SETNAME_LEN //max setname length
 #define MAX_SETNAME_LEN 32
 #endif
+#ifndef MAX_ELENAME_LEN //max setname length
+#define MAX_ELENAME_LEN 32
+#endif
+#define FNAME_MAX 1024
+#define FPATH_MAX 8192
 
 /* Public */
 int         lexer_init(void);
@@ -53,6 +55,8 @@ struct dirent* lexer_direntpa[DE_STACKSIZE],** lexer_direntpp,** lexer_direntpb;
 /* Private */
 extern //lexer_fsm.rl
 int         lexer_lexstring(uint8_t*, int);
+extern //lexer_fsm.rl
+int    lexer_setstr(uint8_t*, int);
 extern //scanner.c
 int         scanner_init(void);
 extern //scanner.c
@@ -64,6 +68,12 @@ YYSTYPE     yylval;
 static
 uint8_t const* current_filename;
 static
+uint8_t prev_setname[MAX_SETNAME_LEN];  
+static
+uint8_t prev_elename[MAX_ELENAME_LEN];
+static
+uint8_t map_key[] = "~";
+static
 struct tok
 { YYSTYPE lval;  //token val
   int     tok_t; //token type
@@ -174,7 +184,7 @@ int lexer_lexfile
 #define HIDDEN_WARNING "%s is hidden and will not be parsed!\n", filename
 ( const uint8_t  *filename
 )
-{ static uint8_t fname[NAME_MAX];
+{ static uint8_t fname[FNAME_MAX];
   uint8_t        *last_period = NULL, *iter;
 
   if (*filename ==  '.')
@@ -182,7 +192,7 @@ int lexer_lexfile
       return 0;
     }
   /* Copy the filename and remove its suffix */
-  u8_strncpy(fname,filename,NAME_MAX);
+  u8_strncpy(fname,filename,FNAME_MAX);
   last_period = NULL;
   for (iter = fname; *iter; iter++)  //find the last '.' char
     if (*iter ==  '.')
@@ -191,84 +201,335 @@ int lexer_lexfile
     *last_period =  0;             //truncate the string there
   /* Register the current_filename */
   current_filename = filename;
-  
+  printf("lexer_lexfilename(%s)\n",fname);
   return lexer_lexfilename(fname);
 }
 
 uint8_t const* lexer_get_current_filepath
 ()
-{ static uint8_t        current_path[PATH_MAX];
+{ static uint8_t        current_path[FPATH_MAX];
   static uint8_t const* last_filename;
   if ((!last_filename || last_filename != current_filename) &&
-      (realpath(current_filename, current_path) != (char*) current_path))
+      ((uint8_t*) realpath(current_filename, current_path) != (uint8_t*) current_path))
     { perror("realpath: ");
       return NULL;
     }
-  return (const char*)current_path;
+  return (const uint8_t*)current_path;
 }
 
+/* Returns 1 on success, 0 on failure */
+int
+lexer_ismapfile(uint8_t* str)
+{
+  int i, len;
+
+  len = u8_strlen(str);
+  for(i = 0; i < len; i++)
+    if(str[i] == '~')
+      return 1;
+}
+
+
 /* Scan filename and push the its tokens
    onto the stack */
 int lexer_lexfilename
 (uint8_t* str)
-{
-  int ntok, i, cmp, len, set_len, height, width;
-  char map_key[] = "_m_";
-  static uint8_t set_name[MAX_SETNAME_LEN] = {0};
-  uint8_t *first, *map_begin;
-
-  printf("Starting lexerfilename on %s\n", str);
+#define REF(STR) (STR[0] <= 0x39 && STR[0] >= 0x30)  
+#define DEL_FTOK(STR) (STR = u8_strchr(STR, '_') + 1)
+#define NEXT_TOK(STR) (u8_strchr(STR, '_') + 1)
+#define SET_CURR_SETNAME(STR)                   \
+  do {                                         \
+  printf("setting curr_setname of str(%s)\n", STR); \
+  setname_end = u8_chr(STR, FNAME_MAX, '_');   \
+  setname_len = setname_end - str;             \
+  u8_move(curr_setname, STR, setname_len);     \
+  printf("curr_setname is now %s\n",curr_setname); \
+   } while (0)
+#define SET_CURR_ELENAME(STR) \
+  do { \
+    printf("setting curr_elename of str(%s)\n", STR); \
+    setname_end = u8_chr(STR, FNAME_MAX, '_') + 1; \
+    if(REF(setname_end)) \
+      setname_end = u8_chr(setname_end, FNAME_MAX, '_') + 1; \
+    elename_end = u8_chr(setname_end, FNAME_MAX, '_'); \
+    elename_len = elename_end - setname_end; \
+    u8_move(curr_elename, setname_end, elename_len); \
+    printf("curr_elename is now %s\n", curr_elename); \
+  } while (0) 
   
+#define SETNAME_MATCHES()  (u8_strcmp(curr_setname, prev_setname) == 0)
+#define ELENAME_MATCHES()  (u8_strcmp(curr_elename, prev_elename) == 0)
+#define UPDATE_PREV_SETNAME(STR) \
+  do { \
+    printf("updating prev_setname from (%s)", prev_setname);           \
+  u8_set(prev_setname , (ucs4_t) 0, MAX_SETNAME_LEN );  \
+  u8_move(prev_setname, curr_setname, setname_len);  \
+  printf(" to %s\n", prev_setname); \
+  } while (0)
+#define UPDATE_PREV_ELENAME(STR) \
+  do { \
+  u8_set(prev_elename , (ucs4_t) 0, MAX_ELENAME_LEN );  \
+  u8_move(prev_elename, curr_elename, elename_len);  \
+  } while (0)
+#define PREV_MAPFILE() (TK_STACKX - 5)->tok_t == MOPEN || (TK_STACKX-3)->tok_t == MOPEN
+#define SET_MAPSTR(STR)  (STR = u8_strstr(STR, map_key))
+
+{ int ntok, len, newstrt;
+  uint8_t *filepath;
+  typedef enum filetypes {
+    error = 0,
+    set_model,
+    set_map,
+    ele_model,
+    ele_map,
+    ele_vlink,
+    set_olink,
+    set_vlink
+  } filetypes;
+
+  ntok = 0;
 
+  printf("|---- Begin lexerfilename on %s ----|\n", str);
+  
   if(*str == 0)
-    printf("Lexfilename:: str is NULL so fail\n");
-  printf("setname is %s\n", set_name);
+    perror("Lexfilename:: str is NULL so fail\n");
+
+  /* Determine the filetype of str */
+  len = u8_strlen(str);
+  newstrt = lexer_setstr(str,len);
+
+  str = str + newstrt;
+
+  len = u8_strlen(str);
   
-  /* If last file was a mapfile, then its 5th to last token should
-  be a MOPEN. If this is the case, then we only pass MOPEN, height,
-  weight and name of the current file. */
-  if( (TK_STACKX - 5)->tok_t == MOPEN )
-    { printf("The last file was a mapfile\n");
-      if( (map_begin = strstr(map_key, str)) ) //if the current file is a mapfile
-       { printf("The current file is a variant of the last mapfile\n");
-         printf("Start lexing mapfile %s\n", str);
-         ntok += lexer_lexstring(map_begin, strlen(map_begin));
+  ntok += lexer_lexstring(str, len);
+
+  /* Need to add map variant name 'default' if user did not specify a
+      map variant name */
+  /* if(filetype == ele_map) */
+  /*   { if(!u8_strchr(str, '_')) //map variant name not provided */
+  /*      { yylval.str = "default"; */
+  /*    lexer_pushtok(NAME, yylval); */
+  /*    ntok++; */
+  /*    printf("Pushing default ele_map name\n");     */
+  /*      }      */
+  /*  } */
+
+  /* Pass back filepath as end of statment operator */
+  filepath = u8_strdup(lexer_get_current_filepath());
+  yylval.str = filepath;
+  lexer_pushtok(NAME, yylval);
+  printf("Pushing filepath %s\n", filepath);
+  ntok++;
+     
+  printf("|---- Ending lexer_lexfilename on %s, %d tokens were lexed ----|\n", str, ntok);
+  return ntok;
+}
+
+int
+lexer_lexelemap
+( uint8_t* str)
+{ int setname_len, elename_len, strlen;
+  uint8_t* setname_end, *elename_end, *newstrt;
+  uint8_t curr_setname[MAX_SETNAME_LEN] = {0};
+  uint8_t curr_elename[MAX_ELENAME_LEN] = {0};
+
+  newstrt = str;
+  
+  SET_CURR_SETNAME(newstrt);
+  SET_CURR_ELENAME(newstrt);
+  if(PREV_MAPFILE())
+    { printf("*previous file was mapfile*\n");
+      SET_MAPSTR(newstrt);
+    }
+  else
+    { 
+      if(SETNAME_MATCHES())
+       { DEL_FTOK(newstrt);
+         if(REF(newstrt))
+           DEL_FTOK(newstrt);
+         printf("setname matches\n");
+         if(ELENAME_MATCHES())
+            DEL_FTOK(newstrt);
+         if(REF(str))
+           DEL_FTOK(newstrt);
+       }          
+     }
+  UPDATE_PREV_ELENAME(newstrt);
+  UPDATE_PREV_SETNAME(newstrt);
+
+  return newstrt - str;
+
+  
+}
+
+int 
+lexer_lexelemodel
+(uint8_t* str)
+{ int setname_len, elename_len;
+  uint8_t* setname_end, *elename_end, *newstrt;
+  uint8_t curr_setname[MAX_SETNAME_LEN] = {0};
+  uint8_t curr_elename[MAX_ELENAME_LEN] = {0};
+
+  printf("In lexelemodel, str is %s\n", str);
+
+  newstrt = str;
+  
+  SET_CURR_SETNAME(newstrt);
+  SET_CURR_ELENAME(newstrt);
+  if(SETNAME_MATCHES())
+    { printf("in ele_model: setname matches\n");
+      DEL_FTOK(newstrt);
+      printf("newstrt is now %s\n", newstrt);
+      if(REF(newstrt))
+       DEL_FTOK(newstrt);
+      if(ELENAME_MATCHES())
+       { printf("in ele_model: elename matches\n");
+         DEL_FTOK(newstrt);
+         if(REF(newstrt))
+           DEL_FTOK(newstrt);
        }
-      printf("Current file is not a variant of the last mapfile\n");      
     }
-  else //last file was not a mapfile
-    { printf("Last file was not a mapfile\n");
+  UPDATE_PREV_ELENAME(newstrt);
+  UPDATE_PREV_SETNAME(newstrt);
 
-      first = (uint8_t*) u8_strchr(str,  '_'); //find the first '_' to find where str set_name ends    
-      
-      if(set_name[0] != 0) //if there is a set_name from last str     
-       { printf("There is a set_name (%s) present\n", set_name);
-          set_len = first - str;
-           
-         if(u8_strncmp(str, set_name, set_len) == 0) //check if it matches the current set_name
-           { str = str + set_len + 1;                    //if so, remove it from str
-             printf("str set_name matched last set_name, set str to %s\n", str);
-           }
-         else //update set_name to be str set_name
-           { u8_cpy(set_name, str, set_len);
-             set_name[set_len] = 0;
-             
-           }
-        }
-      else //set set_name
-       { u8_cpy(set_name, str, first-str);
-       } 
-      /* Call lexer_lexstring to tokenize the string */
-      printf("calling lexstring to tokenize str (%s) of len %d\n", str, u8_strlen(str));
-      ntok += lexer_lexstring(str, u8_strlen(str));
+  return newstrt - str;
+}
+
+int
+lexer_lexsetmap
+(uint8_t* str)
+{ int setname_len, elename_len;
+  uint8_t* setname_end, *elename_end, *newstrt;
+  uint8_t curr_setname[MAX_SETNAME_LEN] = {0};
+  uint8_t curr_elename[MAX_ELENAME_LEN] = {0};
+
+  newstrt = str;
+  
+  SET_CURR_SETNAME(newstrt); 
+  if(PREV_MAPFILE())
+    SET_MAPSTR(newstrt);
+  else
+    if( SETNAME_MATCHES())
+      DEL_FTOK(newstrt);
+      if(REF(newstrt))
+       DEL_FTOK(newstrt);
+
+  UPDATE_PREV_SETNAME(newstrt);
+
+  return newstrt - str;
+}
+
+int
+lexer_lexsetmodel
+(uint8_t* str)
+{ int setname_len, elename_len;
+  uint8_t* setname_end, *elename_end, *newstrt;
+  uint8_t curr_setname[MAX_SETNAME_LEN] = {0};
+  uint8_t curr_elename[MAX_ELENAME_LEN] = {0};
+
+  newstrt = str;
+
+  SET_CURR_SETNAME(newstrt);
+  if( SETNAME_MATCHES())
+    DEL_FTOK(newstrt);
+  if(REF(newstrt))
+    DEL_FTOK(newstrt);
+  UPDATE_PREV_SETNAME(newstrt);
+
+  return newstrt - str;
+
+}
+
+int
+lexer_lexsetvlink
+(uint8_t* str)
+{ int setname_len, elename_len;
+  uint8_t* setname_end, *elename_end, *newstrt;
+  uint8_t curr_setname[MAX_SETNAME_LEN] = {0};
+  uint8_t curr_elename[MAX_ELENAME_LEN] = {0};
+
+  newstrt = str;
+
+  SET_CURR_SETNAME(newstrt);
+  if( SETNAME_MATCHES())
+    DEL_FTOK(newstrt);
+  if(REF((NEXT_TOK(newstrt)))) //if NAME REF REF
+    DEL_FTOK(newstrt);
+  UPDATE_PREV_SETNAME(newstrt);
+
+  return newstrt - str;
+
+}
+
+int
+lexer_lexelevlink
+(uint8_t* str)
+{ int setname_len, elename_len;
+  uint8_t* setname_end, *elename_end, *newstrt;
+  uint8_t curr_setname[MAX_SETNAME_LEN] = {0};
+  uint8_t curr_elename[MAX_ELENAME_LEN] = {0};
+
+  newstrt = str;
+
+  SET_CURR_SETNAME(newstrt);
+  SET_CURR_ELENAME(newstrt);
+  if(SETNAME_MATCHES())
+    { DEL_FTOK(newstrt);
+      if(REF(NEXT_TOK(newstrt))) //NAME REF REF, where  is set_label
+        DEL_FTOK(newstrt);
     }
-    
-  /*TODO: if regfile, store full path for later */
+       
+  return newstrt - str;
+}
 
-  printf("Ending lexer_lex on %s, %d tokens were lexed\n", str, ntok);
-  return ntok;
+int
+lexer_lexsetolink
+(uint8_t* str)
+{ int setname_len, elename_len;
+  uint8_t* setname_end, *elename_end;
+  uint8_t curr_setname[MAX_SETNAME_LEN] = {0};
+  uint8_t curr_elename[MAX_ELENAME_LEN] = {0};
+
+  return 0;
+
+  //do nothing
 }
 
+int
+lexer_lexeleolink
+(uint8_t* str)
+{ int setname_len, elename_len;
+  uint8_t* setname_end, *elename_end, *newstrt;
+  uint8_t curr_setname[MAX_SETNAME_LEN] = {0};
+  uint8_t curr_elename[MAX_ELENAME_LEN] = {0};
+
+  newstrt = str;
+  
+  SET_CURR_SETNAME(newstrt);
+  printf("prev_setname %s, curr_setname %s\n", prev_setname, curr_setname);
+  if(SETNAME_MATCHES())
+    { DEL_FTOK(newstrt);
+      if(REF(newstrt))
+       DEL_FTOK(newstrt);
+    }
+
+  return newstrt - str;
+
+  
+}
+
+
+/**************************/
+/****Abandon All Hope******/
+/**************************/
+/***                    ***/
+/***                    ***/       
+/***                    ***/
+/***                    ***/
+
+
+
 /* int lexer_lexmapfile */
 /* #define INC_X() */
 /* (int height, int width) */
@@ -292,13 +553,13 @@ int lexer_lexfilename
 /* } */
 /* fname_bytes = (uint8_t*)(DE_POP()->d_name); */
       /* printf("d_name is %s\n", fname_bytes); */
-      /* for (fnp = filename, i = 0; i < NAME_MAX; i += unit_size, fnp++) */
-      /*       { unit_size = u8_mblen(fname_bytes + i, min(4, NAME_MAX - i)); */
+      /* for (fnp = filename, i = 0; i < FNAME_MAX; i += unit_size, fnp++) */
+      /*       { unit_size = u8_mblen(fname_bytes + i, min(4, FNAME_MAX - i)); */
       /*         if (u8_mbtouc(fnp, fname_bytes + i, unit_size) == -1) //add ucs4 char to the filename */
       /*           FAIL("Lexer failed to convert ^%s to unicode\n", (fname_bytes + i)); */
       /*         if (*fnp == 0) //added a terminating char */
       /*           break; */
       /*       } */
-      /* if(u8_mbtouc(filename, DE_POP()->d_name, NAME_MAX) == -1) */
+      /* if(u8_mbtouc(filename, DE_POP()->d_name, FNAME_MAXy) == -1) */
       /*       FAIL("Lexer failed to convert d_name into uint8_t\n"); */
       /* ulc_fprintf(stdout, "filename is %11U\n c", filename); */