APC main driver
authorksg <ken@mihrtec.com>
Fri, 26 Aug 2016 17:54:19 +0000 (10:54 -0700)
committerksg <ken@mihrtec.com>
Fri, 26 Aug 2016 17:54:19 +0000 (10:54 -0700)
.gitignore
src/apc/lexer.c [new file with mode: 0644]
src/apc/main.c [new file with mode: 0644]
src/lexer.c [deleted file]

index 21035cc..7be2c06 100644 (file)
@@ -3,3 +3,4 @@
 dist/*
 extern/*
 proto/*
+.#*
diff --git a/src/apc/lexer.c b/src/apc/lexer.c
new file mode 100644 (file)
index 0000000..0d408b9
--- /dev/null
@@ -0,0 +1,92 @@
+/*!@file
+  \brief   lexical analyzer implementation for APC
+  \details this lexer scans a root directory given from the command line
+           for subdirectories and files structured for the APC grammar.
+  \author  Jordan Lavatai
+  \date    Aug 2016
+  ----------------------------------------------------------------------------*/
+//stdc
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+//posix
+#include <unistd.h>
+#include <stdlib.h>
+//bison
+#include "fileparser.tab.h"
+#define TOKEN_BUF_SIZE 1024
+#define DIRP_STACK_SIZE 512
+
+int lexer_init(void);
+int lexer(void);
+
+static
+int lexer_scan(void);
+
+static
+int  token_buf[TOKEN_BUF_SIZE], *tbp, *tbx;
+static
+DIR* dirp_stack[DIRP_STACK_SIZE], *dsp;
+
+/* Initialize pointers */
+int
+lexer_init()
+{ tbp = tbx = token_buf;
+  dsp = dirp_stack;
+  return 0;
+}
+
+/* Returns a token identifier and sets yylval */
+int
+lexer()
+{ if (lexer_scan() == 0)
+    return 0;
+  yylval = *tbp++;
+  return *tbp++;
+}
+
+/* Scanner
+   Scans a filename from its alphabetically ordered list of file elements
+   and tokenizes the result.  If the file list is empty, then the stack of
+   directory elements will be popped and processed as they are encountered.
+
+   Returns the number of tokens generated.
+*/
+#define MAX_ENTITIES 256
+static
+int lexer_scan()
+{ static struct dirent* entity;
+  static struct dirent* files[MAX_ENTITIES];
+  static struct dirent* dirs = files + MAX_ENTITIES - 1;
+  static int            num_files = 0;
+  static int            num_dirs = 0;
+
+  //sort out files and directories, grow directories from bottom up
+  while ((entity = readdir(dirp)) != NULL)
+    { switch (entity->d_type)
+        { case DT_LNK:
+          case DT_REG:
+            files[num_files++] = entity;
+            break;
+          case DT_DIR:
+            *(dirs - num_dirs++) = entity;
+            break;
+          case DT_UNKNOWN:
+          default:
+            printf("Ignoring unknown file: %s\n", entity->d_name);
+            break;
+        }
+    }
+  if (errno)
+    perror("readdir");
+  qsort(&files[0], num_files, sizeof struct dirent*, qalpha);
+  num_ents = scandirat(dirfd, ".", &namelist, scanfilter, scancompar);
+  if (num_ents < 0)
+    { perror("scandirat");
+      return -1;
+    }
+  //process files
+
+  //recurse into directories
+
+}
diff --git a/src/apc/main.c b/src/apc/main.c
new file mode 100644 (file)
index 0000000..a53a6cb
--- /dev/null
@@ -0,0 +1,62 @@
+/*!@file
+  \brief   APC main driver
+  \details The driver assumes the existence of a bison-generated parser,
+           referenced by the external function 'yyparse'.
+           It also assumes the existence of a lexer which must be initialized
+           before parsing, referenced by the external function 'lexer_init'
+           which assumes standard error handling.
+           All input arguments are made available through the exposed (that is,
+           non-static) array of character pointers 'cargs', which point
+           to the non-duplicated strings in 'argv' directly from the system.
+  \author  Jordan Lavatai
+  \date    Aug 2016
+  ----------------------------------------------------------------------------*/
+/* Standard */
+#include <errno.h>
+/* Posix */
+#include <unistd.h> //getopt
+
+int main(int, char*[]);
+
+const char* cargs['Z'] = {0};
+
+extern //bison
+void yyparse(void);
+extern //lexer.c
+int  lexer_init(void);
+
+/* Main entry from terminal
+   parses the command line and kicks off recursive scanning
+*/
+int main
+( int   argc,
+  char* argv[]
+)
+#define MAXERR "-%c allows at most " #MAX_STR_LEN " input characters", opt
+#define USAGE  "Usage: %s [-r root]\n", argv[0]
+#define DONE   -1
+{ int   opt;
+
+ getopt:
+  switch (opt = getopt(argc, argv, "r:o:"))
+  { case DONE:
+      break;
+    case 'r' :
+    case 'o' :
+      if (strnlen(optarg, MAX_STR_LEN) != MAX_STR_LEN)
+        { cargs[opt] = optarg;
+          goto getopt;
+        }
+      fprintf(stderr, MAXERR);
+    default :
+      fprintf(stderr, USAGE);
+      exit(EXIT_FAILURE);
+  }
+  if (lexer_init())
+    { perror("lexer");
+      exit(EXIT_FAILURE);
+    }
+  yyparse();
+  exit(EXIT_SUCCESS);
+}
+
diff --git a/src/lexer.c b/src/lexer.c
deleted file mode 100644 (file)
index b230a4a..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*!@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;
-    }
-
-
-
-}