* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#include <stdio.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
#include "gmqcc.h"
/*
lex->size = lex->length; /* copy, this is never changed */
fseek(lex->file, 0, SEEK_SET);
lex->last = 0;
- lex->line = 1;
+ lex->line = 0;
memset(lex->peek, 0, sizeof(lex->peek));
return lex;
if (!file) return;
fclose(file->file); /* may already be closed */
- mem_d(file);
+ mem_d (file);
}
static void lex_addch(int ch, struct lex_file *file) {
static int lex_getch(struct lex_file *file) {
int ch = lex_inget(file);
-
+
+ static int str = 0;
switch (ch) {
case '?' :
return lex_trigraph(file);
case '<' :
case ':' :
case '%' :
- return lex_digraph (file, ch);
- case '\n': file->line ++;
+ case '"' : str = !str; if (str) { file->line ++; }
+ return lex_digraph(file, ch);
+
+ case '\n':
+ if (!str)
+ file->line++;
}
return ch;
lex_addch(ch, file);
while ((ch = lex_getch(file)) != '*') {
if (ch == EOF)
- return error(ERROR_LEX, "malformatted comment at line", "");
+ return error(file, ERROR_LEX, "malformatted comment");
else
lex_addch(ch, file);
}
/* valid identifier */
if (ch > 0 && (ch == '_' || isalpha(ch))) {
lex_clear(file);
- while (ch > 0 && ch != ' ' && ch != '(' && ch != '\n' && ch != ';') {
+
+ /*
+ * Yes this is dirty, but there is no other _sane_ easy
+ * way to do it, this is what I call defensive programming
+ * if something breaks, add more defense :-)
+ */
+ while (ch > 0 && ch != ' ' && ch != '(' &&
+ ch != '\n' && ch != ';' && ch != ')') {
lex_addch(ch, file);
ch = lex_getsource(file);
}
memset(file->peek, 0, sizeof(file->peek ));
memset(file->lastok, 0, sizeof(file->lastok));
}
+
+/*
+ * Include a file into the lexer / parsing process: This really
+ * should check if names are the same to prevent endless include
+ * recrusion.
+ */
+struct lex_file *lex_include(struct lex_file *lex, char *file) {
+ util_strrq(file);
+ if (strncmp(lex->name, file, strlen(lex->name)) == 0) {
+ error(lex, ERROR_LEX, "Source file cannot include itself\n");
+ exit (-1);
+ }
+
+ FILE *fp = fopen(file, "r");
+ if (!fp) {
+ error(lex, ERROR_LEX, "Include file `%s` doesn't exist\n", file);
+ exit (-1);
+ }
+
+ return lex_open(fp);
+}