From 183b3f9cb9841820f52f2aa3af258e19d3269806 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 3 Nov 2010 19:30:49 +0100 Subject: [PATCH 1/8] added notes about byacc and boost, removed fixed macos x build issues --- doc/TODO.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/TODO.txt b/doc/TODO.txt index c01b13ab..feed2b9a 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -185,6 +185,11 @@ o Consider decoupling DXF-specific functionality from the 2D subsystem o Visitation refactoring - Make AbstractNode members private/protected? +BUILD SYSTEM +------------ +o Fedora is reported to ship with byacc, which doesn't support bison extensions (e.g. %debuig). Look into this, either be yacc-compatible or force the build system to use bison. +o We currently link in -lboost_thread. Should we always use -lboost_thread-mt under Linux or can we pick this up using qmake? + TESTING ------- o Caching and MDI looks suspicious when the code relies on external resources @@ -208,9 +213,6 @@ MISC ---- o Streamline the cmd-line interface a bit - Implicit output file format -o Mac OS X: - - 32-bit compatibility - o Build everything including i386 arch o Write checklists for typical extension work (add new module, add new function) -> make sure new test files are added From e2ae2a714d623473b7e85c32b22a08156f461d77 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Wed, 17 Nov 2010 21:27:10 +0000 Subject: [PATCH 2/8] This adds support for escape sequences in strings e.g \t \n \r \" \\ --- src/lexer.l | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 49243fdd..b9491693 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -140,11 +140,15 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { {DIGIT}+|{DIGIT}*\.{DIGIT}+|{DIGIT}+\.{DIGIT}* { parserlval.number = QString(yytext).toDouble(); return TOK_NUMBER; } "$"?[a-zA-Z0-9_]+ { parserlval.text = strdup(yytext); return TOK_ID; } -\"[^"]*\" { - parserlval.text = strdup(yytext+1); - parserlval.text[strlen(parserlval.text)-1] = 0; - return TOK_STRING; -} +\"(\\[tnr\"\\]|[^\\"])*\" { QString str(yytext+1); + str.chop(1); + str=str.replace("\\\\","\\"); + str=str.replace("\\\"","\""); + str=str.replace("\\t","\t"); + str=str.replace("\\n","\n"); + str=str.replace("\\r","\r"); + parserlval.text = strdup(str.toAscii().data()); + return TOK_STRING; } [\n\r\t ] \/\/[^\n]*\n? From ff249dfefb59a7d999210be269d1169c3db5646d Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Tue, 30 Nov 2010 20:44:05 +0000 Subject: [PATCH 3/8] Improvement to lexing of strings don't use QString.replace, use the power of flex instead. --- src/lexer.l | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index b9491693..86006d06 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -30,7 +30,7 @@ #include "parser_yacc.h" #include #include - +QString* stringcontents; int lexerget_lineno(void); #ifdef __GNUC__ static void yyunput(int, char*) __attribute__((unused)); @@ -63,7 +63,7 @@ extern const char *parser_source_path; %option yylineno %option noyywrap -%x comment +%x comment string DIGIT [0-9] @@ -140,15 +140,19 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { {DIGIT}+|{DIGIT}*\.{DIGIT}+|{DIGIT}+\.{DIGIT}* { parserlval.number = QString(yytext).toDouble(); return TOK_NUMBER; } "$"?[a-zA-Z0-9_]+ { parserlval.text = strdup(yytext); return TOK_ID; } -\"(\\[tnr\"\\]|[^\\"])*\" { QString str(yytext+1); - str.chop(1); - str=str.replace("\\\\","\\"); - str=str.replace("\\\"","\""); - str=str.replace("\\t","\t"); - str=str.replace("\\n","\n"); - str=str.replace("\\r","\r"); - parserlval.text = strdup(str.toAscii().data()); - return TOK_STRING; } +\" { BEGIN(string); stringcontents = new QString(); } +{ +\\n { stringcontents->append('\n'); } +\\t { stringcontents->append('\t'); } +\\r { stringcontents->append('\r'); } +\\\\ { stringcontents->append('\\'); } +\\\" { stringcontents->append('"'); } +[^\\\n\"]+ { stringcontents->append(lexertext); } +\" { BEGIN(INITIAL); + parserlval.text = strdup(stringcontents->toLocal8Bit()); + delete stringcontents; + return TOK_STRING; } +} [\n\r\t ] \/\/[^\n]*\n? From 5ef31011f39106318981d758967b64b5ee2fb275 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Fri, 3 Dec 2010 17:43:00 +0000 Subject: [PATCH 4/8] Added support for nested includes. --- src/lexer.l | 72 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 86006d06..91606c6e 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -28,6 +28,7 @@ #include "openscad.h" #include "printutils.h" #include "parser_yacc.h" +#include #include #include QString* stringcontents; @@ -58,35 +59,33 @@ extern const char *parser_source_path; } \ } +void includefile(); +QDir sourcepath(); +QStack path_stack; + +QString filename; +QString filepath; + %} %option yylineno %option noyywrap %x comment string +%x include path DIGIT [0-9] %% -include[ \t\r\n>]*"<"[^ \t\r\n>]+">" { - QString filename(yytext); - filename.remove(QRegExp("^include[ \t\r\n>]*<")); - filename.remove(QRegExp(">$")); - QFileInfo finfo(QDir(parser_source_path), filename); - if (!finfo.exists()) { - finfo = QFileInfo(QDir(librarydir), filename); - } - handle_dep(finfo.absoluteFilePath()); - yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r"); - if (!yyin) { - PRINTA("WARNING: Can't open input file `%1'.", filename); - } else { - yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); - BEGIN(INITIAL); - } +include[ \t\r\n>]*"<" { BEGIN(include); } +{ +[^\t\r\n>]+"/" { filepath = yytext; } +[^\t\r\n>/]+ { filename = yytext; } +">" { BEGIN(INITIAL); includefile(); } } + use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { QString filename(yytext); filename.remove(QRegExp("^use[ \t\r\n>]*<")); @@ -121,6 +120,8 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { } <> { + if(!path_stack.isEmpty()) + path_stack.pop(); if (yyin && yyin != stdin) fclose(yyin); yypop_buffer_state(); @@ -169,3 +170,42 @@ use[ \t\r\n>]*"<"[^ \t\r\n>]+">" { . { return yytext[0]; } +%% + +QDir sourcepath() +{ + if(!path_stack.isEmpty()) + return path_stack.top(); + + return QDir(parser_source_path); +} + +void includefile() +{ + if(filename.isEmpty()) + return; + + if(filepath.isEmpty()) { + path_stack.push(sourcepath()); + } else { + QFileInfo dirinfo(sourcepath(),filepath); + path_stack.push(dirinfo.dir()); + filepath.clear(); + } + + QFileInfo finfo(sourcepath(), filename); + if (!finfo.exists()) { + finfo = QFileInfo(QDir(librarydir), filename); + } + + handle_dep(finfo.absoluteFilePath()); + yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r"); + if (!yyin) { + PRINTA("WARNING: Can't open input file `%1'.", filename); + return; + } + filename.clear(); + + yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); +} + From d98e398ec185f87501c1374cc3863457ed450663 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Thu, 9 Dec 2010 12:18:24 +0000 Subject: [PATCH 5/8] Removed some unneeded cruft. --- src/lexer.l | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lexer.l b/src/lexer.l index 91606c6e..9e8aaf85 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -72,7 +72,7 @@ QString filepath; %option noyywrap %x comment string -%x include path +%x include DIGIT [0-9] @@ -80,9 +80,9 @@ DIGIT [0-9] include[ \t\r\n>]*"<" { BEGIN(include); } { -[^\t\r\n>]+"/" { filepath = yytext; } -[^\t\r\n>/]+ { filename = yytext; } -">" { BEGIN(INITIAL); includefile(); } +[^\t\r\n>]+"/" { filepath = yytext; } +[^\t\r\n>/]+ { filename = yytext; } +">" { BEGIN(INITIAL); includefile(); } } From 44dd33a5567681d28adb963d1d325aa86d723130 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Fri, 10 Dec 2010 11:46:09 +0000 Subject: [PATCH 6/8] Added some tests for new nested include feature. --- testdata/scad/include test6.scad | 4 ++ testdata/scad/include-test.scad | 37 +++++++++++++++++++ testdata/scad/include-test5.scad | 4 ++ .../scad/sub1/sub2/sub3/include-test4.scad | 4 ++ .../sub1/sub2/sub3/sub4/include-test2.scad | 10 +++++ .../sub1/sub2/sub3/sub4/include-test3.scad | 4 ++ 6 files changed, 63 insertions(+) create mode 100644 testdata/scad/include test6.scad create mode 100644 testdata/scad/include-test.scad create mode 100644 testdata/scad/include-test5.scad create mode 100644 testdata/scad/sub1/sub2/sub3/include-test4.scad create mode 100644 testdata/scad/sub1/sub2/sub3/sub4/include-test2.scad create mode 100644 testdata/scad/sub1/sub2/sub3/sub4/include-test3.scad diff --git a/testdata/scad/include test6.scad b/testdata/scad/include test6.scad new file mode 100644 index 00000000..7a794560 --- /dev/null +++ b/testdata/scad/include test6.scad @@ -0,0 +1,4 @@ +module test6() +{ + echo("included from include test6.scad"); +} diff --git a/testdata/scad/include-test.scad b/testdata/scad/include-test.scad new file mode 100644 index 00000000..a9528f5f --- /dev/null +++ b/testdata/scad/include-test.scad @@ -0,0 +1,37 @@ +//Test that the entire path is pushed onto the stack upto the last '/' +include + +//Test with empty path +include + +//Test without preceeding space +include + +//Test with other strange character that is allowed +include>>>>> + +//Test that filenames with spaces work +include + +//Test with empty file +include + +//Test with empty path and file +include + +//Test with empty +include <> + +module test1() +{ + test2(); + test3(); + test4(); + test5(); + test6(); + + //Just to give a top level object + sphere(1); +} + +test1(); diff --git a/testdata/scad/include-test5.scad b/testdata/scad/include-test5.scad new file mode 100644 index 00000000..4f6e6560 --- /dev/null +++ b/testdata/scad/include-test5.scad @@ -0,0 +1,4 @@ +module test5() +{ + echo("included from include-test5.scad"); +} diff --git a/testdata/scad/sub1/sub2/sub3/include-test4.scad b/testdata/scad/sub1/sub2/sub3/include-test4.scad new file mode 100644 index 00000000..1cb7eab2 --- /dev/null +++ b/testdata/scad/sub1/sub2/sub3/include-test4.scad @@ -0,0 +1,4 @@ +module test4() +{ + echo("included from include-test4.scad"); +} diff --git a/testdata/scad/sub1/sub2/sub3/sub4/include-test2.scad b/testdata/scad/sub1/sub2/sub3/sub4/include-test2.scad new file mode 100644 index 00000000..9f4c9632 --- /dev/null +++ b/testdata/scad/sub1/sub2/sub3/sub4/include-test2.scad @@ -0,0 +1,10 @@ +//Test nested include +include + +//Test relative file location +include <../include-test4.scad> + +module test2 () +{ + echo("included from include-test2.scad"); +} diff --git a/testdata/scad/sub1/sub2/sub3/sub4/include-test3.scad b/testdata/scad/sub1/sub2/sub3/sub4/include-test3.scad new file mode 100644 index 00000000..2f67e933 --- /dev/null +++ b/testdata/scad/sub1/sub2/sub3/sub4/include-test3.scad @@ -0,0 +1,4 @@ +module test3() +{ + echo("included from include-test3.scad"); +} From 03c02cde89d43d465b9e9a354be8668fe6fca56d Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Fri, 10 Dec 2010 18:31:33 +0000 Subject: [PATCH 7/8] A basic test for the escape sequences in strings. --- testdata/scad/string-test.scad | 1 + 1 file changed, 1 insertion(+) create mode 100644 testdata/scad/string-test.scad diff --git a/testdata/scad/string-test.scad b/testdata/scad/string-test.scad new file mode 100644 index 00000000..5ec4cfb4 --- /dev/null +++ b/testdata/scad/string-test.scad @@ -0,0 +1 @@ +echo("The quick brown fox \tjumps \"over\" the lazy dog.\rThe quick brown fox.\nThe \\lazy\\ dog."); From 052f8bc620f579271be69a0d0d699b8b4ac5bb14 Mon Sep 17 00:00:00 2001 From: Giles Bathgate Date: Sat, 11 Dec 2010 12:41:23 +0000 Subject: [PATCH 8/8] Fix for when the included file doesn't exist. Needed because we will never get an EOF, and so never pop the stack. --- src/lexer.l | 1 + testdata/scad/include-test.scad | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/lexer.l b/src/lexer.l index 9e8aaf85..932711ba 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -202,6 +202,7 @@ void includefile() yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r"); if (!yyin) { PRINTA("WARNING: Can't open input file `%1'.", filename); + path_stack.pop(); return; } filename.clear(); diff --git a/testdata/scad/include-test.scad b/testdata/scad/include-test.scad index a9528f5f..5db02d73 100644 --- a/testdata/scad/include-test.scad +++ b/testdata/scad/include-test.scad @@ -1,6 +1,9 @@ //Test that the entire path is pushed onto the stack upto the last '/' include +//Test that a non existent path/file doesn't screw things up +include + //Test with empty path include