From 874ee75cb80d2a9eed52e0a2d81250c24c91f8aa Mon Sep 17 00:00:00 2001 From: David de Hilster Date: Thu, 29 Oct 2026 15:55:30 -0400 Subject: [PATCH] logs/ is made on Linux and macOS; a CRLF .kbb or .dict loads there (4.2.52) dir_exists() and make_dir() in lite/mach.cpp are no-ops off Windows, so NLP::init never made /logs there. make_ana.log, cgerr.log and file.log all failed to open without a word, and an analyzer that did not build left no diagnostics at all on the platform that serves clients. init now makes logs/ with std::filesystem, as the compile branch already does for run/ (NLP-ENGINE-527). dir_exists()/make_dir() are left alone. readKBB, readDict and findDictConcept read lines with a bare getline(). A .kbb or .dict checked out on Windows has CRLF line ends, and read on Linux or macOS every line kept its '\r': the concepts loaded as "verbs\r" and findconcept("verbs") came back null, with no error. They now drop a trailing '\r', as readFullLine() already did for the lazy *full files. (Windows reads these in text mode and was not affected; .kb command files already handled '\r'.) Co-Authored-By: Claude Opus 5.5 --- cs/libconsh/cg.cpp | 12 ++++++++++++ lite/nlp.cpp | 10 ++++++++-- nlp/main.cpp | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cs/libconsh/cg.cpp b/cs/libconsh/cg.cpp index 16965ed1..20e675d0 100644 --- a/cs/libconsh/cg.cpp +++ b/cs/libconsh/cg.cpp @@ -3888,6 +3888,10 @@ bool CG::readDict(std::string file, std::vector kbfiles) allDictStream_.open(file, std::ios::in); while (std::getline(allDictStream_, line)) { + // A CRLF file (eg a Windows checkout) read on Linux/macOS keeps + // the '\r', which would end up in the last word or value. + if (!line.empty() && line.back() == '\r') + line.pop_back(); _TCHAR *buf = line.data(); lineCount++; // Blank out /* ... */ before the line lexer sees it. A comment-only @@ -4262,6 +4266,11 @@ bool CG::readKBB(std::string file) { bool inBlock = false; // Open "/*" carried between lines. while (std::getline(streamer, line)) { + // A CRLF file (eg a Windows checkout) read on Linux/macOS keeps + // the '\r': the concept on every line was then named "verbs\r" + // and findconcept("verbs") came back null, with no error. + if (!line.empty() && line.back() == '\r') + line.pop_back(); _TCHAR *buf = line.data(); // Blank out /* ... */ before the line lexer sees it. // 07/31/26 DD. // Only a line the stripper actually touched is dropped when it comes @@ -5194,6 +5203,9 @@ int32_t length2 = strp.length(); bool done = false; while (allDictStream_.getline(buf, MAXMSG) && !done) { + size_t blen = strlen(buf); + if (blen && buf[blen-1] == '\r') // CRLF file read on Linux/macOS. + buf[blen-1] = '\0'; icu::StringPiece sp(buf); const char *line = sp.data(); int32_t length = sp.length(); diff --git a/lite/nlp.cpp b/lite/nlp.cpp index c55e9244..007f3044 100644 --- a/lite/nlp.cpp +++ b/lite/nlp.cpp @@ -460,8 +460,14 @@ _TCHAR errout[MAXMSG]; // 03/22/99 AM. _TCHAR *logdirname = _T("logs"); // 05/19/01 AM. _TCHAR logdir[MAXSTR]; // 05/19/01 AM. _stprintf(logdir, _T("%s%c%s"), appdir,DIR_CH,logdirname); // 05/19/01 AM. -if (!dir_exists(logdir)) // 05/19/01 AM. - make_dir(logdir); // 05/19/01 AM. +// std::filesystem, not dir_exists()/make_dir(): both are no-ops on +// Linux/macOS (see NLP-ENGINE-527 below), so logs/ was never made there +// and make_ana.log, cgerr.log and file.log silently failed to open. A +// failed analyzer build then left no diagnostics at all off Windows. +{ +std::error_code ec; +std::filesystem::create_directory(logdir, ec); +} // SOME GLOBAL INITS. // 09/27/00 AM. diff --git a/nlp/main.cpp b/nlp/main.cpp index d45a2794..c6236e5b 100644 --- a/nlp/main.cpp +++ b/nlp/main.cpp @@ -18,7 +18,7 @@ All rights reserved. #include -#define NLP_ENGINE_VERSION "4.2.51" +#define NLP_ENGINE_VERSION "4.2.52" bool cmdReadArgs(int, _TCHAR *argv[], _TCHAR *&, _TCHAR *&, _TCHAR *&, _TCHAR *&, bool &, bool &, bool &, bool &, bool &, bool &, int &, bool &, bool &, _TCHAR *&, double &, _TCHAR *&); void cmdHelpargs(_TCHAR *);