Compare commits

..

No commits in common. "a0ac8391932a4060e15e8ab29715fa5a66f15f64" and "290fc21b2ce6bf43b2319b76e9b1234d32c0c087" have entirely different histories.

41 changed files with 3370 additions and 87129 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,12 +0,0 @@
#
# The following are a set of tools to obtain and process dictionaries from the SKK project in order to use them with ktrans(1).
#
# grabskkdicts pulls the skk kana-kanji conversion dictionaries from the skk-dev/dict repo.
# skk2ktrans takes an skk dictionary and converts it into a kanji jisho suitable to be used with ktrans(1).
#
# You can fetch and convert all the dictionaries by running this file.
#
grabskkdicts
for(d in skkdicts/SKK-JISYO.*)
<$d skk2ktrans >$d.jisho

View file

@ -1,2 +0,0 @@
#!/bin/rc
git/clone https://github.com/skk-dev/dict skkdicts

View file

@ -1,2 +0,0 @@
#!/bin/rc
tcs -sf jis | awk '$1 !~ /;;/ {gsub("(^\/|\/$)", "", $2); gsub(" ", " "); gsub("\/", " ", $2);} {print}'

View file

@ -956,7 +956,3 @@ I really don't understand the approach being taken here.
I want to understand what the goal here is.
It won't happen.
That is either a funny joke, or it shows you don't understand Unix.
The smallest diffs are the best.
I don't understand what the proposal is.
The man page says "don't do that".
That seems disgustingly verbose to me.

View file

@ -22,18 +22,16 @@ if(~ $#p9part 0){
exit ''
}
if(test -f /386/mbr){
echo
echo 'If you use the Windows NT/2000/XP master boot record'
echo 'or a master boot record from a Unix clone (e.g., LILO or'
echo 'FreeBSD bootmgr), it is probably safe to continue using'
echo 'that boot record rather than install the Plan 9 boot record.'
echo
prompt 'Install the Plan 9 master boot record' yes no
switch($rd) {
case yes
disk/mbr -m /386/mbr /dev/$disk/data
}
echo
echo 'If you use the Windows NT/2000/XP master boot record'
echo 'or a master boot record from a Unix clone (e.g., LILO or'
echo 'FreeBSD bootmgr), it is probably safe to continue using'
echo 'that boot record rather than install the Plan 9 boot record.'
echo
prompt 'Install the Plan 9 master boot record' yes no
switch($rd) {
case yes
disk/mbr -m /386/mbr /dev/$disk/data
}
prompt 'Mark the Plan 9 partition active' yes no

View file

@ -30,27 +30,17 @@ case go
9fat=$rd
export 9fat
if(~ $#bootfile 1){
bootfile=`{basename $bootfile}
}
if(! ~ $#bootfile 1 || ! test -f /$cputype/$bootfile) {
bootfile=()
}
bootfile=`{basename $bootfile}
if(! test -f /tmp/plan9.ini) {
@{
if(~ $#bootfile 1)
echo 'bootfile='^$bootfile
if(~ $#fs 1)
echo 'bootargs=local!'^$fs' '$"fsflags
echo 'bootfile='^$bootfile
echo 'bootargs=local!'^$fs' '$"fsflags
if(~ $#nvram 1)
echo 'nvram='^$nvram
if(~ $#mouseport 1)
echo 'mouseport='^$mouseport
if(~ $#monitor 1)
echo 'monitor='^$monitor
if(~ $#vgasize 1)
echo 'vgasize='^$vgasize
echo 'mouseport='^$mouseport
echo 'monitor='^$monitor
echo 'vgasize='^$vgasize
cd '#ec'
for(i in *){
echo -n $"i'='
@ -82,50 +72,32 @@ case go
# always make backup of old bootsector
logprog dd -bs 512 -count 1 -if $9fat -of /tmp/pbs.bak
if (! test -f /386/pbs) {
if(~ $need9fatformat yes){
log Initializing Plan 9 FAT partition.
logprog disk/format -r 2 -d -l PLAN9 $9fat
}
if(~ $need9fatformat yes){
log Initializing Plan 9 FAT partition.
logprog disk/format -r 2 -d -b /n/newfs/386/pbs -l PLAN9 $9fat
}
if not {
if(~ $need9fatformat yes){
log Initializing Plan 9 FAT partition.
logprog disk/format -r 2 -d -b /386/pbs -l PLAN9 $9fat
}
if not {
log Updating bootsector.
logprog disk/format -b /386/pbs $9fat
}
log Updating bootsector.
logprog disk/format -b /n/newfs/386/pbs $9fat
}
logprog mount -c /srv/dos /n/9fat $9fat
if(test -f /386/9bootfat) {
logprog rm -f /n/9fat/9bootfat
logprog cp /386/9bootfat /n/9fat/9bootfat
logprog rm -f /n/9fat/^(9bootfat plan9.ini $bootfile)
# make file continous on disk
logprog chmod +al /n/9fat/9bootfat
}
logprog cp /n/newfs/386/9bootfat /n/9fat/9bootfat
# make file continous on disk
logprog chmod +al /n/9fat/9bootfat
# copy config
logprog rm -f /n/9fat/plan9.ini
logprog cp /tmp/plan9.ini /n/9fat/plan9.ini
# copy kernel
if(~ $#bootfile 1){
logprog rm -f /n/9fat/$bootfile
logprog cp /$cputype/$bootfile /n/9fat/$bootfile
}
logprog cp /n/newfs/$cputype/$bootfile /n/9fat/
# copy efi bootloader
for(i in /386/*.efi){
if(test -f $i) {
logprog mkdir -p /n/9fat/efi/boot
logprog cp $i /n/9fat/efi/boot/
}
}
logprog mkdir -p /n/9fat/efi/boot
logprog cp /386/^(bootia32.efi bootx64.efi) /n/9fat/efi/boot
# copy in backups
if(test -f /tmp/oldplan9.ini)

View file

@ -5260,5 +5260,3 @@ MY NAME IS BEING USED IN A PHISHING ATTACK. DO NOT RESPOND TO MAIL OFFERING MON
Xterm.js
GPU.js
Joys of Porting a Kernel to WebAssembly
Never change anything. You can only make it worse. -- Ted Unangst
Use a client written in Go? -- Skip Tavakkolian

View file

@ -835,10 +835,8 @@ used.
The snarf buffer is unaffected.
.TP
.B <rio>
Exchange dot with snarf buffer of
Exchange snarf buffers with
.IR rio .
If dot is the null string, the text in the snarf buffer is
used.
.TP
.BI / regexp
Search forward for the next match of the last regular expression

View file

@ -67,11 +67,6 @@ and any initial arguments to that program, for example
ls | mc
.EE
.PP
There may be up to 256 bytes of arguments passed to the interpreter.
These are tokenized into up to 32 arguments by
.IR tokenize (2)
before being passed as the interpreters argument vector.
.PP
When a C program is executed,
it is called as follows:
.IP

View file

@ -1,98 +0,0 @@
.TH I2C 3
.SH NAME
i2c \- I²C Bus Interface
.SH SYNOPSIS
.nf
.B bind -a #J /dev
.PP
.nf
.BI /dev/ bus /i2c. n .ctl
.BI /dev/ bus /i2c. n .data
.SH DESCRIPTION
The I²C (Inter-Integrated Circuit) bus is a serial bus standard
invented by Philips.
It is used to connect chips over short-distances like on a motherboard
or between boards.
The bus requires only a single data signal
.IR SDA ,
a clock signal
.I SDC
and ground.
Devices on the bus have 7-bit or 10-bit addresses, which is
determined by the device (see the datasheet).
Every device monitors the bus and waits for the master to initiate
a transaction.
Each transaction starts with the master sending the target device address
with a direction bit and the device acknowledges each byte
received if its address matched.
Depending on the device, more bytes must be transmitted after the
.IR device-address .
For example, encoding a register number at a memory offset.
We refer to these bytes as the
.IR sub-address .
After the address phase, the data phase begins where
zero or more data bytes are either transmitted or received
depending on the transaction direction.
.PP
This driver supports multiple buses (controllers) to be registered
by platform specific code in the kernel.
Each bus is represented as a directory with a platform specific name.
.PP
Because all received bytes are acknowledged by target devices,
it is possible for the master to enumerate all existing addresses
on a bus, which is done when accessing the
.I bus
directory.
.PP
Platform specific code can also register individual devices,
supplying a meaningful device configuration.
It can also be necessary to manually register devices if
the device has been disabled by an enable signal or
otherwise inhibited during enumeration.
.PP
Each device appears as a control (
.BI i2c. n .ctl
)
and a data file (
.BI i2c. n .data
) in the
.I bus
directory
where
.I n
is the device-address in hexadecimal.
.PP
The data file is used to initiate transactions to the device.
The initial
.I sub-address
bytes sent are derived from the file position according to the device
configuration, and the length of the data phase is controlled by
the requested read or write size.
The requested size might be truncated by the driver if
the request exceeds the logical file-size.
.PP
The control-file provides access to the device configuration.
When read,
it reproduces this configuration in text form.
The following text lines are accepted when written to the control-file:
.TF "subaddress n"
.TP
.BI "subaddress " n
Sets the length
.IR n ,
in bytes, of the sub-address for the device
that is derived from the file-position of the data-file.
This can be set to zero if no sub-address bytes should
be generated by the driver.
By default, the sub-address length is 1.
.TP
.BI "size " n
Changes the logical size of the data-file to
.IR n .
Making sure the file-position is not exceeding this size.
.SH SOURCE
.B /sys/src/9/port/devi2c.c
.SH HISTORY
The file-interface has been inspired by infernos devi2c,
but with the addition of supporting multiple buses
and device enumeration.

View file

@ -682,43 +682,33 @@ Otherwise a free port number starting at 5000 is chosen.
The connect fails if the combination of local and remote address/port pairs
are already assigned to another port.
.TP
.BI announce\ [ip-address ! ]port
Set the local IP address and port number and accept calls there. If
ip-address is left out, accept calls on any address. If port is 0, a
port is automatically choosen that is not yet announced.
If the address is
.BI announce\ X
.I X
is a decimal port number or
.LR * .
Set the local port
number to
.I X
and accept calls to
.IR X .
If
.I X
is
.LR * ,
accept calls on any address.
If port is
.LR * ,
accept calls on any port.
If port is
.LR * ,
and the address is left out, accept calls on any address and port.
accept
calls for any port that no process has explicitly announced.
The local IP address cannot be set.
.B Announce
fails if the connection is already announced.
fails if the connection is already announced or connected.
.TP
.BI bind\ [ip-address ! ]port
Set the local IP address and port number like for a server connection
similar to the
.B announce
command.
If ip-address is left out, an address is automatically selected. If
port is 0, a port is automatically choosen that is not yet announced.
This command has no actual effect, beyond remembering the parameters
and possibly selecting an unused port.
The commands
.B announce
and
.B connect
reset both the local address and the port according to their own
parameters.
This command also does
.B not
reserve the IP address and port, another connection can use them, even
while they are registered in a connection by this command.
This exists to support emulation of BSD sockets by the APE libraries
(see
.BI bind\ X
.I X
is a decimal port number or
.LR * .
Set the local port number to
.IR X .
This exists to support emulation
of BSD sockets by the APE libraries (see
.IR pcc (1))
and is not otherwise used.
.\" this is gone

View file

@ -62,7 +62,7 @@ changeuser, convkeys, printnetkey, status, enable, disable, authsrv, guard.srv,
.PP
.B auth/box
[
.B -s
.B -d
] [
.B -rc
.I file
@ -298,8 +298,9 @@ the child namespace; the
flag specifies a string of driver
characters to keep. The
.B -s
flag initializes the namespace to what rc expects,
and passes its arguments unmodified to /bin/rc.
flag gives a base set of namespace
components, ones expected by rc, then passes
the first argument as a script file to rc.
.PP
.I As
executes

View file

@ -13,8 +13,7 @@ dev
tls
cap
fs
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
mouse mouse
uart gpio
@ -23,11 +22,10 @@ dev
usb
link
loopbackmedium
ethermedium
archbcm
usbdwc
ethermedium
loopbackmedium
netdevmedium
ip
tcp

View file

@ -13,8 +13,7 @@ dev
tls
cap
fs
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
mouse mouse
uart gpio
@ -23,11 +22,10 @@ dev
usb
link
loopbackmedium
ethermedium
archbcm2
usbdwc
ethermedium
loopbackmedium
netdevmedium
ip
tcp

View file

@ -13,8 +13,7 @@ dev
tls
cap
fs
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
mouse mouse
uart gpio
@ -24,11 +23,10 @@ dev
dtracy
link
loopbackmedium
ethermedium
archbcm3
usbdwc
ethermedium
loopbackmedium
netdevmedium
ip
tcp

View file

@ -14,8 +14,7 @@ dev
cap
fs
ether netif
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
mouse mouse
uart gpio
@ -32,7 +31,6 @@ link
ethergenet ethermii
ethermedium
loopbackmedium
netdevmedium
ip
tcp

View file

@ -1,349 +0,0 @@
/*
* NXP PCF8523 real time clock
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "../port/i2c.h"
enum {
Seconds= 0x03,
Minutes= 0x04,
Hours= 0x05,
Mday= 0x06,
Wday= 0x07,
Month= 0x08,
Year= 0x09,
Nbcd= 1+Year-Seconds,
};
typedef struct Rtc Rtc;
struct Rtc
{
int sec;
int min;
int hour;
int mday;
int wday;
int mon;
int year;
};
enum{
Qdir = 0,
Qrtc,
};
Dirtab rtcdir[]={
".", {Qdir, 0, QTDIR}, 0, 0555,
"rtc", {Qrtc, 0}, 0, 0664,
};
static ulong rtc2sec(Rtc*);
static void sec2rtc(ulong, Rtc*);
static I2Cdev *i2c;
static Chan*
rtcattach(char* spec)
{
i2c = i2cdev(i2cbus("i2c3"), 0x68);
if(i2c == nil)
error(Enonexist);
i2c->subaddr = 1;
i2c->size = 0x14;
return devattach('r', spec);
}
static Walkqid*
rtcwalk(Chan* c, Chan *nc, char** name, int nname)
{
return devwalk(c, nc, name, nname, rtcdir, nelem(rtcdir), devgen);
}
static int
rtcstat(Chan* c, uchar* dp, int n)
{
return devstat(c, dp, n, rtcdir, nelem(rtcdir), devgen);
}
static Chan*
rtcopen(Chan* c, int omode)
{
omode = openmode(omode);
switch((ulong)c->qid.path){
case Qrtc:
if(strcmp(up->user, eve)!=0 && omode!=OREAD)
error(Eperm);
break;
}
return devopen(c, omode, rtcdir, nelem(rtcdir), devgen);
}
static void
rtcclose(Chan*)
{
}
#define GETBCD(o) (((bcdclock[o]&0xf)%10) + 10*((bcdclock[o]>>4)%10))
static long
_rtctime(void)
{
uchar bcdclock[Nbcd];
Rtc rtc;
/* read clock values */
i2crecv(i2c, bcdclock, Nbcd, Seconds);
/*
* convert from BCD
*/
rtc.sec = GETBCD(Seconds-Seconds) % 60;
rtc.min = GETBCD(Minutes-Seconds) % 60;
rtc.hour = GETBCD(Hours-Seconds) % 24;
rtc.mday = GETBCD(Mday-Seconds);
rtc.wday = GETBCD(Wday-Seconds) % 7;
rtc.mon = GETBCD(Month-Seconds);
rtc.year = GETBCD(Year-Seconds) % 100;
/*
* the world starts jan 1 1970
*/
if(rtc.year < 70)
rtc.year += 2000;
else
rtc.year += 1900;
return rtc2sec(&rtc);
}
long
rtctime(void)
{
int i;
long t, ot;
/* loop till we get two reads in a row the same */
t = _rtctime();
for(i = 0; i < 100; i++){
ot = t;
t = _rtctime();
if(ot == t)
break;
}
if(i == 100) print("we are boofheads\n");
return t;
}
static long
rtcread(Chan* c, void* buf, long n, vlong off)
{
ulong offset = off;
if(c->qid.type & QTDIR)
return devdirread(c, buf, n, rtcdir, nelem(rtcdir), devgen);
switch((ulong)c->qid.path){
case Qrtc:
return readnum(offset, buf, n, rtctime(), 12);
}
error(Ebadarg);
return 0;
}
#define PUTBCD(n,o) bcdclock[o] = (n % 10) | (((n / 10) % 10)<<4)
static long
rtcwrite(Chan* c, void* buf, long n, vlong off)
{
Rtc rtc;
ulong secs;
char *cp, sbuf[32];
uchar bcdclock[Nbcd];
ulong offset = off;
if(offset!=0)
error(Ebadarg);
switch((ulong)c->qid.path){
case Qrtc:
if(n >= sizeof(sbuf))
error(Ebadarg);
strncpy(sbuf, buf, n);
sbuf[n] = '\0';
for(cp = sbuf; *cp != '\0'; cp++)
if(*cp >= '0' && *cp <= '9')
break;
secs = strtoul(cp, 0, 0);
/*
* convert to bcd
*/
sec2rtc(secs, &rtc);
PUTBCD(rtc.sec, Seconds-Seconds);
PUTBCD(rtc.min, Minutes-Seconds);
PUTBCD(rtc.hour, Hours-Seconds);
PUTBCD(rtc.mday, Mday-Seconds);
PUTBCD(rtc.wday, Wday-Seconds);
PUTBCD(rtc.mon, Month-Seconds);
PUTBCD(rtc.year, Year-Seconds);
/*
* write the clock
*/
i2csend(i2c, bcdclock, Nbcd, Seconds);
return n;
}
error(Ebadarg);
return 0;
}
Dev rtcdevtab = {
'r',
"rtc",
devreset,
devinit,
devshutdown,
rtcattach,
rtcwalk,
rtcstat,
rtcopen,
devcreate,
rtcclose,
rtcread,
devbread,
rtcwrite,
devbwrite,
devremove,
devwstat,
};
#define SEC2MIN 60L
#define SEC2HOUR (60L*SEC2MIN)
#define SEC2DAY (24L*SEC2HOUR)
/*
* days per month plus days/year
*/
static int dmsize[] =
{
365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
static int ldmsize[] =
{
366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
/*
* return the days/month for the given year
*/
static int*
yrsize(int y)
{
if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0))
return ldmsize;
else
return dmsize;
}
/*
* compute seconds since Jan 1 1970
*/
static ulong
rtc2sec(Rtc *rtc)
{
ulong secs;
int i;
int *d2m;
secs = 0;
/*
* seconds per year
*/
for(i = 1970; i < rtc->year; i++){
d2m = yrsize(i);
secs += d2m[0] * SEC2DAY;
}
/*
* seconds per month
*/
d2m = yrsize(rtc->year);
for(i = 1; i < rtc->mon; i++)
secs += d2m[i] * SEC2DAY;
secs += (rtc->mday-1) * SEC2DAY;
secs += rtc->hour * SEC2HOUR;
secs += rtc->min * SEC2MIN;
secs += rtc->sec;
return secs;
}
/*
* compute rtc from seconds since Jan 1 1970
*/
static void
sec2rtc(ulong secs, Rtc *rtc)
{
int d;
long hms, day;
int *d2m;
/*
* break initial number into days
*/
hms = secs % SEC2DAY;
day = secs / SEC2DAY;
if(hms < 0) {
hms += SEC2DAY;
day -= 1;
}
/*
* 19700101 was thursday
*/
rtc->wday = (day + 7340036L) % 7;
/*
* generate hours:minutes:seconds
*/
rtc->sec = hms % 60;
d = hms / 60;
rtc->min = d % 60;
d /= 60;
rtc->hour = d;
/*
* year number
*/
if(day >= 0)
for(d = 1970; day >= *yrsize(d); d++)
day -= *yrsize(d);
else
for (d = 1970; day < 0; d--)
day += *yrsize(d-1);
rtc->year = d;
/*
* generate month
*/
d2m = yrsize(rtc->year);
for(d = 1; day >= d2m[d]; d++)
day -= d2m[d];
rtc->mday = day + 1;
rtc->mon = d;
return;
}

View file

@ -265,7 +265,7 @@ intrenable(int irq, void (*f)(Ureg*, void*), void *a, int tbdf, char *)
prio = 0x80;
intid = irq;
if((v = xalloc(sizeof(Vctl))) == nil)
panic("intrenable: no mem");
panic("irqenable: no mem");
v->irq = irq;
v->intid = intid;
v->f = f;

View file

@ -13,14 +13,12 @@ dev
cap
fs
ether netif
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen swcursor
mouse screen swcursor
uart
usb
i2c
rtc devi2c
sd
link
@ -28,10 +26,8 @@ link
etherimx ethermii
ethermedium
loopbackmedium
netdevmedium
i2cimx devi2c
pciimx pci
ip
tcp
udp

View file

@ -227,25 +227,26 @@ rtcwrite(Chan* c, void* buf, long n, vlong off)
char *a, *start;
Rtc rtc;
ulong secs;
char *cp, sbuf[32];
uchar bcdclock[Nbcd];
char *cp, *ep;
ulong offset = off;
if(offset!=0)
error(Ebadarg);
switch((ulong)c->qid.path){
case Qrtc:
/*
* read the time
*/
if(n >= sizeof(sbuf))
error(Ebadarg);
strncpy(sbuf, buf, n);
sbuf[n] = '\0';
for(cp = sbuf; *cp != '\0'; cp++)
if(*cp >= '0' && *cp <= '9')
cp = ep = buf;
ep += n;
while(cp < ep){
if(*cp>='0' && *cp<='9')
break;
cp++;
}
secs = strtoul(cp, 0, 0);
/*

View file

@ -20,7 +20,7 @@ dev
dtracy
ether netif
bridge log
bridge netif log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
draw screen vga vgax vgasoft
@ -81,9 +81,9 @@ link
ethervirtio pci
ethervirtio10 pci
ethermedium
loopbackmedium
netdevmedium
pcmciamodem
netdevmedium
loopbackmedium
usbuhci pci
usbohci pci
usbehci usbehcipc

View file

@ -19,8 +19,8 @@ dev
fs
ether netif
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
bridge netif log
ip arp chandial ip ipv6 ipaux iproute netlog ethermedium nullmedium pktmedium inferno
draw screen vga vgax vgasoft
mouse mouse
@ -79,9 +79,9 @@ link
ethervirtio pci
ethervirtio10 pci
ethermedium
loopbackmedium
netdevmedium
# pcmciamodem
netdevmedium
loopbackmedium
usbuhci pci
usbohci pci
usbehci pci usbehcipc

View file

@ -243,19 +243,35 @@ sysrfork(va_list list)
}
static int
shargs(char *s, int n, char **ap, int nap)
shargs(char *s, int n, char **ap)
{
char *p;
int i;
if(n <= 2 || s[0] != '#' || s[1] != '!')
return -1;
s += 2;
n -= 2; /* skip #! */
if((p = memchr(s, '\n', n)) == nil)
return 0;
*p = 0;
i = tokenize(s, ap, nap-1);
for(i=0;; i++){
if(i >= n)
return 0;
if(s[i]=='\n')
break;
}
s[i] = 0;
i = 0;
for(;;) {
while(*s==' ' || *s=='\t')
s++;
if(*s == 0)
break;
ap[i++] = s++;
while(*s && *s!=' ' && *s!='\t')
s++;
if(*s == 0)
break;
*s++ = 0;
}
ap[i] = nil;
return i;
}
@ -284,15 +300,12 @@ beswav(uvlong v)
uintptr
sysexec(va_list list)
{
union {
struct {
Exec;
uvlong hdr[1];
} ehdr;
char buf[256];
} u;
char line[256];
char *progarg[32+1];
struct {
Exec;
uvlong hdr[1];
} ehdr;
char line[sizeof(ehdr)];
char *progarg[sizeof(line)/2+1];
volatile char *args, *elem, *file0;
char **argv, **argp, **argp0;
char *a, *e, *charp, *file;
@ -340,22 +353,22 @@ sysexec(va_list list)
if(!indir)
kstrdup(&elem, up->genbuf);
n = devtab[tc->type]->read(tc, u.buf, sizeof(u.buf), 0);
n = devtab[tc->type]->read(tc, &ehdr, sizeof(ehdr), 0);
if(n >= sizeof(Exec)) {
magic = beswal(u.ehdr.magic);
magic = beswal(ehdr.magic);
if(magic == AOUT_MAGIC) {
if(magic & HDR_MAGIC) {
if(n < sizeof(u.ehdr))
if(n < sizeof(ehdr))
error(Ebadexec);
entry = beswav(u.ehdr.hdr[0]);
text = UTZERO+sizeof(u.ehdr);
entry = beswav(ehdr.hdr[0]);
text = UTZERO+sizeof(ehdr);
} else {
entry = beswal(u.ehdr.entry);
entry = beswal(ehdr.entry);
text = UTZERO+sizeof(Exec);
}
if(entry < text)
error(Ebadexec);
text += beswal(u.ehdr.text);
text += beswal(ehdr.text);
if(text <= entry || text >= (USTKTOP-USTKSIZE))
error(Ebadexec);
@ -380,8 +393,8 @@ sysexec(va_list list)
/*
* Process #! /bin/sh args ...
*/
memmove(line, u.buf, n);
n = shargs(line, n, progarg, nelem(progarg));
memmove(line, &ehdr, n);
n = shargs(line, n, progarg);
if(n < 1)
error(Ebadexec);
/*
@ -398,8 +411,8 @@ sysexec(va_list list)
t = (text+align) & ~align;
text -= UTZERO;
data = beswal(u.ehdr.data);
bss = beswal(u.ehdr.bss);
data = beswal(ehdr.data);
bss = beswal(ehdr.bss);
align = BY2PG-1;
d = (t + data + align) & ~align;
bssend = t + data + bss;

View file

@ -11,9 +11,8 @@ dev
env
pipe
dup
ether netif
bridge log
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
ether netif
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium inferno
tls
cap
kprof

View file

@ -39,30 +39,6 @@ _sock_inport(struct sockaddr *a)
return 0;
}
int
_sock_inisany(int af, void *addr)
{
int alen;
void *any;
/* an IPv4 address that is auto-initialized to all zeros */
static struct in_addr inaddr_any;
switch(af){
case AF_INET:
alen = sizeof inaddr_any.s_addr;
any = &inaddr_any;
break;
case AF_INET6:
alen = sizeof in6addr_any;
any = &in6addr_any;
break;
default:
return 0;
}
return 0 == memcmp(addr, any, alen);
}
int
_sock_inaddr(int af, char *ip, char *port, void *a, int *alen)
{
@ -121,23 +97,3 @@ _sock_ingetaddr(Rock *r, void *a, int *alen, char *file)
close(fd);
}
}
char *
_sock_inaddr2string(Rock *r, char *dest, int dlen)
{
int af = r->domain;
void *addr = _sock_inip(&r->addr);
int port = _sock_inport(&r->addr);
char *d = dest;
char *dend = dest+dlen;
if(!_sock_inisany(af, addr)){
inet_ntop(af, addr, d, dlen-1);
d = memchr(d, 0, dlen-1);
*(d++) = '!';
}
snprintf(d, dend-d, "%d", port);
return dest;
}

View file

@ -24,7 +24,7 @@
int
bind(int fd, void *a, int alen)
{
int n, len, cfd;
int n, len, cfd, port;
struct sockaddr *sa;
Rock *r;
char msg[128];
@ -55,25 +55,20 @@ bind(int fd, void *a, int alen)
errno = EBADF;
return -1;
}
strcpy(msg, "bind ");
_sock_inaddr2string(r, msg + 5, sizeof msg - 5);
port = _sock_inport(&r->addr);
if(port > 0)
snprintf(msg, sizeof msg, "bind %d", port);
else
strcpy(msg, "bind *");
n = write(cfd, msg, strlen(msg));
if(n < 0){
_syserrno();
if(errno == EPLAN9)
errno = EOPNOTSUPP;
errno = EOPNOTSUPP; /* Improve error reporting!!! */
close(cfd);
return -1;
}
close(cfd);
if(_sock_inport(&r->addr) == 0)
if(port <= 0)
_sock_ingetaddr(r, &r->addr, 0, "local");
return 0;
}

View file

@ -121,7 +121,7 @@ listen(fd, backlog)
int backlog;
{
Rock *r;
int n, cfd;
int n, cfd, port;
char msg[128];
struct sockaddr_un *lunix;
@ -139,13 +139,20 @@ listen(fd, backlog)
errno = EBADF;
return -1;
}
strcpy(msg, "announce ");
_sock_inaddr2string(r, msg + 9, sizeof msg - 9);
port = _sock_inport(&r->addr);
if(port >= 0) {
if(write(cfd, "bind 0", 6) < 0) {
errno = EGREG;
close(cfd);
return -1;
}
snprintf(msg, sizeof msg, "announce %d", port);
}
else
strcpy(msg, "announce *");
n = write(cfd, msg, strlen(msg));
if(n < 0){
_syserrno();
if(errno == EPLAN9)
errno = EOPNOTSUPP;
errno = EOPNOTSUPP; /* Improve error reporting!!! */
close(cfd);
return -1;
}

View file

@ -43,7 +43,5 @@ extern int _sock_data(int, char*, int, int, int, Rock**);
extern int _sock_ipattr(char*);
extern void* _sock_inip(struct sockaddr*);
extern int _sock_inport(struct sockaddr*);
extern int _sock_inisany(int af, void *addr);
extern int _sock_inaddr(int, char*, char*, void*, int*);
extern void _sock_ingetaddr(Rock*, void*, int*, char*);
extern char* _sock_inaddr2string(Rock *r, char *dest, int dlen);

View file

@ -2,11 +2,7 @@
#include <libc.h>
#include <auth.h>
static int debug;
static char cwd[8192];
static char *parts[256];
static int mflags[nelem(parts)];
static int nparts;
static int debug;
static void
binderr(char *new, char *old, int flag)
@ -36,14 +32,20 @@ binderr(char *new, char *old, int flag)
fprint(2, "bind %s %s %s\n", dash, new, old);
}
if(bind(new, old, flag) < 0)
sysfatal("bind %s: %r", new);
sysfatal("bind: %r");
}
static void
resolvenames(char **names, int nname)
{
int i;
char buf[8192];
int fd;
fd = open(".", OREAD|OCEXEC);
if(fd < 0)
sysfatal("could not open .: %r");
fd2path(fd, buf, sizeof buf);
for(i = 0; i < nname; i++){
if(names[i] == nil)
continue;
@ -53,9 +55,10 @@ resolvenames(char **names, int nname)
case '/':
break;
default:
names[i] = cleanname(smprint("%s/%s", cwd, names[i]));
}
names[i] = cleanname(smprint("%s/%s", buf, names[i]));
}
}
close(fd);
}
static void
@ -100,8 +103,7 @@ sandbox(char **names, int *flags, int nname)
free(d);
binderr(skel, dir, MBEFORE);
}
if(flags[j] != -1)
binderr(names[j], targ, flags[j]);
binderr(names[j], targ, flags[j]);
}
binderr(newroot, "/", MREPL);
}
@ -131,11 +133,16 @@ skelfs(void)
sysfatal("/mnt/d mount setup: %r");
}
static char *parts[256];
static int mflags[nelem(parts)];
static int nparts;
static char *rc[] = { "/bin/rc", nil , nil};
static void
push(char *path, int flag)
{
if(nparts == nelem(parts))
sysfatal("too many bound paths");
sysfatal("component overflow");
parts[nparts] = path;
mflags[nparts++] = flag;
}
@ -143,23 +150,23 @@ push(char *path, int flag)
void
usage(void)
{
fprint(2, "usage %s: [ -r file ] [ -c dir ] [ -e devs ] cmd args...\n", argv0);
fprint(2, "usage %s: [ -d ] [ -r file ] [ -c dir ] [ -e devs ] [ -. path ] cmd args...\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
char **argp, devs[128];
int i, narg, dfd;
char devs[1024];
int dfd;
char *path;
char *a;
int sflag;
nparts = 0;
narg = 0;
path = "/";
memset(devs, 0, sizeof devs);
sflag = 0;
argp = argv;
ARGBEGIN{
case 'D':
debug++;
@ -177,6 +184,9 @@ main(int argc, char **argv)
case 'e':
snprint(devs, sizeof devs, "%s%s", devs, EARGF(usage()));
break;
case '.':
path = EARGF(usage());
break;
case 's':
sflag = 1;
break;
@ -185,19 +195,18 @@ main(int argc, char **argv)
break;
}ARGEND
if(argc == 0 && !sflag)
if(argc == 0)
usage();
if(getwd(cwd, sizeof(cwd)) == nil)
sysfatal("getwd: %r");
push(cwd, -1);
if(sflag){
snprint(devs, sizeof devs, "%s%s", devs, "|d");
push("/srv", MREPL|MCREATE);
push("/env", MREPL|MCREATE);
push("/rc", MREPL);
push("/bin", MREPL);
argp[narg++] = "/bin/rc";
push(argv[0], MREPL);
rc[1] = argv[0];
argv = rc;
} else {
if(access(argv[0], AEXIST) == -1){
if((argv[0] = smprint("/bin/%s", argv[0])) == nil)
@ -207,9 +216,6 @@ main(int argc, char **argv)
}
push(argv[0], MREPL);
}
for(i = 0; i < argc; i++)
argp[narg++] = argv[i];
argp[narg] = nil;
rfork(RFNAMEG|RFFDG);
skelfs();
@ -219,7 +225,7 @@ main(int argc, char **argv)
resolvenames(parts, nparts);
sandbox(parts, mflags, nparts);
if(debug)
fprint(2, "chdev %s\n", devs);
@ -232,8 +238,8 @@ main(int argc, char **argv)
}
close(dfd);
if(chdir(cwd) < 0)
sysfatal("chdir %s: %r", cwd);
exec(argp[0], argp);
if(chdir(path) < 0)
sysfatal("can not cd to %s", path);
exec(argv[0], argv);
sysfatal("exec: %r");
}

View file

@ -64,7 +64,7 @@ lookup(Pfilt *pf, Object *o)
}
int
matchesfilter1(Pfilt *pf, Object *t, Object *pt)
filtermatch1(Pfilt *pf, Object *t, Object *pt)
{
Object *a, *b;
Hash ha, hb;
@ -88,7 +88,7 @@ matchesfilter1(Pfilt *pf, Object *t, Object *pt)
sysfatal("read %H: %r", ha);
if((b = readobject(hb)) == nil)
sysfatal("read %H: %r", hb);
r = matchesfilter1(&pf->sub[i], a, b);
r = filtermatch1(&pf->sub[i], a, b);
unref(a);
unref(b);
if(r)
@ -98,12 +98,11 @@ matchesfilter1(Pfilt *pf, Object *t, Object *pt)
}
int
matchesfilter(Object *o)
filtermatch(Object *o)
{
Object *t, *p, *pt;
int i, r;
assert(o->type == GCommit);
if(pathfilt == nil)
return 1;
if((t = readobject(o->commit->tree)) == nil)
@ -113,7 +112,7 @@ matchesfilter(Object *o)
sysfatal("read %H: %r", o->commit->parent[i]);
if((pt = readobject(p->commit->tree)) == nil)
sysfatal("read %H: %r", o->commit->tree);
r = matchesfilter1(pathfilt, t, pt);
r = filtermatch1(pathfilt, t, pt);
unref(p);
unref(pt);
if(r)
@ -132,13 +131,16 @@ nextline(char *p, char *e)
return p;
}
static int
static void
show(Object *o)
{
Tm tm;
char *p, *q, *e;
assert(o->type == GCommit);
if(!filtermatch(o))
return;
if(shortlog){
p = o->commit->msg;
e = p + o->commit->nmsg;
@ -168,7 +170,6 @@ show(Object *o)
Bprint(out, "\n");
}
Bflush(out);
return 1;
}
static void
@ -180,14 +181,10 @@ showquery(char *q)
if((n = resolverefs(&h, q)) == -1)
sysfatal("resolve: %r");
for(i = 0; i < n && (msgcount == -1 || msgcount > 0); i++){
for(i = 0; i < n && (msgcount == -1 || msgcount-- > 0); i++){
if((o = readobject(h[i])) == nil)
sysfatal("read %H: %r", h[i]);
if(matchesfilter(o)){
show(o);
if(msgcount != -1)
msgcount--;
}
show(o);
unref(o);
}
exits(nil);
@ -210,12 +207,8 @@ showcommits(char *c)
qinit(&objq);
osinit(&done);
qput(&objq, o, 0);
while(qpop(&objq, &e) && (msgcount == -1 || msgcount > 0)){
if(matchesfilter(e.o)){
show(e.o);
if(msgcount != -1)
msgcount--;
}
while(qpop(&objq, &e) && (msgcount == -1 || msgcount-- > 0)){
show(e.o);
for(i = 0; i < e.o->commit->nparent; i++){
if(oshas(&done, e.o->commit->parent[i]))
continue;

View file

@ -1,224 +0,0 @@
#include <u.h>
#include <libc.h>
#include "hash.h"
typedef struct Hnode Hnode;
struct Hnode {
int filled;
int next;
void *key;
};
enum{
Tagsize = sizeof(Hnode),
};
uvlong
shash(char *s)
{
uvlong hash;
hash = 7;
for(; *s; s++)
hash = hash*31 + *s;
return hash;
}
Hmap*
hmapalloc(int nbuckets, int size)
{
void *store;
Hmap *h;
int nsz;
nsz = Tagsize + size;
store = mallocz(sizeof(*h) + (nbuckets * nsz), 1);
if(store == nil)
return nil;
h = store;
h->nbs = nbuckets;
h->nsz = nsz;
h->len = h->cap = nbuckets;
h->nodes = store;
h->nodes += sizeof(*h);
return store;
}
int
hmaprepl(Hmap **store, char *key, void *new, void *old, int freekeys)
{
Hnode *n;
uchar *v;
uchar *oldv;
Hmap *h;
int next;
vlong diff;
h = *store;
oldv = nil;
v = h->nodes + (shash(key)%h->nbs) * h->nsz;
for(;;){
n = (Hnode*)v;
next = n->next;
if(n->filled == 0)
goto replace;
if(strcmp(n->key, key) == 0){
if(freekeys)
free(n->key);
oldv = v + Tagsize;
goto replace;
}
if(next == 0)
break;
v = h->nodes + next*h->nsz;
}
if(h->cap == h->len){
/* figure out way back from a relocation */
diff = v - h->nodes;
h->cap *= 2;
*store = realloc(*store, sizeof(*h) + h->cap*h->nsz);
h = *store;
h->nodes = (uchar*)*store + sizeof(*h);
memset(h->nodes + h->len*h->nsz, 0, h->nsz);
v = h->nodes + diff;
n = (Hnode*)v;
}
n->next = h->len;
h->len++;
assert(h->len <= h->cap);
v = h->nodes + n->next*h->nsz;
n = (Hnode*)v;
replace:
memmove(v + Tagsize, new, h->nsz - Tagsize);
n->filled++;
n->key = key;
n->next = next;
if(old != nil && oldv != nil){
memmove(old, oldv, h->nsz - Tagsize);
return 1;
}
return 0;
}
int
hmapupd(Hmap **h, char *key, void *new)
{
char *prev;
prev = hmapkey(*h, key);
if(prev == nil)
prev = key;
return hmaprepl(h, prev, new, nil, 0);
}
void*
_hmapget(Hmap *h, char *key)
{
Hnode *n;
uchar *v;
v = h->nodes + (shash(key)%h->nbs)*h->nsz;
for(;;){
n = (Hnode*)v;
if(n->filled != 0 && strcmp(n->key, key) == 0)
return v;
if(n->next == 0)
break;
v = h->nodes + n->next*h->nsz;
}
return nil;
}
int
hmapget(Hmap *h, char *key, void *dst)
{
uchar *v;
v = _hmapget(h, key);
if(v == nil)
return -1;
if(dst != nil)
memmove(dst, v + Tagsize, h->nsz - Tagsize);
return 0;
}
int
hmapdel(Hmap *h, char *key, void *dst, int freekey)
{
uchar *v;
Hnode *n;
v = _hmapget(h, key);
if(v == nil)
return -1;
n = (Hnode*)v;
n->filled = 0;
if(freekey)
free(n->key);
if(dst != nil)
memmove(dst, v + Tagsize, h->nsz - Tagsize);
return 0;
}
char*
hmapkey(Hmap *h, char *key)
{
uchar *v;
Hnode *n;
v = _hmapget(h, key);
if(v == nil)
return nil;
n = (Hnode*)v;
return n->key;
}
Hmap*
hmaprehash(Hmap *old, int buckets)
{
int i;
uchar *v;
Hnode *n;
Hmap *new;
if(buckets == 0)
buckets = old->len;
new = hmapalloc(buckets, old->nsz - Tagsize);
for(i=0 ; i < old->len; i++){
v = old->nodes + i*old->nsz;
n = (Hnode*)v;
hmaprepl(&new, n->key, v + Tagsize, nil, 0);
}
free(old);
return new;
}
void
hmapreset(Hmap *h, int freekeys)
{
Hnode *n;
uchar *v;
int i;
for(i=0; i < h->len; i++){
v = h->nodes + i*h->nsz;
n = (Hnode*)v;
if(n->filled == 0)
continue;
if(freekeys)
free(n->key);
n->filled = 0;
}
h->len = 0;
}

View file

@ -1,23 +0,0 @@
typedef union Hkey Hkey;
union Hkey {
void *p;
int v;
};
typedef struct Hmap Hmap;
struct Hmap {
int nbs;
int nsz;
int len;
int cap;
uchar *nodes;
};
Hmap* hmapalloc(int nbuckets, int size);
int hmapget(Hmap *h, char *key, void *dst);
int hmaprepl(Hmap **h, char *key, void *new, void *old, int freekeys);
int hmapupd(Hmap **h, char *key, void *new);
int hmapdel(Hmap *h, char *key, void *dst, int freekey);
char* hmapkey(Hmap *h, char *key);
void hmapreset(Hmap *h, int freekeys);

211
sys/src/cmd/ktrans/jisho.c Normal file
View file

@ -0,0 +1,211 @@
/*
* open jisho file, and set the size of this jisho etc
*
* Kenji Okamoto August 4, 2000
* Osaka Prefecture Univ.
* okamoto@granite.cias.osakafu-u.ac.jp
*/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "jisho.h"
Dictionary *openQDIC(char *);
void freeQDIC(Dictionary*);
KouhoList *getKouhoHash(Dictionary*, char *);
KouhoList *getKouhoFile(DicList*, char *);
void selectKouho(KouhoList **, KouhoList*);
int hashVal(char *);
void addHash(Hash **, DicList*);
/*
* Open QuickDIC (hashed personal dictionary)
* open skk styled ktrans dictionary file, and make its hash table
* based on individual header kana strings
*
* KouhoList
* |---------|
* Hash |---->kouho---->kouhotop
* |-------| |
* dic---->dhash---->dicindex---->kanahead
* |--------| |--------|
* Dictionary DicList
*
*/
Dictionary *
openQDIC(char *dicname)
{
Biobuf *f;
void *Bbuf;
Dictionary *dic;
DicList *dicitem; /* for a future extension */
char buf[1024], *startstr, *endstr;
int i;
SET(dicitem); /* yes, I know I'm wrong, but... */
dic = (Dictionary*)malloc(sizeof(Dictionary));
/* make room for pointer array (size=HASHSIZE) of hash table */
for(i=0; i< HASHSIZE; i++) dic->dhash[i] = 0;
dic->dlist = 0; /* for a future extension (more than one dics ^_^ */
if ((f = Bopen(dicname, OREAD)) == 0)
return dic;
/* make hash table by the dic's header word */
while(Bbuf = Brdline(f, '\n')) {
strncpy(buf, (char *)Bbuf, Blinelen(f));
if (buf[0] == ';') /* comment line */
continue;
else {
/* get header word from jisho */
startstr = buf;
if(!(endstr = utfutf(startstr, "\t"))) break;
*endstr = '\0';
/* dicitem includes each header word from the jisho */
dicitem = (DicList*)malloc(sizeof(DicList)+(endstr-startstr+1));
dicitem->nextitem = 0; /* for a future extension */
strcpy(dicitem->kanahead, startstr);
dicitem->kouho = getKouhoFile(dicitem, endstr); /* read kouho from jisho */
addHash(dic->dhash, dicitem);
}
continue;
}
dic->dlist = dicitem;
Bterm(f);
return dic;
}
/*
* free dynamically allocated memory
*/
void
freeQDIC(Dictionary *dic)
{
Hash *hash1, *hash2;
DicList *dlist, *dlist2;
int l;
for (dlist = dic->dlist;
dlist != 0;
dlist2 = dlist, dlist = dlist->nextitem, free((void *)dlist2));
for (l = 0; l < HASHSIZE; l++) {
for (hash1 = dic->dhash[l]; hash1; hash1 = hash2) {
if (hash1->next !=0) {
hash2 = hash1->next;
free((void *)hash1);
}else
break;
}
}
free((void *)dic);
}
int
hashVal(char *s)
{
uint h;
h = 0x811c9dc5;
while(*s != 0)
h = (h^(uchar)*s++) * 0x1000193;
return h % HASHSIZE;
}
void
addHash(Hash **hash, DicList *ditem)
{
Hash *h;
int v;
v = hashVal(ditem->kanahead);
h = (Hash*)malloc(sizeof(Hash));
h->dicindex = ditem;
h->length = strlen(ditem->kanahead);
h->next = hash[v];
hash[v] = h;
}
/*
* read Kouho list from the jisho file defined by Biobuf descriptor f
*
* revised for Plan 9 by K.Okamoto
*/
KouhoList *
getKouhoFile(DicList *dicitem, char * endstr)
{
char *kouhostart, *kouhoend;
KouhoList *kouhoitem, *currntkouhoitem=0, *prevkouhoitem;
prevkouhoitem = 0;
kouhostart = endstr + 1;
while((kouhoend = utfutf(kouhostart, " ")) ||
(kouhoend = utfutf(kouhostart, "\n"))) {
*kouhoend = '\0';
kouhoitem = (KouhoList*)malloc(sizeof(KouhoList)+(kouhoend-kouhostart+1));
kouhoitem->nextkouho = 0;
kouhoitem->prevkouho = prevkouhoitem;
kouhoitem->dicitem = dicitem;
strcpy(kouhoitem->kouhotop, kouhostart);
if (prevkouhoitem)
prevkouhoitem->nextkouho = kouhoitem;
else
currntkouhoitem = kouhoitem;
prevkouhoitem = kouhoitem;
kouhostart = kouhoend + 1;
}
return currntkouhoitem;
}
/*
* get matched kouho from the hash table of header word of the dict
* if found, returns pointer to the first candidate in the hash table.
* if not found, returns 0.
*
* from getCand() in skklib.c by Akinori Ito et al.,(aito@ei5sun.yz.yamagata-u.ac.jp)
*/
KouhoList *
getKouhoHash(Dictionary *dic, char *s)
{
int l, v;
Hash *h;
l = strlen(s);
v = hashVal(s);
for (h = dic->dhash[v]; h != 0; h = h->next) {
if (h->length != l ||
strcmp(h->dicindex->kanahead, s)) continue;
return h->dicindex->kouho; /* return matched kouho */
}
return 0;
}
/*
* from skklib.c by Akinori Ito et al.,(aito@ei5sun.yz.yamagata-u.ac.jp)
* just modified to read easier for current purpose
*/
void
selectKouho(KouhoList **first, KouhoList *current)
{
/* take off currentkouho from the kouholist table */
if (current->prevkouho) {
current->prevkouho->nextkouho = current->nextkouho;
if (current->nextkouho)
current->nextkouho->prevkouho = current->prevkouho;
current->prevkouho = 0;
}
/* take place of firstkouho by currentkouho */
if (*first != current) {
(*first)->prevkouho = current;
current->nextkouho = *first;
*first = current;
}
}

View file

@ -0,0 +1,41 @@
/*
* Kenji Okamoto August 4, 2000
* Osaka Prefecture Univ.
* okamoto@granite.cias.osakafu-u.ac.jp
*/
#define HASHSIZE 257
/*
* Structure for Dictionary's header word (in Hiragana)
*/
typedef struct DicList DicList;
struct DicList {
struct KouhoList *kouho;
struct DicList *nextitem; /* for a future extension */
char kanahead[1];
};
/*
* Structure for Kouho of each index word in the dictionary
*/
typedef struct KouhoList KouhoList;
struct KouhoList {
struct KouhoList *nextkouho;
struct KouhoList *prevkouho;
struct DicList *dicitem;
char kouhotop[1]; /* top of the kouhos */
} ;
typedef struct Hash Hash;
struct Hash {
DicList *dicindex; /* pointer to a KouhoList and kanahead etc */
short length;
struct Hash *next;
};
typedef struct Dictionary Dictionary;
struct Dictionary {
DicList *dlist; /* for a future extension, having more than one dictionaries */
Hash *dhash[HASHSIZE];
};

File diff suppressed because it is too large Load diff

View file

@ -6,26 +6,16 @@
* okamoto@granite.cias.osakafu-u.ac.jp
*/
/*
* A glossary on some of the Japanese vocabulary used:
* kana: syllabic letting, either hiragana() or katakana()
* kanji(): borrowed characters, in
* Okurigana(): kana tail to kanji, in
* Joshi(): particle, in
* Jisho(): dictionary
* kouho(): candidate
*/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "hash.h"
#include "ktrans.h"
#include "jisho.h"
#define LSIZE 256
Rune lbuf[LSIZE]; /* hiragana buffer for key input written by send() */
Hmap *table;
Map *table = hira; /* default language conversion table */
uchar okurigana[LSIZE]; /* buffer for okurigana */
char okuri = 0; /* buffer/flag for capital input char */
int in, out;
@ -33,10 +23,16 @@ int llen, olen, joshi = 0;
int natural = 1; /* not Japanese but English mode */
int changelang(int);
int dotrans(Hmap*);
int dotrans(Dictionary*);
int nrune(char *);
void send(uchar *, int);
Hmap* opendict(Hmap *, char *);
Map *match(uchar *p, int *nc, Map *table);
extern Dictionary *openQDIC(char *);
extern KouhoList *getKouhoHash(Dictionary*, char *);
extern KouhoList *getKouhoFile(DicList*, char *);
extern void freeQDIC(Dictionary*);
extern void selectKouho(KouhoList **, KouhoList*);
void
kbdopen(void)
@ -93,49 +89,6 @@ kbdopen(void)
exits(nil);
}
Map signalmore = {
"_", nil, 1,
};
Hmap*
initmap(Map *m, int n)
{
int i, j;
char buf[16];
char *s;
Map prev;
Hmap *h;
h = hmapalloc(n, sizeof(Map));
for(i = 0; i < n; i++){
if(m[i].roma == nil || m[i].roma[0] == '\0')
continue;
//We mark all partial strings so we know when
//we have partial match when ingesting.
j = 2;
for(s = m[i].roma; *s && j <= sizeof buf; s++){
snprint(buf, j, "%s", m[i].roma);
prev = m[i];
if(hmapget(h, buf, &prev) == 0){
if(prev.leadstomore == 1 && s[1] == '\0'){
//confict; partial & valid input
prev = m[i];
prev.leadstomore = 1;
}
}
if(s[1] == '\0'){
hmaprepl(&h, strdup(buf), &prev, nil, 1);
} else {
hmaprepl(&h, strdup(buf), &signalmore, nil, 1);
}
j++;
}
}
return h;
}
void
usage(void)
{
@ -148,11 +101,11 @@ main(int argc, char *argv[])
{
uchar *bp, *ep, buf[128];
Map lkup, last;
int wantmore;
Map *mp;
int nchar, wantmore;
int n, c;
char *jishoname, *zidianname;
Hmap *jisho, *zidian;
char *dictname;
Dictionary *jisho;
ARGBEGIN{
default: usage();
@ -160,20 +113,9 @@ main(int argc, char *argv[])
if(argc != 0)
usage();
if((jishoname = getenv("jisho")) == nil)
jishoname = "/lib/kanji.jisho";
jisho = opendict(nil, jishoname);
if((zidianname = getenv("zidian")) == nil)
zidianname = "/lib/hanzi.zidian";
zidian = opendict(nil, zidianname);
hira = table = initmap(mhira, nelem(mhira));
kata = initmap(mkata, nelem(mkata));
greek = initmap(mgreek, nelem(mgreek));
cyril = initmap(mcyril, nelem(mcyril));
hangul = initmap(mhangul, nelem(mhangul));
last = (Map){nil, nil, -1};
if((dictname = getenv("jisho")) == nil)
dictname = "/lib/kanji.jisho";
jisho = openQDIC(dictname);
kbdopen();
if(fork())
@ -205,8 +147,8 @@ main(int argc, char *argv[])
wantmore = 0;
if (*bp=='') { /* ^x read ktrans-jisho once more */
jisho = opendict(jisho, jishoname);
zidian = opendict(zidian, zidianname);
freeQDIC(jisho);
jisho = openQDIC(dictname);
llen = 0;
olen = okuri = joshi = 0;
wantmore=0;
@ -214,10 +156,7 @@ main(int argc, char *argv[])
continue;
}
if (*bp=='') { /* ^\ (start translation command) */
if (table == hanzi)
c = dotrans(zidian);
else
c = dotrans(jisho);
c = dotrans(jisho);
if (c)
*bp = c; /* pointer to translated rune */
else
@ -228,13 +167,11 @@ main(int argc, char *argv[])
bp++;
llen = 0;
olen = okuri = joshi = 0;
last.kana = nil;
continue;
}
if (changelang(*bp)) { /* change language mode OK */
bp++;
olen = okuri = joshi = 0;
last.kana = nil;
continue;
}
if (natural || *bp<=' ' || *bp>='{') { /* English mode but not ascii */
@ -242,7 +179,6 @@ main(int argc, char *argv[])
int rlen = chartorune(&r, (char *)bp);
send(bp, rlen); /* write bp to /dev/cons */
bp += rlen;
last.kana = nil;
continue;
}
if (table == hira && (*bp >= 'A' && *bp <= 'Z') && (*(bp+1) < 'A'
@ -256,33 +192,27 @@ main(int argc, char *argv[])
joshi = 1;
olen = 0;
}
if(hmapget(table, (char*)bp, &lkup) < 0){
if(last.kana != nil){
send((uchar*)last.kana, strlen(last.kana));
bp += strlen(last.roma);
} else
send(bp++, 1);
last.kana = nil;
break;
mp = match(bp, &nchar, table);
if (mp == 0) {
if (nchar>0) { /* match, longer possible */
wantmore++;
break;
}
send(bp++, 1); /* alphabet in kana mode */
} else {
send((uchar*)mp->kana, strlen(mp->kana));
bp += nchar;
}
/* concatinations; only advance a single character */
if(lkup.kana != nil && strstr("ッっ", lkup.kana))
lkup.roma = "_";
/* partial match */
if(lkup.kana == nil || lkup.leadstomore == 1){
if(lkup.kana != nil)
last = lkup;
wantmore = 1;
break;
}
last.kana = nil;
send((uchar*)lkup.kana, strlen(lkup.kana));
bp += strlen(lkup.roma);
}
}
}
int
min(int a, int b)
{
return a<b? a: b;
}
/*
* send UTF string (p) with length (n) to stdout
* and write rune (r) in global lbuf[] buffer
@ -302,9 +232,7 @@ send(uchar *p, int n)
llen -= 64;
}
if(table != hira && table != hanzi)
return;
if(natural && table != hanzi)
if (table!=hira || natural)
return;
ep = p+n;
@ -325,13 +253,49 @@ send(uchar *p, int n)
}
}
/*
* Romaji to Hiragana/Katakana conversion
* romaji shoud be input as small letter
* returns the matched address in table, hira, kata, etc.
* nc: number of character (return value)
*/
Map *
match(uchar *p, int *nc, Map *table)
{
register Map *longp = 0, *kp;
static char last;
int longest = 0;
*nc = -1;
for (kp=table; kp->roma; kp++) {
if (*p == *kp->roma) {
int lr = strlen(kp->roma);
int len = min(lr, strlen((char *)p));
if (strncmp(kp->roma, (char *)p, len)==0) {
if (len<lr) {
*nc = 1;
return 0;
}
if (len>longest) {
longest = len;
longp = kp;
}
}
}
}
if (longp) {
last = longp->roma[longest-1];
*nc = longp->advance;
}
return longp;
}
int
changelang(int c)
{
switch(c){
case '': /* ^t (English mode) */
natural = 1;
table = hira;
llen = 0;
return 1;
break;
@ -370,80 +334,23 @@ changelang(int c)
llen = 0;
return 1;
break;
case '': /* ^c (Chinese mode) */
natural = 1;
table = hanzi;
llen = 0;
return 1;
break;
}
return 0;
}
Hmap*
opendict(Hmap *h, char *name)
{
Biobuf *b;
char *p;
char *dot, *rest;
char *kouho[16];
int i;
b = Bopen(name, OREAD);
if(b == nil)
return nil;
if(h == nil)
h = hmapalloc(8192, sizeof(kouho));
else
hmapreset(h, 1);
while(p = Brdstr(b, '\n', 1)){
if(p[0] == '\0' || p[0] == ';'){
Err:
free(p);
continue;
}
dot = utfrune(p, '\t');
if(dot == nil)
goto Err;
*dot = '\0';
rest = dot+1;
if(*rest == '\0')
goto Err;
memset(kouho, 0, sizeof kouho);
i = 0;
while(i < nelem(kouho)-1 && (dot = utfrune(rest, ' '))){
*dot = '\0';
kouho[i++] = rest;
rest = dot+1;
}
if(i < nelem(kouho)-1)
kouho[i] = rest;
/* key is the base pointer; overwrites clean up for us */
hmaprepl(&h, p, kouho, nil, 1);
}
Bterm(b);
return h;
}
/*
* write translated kanji runes to stdout and return last character
* if it's not ctl-\. if the last is ctl-\, proceed with
* translation of the next kouho
*/
int
dotrans(Hmap *dic)
dotrans(Dictionary *dic)
{
Rune *res, r[1];
char v[1024], *p, tbuf[64], hirabuf[64];
int j, lastlen, nokouho = 0;
char ch;
int i;
char *kouho[16];
KouhoList *fstkouho, *currentkouho;
if (llen==0)
return 0; /* don't use kanji transform function */
@ -468,13 +375,15 @@ dotrans(Hmap *dic)
if (okuri && joshi != 1) /* verb mode */
hirabuf[strlen(hirabuf) - 1] = '\0';
if(hmapget(dic, v, kouho) < 0){
if(!(fstkouho = getKouhoHash(dic, v))) { /* not found */
llen = olen = okuri = joshi = 0;
okurigana[0] = 0;
return 0;
}
for(i = 0; i < nelem(kouho) && kouho[i] != nil; i++) {
p = kouho[i];
currentkouho = fstkouho;
for(;;) {
p = currentkouho->kouhotop; /* p to the head of kanji kouho array */
lastlen = nrune(tbuf); /* number of rune chars */
if (okuri && joshi != 1) /* verb mode */
@ -498,9 +407,10 @@ dotrans(Hmap *dic)
exits(nil);
if (ch == '') { /* if next input is ^\, once again */
if(i+1 < nelem(kouho) && kouho[i+1] != nil) { /* have next kouho */
if(currentkouho->nextkouho != 0) { /* have next kouho */
nokouho = 0;
strcpy(tbuf, p);
currentkouho = currentkouho->nextkouho;
if (okuri && joshi != 1) /* verb mode */
for (j=0; j<nrune(tbuf); j++)
@ -532,12 +442,8 @@ dotrans(Hmap *dic)
break;
}
} else {
if(!nokouho && i != 0){ /* learn the previous use of the kouho */
p = kouho[0];
kouho[0] = kouho[i];
kouho[i] = p;
hmapupd(&dic, v, kouho);
}
if(!nokouho) /* learn the previous use of the kouho */
selectKouho(&(fstkouho->dicitem->kouho), currentkouho);
olen = okuri = joshi = 0;
okurigana[0] = 0;

View file

@ -2,9 +2,9 @@
BIN=/$objtype/bin
TARG=ktrans
HFILES=ktrans.h
HFILES=jisho.h ktrans.h
OFILES=\
hash.$O\
main.$O\
jisho.$O
</sys/src/cmd/mkone

View file

@ -608,8 +608,6 @@ redraw(void)
for(j=0; j<nhidden; j++)
if(w == hidden[j])
break;
memmove(w->cols, &cols[BACK], sizeof(w->cols));
frinittick(w);
incref(w);
if(j < nhidden){

View file

@ -802,8 +802,6 @@ changemesg(Plumbmsg *pm)
digest = plumblookup(pm->attr, "digest");
action = plumblookup(pm->attr, "mailtype");
if(digest == nil || action == nil)
return;
if(strcmp(action, "new") == 0){
if((m = load(pm->data, digest, 1)) == nil)
return;

View file

@ -1,4 +1,4 @@
<div class="left">
<div class="left>
<a href="https://owen.bellz.org">escape</a> |
<a href="//withdrawal.owen.bellz.org">withdrawal</a>
</div>