grammar proto1
[henge/webcc.git] / src / lexer.c
1 /*!@file
2 \brief lexical analyzer implementation for APC
3 \details lexer for tokenizing filenames from a directory root
4 \author Jordan Lavatai
5 \date Aug 2016
6 ----------------------------------------------------------------------------*/
7 //stdc
8 #include <stdio.h>
9 #include <string.h>
10 #include <errno.h>
11 //posix
12 #include <unistd.h>
13 #include <dirent.h>
14 //bison
15 #include "fileparser.tab.h"
16
17 int lexer_init(void);
18 int lexer();
19
20 #define BUF_SIZE 256
21 #define STACK_BUF_SIZE (BUF_SIZE >> 2)
22 static DIR* dp_stack_buf[STACK_BUF_SIZE];
23 static char path_buf[BUF_SIZE];
24 static char storage_buf[BUF_SIZE];
25
26 /* Setup stack and first directory to read from */
27 int
28 lexer_init()
29 { char cwd_buf[MAX_TOK_LEN];
30
31 dsp = dp_stack_base;
32 getcwd(path_buf, MAX_TOK_LEN);
33 printf("|------cwd is %s------|\n", path_buf);
34 if(!(*dsp = opendir(path_buf)))
35 printf("opendir(cwd) failed in linit()\n");
36
37 *dsp = dp;
38 printf("dp_stack is %x, dsp is %x size is %d\n",*dp_stack, *dsp, sizeof dp);
39
40 return 0;
41 }
42
43 /* Returns token identifier and sets yylval */
44 int
45 lexer()
46 { static DIR** dsp = &dp_stack_buf;
47 int tok_t;
48 char buf[MAX_TOK_LEN];
49 char* file_name;
50
51 printf("|------in yylex(), calling tok_dir------|\n");
52 if((tok_t = tok_dir(*dsp, yylval.str)) == -1)
53 printf("tok_dir returned -1, something is broken\n");
54 printf("|------in yylex(), returning tok_t = %d | err = %s------|\n", tok_t, strerror(errno));
55 return tok_t;
56 }
57
58 #define DSP_PUSH(_val) *++dsp = (_val)
59
60 int
61 tok_dir(DIR* dp, char buf[])
62 {
63 struct dirent* de; /* directory entry */
64 static DIR *tmp_dp;
65 char *tmp_path;
66 int path_len;
67
68
69 tok_start:
70 if((*dsp == NULL) || (de = readdir(*dsp)) == NULL)
71 {
72 if(errno)
73 { printf("Error:%s in tok_dir\n", strerror(errno));
74 return errno;
75 }
76 if( (dsp - dp_stack) >= 0)
77 {
78 printf("Current directory is null, pop one off ");
79 #define DSP_POP() *dsp--
80
81 dp = DSP_POP();
82
83 /* Remove directory that was popped from path */
84 #define SUB_PATH() tmp_path = strrchr(path, '/'); \
85 path_len = strlen(tmp_path); \
86 memset(tmp_path, 0, path_len)
87
88 SUB_PATH();
89
90 goto tok_start;
91 }
92 return 0; /* Done */
93 }
94
95 else if(de->d_type == DT_REG)
96 { printf("|------dir_ent is a file, "\
97 "setting yylval to %s------|\n", de->d_name);
98 memmove(buf, de->d_name, MAX_TOK_LEN);
99 return FDAT;
100 }
101 else if (de->d_type == DT_DIR )
102 { if ((dsp - dp_stack) >= MAX_DIR_DEP) /* We've opened to many directories */
103 {
104 printf("Too many directories!\n");
105 return 1;
106 }
107 if(strcmp(de->d_name,".") == 0 || strcmp(de->d_name,"..") == 0)
108 {
109 printf("directory is %s \n", de->d_name);
110 goto tok_start;
111 }
112
113 printf("|------ dir_ent is directory %s, "\
114 "cwd = %s, path = %s ------|\n", de->d_name, get_current_dir_name(), path);
115
116
117 /* Add directory name to path */
118 #define ADD_PATH(_name) strcat(path, "/"); \
119 strcat(path, _name)
120
121 ADD_PATH(de->d_name);
122
123 tmp_dp = opendir(path);
124 if(tmp_dp == 0)
125 { printf("opening the directory failed,"\
126 "errno = %s\n", strerror(errno));
127 return -1;
128 }
129
130 DSP_PUSH(tmp_dp);
131
132 goto tok_start;
133
134 }
135 else
136 {
137 printf("A file that is not a diretory or a regular file is unable to be tokenized: %s\n", de->d_name);
138 return -1;
139 }
140
141
142
143 }