Filenames with spaces; output beside the input file; warning fixes (from dev c08eb1bbfa4c)

- Filenames may contain spaces: quote on the command line; filename
  lists use a standalone "/" separator; unseparated names that do not
  exist are rejoined into names that do (announced); leading ~ expands.
- Without -o, output is written to the input file's directory; -o fully
  specifies the output directory and basename.
- "Word not parsed" warnings now appear without -v, only for text that
  survives removal, with correct line numbers.
- New tst/filename_test.sh regression suite.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 23:22:59 +02:00
parent d9c98ac86d
commit fd9a370af7
21 changed files with 430 additions and 34 deletions

View File

@@ -92,16 +92,39 @@ katom_list make_katoms_from_word(std::string s, const std::string& source_desc,
return klist;
}
}
if (verbose_level > 0) {
std::cerr << command_name
<< " [warning]: Word not parsed in "
<< source_desc << ", line " << line+1 << ":\n"
<< " " << s << "\n"
<< "To include a special character (@, |, #, and ^), put \"^\" before it.\n";
//return std::vector{ std::make_shared<Katom>(s, Locator(), katom_t::word) };
//return std::vector{ std::make_shared<Katom>(s, katom_t::word, Locator(source_desc, line, chr)) };
Katom k(s, katom_t::word, Locator(source_desc, line, chr));
k.m_unparsed = true; // Warning deferred to warn_unparsed_katoms()
return std::vector{ k };
}
}
// Warn about words that matched no katom type -- but only those that
// survive processing: text removed by #, ##, or #[...]#, replaced spans,
// and literal content (definition interiors, @code bodies) never warn.
// Called at the end of Machine::process_katoms(), after those passes have
// marked the katoms. Clears the flag after warning so repeated processing
// of the same katom list does not warn twice. With warn=false (the @eval
// read-back sub-Machine, whose katoms hold machine-generated result text)
// no warning is printed and every flag is cleared, so the katoms stay
// silent after they are spliced into the calling Machine's list.
void warn_unparsed_katoms(katom_list& katoms, bool warn)
{
for (Katom& k : katoms) {
if (!k.m_unparsed) continue;
if (!warn) {
k.m_unparsed = false;
continue;
}
if (k.m_type != katom_t::ignored
&& k.m_type != katom_t::replaced
&& k.m_type != katom_t::literal) {
std::cerr << command_name
<< " [warning]: Word not parsed in "
<< k.m_loc.m_filename << ", line " << k.m_loc.m_line << ":\n"
<< " " << k.m_text << "\n"
<< "To include a special character (@, |, #, and ^), put \"^\" before it.\n";
k.m_unparsed = false;
}
return std::vector{ Katom(s, katom_t::word, Locator(source_desc, line, chr)) };
}
}