From c6658233045b0039b328394f38b3297501df0c30 Mon Sep 17 00:00:00 2001 From: ksg Date: Fri, 26 Aug 2016 10:54:19 -0700 Subject: [PATCH] APC main driver --- .gitignore | 1 + src/apc/lexer.c | 92 +++++++++++++++++++++++++++++++ src/apc/main.c | 62 +++++++++++++++++++++ src/lexer.c | 143 ------------------------------------------------ 4 files changed, 155 insertions(+), 143 deletions(-) create mode 100644 src/apc/lexer.c create mode 100644 src/apc/main.c delete mode 100644 src/lexer.c diff --git a/.gitignore b/.gitignore index 21035cc..7be2c06 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist/* extern/* proto/* +.#* diff --git a/src/apc/lexer.c b/src/apc/lexer.c new file mode 100644 index 0000000..0d408b9 --- /dev/null +++ b/src/apc/lexer.c @@ -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 +#include +#include +//posix +#include +#include +//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 index 0000000..a53a6cb --- /dev/null +++ b/src/apc/main.c @@ -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 +/* Posix */ +#include //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 index b230a4a..0000000 --- a/src/lexer.c +++ /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 -#include -#include -//posix -#include -#include -//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; - } - - - -} -- 2.18.0