Open asmwarrior opened 4 years ago
Ah, yes. I was careless with the path conversions because this has been a slow effort to generalize the initialization logic from a bunch of commands I've been running manually on my own machine. In this case, just calling u8string() first is a quick fix, but the better solution is to leverage the new path API and have llreader
accept it instead of a bunch of hacked-up char*
overloads.
The quick fix is now in the twenty
branch. See #17.
You might have better luck with the Test target, assuming you have GoogleTest handy. The main method of the Debug target depends on ENIGMA's game engine source for input data, but the tests are totally hermetic.
Only issue is that they're still rather small. I'm building them up with corner cases which JDI was originally written to gloss over—things that usually don't matter for code completion. The new C++ standards expose the entire language very explicitly, so I'm having to recode large chunks to look more like pages out of the standard.
Ah, yes. I was careless with the path conversions because this has been a slow effort to generalize the initialization logic from a bunch of commands I've been running manually on my own machine. In this case, just calling u8string() first is a quick fix, but the better solution is to leverage the new path API and have
llreader
accept it instead of a bunch of hacked-upchar*
overloads.The quick fix is now in the
twenty
branch. See #17.
I'm on this branch, but the same error still exits.
The problem is: std::filesystem::path
Here, I see that in the document: std::filesystem::path - cppreference.com, and the document said:
value_type character type used by the native encoding of the filesystem: char on POSIX, wchar_t on Windows std::filesystem::path::c_str, this accesses the native path name as a character string.
So, on Windows, c_str() also return the native character type string, which is wchar_t type.
But incfile.open() need a char* type string.
I just missed a file. I fixed Main but not lex_cpp. Calling u8string().c_str()
is the workaround. Alternatively, it'd be better to replace the llreader
constructor and open()
routine to just accept const std::filesystem::path &
instead. But I can't remember if CreateFileW
takes the exact same parameters (it's proper to instead call it with the wide string version, CreateFileW(filename.u16string().c_str(),
...).
Patching lex_cpp.cpp
to just call u8string()
first is easier, but if you're willing to try out the CreateFileW patch, that'll solve this for the longer term.
I just missed a file. I fixed Main but not lex_cpp. Calling
u8string().c_str()
is the workaround.
I'm using such code: incfile.open((incfn = cur_path / fnfind).string().c_str());
, which is also OK.
Alternatively, it'd be better to replace the
llreader
constructor andopen()
routine to just acceptconst std::filesystem::path &
instead. But I can't remember ifCreateFileW
takes the exact same parameters (it's proper to instead call it with the wide string version,CreateFileW(filename.u16string().c_str(),
...).Patching
lex_cpp.cpp
to just callu8string()
first is easier, but if you're willing to try out the CreateFileW patch, that'll solve this for the longer term.
You can create a branch, and then I can test it? CreateFileW is a native Windows API, and we could use the std's function if possible?
Eh, Windows build's already broken. We'll get CI set up for it eventually. In the meantime, can't do worse than broken build. Pushed it as https://github.com/JoshDreamland/JustDefineIt/pull/17/commits/e44072c8f8d54e769bcd177336137edaaf6bfd42.
There are some other build errors, such as:
F:\code\justdefineit\JustDefineIt\test\MAIN.cc: In function 'int main(int, char**)':
F:\code\justdefineit\JustDefineIt\test\MAIN.cc:332:28: error: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'size_t' {aka 'long long unsigned int'} [-Werror=format=]
332 | printf("Final stats: %lu correct, %lu incorrect\n", correct, incorrect);
| ~~^ ~~~~~~~
| | |
| long unsigned int size_t {aka long long unsigned int}
| %llu
F:\code\justdefineit\JustDefineIt\test\MAIN.cc:332:41: error: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'size_t' {aka 'long long unsigned int'} [-Werror=format=]
332 | printf("Final stats: %lu correct, %lu incorrect\n", correct, incorrect);
| ~~^ ~~~~~~~~~
| | |
| long unsigned int size_t {aka long long unsigned int}
| %llu
It might be worth turning of -Werror in the build settings (or building with cmake). I hold myself to -Wpedantic-errors when building locally, but that's probably not the best way to get it running for you right now.
Oh, also worth noting that path.string()
will not necessarily behave correctly in C++20. It might return the wide string type. Explicitly asking for u8string/u16string should work out, though.
Oh, also worth noting that
path.string()
will not necessarily behave correctly in C++20. It might return the wide string type. Explicitly asking for u8string/u16string should work out, though.
OK.
Please note that there is no function under Windows like:
signal(SIGTRAP, donothing);
If I comment out this function, than I get
F:\code\justdefineit\JustDefineIt\src\System\lex_cpp.cpp:45:13: error: 'void donothing(int)' defined but not used [-Werror=unused-function]
So, I have to turning of -Werror in the build settings. I'm using cbp file.
Oof, no catching SIGTRAP, either? That's fine; there is logic elsewhere that raises SIGTRAP using an inline assembly block, but only if the code being parsed contains #pragma DEBUG_ENTRY_POINT
. I added the signal handler to avoid crashing when running with no debugger attached.
Turning off Werror is probably for the best, at this point. Let me know if anything else is still broken.
There are some Windows related build issue:
src/General/debug_macros.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/General/debug_macros.cpp b/src/General/debug_macros.cpp
index 9dd8178..fb561d7 100644
--- a/src/General/debug_macros.cpp
+++ b/src/General/debug_macros.cpp
@@ -36,8 +36,15 @@ void render_ast_nd(jdi::AST& ast, std::string cat)
string fullp = DEBUG_OUTPUT_PATH "/AST_Renders/" + cat; // The full path to which this AST will be rendered.
if (!ast_rn) {
+#ifdef __linux__
mkdir(DEBUG_OUTPUT_PATH "/AST_Renders", 0777);
mkdir(fullp.c_str(),0777);
+#else
+ mkdir(DEBUG_OUTPUT_PATH "/AST_Renders");
+ mkdir(fullp.c_str());
+#endif
+
+
}
char fn[32]; sprintf(fn,"/ast_%08u.svg",ast_rn++);
fullp += fn;
It looks mkdir only takes one parameter in Windows.
I can build the exe file (The Debug target in Code::Blocks project) Now, what is the way to simply test the parser?
When I run the target, it gives such command line messages:
Usage: JustDefineIt <c++std> </path/to/enigma> <test_lexer>
Will assume default values.
terminate called after throwing an instance of 'std::filesystem::__cxx11::filesy
stem_error'
what(): filesystem error: cannot create directory: No such file or directory
[/tmp/jdi]
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Process returned 3 (0x3) execution time : 43.420 s
Press any key to continue.
Maybe, the path is different with Linux and Windows.
My question is: Is it possible to simply let the parser parse a single header file. Such like:
JustDefineIt test.h
I can throw one together this evening for you to play with. As long as you only need C++03, you should see decent results. The target you're building is configured to parse a specific project of ours, and so it defines include directories and macros specific to that engine.
I cut the general parts out of the old main and into a new one under a new "Demo" build target (https://github.com/JoshDreamland/JustDefineIt/pull/17/commits/dcdce97d50a375aa4f23adb116ee11dd013cc539).
I am not certain it will build for you, but I've done my best on that front. I threw in a macro that preprocesses away __attribute__
. This is one of the training wheels I recently removed from the project to try to get it up to shape with C++11 and beyond. But without that, it can't correctly read, eg, std::string
, which greatly damages future code comprehension. With the macro in place, it works reasonably well:
> d std::string
Enter the item to define:
>> typedef basic_string<char, char_traits<char><>, allocator<char>> string;
...ignoring a CLI quirk in switching from getch()
to cin
. You can see where I defined it on line 249.
Cheers
Thanks.
This patch is need because Windows only have nul
demo/main.cc | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/demo/main.cc b/demo/main.cc
index 3e13065..1e21a58 100644
--- a/demo/main.cc
+++ b/demo/main.cc
@@ -80,9 +80,16 @@ static bool prepare_builtin_context() {
}
for (const std::string& p : include_paths) builtin.add_search_directory(p);
+
+#ifdef _WIN32
+ std::string dev_null = "nul";
+#else
+ std::string dev_null = "/dev/null";
+#endif // _WIN32
+
std::string preprocess_command =
- "cpp -dM -x c++ --std=" + cpp_std + " -E /dev/null"
- " > " + defines_file.u8string();
+ "cpp -dM -x c++ --std=" + cpp_std + " -E " + dev_null
+ + " > " + defines_file.u8string();
std::cout << "Obtaining GCC defines list via command line: "
<< preprocess_command << std::endl;
if (std::system(preprocess_command.c_str()) != 0) {
Also, I think this patch is also needed
test/MAIN.cc | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/test/MAIN.cc b/test/MAIN.cc
index d1cc32c..929fd3c 100644
--- a/test/MAIN.cc
+++ b/test/MAIN.cc
@@ -238,9 +238,14 @@ int main(int argc, char** argv) {
builtin.add_search_directory(enigma_shared.u8string());
builtin.add_search_directory(enigma_temp.u8string());
+#ifdef _WIN32
+ std::string dev_null = "nul"
+#else
+ std::string dev_null = "/dev/null"
+#endif // _WIN32
std::string preprocess_command =
- "cpp -dM -x c++ --std=" + get_cpp_standard_str(cpp_std) + " -E /dev/null"
- " > " + gcc_defines.u8string();
+ "cpp -dM -x c++ --std=" + get_cpp_standard_str(cpp_std) + " -E " + dev_null
+ + " > " + gcc_defines.u8string();
if (std::system(preprocess_command.c_str()) != 0) {
std::cerr << "Failed to generate gcc defines. Bye" << std::endl;
return -1;
Oops. I created a blank_file
variable to work around that, but I only plugged it into one of the two commands. Pushed a fix to use it in the other command in 03421f7.
And yes, at some point, I should merge the logic here with that in our original MAIN.cc
. I'm thinking I can move these calls directly into builtin.cpp
. I'd have done so already, but I dislike the reliance on temp files. Fortunately, std::filesystem
makes that vastly more convenient.
Is nul
a Windows idiom I've missed, or is it a file you created?
Under Windows, there is no such command(tool):
if (show) {
a.writeSVG("/tmp/anus.svg");
if (system("xdg-open /tmp/anus.svg"))
std::cout << "Failed to open." << std::endl;
}
Is there any way I can print/view the whole parsing tree?
Here is my log, which seems correct, but I'd like to check how the parser is parsing a simple file:
Created blank file for preprocessing.
Polling GCC for include directories for c++03...
- Command: gcc -E -x c++ --std=c++03 -v C:\Users\zyh\AppData\Local\Temp\jdi\bla
nk > C:\Users\zyh\AppData\Local\Temp\jdi\search_dirs.txt 2>&1
- Command succeeded. System include paths:
- F:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../inc
lude/c++/10.1.0
- F:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../inc
lude/c++/10.1.0/x86_64-w64-mingw32
- F:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../inc
lude/c++/10.1.0/backward
- F:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/include
- F:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../inc
lude
- F:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/include-fixed
- F:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86
_64-w64-mingw32/include
Obtaining GCC defines list via command line: cpp -dM -x c++ --std=c++03 -E nul >
C:\Users\zyh\AppData\Local\Temp\jdi\defines.cc
Command succeeded. Reading in GCC definitions.Beginning parse of file `"test.h"`
...
====[++++++++++++++++++++++++++++++ SUCCESS! ++++++++++++++++++++++++++++++]====
Parse completed with 0 errors and 0 warnings.
Commands are single-letter; 'h' for help.
Follow commands with ENTER on non-unix.
> h
'c' Coerce an expression, printing its type
'd' Define a symbol, printing it recursively
'e' Evaluate an expression, printing its result
'f' Print flags for a given definition
'h' Print this help information
'm' Define a macro, printing a breakdown of its definition
'o' Print the order of declarations in a given scope
'r' Render an AST representing an expression
's' Render an AST representing an expression and show it
'q' Quit this interface
> c
Enter the expression to evaluate:
>> ERROR(user input:1:0): Expected expression before end of code ()
Bailing.
> c std::string
Enter the expression to evaluate:
>> ERROR(user input:1:12): Scope `int` (`std`) has no member `string`
Type of expression: <null>
nullptr
> e std::string
Enter the expression to evaluate:
>> ERROR(user input:1:12): AST evaluation failure: No `string' found in primitiv
e int
Value returned: 0
This is my test.h file:
// my_class.h
namespace N
{
class my_class
{
public:
void do_something();
};
}
You want the d
command. Use d ::
and it'll just dump everything.
Is
nul
a Windows idiom I've missed, or is it a file you created?
See here: linux - What is a cross-platform compatible way to redirect to NUL or /dev/null? - Stack Overflow
Under Code::Blocks' source code, we use something similar like:
// Windows: mingw32-g++ -v -E -x c++ nul
// Linux : g++ -v -E -x c++ /dev/null
// do the trick only for c++, not needed then for C (since this is a subset of C++)
// Different command on Windows and other OSes
#ifdef __WXMSW__
const wxString args(_T(" -v -E -x c++ nul"));
#else
const wxString args(_T(" -v -E -x c++ /dev/null"));
#endif
Ah. Well, you can also just populate search dirs manually the same way the functions in that routine does. Our game engine also has that info lying around, which is why I never moved it into the API.
And before you ask, here's a breakdown of some oddities you'll see in the output:
inline void swap(<null> &_Tp, <null>, <null> &_Tp);
The argument types aren't known (parsing error).
template<typename _Iterator> inline (?=reverse_iterator<_Iterator>::difference_type) operator-(const reverse_iterator &__x, const reverse_iterator &__y); // ... typedef (?=__truth_type<__value>::__type) __type;
The types are kind of known (they're dependent types).
typedef __locale_t __c_locale (typedef __locale_struct *__locale_t;)
Printing error (not so pretty print I hacked together for inspection).
Also probably a few thousand parse errors in general. Some from missing features, some from bugs. Working on it, slowly.
I see a build error when building the demo target, see this log
-------------- Build file: Demo in JustDefineIt (compiler: GNU GCC Compiler)---------------
[100.0%] g++.exe -Wshadow -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Wunreachable-code -Wmissing-declarations -Wswitch-enum -Wswitch-default -Wmain -pedantic-errors -pedantic -Wextra -Wall -Wmissing-include-dirs -std=c++1z -g -D_GLIBCXX_DEBUG -DDEBUG_MODE -I.\src -c F:\code\justdefineit\JustDefineIt\src\General\llreader.cpp -o obj\Debug\src\General\llreader.o
In file included from F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/debug.h:133,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/bits/stl_algobase.h:69,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/bits/char_traits.h:39,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/string:40,
from F:\code\justdefineit\JustDefineIt\src\General\llreader.h:41,
from F:\code\justdefineit\JustDefineIt\src\General\llreader.cpp:39:
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:424:15: error: expected unqualified-id before ')' token
424 | __deref();
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:427:34: error: expected primary-expression before '<' token
427 | typename = decltype(__deref<_It>() < __deref<_It>())>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:427:38: error: expected primary-expression before '>' token
427 | typename = decltype(__deref<_It>() < __deref<_It>())>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:427:40: error: expected primary-expression before ')' token
427 | typename = decltype(__deref<_It>() < __deref<_It>())>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:427:51: error: expected primary-expression before '<' token
427 | typename = decltype(__deref<_It>() < __deref<_It>())>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:427:55: error: expected primary-expression before '>' token
427 | typename = decltype(__deref<_It>() < __deref<_It>())>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:427:57: error: expected primary-expression before ')' token
427 | typename = decltype(__deref<_It>() < __deref<_It>())>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:441:42: error: expected primary-expression before '<' token
441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:441:46: error: expected primary-expression before '>' token
441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:441:48: error: expected primary-expression before ')' token
441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:441:58: error: expected primary-expression before '<' token
441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:441:62: error: expected primary-expression before '>' token
441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
| ^
F:/msys64-20200924/mingw64/include/c++/10.2.0/debug/functions.h:441:64: error: expected primary-expression before ')' token
441 | = decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
| ^
Process terminated with status 1 (0 minute(s), 3 second(s))
13 error(s), 0 warning(s) (0 minute(s), 3 second(s))
It looks like this is caused by a GCC 10 version under msys2?
Perhaps moving #include "llreader.h"
to the top of llreader.cpp
will fix it? The problem seems to be a build error just from including headers in that order, which shouldn't happen. My guess is just #include <windows.h>
followed by #include <string>
will reproduce it, in which case it's a MinGW/msys bug. Can you check?
Perhaps moving
#include "llreader.h"
to the top ofllreader.cpp
will fix it?
Yes, this fixes the build issue, thanks for the help!
The problem seems to be a build error just from including headers in that order, which shouldn't happen. My guess is just
#include <windows.h>
followed by#include <string>
will reproduce it, in which case it's a MinGW/msys bug. Can you check?
I just create a simple test code like below:
#include <string>
#include <windows.h>
using namespace std;
int main()
{
return 0;
}
And it builds OK without any issue.
-------------- Build: Debug in abc (compiler: GNU GCC Compiler)---------------
[ 50.0%] g++.exe -Wall -fexceptions -g -c D:\code\test-msys2-code\abc\main.cpp -o obj\Debug\main.o
[100.0%] g++.exe -o bin\Debug\abc.exe obj\Debug\main.o
Output file is bin\Debug\abc.exe with size 135.31 KB
Process terminated with status 0 (0 minute(s), 1 second(s))
0 error(s), 0 warning(s) (0 minute(s), 1 second(s))
You want the
d
command. Used ::
and it'll just dump everything.
It looks like this command does not dump everything, it just print the namespace.
I have this code to be parsed:
// my_class.h
namespace N
{
class my_class
{
public:
void do_something();
};
}
Then here is the command result:
> d ::
Enter the item to define:
>> {
namespace N {
}
}
>
Does this command only print the namespace recursively? It does not print the symbol void do_something();
. Thanks.
Ugh. No, sounds as though I've broken something. I haven't finished integrating the newly-merged master with our own codebase yet, so not terribly surprising I missed something in my cursory inspection. What's odd is that I confirmed the system recognized our own structures, so perhaps this is a recent regression I didn't think to look for.
I'll get some unit tests added for this and we can hopefully avoid this problem in the future. Thanks for the update!
Yeah, it was a regression. While I was replacing all JDI's internal pointer types with unique_ptr
, I noticed struct definitions were being written to the same pool as other definitions, meaning there was no way to correctly have a class and non-class with the same name in one scope. I fixed that, breaking some of the reflection on types. Pushed a fix, as well as unit tests, to the twenty
branch.
I've gone ahead and merged it into master. No sense turning back, at this point.
OK, It now print the member function. Good work!
BTW, I have a lot of changes in my local copy against the master HEAD. Which make the cbp build under Windows(I'm using code::blocks + Msys2)
Here is first patch:
From 18e768165297a9bc7d37b648c70f8c1d487fc6e3 Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Sun, 5 Jul 2020 14:08:54 +0800
Subject: [PATCH 01/10] mkdir only accept one argument under Windows
---
src/General/debug_macros.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/General/debug_macros.cpp b/src/General/debug_macros.cpp
index 9dd8178..fb561d7 100644
--- a/src/General/debug_macros.cpp
+++ b/src/General/debug_macros.cpp
@@ -36,8 +36,15 @@ void render_ast_nd(jdi::AST& ast, std::string cat)
string fullp = DEBUG_OUTPUT_PATH "/AST_Renders/" + cat; // The full path to which this AST will be rendered.
if (!ast_rn) {
+#ifdef __linux__
mkdir(DEBUG_OUTPUT_PATH "/AST_Renders", 0777);
mkdir(fullp.c_str(),0777);
+#else
+ mkdir(DEBUG_OUTPUT_PATH "/AST_Renders");
+ mkdir(fullp.c_str());
+#endif
+
+
}
char fn[32]; sprintf(fn,"/ast_%08u.svg",ast_rn++);
fullp += fn;
--
2.25.0.windows.1
This is the second patch, which comment out the signal function under Windows. I think we need a #if here?
From 32ceb44f9cc14c0844843253112116bfc347fa34 Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Sun, 5 Jul 2020 14:09:58 +0800
Subject: [PATCH 02/10] comment out the signal() function call as there is not
such all under windows
---
src/System/lex_cpp.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/System/lex_cpp.cpp b/src/System/lex_cpp.cpp
index f80c20c..1cf2f6a 100644
--- a/src/System/lex_cpp.cpp
+++ b/src/System/lex_cpp.cpp
@@ -1119,7 +1119,7 @@ void lexer::handle_preprocessor() {
{
string n = read_preprocessor_args();
if (n == "DEBUG_ENTRY_POINT" and (conditionals.empty() or conditionals.back().is_true)) {
- signal(SIGTRAP, donothing); // Try not to die when we raise hell in the interrupt handler briefly
+ //signal(SIGTRAP, donothing); // Try not to die when we raise hell in the interrupt handler briefly
asm("INT3;"); // Raise hell in the interrupt handler; the debugger will grab us from here
cout << "* Debug entry point" << endl;
}
--
2.25.0.windows.1
The third patch. Do you have a rule that the trailing line space should be removed?
From 1ba7464df9e6ef777a8e6c1ff3a551c7cfd51ac7 Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Sun, 5 Jul 2020 14:10:18 +0800
Subject: [PATCH 03/10] remove trailing spaces
---
src/General/debug_macros.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/General/debug_macros.cpp b/src/General/debug_macros.cpp
index fb561d7..4d77582 100644
--- a/src/General/debug_macros.cpp
+++ b/src/General/debug_macros.cpp
@@ -1,22 +1,22 @@
/**
* @file debug_macros.cpp
* @brief Source implementing the conditional macros for parser debugging.
- *
+ *
* This file implements the ass-end of the debug macros.
*
* @section License
- *
+ *
* Copyright (C) 2011 Josh Ventura
* This file is part of JustDefineIt.
- *
+ *
* JustDefineIt is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3 of the License, or (at your option) any later version.
- *
+ *
* JustDefineIt is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
+ *
* You should have received a copy of the GNU General Public License along with
* JustDefineIt. If not, see <http://www.gnu.org/licenses/>.
**/
@@ -34,7 +34,7 @@ static unsigned ast_rn = 0;
void render_ast_nd(jdi::AST& ast, std::string cat)
{
string fullp = DEBUG_OUTPUT_PATH "/AST_Renders/" + cat; // The full path to which this AST will be rendered.
-
+
if (!ast_rn) {
#ifdef __linux__
mkdir(DEBUG_OUTPUT_PATH "/AST_Renders", 0777);
@@ -48,7 +48,7 @@ void render_ast_nd(jdi::AST& ast, std::string cat)
}
char fn[32]; sprintf(fn,"/ast_%08u.svg",ast_rn++);
fullp += fn;
-
+
ast.writeSVG(fullp.c_str());
}
--
2.25.0.windows.1
The forth patch, I have to use a type cast operator to make the compiler happy.
From f2a3aed012de21775e2270d15fd50b1e2f2fc459 Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Sun, 5 Jul 2020 14:11:23 +0800
Subject: [PATCH 04/10] cast type to int, if not use cast, the compiler get
confused witch type to convert
---
src/Storage/definition.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Storage/definition.cpp b/src/Storage/definition.cpp
index dd21764..f5fd2cd 100644
--- a/src/Storage/definition.cpp
+++ b/src/Storage/definition.cpp
@@ -652,7 +652,7 @@ string definition_template::toString(unsigned levels, unsigned indent) const {
else {
res += (d->integer_type.def? d->integer_type.toString() : "<ERROR>");
if (d->flags & DEF_VALUED)
- res += " = " + ((definition_valued*) d.get())->value_of;
+ res += " = " + int(((definition_valued*) d.get())->value_of);
}
first = false;
}
--
2.25.0.windows.1
Now the patch for the cbp file, I just disable the compiler option
From 32542b7716cde05ea45f3decef66014346479f85 Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Sat, 11 Jul 2020 11:25:56 +0800
Subject: [PATCH 06/10] cbp: disable -Werror
---
JustDefineIt.cbp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/JustDefineIt.cbp b/JustDefineIt.cbp
index 41f583c..5ec48b9 100644
--- a/JustDefineIt.cbp
+++ b/JustDefineIt.cbp
@@ -93,14 +93,12 @@
</Build>
<Compiler>
<Add option="-Wshadow" />
- <Add option="-Winit-self" />
<Add option="-Wredundant-decls" />
<Add option="-Wcast-align" />
<Add option="-Wundef" />
<Add option="-Wfloat-equal" />
<Add option="-Wunreachable-code" />
<Add option="-Wmissing-declarations" />
- <Add option="-Wmissing-include-dirs" />
<Add option="-Wswitch-enum" />
<Add option="-Wswitch-default" />
<Add option="-Wmain" />
@@ -108,7 +106,7 @@
<Add option="-pedantic" />
<Add option="-Wextra" />
<Add option="-Wall" />
- <Add option="-Werror" />
+ <Add option="-Wmissing-include-dirs" />
<Add directory="./src" />
</Compiler>
<Unit filename="demo/main.cc">
--
2.25.0.windows.1
Also, another changes which make the compiler happy
From 63d5b4357ab9c21829d79f08bac43792de17ebfe Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Sat, 11 Jul 2020 11:26:26 +0800
Subject: [PATCH 07/10] printf use %zu
---
test/MAIN.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/MAIN.cc b/test/MAIN.cc
index 31731d8..d1cc32c 100644
--- a/test/MAIN.cc
+++ b/test/MAIN.cc
@@ -329,7 +329,7 @@ int main(int argc, char** argv) {
printf("%2d : %2d - %d\n", a, b, ndiffs);
ndiffs += diff;
}
- printf("Final stats: %lu correct, %lu incorrect\n", correct, incorrect);
+ printf("Final stats: %zu correct, %zu incorrect\n", correct, incorrect);
return 0;
}
--
2.25.0.windows.1
There is nul under Windows which is different than Linux
From c069bb55fd33092007c8ae1d391ebbe7151c6e51 Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Tue, 6 Oct 2020 13:18:03 +0800
Subject: [PATCH 08/10] fix build error on Windows(it use nul in Windows)
---
test/MAIN.cc | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/test/MAIN.cc b/test/MAIN.cc
index d1cc32c..db3cb15 100644
--- a/test/MAIN.cc
+++ b/test/MAIN.cc
@@ -238,9 +238,14 @@ int main(int argc, char** argv) {
builtin.add_search_directory(enigma_shared.u8string());
builtin.add_search_directory(enigma_temp.u8string());
+#ifdef _WIN32
+ std::string dev_null = "nul";
+#else
+ std::string dev_null = "/dev/null";
+#endif // _WIN32
std::string preprocess_command =
- "cpp -dM -x c++ --std=" + get_cpp_standard_str(cpp_std) + " -E /dev/null"
- " > " + gcc_defines.u8string();
+ "cpp -dM -x c++ --std=" + get_cpp_standard_str(cpp_std) + " -E " + dev_null
+ + " > " + gcc_defines.u8string();
if (std::system(preprocess_command.c_str()) != 0) {
std::cerr << "Failed to generate gcc defines. Bye" << std::endl;
return -1;
--
2.25.0.windows.1
BTW: I see that in today's rebase, you have change some dev_null string in other place by a blank_file
, maybe blank_file
could be also used here?
As you suggested, I have put the llreader.h in the first place of the cpp file, which fix the build error.
From a0354e104cb837addaa0b6070ef10c2c5cb3c94a Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Tue, 6 Oct 2020 13:18:43 +0800
Subject: [PATCH 09/10] fix build error under Msys2
---
src/General/llreader.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/General/llreader.cpp b/src/General/llreader.cpp
index 55eb36c..0f76b04 100644
--- a/src/General/llreader.cpp
+++ b/src/General/llreader.cpp
@@ -23,7 +23,7 @@
* You should have received a copy of the GNU General Public License along with
* JustDefineIt. If not, see <http://www.gnu.org/licenses/>.
**/
-
+#include "llreader.h"
#include <cstdio>
#include <cstring>
#if defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__WIN64__)
@@ -36,7 +36,7 @@
#include <fcntl.h>
#endif
-#include "llreader.h"
+
#include <iostream>
/// Enumeration of open states for an \c llreader.
--
2.25.0.windows.1
I see another build error here:
[100.0%] g++.exe -Wshadow -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Wunreachable-code -Wmissing-declarations -Wswitch-enum -Wswitch-default -Wmain -pedantic-errors -pedantic -Wextra -Wall -Wmissing-include-dirs -std=c++1z -g -D_GLIBCXX_DEBUG -DDEBUG_MODE -I.\src -c F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp -o obj\Debug\src\Parser\handlers\handle_declarators.o
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp: In member function 'int jdi::context_parser::handle_declarators(jdi::definition_scope*, jdi::token_t&, unsigned int, jdi::definition*&)':
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:52:16: error: expected unqualified-id before '=' token
52 | bool _inline = token.type == TT_DECFLAG && token.content.toString() == "inline";
| ^
In file included from F:/msys64-20200924/mingw64/x86_64-w64-mingw32/include/corecrt.h:10,
from F:/msys64-20200924/mingw64/x86_64-w64-mingw32/include/crtdefs.h:10,
from F:/msys64-20200924/mingw64/x86_64-w64-mingw32/include/stddef.h:7,
from F:/msys64-20200924/mingw64/lib/gcc/x86_64-w64-mingw32/10.2.0/include/stddef.h:1,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/bits/cxxabi_init_exception.h:38,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/bits/exception_ptr.h:38,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/exception:147,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/new:41,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/ext/new_allocator.h:33,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/x86_64-w64-mingw32/bits/c++allocator.h:33,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/bits/allocator.h:46,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/bits/stl_tree.h:64,
from F:/msys64-20200924/mingw64/include/c++/10.2.0/map:60,
from .\src/API/context.h:36,
from .\src/Parser/context_parser.h:58,
from F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:26:
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:93:14: error: 'decl-specifier' invalid in condition
93 | else if (_inline && token.type == TT_NAMESPACE) {
| ^~~~~~~
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:93:14: error: 'inline' specifier invalid for variable 'token' declared at block scope
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:93:25: warning: declaration of 'int&& token' shadows a parameter [-Wshadow]
93 | else if (_inline && token.type == TT_NAMESPACE) {
| ^~~~~
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:47:74: note: shadowed declaration is here
47 | int context_parser::handle_declarators(definition_scope *scope, token_t& token,
| ~~~~~~~~~^~~~~
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:93:30: error: expected initializer before '.' token
93 | else if (_inline && token.type == TT_NAMESPACE) {
| ^
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:93:30: error: expected ')' before '.' token
93 | else if (_inline && token.type == TT_NAMESPACE) {
| ~ ^
| )
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:94:54: error: cannot convert 'int' to 'jdi::token_t&'
94 | definition_scope *ns = handle_namespace(scope, token);
| ^~~~~
| |
| int
In file included from F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:26:
.\src/Parser/context_parser.h:401:72: note: initializing argument 2 of 'jdi::definition_scope* jdi::context_parser::handle_namespace(jdi::definition_scope*, jdi::token_t&)'
401 | definition_scope *handle_namespace(definition_scope *scope, token_t& token);
| ~~~~~~~~~^~~~~
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:97:17: error: request for member 'type' in 'token', which is of non-class type 'int'
97 | if (token.type != TT_RIGHTBRACE) return 1;
| ^~~~
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:98:13: error: request for member 'type' in 'token', which is of non-class type 'int'
98 | token.type = TT_SEMICOLON;
| ^~~~
F:\code\justdefineit\JustDefineIt\src\Parser\handlers\handle_declarators.cpp:101:13: error: request for member 'report_error' in 'token', which is of non-class type 'int'
101 | token.report_error(herr, "Declaration does not give a valid type");
| ^~~~~~~~~~~~
Process terminated with status 1 (0 minute(s), 2 second(s))
9 error(s), 1 warning(s) (0 minute(s), 2 second(s))
It looks in such line bool _inline = token.type == TT_DECFLAG && token.content.toString() == "inline";
int context_parser::handle_declarators(definition_scope *scope, token_t& token,
unsigned inherited_flags,
definition* &res) {
// Skip destructor tildes; log if we are a destructor
bool dtor = token.type == TT_TILDE;
bool _inline = token.type == TT_DECFLAG && token.content.toString() == "inline";
if (dtor) token = read_next_token(scope);
// Outsource to read_fulltype, which will take care of the hard work for us.
// When this function finishes, per its specification, our token will be set to the next relevant, non-referencer symbol.
// This means an identifier if the syntax is correct.
full_type tp = read_fulltype(token, scope);
if (dtor) {
if (tp.refs.name.empty() && tp.def == scope && !tp.flags &&
tp.refs.size() == 1 && tp.refs.top().type == ref_stack::RT_FUNCTION) {
tp.refs.name = "~" + scope->name;
tp.def = builtin_type__void;
} else {
token.report_error(herr, "Junk destructor; remove tilde?");
FATAL_RETURN(1);
}
}
Any idea how to fix this build error, I have to comment out the part after the &&
to work around this issue, but this is not a solution.
workaround:
From 61dc3e4cf18bb0eccb024e99f5358ccad585cf23 Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Sun, 5 Jul 2020 14:12:12 +0800
Subject: [PATCH 05/10] ! do not compare the inline string?
---
src/Parser/handlers/handle_declarators.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Parser/handlers/handle_declarators.cpp b/src/Parser/handlers/handle_declarators.cpp
index 6c58216..23462f7 100644
--- a/src/Parser/handlers/handle_declarators.cpp
+++ b/src/Parser/handlers/handle_declarators.cpp
@@ -49,7 +49,7 @@ int context_parser::handle_declarators(definition_scope *scope, token_t& token,
definition* &res) {
// Skip destructor tildes; log if we are a destructor
bool dtor = token.type == TT_TILDE;
- bool _inline = token.type == TT_DECFLAG && token.content.toString() == "inline";
+ bool _inline_1 = (token.type == TT_DECFLAG) ;//&& (token.content.toString() == "inline"));
if (dtor) token = read_next_token(scope);
// Outsource to read_fulltype, which will take care of the hard work for us.
@@ -90,7 +90,7 @@ int context_parser::handle_declarators(definition_scope *scope, token_t& token,
herr->at(token));
return !res;
}
- else if (_inline && token.type == TT_NAMESPACE) {
+ else if (_inline_1 && token.type == TT_NAMESPACE) {
definition_scope *ns = handle_namespace(scope, token);
if (!ns) return 1;
scope->use_namespace(ns);
--
2.25.0.windows.1
The compiler you're using seems to have some serious problems... that, or Windows has reserved _inline
. In theory, only __inline
would be reserved for the compiler. Anyway, renaming it to is_inline
should work.
Thanks for the patches! I'll apply them tonight. Might be easier to just commit them to a local fork and drop a pull request. Or I can give you access to push them as a branch, if you like.
I can start a pull request, but I think a lot of my patches should be modified, because it will break the Linux build.
That's the reason I post the patch contents here in the comments.
Ah, I understand. Nope, don't worry about it. I'll update the code around the patched areas to use newer C++ features instead of relying on platform-specific code. Looks as though most of these patches are for things covered by std::filesystem, or small oversights my compiler doesn't care about.
Thanks for the pointers!
One question: why does your implementation not support <csignal>
? It's been standard since the beginning of time. Microsoft even lists it, here: https://docs.microsoft.com/en-us/cpp/standard-library/csignal?view=vs-2019
Is it just the SIGTRAP macro? I can replace it with 3.
One question: why does your implementation not support
<csignal>
? It's been standard since the beginning of time. Microsoft even lists it, here: https://docs.microsoft.com/en-us/cpp/standard-library/csignal?view=vs-2019Is it just the SIGTRAP macro? I can replace it with 3.
Yes, it is just SIGTRAP macro.
See the build error:
-------------- Build file: Demo in JustDefineIt (compiler: GNU GCC Compiler)---------------
[100.0%] g++.exe -Wshadow -Wredundant-decls -Wcast-align -Wundef -Wfloat-equal -Wunreachable-code -Wmissing-declarations -Wswitch-enum -Wswitch-default -Wmain -pedantic-errors -pedantic -Wextra -Wall -Wmissing-include-dirs -std=c++1z -g -D_GLIBCXX_DEBUG -DDEBUG_MODE -I.\src -c F:\code\justdefineit\JustDefineIt\src\System\lex_cpp.cpp -o obj\Debug\src\System\lex_cpp.o
F:\code\justdefineit\JustDefineIt\src\System\lex_cpp.cpp: In member function 'void jdi::lexer::handle_preprocessor()':
F:\code\justdefineit\JustDefineIt\src\System\lex_cpp.cpp:1122:20: error: 'SIGTRAP' was not declared in this scope
1122 | signal(SIGTRAP, donothing); // Try not to die when we raise hell in the interrupt handler briefly
| ^~~~~~~
Process terminated with status 1 (0 minute(s), 3 second(s))
1 error(s), 0 warning(s) (0 minute(s), 3 second(s))
Still haven't figured out that header order problem. I think maybe you need to enable STL debug mode to reproduce it, but I still think it's the include order of <windows.h>
and <string>
. It would be good to hunt that down, as I'm pretty sure it's a library issue. My guess would be #define reference
appearing somewhere in the Windows headers.
Regardless, the include belongs at the top of the file, anyway, and I've applied those patches or a similar fix and created #21 to merge them. I am hoping that branch will build for you without error. It might be good to have a dump of all the compiler warnings so I can take a crack at those, but I'm sure I'll generate more when I go to add support for parameter packs and decltype.
I'm building the PatchesForWindows
branch, and it build successfully under MSYS2 + CodeBlocks.
Good work!
Excellent. Also, fundies went ahead and added a MinGW build to the CI, so we should be able to avoid future breakages that way.
I have msys2, and have its 64bit GCC compiler install. When using the cbp file under Code::Blocks, I see some build errors, such as this one:
There are some other build errors, but let's fix them one by one.