Eliminate str2wcs

This commit is contained in:
ridiculousfish 2012-12-19 13:31:06 -08:00
parent b0a9a5a756
commit 644607c29f
16 changed files with 161 additions and 210 deletions

View file

@ -188,12 +188,11 @@ static void builtin_wperror(const wchar_t *s)
stderr_buffer.append(L": "); stderr_buffer.append(L": ");
} }
char *err = strerror(errno); char *err = strerror(errno);
wchar_t *werr = str2wcs(err); if (err)
if (werr)
{ {
const wcstring werr = str2wcstring(err);
stderr_buffer.append(werr); stderr_buffer.append(werr);
stderr_buffer.push_back(L'\n'); stderr_buffer.push_back(L'\n');
free(werr);
} }
} }
@ -3065,7 +3064,7 @@ static int builtin_source(parser_t &parser, wchar_t ** argv)
return STATUS_BUILTIN_ERROR; return STATUS_BUILTIN_ERROR;
} }
fn = wrealpath(argv[1], 0); fn = wrealpath(argv[1], NULL);
if (!fn) if (!fn)
{ {

View file

@ -81,6 +81,7 @@ parts of fish.
#include "fallback.cpp" #include "fallback.cpp"
static wchar_t *str2wcs_internal(const char *in, const size_t in_len, wchar_t *out);
struct termios shell_modes; struct termios shell_modes;
@ -163,23 +164,31 @@ int fgetws2(wcstring *s, FILE *f)
} }
} }
wchar_t *str2wcs(const char *in) static wchar_t *str2wcs(const char *in)
{ {
wchar_t *out;
size_t len = strlen(in); size_t len = strlen(in);
wchar_t *out = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
out = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
if (!out) if (!out)
{ {
DIE_MEM(); DIE_MEM();
} }
return str2wcs_internal(in, out); return str2wcs_internal(in, strlen(in), out);
}
wcstring str2wcstring(const char *in, size_t len)
{
assert(in != NULL);
std::string tmp_str(in, len);
wchar_t *tmp = str2wcs(tmp_str.c_str());
wcstring result = tmp;
free(tmp);
return result;
} }
wcstring str2wcstring(const char *in) wcstring str2wcstring(const char *in)
{ {
assert(in != NULL);
wchar_t *tmp = str2wcs(in); wchar_t *tmp = str2wcs(in);
wcstring result = tmp; wcstring result = tmp;
free(tmp); free(tmp);
@ -194,24 +203,31 @@ wcstring str2wcstring(const std::string &in)
return result; return result;
} }
wchar_t *str2wcs_internal(const char *in, wchar_t *out) /**
Converts the narrow character string \c in into it's wide
equivalent, stored in \c out. \c out must have enough space to fit
the entire string.
The string may contain embedded nulls.
This function encodes illegal character sequences in a reversible
way using the private use area.
*/
static wchar_t *str2wcs_internal(const char *in, const size_t in_len, wchar_t *out)
{ {
size_t res=0; size_t res=0;
size_t in_pos=0; size_t in_pos=0;
size_t out_pos = 0; size_t out_pos = 0;
mbstate_t state; mbstate_t state;
size_t len;
CHECK(in, 0); CHECK(in, 0);
CHECK(out, 0); CHECK(out, 0);
len = strlen(in);
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
while (in[in_pos]) while (in[in_pos])
{ {
res = mbrtowc(&out[out_pos], &in[in_pos], len-in_pos, &state); res = mbrtowc(&out[out_pos], &in[in_pos], in_len-in_pos, &state);
if (((out[out_pos] >= ENCODE_DIRECT_BASE) && if (((out[out_pos] >= ENCODE_DIRECT_BASE) &&
(out[out_pos] < ENCODE_DIRECT_BASE+256)) || (out[out_pos] < ENCODE_DIRECT_BASE+256)) ||
@ -298,12 +314,12 @@ std::string wcs2string(const wcstring &input)
{ {
std::string result; std::string result;
result.reserve(input.size()); result.reserve(input.size());
mbstate_t state; mbstate_t state;
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
char converted[MB_LEN_MAX + 1]; char converted[MB_LEN_MAX + 1];
for (size_t i=0; i < input.size(); i++) for (size_t i=0; i < input.size(); i++)
{ {
wchar_t wc = input[i]; wchar_t wc = input[i];
@ -330,7 +346,7 @@ std::string wcs2string(const wcstring &input)
} }
} }
} }
return result; return result;
} }

View file

@ -206,35 +206,18 @@ void show_stackframe();
*/ */
int fgetws2(wcstring *s, FILE *f); int fgetws2(wcstring *s, FILE *f);
/**
Returns a newly allocated wide character string equivalent of the
specified multibyte character string
This function encodes illegal character sequences in a reversible
way using the private use area.
*/
wchar_t *str2wcs(const char *in);
/** /**
Returns a newly allocated wide character string equivalent of the Returns a wide character string equivalent of the
specified multibyte character string specified multibyte character string
This function encodes illegal character sequences in a reversible This function encodes illegal character sequences in a reversible
way using the private use area. way using the private use area.
*/ */
wcstring str2wcstring(const char *in); wcstring str2wcstring(const char *in);
wcstring str2wcstring(const char *in, size_t len);
wcstring str2wcstring(const std::string &in); wcstring str2wcstring(const std::string &in);
/**
Converts the narrow character string \c in into it's wide
equivalent, stored in \c out. \c out must have enough space to fit
the entire string.
This function encodes illegal character sequences in a reversible
way using the private use area.
*/
wchar_t *str2wcs_internal(const char *in, wchar_t *out);
/** /**
Returns a newly allocated multibyte character string equivalent of Returns a newly allocated multibyte character string equivalent of
the specified wide character string the specified wide character string

View file

@ -1719,17 +1719,16 @@ bool completer_t::try_complete_user(const wcstring &str)
while ((pw=getpwent()) != 0) while ((pw=getpwent()) != 0)
{ {
double current_time = timef(); double current_time = timef();
wchar_t *pw_name;
if (current_time - start_time > 0.2) if (current_time - start_time > 0.2)
{ {
return 1; return 1;
} }
pw_name = str2wcs(pw->pw_name); if (pw->pw_name)
if (pw_name)
{ {
const wcstring pw_name_str = str2wcstring(pw->pw_name);
const wchar_t *pw_name = pw_name_str.c_str();
if (wcsncmp(user_name, pw_name, name_len)==0) if (wcsncmp(user_name, pw_name, name_len)==0)
{ {
wcstring desc = format_string(COMPLETE_USER_DESC, pw_name); wcstring desc = format_string(COMPLETE_USER_DESC, pw_name);
@ -1751,7 +1750,6 @@ bool completer_t::try_complete_user(const wcstring &str)
COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE); COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE);
res=1; res=1;
} }
free(pw_name);
} }
} }
endpwent(); endpwent();

74
env.cpp
View file

@ -518,9 +518,11 @@ static void env_set_defaults()
if (env_get_string(L"USER").missing()) if (env_get_string(L"USER").missing())
{ {
struct passwd *pw = getpwuid(getuid()); struct passwd *pw = getpwuid(getuid());
wchar_t *unam = str2wcs(pw->pw_name); if (pw->pw_name != NULL)
env_set(L"USER", unam, ENV_GLOBAL); {
free(unam); const wcstring wide_name = str2wcstring(pw->pw_name);
env_set(L"USER", NULL, ENV_GLOBAL);
}
} }
if (env_get_string(L"HOME").missing()) if (env_get_string(L"HOME").missing())
@ -528,9 +530,11 @@ static void env_set_defaults()
const env_var_t unam = env_get_string(L"USER"); const env_var_t unam = env_get_string(L"USER");
char *unam_narrow = wcs2str(unam.c_str()); char *unam_narrow = wcs2str(unam.c_str());
struct passwd *pw = getpwnam(unam_narrow); struct passwd *pw = getpwnam(unam_narrow);
wchar_t *dir = str2wcs(pw->pw_dir); if (pw->pw_dir != NULL)
env_set(L"HOME", dir, ENV_GLOBAL); {
free(dir); const wcstring dir = str2wcstring(pw->pw_dir);
env_set(L"HOME", dir.c_str(), ENV_GLOBAL);
}
free(unam_narrow); free(unam_narrow);
} }
@ -539,9 +543,9 @@ static void env_set_defaults()
} }
// Some variables should not be arrays. This used to be handled by a startup script, but we'd like to get down to 0 forks for startup, so handle it here. // Some variables should not be arrays. This used to be handled by a startup script, but we'd like to get down to 0 forks for startup, so handle it here.
static bool variable_can_be_array(const wchar_t *key) static bool variable_can_be_array(const wcstring &key)
{ {
if (! wcscmp(key, L"DISPLAY")) if (key == L"DISPLAY")
{ {
return false; return false;
} }
@ -554,9 +558,6 @@ static bool variable_can_be_array(const wchar_t *key)
void env_init(const struct config_paths_t *paths /* or NULL */) void env_init(const struct config_paths_t *paths /* or NULL */)
{ {
char **p; char **p;
struct passwd *pw;
wchar_t *uname;
wchar_t *version;
/* /*
env_read_only variables can not be altered directly by the user env_read_only variables can not be altered directly by the user
@ -610,41 +611,24 @@ void env_init(const struct config_paths_t *paths /* or NULL */)
*/ */
for (p=environ?environ:__environ; p && *p; p++) for (p=environ?environ:__environ; p && *p; p++)
{ {
wchar_t *key, *val; const wcstring key_and_val = str2wcstring(*p); //like foo=bar
size_t eql = key_and_val.find(L'=');
key = str2wcs(*p); if (eql == wcstring::npos)
if (!key)
{ {
continue; // no equals found
} env_set(key_and_val, L"", ENV_EXPORT);
val = wcschr(key, L'=');
if (val == 0)
{
env_set(key, L"", ENV_EXPORT);
} }
else else
{ {
*val = L'\0'; wcstring key = key_and_val.substr(0, eql);
val++; wcstring val = key_and_val.substr(eql + 1);
//fwprintf( stderr, L"Set $%ls to %ls\n", key, val );
if (variable_can_be_array(val)) if (variable_can_be_array(val))
{ {
for (size_t i=0; val[i] != L'\0'; i++) std::replace(val.begin(), val.end(), L':', ARRAY_SEP);
{
if (val[i] == L':')
{
val[i] = ARRAY_SEP;
}
}
} }
env_set(key, val, ENV_EXPORT | ENV_GLOBAL); env_set(key, val.c_str(), ENV_EXPORT | ENV_GLOBAL);
} }
free(key);
} }
/* Set the given paths in the environment, if we have any */ /* Set the given paths in the environment, if we have any */
@ -664,21 +648,19 @@ void env_init(const struct config_paths_t *paths /* or NULL */)
/* /*
Set up the USER variable Set up the USER variable
*/ */
pw = getpwuid(getuid()); const struct passwd *pw = getpwuid(getuid());
if (pw) if (pw && pw->pw_name)
{ {
uname = str2wcs(pw->pw_name); const wcstring uname = str2wcstring(pw->pw_name);
env_set(L"USER", uname, ENV_GLOBAL | ENV_EXPORT); env_set(L"USER", uname.c_str(), ENV_GLOBAL | ENV_EXPORT);
free(uname);
} }
/* /*
Set up the version variables Set up the version variables
*/ */
version = str2wcs(PACKAGE_VERSION); wcstring version = str2wcstring(PACKAGE_VERSION);
env_set(L"version", version, ENV_GLOBAL); env_set(L"version", version.c_str(), ENV_GLOBAL);
env_set(L"FISH_VERSION", version, ENV_GLOBAL); env_set(L"FISH_VERSION", version.c_str(), ENV_GLOBAL);
free(version);
const env_var_t fishd_dir_wstr = env_get_string(L"FISHD_SOCKET_DIR"); const env_var_t fishd_dir_wstr = env_get_string(L"FISHD_SOCKET_DIR");
const env_var_t user_dir_wstr = env_get_string(L"USER"); const env_var_t user_dir_wstr = env_get_string(L"USER");

View file

@ -1211,12 +1211,12 @@ void exec(parser_t &parser, job_t *j)
/* Get the strings we'll write before we fork (since they call malloc) */ /* Get the strings we'll write before we fork (since they call malloc) */
const wcstring &out = get_stdout_buffer(), &err = get_stderr_buffer(); const wcstring &out = get_stdout_buffer(), &err = get_stderr_buffer();
/* These strings may contain embedded nulls, so don't treat them as C strings */ /* These strings may contain embedded nulls, so don't treat them as C strings */
const std::string outbuff_str = wcs2string(out); const std::string outbuff_str = wcs2string(out);
const char *outbuff = outbuff_str.data(); const char *outbuff = outbuff_str.data();
size_t outbuff_len = outbuff_str.size(); size_t outbuff_len = outbuff_str.size();
const std::string errbuff_str = wcs2string(err); const std::string errbuff_str = wcs2string(err);
const char *errbuff = errbuff_str.data(); const char *errbuff = errbuff_str.data();
size_t errbuff_len = errbuff_str.size(); size_t errbuff_len = errbuff_str.size();
@ -1466,25 +1466,19 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst)
begin=end=io_buffer->out_buffer_ptr(); begin=end=io_buffer->out_buffer_ptr();
//REWRITEME
if (lst) if (lst)
{ {
while (1) while (1)
{ {
if (*end == 0) if (*end == 0)
{ {
assert(begin != NULL);
if (begin != end) if (begin != end)
{ {
wchar_t *el = str2wcs(begin); const wcstring el = str2wcstring(begin);
if (el) lst->push_back(el);
{
lst->push_back(el);
free(el);
}
else
{
debug(2, L"Got null string on line %d of file %s", __LINE__, __FILE__);
}
} }
io_buffer_destroy(io_buffer); io_buffer_destroy(io_buffer);
@ -1492,19 +1486,9 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst)
} }
else if (*end == sep) else if (*end == sep)
{ {
wchar_t *el;
*end=0; *end=0;
el = str2wcs(begin); const wcstring el = str2wcstring(begin);
if (el) lst->push_back(el);
{
lst->push_back(el);
free(el);
}
else
{
debug(2, L"Got null string on line %d of file %s", __LINE__, __FILE__);
}
begin = end+1; begin = end+1;
} }
end++; end++;

View file

@ -115,7 +115,7 @@ enum
}; };
/** Character for separating two array elements. We use 30, i.e. the ascii record separator since that seems logical. */ /** Character for separating two array elements. We use 30, i.e. the ascii record separator since that seems logical. */
#define ARRAY_SEP 0x1e #define ARRAY_SEP ((wchar_t)(0x1e))
/** String containing the character for separating two array elements */ /** String containing the character for separating two array elements */
#define ARRAY_SEP_STR L"\x1e" #define ARRAY_SEP_STR L"\x1e"

View file

@ -483,11 +483,10 @@ int main(int argc, char **argv)
const io_chain_t empty_ios; const io_chain_t empty_ios;
if (read_init(paths)) if (read_init(paths))
{ {
if (cmd != 0) if (cmd != NULL)
{ {
wchar_t *cmd_wcs = str2wcs(cmd); const wcstring cmd_wcs = str2wcstring(cmd);
res = parser.eval(cmd_wcs, empty_ios, TOP); res = parser.eval(cmd_wcs, empty_ios, TOP);
free(cmd_wcs);
reader_exit(0, 0); reader_exit(0, 0);
} }
else else
@ -502,7 +501,6 @@ int main(int argc, char **argv)
char *file = *(argv+(my_optind++)); char *file = *(argv+(my_optind++));
int i; int i;
int fd; int fd;
wchar_t *rel_filename, *abs_filename;
if ((fd = open(file, O_RDONLY)) == -1) if ((fd = open(file, O_RDONLY)) == -1)
@ -527,17 +525,16 @@ int main(int argc, char **argv)
env_set(L"argv", sb.c_str(), 0); env_set(L"argv", sb.c_str(), 0);
} }
rel_filename = str2wcs(file); const wcstring rel_filename = str2wcstring(file);
abs_filename = wrealpath(rel_filename, 0); const wchar_t *abs_filename = wrealpath(rel_filename, NULL);
if (!abs_filename) if (!abs_filename)
{ {
abs_filename = wcsdup(rel_filename); abs_filename = wcsdup(rel_filename.c_str());
} }
reader_push_current_filename(intern(abs_filename)); reader_push_current_filename(intern(abs_filename));
free(rel_filename); free((void *)abs_filename);
free(abs_filename);
res = reader_read(fd, empty_ios); res = reader_read(fd, empty_ios);

View file

@ -479,7 +479,7 @@ static void completion_print(int cols,
int *width, int *width,
int row_start, int row_start,
int row_stop, int row_stop,
wchar_t *prefix, const wchar_t *prefix,
int is_quoted, int is_quoted,
const std::vector<comp_t *> &lst) const std::vector<comp_t *> &lst)
{ {
@ -529,7 +529,7 @@ static void completion_print(int cols,
*/ */
static int completion_try_print(int cols, static int completion_try_print(int cols,
wchar_t *prefix, const wchar_t *prefix,
int is_quoted, int is_quoted,
std::vector<comp_t *> &lst) std::vector<comp_t *> &lst)
{ {
@ -1086,9 +1086,8 @@ static void init(int mangle_descriptors, int out)
term = getenv("TERM"); term = getenv("TERM");
if (term) if (term)
{ {
wchar_t *wterm = str2wcs(term); wcstring wterm = str2wcstring(term);
output_set_term(wterm); output_set_term(wterm);
free(wterm);
} }
/* Infer term256 support */ /* Infer term256 support */
@ -1129,7 +1128,6 @@ static void read_array(FILE* file, wcstring_list_t &comp)
{ {
std::vector<char> buffer; std::vector<char> buffer;
int c; int c;
wchar_t *wcs;
while (!feof(file)) while (!feof(file))
{ {
@ -1154,16 +1152,10 @@ static void read_array(FILE* file, wcstring_list_t &comp)
if (! buffer.empty()) if (! buffer.empty())
{ {
buffer.push_back(0); buffer.push_back(0);
wcstring wcs = str2wcstring(&buffer.at(0));
wcs = str2wcs(&buffer.at(0)); if (unescape_string(wcs, false))
if (wcs)
{ {
wcstring tmp = wcs; comp.push_back(wcs);
if (unescape_string(tmp, 0))
{
comp.push_back(tmp);
}
free(wcs);
} }
} }
} }
@ -1191,7 +1183,7 @@ int main(int argc, char **argv)
int i; int i;
int is_quoted=0; int is_quoted=0;
wcstring_list_t comp; wcstring_list_t comp;
wchar_t *prefix = 0; wcstring prefix;
int mangle_descriptors = 0; int mangle_descriptors = 0;
int result_fd = -1; int result_fd = -1;
@ -1292,7 +1284,7 @@ int main(int argc, char **argv)
case 'p': case 'p':
{ {
prefix = str2wcs(optarg); prefix = str2wcstring(optarg);
break; break;
} }
@ -1335,12 +1327,6 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
if (!prefix)
{
prefix = wcsdup(L"");
}
} }
else else
{ {
@ -1364,7 +1350,7 @@ int main(int argc, char **argv)
{ {
mangle_descriptors = 1; mangle_descriptors = 1;
prefix = str2wcs(argv[2]); prefix = str2wcstring(argv[2]);
is_quoted = strcmp("1", argv[1])==0; is_quoted = strcmp("1", argv[1])==0;
if (argc > 3) if (argc > 3)
@ -1395,10 +1381,10 @@ int main(int argc, char **argv)
mangle_descriptions(comp); mangle_descriptions(comp);
if (wcscmp(prefix, L"-") == 0) if (prefix == L"-")
join_completions(comp); join_completions(comp);
std::vector<comp_t *> completions = mangle_completions(comp, prefix); std::vector<comp_t *> completions = mangle_completions(comp, prefix.c_str());
/** /**
Try to print the completions. Start by trying to print the Try to print the completions. Start by trying to print the
@ -1408,7 +1394,7 @@ int main(int argc, char **argv)
*/ */
for (i = PAGER_MAX_COLS; i>0; i--) for (i = PAGER_MAX_COLS; i>0; i--)
{ {
switch (completion_try_print(i, prefix, is_quoted, completions)) switch (completion_try_print(i, prefix.c_str(), is_quoted, completions))
{ {
case PAGER_RETRY: case PAGER_RETRY:
@ -1431,8 +1417,6 @@ int main(int argc, char **argv)
} }
} }
free(prefix);
fwprintf(out_file, L"%ls", out_buff.c_str()); fwprintf(out_file, L"%ls", out_buff.c_str());
if (is_ca_mode) if (is_ca_mode)
{ {

View file

@ -249,7 +249,6 @@ static void test_convert()
for (i=0; i<ESCAPE_TEST_COUNT; i++) for (i=0; i<ESCAPE_TEST_COUNT; i++)
{ {
wchar_t *w;
const char *o, *n; const char *o, *n;
char c; char c;
@ -265,22 +264,56 @@ static void test_convert()
sb.push_back(c); sb.push_back(c);
o = &sb.at(0); o = &sb.at(0);
w = str2wcs(o); const wcstring w = str2wcstring(o);
n = wcs2str(w); n = wcs2str(w.c_str());
if (!o || !w || !n) if (!o || !n)
{ {
err(L"Line %d - Conversion cycle of string %s produced null pointer on %s", __LINE__, o, w?L"str2wcs":L"wcs2str"); err(L"Line %d - Conversion cycle of string %s produced null pointer on %s", __LINE__, o, L"wcs2str");
} }
if (strcmp(o, n)) if (strcmp(o, n))
{ {
err(L"Line %d - %d: Conversion cycle of string %s produced different string %s", __LINE__, i, o, n); err(L"Line %d - %d: Conversion cycle of string %s produced different string %s", __LINE__, i, o, n);
} }
free(w);
free((void *)n); free((void *)n);
} }
}
/* Verify correct behavior with embedded nulls */
static void test_convert_nulls(void)
{
return;
say(L"Testing embedded nulls in string conversion");
const wchar_t in[] = L"AAA\0BBB";
const size_t in_len = (sizeof in / sizeof *in) - 1;
const wcstring in_str = wcstring(in, in_len);
std::string out_str = wcs2string(in_str);
if (out_str.size() != in_len)
{
err(L"Embedded nulls mishandled in wcs2string");
}
for (size_t i=0; i < in_len; i++)
{
if (in[i] != out_str.at(i))
{
err(L"Embedded nulls mishandled in wcs2string at index %lu", (unsigned long)i);
}
}
wcstring out_wstr = str2wcstring(out_str);
if (out_wstr.size() != in_len)
{
err(L"Embedded nulls mishandled in str2wcstring");
}
for (size_t i=0; i < in_len; i++)
{
if (in[i] != out_wstr.at(i))
{
err(L"Embedded nulls mishandled in str2wcstring at index %lu", (unsigned long)i);
}
}
} }
@ -1461,6 +1494,7 @@ int main(int argc, char **argv)
test_format(); test_format();
test_escape(); test_escape();
test_convert(); test_convert();
test_convert_nulls();
test_tok(); test_tok();
test_fork(); test_fork();
test_parser(); test_parser();

View file

@ -598,7 +598,8 @@ static wchar_t *fishd_env_get(const wchar_t *key)
free(nkey); free(nkey);
if (nres) if (nres)
{ {
return str2wcs(nres); wcstring tmp = str2wcstring(nres);
return wcsdup(tmp.c_str());
} }
else else
{ {

View file

@ -353,7 +353,7 @@ int input_init()
} }
const env_var_t term = env_get_string(L"TERM"); const env_var_t term = env_get_string(L"TERM");
assert(! term.missing()); assert(! term.missing());
output_set_term(term.c_str()); output_set_term(term);
input_terminfo_init(); input_terminfo_init();

View file

@ -724,9 +724,9 @@ rgb_color_t parse_color(const wcstring &val, bool is_background)
return result; return result;
} }
void output_set_term(const wchar_t *term) void output_set_term(const wcstring &term)
{ {
current_term = term; current_term.assign(term);
} }
const wchar_t *output_get_term() const wchar_t *output_get_term()

View file

@ -154,7 +154,7 @@ void output_set_writer(int (*writer)(char));
int (*output_get_writer())(char) ; int (*output_get_writer())(char) ;
/** Set the terminal name */ /** Set the terminal name */
void output_set_term(const wchar_t *term); void output_set_term(const wcstring &term);
/** Return the terminal name */ /** Return the terminal name */
const wchar_t *output_get_term(); const wchar_t *output_get_term();

View file

@ -1098,19 +1098,17 @@ static void run_pager(const wcstring &prefix, int is_quoted, const std::vector<c
int nil=0; int nil=0;
out->out_buffer_append((char *)&nil, 1); out->out_buffer_append((char *)&nil, 1);
wchar_t *tmp; const char *outbuff = out->out_buffer_ptr();
wchar_t *str = str2wcs(out->out_buffer_ptr()); if (outbuff)
if (str)
{ {
for (tmp = str + wcslen(str)-1; tmp >= str; tmp--) const wcstring str = str2wcstring(outbuff);
size_t idx = str.size();
while (idx--)
{ {
input_unreadch(*tmp); input_unreadch(str.at(idx));
} }
free(str);
} }
io_buffer_destroy(out); io_buffer_destroy(out);
io_buffer_destroy(in); io_buffer_destroy(in);
} }
@ -3466,9 +3464,6 @@ static int read_ni(int fd, const io_chain_t &io)
in_stream = fdopen(des, "r"); in_stream = fdopen(des, "r");
if (in_stream != 0) if (in_stream != 0)
{ {
wchar_t *str;
size_t acc_used;
while (!feof(in_stream)) while (!feof(in_stream))
{ {
char buff[4096]; char buff[4096];
@ -3489,9 +3484,8 @@ static int read_ni(int fd, const io_chain_t &io)
acc.insert(acc.end(), buff, buff + c); acc.insert(acc.end(), buff, buff + c);
} }
acc.push_back(0);
acc_used = acc.size(); const wcstring str = str2wcstring(&acc.at(0), acc.size());
str = str2wcs(&acc.at(0));
acc.clear(); acc.clear();
if (fclose(in_stream)) if (fclose(in_stream))
@ -3502,36 +3496,16 @@ static int read_ni(int fd, const io_chain_t &io)
res = 1; res = 1;
} }
if (str) wcstring sb;
if (! parser.test(str.c_str(), 0, &sb, L"fish"))
{ {
wcstring sb; parser.eval(str, io, TOP);
if (! parser.test(str, 0, &sb, L"fish"))
{
parser.eval(str, io, TOP);
}
else
{
fwprintf(stderr, L"%ls", sb.c_str());
res = 1;
}
free(str);
} }
else else
{ {
if (acc_used > 1) fwprintf(stderr, L"%ls", sb.c_str());
{ res = 1;
debug(1,
_(L"Could not convert input. Read %d bytes."),
acc_used-1);
}
else
{
debug(1,
_(L"Could not read input stream"));
}
res=1;
} }
} }
else else
{ {

View file

@ -296,23 +296,22 @@ void wperror(const wcstring &s)
wchar_t *wrealpath(const wcstring &pathname, wchar_t *resolved_path) wchar_t *wrealpath(const wcstring &pathname, wchar_t *resolved_path)
{ {
cstring tmp = wcs2string(pathname); cstring narrow_path = wcs2string(pathname);
char *narrow_res = realpath(tmp.c_str(), 0); char *narrow_res = realpath(narrow_path.c_str(), NULL);
wchar_t *res;
if (!narrow_res) if (!narrow_res)
return 0; return NULL;
wchar_t *res;
wcstring wide_res = str2wcstring(narrow_res);
if (resolved_path) if (resolved_path)
{ {
wchar_t *tmp2 = str2wcs(narrow_res); wcslcpy(resolved_path, wide_res.c_str(), PATH_MAX);
wcslcpy(resolved_path, tmp2, PATH_MAX);
free(tmp2);
res = resolved_path; res = resolved_path;
} }
else else
{ {
res = str2wcs(narrow_res); res = wcsdup(wide_res.c_str());
} }
free(narrow_res); free(narrow_res);