mirror of
https://github.com/0intro/wmii
synced 2024-11-23 06:11:21 +03:00
Add locale charset crud.
This commit is contained in:
parent
154f750e0a
commit
20f317dd6a
3
LICENSE
3
LICENSE
@ -1,6 +1,7 @@
|
||||
|
||||
Copyright © 2006-2009 Kris Maglione <maglione.k@gmail.com>
|
||||
Copyright © 2006-2010 Kris Maglione <maglione.k@gmail.com>
|
||||
Copyright © 2003-2006 Anselm R Garbe <anselm@garbe.us>
|
||||
Portions Copyright © 2002 by Lucent Technologies.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
@ -41,8 +41,6 @@ main(int argc, char *argv[]) {
|
||||
usage();
|
||||
}ARGEND;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
initdisplay();
|
||||
|
||||
s = ARGF();
|
||||
|
@ -186,8 +186,10 @@ main(int argc, char *argv[]) {
|
||||
int i;
|
||||
long ndump;
|
||||
|
||||
quotefmtinstall();
|
||||
setlocale(LC_CTYPE, "");
|
||||
fmtinstall('r', errfmt);
|
||||
quotefmtinstall();
|
||||
|
||||
screen_hint = PointerScreen;
|
||||
|
||||
find = strstr;
|
||||
@ -227,7 +229,7 @@ main(int argc, char *argv[]) {
|
||||
cmdsep = EARGF(usage());
|
||||
break;
|
||||
case 'v':
|
||||
print("%s", version);
|
||||
lprint(1, "%s", version);
|
||||
return 0;
|
||||
default:
|
||||
usage();
|
||||
@ -236,8 +238,6 @@ main(int argc, char *argv[]) {
|
||||
if(argc)
|
||||
usage();
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
initdisplay();
|
||||
|
||||
xext_init();
|
||||
|
@ -90,9 +90,9 @@ next:
|
||||
if(input.filter_start == 0 && input.pos == input.end)
|
||||
menu_cmd(CMPL_FIRST, 0);
|
||||
if(!motion && matchidx && !strcmp(input.string, matchidx->string))
|
||||
print("%s", matchidx->retstring);
|
||||
lprint(1, "%s", matchidx->retstring);
|
||||
else
|
||||
print("%s", input.string);
|
||||
lprint(1, "%s", input.string);
|
||||
break;
|
||||
case REJECT:
|
||||
srv.running = false;
|
||||
|
@ -130,6 +130,7 @@ main(int argc, char *argv[]) {
|
||||
ulong win;
|
||||
char *s;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
fmtinstall('E', fmtevent);
|
||||
|
||||
ARGBEGIN{
|
||||
@ -140,14 +141,12 @@ main(int argc, char *argv[]) {
|
||||
direction = DVertical;
|
||||
break;
|
||||
case 'v':
|
||||
print("%s", version);
|
||||
lprint(1, "%s", version);
|
||||
return 0;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
initdisplay();
|
||||
|
||||
testwin = createwindow(&scr.root, Rect(0, 0, 1, 1), 0,
|
||||
|
@ -116,7 +116,6 @@ main(int argc, char *argv[]) {
|
||||
program_args = argv;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
fmtinstall('r', errfmt);
|
||||
fmtinstall('E', fmtevent);
|
||||
|
||||
@ -163,7 +162,7 @@ main(int argc, char *argv[]) {
|
||||
debug++;
|
||||
break;
|
||||
case 'v':
|
||||
print("%s", version);
|
||||
lprint(1, "%s", version);
|
||||
return 0;
|
||||
default:
|
||||
usage();
|
||||
@ -184,7 +183,7 @@ main(int argc, char *argv[]) {
|
||||
if(tray.selection == nil)
|
||||
fatal("Another system tray is already running.");
|
||||
if(tray.selection->oldowner)
|
||||
print("Replacing currently running system tray.\n");
|
||||
lprint(1, "Replacing currently running system tray.\n");
|
||||
|
||||
xext_init();
|
||||
tray_init();
|
||||
|
@ -630,7 +630,6 @@ client_kill(Client *c, bool nice) {
|
||||
ulong *pid;
|
||||
long n;
|
||||
|
||||
c->dead = 1;
|
||||
if(!nice) {
|
||||
getprop_textlist(&c->w, "WM_CLIENT_MACHINE", &host);
|
||||
n = getprop_ulong(&c->w, Net("WM_PID"), "CARDINAL", 0, &pid, 1);
|
||||
@ -642,6 +641,7 @@ client_kill(Client *c, bool nice) {
|
||||
XKillClient(display, c->w.xid);
|
||||
}
|
||||
else if(c->proto & ProtoDelete) {
|
||||
c->dead = 1;
|
||||
client_message(c, "WM_DELETE_WINDOW", 0);
|
||||
ewmh_checkresponsive(c);
|
||||
}
|
||||
|
@ -335,12 +335,12 @@ main(int argc, char *argv[]) {
|
||||
char *wmiirc, *s;
|
||||
int i;
|
||||
|
||||
quotefmtinstall();
|
||||
setlocale(LC_CTYPE, "");
|
||||
fmtinstall('r', errfmt);
|
||||
fmtinstall('a', afmt);
|
||||
fmtinstall('C', Cfmt);
|
||||
extern int fmtevent(Fmt*);
|
||||
fmtinstall('E', fmtevent);
|
||||
quotefmtinstall();
|
||||
|
||||
wmiirc = "wmiirc";
|
||||
|
||||
@ -353,7 +353,7 @@ extern int fmtevent(Fmt*);
|
||||
wmiirc = EARGF(usage());
|
||||
break;
|
||||
case 'v':
|
||||
print("%s", version);
|
||||
lprint(1, "%s", version);
|
||||
exit(0);
|
||||
case 'D':
|
||||
s = EARGF(usage());
|
||||
@ -368,7 +368,6 @@ extern int fmtevent(Fmt*);
|
||||
if(argc)
|
||||
usage();
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
starting = true;
|
||||
|
||||
initdisplay();
|
||||
|
@ -116,7 +116,7 @@ main(int argc, char **argv)
|
||||
|
||||
ARGBEGIN{
|
||||
case 'v':
|
||||
print("%s\n", version);
|
||||
lprint(1, "%s\n", version);
|
||||
return 0;
|
||||
case 'a':
|
||||
address = EARGF(usage());
|
||||
@ -172,8 +172,8 @@ main(int argc, char **argv)
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s -v\n", argv0);
|
||||
fprintf(stderr, " %s [-a <address>] [-i <arg>] menitem[:command] ...\n", argv0);
|
||||
lprint(2, "usage: %s -v\n", argv0);
|
||||
lprint(2, " %s [-a <address>] [-i <arg>] menitem[:command] ...\n", argv0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -210,8 +210,7 @@ run_menu(void)
|
||||
XNextEvent(display, &ev);
|
||||
switch (ev.type) {
|
||||
default:
|
||||
fprintf(stderr, "%s: unknown ev.type %d\n",
|
||||
argv0, ev.type);
|
||||
lprint(2, "%s: unknown ev.type %d\n", argv0, ev.type);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
i = ev.xbutton.y / high;
|
||||
@ -220,7 +219,7 @@ run_menu(void)
|
||||
else if(i < 0 || i >= numitems)
|
||||
return;
|
||||
|
||||
printf("%s\n", commands[i]);
|
||||
lprint(1, "%s\n", commands[i]);
|
||||
return;
|
||||
case ButtonPress:
|
||||
case MotionNotify:
|
||||
|
157
cmd/wmiir.c
157
cmd/wmiir.c
@ -4,23 +4,28 @@
|
||||
#define IXP_NO_P9_
|
||||
#define IXP_P9_STRUCTS
|
||||
#include <dirent.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/signal.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <ixp.h>
|
||||
#include <stuff/util.h>
|
||||
#include <bio.h>
|
||||
#include <fmt.h>
|
||||
|
||||
static IxpClient *client;
|
||||
static Biobuf *outbuf;
|
||||
static IxpClient* client;
|
||||
static Biobuf* outbuf;
|
||||
static bool binary;
|
||||
|
||||
static void
|
||||
usage(void) {
|
||||
fprint(1,
|
||||
"usage: %s [-a <address>] {create | ls [-dlp] | read | remove | write} <file>\n"
|
||||
lprint(1,
|
||||
"usage: %s [-a <address>] [-b] {create | ls [-dlp] | read | remove | write} <file>\n"
|
||||
" %s [-a <address>] xwrite <file> <data>\n"
|
||||
" %s -v\n", argv0, argv0, argv0);
|
||||
exit(1);
|
||||
@ -31,21 +36,110 @@ errfmt(Fmt *f) {
|
||||
return fmtstrcpy(f, ixp_errbuf());
|
||||
}
|
||||
|
||||
static bool
|
||||
flush(IxpCFid *fid, char *in, int len, bool binary) {
|
||||
static mbstate_t state;
|
||||
static char buf[IXP_MAX_MSG];
|
||||
static char *out = buf, *outend = buf + sizeof buf;
|
||||
char *inend;
|
||||
wchar_t w;
|
||||
Rune r;
|
||||
int res;
|
||||
|
||||
if(binary)
|
||||
return ixp_write(fid, in, len) == len;
|
||||
|
||||
inend = in + len;
|
||||
do {
|
||||
if(in == nil || out + UTFmax > outend) {
|
||||
if(ixp_write(fid, buf, out - buf) != out - buf)
|
||||
return false;
|
||||
out = buf;
|
||||
}
|
||||
if(in == nil) {
|
||||
state = (mbstate_t){0};
|
||||
return true;
|
||||
}
|
||||
|
||||
switch((res = mbrtowc(&w, in, inend - in, &state))) {
|
||||
case -1:
|
||||
return false;
|
||||
case 0:
|
||||
case -2:
|
||||
return true;
|
||||
default:
|
||||
in += res;
|
||||
r = w < Runemax ? w : Runesync;
|
||||
out += runetochar(out, &r);
|
||||
}
|
||||
} while(in < inend);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
unflush(int fd, char *in, int len, bool binary) {
|
||||
static mbstate_t state;
|
||||
static char buf[IXP_MAX_MSG], extra[UTFmax];
|
||||
static char *out = buf, *outend = buf + sizeof buf;
|
||||
static int nextra;
|
||||
char *start;
|
||||
Rune r;
|
||||
int res, n;
|
||||
|
||||
if(binary)
|
||||
return write(fd, in, len) == len;
|
||||
|
||||
if(in) {
|
||||
if((n = nextra)) {
|
||||
nextra = 0;
|
||||
while(len > 0 && n < UTFmax && !fullrune(extra, n)) {
|
||||
extra[n++] = *in++;
|
||||
len--;
|
||||
}
|
||||
unflush(fd, extra, n, binary);
|
||||
}
|
||||
n = utfnlen(in, len);
|
||||
}
|
||||
|
||||
start = in;
|
||||
do {
|
||||
if(in == nil || out + MB_LEN_MAX > outend) {
|
||||
if(write(fd, buf, out - buf) != out - buf)
|
||||
return false;
|
||||
out = buf;
|
||||
}
|
||||
if(in == nil || n == 0) {
|
||||
state = (mbstate_t){0};
|
||||
return true;
|
||||
}
|
||||
|
||||
in += chartorune(&r, in);
|
||||
n--;
|
||||
res = wcrtomb(out, r, &state);
|
||||
if(res == -1)
|
||||
*out++ = '?';
|
||||
else
|
||||
out += res;
|
||||
} while(n > 0);
|
||||
if(in < start + len) {
|
||||
nextra = min(sizeof extra, len - (in - start));
|
||||
memcpy(extra, in, nextra);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Utility Functions */
|
||||
static void
|
||||
write_data(IxpCFid *fid, char *name) {
|
||||
void *buf;
|
||||
write_data(IxpCFid *fid, char *name, bool binary) {
|
||||
char buf[IXP_MAX_MSG];
|
||||
int len;
|
||||
|
||||
buf = emalloc(fid->iounit);;
|
||||
for(;;) {
|
||||
len = read(0, buf, fid->iounit);
|
||||
if(len <= 0)
|
||||
break;
|
||||
if(ixp_write(fid, buf, len) != len)
|
||||
while((len = read(0, buf, fid->iounit)) > 0)
|
||||
if(!flush(fid, buf, len, binary))
|
||||
fatal("cannot write file %q\n", name);
|
||||
}
|
||||
free(buf);
|
||||
|
||||
if(!binary)
|
||||
flush(fid, nil, 0, binary);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -101,14 +195,14 @@ print_stat(Stat *s, int lflag, char *file, int pflag) {
|
||||
file = "";
|
||||
|
||||
if(lflag)
|
||||
Bprint(outbuf, "%s %s %s %5llud %s %s%s%s\n",
|
||||
modestr(s->mode), s->uid, s->gid, s->length,
|
||||
timestr(s->mtime), file, slash, s->name);
|
||||
Blprint(outbuf, "%s %s %s %5llud %s %s%s%s\n",
|
||||
modestr(s->mode), s->uid, s->gid, s->length,
|
||||
timestr(s->mtime), file, slash, s->name);
|
||||
else {
|
||||
if((s->mode&P9_DMDIR) && strcmp(s->name, "/"))
|
||||
Bprint(outbuf, "%s%s%s/\n", file, slash, s->name);
|
||||
Blprint(outbuf, "%s%s%s/\n", file, slash, s->name);
|
||||
else
|
||||
Bprint(outbuf, "%s%s%s\n", file, slash, s->name);
|
||||
Blprint(outbuf, "%s%s%s\n", file, slash, s->name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,7 +222,7 @@ xwrite(int argc, char *argv[]) {
|
||||
if(fid == nil)
|
||||
fatal("Can't open file '%s': %r\n", file);
|
||||
|
||||
write_data(fid, file);
|
||||
write_data(fid, file, binary);
|
||||
ixp_close(fid);
|
||||
return 0;
|
||||
}
|
||||
@ -160,7 +254,7 @@ xawrite(int argc, char *argv[]) {
|
||||
strcat(buf, " ");
|
||||
}
|
||||
|
||||
if(ixp_write(fid, buf, nbuf) == -1)
|
||||
if(!(flush(fid, buf, nbuf, binary) && (binary || flush(fid, 0, 0, binary))))
|
||||
fatal("cannot write file '%s': %r\n", file);
|
||||
ixp_close(fid);
|
||||
free(buf);
|
||||
@ -183,7 +277,7 @@ xcreate(int argc, char *argv[]) {
|
||||
fatal("Can't create file '%s': %r\n", file);
|
||||
|
||||
if((fid->qid.type&P9_DMDIR) == 0)
|
||||
write_data(fid, file);
|
||||
write_data(fid, file, binary);
|
||||
ixp_close(fid);
|
||||
return 0;
|
||||
}
|
||||
@ -200,7 +294,7 @@ xremove(int argc, char *argv[]) {
|
||||
file = EARGF(usage());
|
||||
do {
|
||||
if(!ixp_remove(client, file))
|
||||
fprint(2, "%s: Can't remove file '%s': %r\n", argv0, file);
|
||||
lprint(2, "%s: Can't remove file '%s': %r\n", argv0, file);
|
||||
}while((file = ARGF()));
|
||||
return 0;
|
||||
}
|
||||
@ -226,11 +320,13 @@ xread(int argc, char *argv[]) {
|
||||
|
||||
buf = emalloc(fid->iounit);
|
||||
while((count = ixp_read(fid, buf, fid->iounit)) > 0)
|
||||
write(1, buf, count);
|
||||
unflush(1, buf, count, binary);
|
||||
if(!binary)
|
||||
unflush(1, 0, 0, binary);
|
||||
ixp_close(fid);
|
||||
|
||||
if(count == -1)
|
||||
fprint(2, "%s: cannot read file '%s': %r\n", argv0, file);
|
||||
lprint(2, "%s: cannot read file '%s': %r\n", argv0, file);
|
||||
} while((file = ARGF()));
|
||||
|
||||
return 0;
|
||||
@ -327,7 +423,7 @@ xnamespace(int argc, char *argv[]) {
|
||||
path = ixp_namespace();
|
||||
if(path == nil)
|
||||
fatal("can't find namespace: %r\n");
|
||||
Bprint(outbuf, "%s\n", path);
|
||||
Blprint(outbuf, "%s\n", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -345,6 +441,7 @@ xproglist(int argc, char *argv[]) {
|
||||
}ARGEND;
|
||||
|
||||
while((dir = ARGF()))
|
||||
/* Don't use Blprint. wimenu expects UTF-8. */
|
||||
if((d = opendir(dir))) {
|
||||
while((de = readdir(d)))
|
||||
if(access(de->d_name, X_OK))
|
||||
@ -418,14 +515,20 @@ main(int argc, char *argv[]) {
|
||||
exectab *tab;
|
||||
int ret;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
binary = utf8locale();
|
||||
|
||||
quotefmtinstall();
|
||||
fmtinstall('r', errfmt);
|
||||
|
||||
address = getenv("WMII_ADDRESS");
|
||||
|
||||
ARGBEGIN{
|
||||
case 'b':
|
||||
binary = true;
|
||||
break;
|
||||
case 'v':
|
||||
print("%s-" VERSION ", " COPYRIGHT "\n", argv0);
|
||||
lprint(1, "%s-" VERSION ", " COPYRIGHT "\n", argv0);
|
||||
exit(0);
|
||||
case 'a':
|
||||
address = EARGF(usage());
|
||||
|
@ -3,7 +3,9 @@
|
||||
*/
|
||||
|
||||
#include <stuff/geom.h>
|
||||
#include <langinfo.h>
|
||||
#include <stdarg.h>
|
||||
#include <bio.h>
|
||||
#include <fmt.h>
|
||||
#include <regexp9.h>
|
||||
|
||||
@ -26,6 +28,12 @@ enum {
|
||||
GInvert = 1<<0,
|
||||
};
|
||||
|
||||
enum {
|
||||
Runemax = (1 << (sizeof(Rune) * 8)) - 1,
|
||||
};
|
||||
|
||||
#define utf8locale() (!strcmp(nl_langinfo(CODESET), "UTF-8"))
|
||||
|
||||
#ifdef VARARGCK
|
||||
# pragma varargck argpos _die 3
|
||||
# pragma varargck argpos fatal 1
|
||||
@ -35,7 +43,8 @@ enum {
|
||||
#define strlcat stuff_strlcat
|
||||
#define strcasestr stuff_strcasestr
|
||||
|
||||
|
||||
int Blprint(Biobuf*, const char*, ...);
|
||||
int Bvlprint(Biobuf*, const char*, va_list);
|
||||
void _die(char*, int, char*, ...);
|
||||
void backtrace(char*);
|
||||
void closeexec(int);
|
||||
@ -48,12 +57,16 @@ char* estrdup(const char*);
|
||||
char* estrndup(const char*, uint);
|
||||
void fatal(const char*, ...);
|
||||
void* freelater(void*);
|
||||
int getbase(const char**, long*);
|
||||
bool getint(const char*, int*);
|
||||
bool getlong(const char*, long*);
|
||||
bool getulong(const char*, ulong*);
|
||||
int getbase(const char**, long*);
|
||||
bool getint(const char*, int*);
|
||||
bool getlong(const char*, long*);
|
||||
bool getulong(const char*, ulong*);
|
||||
void grep(char**, Reprog*, int);
|
||||
char* join(char**, char*, Fmt*);
|
||||
int localefmt(Fmt*);
|
||||
void localefmtinstall(void);
|
||||
int localelen(char*, char*);
|
||||
int lprint(int, const char*, ...);
|
||||
int max(int, int);
|
||||
int min(int, int);
|
||||
uvlong nsec(void);
|
||||
@ -64,7 +77,7 @@ int spawn3(int[3], const char*, char*[]);
|
||||
int spawn3l(int[3], const char*, ...);
|
||||
uint stokenize(char**, uint, char*, char*);
|
||||
char* strcasestr(const char*, const char*);
|
||||
char* strend(char*, int);
|
||||
char* strend(char*, int);
|
||||
uint strlcat(char*, const char*, uint);
|
||||
int strlcatprint(char*, int, const char*, ...);
|
||||
char* sxprint(const char*, ...);
|
||||
@ -73,6 +86,7 @@ void trim(char *str, const char *chars);
|
||||
void uniq(char**);
|
||||
int unquote(char*, char*[], int);
|
||||
int utflcpy(char*, const char*, int);
|
||||
int vlprint(int, const char*, va_list);
|
||||
char* vsxprint(const char*, va_list);
|
||||
extern char buffer[8092];
|
||||
extern char* _buffer;
|
||||
|
@ -34,6 +34,12 @@ OBJ=\
|
||||
event/selectionrequest \
|
||||
event/unmapnotify \
|
||||
event/xtime \
|
||||
fmt/blprint \
|
||||
fmt/bvlprint \
|
||||
fmt/localefmt \
|
||||
fmt/localelen \
|
||||
fmt/lprint \
|
||||
fmt/vlprint \
|
||||
geom/get_sticky \
|
||||
geom/quadrant \
|
||||
geom/rect_contains_p \
|
||||
|
19
lib/libstuff/fmt/blprint.c
Normal file
19
lib/libstuff/fmt/blprint.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
|
||||
* Copyright ©2002 by Lucent Technologies.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "fmtdef.h"
|
||||
#include <bio.h>
|
||||
|
||||
int
|
||||
Blprint(Biobuf *bp, const char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
int n;
|
||||
|
||||
va_start(arg, fmt);
|
||||
n = Bvlprint(bp, fmt, arg);
|
||||
va_end(arg);
|
||||
return n;
|
||||
}
|
||||
|
58
lib/libstuff/fmt/bvlprint.c
Normal file
58
lib/libstuff/fmt/bvlprint.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
|
||||
* Copyright ©2002 by Lucent Technologies.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "fmtdef.h"
|
||||
#include <bio.h>
|
||||
|
||||
static int
|
||||
fmtBlflush(Fmt *f)
|
||||
{
|
||||
mbstate_t state;
|
||||
Biobuf *bp;
|
||||
Rune *rp, *rend;
|
||||
int res;
|
||||
|
||||
bp = f->farg;
|
||||
rend = f->to;
|
||||
state = (mbstate_t){0};
|
||||
for(rp=(Rune*)f->start; rp < rend; rp++) {
|
||||
if(MB_LEN_MAX + bp->ocount > 0 && Bflush(bp) < 0)
|
||||
return 0;
|
||||
|
||||
res = wcrtomb((char*)bp->ebuf + bp->ocount, *rp, &state);
|
||||
if(res == -1)
|
||||
Bputc(bp, '?');
|
||||
else
|
||||
bp->ocount += res;
|
||||
}
|
||||
f->to = f->start;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
Bvlprint(Biobuf *bp, const char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
Rune buf[256];
|
||||
int res;
|
||||
|
||||
if(utf8locale())
|
||||
return Bvprint(bp, fmt, args);
|
||||
|
||||
f.runes = 1;
|
||||
f.start = (char*)buf;
|
||||
f.to = (char*)buf;
|
||||
f.stop = (char*)(buf + nelem(buf) - 1);
|
||||
f.flush = fmtBlflush;
|
||||
f.farg = bp;
|
||||
f.nfmt = 0;
|
||||
|
||||
va_copy(f.args, args);
|
||||
res = dofmt(&f, fmt);
|
||||
va_end(f.args);
|
||||
if(res > 0 && fmtBlflush(&f) == 0)
|
||||
return -1;
|
||||
return res;
|
||||
}
|
||||
|
10
lib/libstuff/fmt/fmtdef.h
Normal file
10
lib/libstuff/fmt/fmtdef.h
Normal file
@ -0,0 +1,10 @@
|
||||
#include <stuff/util.h>
|
||||
#include <langinfo.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
extern void* __fmtflush(Fmt *f, void *t, int len);
|
||||
extern int __fmtpad(Fmt *f, int n);
|
||||
extern int __rfmtpad(Fmt *f, int n);
|
||||
|
107
lib/libstuff/fmt/localefmt.c
Normal file
107
lib/libstuff/fmt/localefmt.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
|
||||
* Copyright ©2002 by Lucent Technologies.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "fmtdef.h"
|
||||
|
||||
static bool
|
||||
pad(Fmt *f, int len) {
|
||||
if(f->flags & FmtWidth) {
|
||||
if(f->runes)
|
||||
return __rfmtpad(f, f->width - len) >= 0;
|
||||
return __fmtpad(f, f->width - len) >= 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
localefmt(Fmt *f) {
|
||||
mbstate_t state;
|
||||
Rune *rp, *rend;
|
||||
char *sp, *send, *str, *end;
|
||||
Rune r;
|
||||
wchar_t w;
|
||||
int res, count, rlen;
|
||||
|
||||
str = va_arg(f->args, char*);
|
||||
|
||||
if(utf8locale()) {
|
||||
/* We handle precision in bytes, fmtstrcpy in characters */
|
||||
if(f->flags & FmtPrec)
|
||||
f->prec = utfnlen(str, f->prec);
|
||||
return fmtstrcpy(f, str);
|
||||
}
|
||||
|
||||
end = 0;
|
||||
if(f->flags & FmtPrec)
|
||||
end = str + f->prec;
|
||||
|
||||
if(!(f->flags & FmtLeft) && !pad(f, localelen(str, end)))
|
||||
return -1;
|
||||
|
||||
sp = f->to;
|
||||
send = f->stop;
|
||||
rp = (Rune*)f->to;
|
||||
rend = (Rune*)f->stop;
|
||||
|
||||
count = 0;
|
||||
for(state = (mbstate_t){0}; ; str += res) {
|
||||
switch((res = mbrtowc(&w, str, end ? end - str : MB_LEN_MAX, &state))) {
|
||||
case 0:
|
||||
case -2:
|
||||
break;
|
||||
case -1:
|
||||
w = Runesync;
|
||||
res = 1;
|
||||
/* Fallthrough. */
|
||||
default:
|
||||
count++;
|
||||
if(w > Runemax)
|
||||
w = Runesync;
|
||||
r = w;
|
||||
// print("%d %C\n", res, r);
|
||||
if(f->runes) {
|
||||
if(rp >= rend) {
|
||||
// print("flush\n");
|
||||
rp = (Rune*)__fmtflush(f, rp, sizeof *rp);
|
||||
rend = (Rune*)f->stop;
|
||||
if(rp == nil)
|
||||
return -1;
|
||||
}
|
||||
*rp++ = r;
|
||||
}else {
|
||||
if(sp + UTFmax > send && sp + (rlen = runelen(r)) > send) {
|
||||
// print("flush %d\n", rlen);
|
||||
sp = __fmtflush(f, sp, rlen);
|
||||
send = f->stop;
|
||||
if(sp == nil)
|
||||
return -1;
|
||||
}
|
||||
if(r < Runeself)
|
||||
*sp++ = (char)r;
|
||||
else
|
||||
sp += runetochar(sp, &r);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(f->runes) {
|
||||
f->nfmt += rp - (Rune*)f->to;
|
||||
f->to = (char*)rp;
|
||||
}else {
|
||||
f->nfmt += sp - (char*)f->to;
|
||||
f->to = sp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if((f->flags & FmtLeft) && !pad(f, count))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
localefmtinstall(void) {
|
||||
fmtinstall('L', localefmt);
|
||||
}
|
||||
|
33
lib/libstuff/fmt/localelen.c
Normal file
33
lib/libstuff/fmt/localelen.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
|
||||
* Copyright ©2002 by Lucent Technologies.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
localelen(char *str, char *end) {
|
||||
mbstate_t state;
|
||||
size_t n, res;
|
||||
|
||||
if(utf8locale()) {
|
||||
if(end)
|
||||
return utfnlen(str, end - str);
|
||||
return utflen(str);
|
||||
}
|
||||
|
||||
state = (mbstate_t){0};
|
||||
n = 0;
|
||||
for(n=0;;)
|
||||
switch((res = mbrtowc(nil, str, end ? end - str : MB_LEN_MAX, &state))) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
case -2:
|
||||
return n;
|
||||
default:
|
||||
n++;
|
||||
str += res;
|
||||
}
|
||||
return n; /* Not reached. */
|
||||
}
|
||||
|
17
lib/libstuff/fmt/lprint.c
Normal file
17
lib/libstuff/fmt/lprint.c
Normal file
@ -0,0 +1,17 @@
|
||||
/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
|
||||
* Copyright ©2002 by Lucent Technologies.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
lprint(int fd, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
int res;
|
||||
|
||||
va_start(ap, fmt);
|
||||
res = vlprint(fd, fmt, ap);
|
||||
va_end(ap);
|
||||
return res;
|
||||
}
|
||||
|
60
lib/libstuff/fmt/vlprint.c
Normal file
60
lib/libstuff/fmt/vlprint.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
|
||||
* Copyright ©2002 by Lucent Technologies.
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "fmtdef.h"
|
||||
#include <unistd.h>
|
||||
|
||||
static int
|
||||
fmtlfdflush(Fmt *f) {
|
||||
mbstate_t state;
|
||||
char buf[256];
|
||||
Rune *rp, *rend;
|
||||
char *sp, *send;
|
||||
int res;
|
||||
|
||||
sp = buf;
|
||||
send = buf + sizeof buf - UTFmax;
|
||||
rend = f->to;
|
||||
state = (mbstate_t){0};
|
||||
for(rp=(Rune*)f->start; rp < rend; rp++) {
|
||||
res = wcrtomb(sp, *rp, &state);
|
||||
if(res == -1)
|
||||
*sp++ = '?'; /* Fixme? */
|
||||
else
|
||||
sp += res;
|
||||
if(sp >= send || rp == rend - 1) {
|
||||
if(write((uintptr_t)f->farg, buf, sp - buf) != sp - buf)
|
||||
return 0;
|
||||
sp = buf;
|
||||
}
|
||||
}
|
||||
f->to = f->start;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
vlprint(int fd, const char *fmt, va_list args) {
|
||||
Fmt f;
|
||||
Rune buf[256];
|
||||
int res;
|
||||
|
||||
if(utf8locale())
|
||||
return vfprint(fd, fmt, args);
|
||||
|
||||
f.runes = 1;
|
||||
f.start = (char*)buf;
|
||||
f.to = (char*)buf;
|
||||
f.stop = (char*)(buf + nelem(buf) - 1);
|
||||
f.flush = fmtlfdflush;
|
||||
f.farg = (void*)(uintptr_t)fd;
|
||||
f.nfmt = 0;
|
||||
|
||||
va_copy(f.args, args);
|
||||
res = dofmt(&f, fmt);
|
||||
va_end(f.args);
|
||||
if(res > 0 && fmtlfdflush(&f) == 0)
|
||||
return -1;
|
||||
return res;
|
||||
}
|
||||
|
@ -210,17 +210,19 @@ Most aspects of `wmii` are controlled via the filesystem.
|
||||
It is usually accessed via the wmiir(1) command, but it
|
||||
can be accessed by any ``9P``, including plan9port's
|
||||
9P[1], and can be mounted natively on Linux via v9fs[1],
|
||||
and on Inferno (which man run on top of Linux).
|
||||
and on Inferno (which man run on top of Linux). All data in the
|
||||
filesystem, including filenames, is UTF-8 encoded. However, when
|
||||
accessed via wmiir(1), text is automatically translated to and
|
||||
from your locale encoding.
|
||||
|
||||
The filesystem is, as are many other 9P filesystems, entirely
|
||||
synthetic. The files exist only in memory, and are not written
|
||||
to disk. They are generally initiated on wmii startup via a
|
||||
script such as rc.wmii or wmiirc. Several files read commands,
|
||||
others simply act as if they were ordinary files (their contents
|
||||
are updated and returned exactly as written), though writing
|
||||
them has side-effects (such as changing key bindings). A
|
||||
description of the filesystem layout and control commands
|
||||
follows.
|
||||
script such as wmiirc. Several files read commands, others
|
||||
simply act as if they were ordinary files (their contents are
|
||||
updated and returned exactly as written), though writing them
|
||||
has side-effects (such as changing key bindings). A description
|
||||
of the filesystem layout and control commands follows.
|
||||
|
||||
== Hierarchy ==
|
||||
|
||||
|
@ -10,8 +10,8 @@ wmiir - The wmii 9P filesystem client
|
||||
|
||||
= SYNOPSIS =
|
||||
|
||||
wmiir [-a <address>] {create | ls [-dlp] | read | remove | write} <file> +
|
||||
wmiir [-a <address>] xwrite <file> <data> ... +
|
||||
wmiir [-a <address>] [-b] {create | ls [-dlp] | read | remove | write} <file> +
|
||||
wmiir [-a <address>] [-b] xwrite <file> <data> ... +
|
||||
wmiir -v
|
||||
|
||||
= DESCRIPTION =
|
||||
@ -21,10 +21,20 @@ to its virtual filesystem by default. `wmiir` is most often used to query and
|
||||
issue commands to `wmii`, both from the command line and from its `sh`-based
|
||||
configuration scripts.
|
||||
|
||||
Since the default encoding of 9P filesystems is UTF-8, `wmiir`
|
||||
assumes that all data read and written is text data and
|
||||
translates to or from your locale character encoding as
|
||||
necessary. When working with non-text data in a non-UTF-8
|
||||
locale, the _-b_ flag should be specified to disable this
|
||||
behavior.
|
||||
|
||||
= ARGUMENTS =
|
||||
|
||||
: -a
|
||||
The address at which to connect to `wmii`.
|
||||
: -b
|
||||
With the _-b_ flag, data that you intend to read or
|
||||
write is treated as binary data.
|
||||
:
|
||||
= COMMANDS =
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user