Skip to content

Commit 644607c

Browse files
Eliminate str2wcs
1 parent b0a9a5a commit 644607c

16 files changed

+161
-210
lines changed

builtin.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,11 @@ static void builtin_wperror(const wchar_t *s)
188188
stderr_buffer.append(L": ");
189189
}
190190
char *err = strerror(errno);
191-
wchar_t *werr = str2wcs(err);
192-
if (werr)
191+
if (err)
193192
{
193+
const wcstring werr = str2wcstring(err);
194194
stderr_buffer.append(werr);
195195
stderr_buffer.push_back(L'\n');
196-
free(werr);
197196
}
198197
}
199198

@@ -3065,7 +3064,7 @@ static int builtin_source(parser_t &parser, wchar_t ** argv)
30653064
return STATUS_BUILTIN_ERROR;
30663065
}
30673066

3068-
fn = wrealpath(argv[1], 0);
3067+
fn = wrealpath(argv[1], NULL);
30693068

30703069
if (!fn)
30713070
{

common.cpp

+31-15
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ parts of fish.
8181
#include "fallback.cpp"
8282

8383

84+
static wchar_t *str2wcs_internal(const char *in, const size_t in_len, wchar_t *out);
8485

8586
struct termios shell_modes;
8687

@@ -163,23 +164,31 @@ int fgetws2(wcstring *s, FILE *f)
163164
}
164165
}
165166

166-
wchar_t *str2wcs(const char *in)
167+
static wchar_t *str2wcs(const char *in)
167168
{
168-
wchar_t *out;
169169
size_t len = strlen(in);
170-
171-
out = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
172-
170+
wchar_t *out = (wchar_t *)malloc(sizeof(wchar_t)*(len+1));
173171
if (!out)
174172
{
175173
DIE_MEM();
176174
}
177175

178-
return str2wcs_internal(in, out);
176+
return str2wcs_internal(in, strlen(in), out);
177+
}
178+
179+
wcstring str2wcstring(const char *in, size_t len)
180+
{
181+
assert(in != NULL);
182+
std::string tmp_str(in, len);
183+
wchar_t *tmp = str2wcs(tmp_str.c_str());
184+
wcstring result = tmp;
185+
free(tmp);
186+
return result;
179187
}
180188

181189
wcstring str2wcstring(const char *in)
182190
{
191+
assert(in != NULL);
183192
wchar_t *tmp = str2wcs(in);
184193
wcstring result = tmp;
185194
free(tmp);
@@ -194,24 +203,31 @@ wcstring str2wcstring(const std::string &in)
194203
return result;
195204
}
196205

197-
wchar_t *str2wcs_internal(const char *in, wchar_t *out)
206+
/**
207+
Converts the narrow character string \c in into it's wide
208+
equivalent, stored in \c out. \c out must have enough space to fit
209+
the entire string.
210+
211+
The string may contain embedded nulls.
212+
213+
This function encodes illegal character sequences in a reversible
214+
way using the private use area.
215+
*/
216+
static wchar_t *str2wcs_internal(const char *in, const size_t in_len, wchar_t *out)
198217
{
199218
size_t res=0;
200219
size_t in_pos=0;
201220
size_t out_pos = 0;
202221
mbstate_t state;
203-
size_t len;
204222

205223
CHECK(in, 0);
206224
CHECK(out, 0);
207225

208-
len = strlen(in);
209-
210226
memset(&state, 0, sizeof(state));
211227

212228
while (in[in_pos])
213229
{
214-
res = mbrtowc(&out[out_pos], &in[in_pos], len-in_pos, &state);
230+
res = mbrtowc(&out[out_pos], &in[in_pos], in_len-in_pos, &state);
215231

216232
if (((out[out_pos] >= ENCODE_DIRECT_BASE) &&
217233
(out[out_pos] < ENCODE_DIRECT_BASE+256)) ||
@@ -298,12 +314,12 @@ std::string wcs2string(const wcstring &input)
298314
{
299315
std::string result;
300316
result.reserve(input.size());
301-
317+
302318
mbstate_t state;
303319
memset(&state, 0, sizeof(state));
304-
320+
305321
char converted[MB_LEN_MAX + 1];
306-
322+
307323
for (size_t i=0; i < input.size(); i++)
308324
{
309325
wchar_t wc = input[i];
@@ -330,7 +346,7 @@ std::string wcs2string(const wcstring &input)
330346
}
331347
}
332348
}
333-
349+
334350
return result;
335351
}
336352

common.h

+2-19
Original file line numberDiff line numberDiff line change
@@ -206,35 +206,18 @@ void show_stackframe();
206206
*/
207207
int fgetws2(wcstring *s, FILE *f);
208208

209-
/**
210-
Returns a newly allocated wide character string equivalent of the
211-
specified multibyte character string
212-
213-
This function encodes illegal character sequences in a reversible
214-
way using the private use area.
215-
*/
216-
wchar_t *str2wcs(const char *in);
217209

218210
/**
219-
Returns a newly allocated wide character string equivalent of the
211+
Returns a wide character string equivalent of the
220212
specified multibyte character string
221213
222214
This function encodes illegal character sequences in a reversible
223215
way using the private use area.
224216
*/
225217
wcstring str2wcstring(const char *in);
218+
wcstring str2wcstring(const char *in, size_t len);
226219
wcstring str2wcstring(const std::string &in);
227220

228-
/**
229-
Converts the narrow character string \c in into it's wide
230-
equivalent, stored in \c out. \c out must have enough space to fit
231-
the entire string.
232-
233-
This function encodes illegal character sequences in a reversible
234-
way using the private use area.
235-
*/
236-
wchar_t *str2wcs_internal(const char *in, wchar_t *out);
237-
238221
/**
239222
Returns a newly allocated multibyte character string equivalent of
240223
the specified wide character string

complete.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -1719,17 +1719,16 @@ bool completer_t::try_complete_user(const wcstring &str)
17191719
while ((pw=getpwent()) != 0)
17201720
{
17211721
double current_time = timef();
1722-
wchar_t *pw_name;
17231722

17241723
if (current_time - start_time > 0.2)
17251724
{
17261725
return 1;
17271726
}
17281727

1729-
pw_name = str2wcs(pw->pw_name);
1730-
1731-
if (pw_name)
1728+
if (pw->pw_name)
17321729
{
1730+
const wcstring pw_name_str = str2wcstring(pw->pw_name);
1731+
const wchar_t *pw_name = pw_name_str.c_str();
17331732
if (wcsncmp(user_name, pw_name, name_len)==0)
17341733
{
17351734
wcstring desc = format_string(COMPLETE_USER_DESC, pw_name);
@@ -1751,7 +1750,6 @@ bool completer_t::try_complete_user(const wcstring &str)
17511750
COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE | COMPLETE_NO_SPACE);
17521751
res=1;
17531752
}
1754-
free(pw_name);
17551753
}
17561754
}
17571755
endpwent();

env.cpp

+28-46
Original file line numberDiff line numberDiff line change
@@ -518,19 +518,23 @@ static void env_set_defaults()
518518
if (env_get_string(L"USER").missing())
519519
{
520520
struct passwd *pw = getpwuid(getuid());
521-
wchar_t *unam = str2wcs(pw->pw_name);
522-
env_set(L"USER", unam, ENV_GLOBAL);
523-
free(unam);
521+
if (pw->pw_name != NULL)
522+
{
523+
const wcstring wide_name = str2wcstring(pw->pw_name);
524+
env_set(L"USER", NULL, ENV_GLOBAL);
525+
}
524526
}
525527

526528
if (env_get_string(L"HOME").missing())
527529
{
528530
const env_var_t unam = env_get_string(L"USER");
529531
char *unam_narrow = wcs2str(unam.c_str());
530532
struct passwd *pw = getpwnam(unam_narrow);
531-
wchar_t *dir = str2wcs(pw->pw_dir);
532-
env_set(L"HOME", dir, ENV_GLOBAL);
533-
free(dir);
533+
if (pw->pw_dir != NULL)
534+
{
535+
const wcstring dir = str2wcstring(pw->pw_dir);
536+
env_set(L"HOME", dir.c_str(), ENV_GLOBAL);
537+
}
534538
free(unam_narrow);
535539
}
536540

@@ -539,9 +543,9 @@ static void env_set_defaults()
539543
}
540544

541545
// 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.
542-
static bool variable_can_be_array(const wchar_t *key)
546+
static bool variable_can_be_array(const wcstring &key)
543547
{
544-
if (! wcscmp(key, L"DISPLAY"))
548+
if (key == L"DISPLAY")
545549
{
546550
return false;
547551
}
@@ -554,9 +558,6 @@ static bool variable_can_be_array(const wchar_t *key)
554558
void env_init(const struct config_paths_t *paths /* or NULL */)
555559
{
556560
char **p;
557-
struct passwd *pw;
558-
wchar_t *uname;
559-
wchar_t *version;
560561

561562
/*
562563
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 */)
610611
*/
611612
for (p=environ?environ:__environ; p && *p; p++)
612613
{
613-
wchar_t *key, *val;
614-
615-
key = str2wcs(*p);
616-
617-
if (!key)
614+
const wcstring key_and_val = str2wcstring(*p); //like foo=bar
615+
size_t eql = key_and_val.find(L'=');
616+
if (eql == wcstring::npos)
618617
{
619-
continue;
620-
}
621-
622-
val = wcschr(key, L'=');
623-
624-
if (val == 0)
625-
{
626-
env_set(key, L"", ENV_EXPORT);
618+
// no equals found
619+
env_set(key_and_val, L"", ENV_EXPORT);
627620
}
628621
else
629622
{
630-
*val = L'\0';
631-
val++;
632-
633-
//fwprintf( stderr, L"Set $%ls to %ls\n", key, val );
623+
wcstring key = key_and_val.substr(0, eql);
624+
wcstring val = key_and_val.substr(eql + 1);
634625
if (variable_can_be_array(val))
635626
{
636-
for (size_t i=0; val[i] != L'\0'; i++)
637-
{
638-
if (val[i] == L':')
639-
{
640-
val[i] = ARRAY_SEP;
641-
}
642-
}
627+
std::replace(val.begin(), val.end(), L':', ARRAY_SEP);
643628
}
644629

645-
env_set(key, val, ENV_EXPORT | ENV_GLOBAL);
630+
env_set(key, val.c_str(), ENV_EXPORT | ENV_GLOBAL);
646631
}
647-
free(key);
648632
}
649633

650634
/* 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 */)
664648
/*
665649
Set up the USER variable
666650
*/
667-
pw = getpwuid(getuid());
668-
if (pw)
651+
const struct passwd *pw = getpwuid(getuid());
652+
if (pw && pw->pw_name)
669653
{
670-
uname = str2wcs(pw->pw_name);
671-
env_set(L"USER", uname, ENV_GLOBAL | ENV_EXPORT);
672-
free(uname);
654+
const wcstring uname = str2wcstring(pw->pw_name);
655+
env_set(L"USER", uname.c_str(), ENV_GLOBAL | ENV_EXPORT);
673656
}
674657

675658
/*
676659
Set up the version variables
677660
*/
678-
version = str2wcs(PACKAGE_VERSION);
679-
env_set(L"version", version, ENV_GLOBAL);
680-
env_set(L"FISH_VERSION", version, ENV_GLOBAL);
681-
free(version);
661+
wcstring version = str2wcstring(PACKAGE_VERSION);
662+
env_set(L"version", version.c_str(), ENV_GLOBAL);
663+
env_set(L"FISH_VERSION", version.c_str(), ENV_GLOBAL);
682664

683665
const env_var_t fishd_dir_wstr = env_get_string(L"FISHD_SOCKET_DIR");
684666
const env_var_t user_dir_wstr = env_get_string(L"USER");

exec.cpp

+9-25
Original file line numberDiff line numberDiff line change
@@ -1211,12 +1211,12 @@ void exec(parser_t &parser, job_t *j)
12111211

12121212
/* Get the strings we'll write before we fork (since they call malloc) */
12131213
const wcstring &out = get_stdout_buffer(), &err = get_stderr_buffer();
1214-
1214+
12151215
/* These strings may contain embedded nulls, so don't treat them as C strings */
12161216
const std::string outbuff_str = wcs2string(out);
12171217
const char *outbuff = outbuff_str.data();
12181218
size_t outbuff_len = outbuff_str.size();
1219-
1219+
12201220
const std::string errbuff_str = wcs2string(err);
12211221
const char *errbuff = errbuff_str.data();
12221222
size_t errbuff_len = errbuff_str.size();
@@ -1466,45 +1466,29 @@ static int exec_subshell_internal(const wcstring &cmd, wcstring_list_t *lst)
14661466

14671467
begin=end=io_buffer->out_buffer_ptr();
14681468

1469+
//REWRITEME
1470+
14691471
if (lst)
14701472
{
14711473
while (1)
14721474
{
14731475
if (*end == 0)
14741476
{
1477+
assert(begin != NULL);
14751478
if (begin != end)
14761479
{
1477-
wchar_t *el = str2wcs(begin);
1478-
if (el)
1479-
{
1480-
lst->push_back(el);
1481-
1482-
free(el);
1483-
}
1484-
else
1485-
{
1486-
debug(2, L"Got null string on line %d of file %s", __LINE__, __FILE__);
1487-
}
1480+
const wcstring el = str2wcstring(begin);
1481+
lst->push_back(el);
14881482
}
14891483
io_buffer_destroy(io_buffer);
14901484

14911485
return status;
14921486
}
14931487
else if (*end == sep)
14941488
{
1495-
wchar_t *el;
14961489
*end=0;
1497-
el = str2wcs(begin);
1498-
if (el)
1499-
{
1500-
lst->push_back(el);
1501-
1502-
free(el);
1503-
}
1504-
else
1505-
{
1506-
debug(2, L"Got null string on line %d of file %s", __LINE__, __FILE__);
1507-
}
1490+
const wcstring el = str2wcstring(begin);
1491+
lst->push_back(el);
15081492
begin = end+1;
15091493
}
15101494
end++;

0 commit comments

Comments
 (0)