began work on a msg command
This commit is contained in:
parent
e2bdd05775
commit
a164afe170
@ -69,11 +69,16 @@ void dc_account_set_token(dc_account_t a, char const *token);
|
|||||||
char const *dc_account_token(dc_account_t a);
|
char const *dc_account_token(dc_account_t a);
|
||||||
bool dc_account_has_token(dc_account_t a);
|
bool dc_account_has_token(dc_account_t a);
|
||||||
|
|
||||||
|
/* compare
|
||||||
|
*/
|
||||||
|
bool dc_account_equal(dc_account_t a, dc_account_t b);
|
||||||
|
|
||||||
/* relationships
|
/* relationships
|
||||||
*/
|
*/
|
||||||
void dc_account_set_friends(dc_account_t a, dc_account_t *ptr, size_t len);
|
void dc_account_set_friends(dc_account_t a, dc_account_t *ptr, size_t len);
|
||||||
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i);
|
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i);
|
||||||
size_t dc_account_friends_size(dc_account_t a);
|
size_t dc_account_friends_size(dc_account_t a);
|
||||||
|
dc_account_t dc_account_findfriend(dc_account_t a, char const *fullname);
|
||||||
|
|
||||||
int dc_account_friend_state(dc_account_t a);
|
int dc_account_friend_state(dc_account_t a);
|
||||||
void dc_account_set_friend_state(dc_account_t a, int state);
|
void dc_account_set_friend_state(dc_account_t a, int state);
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
|
#include <dc/account.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A discord channel. Exactly what it says on the tin. A place where one
|
* A discord channel. Exactly what it says on the tin. A place where one
|
||||||
* or more guardsmen can exchange Slaaneshi heresy without their commissars
|
* or more guardsmen can exchange Slaaneshi heresy without their commissars
|
||||||
@ -50,4 +52,7 @@ dc_channel_t dc_channel_from_json(json_t *j);
|
|||||||
dc_channel_type_t dc_channel_type(dc_channel_t c);
|
dc_channel_type_t dc_channel_type(dc_channel_t c);
|
||||||
void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t);
|
void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t);
|
||||||
|
|
||||||
|
size_t dc_channel_recipients(dc_channel_t c);
|
||||||
|
dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -282,6 +282,13 @@ char const *dc_account_fullname(dc_account_t a)
|
|||||||
return a->full;
|
return a->full;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dc_account_equal(dc_account_t a, dc_account_t b)
|
||||||
|
{
|
||||||
|
return_if_true(a == NULL && b == NULL, true);
|
||||||
|
return_if_true(a == NULL || b == NULL, false);
|
||||||
|
return (strcmp(a->full, b->full) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
void dc_account_set_friends(dc_account_t a, dc_account_t *friends, size_t len)
|
void dc_account_set_friends(dc_account_t a, dc_account_t *friends, size_t len)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -293,6 +300,21 @@ void dc_account_set_friends(dc_account_t a, dc_account_t *friends, size_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dc_account_t dc_account_findfriend(dc_account_t a, char const *fullname)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
return_if_true(a == NULL || fullname == NULL, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < a->friends->len; i++) {
|
||||||
|
dc_account_t f = g_ptr_array_index(a->friends, i);
|
||||||
|
if (strcmp(f->full, fullname) == 0) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i)
|
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i)
|
||||||
{
|
{
|
||||||
return_if_true(a == NULL || a->friends == NULL, NULL);
|
return_if_true(a == NULL || a->friends == NULL, NULL);
|
||||||
|
@ -18,7 +18,7 @@ bool dc_api_create_channel(dc_api_t api, dc_account_t login,
|
|||||||
goto_if_true(url == NULL, cleanup);
|
goto_if_true(url == NULL, cleanup);
|
||||||
|
|
||||||
/* build a JSON object that contains one array called "recipients":
|
/* build a JSON object that contains one array called "recipients":
|
||||||
* {"recipients": ["snowflake#1", "snowflake#N"]}
|
* {"recipients": ["snowflake#1", ..., "snowflake#N"]}
|
||||||
*/
|
*/
|
||||||
data = json_object();
|
data = json_object();
|
||||||
array = json_array();
|
array = json_array();
|
||||||
@ -42,6 +42,7 @@ bool dc_api_create_channel(dc_api_t api, dc_account_t login,
|
|||||||
goto_if_true(c == NULL, cleanup);
|
goto_if_true(c == NULL, cleanup);
|
||||||
|
|
||||||
*channel = c;
|
*channel = c;
|
||||||
|
ret = true;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
|
@ -225,3 +225,16 @@ void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t)
|
|||||||
return_if_true(c == NULL,);
|
return_if_true(c == NULL,);
|
||||||
c->type = t;
|
c->type = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t dc_channel_recipients(dc_channel_t c)
|
||||||
|
{
|
||||||
|
return_if_true(c == NULL || c->recipients == NULL, 0);
|
||||||
|
return c->recipients->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i)
|
||||||
|
{
|
||||||
|
return_if_true(c == NULL || c->recipients == NULL, NULL);
|
||||||
|
return_if_true(i >= c->recipients->len, NULL);
|
||||||
|
return g_ptr_array_index(c->recipients, i);
|
||||||
|
}
|
||||||
|
@ -20,6 +20,7 @@ SET(SOURCES
|
|||||||
"src/input.c"
|
"src/input.c"
|
||||||
"src/login.c"
|
"src/login.c"
|
||||||
"src/mainwindow.c"
|
"src/mainwindow.c"
|
||||||
|
"src/msg.c"
|
||||||
"src/ncdc.c"
|
"src/ncdc.c"
|
||||||
"src/textview.c"
|
"src/textview.c"
|
||||||
"src/util.c"
|
"src/util.c"
|
||||||
|
@ -27,5 +27,6 @@ ncdc_commands_t *ncdc_find_cmd(ncdc_commands_t *cmds, wchar_t const *name);
|
|||||||
bool ncdc_cmd_friends(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
bool ncdc_cmd_friends(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
||||||
bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
||||||
bool ncdc_cmd_quit(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
bool ncdc_cmd_quit(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
||||||
|
bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,6 +14,9 @@ ncdc_mainwindow_t ncdc_mainwindow_new(void);
|
|||||||
#define LOG(n, ...) ncdc_mainwindow_log(n, __VA_ARGS__)
|
#define LOG(n, ...) ncdc_mainwindow_log(n, __VA_ARGS__)
|
||||||
void ncdc_mainwindow_log(ncdc_mainwindow_t w, wchar_t const *fmt, ...);
|
void ncdc_mainwindow_log(ncdc_mainwindow_t w, wchar_t const *fmt, ...);
|
||||||
|
|
||||||
|
GPtrArray *ncdc_mainwindow_views(ncdc_mainwindow_t n);
|
||||||
|
void ncdc_mainwindow_switchview(ncdc_mainwindow_t n, int idx);
|
||||||
|
|
||||||
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n);
|
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n);
|
||||||
void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n);
|
void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n);
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ char *w_convert(wchar_t const *w);
|
|||||||
wchar_t* wcsndup(const wchar_t* string, size_t maxlen);
|
wchar_t* wcsndup(const wchar_t* string, size_t maxlen);
|
||||||
size_t w_strlenv(wchar_t **s);
|
size_t w_strlenv(wchar_t **s);
|
||||||
void w_strfreev(wchar_t **s);
|
void w_strfreev(wchar_t **s);
|
||||||
|
wchar_t *w_joinv(wchar_t const **v, size_t len);
|
||||||
wchar_t **w_tokenise(wchar_t const *w);
|
wchar_t **w_tokenise(wchar_t const *w);
|
||||||
wchar_t *w_next_tok(wchar_t const *w);
|
wchar_t *w_next_tok(wchar_t const *w);
|
||||||
wchar_t const *w_next_word(wchar_t const *w, ssize_t len);
|
wchar_t const *w_next_word(wchar_t const *w, ssize_t len);
|
||||||
|
@ -8,6 +8,12 @@ typedef struct ncdc_textview_ *ncdc_textview_t;
|
|||||||
|
|
||||||
ncdc_textview_t ncdc_textview_new(void);
|
ncdc_textview_t ncdc_textview_new(void);
|
||||||
|
|
||||||
|
dc_account_t ncdc_textview_account(ncdc_textview_t v);
|
||||||
|
void ncdc_textview_set_account(ncdc_textview_t v, dc_account_t a);
|
||||||
|
|
||||||
|
dc_channel_t ncdc_textview_channel(ncdc_textview_t v);
|
||||||
|
void ncdc_textview_set_channel(ncdc_textview_t v, dc_channel_t a);
|
||||||
|
|
||||||
void ncdc_textview_append(ncdc_textview_t v, wchar_t const *w);
|
void ncdc_textview_append(ncdc_textview_t v, wchar_t const *w);
|
||||||
wchar_t const *ncdc_textview_nthline(ncdc_textview_t v, size_t i);
|
wchar_t const *ncdc_textview_nthline(ncdc_textview_t v, size_t i);
|
||||||
void ncdc_textview_render(ncdc_textview_t v, WINDOW *win, int lines, int cols);
|
void ncdc_textview_render(ncdc_textview_t v, WINDOW *win, int lines, int cols);
|
||||||
|
@ -4,6 +4,7 @@ ncdc_commands_t cmds[] = {
|
|||||||
{ L"/friend", ncdc_cmd_friends },
|
{ L"/friend", ncdc_cmd_friends },
|
||||||
{ L"/friends", ncdc_cmd_friends },
|
{ L"/friends", ncdc_cmd_friends },
|
||||||
{ L"/login", ncdc_cmd_login },
|
{ L"/login", ncdc_cmd_login },
|
||||||
|
{ L"/msg", ncdc_cmd_msg },
|
||||||
{ L"/quit", ncdc_cmd_quit },
|
{ L"/quit", ncdc_cmd_quit },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
@ -34,6 +34,11 @@ bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dc_api_get_userinfo(api, acc, acc)) {
|
||||||
|
LOG(n, L"login: %ls: failed to get basic user information", av[1]);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
current_account = acc;
|
current_account = acc;
|
||||||
LOG(n, L"login: %ls: authentication successful", av[1]);
|
LOG(n, L"login: %ls: authentication successful", av[1]);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
@ -37,6 +37,9 @@ struct ncdc_mainwindow_
|
|||||||
WINDOW *sep2;
|
WINDOW *sep2;
|
||||||
|
|
||||||
ncdc_input_t in;
|
ncdc_input_t in;
|
||||||
|
|
||||||
|
GPtrArray *views;
|
||||||
|
int curview;
|
||||||
ncdc_textview_t log;
|
ncdc_textview_t log;
|
||||||
|
|
||||||
int focus;
|
int focus;
|
||||||
@ -59,7 +62,11 @@ static void ncdc_mainwindow_free(ncdc_mainwindow_t n)
|
|||||||
delwin(n->sep2);
|
delwin(n->sep2);
|
||||||
|
|
||||||
dc_unref(n->in);
|
dc_unref(n->in);
|
||||||
dc_unref(n->log);
|
|
||||||
|
if (n->views != NULL) {
|
||||||
|
g_ptr_array_unref(n->views);
|
||||||
|
n->views = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(n);
|
free(n);
|
||||||
}
|
}
|
||||||
@ -74,7 +81,11 @@ ncdc_mainwindow_t ncdc_mainwindow_new(void)
|
|||||||
ptr->in = ncdc_input_new();
|
ptr->in = ncdc_input_new();
|
||||||
ncdc_input_set_callback(ptr->in, ncdc_mainwindow_callback, ptr);
|
ncdc_input_set_callback(ptr->in, ncdc_mainwindow_callback, ptr);
|
||||||
|
|
||||||
|
ptr->views = g_ptr_array_new_with_free_func(
|
||||||
|
(GDestroyNotify)dc_unref
|
||||||
|
);
|
||||||
ptr->log = ncdc_textview_new();
|
ptr->log = ncdc_textview_new();
|
||||||
|
g_ptr_array_add(ptr->views, ptr->log);
|
||||||
|
|
||||||
ptr->guilds = newwin(5, 5, 1, 1);
|
ptr->guilds = newwin(5, 5, 1, 1);
|
||||||
ptr->chat = newwin(5, 5, 4, 4);
|
ptr->chat = newwin(5, 5, 4, 4);
|
||||||
@ -192,11 +203,28 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPtrArray *ncdc_mainwindow_views(ncdc_mainwindow_t n)
|
||||||
|
{
|
||||||
|
return n->views;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ncdc_mainwindow_switchview(ncdc_mainwindow_t n, int idx)
|
||||||
|
{
|
||||||
|
return_if_true(n == NULL || n->views == NULL,);
|
||||||
|
return_if_true(idx >= n->views->len,);
|
||||||
|
n->curview = idx;
|
||||||
|
}
|
||||||
|
|
||||||
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n)
|
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n)
|
||||||
{
|
{
|
||||||
|
ncdc_textview_t v = 0;
|
||||||
|
|
||||||
wnoutrefresh(n->guilds);
|
wnoutrefresh(n->guilds);
|
||||||
|
|
||||||
ncdc_textview_render(n->log, n->chat, n->chat_h, n->chat_w);
|
/* render active text view
|
||||||
|
*/
|
||||||
|
v = g_ptr_array_index(n->views, n->curview);
|
||||||
|
ncdc_textview_render(v, n->chat, n->chat_h, n->chat_w);
|
||||||
wnoutrefresh(n->chat);
|
wnoutrefresh(n->chat);
|
||||||
|
|
||||||
ncdc_input_draw(n->in, n->input);
|
ncdc_input_draw(n->in, n->input);
|
||||||
|
79
ncdc/src/msg.c
Normal file
79
ncdc/src/msg.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include <ncdc/cmds.h>
|
||||||
|
#include <ncdc/ncdc.h>
|
||||||
|
#include <ncdc/textview.h>
|
||||||
|
|
||||||
|
bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
||||||
|
{
|
||||||
|
return_if_true(ac <= 1, false);
|
||||||
|
|
||||||
|
char * target = NULL;
|
||||||
|
wchar_t *full_message = NULL;
|
||||||
|
char * message = NULL;
|
||||||
|
bool ret = false;
|
||||||
|
dc_channel_t c = NULL;
|
||||||
|
ncdc_textview_t v = NULL;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
if (current_account == NULL || !dc_account_has_token(current_account)) {
|
||||||
|
LOG(n, L"msg: not logged in");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = w_convert(av[1]);
|
||||||
|
goto_if_true(target == NULL, cleanup);
|
||||||
|
|
||||||
|
/* find out if the target is a friend we can contact
|
||||||
|
*/
|
||||||
|
dc_account_t f = dc_account_findfriend(current_account, target);
|
||||||
|
if (f == NULL) {
|
||||||
|
LOG(n, L"msg: no such friend found: \"%s\"", target);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if we have a channel already, that services that user
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ncdc_mainwindow_views(n)->len; i++) {
|
||||||
|
v = g_ptr_array_index(ncdc_mainwindow_views(n), i);
|
||||||
|
dc_channel_t chan = ncdc_textview_channel(v);
|
||||||
|
|
||||||
|
if (chan != NULL &&
|
||||||
|
dc_channel_type(chan) == CHANNEL_TYPE_DM_TEXT &&
|
||||||
|
dc_account_equal(dc_channel_nthrecipient(chan, 1), f)) {
|
||||||
|
c = dc_ref(chan);
|
||||||
|
ncdc_mainwindow_switchview(n, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == NULL) {
|
||||||
|
/* no? create a new window and switch to it
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!dc_api_create_channel(api, current_account, &f, 1, &c)) {
|
||||||
|
LOG(n, L"msg: failed to create channel");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = ncdc_textview_new();
|
||||||
|
goto_if_true(v == NULL, cleanup);
|
||||||
|
|
||||||
|
ncdc_textview_set_account(v, dc_ref(current_account));
|
||||||
|
ncdc_textview_set_channel(v, dc_ref(c));
|
||||||
|
|
||||||
|
g_ptr_array_add(ncdc_mainwindow_views(n), dc_ref(v));
|
||||||
|
ncdc_mainwindow_switchview(n, ncdc_mainwindow_views(n)->len-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
dc_unref(c);
|
||||||
|
dc_unref(v);
|
||||||
|
|
||||||
|
free(target);
|
||||||
|
free(full_message);
|
||||||
|
free(message);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -4,14 +4,24 @@
|
|||||||
struct ncdc_textview_
|
struct ncdc_textview_
|
||||||
{
|
{
|
||||||
dc_refable_t ref;
|
dc_refable_t ref;
|
||||||
|
|
||||||
GPtrArray *par;
|
GPtrArray *par;
|
||||||
|
|
||||||
|
dc_account_t account;
|
||||||
|
dc_channel_t channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ncdc_textview_free(ncdc_textview_t v)
|
static void ncdc_textview_free(ncdc_textview_t v)
|
||||||
{
|
{
|
||||||
return_if_true(v == NULL,);
|
return_if_true(v == NULL,);
|
||||||
|
|
||||||
|
dc_unref(v->account);
|
||||||
|
dc_unref(v->channel);
|
||||||
|
|
||||||
|
if (v->par != NULL) {
|
||||||
g_ptr_array_unref(v->par);
|
g_ptr_array_unref(v->par);
|
||||||
|
}
|
||||||
|
|
||||||
free(v);
|
free(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +41,32 @@ ncdc_textview_t ncdc_textview_new(void)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dc_account_t ncdc_textview_account(ncdc_textview_t v)
|
||||||
|
{
|
||||||
|
return_if_true(v == NULL, NULL);
|
||||||
|
return v->account;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ncdc_textview_set_account(ncdc_textview_t v, dc_account_t a)
|
||||||
|
{
|
||||||
|
return_if_true(v == NULL || a == NULL,);
|
||||||
|
dc_unref(v->account);
|
||||||
|
v->account = dc_ref(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
dc_channel_t ncdc_textview_channel(ncdc_textview_t v)
|
||||||
|
{
|
||||||
|
return_if_true(v == NULL, NULL);
|
||||||
|
return v->channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ncdc_textview_set_channel(ncdc_textview_t v, dc_channel_t a)
|
||||||
|
{
|
||||||
|
return_if_true(v == NULL || a == NULL,);
|
||||||
|
dc_unref(v->channel);
|
||||||
|
v->channel = dc_ref(a);
|
||||||
|
}
|
||||||
|
|
||||||
void ncdc_textview_append(ncdc_textview_t v, wchar_t const *w)
|
void ncdc_textview_append(ncdc_textview_t v, wchar_t const *w)
|
||||||
{
|
{
|
||||||
return_if_true(v == NULL || w == NULL,);
|
return_if_true(v == NULL || w == NULL,);
|
||||||
|
@ -118,6 +118,26 @@ wchar_t **w_tokenise(wchar_t const *str)
|
|||||||
return (wchar_t**)g_ptr_array_free(array, FALSE);
|
return (wchar_t**)g_ptr_array_free(array, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wchar_t *w_joinv(wchar_t const **v, size_t len)
|
||||||
|
{
|
||||||
|
wchar_t *buf = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
FILE *f = open_wmemstream(&buf, &buflen);
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
return_if_true(f == NULL, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
fwprintf(f, L"%ls", v[i]);
|
||||||
|
if (i < (len-1)) {
|
||||||
|
fputwc(' ', f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
char *w_convert(wchar_t const *w)
|
char *w_convert(wchar_t const *w)
|
||||||
{
|
{
|
||||||
size_t sz = 0;
|
size_t sz = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user