write tool fixes
This commit is contained in:
+2
-2
@@ -197,8 +197,8 @@ int rune_width(int cp);
|
||||
|
||||
void mkdir_p(std::string_view dir);
|
||||
std::string project_id();
|
||||
std::string bantam_tmp_dir();
|
||||
std::string tool_res_dir();
|
||||
std::string bantam_tmp_dir(std::string_view sess_id = "");
|
||||
std::string tool_res_dir(std::string_view sess_id = "");
|
||||
std::string md5_hex(std::string_view data);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
@@ -229,6 +229,8 @@ static int AL(Cfg &cfg, Messages &msgs, Usage &out, volatile int *interrupted, s
|
||||
else if (!has_line && !has_byte && !has_del_lines && !has_del_bytes) {
|
||||
/* No offset/deletion parameters: overwrite the whole file. */
|
||||
std::string c = filter_text(cv);
|
||||
/* Ensure the written file ends with a single trailing newline. */
|
||||
if (!c.empty() && c.back() != '\n') c.push_back('\n');
|
||||
auto sl = fp.find_last_of('/');
|
||||
if (sl != std::string::npos) mkdir_p(std::string_view(fp).substr(0, sl));
|
||||
else mkdir_p(".");
|
||||
@@ -236,6 +238,10 @@ static int AL(Cfg &cfg, Messages &msgs, Usage &out, volatile int *interrupted, s
|
||||
else { res = sfmt("Successfully wrote %zu bytes to %s", c.size(), fp.c_str()); }
|
||||
} else {
|
||||
int werr = 0; std::string c = filter_text(cv);
|
||||
/* Line-based edits keep the text-file trailing-newline convention;
|
||||
* byte-based edits are exact byte operations and must not have a
|
||||
* newline injected. */
|
||||
if (!(has_byte || has_del_bytes) && !c.empty() && c.back() != '\n') c.push_back('\n');
|
||||
res = write_file(fp, line_off, byte_off, del_lines, del_bytes, c, &werr);
|
||||
if (werr) sty = 31;
|
||||
}
|
||||
|
||||
@@ -291,6 +291,13 @@ std::string write_file(std::string_view path, long line_offset, long byte_offset
|
||||
nd.append(data, 0, prefix_len);
|
||||
nd.append(content);
|
||||
if (suffix_len) nd.append(data, end_del, suffix_len);
|
||||
/* Keep a single trailing newline for line-based / whole-file text writes.
|
||||
* Byte-based edits are exact byte operations and must not be mutated with an
|
||||
* injected newline, so the guard is skipped whenever a byte offset or byte
|
||||
* deletion is actually in effect. */
|
||||
bool byte_based = (line_offset < 0 && byte_offset >= 0) ||
|
||||
(del_lines < 0 && del_bytes >= 0);
|
||||
if (!byte_based && !nd.empty() && nd.back() != '\n') nd.push_back('\n');
|
||||
if (!write_file_str(p, nd)) {
|
||||
*err = 1;
|
||||
return sfmt("[tool error: write %s: %s]", p.c_str(), strerror(errno));
|
||||
|
||||
@@ -192,15 +192,27 @@ void mkdir_p(std::string_view dir) {
|
||||
}
|
||||
mkdir(path.c_str(), 0755);
|
||||
}
|
||||
std::string bantam_tmp_dir() {
|
||||
std::string bantam_tmp_dir(std::string_view sess_id) {
|
||||
const char *tmp = std::getenv("TMPDIR");
|
||||
if (!tmp || !*tmp) tmp = "/tmp";
|
||||
std::string p = std::string(tmp) + "/bantam";
|
||||
std::string base(tmp);
|
||||
/* Drop a single trailing slash so we never build a "//bantam" path (which
|
||||
* some platforms treat as a special "super-root"); keep "/" itself intact. */
|
||||
if (base.size() > 1 && base.back() == '/') base.pop_back();
|
||||
std::string p = base;
|
||||
if (p != "/") p += "/";
|
||||
p += "bantam";
|
||||
/* Segregate temporary artifacts per session so different projects/sessions
|
||||
* never share or collide on scratch files. */
|
||||
std::string sid(sess_id);
|
||||
if (sid.empty()) sid = project_id();
|
||||
if (!sid.empty()) { p += "/"; p += sid; }
|
||||
mkdir_p(p);
|
||||
return p;
|
||||
}
|
||||
std::string tool_res_dir() {
|
||||
std::string base = bantam_tmp_dir();
|
||||
|
||||
std::string tool_res_dir(std::string_view sess_id) {
|
||||
std::string base = bantam_tmp_dir(sess_id);
|
||||
std::string p = base + "/toolres";
|
||||
mkdir_p(p);
|
||||
return p;
|
||||
|
||||
Reference in New Issue
Block a user