ksherlock / mpw

Macintosh Programmer's Workshop (mpw) compatibility layer
238 stars 21 forks source link

Fix compilation with current readline #52

Open ryandesign opened 1 year ago

ryandesign commented 1 year ago

This PR fixes the following errors I got when trying to compile the latest code on macOS 12.3.1 with readline 8.1.2.000 installed (using MacPorts):

[ 73%] Building CXX object bin/CMakeFiles/mpw.dir/debugger.cpp.o
cd /path/to/build/bin && /usr/bin/clang++  -I/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1 -I/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/bin -I/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/libsane/include -Wall -Wno-deprecated-declarations -Wno-unused-variable -arch x86_64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk -mmacosx-version-min=12.0 -std=c++11 -MD -MT bin/CMakeFiles/mpw.dir/debugger.cpp.o -MF CMakeFiles/mpw.dir/debugger.cpp.o.d -o CMakeFiles/mpw.dir/debugger.cpp.o -c /path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/bin/debugger.cpp
/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/bin/debugger.cpp:1228:34: error: incompatible function pointer types assigning to 'rl_compentry_func_t *' (aka 'char *(*)(const char *, int)') from 'Function *' (aka 'int (*)()')
                rl_completion_entry_function = (Function *)mpw_completion_entry_function;
                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/bin/debugger.cpp:1240:2: error: use of undeclared identifier 'add_history'
        add_history("!Andy, it still has history!");
        ^
/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/bin/debugger.cpp:1312:4: error: unknown type name 'HIST_ENTRY'
                        HIST_ENTRY *he = current_history();
                        ^
/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/bin/debugger.cpp:1312:21: error: use of undeclared identifier 'current_history'
                        HIST_ENTRY *he = current_history();
                                         ^
/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/bin/debugger.cpp:1314:5: error: use of undeclared identifier 'add_history'
                                add_history(cp);
                                ^
5 errors generated.
make[2]: *** [bin/CMakeFiles/mpw.dir/debugger.cpp.o] Error 1

Function * is an ancient readline type which no longer exists. Function * and friends were deprecated in readline 4.2 (released April 2001) and removed in readline 6.3 (released February 2014).

The add_history and current_history functions and the HIST_ENTRY type appear to be defined in <readline/history.h> which I guess needs to be included separately now.

ryandesign commented 1 year ago

While this PR makes the code compile successfully with GNU readline 8.1.2.000 (and -ledit in bin/CMakeLists.txt should be changed to -lreadline as well; see #54), it also makes the code fail to compile with the "readline compatible" libedit included in macOS 12.3.1 with the unsurprising reverse error message

/path/to/mpw-022d4cffe99e2a0f991182196491cba434e842a1/bin/debugger.cpp:1229:34: error: incompatible function pointer types assigning to 'Function *' (aka 'int (*)(const char *, int)') from 'rl_compentry_func_t *' (aka 'char *(*)(const char *, int)')
                rl_completion_entry_function = (rl_compentry_func_t *)mpw_completion_entry_function;
                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

I'm not sure how one is meant to write software that is compatible with both readline and editline. It doesn't help that there appear to be several different projects calling themselves "libedit" or "editline".

ksherlock commented 1 year ago

When I was working on linux port, I did this:

#if RL_READLINE_VERSION == 0x0402
/* actually libedit */
rl_completion_entry_function = (Function *)mpw_completion_entry_function;
#else
/* gnu readline, I presume */
rl_completion_entry_function = mpw_completion_entry_function;
#endif

For another project that handled both, I did this, which is cleaner:

rl_completion_entry_function = reinterpret_cast<decltype(rl_completion_entry_function)>(mpw_completion_entry_function);