grammar proto1
[henge/webcc.git] / src / lexer.c
diff --git a/src/lexer.c b/src/lexer.c
new file mode 100644 (file)
index 0000000..b230a4a
--- /dev/null
@@ -0,0 +1,143 @@
+/*!@file
+  \brief   lexical analyzer implementation for APC
+  \details lexer for tokenizing filenames from a directory root
+  \author  Jordan Lavatai
+  \date    Aug 2016
+  ----------------------------------------------------------------------------*/
+//stdc
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+//posix
+#include <unistd.h>
+#include <dirent.h>
+//bison
+#include "fileparser.tab.h"
+
+int lexer_init(void);
+int lexer();
+
+#define BUF_SIZE 256
+#define STACK_BUF_SIZE (BUF_SIZE >> 2)
+static DIR*  dp_stack_buf[STACK_BUF_SIZE];
+static char  path_buf[BUF_SIZE];
+static char  storage_buf[BUF_SIZE];
+
+/* Setup stack and first directory to read from */
+int
+lexer_init()
+{ char cwd_buf[MAX_TOK_LEN];
+
+  dsp = dp_stack_base;
+  getcwd(path_buf, MAX_TOK_LEN);
+  printf("|------cwd is %s------|\n", path_buf);
+  if(!(*dsp = opendir(path_buf)))
+    printf("opendir(cwd) failed in linit()\n");
+
+  *dsp = dp;
+  printf("dp_stack is %x, dsp is %x size is %d\n",*dp_stack, *dsp, sizeof dp);
+
+  return 0;
+}
+
+/* Returns token identifier and sets yylval */
+int
+lexer()
+{ static DIR** dsp = &dp_stack_buf;
+  int tok_t;
+  char buf[MAX_TOK_LEN];
+  char* file_name;
+
+  printf("|------in yylex(), calling tok_dir------|\n");
+  if((tok_t = tok_dir(*dsp, yylval.str)) == -1)
+    printf("tok_dir returned -1, something is broken\n");
+  printf("|------in yylex(), returning tok_t = %d | err = %s------|\n", tok_t, strerror(errno));
+  return tok_t;
+}
+
+#define DSP_PUSH(_val) *++dsp = (_val)
+
+int
+tok_dir(DIR* dp, char buf[])
+{
+  struct dirent* de; /* directory entry */
+  static DIR *tmp_dp;
+  char *tmp_path;
+  int path_len;
+
+
+tok_start:
+  if((*dsp == NULL) || (de = readdir(*dsp)) == NULL)
+    {
+      if(errno)
+        {  printf("Error:%s in tok_dir\n", strerror(errno));
+          return errno;
+        }
+      if( (dsp - dp_stack) >= 0)
+        {
+          printf("Current directory is null, pop one off ");
+#define DSP_POP() *dsp--
+
+          dp = DSP_POP();
+
+          /* Remove directory that was popped from path */
+#define SUB_PATH() tmp_path = strrchr(path, '/'); \
+          path_len = strlen(tmp_path);            \
+          memset(tmp_path, 0, path_len)
+
+          SUB_PATH();
+
+          goto tok_start;
+        }
+      return 0; /* Done */
+    }
+
+  else if(de->d_type == DT_REG)
+    { printf("|------dir_ent is a file, "\
+             "setting yylval to %s------|\n", de->d_name);
+      memmove(buf, de->d_name, MAX_TOK_LEN);
+      return FDAT;
+    }
+  else if (de->d_type == DT_DIR )
+    { if ((dsp - dp_stack) >= MAX_DIR_DEP) /* We've opened to many directories */
+        {
+          printf("Too many directories!\n");
+          return 1;
+        }
+      if(strcmp(de->d_name,".") == 0 || strcmp(de->d_name,"..") == 0)
+        {
+          printf("directory is %s \n", de->d_name);
+          goto tok_start;
+        }
+
+      printf("|------ dir_ent is directory %s, "\
+             "cwd = %s, path = %s ------|\n", de->d_name, get_current_dir_name(), path);
+
+
+      /* Add directory name to path */
+#define ADD_PATH(_name) strcat(path, "/");      \
+                        strcat(path, _name)
+
+      ADD_PATH(de->d_name);
+
+      tmp_dp = opendir(path);
+      if(tmp_dp == 0)
+        { printf("opening the directory failed,"\
+                 "errno = %s\n", strerror(errno));
+          return -1;
+        }
+
+      DSP_PUSH(tmp_dp);
+
+      goto tok_start;
+
+    }
+  else
+    {
+      printf("A file that is not a diretory or a regular file is unable to be tokenized: %s\n", de->d_name);
+      return -1;
+    }
+
+
+
+}