mirror of
https://github.com/golang/go
synced 2024-10-14 03:43:28 +00:00
import the plan 9 libraries libc (lib9) and libbio into the tree.
remove the dependency on /home/r. SVN=122482
This commit is contained in:
parent
a40a79829f
commit
69b74c3953
117
include/bio.h
Normal file
117
include/bio.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/include/bio.h
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _BIO_H_
|
||||
#define _BIO_H_ 1
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef AUTOLIB
|
||||
AUTOLIB(bio)
|
||||
#endif
|
||||
|
||||
#include <sys/types.h> /* for off_t */
|
||||
#include <fcntl.h> /* for O_RDONLY, O_WRONLY */
|
||||
|
||||
typedef struct Biobuf Biobuf;
|
||||
|
||||
enum
|
||||
{
|
||||
Bsize = 8*1024,
|
||||
Bungetsize = 4, /* space for ungetc */
|
||||
Bmagic = 0x314159,
|
||||
Beof = -1,
|
||||
Bbad = -2,
|
||||
|
||||
Binactive = 0, /* states */
|
||||
Bractive,
|
||||
Bwactive,
|
||||
Bracteof,
|
||||
|
||||
Bend
|
||||
};
|
||||
|
||||
struct Biobuf
|
||||
{
|
||||
int icount; /* neg num of bytes at eob */
|
||||
int ocount; /* num of bytes at bob */
|
||||
int rdline; /* num of bytes after rdline */
|
||||
int runesize; /* num of bytes of last getrune */
|
||||
int state; /* r/w/inactive */
|
||||
int fid; /* open file */
|
||||
int flag; /* magic if malloc'ed */
|
||||
off_t offset; /* offset of buffer in file */
|
||||
int bsize; /* size of buffer */
|
||||
unsigned char* bbuf; /* pointer to beginning of buffer */
|
||||
unsigned char* ebuf; /* pointer to end of buffer */
|
||||
unsigned char* gbuf; /* pointer to good data in buf */
|
||||
unsigned char b[Bungetsize+Bsize];
|
||||
};
|
||||
|
||||
#define BGETC(bp)\
|
||||
((bp)->icount?(bp)->bbuf[(bp)->bsize+(bp)->icount++]:Bgetc((bp)))
|
||||
#define BPUTC(bp,c)\
|
||||
((bp)->ocount?(bp)->bbuf[(bp)->bsize+(bp)->ocount++]=(c),0:Bputc((bp),(c)))
|
||||
#define BOFFSET(bp)\
|
||||
(((bp)->state==Bractive)?\
|
||||
(bp)->offset + (bp)->icount:\
|
||||
(((bp)->state==Bwactive)?\
|
||||
(bp)->offset + ((bp)->bsize + (bp)->ocount):\
|
||||
-1))
|
||||
#define BLINELEN(bp)\
|
||||
(bp)->rdline
|
||||
#define BFILDES(bp)\
|
||||
(bp)->fid
|
||||
|
||||
int Bbuffered(Biobuf*);
|
||||
Biobuf* Bfdopen(int, int);
|
||||
int Bfildes(Biobuf*);
|
||||
int Bflush(Biobuf*);
|
||||
int Bgetc(Biobuf*);
|
||||
int Bgetd(Biobuf*, double*);
|
||||
long Bgetrune(Biobuf*);
|
||||
int Binit(Biobuf*, int, int);
|
||||
int Binits(Biobuf*, int, int, unsigned char*, int);
|
||||
int Blinelen(Biobuf*);
|
||||
off_t Boffset(Biobuf*);
|
||||
Biobuf* Bopen(char*, int);
|
||||
int Bprint(Biobuf*, char*, ...);
|
||||
int Bputc(Biobuf*, int);
|
||||
int Bputrune(Biobuf*, long);
|
||||
void* Brdline(Biobuf*, int);
|
||||
char* Brdstr(Biobuf*, int, int);
|
||||
long Bread(Biobuf*, void*, long);
|
||||
off_t Bseek(Biobuf*, off_t, int);
|
||||
int Bterm(Biobuf*);
|
||||
int Bungetc(Biobuf*);
|
||||
int Bungetrune(Biobuf*);
|
||||
long Bwrite(Biobuf*, void*, long);
|
||||
int Bvprint(Biobuf*, char*, va_list);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
116
include/fmt.h
Normal file
116
include/fmt.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
#ifndef _FMT_H_
|
||||
#define _FMT_H_ 1
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <utf.h>
|
||||
|
||||
typedef struct Fmt Fmt;
|
||||
struct Fmt{
|
||||
unsigned char runes; /* output buffer is runes or chars? */
|
||||
void *start; /* of buffer */
|
||||
void *to; /* current place in the buffer */
|
||||
void *stop; /* end of the buffer; overwritten if flush fails */
|
||||
int (*flush)(Fmt *); /* called when to == stop */
|
||||
void *farg; /* to make flush a closure */
|
||||
int nfmt; /* num chars formatted so far */
|
||||
va_list args; /* args passed to dofmt */
|
||||
int r; /* % format Rune */
|
||||
int width;
|
||||
int prec;
|
||||
unsigned long flags;
|
||||
char *decimal; /* decimal point; cannot be "" */
|
||||
|
||||
/* For %'d */
|
||||
char *thousands; /* separator for thousands */
|
||||
|
||||
/*
|
||||
* Each char is an integer indicating #digits before next separator. Values:
|
||||
* \xFF: no more grouping (or \x7F; defined to be CHAR_MAX in POSIX)
|
||||
* \x00: repeat previous indefinitely
|
||||
* \x**: count that many
|
||||
*/
|
||||
char *grouping; /* descriptor of separator placement */
|
||||
};
|
||||
|
||||
enum{
|
||||
FmtWidth = 1,
|
||||
FmtLeft = FmtWidth << 1,
|
||||
FmtPrec = FmtLeft << 1,
|
||||
FmtSharp = FmtPrec << 1,
|
||||
FmtSpace = FmtSharp << 1,
|
||||
FmtSign = FmtSpace << 1,
|
||||
FmtApost = FmtSign << 1,
|
||||
FmtZero = FmtApost << 1,
|
||||
FmtUnsigned = FmtZero << 1,
|
||||
FmtShort = FmtUnsigned << 1,
|
||||
FmtLong = FmtShort << 1,
|
||||
FmtVLong = FmtLong << 1,
|
||||
FmtComma = FmtVLong << 1,
|
||||
FmtByte = FmtComma << 1,
|
||||
FmtLDouble = FmtByte << 1,
|
||||
|
||||
FmtFlag = FmtLDouble << 1
|
||||
};
|
||||
|
||||
extern int (*fmtdoquote)(int);
|
||||
|
||||
/* Edit .+1,/^$/ | cfn $PLAN9/src/lib9/fmt/?*.c | grep -v static |grep -v __ */
|
||||
int dofmt(Fmt *f, char *fmt);
|
||||
int dorfmt(Fmt *f, const Rune *fmt);
|
||||
double fmtcharstod(int(*f)(void*), void *vp);
|
||||
int fmtfdflush(Fmt *f);
|
||||
int fmtfdinit(Fmt *f, int fd, char *buf, int size);
|
||||
int fmtinstall(int c, int (*f)(Fmt*));
|
||||
int fmtnullinit(Fmt*);
|
||||
void fmtlocaleinit(Fmt*, char*, char*, char*);
|
||||
int fmtprint(Fmt *f, char *fmt, ...);
|
||||
int fmtrune(Fmt *f, int r);
|
||||
int fmtrunestrcpy(Fmt *f, Rune *s);
|
||||
int fmtstrcpy(Fmt *f, char *s);
|
||||
char* fmtstrflush(Fmt *f);
|
||||
int fmtstrinit(Fmt *f);
|
||||
double fmtstrtod(const char *as, char **aas);
|
||||
int fmtvprint(Fmt *f, char *fmt, va_list args);
|
||||
int fprint(int fd, char *fmt, ...);
|
||||
int print(char *fmt, ...);
|
||||
void quotefmtinstall(void);
|
||||
int quoterunestrfmt(Fmt *f);
|
||||
int quotestrfmt(Fmt *f);
|
||||
Rune* runefmtstrflush(Fmt *f);
|
||||
int runefmtstrinit(Fmt *f);
|
||||
Rune* runeseprint(Rune *buf, Rune *e, char *fmt, ...);
|
||||
Rune* runesmprint(char *fmt, ...);
|
||||
int runesnprint(Rune *buf, int len, char *fmt, ...);
|
||||
int runesprint(Rune *buf, char *fmt, ...);
|
||||
Rune* runevseprint(Rune *buf, Rune *e, char *fmt, va_list args);
|
||||
Rune* runevsmprint(char *fmt, va_list args);
|
||||
int runevsnprint(Rune *buf, int len, char *fmt, va_list args);
|
||||
char* seprint(char *buf, char *e, char *fmt, ...);
|
||||
char* smprint(char *fmt, ...);
|
||||
int snprint(char *buf, int len, char *fmt, ...);
|
||||
int sprint(char *buf, char *fmt, ...);
|
||||
int vfprint(int fd, char *fmt, va_list args);
|
||||
char* vseprint(char *buf, char *e, char *fmt, va_list args);
|
||||
char* vsmprint(char *fmt, va_list args);
|
||||
int vsnprint(char *buf, int len, char *fmt, va_list args);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
364
include/libc.h
Normal file
364
include/libc.h
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
Derived from Inferno include/kern.h and
|
||||
Plan 9 from User Space include/libc.h
|
||||
|
||||
http://code.google.com/p/inferno-os/source/browse/include/kern.h
|
||||
http://code.swtch.com/plan9port/src/tip/include/libc.h
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
Portions Copyright © 2001-2007 Russ Cox. All rights reserved.
|
||||
Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Lib9 is miscellany from the Plan 9 C library that doesn't
|
||||
* fit into libutf or into libfmt, but is still missing from traditional
|
||||
* Unix C libraries.
|
||||
*/
|
||||
#ifndef _LIBC_H_
|
||||
#define _LIBC_H_ 1
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <utf.h>
|
||||
#include <fmt.h>
|
||||
|
||||
/*
|
||||
* Begin trimmed down usual libc.h
|
||||
*/
|
||||
|
||||
#ifndef nil
|
||||
#define nil ((void*)0)
|
||||
#endif
|
||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(s, m) (ulong)(&(((s*)0)->m))
|
||||
#endif
|
||||
|
||||
extern char* strecpy(char*, char*, char*);
|
||||
extern int tokenize(char*, char**, int);
|
||||
|
||||
extern double p9cputime(void);
|
||||
#ifndef NOPLAN9DEFINES
|
||||
#define cputime p9cputime
|
||||
#endif
|
||||
/*
|
||||
* one-of-a-kind
|
||||
*/
|
||||
enum
|
||||
{
|
||||
PNPROC = 1,
|
||||
PNGROUP = 2
|
||||
};
|
||||
int isInf(double, int);
|
||||
|
||||
extern int p9atoi(char*);
|
||||
extern long p9atol(char*);
|
||||
extern vlong p9atoll(char*);
|
||||
extern double fmtcharstod(int(*)(void*), void*);
|
||||
extern char* cleanname(char*);
|
||||
extern int exitcode(char*);
|
||||
extern void exits(char*);
|
||||
extern double frexp(double, int*);
|
||||
extern char* p9getenv(char*);
|
||||
extern int p9putenv(char*, char*);
|
||||
extern int getfields(char*, char**, int, int, char*);
|
||||
extern int gettokens(char *, char **, int, char *);
|
||||
extern char* getuser(void);
|
||||
extern char* p9getwd(char*, int);
|
||||
extern void p9longjmp(p9jmp_buf, int);
|
||||
extern char* mktemp(char*);
|
||||
extern int opentemp(char*);
|
||||
extern void p9notejmp(void*, p9jmp_buf, int);
|
||||
extern void perror(const char*);
|
||||
extern int postnote(int, int, char *);
|
||||
extern double p9pow10(int);
|
||||
extern char* searchpath(char*);
|
||||
#define p9setjmp(b) sigsetjmp((void*)(b), 1)
|
||||
|
||||
extern void sysfatal(char*, ...);
|
||||
|
||||
#ifndef NOPLAN9DEFINES
|
||||
#define atoi p9atoi
|
||||
#define atol p9atol
|
||||
#define atoll p9atoll
|
||||
#define getenv p9getenv
|
||||
#define getwd p9getwd
|
||||
#define longjmp p9longjmp
|
||||
#undef setjmp
|
||||
#define setjmp p9setjmp
|
||||
#define putenv p9putenv
|
||||
#define notejmp p9notejmp
|
||||
#define jmp_buf p9jmp_buf
|
||||
#define pow10 p9pow10
|
||||
#define strtod fmtstrtod
|
||||
#define charstod fmtcharstod
|
||||
#endif
|
||||
|
||||
/*
|
||||
* system calls
|
||||
*
|
||||
*/
|
||||
#define STATMAX 65535U /* max length of machine-independent stat structure */
|
||||
#define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */
|
||||
#define ERRMAX 128 /* max length of error string */
|
||||
|
||||
#define MORDER 0x0003 /* mask for bits defining order of mounting */
|
||||
#define MREPL 0x0000 /* mount replaces object */
|
||||
#define MBEFORE 0x0001 /* mount goes before others in union directory */
|
||||
#define MAFTER 0x0002 /* mount goes after others in union directory */
|
||||
#define MCREATE 0x0004 /* permit creation in mounted directory */
|
||||
#define MCACHE 0x0010 /* cache some data */
|
||||
#define MMASK 0x0017 /* all bits on */
|
||||
|
||||
#define OREAD 0 /* open for read */
|
||||
#define OWRITE 1 /* write */
|
||||
#define ORDWR 2 /* read and write */
|
||||
#define OEXEC 3 /* execute, == read but check execute permission */
|
||||
#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
|
||||
#define OCEXEC 32 /* or'ed in, close on exec */
|
||||
#define ORCLOSE 64 /* or'ed in, remove on close */
|
||||
#define ODIRECT 128 /* or'ed in, direct access */
|
||||
#define ONONBLOCK 256 /* or'ed in, non-blocking call */
|
||||
#define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */
|
||||
#define OLOCK 0x2000 /* or'ed in, lock after opening */
|
||||
#define OAPPEND 0x4000 /* or'ed in, append only */
|
||||
|
||||
#define AEXIST 0 /* accessible: exists */
|
||||
#define AEXEC 1 /* execute access */
|
||||
#define AWRITE 2 /* write access */
|
||||
#define AREAD 4 /* read access */
|
||||
|
||||
/* Segattch */
|
||||
#define SG_RONLY 0040 /* read only */
|
||||
#define SG_CEXEC 0100 /* detach on exec */
|
||||
|
||||
#define NCONT 0 /* continue after note */
|
||||
#define NDFLT 1 /* terminate after note */
|
||||
#define NSAVE 2 /* clear note but hold state */
|
||||
#define NRSTR 3 /* restore saved state */
|
||||
|
||||
/* bits in Qid.type */
|
||||
#define QTDIR 0x80 /* type bit for directories */
|
||||
#define QTAPPEND 0x40 /* type bit for append only files */
|
||||
#define QTEXCL 0x20 /* type bit for exclusive use files */
|
||||
#define QTMOUNT 0x10 /* type bit for mounted channel */
|
||||
#define QTAUTH 0x08 /* type bit for authentication file */
|
||||
#define QTTMP 0x04 /* type bit for non-backed-up file */
|
||||
#define QTSYMLINK 0x02 /* type bit for symbolic link */
|
||||
#define QTFILE 0x00 /* type bits for plain file */
|
||||
|
||||
/* bits in Dir.mode */
|
||||
#define DMDIR 0x80000000 /* mode bit for directories */
|
||||
#define DMAPPEND 0x40000000 /* mode bit for append only files */
|
||||
#define DMEXCL 0x20000000 /* mode bit for exclusive use files */
|
||||
#define DMMOUNT 0x10000000 /* mode bit for mounted channel */
|
||||
#define DMAUTH 0x08000000 /* mode bit for authentication file */
|
||||
#define DMTMP 0x04000000 /* mode bit for non-backed-up file */
|
||||
#define DMSYMLINK 0x02000000 /* mode bit for symbolic link (Unix, 9P2000.u) */
|
||||
#define DMDEVICE 0x00800000 /* mode bit for device file (Unix, 9P2000.u) */
|
||||
#define DMNAMEDPIPE 0x00200000 /* mode bit for named pipe (Unix, 9P2000.u) */
|
||||
#define DMSOCKET 0x00100000 /* mode bit for socket (Unix, 9P2000.u) */
|
||||
#define DMSETUID 0x00080000 /* mode bit for setuid (Unix, 9P2000.u) */
|
||||
#define DMSETGID 0x00040000 /* mode bit for setgid (Unix, 9P2000.u) */
|
||||
|
||||
#define DMREAD 0x4 /* mode bit for read permission */
|
||||
#define DMWRITE 0x2 /* mode bit for write permission */
|
||||
#define DMEXEC 0x1 /* mode bit for execute permission */
|
||||
|
||||
#ifdef RFMEM /* FreeBSD, OpenBSD */
|
||||
#undef RFFDG
|
||||
#undef RFNOTEG
|
||||
#undef RFPROC
|
||||
#undef RFMEM
|
||||
#undef RFNOWAIT
|
||||
#undef RFCFDG
|
||||
#undef RFNAMEG
|
||||
#undef RFENVG
|
||||
#undef RFCENVG
|
||||
#undef RFCFDG
|
||||
#undef RFCNAMEG
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
RFNAMEG = (1<<0),
|
||||
RFENVG = (1<<1),
|
||||
RFFDG = (1<<2),
|
||||
RFNOTEG = (1<<3),
|
||||
RFPROC = (1<<4),
|
||||
RFMEM = (1<<5),
|
||||
RFNOWAIT = (1<<6),
|
||||
RFCNAMEG = (1<<10),
|
||||
RFCENVG = (1<<11),
|
||||
RFCFDG = (1<<12)
|
||||
/* RFREND = (1<<13), */
|
||||
/* RFNOMNT = (1<<14) */
|
||||
};
|
||||
|
||||
typedef
|
||||
struct Qid
|
||||
{
|
||||
uvlong path;
|
||||
ulong vers;
|
||||
uchar type;
|
||||
} Qid;
|
||||
|
||||
typedef
|
||||
struct Dir {
|
||||
/* system-modified data */
|
||||
ushort type; /* server type */
|
||||
uint dev; /* server subtype */
|
||||
/* file data */
|
||||
Qid qid; /* unique id from server */
|
||||
ulong mode; /* permissions */
|
||||
ulong atime; /* last read time */
|
||||
ulong mtime; /* last write time */
|
||||
vlong length; /* file length */
|
||||
char *name; /* last element of path */
|
||||
char *uid; /* owner name */
|
||||
char *gid; /* group name */
|
||||
char *muid; /* last modifier name */
|
||||
|
||||
/* 9P2000.u extensions */
|
||||
uint uidnum; /* numeric uid */
|
||||
uint gidnum; /* numeric gid */
|
||||
uint muidnum; /* numeric muid */
|
||||
char *ext; /* extended info */
|
||||
} Dir;
|
||||
|
||||
typedef
|
||||
struct Waitmsg
|
||||
{
|
||||
int pid; /* of loved one */
|
||||
ulong time[3]; /* of loved one & descendants */
|
||||
char *msg;
|
||||
} Waitmsg;
|
||||
|
||||
extern void _exits(char*);
|
||||
|
||||
extern void abort(void);
|
||||
extern long p9alarm(ulong);
|
||||
extern int await(char*, int);
|
||||
extern int awaitfor(int, char*, int);
|
||||
extern int awaitnohang(char*, int);
|
||||
extern int p9chdir(char*);
|
||||
extern int close(int);
|
||||
extern int p9create(char*, int, ulong);
|
||||
extern int p9dup(int, int);
|
||||
extern int errstr(char*, uint);
|
||||
extern int p9exec(char*, char*[]);
|
||||
extern int p9execl(char*, ...);
|
||||
extern int p9rfork(int);
|
||||
extern int noted(int);
|
||||
extern int notify(void(*)(void*, char*));
|
||||
extern int noteenable(char*);
|
||||
extern int notedisable(char*);
|
||||
extern int notifyon(char*);
|
||||
extern int notifyoff(char*);
|
||||
extern int p9open(char*, int);
|
||||
extern int fd2path(int, char*, int);
|
||||
extern int p9pipe(int*);
|
||||
extern long readn(int, void*, long);
|
||||
extern int remove(const char*);
|
||||
extern vlong p9seek(int, vlong, int);
|
||||
extern int p9sleep(long);
|
||||
extern Waitmsg* p9wait(void);
|
||||
extern Waitmsg* p9waitfor(int);
|
||||
extern Waitmsg* waitnohang(void);
|
||||
extern int p9waitpid(void);
|
||||
extern ulong rendezvous(ulong, ulong);
|
||||
|
||||
#ifndef NOPLAN9DEFINES
|
||||
#define alarm p9alarm
|
||||
#define dup p9dup
|
||||
#define exec p9exec
|
||||
#define execl p9execl
|
||||
#define seek p9seek
|
||||
#define sleep p9sleep
|
||||
#define wait p9wait
|
||||
#define waitpid p9waitpid
|
||||
#define rfork p9rfork
|
||||
#define create p9create
|
||||
#undef open
|
||||
#define open p9open
|
||||
#define pipe p9pipe
|
||||
#define waitfor p9waitfor
|
||||
#endif
|
||||
|
||||
extern Dir* dirstat(char*);
|
||||
extern Dir* dirfstat(int);
|
||||
extern int dirwstat(char*, Dir*);
|
||||
extern int dirfwstat(int, Dir*);
|
||||
extern void nulldir(Dir*);
|
||||
extern long dirreadall(int, Dir**);
|
||||
extern void rerrstr(char*, uint);
|
||||
extern char* sysname(void);
|
||||
extern void werrstr(char*, ...);
|
||||
extern char* getns(void);
|
||||
extern char* get9root(void);
|
||||
extern char* unsharp(char*);
|
||||
|
||||
/* external names that we don't want to step on */
|
||||
#ifndef NOPLAN9DEFINES
|
||||
#define main p9main
|
||||
#endif
|
||||
|
||||
/* compiler directives on plan 9 */
|
||||
#define SET(x) ((x)=0)
|
||||
#define USED(x) if(x){}else{}
|
||||
#ifdef __GNUC__
|
||||
# if __GNUC__ >= 3
|
||||
# undef USED
|
||||
# define USED(x) ((void)(x))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* command line */
|
||||
extern char *argv0;
|
||||
extern void __fixargv0(void);
|
||||
#define ARGBEGIN for((argv0?0:(argv0=(__fixargv0(),*argv))),argv++,argc--;\
|
||||
argv[0] && argv[0][0]=='-' && argv[0][1];\
|
||||
argc--, argv++) {\
|
||||
char *_args, *_argt;\
|
||||
Rune _argc;\
|
||||
_args = &argv[0][1];\
|
||||
if(_args[0]=='-' && _args[1]==0){\
|
||||
argc--; argv++; break;\
|
||||
}\
|
||||
_argc = 0;\
|
||||
while(*_args && (_args += chartorune(&_argc, _args)))\
|
||||
switch(_argc)
|
||||
#define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc);
|
||||
#define ARGF() (_argt=_args, _args="",\
|
||||
(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
|
||||
#define EARGF(x) (_argt=_args, _args="",\
|
||||
(*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
|
||||
|
||||
#define ARGC() _argc
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* _LIB9_H_ */
|
208
include/u.h
Normal file
208
include/u.h
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
Plan 9 from User Space include/u.h
|
||||
http://code.swtch.com/plan9port/src/tip/include/u.h
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _U_H_
|
||||
#define _U_H_ 1
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define __BSD_VISIBLE 1 /* FreeBSD 5.x */
|
||||
#if defined(__sun__)
|
||||
# define __EXTENSIONS__ 1 /* SunOS */
|
||||
# if defined(__SunOS5_6__) || defined(__SunOS5_7__) || defined(__SunOS5_8__)
|
||||
/* NOT USING #define __MAKECONTEXT_V2_SOURCE 1 / * SunOS */
|
||||
# else
|
||||
# define __MAKECONTEXT_V2_SOURCE 1
|
||||
# endif
|
||||
#endif
|
||||
#define _BSD_SOURCE 1
|
||||
#define _NETBSD_SOURCE 1 /* NetBSD */
|
||||
#define _SVID_SOURCE 1
|
||||
#if !defined(__APPLE__) && !defined(__OpenBSD__)
|
||||
# define _XOPEN_SOURCE 1000
|
||||
# define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
# include <sys/cdefs.h>
|
||||
/* for strtoll */
|
||||
# undef __ISO_C_VISIBLE
|
||||
# define __ISO_C_VISIBLE 1999
|
||||
# undef __LONG_LONG_SUPPORTED
|
||||
# define __LONG_LONG_SUPPORTED
|
||||
#endif
|
||||
#define _LARGEFILE64_SOURCE 1
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <setjmp.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h> /* for tolower */
|
||||
|
||||
/*
|
||||
* OS-specific crap
|
||||
*/
|
||||
#define _NEEDUCHAR 1
|
||||
#define _NEEDUSHORT 1
|
||||
#define _NEEDUINT 1
|
||||
#define _NEEDULONG 1
|
||||
|
||||
typedef long p9jmp_buf[sizeof(sigjmp_buf)/sizeof(long)];
|
||||
|
||||
#if defined(__linux__)
|
||||
# include <sys/types.h>
|
||||
# if defined(__Linux26__)
|
||||
# include <pthread.h>
|
||||
# define PLAN9PORT_USING_PTHREADS 1
|
||||
# endif
|
||||
# if defined(__USE_MISC)
|
||||
# undef _NEEDUSHORT
|
||||
# undef _NEEDUINT
|
||||
# undef _NEEDULONG
|
||||
# endif
|
||||
#elif defined(__sun__)
|
||||
# include <sys/types.h>
|
||||
# include <pthread.h>
|
||||
# define PLAN9PORT_USING_PTHREADS 1
|
||||
# undef _NEEDUSHORT
|
||||
# undef _NEEDUINT
|
||||
# undef _NEEDULONG
|
||||
# define nil 0 /* no cast to void* */
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <sys/types.h>
|
||||
# include <osreldate.h>
|
||||
# if __FreeBSD_version >= 500000
|
||||
# define PLAN9PORT_USING_PTHREADS 1
|
||||
# include <pthread.h>
|
||||
# endif
|
||||
# if !defined(_POSIX_SOURCE)
|
||||
# undef _NEEDUSHORT
|
||||
# undef _NEEDUINT
|
||||
# endif
|
||||
#elif defined(__APPLE__)
|
||||
# include <sys/types.h>
|
||||
# include <pthread.h>
|
||||
# define PLAN9PORT_USING_PTHREADS 1
|
||||
# if __GNUC__ < 4
|
||||
# undef _NEEDUSHORT
|
||||
# undef _NEEDUINT
|
||||
# endif
|
||||
# undef _ANSI_SOURCE
|
||||
# undef _POSIX_C_SOURCE
|
||||
# undef _XOPEN_SOURCE
|
||||
# if !defined(NSIG)
|
||||
# define NSIG 32
|
||||
# endif
|
||||
# define _NEEDLL 1
|
||||
#elif defined(__NetBSD__)
|
||||
# include <sched.h>
|
||||
# include <sys/types.h>
|
||||
# undef _NEEDUSHORT
|
||||
# undef _NEEDUINT
|
||||
# undef _NEEDULONG
|
||||
#elif defined(__OpenBSD__)
|
||||
# include <sys/types.h>
|
||||
# undef _NEEDUSHORT
|
||||
# undef _NEEDUINT
|
||||
# undef _NEEDULONG
|
||||
#else
|
||||
/* No idea what system this is -- try some defaults */
|
||||
# include <pthread.h>
|
||||
# define PLAN9PORT_USING_PTHREADS 1
|
||||
#endif
|
||||
|
||||
#ifndef O_DIRECT
|
||||
#define O_DIRECT 0
|
||||
#endif
|
||||
|
||||
typedef signed char schar;
|
||||
|
||||
#ifdef _NEEDUCHAR
|
||||
typedef unsigned char uchar;
|
||||
#endif
|
||||
#ifdef _NEEDUSHORT
|
||||
typedef unsigned short ushort;
|
||||
#endif
|
||||
#ifdef _NEEDUINT
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
#ifdef _NEEDULONG
|
||||
typedef unsigned long ulong;
|
||||
#endif
|
||||
typedef unsigned long long uvlong;
|
||||
typedef long long vlong;
|
||||
|
||||
typedef uint64_t u64int;
|
||||
typedef int64_t s64int;
|
||||
typedef uint8_t u8int;
|
||||
typedef int8_t s8int;
|
||||
typedef uint16_t u16int;
|
||||
typedef int16_t s16int;
|
||||
typedef uintptr_t uintptr;
|
||||
typedef intptr_t intptr;
|
||||
typedef uint32_t u32int;
|
||||
typedef int32_t s32int;
|
||||
|
||||
#undef _NEEDUCHAR
|
||||
#undef _NEEDUSHORT
|
||||
#undef _NEEDUINT
|
||||
#undef _NEEDULONG
|
||||
|
||||
/*
|
||||
* Funny-named symbols to tip off 9l to autolink.
|
||||
*/
|
||||
#define AUTOLIB(x) static int __p9l_autolib_ ## x = 1;
|
||||
#define AUTOFRAMEWORK(x) static int __p9l_autoframework_ ## x = 1;
|
||||
|
||||
/*
|
||||
* Gcc is too smart for its own good.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
# undef strcmp /* causes way too many warnings */
|
||||
# if __GNUC__ >= 4 || (__GNUC__==3 && !defined(__APPLE_CC__))
|
||||
# undef AUTOLIB
|
||||
# define AUTOLIB(x) int __p9l_autolib_ ## x __attribute__ ((weak));
|
||||
# undef AUTOFRAMEWORK
|
||||
# define AUTOFRAMEWORK(x) int __p9l_autoframework_ ## x __attribute__ ((weak));
|
||||
# else
|
||||
# undef AUTOLIB
|
||||
# define AUTOLIB(x) static int __p9l_autolib_ ## x __attribute__ ((unused));
|
||||
# undef AUTOFRAMEWORK
|
||||
# define AUTOFRAMEWORK(x) static int __p9l_autoframework_ ## x __attribute__ ((unused));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
18
src/clean.bash
Executable file
18
src/clean.bash
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2009 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
for i in lib9 libbio
|
||||
do
|
||||
cd $i
|
||||
make clean
|
||||
cd ..
|
||||
done
|
||||
|
||||
for i in cmd runtime
|
||||
do
|
||||
cd $i
|
||||
bash clean.bash
|
||||
cd ..
|
||||
done
|
|
@ -3,7 +3,7 @@
|
|||
# license that can be found in the LICENSE file.
|
||||
|
||||
YFLAGS=-d
|
||||
CFLAGS=-I/home/r/plan9/include -I$(GOROOT)/include
|
||||
CFLAGS=-I$(GOROOT)/include
|
||||
BIN=$(HOME)/bin
|
||||
O=o
|
||||
|
||||
|
@ -26,7 +26,7 @@ YFILES=\
|
|||
a.y\
|
||||
|
||||
$(TARG): $(OFILES)
|
||||
cc -o $(TARG) -L/home/r/plan9/lib $(OFILES) -lbio -l9
|
||||
cc -o $(TARG) -L$(GOROOT)/lib $(OFILES) -lbio -l9
|
||||
|
||||
$(OFILES): $(HFILES)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
CFLAGS=-I/home/r/plan9/include -I$(GOROOT)/include
|
||||
CFLAGS=-I$(GOROOT)/include
|
||||
BIN=$(HOME)/bin
|
||||
O=o
|
||||
|
||||
|
@ -32,7 +32,7 @@ LIB=\
|
|||
../cc/cc.a$O
|
||||
|
||||
$(TARG): $(OFILES) $(LIB)
|
||||
cc -o $(TARG) -L/home/r/plan9/lib $(OFILES) $(LIB) -lbio -l9
|
||||
cc -o $(TARG) -L$(GOROOT)/lib $(OFILES) $(LIB) -lbio -l9
|
||||
|
||||
$(OFILES): $(HFILES)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
CFLAGS=-I/home/r/plan9/include -I$(GOROOT)/include
|
||||
CFLAGS=-I$(GOROOT)/include
|
||||
BIN=$(HOME)/bin
|
||||
O=o
|
||||
|
||||
|
@ -27,7 +27,7 @@ LIB=\
|
|||
../gc/gc.a$O
|
||||
|
||||
$(TARG): $(OFILES) $(LIB)
|
||||
cc -o $(TARG) -L/home/r/plan9/lib $(OFILES) $(LIB) -lbio -l9
|
||||
cc -o $(TARG) -L$(GOROOT)/lib $(OFILES) $(LIB) -lbio -l9
|
||||
|
||||
$(OFILES): $(HFILES)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
CFLAGS=-I/home/r/plan9/include -I$(GOROOT)/include
|
||||
CFLAGS=-I$(GOROOT)/include
|
||||
BIN=$(HOME)/bin
|
||||
O=o
|
||||
|
||||
|
@ -25,7 +25,7 @@ HFILES=\
|
|||
|
||||
|
||||
$(TARG): $(OFILES)
|
||||
cc -o $(TARG) -L/home/r/plan9/lib $(OFILES) -lbio -l9
|
||||
cc -o $(TARG) -L$(GOROOT)/lib $(OFILES) -lbio -l9
|
||||
|
||||
$(OFILES): $(HFILES)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# license that can be found in the LICENSE file.
|
||||
|
||||
YFLAGS=-d
|
||||
CFLAGS=-I/home/r/plan9/include -I$(GOROOT)/include
|
||||
CFLAGS=-I$(GOROOT)/include
|
||||
BIN=$(HOME)/bin
|
||||
O=o
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# license that can be found in the LICENSE file.
|
||||
|
||||
YFLAGS=-d
|
||||
CFLAGS=-I/home/r/plan9/include -I$(GOROOT)/include
|
||||
CFLAGS=-I$(GOROOT)/include
|
||||
BIN=$(HOME)/bin
|
||||
O=o
|
||||
|
||||
|
|
126
src/lib9/Makefile
Normal file
126
src/lib9/Makefile
Normal file
|
@ -0,0 +1,126 @@
|
|||
# Copyright 2009 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
include ../Make.conf
|
||||
|
||||
LIB=lib9.a
|
||||
|
||||
NUM=\
|
||||
charstod.$O\
|
||||
pow10.$O\
|
||||
|
||||
# Could add fmt/errfmt, but we want to pick it up from ./errstr.c instead.
|
||||
FMTOFILES=\
|
||||
dofmt.$O\
|
||||
fltfmt.$O\
|
||||
fmt.$O\
|
||||
fmtfd.$O\
|
||||
fmtfdflush.$O\
|
||||
fmtlocale.$O\
|
||||
fmtlock2.$O\
|
||||
fmtnull.$O\
|
||||
fmtprint.$O\
|
||||
fmtquote.$O\
|
||||
fmtrune.$O\
|
||||
fmtstr.$O\
|
||||
fmtvprint.$O\
|
||||
fprint.$O\
|
||||
nan64.$O\
|
||||
print.$O\
|
||||
seprint.$O\
|
||||
smprint.$O\
|
||||
snprint.$O\
|
||||
sprint.$O\
|
||||
strtod.$O\
|
||||
vfprint.$O\
|
||||
vseprint.$O\
|
||||
vsmprint.$O\
|
||||
vsnprint.$O\
|
||||
$(NUM)\
|
||||
|
||||
UTFOFILES=\
|
||||
rune.$O\
|
||||
utfecpy.$O\
|
||||
utflen.$O\
|
||||
utfnlen.$O\
|
||||
utfrrune.$O\
|
||||
utfrune.$O\
|
||||
utfutf.$O\
|
||||
runetype.$O\
|
||||
|
||||
LIB9OFILES=\
|
||||
_p9dir.$O\
|
||||
_exits.$O\
|
||||
argv0.$O\
|
||||
atoi.$O\
|
||||
await.$O\
|
||||
cleanname.$O\
|
||||
create.$O\
|
||||
dirfstat.$O\
|
||||
dirfwstat.$O\
|
||||
dirstat.$O\
|
||||
dirwstat.$O\
|
||||
dup.$O\
|
||||
errstr.$O\
|
||||
exec.$O\
|
||||
execl.$O\
|
||||
exitcode.$O\
|
||||
exits.$O\
|
||||
getenv.$O\
|
||||
getfields.$O\
|
||||
getuser.$O\
|
||||
getwd.$O\
|
||||
jmp.$O\
|
||||
main.$O\
|
||||
nan.$O\
|
||||
notify.$O\
|
||||
nulldir.$O\
|
||||
open.$O\
|
||||
pipe.$O\
|
||||
readn.$O\
|
||||
rfork.$O\
|
||||
seek.$O\
|
||||
strecpy.$O\
|
||||
sysfatal.$O\
|
||||
time.$O\
|
||||
tokenize.$O\
|
||||
|
||||
OFILES=\
|
||||
$(LIB9OFILES)\
|
||||
$(FMTOFILES)\
|
||||
$(UTFOFILES)\
|
||||
|
||||
HFILES=\
|
||||
$(GOROOT)/include/u.h\
|
||||
$(GOROOT)/include/libc.h\
|
||||
|
||||
install: $(LIB)
|
||||
cp $(LIB) $(GOROOT)/lib
|
||||
|
||||
$(LIB): $(OFILES)
|
||||
ar rsc $(LIB) $(OFILES)
|
||||
|
||||
%.$O: fmt/%.c
|
||||
$(CC) -c $(CFLAGS) -DPLAN9PORT -Ifmt $<
|
||||
|
||||
%.$O: utf/%.c
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
clean:
|
||||
rm -f *.$O *.6 6.out $(LIB)
|
||||
|
||||
nuke: clean
|
||||
rm -f $(GOROOT)/lib/$(LIB)
|
||||
|
||||
#XLIB=$PLAN9/lib/$LIB
|
||||
|
||||
#testfmt: testfmt.$O $XLIB
|
||||
# $LD -o $target testfmt.$O
|
||||
|
||||
#testfltfmt: testfltfmt.$O $XLIB
|
||||
# $LD -o $target testfltfmt.$O
|
||||
|
||||
#testprint: testprint.$O $XLIB
|
||||
# $LD -o $target testprint.$O
|
||||
|
35
src/lib9/_exits.c
Normal file
35
src/lib9/_exits.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/_exits.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/_exits.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void
|
||||
_exits(char *s)
|
||||
{
|
||||
if(s == 0 || *s == 0)
|
||||
_exit(0);
|
||||
_exit(exitcode(s));
|
||||
}
|
315
src/lib9/_p9dir.c
Normal file
315
src/lib9/_p9dir.c
Normal file
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/_p9dir.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/_p9dir.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/disk.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/ioctl.h>
|
||||
#define _HAVEDISKLABEL
|
||||
static int diskdev[] = {
|
||||
151, /* aacd */
|
||||
116, /* ad */
|
||||
157, /* ar */
|
||||
118, /* afd */
|
||||
133, /* amrd */
|
||||
13, /* da */
|
||||
102, /* fla */
|
||||
109, /* idad */
|
||||
95, /* md */
|
||||
131, /* mlxd */
|
||||
168, /* pst */
|
||||
147, /* twed */
|
||||
43, /* vn */
|
||||
3, /* wd */
|
||||
87, /* wfd */
|
||||
4, /* da on FreeBSD 5 */
|
||||
};
|
||||
static int
|
||||
isdisk(struct stat *st)
|
||||
{
|
||||
int i, dev;
|
||||
|
||||
if(!S_ISCHR(st->st_mode))
|
||||
return 0;
|
||||
dev = major(st->st_rdev);
|
||||
for(i=0; i<nelem(diskdev); i++)
|
||||
if(diskdev[i] == dev)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) /* maybe OpenBSD too? */
|
||||
char *diskdev[] = {
|
||||
"aacd",
|
||||
"ad",
|
||||
"ar",
|
||||
"afd",
|
||||
"amrd",
|
||||
"da",
|
||||
"fla",
|
||||
"idad",
|
||||
"md",
|
||||
"mlxd",
|
||||
"pst",
|
||||
"twed",
|
||||
"vn",
|
||||
"wd",
|
||||
"wfd",
|
||||
"da",
|
||||
};
|
||||
static int
|
||||
isdisk(struct stat *st)
|
||||
{
|
||||
char *name;
|
||||
int i, len;
|
||||
|
||||
if(!S_ISCHR(st->st_mode))
|
||||
return 0;
|
||||
name = devname(st->st_rdev, S_IFCHR);
|
||||
for(i=0; i<nelem(diskdev); i++){
|
||||
len = strlen(diskdev[i]);
|
||||
if(strncmp(diskdev[i], name, len) == 0 && isdigit((uchar)name[len]))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <linux/hdreg.h>
|
||||
#include <linux/fs.h>
|
||||
#include <sys/ioctl.h>
|
||||
#undef major
|
||||
#define major(dev) ((int)(((dev) >> 8) & 0xff))
|
||||
static vlong
|
||||
disksize(int fd, int dev)
|
||||
{
|
||||
u64int u64;
|
||||
long l;
|
||||
struct hd_geometry geo;
|
||||
|
||||
memset(&geo, 0, sizeof geo);
|
||||
l = 0;
|
||||
u64 = 0;
|
||||
#ifdef BLKGETSIZE64
|
||||
if(ioctl(fd, BLKGETSIZE64, &u64) >= 0)
|
||||
return u64;
|
||||
#endif
|
||||
if(ioctl(fd, BLKGETSIZE, &l) >= 0)
|
||||
return l*512;
|
||||
if(ioctl(fd, HDIO_GETGEO, &geo) >= 0)
|
||||
return (vlong)geo.heads*geo.sectors*geo.cylinders*512;
|
||||
return 0;
|
||||
}
|
||||
#define _HAVEDISKSIZE
|
||||
#endif
|
||||
|
||||
#if !defined(__linux__) && !defined(__sun__)
|
||||
#define _HAVESTGEN
|
||||
#endif
|
||||
|
||||
int _p9usepwlibrary = 1;
|
||||
/*
|
||||
* Caching the last group and passwd looked up is
|
||||
* a significant win (stupidly enough) on most systems.
|
||||
* It's not safe for threaded programs, but neither is using
|
||||
* getpwnam in the first place, so I'm not too worried.
|
||||
*/
|
||||
int
|
||||
_p9dir(struct stat *lst, struct stat *st, char *name, Dir *d, char **str, char *estr)
|
||||
{
|
||||
char *s;
|
||||
char tmp[20];
|
||||
static struct group *g;
|
||||
static struct passwd *p;
|
||||
static int gid, uid;
|
||||
int sz, fd;
|
||||
|
||||
fd = -1;
|
||||
USED(fd);
|
||||
sz = 0;
|
||||
if(d)
|
||||
memset(d, 0, sizeof *d);
|
||||
|
||||
/* name */
|
||||
s = strrchr(name, '/');
|
||||
if(s)
|
||||
s++;
|
||||
if(!s || !*s)
|
||||
s = name;
|
||||
if(*s == '/')
|
||||
s++;
|
||||
if(*s == 0)
|
||||
s = "/";
|
||||
if(d){
|
||||
if(*str + strlen(s)+1 > estr)
|
||||
d->name = "oops";
|
||||
else{
|
||||
strcpy(*str, s);
|
||||
d->name = *str;
|
||||
*str += strlen(*str)+1;
|
||||
}
|
||||
}
|
||||
sz += strlen(s)+1;
|
||||
|
||||
/* user */
|
||||
if(p && st->st_uid == uid && p->pw_uid == uid)
|
||||
;
|
||||
else if(_p9usepwlibrary){
|
||||
p = getpwuid(st->st_uid);
|
||||
uid = st->st_uid;
|
||||
}
|
||||
if(p == nil || st->st_uid != uid || p->pw_uid != uid){
|
||||
snprint(tmp, sizeof tmp, "%d", (int)st->st_uid);
|
||||
s = tmp;
|
||||
}else
|
||||
s = p->pw_name;
|
||||
sz += strlen(s)+1;
|
||||
if(d){
|
||||
if(*str+strlen(s)+1 > estr)
|
||||
d->uid = "oops";
|
||||
else{
|
||||
strcpy(*str, s);
|
||||
d->uid = *str;
|
||||
*str += strlen(*str)+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* group */
|
||||
if(g && st->st_gid == gid && g->gr_gid == gid)
|
||||
;
|
||||
else if(_p9usepwlibrary){
|
||||
g = getgrgid(st->st_gid);
|
||||
gid = st->st_gid;
|
||||
}
|
||||
if(g == nil || st->st_gid != gid || g->gr_gid != gid){
|
||||
snprint(tmp, sizeof tmp, "%d", (int)st->st_gid);
|
||||
s = tmp;
|
||||
}else
|
||||
s = g->gr_name;
|
||||
sz += strlen(s)+1;
|
||||
if(d){
|
||||
if(*str + strlen(s)+1 > estr)
|
||||
d->gid = "oops";
|
||||
else{
|
||||
strcpy(*str, s);
|
||||
d->gid = *str;
|
||||
*str += strlen(*str)+1;
|
||||
}
|
||||
}
|
||||
|
||||
if(d){
|
||||
d->type = 'M';
|
||||
|
||||
d->muid = "";
|
||||
d->qid.path = ((uvlong)st->st_dev<<32) | st->st_ino;
|
||||
#ifdef _HAVESTGEN
|
||||
d->qid.vers = st->st_gen;
|
||||
#endif
|
||||
if(d->qid.vers == 0)
|
||||
d->qid.vers = st->st_mtime + st->st_ctime;
|
||||
d->mode = st->st_mode&0777;
|
||||
d->atime = st->st_atime;
|
||||
d->mtime = st->st_mtime;
|
||||
d->length = st->st_size;
|
||||
|
||||
if(S_ISDIR(st->st_mode)){
|
||||
d->length = 0;
|
||||
d->mode |= DMDIR;
|
||||
d->qid.type = QTDIR;
|
||||
}
|
||||
if(S_ISLNK(lst->st_mode)) /* yes, lst not st */
|
||||
d->mode |= DMSYMLINK;
|
||||
if(S_ISFIFO(st->st_mode))
|
||||
d->mode |= DMNAMEDPIPE;
|
||||
if(S_ISSOCK(st->st_mode))
|
||||
d->mode |= DMSOCKET;
|
||||
if(S_ISBLK(st->st_mode)){
|
||||
d->mode |= DMDEVICE;
|
||||
d->qid.path = ('b'<<16)|st->st_rdev;
|
||||
}
|
||||
if(S_ISCHR(st->st_mode)){
|
||||
d->mode |= DMDEVICE;
|
||||
d->qid.path = ('c'<<16)|st->st_rdev;
|
||||
}
|
||||
/* fetch real size for disks */
|
||||
#ifdef _HAVEDISKSIZE
|
||||
if(S_ISBLK(st->st_mode) && (fd = open(name, O_RDONLY)) >= 0){
|
||||
d->length = disksize(fd, major(st->st_dev));
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
#if defined(DIOCGMEDIASIZE)
|
||||
if(isdisk(st)){
|
||||
int fd;
|
||||
off_t mediasize;
|
||||
|
||||
if((fd = open(name, O_RDONLY)) >= 0){
|
||||
if(ioctl(fd, DIOCGMEDIASIZE, &mediasize) >= 0)
|
||||
d->length = mediasize;
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#elif defined(_HAVEDISKLABEL)
|
||||
if(isdisk(st)){
|
||||
int fd, n;
|
||||
struct disklabel lab;
|
||||
|
||||
if((fd = open(name, O_RDONLY)) < 0)
|
||||
goto nosize;
|
||||
if(ioctl(fd, DIOCGDINFO, &lab) < 0)
|
||||
goto nosize;
|
||||
n = minor(st->st_rdev)&7;
|
||||
if(n >= lab.d_npartitions)
|
||||
goto nosize;
|
||||
|
||||
d->length = (vlong)(lab.d_partitions[n].p_size) * lab.d_secsize;
|
||||
|
||||
nosize:
|
||||
if(fd >= 0)
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
34
src/lib9/argv0.c
Normal file
34
src/lib9/argv0.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/argv0.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/argv0.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <lib9.h>
|
||||
|
||||
char *argv0;
|
||||
|
||||
/*
|
||||
* Mac OS can't deal with files that only declare data.
|
||||
* ARGBEGIN mentions this function so that this file gets pulled in.
|
||||
*/
|
||||
void __fixargv0(void) { }
|
45
src/lib9/atoi.c
Normal file
45
src/lib9/atoi.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/ato*.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/atoi.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
int
|
||||
atoi(char *s)
|
||||
{
|
||||
return strtol(s, 0, 0);
|
||||
}
|
||||
|
||||
long
|
||||
atol(char *s)
|
||||
{
|
||||
return strtol(s, 0, 0);
|
||||
}
|
||||
|
||||
vlong
|
||||
atoll(char *s)
|
||||
{
|
||||
return strtoll(s, 0, 0);
|
||||
}
|
179
src/lib9/await.c
Normal file
179
src/lib9/await.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/await.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/await.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
Portions Copyright 2009 The Go Authors. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define NOPLAN9DEFINES
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#ifndef WCOREDUMP /* not on Mac OS X Tiger */
|
||||
#define WCOREDUMP(status) 0
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
int sig;
|
||||
char *str;
|
||||
} tab[] = {
|
||||
SIGHUP, "hangup",
|
||||
SIGINT, "interrupt",
|
||||
SIGQUIT, "quit",
|
||||
SIGILL, "sys: illegal instruction",
|
||||
SIGTRAP, "sys: breakpoint",
|
||||
SIGABRT, "sys: abort",
|
||||
#ifdef SIGEMT
|
||||
SIGEMT, "sys: emulate instruction executed",
|
||||
#endif
|
||||
SIGFPE, "sys: fp: trap",
|
||||
SIGKILL, "sys: kill",
|
||||
SIGBUS, "sys: bus error",
|
||||
SIGSEGV, "sys: segmentation violation",
|
||||
SIGALRM, "alarm",
|
||||
SIGTERM, "kill",
|
||||
SIGURG, "sys: urgent condition on socket",
|
||||
SIGSTOP, "sys: stop",
|
||||
SIGTSTP, "sys: tstp",
|
||||
SIGCONT, "sys: cont",
|
||||
SIGCHLD, "sys: child",
|
||||
SIGTTIN, "sys: ttin",
|
||||
SIGTTOU, "sys: ttou",
|
||||
#ifdef SIGIO /* not on Mac OS X Tiger */
|
||||
SIGIO, "sys: i/o possible on fd",
|
||||
#endif
|
||||
SIGXCPU, "sys: cpu time limit exceeded",
|
||||
SIGXFSZ, "sys: file size limit exceeded",
|
||||
SIGVTALRM, "sys: virtual time alarm",
|
||||
SIGPROF, "sys: profiling timer alarm",
|
||||
#ifdef SIGWINCH /* not on Mac OS X Tiger */
|
||||
SIGWINCH, "sys: window size change",
|
||||
#endif
|
||||
#ifdef SIGINFO
|
||||
SIGINFO, "sys: status request",
|
||||
#endif
|
||||
SIGUSR1, "sys: usr1",
|
||||
SIGUSR2, "sys: usr2",
|
||||
SIGPIPE, "sys: write on closed pipe",
|
||||
};
|
||||
|
||||
char*
|
||||
_p9sigstr(int sig, char *tmp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<nelem(tab); i++)
|
||||
if(tab[i].sig == sig)
|
||||
return tab[i].str;
|
||||
if(tmp == nil)
|
||||
return nil;
|
||||
sprint(tmp, "sys: signal %d", sig);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int
|
||||
_p9strsig(char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<nelem(tab); i++)
|
||||
if(strcmp(s, tab[i].str) == 0)
|
||||
return tab[i].sig;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Waitmsg*
|
||||
_wait(int pid4, int opt)
|
||||
{
|
||||
int pid, status, cd;
|
||||
struct rusage ru;
|
||||
char tmp[64];
|
||||
ulong u, s;
|
||||
Waitmsg *w;
|
||||
|
||||
w = malloc(sizeof *w + 200);
|
||||
if(w == nil)
|
||||
return nil;
|
||||
memset(w, 0, sizeof *w);
|
||||
w->msg = (char*)&w[1];
|
||||
|
||||
for(;;){
|
||||
/* On Linux, pid==-1 means anyone; on SunOS, it's pid==0. */
|
||||
if(pid4 == -1)
|
||||
pid = wait3(&status, opt, &ru);
|
||||
else
|
||||
pid = wait4(pid4, &status, opt, &ru);
|
||||
if(pid <= 0) {
|
||||
free(w);
|
||||
return nil;
|
||||
}
|
||||
u = ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000);
|
||||
s = ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000);
|
||||
w->pid = pid;
|
||||
w->time[0] = u;
|
||||
w->time[1] = s;
|
||||
w->time[2] = u+s;
|
||||
if(WIFEXITED(status)){
|
||||
if(status)
|
||||
sprint(w->msg, "%d", status);
|
||||
return w;
|
||||
}
|
||||
if(WIFSIGNALED(status)){
|
||||
cd = WCOREDUMP(status);
|
||||
sprint(w->msg, "signal: %s", _p9sigstr(WTERMSIG(status), tmp));
|
||||
if(cd)
|
||||
strcat(w->msg, " (core dumped)");
|
||||
return w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Waitmsg*
|
||||
p9wait(void)
|
||||
{
|
||||
return _wait(-1, 0);
|
||||
}
|
||||
|
||||
Waitmsg*
|
||||
p9waitfor(int pid)
|
||||
{
|
||||
return _wait(pid, 0);
|
||||
}
|
||||
|
||||
Waitmsg*
|
||||
p9waitnohang(void)
|
||||
{
|
||||
return _wait(-1, WNOHANG);
|
||||
}
|
||||
|
||||
int
|
||||
p9waitpid(void)
|
||||
{
|
||||
int status;
|
||||
return wait(&status);
|
||||
}
|
78
src/lib9/cleanname.c
Normal file
78
src/lib9/cleanname.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Inferno libkern/cleanname.c
|
||||
http://code.google.com/p/inferno-os/source/browse/libkern/cleanname.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
/*
|
||||
* In place, rewrite name to compress multiple /, eliminate ., and process ..
|
||||
*/
|
||||
#define SEP(x) ((x)=='/' || (x) == 0)
|
||||
char*
|
||||
cleanname(char *name)
|
||||
{
|
||||
char *p, *q, *dotdot;
|
||||
int rooted;
|
||||
|
||||
rooted = name[0] == '/';
|
||||
|
||||
/*
|
||||
* invariants:
|
||||
* p points at beginning of path element we're considering.
|
||||
* q points just past the last path element we wrote (no slash).
|
||||
* dotdot points just past the point where .. cannot backtrack
|
||||
* any further (no slash).
|
||||
*/
|
||||
p = q = dotdot = name+rooted;
|
||||
while(*p) {
|
||||
if(p[0] == '/') /* null element */
|
||||
p++;
|
||||
else if(p[0] == '.' && SEP(p[1]))
|
||||
p += 1; /* don't count the separator in case it is nul */
|
||||
else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
|
||||
p += 2;
|
||||
if(q > dotdot) { /* can backtrack */
|
||||
while(--q > dotdot && *q != '/')
|
||||
;
|
||||
} else if(!rooted) { /* /.. is / but ./../ is .. */
|
||||
if(q != name)
|
||||
*q++ = '/';
|
||||
*q++ = '.';
|
||||
*q++ = '.';
|
||||
dotdot = q;
|
||||
}
|
||||
} else { /* real path element */
|
||||
if(q != name+rooted)
|
||||
*q++ = '/';
|
||||
while((*q = *p) != '/' && *q != 0)
|
||||
p++, q++;
|
||||
}
|
||||
}
|
||||
if(q == name) /* empty string is really ``.'' */
|
||||
*q++ = '.';
|
||||
*q = '\0';
|
||||
return name;
|
||||
}
|
99
src/lib9/create.c
Normal file
99
src/lib9/create.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/create.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/create.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#define _GNU_SOURCE /* for Linux O_DIRECT */
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <sys/file.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <libc.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef O_DIRECT
|
||||
#define O_DIRECT 0
|
||||
#endif
|
||||
|
||||
int
|
||||
p9create(char *path, int mode, ulong perm)
|
||||
{
|
||||
int fd, cexec, umode, rclose, lock, rdwr;
|
||||
struct flock fl;
|
||||
|
||||
rdwr = mode&3;
|
||||
lock = mode&OLOCK;
|
||||
cexec = mode&OCEXEC;
|
||||
rclose = mode&ORCLOSE;
|
||||
mode &= ~(ORCLOSE|OCEXEC|OLOCK);
|
||||
|
||||
/* XXX should get mode mask right? */
|
||||
fd = -1;
|
||||
if(perm&DMDIR){
|
||||
if(mode != OREAD){
|
||||
werrstr("bad mode in directory create");
|
||||
goto out;
|
||||
}
|
||||
if(mkdir(path, perm&0777) < 0)
|
||||
goto out;
|
||||
fd = open(path, O_RDONLY);
|
||||
}else{
|
||||
umode = (mode&3)|O_CREAT|O_TRUNC;
|
||||
mode &= ~(3|OTRUNC);
|
||||
if(mode&ODIRECT){
|
||||
umode |= O_DIRECT;
|
||||
mode &= ~ODIRECT;
|
||||
}
|
||||
if(mode&OEXCL){
|
||||
umode |= O_EXCL;
|
||||
mode &= ~OEXCL;
|
||||
}
|
||||
if(mode&OAPPEND){
|
||||
umode |= O_APPEND;
|
||||
mode &= ~OAPPEND;
|
||||
}
|
||||
if(mode){
|
||||
werrstr("unsupported mode in create");
|
||||
goto out;
|
||||
}
|
||||
fd = open(path, umode, perm);
|
||||
}
|
||||
out:
|
||||
if(fd >= 0){
|
||||
if(lock){
|
||||
fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 0;
|
||||
if(fcntl(fd, F_SETLK, &fl) < 0){
|
||||
close(fd);
|
||||
werrstr("lock: %r");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(cexec)
|
||||
fcntl(fd, F_SETFL, FD_CLOEXEC);
|
||||
if(rclose)
|
||||
remove(path);
|
||||
}
|
||||
return fd;
|
||||
}
|
54
src/lib9/dirfstat.c
Normal file
54
src/lib9/dirfstat.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/dirfstat.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/dirfstat.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*);
|
||||
|
||||
Dir*
|
||||
dirfstat(int fd)
|
||||
{
|
||||
struct stat st;
|
||||
int nstr;
|
||||
Dir *d;
|
||||
char *str, tmp[100];
|
||||
|
||||
if(fstat(fd, &st) < 0)
|
||||
return nil;
|
||||
|
||||
snprint(tmp, sizeof tmp, "/dev/fd/%d", fd);
|
||||
nstr = _p9dir(&st, &st, tmp, nil, nil, nil);
|
||||
d = malloc(sizeof(Dir)+nstr);
|
||||
if(d == nil)
|
||||
return nil;
|
||||
memset(d, 0, sizeof(Dir)+nstr);
|
||||
str = (char*)&d[1];
|
||||
_p9dir(&st, &st, tmp, d, &str, str+nstr);
|
||||
return d;
|
||||
}
|
||||
|
78
src/lib9/dirfwstat.c
Normal file
78
src/lib9/dirfwstat.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/dirfwstat.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/dirfwstat.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define NOPLAN9DEFINES
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__linux__)
|
||||
/* do nothing -- futimes exists and is fine */
|
||||
|
||||
#elif defined(__SunOS5_9__)
|
||||
/* use futimesat */
|
||||
static int
|
||||
futimes(int fd, struct timeval *tv)
|
||||
{
|
||||
return futimesat(fd, 0, tv);
|
||||
}
|
||||
|
||||
#else
|
||||
/* provide dummy */
|
||||
/* rename just in case -- linux provides an unusable one */
|
||||
#undef futimes
|
||||
#define futimes myfutimes
|
||||
static int
|
||||
futimes(int fd, struct timeval *tv)
|
||||
{
|
||||
werrstr("futimes not available");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
dirfwstat(int fd, Dir *dir)
|
||||
{
|
||||
int ret;
|
||||
struct timeval tv[2];
|
||||
|
||||
ret = 0;
|
||||
if(~dir->mode != 0){
|
||||
if(fchmod(fd, dir->mode) < 0)
|
||||
ret = -1;
|
||||
}
|
||||
if(~dir->mtime != 0){
|
||||
tv[0].tv_sec = dir->mtime;
|
||||
tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = dir->mtime;
|
||||
tv[1].tv_usec = 0;
|
||||
if(futimes(fd, tv) < 0)
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
57
src/lib9/dirstat.c
Normal file
57
src/lib9/dirstat.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/dirstat.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/dirstat.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*);
|
||||
|
||||
Dir*
|
||||
dirstat(char *file)
|
||||
{
|
||||
struct stat lst;
|
||||
struct stat st;
|
||||
int nstr;
|
||||
Dir *d;
|
||||
char *str;
|
||||
|
||||
if(lstat(file, &lst) < 0)
|
||||
return nil;
|
||||
st = lst;
|
||||
if((lst.st_mode&S_IFMT) == S_IFLNK)
|
||||
stat(file, &st);
|
||||
|
||||
nstr = _p9dir(&lst, &st, file, nil, nil, nil);
|
||||
d = malloc(sizeof(Dir)+nstr);
|
||||
if(d == nil)
|
||||
return nil;
|
||||
memset(d, 0, sizeof(Dir)+nstr);
|
||||
str = (char*)&d[1];
|
||||
_p9dir(&lst, &st, file, d, &str, str+nstr);
|
||||
return d;
|
||||
}
|
||||
|
43
src/lib9/dirwstat.c
Normal file
43
src/lib9/dirwstat.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/dirwstat.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/dirwstat.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
#include <sys/time.h>
|
||||
#include <utime.h>
|
||||
|
||||
int
|
||||
dirwstat(char *file, Dir *dir)
|
||||
{
|
||||
struct utimbuf ub;
|
||||
|
||||
/* BUG handle more */
|
||||
if(~dir->mtime == 0)
|
||||
return 0;
|
||||
|
||||
ub.actime = dir->mtime;
|
||||
ub.modtime = dir->mtime;
|
||||
return utime(file, &ub);
|
||||
}
|
36
src/lib9/dup.c
Normal file
36
src/lib9/dup.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/dup.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/dup.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
#undef dup
|
||||
|
||||
int
|
||||
p9dup(int old, int new)
|
||||
{
|
||||
if(new == -1)
|
||||
return dup(old);
|
||||
return dup2(old, new);
|
||||
}
|
106
src/lib9/errstr.c
Normal file
106
src/lib9/errstr.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/errstr.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/errstr.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We assume there's only one error buffer for the whole system.
|
||||
* If you use ffork, you need to provide a _syserrstr. Since most
|
||||
* people will use libthread (which provides a _syserrstr), this is
|
||||
* okay.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <libc.h>
|
||||
|
||||
enum
|
||||
{
|
||||
EPLAN9 = 0x19283745
|
||||
};
|
||||
|
||||
char *(*_syserrstr)(void);
|
||||
static char xsyserr[ERRMAX];
|
||||
static char*
|
||||
getsyserr(void)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = nil;
|
||||
if(_syserrstr)
|
||||
s = (*_syserrstr)();
|
||||
if(s == nil)
|
||||
s = xsyserr;
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
errstr(char *err, uint n)
|
||||
{
|
||||
char tmp[ERRMAX];
|
||||
char *syserr;
|
||||
|
||||
strecpy(tmp, tmp+ERRMAX, err);
|
||||
rerrstr(err, n);
|
||||
syserr = getsyserr();
|
||||
strecpy(syserr, syserr+ERRMAX, tmp);
|
||||
errno = EPLAN9;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rerrstr(char *err, uint n)
|
||||
{
|
||||
char *syserr;
|
||||
|
||||
syserr = getsyserr();
|
||||
if(errno == EINTR)
|
||||
strcpy(syserr, "interrupted");
|
||||
else if(errno != EPLAN9)
|
||||
strcpy(syserr, strerror(errno));
|
||||
strecpy(err, err+n, syserr);
|
||||
}
|
||||
|
||||
/* replaces __errfmt in libfmt */
|
||||
|
||||
int
|
||||
__errfmt(Fmt *f)
|
||||
{
|
||||
if(errno == EPLAN9)
|
||||
return fmtstrcpy(f, getsyserr());
|
||||
return fmtstrcpy(f, strerror(errno));
|
||||
}
|
||||
|
||||
void
|
||||
werrstr(char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
char buf[ERRMAX];
|
||||
|
||||
va_start(arg, fmt);
|
||||
vseprint(buf, buf+ERRMAX, fmt, arg);
|
||||
va_end(arg);
|
||||
errstr(buf, ERRMAX);
|
||||
}
|
||||
|
33
src/lib9/exec.c
Normal file
33
src/lib9/exec.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/exec.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/exec.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
int
|
||||
exec(char *prog, char *argv[])
|
||||
{
|
||||
/* to mimic plan 9 should be just exec, but execvp is a better fit for unix */
|
||||
return execvp(prog, argv);
|
||||
}
|
53
src/lib9/execl.c
Normal file
53
src/lib9/execl.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/execl.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/execl.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
int
|
||||
execl(char *prog, ...)
|
||||
{
|
||||
int i;
|
||||
va_list arg;
|
||||
char **argv;
|
||||
|
||||
va_start(arg, prog);
|
||||
for(i=0; va_arg(arg, char*) != nil; i++)
|
||||
;
|
||||
va_end(arg);
|
||||
|
||||
argv = malloc((i+1)*sizeof(char*));
|
||||
if(argv == nil)
|
||||
return -1;
|
||||
|
||||
va_start(arg, prog);
|
||||
for(i=0; (argv[i] = va_arg(arg, char*)) != nil; i++)
|
||||
;
|
||||
va_end(arg);
|
||||
|
||||
exec(prog, argv);
|
||||
free(argv);
|
||||
return -1;
|
||||
}
|
||||
|
34
src/lib9/exitcode.c
Normal file
34
src/lib9/exitcode.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/exitcode.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/exitcode.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
int
|
||||
exitcode(char *s)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
88
src/lib9/fmt/charstod.c
Normal file
88
src/lib9/fmt/charstod.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* Reads a floating-point number by interpreting successive characters
|
||||
* returned by (*f)(vp). The last call it makes to f terminates the
|
||||
* scan, so is not a character in the number. It may therefore be
|
||||
* necessary to back up the input stream up one byte after calling charstod.
|
||||
*/
|
||||
|
||||
double
|
||||
fmtcharstod(int(*f)(void*), void *vp)
|
||||
{
|
||||
double num, dem;
|
||||
int neg, eneg, dig, exp, c;
|
||||
|
||||
num = 0;
|
||||
neg = 0;
|
||||
dig = 0;
|
||||
exp = 0;
|
||||
eneg = 0;
|
||||
|
||||
c = (*f)(vp);
|
||||
while(c == ' ' || c == '\t')
|
||||
c = (*f)(vp);
|
||||
if(c == '-' || c == '+'){
|
||||
if(c == '-')
|
||||
neg = 1;
|
||||
c = (*f)(vp);
|
||||
}
|
||||
while(c >= '0' && c <= '9'){
|
||||
num = num*10 + c-'0';
|
||||
c = (*f)(vp);
|
||||
}
|
||||
if(c == '.')
|
||||
c = (*f)(vp);
|
||||
while(c >= '0' && c <= '9'){
|
||||
num = num*10 + c-'0';
|
||||
dig++;
|
||||
c = (*f)(vp);
|
||||
}
|
||||
if(c == 'e' || c == 'E'){
|
||||
c = (*f)(vp);
|
||||
if(c == '-' || c == '+'){
|
||||
if(c == '-'){
|
||||
dig = -dig;
|
||||
eneg = 1;
|
||||
}
|
||||
c = (*f)(vp);
|
||||
}
|
||||
while(c >= '0' && c <= '9'){
|
||||
exp = exp*10 + c-'0';
|
||||
c = (*f)(vp);
|
||||
}
|
||||
}
|
||||
exp -= dig;
|
||||
if(exp < 0){
|
||||
exp = -exp;
|
||||
eneg = !eneg;
|
||||
}
|
||||
dem = __fmtpow10(exp);
|
||||
if(eneg)
|
||||
num /= dem;
|
||||
else
|
||||
num *= dem;
|
||||
if(neg)
|
||||
return -num;
|
||||
return num;
|
||||
}
|
629
src/lib9/fmt/dofmt.c
Normal file
629
src/lib9/fmt/dofmt.c
Normal file
|
@ -0,0 +1,629 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/* format the output into f->to and return the number of characters fmted */
|
||||
int
|
||||
dofmt(Fmt *f, char *fmt)
|
||||
{
|
||||
Rune rune, *rt, *rs;
|
||||
int r;
|
||||
char *t, *s;
|
||||
int n, nfmt;
|
||||
|
||||
nfmt = f->nfmt;
|
||||
for(;;){
|
||||
if(f->runes){
|
||||
rt = (Rune*)f->to;
|
||||
rs = (Rune*)f->stop;
|
||||
while((r = *(uchar*)fmt) && r != '%'){
|
||||
if(r < Runeself)
|
||||
fmt++;
|
||||
else{
|
||||
fmt += chartorune(&rune, fmt);
|
||||
r = rune;
|
||||
}
|
||||
FMTRCHAR(f, rt, rs, r);
|
||||
}
|
||||
fmt++;
|
||||
f->nfmt += rt - (Rune *)f->to;
|
||||
f->to = rt;
|
||||
if(!r)
|
||||
return f->nfmt - nfmt;
|
||||
f->stop = rs;
|
||||
}else{
|
||||
t = (char*)f->to;
|
||||
s = (char*)f->stop;
|
||||
while((r = *(uchar*)fmt) && r != '%'){
|
||||
if(r < Runeself){
|
||||
FMTCHAR(f, t, s, r);
|
||||
fmt++;
|
||||
}else{
|
||||
n = chartorune(&rune, fmt);
|
||||
if(t + n > s){
|
||||
t = (char*)__fmtflush(f, t, n);
|
||||
if(t != nil)
|
||||
s = (char*)f->stop;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
while(n--)
|
||||
*t++ = *fmt++;
|
||||
}
|
||||
}
|
||||
fmt++;
|
||||
f->nfmt += t - (char *)f->to;
|
||||
f->to = t;
|
||||
if(!r)
|
||||
return f->nfmt - nfmt;
|
||||
f->stop = s;
|
||||
}
|
||||
|
||||
fmt = (char*)__fmtdispatch(f, fmt, 0);
|
||||
if(fmt == nil)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
__fmtflush(Fmt *f, void *t, int len)
|
||||
{
|
||||
if(f->runes)
|
||||
f->nfmt += (Rune*)t - (Rune*)f->to;
|
||||
else
|
||||
f->nfmt += (char*)t - (char *)f->to;
|
||||
f->to = t;
|
||||
if(f->flush == 0 || (*f->flush)(f) == 0 || (char*)f->to + len > (char*)f->stop){
|
||||
f->stop = f->to;
|
||||
return nil;
|
||||
}
|
||||
return f->to;
|
||||
}
|
||||
|
||||
/*
|
||||
* put a formatted block of memory sz bytes long of n runes into the output buffer,
|
||||
* left/right justified in a field of at least f->width characters (if FmtWidth is set)
|
||||
*/
|
||||
int
|
||||
__fmtpad(Fmt *f, int n)
|
||||
{
|
||||
char *t, *s;
|
||||
int i;
|
||||
|
||||
t = (char*)f->to;
|
||||
s = (char*)f->stop;
|
||||
for(i = 0; i < n; i++)
|
||||
FMTCHAR(f, t, s, ' ');
|
||||
f->nfmt += t - (char *)f->to;
|
||||
f->to = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__rfmtpad(Fmt *f, int n)
|
||||
{
|
||||
Rune *t, *s;
|
||||
int i;
|
||||
|
||||
t = (Rune*)f->to;
|
||||
s = (Rune*)f->stop;
|
||||
for(i = 0; i < n; i++)
|
||||
FMTRCHAR(f, t, s, ' ');
|
||||
f->nfmt += t - (Rune *)f->to;
|
||||
f->to = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__fmtcpy(Fmt *f, const void *vm, int n, int sz)
|
||||
{
|
||||
Rune *rt, *rs, r;
|
||||
char *t, *s, *m, *me;
|
||||
ulong fl;
|
||||
int nc, w;
|
||||
|
||||
m = (char*)vm;
|
||||
me = m + sz;
|
||||
fl = f->flags;
|
||||
w = 0;
|
||||
if(fl & FmtWidth)
|
||||
w = f->width;
|
||||
if((fl & FmtPrec) && n > f->prec)
|
||||
n = f->prec;
|
||||
if(f->runes){
|
||||
if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
|
||||
return -1;
|
||||
rt = (Rune*)f->to;
|
||||
rs = (Rune*)f->stop;
|
||||
for(nc = n; nc > 0; nc--){
|
||||
r = *(uchar*)m;
|
||||
if(r < Runeself)
|
||||
m++;
|
||||
else if((me - m) >= UTFmax || fullrune(m, me-m))
|
||||
m += chartorune(&r, m);
|
||||
else
|
||||
break;
|
||||
FMTRCHAR(f, rt, rs, r);
|
||||
}
|
||||
f->nfmt += rt - (Rune *)f->to;
|
||||
f->to = rt;
|
||||
if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
|
||||
return -1;
|
||||
}else{
|
||||
if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
|
||||
return -1;
|
||||
t = (char*)f->to;
|
||||
s = (char*)f->stop;
|
||||
for(nc = n; nc > 0; nc--){
|
||||
r = *(uchar*)m;
|
||||
if(r < Runeself)
|
||||
m++;
|
||||
else if((me - m) >= UTFmax || fullrune(m, me-m))
|
||||
m += chartorune(&r, m);
|
||||
else
|
||||
break;
|
||||
FMTRUNE(f, t, s, r);
|
||||
}
|
||||
f->nfmt += t - (char *)f->to;
|
||||
f->to = t;
|
||||
if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__fmtrcpy(Fmt *f, const void *vm, int n)
|
||||
{
|
||||
Rune r, *m, *me, *rt, *rs;
|
||||
char *t, *s;
|
||||
ulong fl;
|
||||
int w;
|
||||
|
||||
m = (Rune*)vm;
|
||||
fl = f->flags;
|
||||
w = 0;
|
||||
if(fl & FmtWidth)
|
||||
w = f->width;
|
||||
if((fl & FmtPrec) && n > f->prec)
|
||||
n = f->prec;
|
||||
if(f->runes){
|
||||
if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
|
||||
return -1;
|
||||
rt = (Rune*)f->to;
|
||||
rs = (Rune*)f->stop;
|
||||
for(me = m + n; m < me; m++)
|
||||
FMTRCHAR(f, rt, rs, *m);
|
||||
f->nfmt += rt - (Rune *)f->to;
|
||||
f->to = rt;
|
||||
if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
|
||||
return -1;
|
||||
}else{
|
||||
if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
|
||||
return -1;
|
||||
t = (char*)f->to;
|
||||
s = (char*)f->stop;
|
||||
for(me = m + n; m < me; m++){
|
||||
r = *m;
|
||||
FMTRUNE(f, t, s, r);
|
||||
}
|
||||
f->nfmt += t - (char *)f->to;
|
||||
f->to = t;
|
||||
if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fmt out one character */
|
||||
int
|
||||
__charfmt(Fmt *f)
|
||||
{
|
||||
char x[1];
|
||||
|
||||
x[0] = va_arg(f->args, int);
|
||||
f->prec = 1;
|
||||
return __fmtcpy(f, (const char*)x, 1, 1);
|
||||
}
|
||||
|
||||
/* fmt out one rune */
|
||||
int
|
||||
__runefmt(Fmt *f)
|
||||
{
|
||||
Rune x[1];
|
||||
|
||||
x[0] = va_arg(f->args, int);
|
||||
return __fmtrcpy(f, (const void*)x, 1);
|
||||
}
|
||||
|
||||
/* public helper routine: fmt out a null terminated string already in hand */
|
||||
int
|
||||
fmtstrcpy(Fmt *f, char *s)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if(!s)
|
||||
return __fmtcpy(f, "<nil>", 5, 5);
|
||||
/* if precision is specified, make sure we don't wander off the end */
|
||||
if(f->flags & FmtPrec){
|
||||
#ifdef PLAN9PORT
|
||||
Rune r;
|
||||
i = 0;
|
||||
for(j=0; j<f->prec && s[i]; j++)
|
||||
i += chartorune(&r, s+i);
|
||||
#else
|
||||
/* ANSI requires precision in bytes, not Runes */
|
||||
for(i=0; i<f->prec; i++)
|
||||
if(s[i] == 0)
|
||||
break;
|
||||
j = utfnlen(s, i); /* won't print partial at end */
|
||||
#endif
|
||||
return __fmtcpy(f, s, j, i);
|
||||
}
|
||||
return __fmtcpy(f, s, utflen(s), strlen(s));
|
||||
}
|
||||
|
||||
/* fmt out a null terminated utf string */
|
||||
int
|
||||
__strfmt(Fmt *f)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = va_arg(f->args, char *);
|
||||
return fmtstrcpy(f, s);
|
||||
}
|
||||
|
||||
/* public helper routine: fmt out a null terminated rune string already in hand */
|
||||
int
|
||||
fmtrunestrcpy(Fmt *f, Rune *s)
|
||||
{
|
||||
Rune *e;
|
||||
int n, p;
|
||||
|
||||
if(!s)
|
||||
return __fmtcpy(f, "<nil>", 5, 5);
|
||||
/* if precision is specified, make sure we don't wander off the end */
|
||||
if(f->flags & FmtPrec){
|
||||
p = f->prec;
|
||||
for(n = 0; n < p; n++)
|
||||
if(s[n] == 0)
|
||||
break;
|
||||
}else{
|
||||
for(e = s; *e; e++)
|
||||
;
|
||||
n = e - s;
|
||||
}
|
||||
return __fmtrcpy(f, s, n);
|
||||
}
|
||||
|
||||
/* fmt out a null terminated rune string */
|
||||
int
|
||||
__runesfmt(Fmt *f)
|
||||
{
|
||||
Rune *s;
|
||||
|
||||
s = va_arg(f->args, Rune *);
|
||||
return fmtrunestrcpy(f, s);
|
||||
}
|
||||
|
||||
/* fmt a % */
|
||||
int
|
||||
__percentfmt(Fmt *f)
|
||||
{
|
||||
Rune x[1];
|
||||
|
||||
x[0] = f->r;
|
||||
f->prec = 1;
|
||||
return __fmtrcpy(f, (const void*)x, 1);
|
||||
}
|
||||
|
||||
/* fmt an integer */
|
||||
int
|
||||
__ifmt(Fmt *f)
|
||||
{
|
||||
char buf[140], *p, *conv;
|
||||
/* 140: for 64 bits of binary + 3-byte sep every 4 digits */
|
||||
uvlong vu;
|
||||
ulong u;
|
||||
int neg, base, i, n, fl, w, isv;
|
||||
int ndig, len, excess, bytelen;
|
||||
char *grouping;
|
||||
char *thousands;
|
||||
|
||||
neg = 0;
|
||||
fl = f->flags;
|
||||
isv = 0;
|
||||
vu = 0;
|
||||
u = 0;
|
||||
#ifndef PLAN9PORT
|
||||
/*
|
||||
* Unsigned verbs for ANSI C
|
||||
*/
|
||||
switch(f->r){
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X':
|
||||
fl |= FmtUnsigned;
|
||||
fl &= ~(FmtSign|FmtSpace);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if(f->r == 'p'){
|
||||
u = (ulong)va_arg(f->args, void*);
|
||||
f->r = 'x';
|
||||
fl |= FmtUnsigned;
|
||||
}else if(fl & FmtVLong){
|
||||
isv = 1;
|
||||
if(fl & FmtUnsigned)
|
||||
vu = va_arg(f->args, uvlong);
|
||||
else
|
||||
vu = va_arg(f->args, vlong);
|
||||
}else if(fl & FmtLong){
|
||||
if(fl & FmtUnsigned)
|
||||
u = va_arg(f->args, ulong);
|
||||
else
|
||||
u = va_arg(f->args, long);
|
||||
}else if(fl & FmtByte){
|
||||
if(fl & FmtUnsigned)
|
||||
u = (uchar)va_arg(f->args, int);
|
||||
else
|
||||
u = (char)va_arg(f->args, int);
|
||||
}else if(fl & FmtShort){
|
||||
if(fl & FmtUnsigned)
|
||||
u = (ushort)va_arg(f->args, int);
|
||||
else
|
||||
u = (short)va_arg(f->args, int);
|
||||
}else{
|
||||
if(fl & FmtUnsigned)
|
||||
u = va_arg(f->args, uint);
|
||||
else
|
||||
u = va_arg(f->args, int);
|
||||
}
|
||||
conv = "0123456789abcdef";
|
||||
grouping = "\4"; /* for hex, octal etc. (undefined by spec but nice) */
|
||||
thousands = f->thousands;
|
||||
switch(f->r){
|
||||
case 'd':
|
||||
case 'i':
|
||||
case 'u':
|
||||
base = 10;
|
||||
grouping = f->grouping;
|
||||
break;
|
||||
case 'X':
|
||||
conv = "0123456789ABCDEF";
|
||||
/* fall through */
|
||||
case 'x':
|
||||
base = 16;
|
||||
thousands = ":";
|
||||
break;
|
||||
case 'b':
|
||||
base = 2;
|
||||
thousands = ":";
|
||||
break;
|
||||
case 'o':
|
||||
base = 8;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if(!(fl & FmtUnsigned)){
|
||||
if(isv && (vlong)vu < 0){
|
||||
vu = -(vlong)vu;
|
||||
neg = 1;
|
||||
}else if(!isv && (long)u < 0){
|
||||
u = -(long)u;
|
||||
neg = 1;
|
||||
}
|
||||
}
|
||||
p = buf + sizeof buf - 1;
|
||||
n = 0; /* in runes */
|
||||
excess = 0; /* number of bytes > number runes */
|
||||
ndig = 0;
|
||||
len = utflen(thousands);
|
||||
bytelen = strlen(thousands);
|
||||
if(isv){
|
||||
while(vu){
|
||||
i = vu % base;
|
||||
vu /= base;
|
||||
if((fl & FmtComma) && n % 4 == 3){
|
||||
*p-- = ',';
|
||||
n++;
|
||||
}
|
||||
if((fl & FmtApost) && __needsep(&ndig, &grouping)){
|
||||
n += len;
|
||||
excess += bytelen - len;
|
||||
p -= bytelen;
|
||||
memmove(p+1, thousands, bytelen);
|
||||
}
|
||||
*p-- = conv[i];
|
||||
n++;
|
||||
}
|
||||
}else{
|
||||
while(u){
|
||||
i = u % base;
|
||||
u /= base;
|
||||
if((fl & FmtComma) && n % 4 == 3){
|
||||
*p-- = ',';
|
||||
n++;
|
||||
}
|
||||
if((fl & FmtApost) && __needsep(&ndig, &grouping)){
|
||||
n += len;
|
||||
excess += bytelen - len;
|
||||
p -= bytelen;
|
||||
memmove(p+1, thousands, bytelen);
|
||||
}
|
||||
*p-- = conv[i];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if(n == 0){
|
||||
/*
|
||||
* "The result of converting a zero value with
|
||||
* a precision of zero is no characters." - ANSI
|
||||
*
|
||||
* "For o conversion, # increases the precision, if and only if
|
||||
* necessary, to force the first digit of the result to be a zero
|
||||
* (if the value and precision are both 0, a single 0 is printed)." - ANSI
|
||||
*/
|
||||
if(!(fl & FmtPrec) || f->prec != 0 || (f->r == 'o' && (fl & FmtSharp))){
|
||||
*p-- = '0';
|
||||
n = 1;
|
||||
if(fl & FmtApost)
|
||||
__needsep(&ndig, &grouping);
|
||||
}
|
||||
|
||||
/*
|
||||
* Zero values don't get 0x.
|
||||
*/
|
||||
if(f->r == 'x' || f->r == 'X')
|
||||
fl &= ~FmtSharp;
|
||||
}
|
||||
for(w = f->prec; n < w && p > buf+3; n++){
|
||||
if((fl & FmtApost) && __needsep(&ndig, &grouping)){
|
||||
n += len;
|
||||
excess += bytelen - len;
|
||||
p -= bytelen;
|
||||
memmove(p+1, thousands, bytelen);
|
||||
}
|
||||
*p-- = '0';
|
||||
}
|
||||
if(neg || (fl & (FmtSign|FmtSpace)))
|
||||
n++;
|
||||
if(fl & FmtSharp){
|
||||
if(base == 16)
|
||||
n += 2;
|
||||
else if(base == 8){
|
||||
if(p[1] == '0')
|
||||
fl &= ~FmtSharp;
|
||||
else
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
|
||||
w = 0;
|
||||
if(fl & FmtWidth)
|
||||
w = f->width;
|
||||
for(; n < w && p > buf+3; n++){
|
||||
if((fl & FmtApost) && __needsep(&ndig, &grouping)){
|
||||
n += len;
|
||||
excess += bytelen - len;
|
||||
p -= bytelen;
|
||||
memmove(p+1, thousands, bytelen);
|
||||
}
|
||||
*p-- = '0';
|
||||
}
|
||||
f->flags &= ~FmtWidth;
|
||||
}
|
||||
if(fl & FmtSharp){
|
||||
if(base == 16)
|
||||
*p-- = f->r;
|
||||
if(base == 16 || base == 8)
|
||||
*p-- = '0';
|
||||
}
|
||||
if(neg)
|
||||
*p-- = '-';
|
||||
else if(fl & FmtSign)
|
||||
*p-- = '+';
|
||||
else if(fl & FmtSpace)
|
||||
*p-- = ' ';
|
||||
f->flags &= ~FmtPrec;
|
||||
return __fmtcpy(f, p + 1, n, n + excess);
|
||||
}
|
||||
|
||||
int
|
||||
__countfmt(Fmt *f)
|
||||
{
|
||||
void *p;
|
||||
ulong fl;
|
||||
|
||||
fl = f->flags;
|
||||
p = va_arg(f->args, void*);
|
||||
if(fl & FmtVLong){
|
||||
*(vlong*)p = f->nfmt;
|
||||
}else if(fl & FmtLong){
|
||||
*(long*)p = f->nfmt;
|
||||
}else if(fl & FmtByte){
|
||||
*(char*)p = f->nfmt;
|
||||
}else if(fl & FmtShort){
|
||||
*(short*)p = f->nfmt;
|
||||
}else{
|
||||
*(int*)p = f->nfmt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__flagfmt(Fmt *f)
|
||||
{
|
||||
switch(f->r){
|
||||
case ',':
|
||||
f->flags |= FmtComma;
|
||||
break;
|
||||
case '-':
|
||||
f->flags |= FmtLeft;
|
||||
break;
|
||||
case '+':
|
||||
f->flags |= FmtSign;
|
||||
break;
|
||||
case '#':
|
||||
f->flags |= FmtSharp;
|
||||
break;
|
||||
case '\'':
|
||||
f->flags |= FmtApost;
|
||||
break;
|
||||
case ' ':
|
||||
f->flags |= FmtSpace;
|
||||
break;
|
||||
case 'u':
|
||||
f->flags |= FmtUnsigned;
|
||||
break;
|
||||
case 'h':
|
||||
if(f->flags & FmtShort)
|
||||
f->flags |= FmtByte;
|
||||
f->flags |= FmtShort;
|
||||
break;
|
||||
case 'L':
|
||||
f->flags |= FmtLDouble;
|
||||
break;
|
||||
case 'l':
|
||||
if(f->flags & FmtLong)
|
||||
f->flags |= FmtVLong;
|
||||
f->flags |= FmtLong;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* default error format */
|
||||
int
|
||||
__badfmt(Fmt *f)
|
||||
{
|
||||
char x[3];
|
||||
|
||||
x[0] = '%';
|
||||
x[1] = f->r;
|
||||
x[2] = '%';
|
||||
f->prec = 3;
|
||||
__fmtcpy(f, (const void*)x, 3, 3);
|
||||
return 0;
|
||||
}
|
65
src/lib9/fmt/dorfmt.c
Normal file
65
src/lib9/fmt/dorfmt.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/* format the output into f->to and return the number of characters fmted */
|
||||
|
||||
/* BUG: THIS FILE IS NOT UPDATED TO THE NEW SPEC */
|
||||
int
|
||||
dorfmt(Fmt *f, const Rune *fmt)
|
||||
{
|
||||
Rune *rt, *rs;
|
||||
int r;
|
||||
char *t, *s;
|
||||
int nfmt;
|
||||
|
||||
nfmt = f->nfmt;
|
||||
for(;;){
|
||||
if(f->runes){
|
||||
rt = (Rune*)f->to;
|
||||
rs = (Rune*)f->stop;
|
||||
while((r = *fmt++) && r != '%'){
|
||||
FMTRCHAR(f, rt, rs, r);
|
||||
}
|
||||
f->nfmt += rt - (Rune *)f->to;
|
||||
f->to = rt;
|
||||
if(!r)
|
||||
return f->nfmt - nfmt;
|
||||
f->stop = rs;
|
||||
}else{
|
||||
t = (char*)f->to;
|
||||
s = (char*)f->stop;
|
||||
while((r = *fmt++) && r != '%'){
|
||||
FMTRUNE(f, t, f->stop, r);
|
||||
}
|
||||
f->nfmt += t - (char *)f->to;
|
||||
f->to = t;
|
||||
if(!r)
|
||||
return f->nfmt - nfmt;
|
||||
f->stop = s;
|
||||
}
|
||||
|
||||
fmt = (Rune*)__fmtdispatch(f, (Rune*)fmt, 1);
|
||||
if(fmt == nil)
|
||||
return -1;
|
||||
}
|
||||
return 0; /* not reached */
|
||||
}
|
30
src/lib9/fmt/errfmt.c
Normal file
30
src/lib9/fmt/errfmt.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
__errfmt(Fmt *f)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = strerror(errno);
|
||||
return fmtstrcpy(f, s);
|
||||
}
|
677
src/lib9/fmt/fltfmt.c
Normal file
677
src/lib9/fmt/fltfmt.c
Normal file
|
@ -0,0 +1,677 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <errno.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
enum
|
||||
{
|
||||
FDIGIT = 30,
|
||||
FDEFLT = 6,
|
||||
NSIGNIF = 17
|
||||
};
|
||||
|
||||
/*
|
||||
* first few powers of 10, enough for about 1/2 of the
|
||||
* total space for doubles.
|
||||
*/
|
||||
static double pows10[] =
|
||||
{
|
||||
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
||||
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
|
||||
1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
|
||||
1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
|
||||
1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
|
||||
1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
|
||||
1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
|
||||
1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
|
||||
1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
|
||||
1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
|
||||
1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
|
||||
1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
|
||||
1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
|
||||
1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
|
||||
1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
|
||||
1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
|
||||
};
|
||||
#define npows10 ((int)(sizeof(pows10)/sizeof(pows10[0])))
|
||||
#undef pow10
|
||||
#define pow10 fmtpow10
|
||||
|
||||
static double
|
||||
pow10(int n)
|
||||
{
|
||||
double d;
|
||||
int neg;
|
||||
|
||||
neg = 0;
|
||||
if(n < 0){
|
||||
neg = 1;
|
||||
n = -n;
|
||||
}
|
||||
|
||||
if(n < npows10)
|
||||
d = pows10[n];
|
||||
else{
|
||||
d = pows10[npows10-1];
|
||||
for(;;){
|
||||
n -= npows10 - 1;
|
||||
if(n < npows10){
|
||||
d *= pows10[n];
|
||||
break;
|
||||
}
|
||||
d *= pows10[npows10 - 1];
|
||||
}
|
||||
}
|
||||
if(neg)
|
||||
return 1./d;
|
||||
return d;
|
||||
}
|
||||
|
||||
/*
|
||||
* add 1 to the decimal integer string a of length n.
|
||||
* if 99999 overflows into 10000, return 1 to tell caller
|
||||
* to move the virtual decimal point.
|
||||
*/
|
||||
static int
|
||||
xadd1(char *a, int n)
|
||||
{
|
||||
char *b;
|
||||
int c;
|
||||
|
||||
if(n < 0 || n > NSIGNIF)
|
||||
return 0;
|
||||
for(b = a+n-1; b >= a; b--) {
|
||||
c = *b + 1;
|
||||
if(c <= '9') {
|
||||
*b = c;
|
||||
return 0;
|
||||
}
|
||||
*b = '0';
|
||||
}
|
||||
/*
|
||||
* need to overflow adding digit.
|
||||
* shift number down and insert 1 at beginning.
|
||||
* decimal is known to be 0s or we wouldn't
|
||||
* have gotten this far. (e.g., 99999+1 => 00000)
|
||||
*/
|
||||
a[0] = '1';
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* subtract 1 from the decimal integer string a.
|
||||
* if 10000 underflows into 09999, make it 99999
|
||||
* and return 1 to tell caller to move the virtual
|
||||
* decimal point. this way, xsub1 is inverse of xadd1.
|
||||
*/
|
||||
static int
|
||||
xsub1(char *a, int n)
|
||||
{
|
||||
char *b;
|
||||
int c;
|
||||
|
||||
if(n < 0 || n > NSIGNIF)
|
||||
return 0;
|
||||
for(b = a+n-1; b >= a; b--) {
|
||||
c = *b - 1;
|
||||
if(c >= '0') {
|
||||
if(c == '0' && b == a) {
|
||||
/*
|
||||
* just zeroed the top digit; shift everyone up.
|
||||
* decimal is known to be 9s or we wouldn't
|
||||
* have gotten this far. (e.g., 10000-1 => 09999)
|
||||
*/
|
||||
*b = '9';
|
||||
return 1;
|
||||
}
|
||||
*b = c;
|
||||
return 0;
|
||||
}
|
||||
*b = '9';
|
||||
}
|
||||
/*
|
||||
* can't get here. the number a is always normalized
|
||||
* so that it has a nonzero first digit.
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* format exponent like sprintf(p, "e%+02d", e)
|
||||
*/
|
||||
static void
|
||||
xfmtexp(char *p, int e, int ucase)
|
||||
{
|
||||
char se[9];
|
||||
int i;
|
||||
|
||||
*p++ = ucase ? 'E' : 'e';
|
||||
if(e < 0) {
|
||||
*p++ = '-';
|
||||
e = -e;
|
||||
} else
|
||||
*p++ = '+';
|
||||
i = 0;
|
||||
while(e) {
|
||||
se[i++] = e % 10 + '0';
|
||||
e /= 10;
|
||||
}
|
||||
while(i < 2)
|
||||
se[i++] = '0';
|
||||
while(i > 0)
|
||||
*p++ = se[--i];
|
||||
*p++ = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* compute decimal integer m, exp such that:
|
||||
* f = m*10^exp
|
||||
* m is as short as possible with losing exactness
|
||||
* assumes special cases (NaN, +Inf, -Inf) have been handled.
|
||||
*/
|
||||
static void
|
||||
xdtoa(double f, char *s, int *exp, int *neg, int *ns)
|
||||
{
|
||||
int c, d, e2, e, ee, i, ndigit, oerrno;
|
||||
char tmp[NSIGNIF+10];
|
||||
double g;
|
||||
|
||||
oerrno = errno; /* in case strtod smashes errno */
|
||||
|
||||
/*
|
||||
* make f non-negative.
|
||||
*/
|
||||
*neg = 0;
|
||||
if(f < 0) {
|
||||
f = -f;
|
||||
*neg = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* must handle zero specially.
|
||||
*/
|
||||
if(f == 0){
|
||||
*exp = 0;
|
||||
s[0] = '0';
|
||||
s[1] = '\0';
|
||||
*ns = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* find g,e such that f = g*10^e.
|
||||
* guess 10-exponent using 2-exponent, then fine tune.
|
||||
*/
|
||||
frexp(f, &e2);
|
||||
e = (int)(e2 * .301029995664);
|
||||
g = f * pow10(-e);
|
||||
while(g < 1) {
|
||||
e--;
|
||||
g = f * pow10(-e);
|
||||
}
|
||||
while(g >= 10) {
|
||||
e++;
|
||||
g = f * pow10(-e);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert NSIGNIF digits as a first approximation.
|
||||
*/
|
||||
for(i=0; i<NSIGNIF; i++) {
|
||||
d = (int)g;
|
||||
s[i] = d+'0';
|
||||
g = (g-d) * 10;
|
||||
}
|
||||
s[i] = 0;
|
||||
|
||||
/*
|
||||
* adjust e because s is 314159... not 3.14159...
|
||||
*/
|
||||
e -= NSIGNIF-1;
|
||||
xfmtexp(s+NSIGNIF, e, 0);
|
||||
|
||||
/*
|
||||
* adjust conversion until strtod(s) == f exactly.
|
||||
*/
|
||||
for(i=0; i<10; i++) {
|
||||
g = strtod(s, nil);
|
||||
if(f > g) {
|
||||
if(xadd1(s, NSIGNIF)) {
|
||||
/* gained a digit */
|
||||
e--;
|
||||
xfmtexp(s+NSIGNIF, e, 0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(f < g) {
|
||||
if(xsub1(s, NSIGNIF)) {
|
||||
/* lost a digit */
|
||||
e++;
|
||||
xfmtexp(s+NSIGNIF, e, 0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* play with the decimal to try to simplify.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bump last few digits up to 9 if we can
|
||||
*/
|
||||
for(i=NSIGNIF-1; i>=NSIGNIF-3; i--) {
|
||||
c = s[i];
|
||||
if(c != '9') {
|
||||
s[i] = '9';
|
||||
g = strtod(s, nil);
|
||||
if(g != f) {
|
||||
s[i] = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add 1 in hopes of turning 9s to 0s
|
||||
*/
|
||||
if(s[NSIGNIF-1] == '9') {
|
||||
strcpy(tmp, s);
|
||||
ee = e;
|
||||
if(xadd1(tmp, NSIGNIF)) {
|
||||
ee--;
|
||||
xfmtexp(tmp+NSIGNIF, ee, 0);
|
||||
}
|
||||
g = strtod(tmp, nil);
|
||||
if(g == f) {
|
||||
strcpy(s, tmp);
|
||||
e = ee;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bump last few digits down to 0 as we can.
|
||||
*/
|
||||
for(i=NSIGNIF-1; i>=NSIGNIF-3; i--) {
|
||||
c = s[i];
|
||||
if(c != '0') {
|
||||
s[i] = '0';
|
||||
g = strtod(s, nil);
|
||||
if(g != f) {
|
||||
s[i] = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remove trailing zeros.
|
||||
*/
|
||||
ndigit = NSIGNIF;
|
||||
while(ndigit > 1 && s[ndigit-1] == '0'){
|
||||
e++;
|
||||
--ndigit;
|
||||
}
|
||||
s[ndigit] = 0;
|
||||
*exp = e;
|
||||
*ns = ndigit;
|
||||
errno = oerrno;
|
||||
}
|
||||
|
||||
#ifdef PLAN9PORT
|
||||
static char *special[] = { "NaN", "NaN", "+Inf", "+Inf", "-Inf", "-Inf" };
|
||||
#else
|
||||
static char *special[] = { "nan", "NAN", "inf", "INF", "-inf", "-INF" };
|
||||
#endif
|
||||
|
||||
int
|
||||
__efgfmt(Fmt *fmt)
|
||||
{
|
||||
char buf[NSIGNIF+10], *dot, *digits, *p, *s, suf[10], *t;
|
||||
double f;
|
||||
int c, chr, dotwid, e, exp, fl, ndigits, neg, newndigits;
|
||||
int pad, point, prec, realchr, sign, sufwid, ucase, wid, z1, z2;
|
||||
Rune r, *rs, *rt;
|
||||
|
||||
if(fmt->flags&FmtLong)
|
||||
f = va_arg(fmt->args, long double);
|
||||
else
|
||||
f = va_arg(fmt->args, double);
|
||||
|
||||
/*
|
||||
* extract formatting flags
|
||||
*/
|
||||
fl = fmt->flags;
|
||||
fmt->flags = 0;
|
||||
prec = FDEFLT;
|
||||
if(fl & FmtPrec)
|
||||
prec = fmt->prec;
|
||||
chr = fmt->r;
|
||||
ucase = 0;
|
||||
switch(chr) {
|
||||
case 'A':
|
||||
case 'E':
|
||||
case 'F':
|
||||
case 'G':
|
||||
chr += 'a'-'A';
|
||||
ucase = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* pick off special numbers.
|
||||
*/
|
||||
if(__isNaN(f)) {
|
||||
s = special[0+ucase];
|
||||
special:
|
||||
fmt->flags = fl & (FmtWidth|FmtLeft);
|
||||
return __fmtcpy(fmt, s, strlen(s), strlen(s));
|
||||
}
|
||||
if(__isInf(f, 1)) {
|
||||
s = special[2+ucase];
|
||||
goto special;
|
||||
}
|
||||
if(__isInf(f, -1)) {
|
||||
s = special[4+ucase];
|
||||
goto special;
|
||||
}
|
||||
|
||||
/*
|
||||
* get exact representation.
|
||||
*/
|
||||
digits = buf;
|
||||
xdtoa(f, digits, &exp, &neg, &ndigits);
|
||||
|
||||
/*
|
||||
* get locale's decimal point.
|
||||
*/
|
||||
dot = fmt->decimal;
|
||||
if(dot == nil)
|
||||
dot = ".";
|
||||
dotwid = utflen(dot);
|
||||
|
||||
/*
|
||||
* now the formatting fun begins.
|
||||
* compute parameters for actual fmt:
|
||||
*
|
||||
* pad: number of spaces to insert before/after field.
|
||||
* z1: number of zeros to insert before digits
|
||||
* z2: number of zeros to insert after digits
|
||||
* point: number of digits to print before decimal point
|
||||
* ndigits: number of digits to use from digits[]
|
||||
* suf: trailing suffix, like "e-5"
|
||||
*/
|
||||
realchr = chr;
|
||||
switch(chr){
|
||||
case 'g':
|
||||
/*
|
||||
* convert to at most prec significant digits. (prec=0 means 1)
|
||||
*/
|
||||
if(prec == 0)
|
||||
prec = 1;
|
||||
if(ndigits > prec) {
|
||||
if(digits[prec] >= '5' && xadd1(digits, prec))
|
||||
exp++;
|
||||
exp += ndigits-prec;
|
||||
ndigits = prec;
|
||||
}
|
||||
|
||||
/*
|
||||
* extra rules for %g (implemented below):
|
||||
* trailing zeros removed after decimal unless FmtSharp.
|
||||
* decimal point only if digit follows.
|
||||
*/
|
||||
|
||||
/* fall through to %e */
|
||||
default:
|
||||
case 'e':
|
||||
/*
|
||||
* one significant digit before decimal, no leading zeros.
|
||||
*/
|
||||
point = 1;
|
||||
z1 = 0;
|
||||
|
||||
/*
|
||||
* decimal point is after ndigits digits right now.
|
||||
* slide to be after first.
|
||||
*/
|
||||
e = exp + (ndigits-1);
|
||||
|
||||
/*
|
||||
* if this is %g, check exponent and convert prec
|
||||
*/
|
||||
if(realchr == 'g') {
|
||||
if(-4 <= e && e < prec)
|
||||
goto casef;
|
||||
prec--; /* one digit before decimal; rest after */
|
||||
}
|
||||
|
||||
/*
|
||||
* compute trailing zero padding or truncate digits.
|
||||
*/
|
||||
if(1+prec >= ndigits)
|
||||
z2 = 1+prec - ndigits;
|
||||
else {
|
||||
/*
|
||||
* truncate digits
|
||||
*/
|
||||
assert(realchr != 'g');
|
||||
newndigits = 1+prec;
|
||||
if(digits[newndigits] >= '5' && xadd1(digits, newndigits)) {
|
||||
/*
|
||||
* had 999e4, now have 100e5
|
||||
*/
|
||||
e++;
|
||||
}
|
||||
ndigits = newndigits;
|
||||
z2 = 0;
|
||||
}
|
||||
xfmtexp(suf, e, ucase);
|
||||
sufwid = strlen(suf);
|
||||
break;
|
||||
|
||||
casef:
|
||||
case 'f':
|
||||
/*
|
||||
* determine where digits go with respect to decimal point
|
||||
*/
|
||||
if(ndigits+exp > 0) {
|
||||
point = ndigits+exp;
|
||||
z1 = 0;
|
||||
} else {
|
||||
point = 1;
|
||||
z1 = 1 + -(ndigits+exp);
|
||||
}
|
||||
|
||||
/*
|
||||
* %g specifies prec = number of significant digits
|
||||
* convert to number of digits after decimal point
|
||||
*/
|
||||
if(realchr == 'g')
|
||||
prec += z1 - point;
|
||||
|
||||
/*
|
||||
* compute trailing zero padding or truncate digits.
|
||||
*/
|
||||
if(point+prec >= z1+ndigits)
|
||||
z2 = point+prec - (z1+ndigits);
|
||||
else {
|
||||
/*
|
||||
* truncate digits
|
||||
*/
|
||||
assert(realchr != 'g');
|
||||
newndigits = point+prec - z1;
|
||||
if(newndigits < 0) {
|
||||
z1 += newndigits;
|
||||
newndigits = 0;
|
||||
} else if(newndigits == 0) {
|
||||
/* perhaps round up */
|
||||
if(digits[0] >= '5'){
|
||||
digits[0] = '1';
|
||||
newndigits = 1;
|
||||
goto newdigit;
|
||||
}
|
||||
} else if(digits[newndigits] >= '5' && xadd1(digits, newndigits)) {
|
||||
/*
|
||||
* digits was 999, is now 100; make it 1000
|
||||
*/
|
||||
digits[newndigits++] = '0';
|
||||
newdigit:
|
||||
/*
|
||||
* account for new digit
|
||||
*/
|
||||
if(z1) /* 0.099 => 0.100 or 0.99 => 1.00*/
|
||||
z1--;
|
||||
else /* 9.99 => 10.00 */
|
||||
point++;
|
||||
}
|
||||
z2 = 0;
|
||||
ndigits = newndigits;
|
||||
}
|
||||
sufwid = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* if %g is given without FmtSharp, remove trailing zeros.
|
||||
* must do after truncation, so that e.g. print %.3g 1.001
|
||||
* produces 1, not 1.00. sorry, but them's the rules.
|
||||
*/
|
||||
if(realchr == 'g' && !(fl & FmtSharp)) {
|
||||
if(z1+ndigits+z2 >= point) {
|
||||
if(z1+ndigits < point)
|
||||
z2 = point - (z1+ndigits);
|
||||
else{
|
||||
z2 = 0;
|
||||
while(z1+ndigits > point && digits[ndigits-1] == '0')
|
||||
ndigits--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* compute width of all digits and decimal point and suffix if any
|
||||
*/
|
||||
wid = z1+ndigits+z2;
|
||||
if(wid > point)
|
||||
wid += dotwid;
|
||||
else if(wid == point){
|
||||
if(fl & FmtSharp)
|
||||
wid += dotwid;
|
||||
else
|
||||
point++; /* do not print any decimal point */
|
||||
}
|
||||
wid += sufwid;
|
||||
|
||||
/*
|
||||
* determine sign
|
||||
*/
|
||||
sign = 0;
|
||||
if(neg)
|
||||
sign = '-';
|
||||
else if(fl & FmtSign)
|
||||
sign = '+';
|
||||
else if(fl & FmtSpace)
|
||||
sign = ' ';
|
||||
if(sign)
|
||||
wid++;
|
||||
|
||||
/*
|
||||
* compute padding
|
||||
*/
|
||||
pad = 0;
|
||||
if((fl & FmtWidth) && fmt->width > wid)
|
||||
pad = fmt->width - wid;
|
||||
if(pad && !(fl & FmtLeft) && (fl & FmtZero)){
|
||||
z1 += pad;
|
||||
point += pad;
|
||||
pad = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* format the actual field. too bad about doing this twice.
|
||||
*/
|
||||
if(fmt->runes){
|
||||
if(pad && !(fl & FmtLeft) && __rfmtpad(fmt, pad) < 0)
|
||||
return -1;
|
||||
rt = (Rune*)fmt->to;
|
||||
rs = (Rune*)fmt->stop;
|
||||
if(sign)
|
||||
FMTRCHAR(fmt, rt, rs, sign);
|
||||
while(z1>0 || ndigits>0 || z2>0) {
|
||||
if(z1 > 0){
|
||||
z1--;
|
||||
c = '0';
|
||||
}else if(ndigits > 0){
|
||||
ndigits--;
|
||||
c = *digits++;
|
||||
}else{
|
||||
z2--;
|
||||
c = '0';
|
||||
}
|
||||
FMTRCHAR(fmt, rt, rs, c);
|
||||
if(--point == 0) {
|
||||
for(p = dot; *p; ){
|
||||
p += chartorune(&r, p);
|
||||
FMTRCHAR(fmt, rt, rs, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt->nfmt += rt - (Rune*)fmt->to;
|
||||
fmt->to = rt;
|
||||
if(sufwid && __fmtcpy(fmt, suf, sufwid, sufwid) < 0)
|
||||
return -1;
|
||||
if(pad && (fl & FmtLeft) && __rfmtpad(fmt, pad) < 0)
|
||||
return -1;
|
||||
}else{
|
||||
if(pad && !(fl & FmtLeft) && __fmtpad(fmt, pad) < 0)
|
||||
return -1;
|
||||
t = (char*)fmt->to;
|
||||
s = (char*)fmt->stop;
|
||||
if(sign)
|
||||
FMTCHAR(fmt, t, s, sign);
|
||||
while(z1>0 || ndigits>0 || z2>0) {
|
||||
if(z1 > 0){
|
||||
z1--;
|
||||
c = '0';
|
||||
}else if(ndigits > 0){
|
||||
ndigits--;
|
||||
c = *digits++;
|
||||
}else{
|
||||
z2--;
|
||||
c = '0';
|
||||
}
|
||||
FMTCHAR(fmt, t, s, c);
|
||||
if(--point == 0)
|
||||
for(p=dot; *p; p++)
|
||||
FMTCHAR(fmt, t, s, *p);
|
||||
}
|
||||
fmt->nfmt += t - (char*)fmt->to;
|
||||
fmt->to = t;
|
||||
if(sufwid && __fmtcpy(fmt, suf, sufwid, sufwid) < 0)
|
||||
return -1;
|
||||
if(pad && (fl & FmtLeft) && __fmtpad(fmt, pad) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
235
src/lib9/fmt/fmt.c
Normal file
235
src/lib9/fmt/fmt.c
Normal file
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
enum
|
||||
{
|
||||
Maxfmt = 64
|
||||
};
|
||||
|
||||
typedef struct Convfmt Convfmt;
|
||||
struct Convfmt
|
||||
{
|
||||
int c;
|
||||
volatile Fmts fmt; /* for spin lock in fmtfmt; avoids race due to write order */
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
/* lock by calling __fmtlock, __fmtunlock */
|
||||
int nfmt;
|
||||
Convfmt fmt[Maxfmt];
|
||||
} fmtalloc;
|
||||
|
||||
static Convfmt knownfmt[] = {
|
||||
' ', __flagfmt,
|
||||
'#', __flagfmt,
|
||||
'%', __percentfmt,
|
||||
'\'', __flagfmt,
|
||||
'+', __flagfmt,
|
||||
',', __flagfmt,
|
||||
'-', __flagfmt,
|
||||
'C', __runefmt, /* Plan 9 addition */
|
||||
'E', __efgfmt,
|
||||
#ifndef PLAN9PORT
|
||||
'F', __efgfmt, /* ANSI only */
|
||||
#endif
|
||||
'G', __efgfmt,
|
||||
#ifndef PLAN9PORT
|
||||
'L', __flagfmt, /* ANSI only */
|
||||
#endif
|
||||
'S', __runesfmt, /* Plan 9 addition */
|
||||
'X', __ifmt,
|
||||
'b', __ifmt, /* Plan 9 addition */
|
||||
'c', __charfmt,
|
||||
'd', __ifmt,
|
||||
'e', __efgfmt,
|
||||
'f', __efgfmt,
|
||||
'g', __efgfmt,
|
||||
'h', __flagfmt,
|
||||
#ifndef PLAN9PORT
|
||||
'i', __ifmt, /* ANSI only */
|
||||
#endif
|
||||
'l', __flagfmt,
|
||||
'n', __countfmt,
|
||||
'o', __ifmt,
|
||||
'p', __ifmt,
|
||||
'r', __errfmt,
|
||||
's', __strfmt,
|
||||
#ifdef PLAN9PORT
|
||||
'u', __flagfmt,
|
||||
#else
|
||||
'u', __ifmt,
|
||||
#endif
|
||||
'x', __ifmt,
|
||||
0, nil,
|
||||
};
|
||||
|
||||
|
||||
int (*fmtdoquote)(int);
|
||||
|
||||
/*
|
||||
* __fmtlock() must be set
|
||||
*/
|
||||
static int
|
||||
__fmtinstall(int c, Fmts f)
|
||||
{
|
||||
Convfmt *p, *ep;
|
||||
|
||||
if(c<=0 || c>=65536)
|
||||
return -1;
|
||||
if(!f)
|
||||
f = __badfmt;
|
||||
|
||||
ep = &fmtalloc.fmt[fmtalloc.nfmt];
|
||||
for(p=fmtalloc.fmt; p<ep; p++)
|
||||
if(p->c == c)
|
||||
break;
|
||||
|
||||
if(p == &fmtalloc.fmt[Maxfmt])
|
||||
return -1;
|
||||
|
||||
p->fmt = f;
|
||||
if(p == ep){ /* installing a new format character */
|
||||
fmtalloc.nfmt++;
|
||||
p->c = c;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fmtinstall(int c, int (*f)(Fmt*))
|
||||
{
|
||||
int ret;
|
||||
|
||||
__fmtlock();
|
||||
ret = __fmtinstall(c, f);
|
||||
__fmtunlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Fmts
|
||||
fmtfmt(int c)
|
||||
{
|
||||
Convfmt *p, *ep;
|
||||
|
||||
ep = &fmtalloc.fmt[fmtalloc.nfmt];
|
||||
for(p=fmtalloc.fmt; p<ep; p++)
|
||||
if(p->c == c){
|
||||
while(p->fmt == nil) /* loop until value is updated */
|
||||
;
|
||||
return p->fmt;
|
||||
}
|
||||
|
||||
/* is this a predefined format char? */
|
||||
__fmtlock();
|
||||
for(p=knownfmt; p->c; p++)
|
||||
if(p->c == c){
|
||||
__fmtinstall(p->c, p->fmt);
|
||||
__fmtunlock();
|
||||
return p->fmt;
|
||||
}
|
||||
__fmtunlock();
|
||||
|
||||
return __badfmt;
|
||||
}
|
||||
|
||||
void*
|
||||
__fmtdispatch(Fmt *f, void *fmt, int isrunes)
|
||||
{
|
||||
Rune rune, r;
|
||||
int i, n;
|
||||
|
||||
f->flags = 0;
|
||||
f->width = f->prec = 0;
|
||||
|
||||
for(;;){
|
||||
if(isrunes){
|
||||
r = *(Rune*)fmt;
|
||||
fmt = (Rune*)fmt + 1;
|
||||
}else{
|
||||
fmt = (char*)fmt + chartorune(&rune, (char*)fmt);
|
||||
r = rune;
|
||||
}
|
||||
f->r = r;
|
||||
switch(r){
|
||||
case '\0':
|
||||
return nil;
|
||||
case '.':
|
||||
f->flags |= FmtWidth|FmtPrec;
|
||||
continue;
|
||||
case '0':
|
||||
if(!(f->flags & FmtWidth)){
|
||||
f->flags |= FmtZero;
|
||||
continue;
|
||||
}
|
||||
/* fall through */
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
i = 0;
|
||||
while(r >= '0' && r <= '9'){
|
||||
i = i * 10 + r - '0';
|
||||
if(isrunes){
|
||||
r = *(Rune*)fmt;
|
||||
fmt = (Rune*)fmt + 1;
|
||||
}else{
|
||||
r = *(char*)fmt;
|
||||
fmt = (char*)fmt + 1;
|
||||
}
|
||||
}
|
||||
if(isrunes)
|
||||
fmt = (Rune*)fmt - 1;
|
||||
else
|
||||
fmt = (char*)fmt - 1;
|
||||
numflag:
|
||||
if(f->flags & FmtWidth){
|
||||
f->flags |= FmtPrec;
|
||||
f->prec = i;
|
||||
}else{
|
||||
f->flags |= FmtWidth;
|
||||
f->width = i;
|
||||
}
|
||||
continue;
|
||||
case '*':
|
||||
i = va_arg(f->args, int);
|
||||
if(i < 0){
|
||||
/*
|
||||
* negative precision =>
|
||||
* ignore the precision.
|
||||
*/
|
||||
if(f->flags & FmtPrec){
|
||||
f->flags &= ~FmtPrec;
|
||||
f->prec = 0;
|
||||
continue;
|
||||
}
|
||||
i = -i;
|
||||
f->flags |= FmtLeft;
|
||||
}
|
||||
goto numflag;
|
||||
}
|
||||
n = (*fmtfmt(r))(f);
|
||||
if(n < 0)
|
||||
return nil;
|
||||
if(n == 0)
|
||||
return fmt;
|
||||
}
|
||||
}
|
119
src/lib9/fmt/fmtdef.h
Normal file
119
src/lib9/fmt/fmtdef.h
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* dofmt -- format to a buffer
|
||||
* the number of characters formatted is returned,
|
||||
* or -1 if there was an error.
|
||||
* if the buffer is ever filled, flush is called.
|
||||
* it should reset the buffer and return whether formatting should continue.
|
||||
*/
|
||||
|
||||
typedef int (*Fmts)(Fmt*);
|
||||
|
||||
typedef struct Quoteinfo Quoteinfo;
|
||||
struct Quoteinfo
|
||||
{
|
||||
int quoted; /* if set, string must be quoted */
|
||||
int nrunesin; /* number of input runes that can be accepted */
|
||||
int nbytesin; /* number of input bytes that can be accepted */
|
||||
int nrunesout; /* number of runes that will be generated */
|
||||
int nbytesout; /* number of bytes that will be generated */
|
||||
};
|
||||
|
||||
/* Edit .+1,/^$/ |cfn |grep -v static | grep __ */
|
||||
double __Inf(int sign);
|
||||
double __NaN(void);
|
||||
int __badfmt(Fmt *f);
|
||||
int __charfmt(Fmt *f);
|
||||
int __countfmt(Fmt *f);
|
||||
int __efgfmt(Fmt *fmt);
|
||||
int __errfmt(Fmt *f);
|
||||
int __flagfmt(Fmt *f);
|
||||
int __fmtFdFlush(Fmt *f);
|
||||
int __fmtcpy(Fmt *f, const void *vm, int n, int sz);
|
||||
void* __fmtdispatch(Fmt *f, void *fmt, int isrunes);
|
||||
void * __fmtflush(Fmt *f, void *t, int len);
|
||||
void __fmtlock(void);
|
||||
int __fmtpad(Fmt *f, int n);
|
||||
double __fmtpow10(int n);
|
||||
int __fmtrcpy(Fmt *f, const void *vm, int n);
|
||||
void __fmtunlock(void);
|
||||
int __ifmt(Fmt *f);
|
||||
int __isInf(double d, int sign);
|
||||
int __isNaN(double d);
|
||||
int __needsep(int*, char**);
|
||||
int __needsquotes(char *s, int *quotelenp);
|
||||
int __percentfmt(Fmt *f);
|
||||
void __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout);
|
||||
int __quotestrfmt(int runesin, Fmt *f);
|
||||
int __rfmtpad(Fmt *f, int n);
|
||||
int __runefmt(Fmt *f);
|
||||
int __runeneedsquotes(Rune *r, int *quotelenp);
|
||||
int __runesfmt(Fmt *f);
|
||||
int __strfmt(Fmt *f);
|
||||
|
||||
#define FMTCHAR(f, t, s, c)\
|
||||
do{\
|
||||
if(t + 1 > (char*)s){\
|
||||
t = (char*)__fmtflush(f, t, 1);\
|
||||
if(t != nil)\
|
||||
s = (char*)f->stop;\
|
||||
else\
|
||||
return -1;\
|
||||
}\
|
||||
*t++ = c;\
|
||||
}while(0)
|
||||
|
||||
#define FMTRCHAR(f, t, s, c)\
|
||||
do{\
|
||||
if(t + 1 > (Rune*)s){\
|
||||
t = (Rune*)__fmtflush(f, t, sizeof(Rune));\
|
||||
if(t != nil)\
|
||||
s = (Rune*)f->stop;\
|
||||
else\
|
||||
return -1;\
|
||||
}\
|
||||
*t++ = c;\
|
||||
}while(0)
|
||||
|
||||
#define FMTRUNE(f, t, s, r)\
|
||||
do{\
|
||||
Rune _rune;\
|
||||
int _runelen;\
|
||||
if(t + UTFmax > (char*)s && t + (_runelen = runelen(r)) > (char*)s){\
|
||||
t = (char*)__fmtflush(f, t, _runelen);\
|
||||
if(t != nil)\
|
||||
s = (char*)f->stop;\
|
||||
else\
|
||||
return -1;\
|
||||
}\
|
||||
if(r < Runeself)\
|
||||
*t++ = r;\
|
||||
else{\
|
||||
_rune = r;\
|
||||
t += runetochar(t, &_rune);\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#ifdef va_copy
|
||||
# define VA_COPY(a,b) va_copy(a,b)
|
||||
# define VA_END(a) va_end(a)
|
||||
#else
|
||||
# define VA_COPY(a,b) (a) = (b)
|
||||
# define VA_END(a)
|
||||
#endif
|
||||
|
51
src/lib9/fmt/fmtfd.c
Normal file
51
src/lib9/fmt/fmtfd.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* public routine for final flush of a formatting buffer
|
||||
* to a file descriptor; returns total char count.
|
||||
*/
|
||||
int
|
||||
fmtfdflush(Fmt *f)
|
||||
{
|
||||
if(__fmtFdFlush(f) <= 0)
|
||||
return -1;
|
||||
return f->nfmt;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize an output buffer for buffered printing
|
||||
*/
|
||||
int
|
||||
fmtfdinit(Fmt *f, int fd, char *buf, int size)
|
||||
{
|
||||
f->runes = 0;
|
||||
f->start = buf;
|
||||
f->to = buf;
|
||||
f->stop = buf + size;
|
||||
f->flush = __fmtFdFlush;
|
||||
f->farg = (void*)(uintptr_t)fd;
|
||||
f->flags = 0;
|
||||
f->nfmt = 0;
|
||||
fmtlocaleinit(f, nil, nil, nil);
|
||||
return 0;
|
||||
}
|
37
src/lib9/fmt/fmtfdflush.c
Normal file
37
src/lib9/fmt/fmtfdflush.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* generic routine for flushing a formatting buffer
|
||||
* to a file descriptor
|
||||
*/
|
||||
int
|
||||
__fmtFdFlush(Fmt *f)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = (char*)f->to - (char*)f->start;
|
||||
if(n && write((uintptr)f->farg, f->start, n) != n)
|
||||
return 0;
|
||||
f->to = f->start;
|
||||
return 1;
|
||||
}
|
69
src/lib9/fmt/fmtlocale.c
Normal file
69
src/lib9/fmt/fmtlocale.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* Fill in the internationalization stuff in the State structure.
|
||||
* For nil arguments, provide the sensible defaults:
|
||||
* decimal is a period
|
||||
* thousands separator is a comma
|
||||
* thousands are marked every three digits
|
||||
*/
|
||||
void
|
||||
fmtlocaleinit(Fmt *f, char *decimal, char *thousands, char *grouping)
|
||||
{
|
||||
if(decimal == nil || decimal[0] == '\0')
|
||||
decimal = ".";
|
||||
if(thousands == nil)
|
||||
thousands = ",";
|
||||
if(grouping == nil)
|
||||
grouping = "\3";
|
||||
f->decimal = decimal;
|
||||
f->thousands = thousands;
|
||||
f->grouping = grouping;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are about to emit a digit in e.g. %'d. If that digit would
|
||||
* overflow a thousands (e.g.) grouping, tell the caller to emit
|
||||
* the thousands separator. Always advance the digit counter
|
||||
* and pointer into the grouping descriptor.
|
||||
*/
|
||||
int
|
||||
__needsep(int *ndig, char **grouping)
|
||||
{
|
||||
int group;
|
||||
|
||||
(*ndig)++;
|
||||
group = *(unsigned char*)*grouping;
|
||||
/* CHAR_MAX means no further grouping. \0 means we got the empty string */
|
||||
if(group == 0xFF || group == 0x7f || group == 0x00)
|
||||
return 0;
|
||||
if(*ndig > group){
|
||||
/* if we're at end of string, continue with this grouping; else advance */
|
||||
if((*grouping)[1] != '\0')
|
||||
(*grouping)++;
|
||||
*ndig = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
31
src/lib9/fmt/fmtlock.c
Normal file
31
src/lib9/fmt/fmtlock.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
void
|
||||
__fmtlock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
__fmtunlock(void)
|
||||
{
|
||||
}
|
48
src/lib9/fmt/fmtnull.c
Normal file
48
src/lib9/fmt/fmtnull.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* Absorb output without using resources.
|
||||
*/
|
||||
static Rune nullbuf[32];
|
||||
|
||||
static int
|
||||
__fmtnullflush(Fmt *f)
|
||||
{
|
||||
f->to = nullbuf;
|
||||
f->nfmt = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fmtnullinit(Fmt *f)
|
||||
{
|
||||
memset(f, 0, sizeof *f);
|
||||
f->runes = 1;
|
||||
f->start = nullbuf;
|
||||
f->to = nullbuf;
|
||||
f->stop = nullbuf+nelem(nullbuf);
|
||||
f->flush = __fmtnullflush;
|
||||
fmtlocaleinit(f, nil, nil, nil);
|
||||
return 0;
|
||||
}
|
||||
|
51
src/lib9/fmt/fmtprint.c
Normal file
51
src/lib9/fmt/fmtprint.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* format a string into the output buffer
|
||||
* designed for formats which themselves call fmt,
|
||||
* but ignore any width flags
|
||||
*/
|
||||
int
|
||||
fmtprint(Fmt *f, char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
int n;
|
||||
|
||||
f->flags = 0;
|
||||
f->width = 0;
|
||||
f->prec = 0;
|
||||
VA_COPY(va, f->args);
|
||||
VA_END(f->args);
|
||||
va_start(f->args, fmt);
|
||||
n = dofmt(f, fmt);
|
||||
va_end(f->args);
|
||||
f->flags = 0;
|
||||
f->width = 0;
|
||||
f->prec = 0;
|
||||
VA_COPY(f->args,va);
|
||||
VA_END(va);
|
||||
if(n >= 0)
|
||||
return 0;
|
||||
return n;
|
||||
}
|
||||
|
274
src/lib9/fmt/fmtquote.c
Normal file
274
src/lib9/fmt/fmtquote.c
Normal file
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* How many bytes of output UTF will be produced by quoting (if necessary) this string?
|
||||
* How many runes? How much of the input will be consumed?
|
||||
* The parameter q is filled in by __quotesetup.
|
||||
* The string may be UTF or Runes (s or r).
|
||||
* Return count does not include NUL.
|
||||
* Terminate the scan at the first of:
|
||||
* NUL in input
|
||||
* count exceeded in input
|
||||
* count exceeded on output
|
||||
* *ninp is set to number of input bytes accepted.
|
||||
* nin may be <0 initially, to avoid checking input by count.
|
||||
*/
|
||||
void
|
||||
__quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout)
|
||||
{
|
||||
int w;
|
||||
Rune c;
|
||||
|
||||
q->quoted = 0;
|
||||
q->nbytesout = 0;
|
||||
q->nrunesout = 0;
|
||||
q->nbytesin = 0;
|
||||
q->nrunesin = 0;
|
||||
if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){
|
||||
if(nout < 2)
|
||||
return;
|
||||
q->quoted = 1;
|
||||
q->nbytesout = 2;
|
||||
q->nrunesout = 2;
|
||||
}
|
||||
for(; nin!=0; nin--){
|
||||
if(s)
|
||||
w = chartorune(&c, s);
|
||||
else{
|
||||
c = *r;
|
||||
w = runelen(c);
|
||||
}
|
||||
|
||||
if(c == '\0')
|
||||
break;
|
||||
if(runesout){
|
||||
if(q->nrunesout+1 > nout)
|
||||
break;
|
||||
}else{
|
||||
if(q->nbytesout+w > nout)
|
||||
break;
|
||||
}
|
||||
|
||||
if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){
|
||||
if(!q->quoted){
|
||||
if(runesout){
|
||||
if(1+q->nrunesout+1+1 > nout) /* no room for quotes */
|
||||
break;
|
||||
}else{
|
||||
if(1+q->nbytesout+w+1 > nout) /* no room for quotes */
|
||||
break;
|
||||
}
|
||||
q->nrunesout += 2; /* include quotes */
|
||||
q->nbytesout += 2; /* include quotes */
|
||||
q->quoted = 1;
|
||||
}
|
||||
if(c == '\'') {
|
||||
if(runesout){
|
||||
if(1+q->nrunesout+1 > nout) /* no room for quotes */
|
||||
break;
|
||||
}else{
|
||||
if(1+q->nbytesout+w > nout) /* no room for quotes */
|
||||
break;
|
||||
}
|
||||
q->nbytesout++;
|
||||
q->nrunesout++; /* quotes reproduce as two characters */
|
||||
}
|
||||
}
|
||||
|
||||
/* advance input */
|
||||
if(s)
|
||||
s += w;
|
||||
else
|
||||
r++;
|
||||
q->nbytesin += w;
|
||||
q->nrunesin++;
|
||||
|
||||
/* advance output */
|
||||
q->nbytesout += w;
|
||||
q->nrunesout++;
|
||||
|
||||
#ifndef PLAN9PORT
|
||||
/* ANSI requires precision in bytes, not Runes. */
|
||||
nin-= w-1; /* and then n-- in the loop */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
|
||||
{
|
||||
Rune r, *rm, *rme;
|
||||
char *t, *s, *m, *me;
|
||||
Rune *rt, *rs;
|
||||
ulong fl;
|
||||
int nc, w;
|
||||
|
||||
m = sin;
|
||||
me = m + q->nbytesin;
|
||||
rm = rin;
|
||||
rme = rm + q->nrunesin;
|
||||
|
||||
fl = f->flags;
|
||||
w = 0;
|
||||
if(fl & FmtWidth)
|
||||
w = f->width;
|
||||
if(f->runes){
|
||||
if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
|
||||
return -1;
|
||||
}else{
|
||||
if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
|
||||
return -1;
|
||||
}
|
||||
t = (char*)f->to;
|
||||
s = (char*)f->stop;
|
||||
rt = (Rune*)f->to;
|
||||
rs = (Rune*)f->stop;
|
||||
if(f->runes)
|
||||
FMTRCHAR(f, rt, rs, '\'');
|
||||
else
|
||||
FMTRUNE(f, t, s, '\'');
|
||||
for(nc = q->nrunesin; nc > 0; nc--){
|
||||
if(sin){
|
||||
r = *(uchar*)m;
|
||||
if(r < Runeself)
|
||||
m++;
|
||||
else if((me - m) >= UTFmax || fullrune(m, me-m))
|
||||
m += chartorune(&r, m);
|
||||
else
|
||||
break;
|
||||
}else{
|
||||
if(rm >= rme)
|
||||
break;
|
||||
r = *(uchar*)rm++;
|
||||
}
|
||||
if(f->runes){
|
||||
FMTRCHAR(f, rt, rs, r);
|
||||
if(r == '\'')
|
||||
FMTRCHAR(f, rt, rs, r);
|
||||
}else{
|
||||
FMTRUNE(f, t, s, r);
|
||||
if(r == '\'')
|
||||
FMTRUNE(f, t, s, r);
|
||||
}
|
||||
}
|
||||
|
||||
if(f->runes){
|
||||
FMTRCHAR(f, rt, rs, '\'');
|
||||
USED(rs);
|
||||
f->nfmt += rt - (Rune *)f->to;
|
||||
f->to = rt;
|
||||
if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0)
|
||||
return -1;
|
||||
}else{
|
||||
FMTRUNE(f, t, s, '\'');
|
||||
USED(s);
|
||||
f->nfmt += t - (char *)f->to;
|
||||
f->to = t;
|
||||
if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__quotestrfmt(int runesin, Fmt *f)
|
||||
{
|
||||
int nin, outlen;
|
||||
Rune *r;
|
||||
char *s;
|
||||
Quoteinfo q;
|
||||
|
||||
nin = -1;
|
||||
if(f->flags&FmtPrec)
|
||||
nin = f->prec;
|
||||
if(runesin){
|
||||
r = va_arg(f->args, Rune *);
|
||||
s = nil;
|
||||
}else{
|
||||
s = va_arg(f->args, char *);
|
||||
r = nil;
|
||||
}
|
||||
if(!s && !r)
|
||||
return __fmtcpy(f, (void*)"<nil>", 5, 5);
|
||||
|
||||
if(f->flush)
|
||||
outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
|
||||
else if(f->runes)
|
||||
outlen = (Rune*)f->stop - (Rune*)f->to;
|
||||
else
|
||||
outlen = (char*)f->stop - (char*)f->to;
|
||||
|
||||
__quotesetup(s, r, nin, outlen, &q, f->flags&FmtSharp, f->runes);
|
||||
/*print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout); */
|
||||
|
||||
if(runesin){
|
||||
if(!q.quoted)
|
||||
return __fmtrcpy(f, r, q.nrunesin);
|
||||
return qstrfmt(nil, r, &q, f);
|
||||
}
|
||||
|
||||
if(!q.quoted)
|
||||
return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
|
||||
return qstrfmt(s, nil, &q, f);
|
||||
}
|
||||
|
||||
int
|
||||
quotestrfmt(Fmt *f)
|
||||
{
|
||||
return __quotestrfmt(0, f);
|
||||
}
|
||||
|
||||
int
|
||||
quoterunestrfmt(Fmt *f)
|
||||
{
|
||||
return __quotestrfmt(1, f);
|
||||
}
|
||||
|
||||
void
|
||||
quotefmtinstall(void)
|
||||
{
|
||||
fmtinstall('q', quotestrfmt);
|
||||
fmtinstall('Q', quoterunestrfmt);
|
||||
}
|
||||
|
||||
int
|
||||
__needsquotes(char *s, int *quotelenp)
|
||||
{
|
||||
Quoteinfo q;
|
||||
|
||||
__quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0);
|
||||
*quotelenp = q.nbytesout;
|
||||
|
||||
return q.quoted;
|
||||
}
|
||||
|
||||
int
|
||||
__runeneedsquotes(Rune *r, int *quotelenp)
|
||||
{
|
||||
Quoteinfo q;
|
||||
|
||||
__quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0);
|
||||
*quotelenp = q.nrunesout;
|
||||
|
||||
return q.quoted;
|
||||
}
|
43
src/lib9/fmt/fmtrune.c
Normal file
43
src/lib9/fmt/fmtrune.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
fmtrune(Fmt *f, int r)
|
||||
{
|
||||
Rune *rt;
|
||||
char *t;
|
||||
int n;
|
||||
|
||||
if(f->runes){
|
||||
rt = (Rune*)f->to;
|
||||
FMTRCHAR(f, rt, f->stop, r);
|
||||
f->to = rt;
|
||||
n = 1;
|
||||
}else{
|
||||
t = (char*)f->to;
|
||||
FMTRUNE(f, t, f->stop, r);
|
||||
n = t - (char*)f->to;
|
||||
f->to = t;
|
||||
}
|
||||
f->nfmt += n;
|
||||
return 0;
|
||||
}
|
31
src/lib9/fmt/fmtstr.c
Normal file
31
src/lib9/fmt/fmtstr.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
char*
|
||||
fmtstrflush(Fmt *f)
|
||||
{
|
||||
if(f->start == nil)
|
||||
return nil;
|
||||
*(char*)f->to = '\0';
|
||||
f->to = f->start;
|
||||
return (char*)f->start;
|
||||
}
|
52
src/lib9/fmt/fmtvprint.c
Normal file
52
src/lib9/fmt/fmtvprint.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
|
||||
/*
|
||||
* format a string into the output buffer
|
||||
* designed for formats which themselves call fmt,
|
||||
* but ignore any width flags
|
||||
*/
|
||||
int
|
||||
fmtvprint(Fmt *f, char *fmt, va_list args)
|
||||
{
|
||||
va_list va;
|
||||
int n;
|
||||
|
||||
f->flags = 0;
|
||||
f->width = 0;
|
||||
f->prec = 0;
|
||||
VA_COPY(va,f->args);
|
||||
VA_END(f->args);
|
||||
VA_COPY(f->args,args);
|
||||
n = dofmt(f, fmt);
|
||||
f->flags = 0;
|
||||
f->width = 0;
|
||||
f->prec = 0;
|
||||
VA_END(f->args);
|
||||
VA_COPY(f->args,va);
|
||||
VA_END(va);
|
||||
if(n >= 0)
|
||||
return 0;
|
||||
return n;
|
||||
}
|
||||
|
33
src/lib9/fmt/fprint.c
Normal file
33
src/lib9/fmt/fprint.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
fprint(int fd, char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
n = vfprint(fd, fmt, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
93
src/lib9/fmt/nan64.c
Normal file
93
src/lib9/fmt/nan64.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 64-bit IEEE not-a-number routines.
|
||||
* This is big/little-endian portable assuming that
|
||||
* the 64-bit doubles and 64-bit integers have the
|
||||
* same byte ordering.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
static uvlong uvnan = ((uvlong)0x7FF00000<<32)|0x00000001;
|
||||
static uvlong uvinf = ((uvlong)0x7FF00000<<32)|0x00000000;
|
||||
static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
|
||||
|
||||
/* gcc sees through the obvious casts. */
|
||||
static uvlong
|
||||
d2u(double d)
|
||||
{
|
||||
union {
|
||||
uvlong v;
|
||||
double d;
|
||||
} u;
|
||||
assert(sizeof(u.d) == sizeof(u.v));
|
||||
u.d = d;
|
||||
return u.v;
|
||||
}
|
||||
|
||||
static double
|
||||
u2d(uvlong v)
|
||||
{
|
||||
union {
|
||||
uvlong v;
|
||||
double d;
|
||||
} u;
|
||||
assert(sizeof(u.d) == sizeof(u.v));
|
||||
u.v = v;
|
||||
return u.d;
|
||||
}
|
||||
|
||||
double
|
||||
__NaN(void)
|
||||
{
|
||||
return u2d(uvnan);
|
||||
}
|
||||
|
||||
int
|
||||
__isNaN(double d)
|
||||
{
|
||||
uvlong x;
|
||||
|
||||
x = d2u(d);
|
||||
/* IEEE 754: exponent bits 0x7FF and non-zero mantissa */
|
||||
return (x&uvinf) == uvinf && (x&~uvneginf) != 0;
|
||||
}
|
||||
|
||||
double
|
||||
__Inf(int sign)
|
||||
{
|
||||
return u2d(sign < 0 ? uvneginf : uvinf);
|
||||
}
|
||||
|
||||
int
|
||||
__isInf(double d, int sign)
|
||||
{
|
||||
uvlong x;
|
||||
|
||||
x = d2u(d);
|
||||
if(sign == 0)
|
||||
return x==uvinf || x==uvneginf;
|
||||
else if(sign > 0)
|
||||
return x==uvinf;
|
||||
else
|
||||
return x==uvneginf;
|
||||
}
|
60
src/lib9/fmt/pow10.c
Normal file
60
src/lib9/fmt/pow10.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* this table might overflow 127-bit exponent representations.
|
||||
* in that case, truncate it after 1.0e38.
|
||||
* it is important to get all one can from this
|
||||
* routine since it is used in atof to scale numbers.
|
||||
* the presumption is that C converts fp numbers better
|
||||
* than multipication of lower powers of 10.
|
||||
*/
|
||||
|
||||
static
|
||||
double tab[] =
|
||||
{
|
||||
1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9,
|
||||
1.0e10,1.0e11,1.0e12,1.0e13,1.0e14,1.0e15,1.0e16,1.0e17,1.0e18,1.0e19,
|
||||
1.0e20,1.0e21,1.0e22,1.0e23,1.0e24,1.0e25,1.0e26,1.0e27,1.0e28,1.0e29,
|
||||
1.0e30,1.0e31,1.0e32,1.0e33,1.0e34,1.0e35,1.0e36,1.0e37,1.0e38,1.0e39,
|
||||
1.0e40,1.0e41,1.0e42,1.0e43,1.0e44,1.0e45,1.0e46,1.0e47,1.0e48,1.0e49,
|
||||
1.0e50,1.0e51,1.0e52,1.0e53,1.0e54,1.0e55,1.0e56,1.0e57,1.0e58,1.0e59,
|
||||
1.0e60,1.0e61,1.0e62,1.0e63,1.0e64,1.0e65,1.0e66,1.0e67,1.0e68,1.0e69,
|
||||
};
|
||||
|
||||
double
|
||||
__fmtpow10(int n)
|
||||
{
|
||||
int m;
|
||||
|
||||
if(n < 0) {
|
||||
n = -n;
|
||||
if(n < (int)(sizeof(tab)/sizeof(tab[0])))
|
||||
return 1/tab[n];
|
||||
m = n/2;
|
||||
return __fmtpow10(-m) * __fmtpow10(m-n);
|
||||
}
|
||||
if(n < (int)(sizeof(tab)/sizeof(tab[0])))
|
||||
return tab[n];
|
||||
m = n/2;
|
||||
return __fmtpow10(m) * __fmtpow10(n-m);
|
||||
}
|
33
src/lib9/fmt/print.c
Normal file
33
src/lib9/fmt/print.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
print(char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
n = vfprint(1, fmt, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
33
src/lib9/fmt/seprint.c
Normal file
33
src/lib9/fmt/seprint.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
char*
|
||||
seprint(char *buf, char *e, char *fmt, ...)
|
||||
{
|
||||
char *p;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
p = vseprint(buf, e, fmt, args);
|
||||
va_end(args);
|
||||
return p;
|
||||
}
|
33
src/lib9/fmt/smprint.c
Normal file
33
src/lib9/fmt/smprint.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
char*
|
||||
smprint(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *p;
|
||||
|
||||
va_start(args, fmt);
|
||||
p = vsmprint(fmt, args);
|
||||
va_end(args);
|
||||
return p;
|
||||
}
|
34
src/lib9/fmt/snprint.c
Normal file
34
src/lib9/fmt/snprint.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
snprint(char *buf, int len, char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
n = vsnprint(buf, len, fmt, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
|
45
src/lib9/fmt/sprint.c
Normal file
45
src/lib9/fmt/sprint.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
sprint(char *buf, char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
uint len;
|
||||
va_list args;
|
||||
|
||||
len = 1<<30; /* big number, but sprint is deprecated anyway */
|
||||
/*
|
||||
* on PowerPC, the stack is near the top of memory, so
|
||||
* we must be sure not to overflow a 32-bit pointer.
|
||||
*
|
||||
* careful! gcc-4.2 assumes buf+len < buf can never be true and
|
||||
* optimizes the test away. casting to uintptr works around this bug.
|
||||
*/
|
||||
if((uintptr)buf+len < (uintptr)buf)
|
||||
len = -(uintptr)buf-1;
|
||||
|
||||
va_start(args, fmt);
|
||||
n = vsnprint(buf, len, fmt, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
65
src/lib9/fmt/test.c
Normal file
65
src/lib9/fmt/test.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
quotefmtinstall();
|
||||
print("hello world\n");
|
||||
print("x: %x\n", 0x87654321);
|
||||
print("u: %u\n", 0x87654321);
|
||||
print("d: %d\n", 0x87654321);
|
||||
print("s: %s\n", "hi there");
|
||||
print("q: %q\n", "hi i'm here");
|
||||
print("c: %c\n", '!');
|
||||
print("g: %g %g %g\n", 3.14159, 3.14159e10, 3.14159e-10);
|
||||
print("e: %e %e %e\n", 3.14159, 3.14159e10, 3.14159e-10);
|
||||
print("f: %f %f %f\n", 3.14159, 3.14159e10, 3.14159e-10);
|
||||
print("smiley: %C\n", (Rune)0x263a);
|
||||
print("%g %.18g\n", 2e25, 2e25);
|
||||
print("%2.18g\n", 1.0);
|
||||
print("%2.18f\n", 1.0);
|
||||
print("%f\n", 3.1415927/4);
|
||||
print("%d\n", 23);
|
||||
print("%i\n", 23);
|
||||
print("%0.10d\n", 12345);
|
||||
|
||||
/* test %4$d formats */
|
||||
print("%3$d %4$06d %2$d %1$d\n", 444, 333, 111, 222);
|
||||
print("%3$d %4$06d %2$d %1$d\n", 444, 333, 111, 222);
|
||||
print("%3$d %4$*5$06d %2$d %1$d\n", 444, 333, 111, 222, 20);
|
||||
print("%3$hd %4$*5$06d %2$d %1$d\n", 444, 333, (short)111, 222, 20);
|
||||
print("%3$lld %4$*5$06d %2$d %1$d\n", 444, 333, 111LL, 222, 20);
|
||||
|
||||
/* test %'d formats */
|
||||
print("%'d %'d %'d\n", 1, 2222, 33333333);
|
||||
print("%'019d\n", 0);
|
||||
print("%08d %08d %08d\n", 1, 2222, 33333333);
|
||||
print("%'08d %'08d %'08d\n", 1, 2222, 33333333);
|
||||
print("%'x %'X %'b\n", 0x11111111, 0xabcd1234, 12345);
|
||||
print("%'lld %'lld %'lld\n", 1LL, 222222222LL, 3333333333333LL);
|
||||
print("%019lld %019lld %019lld\n", 1LL, 222222222LL, 3333333333333LL);
|
||||
print("%'019lld %'019lld %'019lld\n", 1LL, 222222222LL, 3333333333333LL);
|
||||
print("%'020lld %'020lld %'020lld\n", 1LL, 222222222LL, 3333333333333LL);
|
||||
print("%'llx %'llX %'llb\n", 0x111111111111LL, 0xabcd12345678LL, 112342345LL);
|
||||
return 0;
|
||||
}
|
37
src/lib9/fmt/vfprint.c
Normal file
37
src/lib9/fmt/vfprint.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
vfprint(int fd, char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
char buf[256];
|
||||
int n;
|
||||
|
||||
fmtfdinit(&f, fd, buf, sizeof(buf));
|
||||
VA_COPY(f.args,args);
|
||||
n = dofmt(&f, fmt);
|
||||
VA_END(f.args);
|
||||
if(n > 0 && __fmtFdFlush(&f) == 0)
|
||||
return -1;
|
||||
return n;
|
||||
}
|
44
src/lib9/fmt/vseprint.c
Normal file
44
src/lib9/fmt/vseprint.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
char*
|
||||
vseprint(char *buf, char *e, char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
|
||||
if(e <= buf)
|
||||
return nil;
|
||||
f.runes = 0;
|
||||
f.start = buf;
|
||||
f.to = buf;
|
||||
f.stop = e - 1;
|
||||
f.flush = 0;
|
||||
f.farg = nil;
|
||||
f.nfmt = 0;
|
||||
VA_COPY(f.args,args);
|
||||
fmtlocaleinit(&f, nil, nil, nil);
|
||||
dofmt(&f, fmt);
|
||||
VA_END(f.args);
|
||||
*(char*)f.to = '\0';
|
||||
return (char*)f.to;
|
||||
}
|
||||
|
87
src/lib9/fmt/vsmprint.c
Normal file
87
src/lib9/fmt/vsmprint.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
static int
|
||||
fmtStrFlush(Fmt *f)
|
||||
{
|
||||
char *s;
|
||||
int n;
|
||||
|
||||
if(f->start == nil)
|
||||
return 0;
|
||||
n = (uintptr)f->farg;
|
||||
n *= 2;
|
||||
s = (char*)f->start;
|
||||
f->start = realloc(s, n);
|
||||
if(f->start == nil){
|
||||
f->farg = nil;
|
||||
f->to = nil;
|
||||
f->stop = nil;
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
f->farg = (void*)(uintptr)n;
|
||||
f->to = (char*)f->start + ((char*)f->to - s);
|
||||
f->stop = (char*)f->start + n - 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
fmtstrinit(Fmt *f)
|
||||
{
|
||||
int n;
|
||||
|
||||
memset(f, 0, sizeof *f);
|
||||
f->runes = 0;
|
||||
n = 32;
|
||||
f->start = malloc(n);
|
||||
if(f->start == nil)
|
||||
return -1;
|
||||
f->to = f->start;
|
||||
f->stop = (char*)f->start + n - 1;
|
||||
f->flush = fmtStrFlush;
|
||||
f->farg = (void*)(uintptr)n;
|
||||
f->nfmt = 0;
|
||||
fmtlocaleinit(f, nil, nil, nil);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* print into an allocated string buffer
|
||||
*/
|
||||
char*
|
||||
vsmprint(char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
int n;
|
||||
|
||||
if(fmtstrinit(&f) < 0)
|
||||
return nil;
|
||||
VA_COPY(f.args,args);
|
||||
n = dofmt(&f, fmt);
|
||||
VA_END(f.args);
|
||||
if(n < 0){
|
||||
free(f.start);
|
||||
return nil;
|
||||
}
|
||||
return fmtstrflush(&f);
|
||||
}
|
43
src/lib9/fmt/vsnprint.c
Normal file
43
src/lib9/fmt/vsnprint.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson,
|
||||
* with contributions from Mike Burrows and Sean Dorward.
|
||||
*
|
||||
* Copyright (c) 2002-2006 by Lucent Technologies.
|
||||
* Portions Copyright (c) 2004 Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
|
||||
* NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
|
||||
* THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
vsnprint(char *buf, int len, char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
|
||||
if(len <= 0)
|
||||
return -1;
|
||||
f.runes = 0;
|
||||
f.start = buf;
|
||||
f.to = buf;
|
||||
f.stop = buf + len - 1;
|
||||
f.flush = 0;
|
||||
f.farg = nil;
|
||||
f.nfmt = 0;
|
||||
VA_COPY(f.args,args);
|
||||
fmtlocaleinit(&f, nil, nil, nil);
|
||||
dofmt(&f, fmt);
|
||||
VA_END(f.args);
|
||||
*(char*)f.to = '\0';
|
||||
return (char*)f.to - buf;
|
||||
}
|
38
src/lib9/fmtlock2.c
Normal file
38
src/lib9/fmtlock2.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/fmtlock2.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/fmtlock2.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
Portions Copyright 2009 The Go Authors. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void
|
||||
__fmtlock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
__fmtunlock(void)
|
||||
{
|
||||
}
|
46
src/lib9/fork.c
Normal file
46
src/lib9/fork.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/fork.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/fork.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <signal.h>
|
||||
#include <libc.h>
|
||||
#include "9proc.h"
|
||||
#undef fork
|
||||
|
||||
int
|
||||
p9fork(void)
|
||||
{
|
||||
int pid;
|
||||
sigset_t all, old;
|
||||
|
||||
sigfillset(&all);
|
||||
sigprocmask(SIG_SETMASK, &all, &old);
|
||||
pid = fork();
|
||||
if(pid == 0){
|
||||
_clearuproc();
|
||||
_p9uproc(0);
|
||||
}
|
||||
sigprocmask(SIG_SETMASK, &old, nil);
|
||||
return pid;
|
||||
}
|
50
src/lib9/getenv.c
Normal file
50
src/lib9/getenv.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/getenv.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/getenv.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
char*
|
||||
p9getenv(char *s)
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = getenv(s);
|
||||
if(t == 0)
|
||||
return 0;
|
||||
return strdup(t);
|
||||
}
|
||||
|
||||
int
|
||||
p9putenv(char *s, char *v)
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = smprint("%s=%s", s, v);
|
||||
if(t == nil)
|
||||
return -1;
|
||||
putenv(t);
|
||||
return 0;
|
||||
}
|
62
src/lib9/getfields.c
Normal file
62
src/lib9/getfields.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Inferno libkern/getfields.c
|
||||
http://code.google.com/p/inferno-os/source/browse/libkern/getfields.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <lib9.h>
|
||||
|
||||
int
|
||||
getfields(char *str, char **args, int max, int mflag, char *set)
|
||||
{
|
||||
Rune r;
|
||||
int nr, intok, narg;
|
||||
|
||||
if(max <= 0)
|
||||
return 0;
|
||||
|
||||
narg = 0;
|
||||
args[narg] = str;
|
||||
if(!mflag)
|
||||
narg++;
|
||||
intok = 0;
|
||||
for(;; str += nr) {
|
||||
nr = chartorune(&r, str);
|
||||
if(r == 0)
|
||||
break;
|
||||
if(utfrune(set, r)) {
|
||||
if(narg >= max)
|
||||
break;
|
||||
*str = 0;
|
||||
intok = 0;
|
||||
args[narg] = str + nr;
|
||||
if(!mflag)
|
||||
narg++;
|
||||
} else {
|
||||
if(!intok && mflag)
|
||||
narg++;
|
||||
intok = 1;
|
||||
}
|
||||
}
|
||||
return narg;
|
||||
}
|
41
src/lib9/getuser.c
Normal file
41
src/lib9/getuser.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/getuser.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/getuser.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <pwd.h>
|
||||
#include <libc.h>
|
||||
|
||||
char*
|
||||
getuser(void)
|
||||
{
|
||||
static char user[64];
|
||||
struct passwd *pw;
|
||||
|
||||
pw = getpwuid(getuid());
|
||||
if(pw == nil)
|
||||
return "none";
|
||||
strecpy(user, user+sizeof user, pw->pw_name);
|
||||
return user;
|
||||
}
|
34
src/lib9/getwd.c
Normal file
34
src/lib9/getwd.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/getwd.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/getwd.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
#undef getwd
|
||||
|
||||
char*
|
||||
p9getwd(char *s, int ns)
|
||||
{
|
||||
return getcwd(s, ns);
|
||||
}
|
42
src/lib9/jmp.c
Normal file
42
src/lib9/jmp.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/jmp.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/jmp.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
void
|
||||
p9longjmp(p9jmp_buf buf, int val)
|
||||
{
|
||||
siglongjmp((void*)buf, val);
|
||||
}
|
||||
|
||||
void
|
||||
p9notejmp(void *x, p9jmp_buf buf, int val)
|
||||
{
|
||||
USED(x);
|
||||
siglongjmp((void*)buf, val);
|
||||
}
|
||||
|
38
src/lib9/main.c
Normal file
38
src/lib9/main.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/main.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/main.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
extern void p9main(int, char**);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
p9main(argc, argv);
|
||||
exits("main");
|
||||
return 99;
|
||||
}
|
52
src/lib9/nan.c
Normal file
52
src/lib9/nan.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/nan.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/nan.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "fmt/nan.h"
|
||||
|
||||
double
|
||||
NaN(void)
|
||||
{
|
||||
return __NaN();
|
||||
}
|
||||
|
||||
double
|
||||
Inf(int sign)
|
||||
{
|
||||
return __Inf(sign);
|
||||
}
|
||||
|
||||
int
|
||||
isNaN(double x)
|
||||
{
|
||||
return __isNaN(x);
|
||||
}
|
||||
|
||||
int
|
||||
isInf(double x, int sign)
|
||||
{
|
||||
return __isInf(x, sign);
|
||||
}
|
297
src/lib9/notify.c
Normal file
297
src/lib9/notify.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/notify.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/notify.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Signal handling for Plan 9 programs.
|
||||
* We stubbornly use the strings from Plan 9 instead
|
||||
* of the enumerated Unix constants.
|
||||
* There are some weird translations. In particular,
|
||||
* a "kill" note is the same as SIGTERM in Unix.
|
||||
* There is no equivalent note to Unix's SIGKILL, since
|
||||
* it's not a deliverable signal anyway.
|
||||
*
|
||||
* We do not handle SIGABRT or SIGSEGV, mainly because
|
||||
* the thread library queues its notes for later, and we want
|
||||
* to dump core with the state at time of delivery.
|
||||
*
|
||||
* We have to add some extra entry points to provide the
|
||||
* ability to tweak which signals are deliverable and which
|
||||
* are acted upon. Notifydisable and notifyenable play with
|
||||
* the process signal mask. Notifyignore enables the signal
|
||||
* but will not call notifyf when it comes in. This is occasionally
|
||||
* useful.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <signal.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
|
||||
extern char *_p9sigstr(int, char*);
|
||||
extern int _p9strsig(char*);
|
||||
|
||||
typedef struct Sig Sig;
|
||||
struct Sig
|
||||
{
|
||||
int sig; /* signal number */
|
||||
int flags;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Restart = 1<<0,
|
||||
Ignore = 1<<1
|
||||
};
|
||||
|
||||
static Sig sigs[] = {
|
||||
SIGHUP, 0,
|
||||
SIGINT, 0,
|
||||
SIGQUIT, 0,
|
||||
SIGILL, 0,
|
||||
SIGTRAP, 0,
|
||||
/* SIGABRT, 0, */
|
||||
#ifdef SIGEMT
|
||||
SIGEMT, 0,
|
||||
#endif
|
||||
SIGFPE, 0,
|
||||
SIGBUS, 0,
|
||||
/* SIGSEGV, 0, */
|
||||
SIGCHLD, Restart|Ignore,
|
||||
SIGSYS, 0,
|
||||
SIGPIPE, Ignore,
|
||||
SIGALRM, 0,
|
||||
SIGTERM, 0,
|
||||
SIGTSTP, Restart|Ignore,
|
||||
/* SIGTTIN, Restart|Ignore, */
|
||||
/* SIGTTOU, Restart|Ignore, */
|
||||
SIGXCPU, 0,
|
||||
SIGXFSZ, 0,
|
||||
SIGVTALRM, 0,
|
||||
SIGUSR1, 0,
|
||||
SIGUSR2, 0,
|
||||
#ifdef SIGWINCH
|
||||
SIGWINCH, Restart|Ignore,
|
||||
#endif
|
||||
#ifdef SIGINFO
|
||||
SIGINFO, Restart|Ignore,
|
||||
#endif
|
||||
};
|
||||
|
||||
static Sig*
|
||||
findsig(int s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<nelem(sigs); i++)
|
||||
if(sigs[i].sig == s)
|
||||
return &sigs[i];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/*
|
||||
* The thread library initializes _notejmpbuf to its own
|
||||
* routine which provides a per-pthread jump buffer.
|
||||
* If we're not using the thread library, we assume we are
|
||||
* single-threaded.
|
||||
*/
|
||||
typedef struct Jmp Jmp;
|
||||
struct Jmp
|
||||
{
|
||||
p9jmp_buf b;
|
||||
};
|
||||
|
||||
static Jmp onejmp;
|
||||
|
||||
static Jmp*
|
||||
getonejmp(void)
|
||||
{
|
||||
return &onejmp;
|
||||
}
|
||||
|
||||
Jmp *(*_notejmpbuf)(void) = getonejmp;
|
||||
static void noteinit(void);
|
||||
|
||||
/*
|
||||
* Actual signal handler.
|
||||
*/
|
||||
|
||||
static void (*notifyf)(void*, char*); /* Plan 9 handler */
|
||||
|
||||
static void
|
||||
signotify(int sig)
|
||||
{
|
||||
char tmp[64];
|
||||
Jmp *j;
|
||||
Sig *s;
|
||||
|
||||
j = (*_notejmpbuf)();
|
||||
switch(p9setjmp(j->b)){
|
||||
case 0:
|
||||
if(notifyf)
|
||||
(*notifyf)(nil, _p9sigstr(sig, tmp));
|
||||
/* fall through */
|
||||
case 1: /* noted(NDFLT) */
|
||||
if(0)print("DEFAULT %d\n", sig);
|
||||
s = findsig(sig);
|
||||
if(s && (s->flags&Ignore))
|
||||
return;
|
||||
signal(sig, SIG_DFL);
|
||||
raise(sig);
|
||||
_exit(1);
|
||||
case 2: /* noted(NCONT) */
|
||||
if(0)print("HANDLED %d\n", sig);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
signonotify(int sig)
|
||||
{
|
||||
USED(sig);
|
||||
}
|
||||
|
||||
int
|
||||
noted(int v)
|
||||
{
|
||||
p9longjmp((*_notejmpbuf)()->b, v==NCONT ? 2 : 1);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
notify(void (*f)(void*, char*))
|
||||
{
|
||||
static int init;
|
||||
|
||||
notifyf = f;
|
||||
if(!init){
|
||||
init = 1;
|
||||
noteinit();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nonsense about enabling and disabling signals.
|
||||
*/
|
||||
typedef void Sighandler(int);
|
||||
static Sighandler*
|
||||
handler(int s)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
sigaction(s, nil, &sa);
|
||||
return sa.sa_handler;
|
||||
}
|
||||
|
||||
static int
|
||||
notesetenable(int sig, int enabled)
|
||||
{
|
||||
sigset_t mask, omask;
|
||||
|
||||
if(sig == 0)
|
||||
return -1;
|
||||
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, sig);
|
||||
sigprocmask(enabled ? SIG_UNBLOCK : SIG_BLOCK, &mask, &omask);
|
||||
return !sigismember(&omask, sig);
|
||||
}
|
||||
|
||||
int
|
||||
noteenable(char *msg)
|
||||
{
|
||||
return notesetenable(_p9strsig(msg), 1);
|
||||
}
|
||||
|
||||
int
|
||||
notedisable(char *msg)
|
||||
{
|
||||
return notesetenable(_p9strsig(msg), 0);
|
||||
}
|
||||
|
||||
static int
|
||||
notifyseton(int s, int on)
|
||||
{
|
||||
Sig *sig;
|
||||
struct sigaction sa, osa;
|
||||
|
||||
sig = findsig(s);
|
||||
if(sig == nil)
|
||||
return -1;
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_handler = on ? signotify : signonotify;
|
||||
if(sig->flags&Restart)
|
||||
sa.sa_flags |= SA_RESTART;
|
||||
|
||||
/*
|
||||
* We can't allow signals within signals because there's
|
||||
* only one jump buffer.
|
||||
*/
|
||||
sigfillset(&sa.sa_mask);
|
||||
|
||||
/*
|
||||
* Install handler.
|
||||
*/
|
||||
sigaction(sig->sig, &sa, &osa);
|
||||
return osa.sa_handler == signotify;
|
||||
}
|
||||
|
||||
int
|
||||
notifyon(char *msg)
|
||||
{
|
||||
return notifyseton(_p9strsig(msg), 1);
|
||||
}
|
||||
|
||||
int
|
||||
notifyoff(char *msg)
|
||||
{
|
||||
return notifyseton(_p9strsig(msg), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization follows sigs table.
|
||||
*/
|
||||
static void
|
||||
noteinit(void)
|
||||
{
|
||||
int i;
|
||||
Sig *sig;
|
||||
|
||||
for(i=0; i<nelem(sigs); i++){
|
||||
sig = &sigs[i];
|
||||
/*
|
||||
* If someone has already installed a handler,
|
||||
* It's probably some ld preload nonsense,
|
||||
* like pct (a SIGVTALRM-based profiler).
|
||||
* Or maybe someone has already called notifyon/notifyoff.
|
||||
* Leave it alone.
|
||||
*/
|
||||
if(handler(sig->sig) != SIG_DFL)
|
||||
continue;
|
||||
notifyseton(sig->sig, 1);
|
||||
}
|
||||
}
|
||||
|
35
src/lib9/nulldir.c
Normal file
35
src/lib9/nulldir.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Inferno lib9/nulldir.c
|
||||
http://code.google.com/p/inferno-os/source/browse/lib9/nulldir.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void
|
||||
nulldir(Dir *d)
|
||||
{
|
||||
memset(d, ~0, sizeof(Dir));
|
||||
d->name = d->uid = d->gid = d->muid = "";
|
||||
}
|
87
src/lib9/open.c
Normal file
87
src/lib9/open.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/open.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/open.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE /* for Linux O_DIRECT */
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <sys/file.h>
|
||||
#include <libc.h>
|
||||
#ifndef O_DIRECT
|
||||
#define O_DIRECT 0
|
||||
#endif
|
||||
|
||||
int
|
||||
p9open(char *name, int mode)
|
||||
{
|
||||
int cexec, rclose;
|
||||
int fd, umode, lock, rdwr;
|
||||
struct flock fl;
|
||||
|
||||
rdwr = mode&3;
|
||||
umode = rdwr;
|
||||
cexec = mode&OCEXEC;
|
||||
rclose = mode&ORCLOSE;
|
||||
lock = mode&OLOCK;
|
||||
mode &= ~(3|OCEXEC|ORCLOSE|OLOCK);
|
||||
if(mode&OTRUNC){
|
||||
umode |= O_TRUNC;
|
||||
mode ^= OTRUNC;
|
||||
}
|
||||
if(mode&ODIRECT){
|
||||
umode |= O_DIRECT;
|
||||
mode ^= ODIRECT;
|
||||
}
|
||||
if(mode&ONONBLOCK){
|
||||
umode |= O_NONBLOCK;
|
||||
mode ^= ONONBLOCK;
|
||||
}
|
||||
if(mode&OAPPEND){
|
||||
umode |= O_APPEND;
|
||||
mode ^= OAPPEND;
|
||||
}
|
||||
if(mode){
|
||||
werrstr("mode 0x%x not supported", mode);
|
||||
return -1;
|
||||
}
|
||||
fd = open(name, umode);
|
||||
if(fd >= 0){
|
||||
if(lock){
|
||||
fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 0;
|
||||
if(fcntl(fd, F_SETLK, &fl) < 0){
|
||||
close(fd);
|
||||
werrstr("lock: %r");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(cexec)
|
||||
fcntl(fd, F_SETFL, FD_CLOEXEC);
|
||||
if(rclose)
|
||||
remove(name);
|
||||
}
|
||||
return fd;
|
||||
}
|
39
src/lib9/pipe.c
Normal file
39
src/lib9/pipe.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/getenv.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/getenv.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include <u.h>
|
||||
#define NOPLAN9DEFINES
|
||||
#include <libc.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/*
|
||||
* We use socketpair to get a two-way pipe.
|
||||
* The pipe still doesn't preserve message boundaries.
|
||||
* Worse, it cannot be reopened via /dev/fd/NNN on Linux.
|
||||
*/
|
||||
int
|
||||
p9pipe(int fd[2])
|
||||
{
|
||||
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
|
||||
}
|
47
src/lib9/readn.c
Normal file
47
src/lib9/readn.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Inferno lib9/readn.c
|
||||
http://code.google.com/p/inferno-os/source/browse/lib9/readn.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <lib9.h>
|
||||
|
||||
long
|
||||
readn(int f, void *av, long n)
|
||||
{
|
||||
char *a;
|
||||
long m, t;
|
||||
|
||||
a = av;
|
||||
t = 0;
|
||||
while(t < n){
|
||||
m = read(f, a+t, n-t);
|
||||
if(m <= 0){
|
||||
if(t == 0)
|
||||
return m;
|
||||
break;
|
||||
}
|
||||
t += m;
|
||||
}
|
||||
return t;
|
||||
}
|
153
src/lib9/rfork.c
Normal file
153
src/lib9/rfork.c
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/rfork.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/rfork.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <libc.h>
|
||||
#undef rfork
|
||||
|
||||
static void
|
||||
nop(int x)
|
||||
{
|
||||
USED(x);
|
||||
}
|
||||
|
||||
int
|
||||
p9rfork(int flags)
|
||||
{
|
||||
int pid, status;
|
||||
int p[2];
|
||||
int n;
|
||||
char buf[128], *q;
|
||||
extern char **environ;
|
||||
|
||||
if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){
|
||||
/* check other flags before we commit */
|
||||
flags &= ~(RFPROC|RFFDG|RFENVG);
|
||||
n = (flags & ~(RFNOTEG|RFNAMEG|RFNOWAIT|RFCENVG));
|
||||
if(n){
|
||||
werrstr("unknown flags %08ux in rfork", n);
|
||||
return -1;
|
||||
}
|
||||
if(flags&RFNOWAIT){
|
||||
/*
|
||||
* BUG - should put the signal handler back after we
|
||||
* finish, but I just don't care. If a program calls with
|
||||
* NOWAIT once, they're not likely to want child notes
|
||||
* after that.
|
||||
*/
|
||||
signal(SIGCHLD, nop);
|
||||
if(pipe(p) < 0)
|
||||
return -1;
|
||||
}
|
||||
pid = fork();
|
||||
if(pid == -1)
|
||||
return -1;
|
||||
if(flags&RFNOWAIT){
|
||||
flags &= ~RFNOWAIT;
|
||||
if(pid){
|
||||
/*
|
||||
* Parent - wait for child to fork wait-free child.
|
||||
* Then read pid from pipe. Assume pipe buffer can absorb the write.
|
||||
*/
|
||||
close(p[1]);
|
||||
status = 0;
|
||||
if(wait4(pid, &status, 0, 0) < 0){
|
||||
werrstr("pipe dance - wait4 - %r");
|
||||
close(p[0]);
|
||||
return -1;
|
||||
}
|
||||
n = readn(p[0], buf, sizeof buf-1);
|
||||
close(p[0]);
|
||||
if(!WIFEXITED(status) || WEXITSTATUS(status)!=0 || n <= 0){
|
||||
if(!WIFEXITED(status))
|
||||
werrstr("pipe dance - !exited 0x%ux", status);
|
||||
else if(WEXITSTATUS(status) != 0)
|
||||
werrstr("pipe dance - non-zero status 0x%ux", status);
|
||||
else if(n < 0)
|
||||
werrstr("pipe dance - pipe read error - %r");
|
||||
else if(n == 0)
|
||||
werrstr("pipe dance - pipe read eof");
|
||||
else
|
||||
werrstr("pipe dance - unknown failure");
|
||||
return -1;
|
||||
}
|
||||
buf[n] = 0;
|
||||
if(buf[0] == 'x'){
|
||||
werrstr("%s", buf+2);
|
||||
return -1;
|
||||
}
|
||||
pid = strtol(buf, &q, 0);
|
||||
}else{
|
||||
/*
|
||||
* Child - fork a new child whose wait message can't
|
||||
* get back to the parent because we're going to exit!
|
||||
*/
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
close(p[0]);
|
||||
pid = fork();
|
||||
if(pid){
|
||||
/* Child parent - send status over pipe and exit. */
|
||||
if(pid > 0)
|
||||
fprint(p[1], "%d", pid);
|
||||
else
|
||||
fprint(p[1], "x %r");
|
||||
close(p[1]);
|
||||
_exit(0);
|
||||
}else{
|
||||
/* Child child - close pipe. */
|
||||
close(p[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(pid != 0)
|
||||
return pid;
|
||||
if(flags&RFCENVG)
|
||||
if(environ)
|
||||
*environ = nil;
|
||||
}
|
||||
if(flags&RFPROC){
|
||||
werrstr("cannot use rfork for shared memory -- use libthread");
|
||||
return -1;
|
||||
}
|
||||
if(flags&RFNAMEG){
|
||||
/* XXX set $NAMESPACE to a new directory */
|
||||
flags &= ~RFNAMEG;
|
||||
}
|
||||
if(flags&RFNOTEG){
|
||||
setpgid(0, getpid());
|
||||
flags &= ~RFNOTEG;
|
||||
}
|
||||
if(flags&RFNOWAIT){
|
||||
werrstr("cannot use RFNOWAIT without RFPROC");
|
||||
return -1;
|
||||
}
|
||||
if(flags){
|
||||
werrstr("unknown flags %08ux in rfork", flags);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
33
src/lib9/seek.c
Normal file
33
src/lib9/seek.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/seek.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/seek.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
vlong
|
||||
seek(int fd, vlong offset, int whence)
|
||||
{
|
||||
return lseek(fd, offset, whence);
|
||||
}
|
42
src/lib9/strecpy.c
Normal file
42
src/lib9/strecpy.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Inferno lib9/strecpy.c
|
||||
http://code.google.com/p/inferno-os/source/browse/lib9/strecpy.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <lib9.h>
|
||||
|
||||
char*
|
||||
strecpy(char *to, char *e, char *from)
|
||||
{
|
||||
if(to >= e)
|
||||
return to;
|
||||
to = memccpy(to, from, '\0', e - to);
|
||||
if(to == nil){
|
||||
to = e - 1;
|
||||
*to = '\0';
|
||||
}else{
|
||||
to--;
|
||||
}
|
||||
return to;
|
||||
}
|
47
src/lib9/sysfatal.c
Normal file
47
src/lib9/sysfatal.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
Plan 9 from User Space src/lib9/sysfatal.c
|
||||
http://code.swtch.com/plan9port/src/tip/src/lib9/sysfatal.c
|
||||
|
||||
Copyright 2001-2007 Russ Cox. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void (*_sysfatal)(char*, ...);
|
||||
|
||||
void
|
||||
sysfatal(char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list arg;
|
||||
|
||||
va_start(arg, fmt);
|
||||
if(_sysfatal)
|
||||
(*_sysfatal)(fmt, arg);
|
||||
vseprint(buf, buf+sizeof buf, fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
__fixargv0();
|
||||
fprint(2, "%s: %s\n", argv0 ? argv0 : "<prog>", buf);
|
||||
exits("fatal");
|
||||
}
|
||||
|
132
src/lib9/tokenize.c
Normal file
132
src/lib9/tokenize.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
Inferno lib9/tokenize.c
|
||||
http://code.google.com/p/inferno-os/source/browse/lib9/tokenize.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <lib9.h>
|
||||
|
||||
static char qsep[] = " \t\r\n";
|
||||
|
||||
static char*
|
||||
qtoken(char *s, char *sep)
|
||||
{
|
||||
int quoting;
|
||||
char *t;
|
||||
|
||||
quoting = 0;
|
||||
t = s; /* s is output string, t is input string */
|
||||
while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
|
||||
if(*t != '\''){
|
||||
*s++ = *t++;
|
||||
continue;
|
||||
}
|
||||
/* *t is a quote */
|
||||
if(!quoting){
|
||||
quoting = 1;
|
||||
t++;
|
||||
continue;
|
||||
}
|
||||
/* quoting and we're on a quote */
|
||||
if(t[1] != '\''){
|
||||
/* end of quoted section; absorb closing quote */
|
||||
t++;
|
||||
quoting = 0;
|
||||
continue;
|
||||
}
|
||||
/* doubled quote; fold one quote into two */
|
||||
t++;
|
||||
*s++ = *t++;
|
||||
}
|
||||
if(*s != '\0'){
|
||||
*s = '\0';
|
||||
if(t == s)
|
||||
t++;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
static char*
|
||||
etoken(char *t, char *sep)
|
||||
{
|
||||
int quoting;
|
||||
|
||||
/* move to end of next token */
|
||||
quoting = 0;
|
||||
while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
|
||||
if(*t != '\''){
|
||||
t++;
|
||||
continue;
|
||||
}
|
||||
/* *t is a quote */
|
||||
if(!quoting){
|
||||
quoting = 1;
|
||||
t++;
|
||||
continue;
|
||||
}
|
||||
/* quoting and we're on a quote */
|
||||
if(t[1] != '\''){
|
||||
/* end of quoted section; absorb closing quote */
|
||||
t++;
|
||||
quoting = 0;
|
||||
continue;
|
||||
}
|
||||
/* doubled quote; fold one quote into two */
|
||||
t += 2;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
int
|
||||
gettokens(char *s, char **args, int maxargs, char *sep)
|
||||
{
|
||||
int nargs;
|
||||
|
||||
for(nargs=0; nargs<maxargs; nargs++){
|
||||
while(*s!='\0' && utfrune(sep, *s)!=nil)
|
||||
*s++ = '\0';
|
||||
if(*s == '\0')
|
||||
break;
|
||||
args[nargs] = s;
|
||||
s = etoken(s, sep);
|
||||
}
|
||||
|
||||
return nargs;
|
||||
}
|
||||
|
||||
int
|
||||
tokenize(char *s, char **args, int maxargs)
|
||||
{
|
||||
int nargs;
|
||||
|
||||
for(nargs=0; nargs<maxargs; nargs++){
|
||||
while(*s!='\0' && utfrune(qsep, *s)!=nil)
|
||||
s++;
|
||||
if(*s == '\0')
|
||||
break;
|
||||
args[nargs] = s;
|
||||
s = qtoken(s, qsep);
|
||||
}
|
||||
|
||||
return nargs;
|
||||
}
|
177
src/lib9/utf/rune.c
Normal file
177
src/lib9/utf/rune.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
|
||||
* ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "plan9.h"
|
||||
#include "utf.h"
|
||||
|
||||
enum
|
||||
{
|
||||
Bit1 = 7,
|
||||
Bitx = 6,
|
||||
Bit2 = 5,
|
||||
Bit3 = 4,
|
||||
Bit4 = 3,
|
||||
|
||||
T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
|
||||
Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
|
||||
T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */
|
||||
T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */
|
||||
T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */
|
||||
|
||||
Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */
|
||||
Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */
|
||||
Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */
|
||||
|
||||
Maskx = (1<<Bitx)-1, /* 0011 1111 */
|
||||
Testx = Maskx ^ 0xFF, /* 1100 0000 */
|
||||
|
||||
Bad = Runeerror
|
||||
};
|
||||
|
||||
int
|
||||
chartorune(Rune *rune, char *str)
|
||||
{
|
||||
int c, c1, c2;
|
||||
long l;
|
||||
|
||||
/*
|
||||
* one character sequence
|
||||
* 00000-0007F => T1
|
||||
*/
|
||||
c = *(uchar*)str;
|
||||
if(c < Tx) {
|
||||
*rune = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* two character sequence
|
||||
* 0080-07FF => T2 Tx
|
||||
*/
|
||||
c1 = *(uchar*)(str+1) ^ Tx;
|
||||
if(c1 & Testx)
|
||||
goto bad;
|
||||
if(c < T3) {
|
||||
if(c < T2)
|
||||
goto bad;
|
||||
l = ((c << Bitx) | c1) & Rune2;
|
||||
if(l <= Rune1)
|
||||
goto bad;
|
||||
*rune = l;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* three character sequence
|
||||
* 0800-FFFF => T3 Tx Tx
|
||||
*/
|
||||
c2 = *(uchar*)(str+2) ^ Tx;
|
||||
if(c2 & Testx)
|
||||
goto bad;
|
||||
if(c < T4) {
|
||||
l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
|
||||
if(l <= Rune2)
|
||||
goto bad;
|
||||
*rune = l;
|
||||
return 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* bad decoding
|
||||
*/
|
||||
bad:
|
||||
*rune = Bad;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
runetochar(char *str, Rune *rune)
|
||||
{
|
||||
long c;
|
||||
|
||||
/*
|
||||
* one character sequence
|
||||
* 00000-0007F => 00-7F
|
||||
*/
|
||||
c = *rune;
|
||||
if(c <= Rune1) {
|
||||
str[0] = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* two character sequence
|
||||
* 0080-07FF => T2 Tx
|
||||
*/
|
||||
if(c <= Rune2) {
|
||||
str[0] = T2 | (c >> 1*Bitx);
|
||||
str[1] = Tx | (c & Maskx);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* three character sequence
|
||||
* 0800-FFFF => T3 Tx Tx
|
||||
*/
|
||||
str[0] = T3 | (c >> 2*Bitx);
|
||||
str[1] = Tx | ((c >> 1*Bitx) & Maskx);
|
||||
str[2] = Tx | (c & Maskx);
|
||||
return 3;
|
||||
}
|
||||
|
||||
int
|
||||
runelen(long c)
|
||||
{
|
||||
Rune rune;
|
||||
char str[10];
|
||||
|
||||
rune = c;
|
||||
return runetochar(str, &rune);
|
||||
}
|
||||
|
||||
int
|
||||
runenlen(Rune *r, int nrune)
|
||||
{
|
||||
int nb, c;
|
||||
|
||||
nb = 0;
|
||||
while(nrune--) {
|
||||
c = *r++;
|
||||
if(c <= Rune1)
|
||||
nb++;
|
||||
else
|
||||
if(c <= Rune2)
|
||||
nb += 2;
|
||||
else
|
||||
nb += 3;
|
||||
}
|
||||
return nb;
|
||||
}
|
||||
|
||||
int
|
||||
fullrune(char *str, int n)
|
||||
{
|
||||
int c;
|
||||
|
||||
if(n > 0) {
|
||||
c = *(uchar*)str;
|
||||
if(c < Tx)
|
||||
return 1;
|
||||
if(n > 1)
|
||||
if(c < T3 || n > 2)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
1151
src/lib9/utf/runetype.c
Normal file
1151
src/lib9/utf/runetype.c
Normal file
File diff suppressed because it is too large
Load diff
47
src/lib9/utf/utfdef.h
Normal file
47
src/lib9/utf/utfdef.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 1998-2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* compiler directive on Plan 9
|
||||
*/
|
||||
#ifndef USED
|
||||
#define USED(x) if(x);else
|
||||
#endif
|
||||
|
||||
/*
|
||||
* easiest way to make sure these are defined
|
||||
*/
|
||||
#define uchar _fmtuchar
|
||||
#define ushort _fmtushort
|
||||
#define uint _fmtuint
|
||||
#define ulong _fmtulong
|
||||
#define vlong _fmtvlong
|
||||
#define uvlong _fmtuvlong
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned long long uvlong;
|
||||
typedef long long vlong;
|
||||
|
||||
/*
|
||||
* nil cannot be ((void*)0) on ANSI C,
|
||||
* because it is used for function pointers
|
||||
*/
|
||||
#undef nil
|
||||
#define nil 0
|
||||
|
||||
#undef nelem
|
||||
#define nelem ((void*)0)
|
||||
|
37
src/lib9/utf/utfecpy.c
Normal file
37
src/lib9/utf/utfecpy.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
|
||||
* ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#define _BSD_SOURCE 1 /* memccpy */
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "plan9.h"
|
||||
#include "utf.h"
|
||||
|
||||
char*
|
||||
utfecpy(char *to, char *e, char *from)
|
||||
{
|
||||
char *end;
|
||||
|
||||
if(to >= e)
|
||||
return to;
|
||||
end = memccpy(to, from, '\0', e - to);
|
||||
if(end == nil){
|
||||
end = e-1;
|
||||
while(end>to && (*--end&0xC0)==0x80)
|
||||
;
|
||||
*end = '\0';
|
||||
}else{
|
||||
end--;
|
||||
}
|
||||
return end;
|
||||
}
|
37
src/lib9/utf/utflen.c
Normal file
37
src/lib9/utf/utflen.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
|
||||
* ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "plan9.h"
|
||||
#include "utf.h"
|
||||
|
||||
int
|
||||
utflen(char *s)
|
||||
{
|
||||
int c;
|
||||
long n;
|
||||
Rune rune;
|
||||
|
||||
n = 0;
|
||||
for(;;) {
|
||||
c = *(uchar*)s;
|
||||
if(c < Runeself) {
|
||||
if(c == 0)
|
||||
return n;
|
||||
s++;
|
||||
} else
|
||||
s += chartorune(&rune, s);
|
||||
n++;
|
||||
}
|
||||
}
|
41
src/lib9/utf/utfnlen.c
Normal file
41
src/lib9/utf/utfnlen.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
|
||||
* ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "plan9.h"
|
||||
#include "utf.h"
|
||||
|
||||
int
|
||||
utfnlen(char *s, long m)
|
||||
{
|
||||
int c;
|
||||
long n;
|
||||
Rune rune;
|
||||
char *es;
|
||||
|
||||
es = s + m;
|
||||
for(n = 0; s < es; n++) {
|
||||
c = *(uchar*)s;
|
||||
if(c < Runeself){
|
||||
if(c == '\0')
|
||||
break;
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if(!fullrune(s, es-s))
|
||||
break;
|
||||
s += chartorune(&rune, s);
|
||||
}
|
||||
return n;
|
||||
}
|
45
src/lib9/utf/utfrrune.c
Normal file
45
src/lib9/utf/utfrrune.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
|
||||
* ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "plan9.h"
|
||||
#include "utf.h"
|
||||
|
||||
char*
|
||||
utfrrune(char *s, long c)
|
||||
{
|
||||
long c1;
|
||||
Rune r;
|
||||
char *s1;
|
||||
|
||||
if(c < Runesync) /* not part of utf sequence */
|
||||
return strrchr(s, c);
|
||||
|
||||
s1 = 0;
|
||||
for(;;) {
|
||||
c1 = *(uchar*)s;
|
||||
if(c1 < Runeself) { /* one byte rune */
|
||||
if(c1 == 0)
|
||||
return s1;
|
||||
if(c1 == c)
|
||||
s1 = s;
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
c1 = chartorune(&r, s);
|
||||
if(r == c)
|
||||
s1 = s;
|
||||
s += c1;
|
||||
}
|
||||
}
|
44
src/lib9/utf/utfrune.c
Normal file
44
src/lib9/utf/utfrune.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
|
||||
* ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "plan9.h"
|
||||
#include "utf.h"
|
||||
|
||||
char*
|
||||
utfrune(char *s, long c)
|
||||
{
|
||||
long c1;
|
||||
Rune r;
|
||||
int n;
|
||||
|
||||
if(c < Runesync) /* not part of utf sequence */
|
||||
return strchr(s, c);
|
||||
|
||||
for(;;) {
|
||||
c1 = *(uchar*)s;
|
||||
if(c1 < Runeself) { /* one byte rune */
|
||||
if(c1 == 0)
|
||||
return 0;
|
||||
if(c1 == c)
|
||||
return s;
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
n = chartorune(&r, s);
|
||||
if(r == c)
|
||||
return s;
|
||||
s += n;
|
||||
}
|
||||
}
|
41
src/lib9/utf/utfutf.c
Normal file
41
src/lib9/utf/utfutf.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
|
||||
* ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "plan9.h"
|
||||
#include "utf.h"
|
||||
|
||||
|
||||
/*
|
||||
* Return pointer to first occurrence of s2 in s1,
|
||||
* 0 if none
|
||||
*/
|
||||
char*
|
||||
utfutf(char *s1, char *s2)
|
||||
{
|
||||
char *p;
|
||||
long f, n1, n2;
|
||||
Rune r;
|
||||
|
||||
n1 = chartorune(&r, s2);
|
||||
f = r;
|
||||
if(f <= Runesync) /* represents self */
|
||||
return strstr(s1, s2);
|
||||
|
||||
n2 = strlen(s2);
|
||||
for(p=s1; p=utfrune(p, f); p+=n1)
|
||||
if(strncmp(p, s2, n2) == 0)
|
||||
return p;
|
||||
return 0;
|
||||
}
|
64
src/libbio/Makefile
Normal file
64
src/libbio/Makefile
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Derived from http://code.google.com/p/inferno-os/source/browse/libbio/mkfile
|
||||
#
|
||||
# Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
# Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
# Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
CFLAGS=-I$(GOROOT)/include
|
||||
O=o
|
||||
|
||||
LIB=libbio.a
|
||||
|
||||
OFILES=\
|
||||
bbuffered.$O\
|
||||
bfildes.$O\
|
||||
bflush.$O\
|
||||
bgetc.$O\
|
||||
bgetrune.$O\
|
||||
bgetd.$O\
|
||||
binit.$O\
|
||||
boffset.$O\
|
||||
bprint.$O\
|
||||
bputc.$O\
|
||||
bputrune.$O\
|
||||
brdline.$O\
|
||||
brdstr.$O\
|
||||
bread.$O\
|
||||
bseek.$O\
|
||||
bwrite.$O\
|
||||
|
||||
HFILES=\
|
||||
$(GOROOT)/include/bio.h\
|
||||
|
||||
install: $(LIB)
|
||||
cp $(LIB) $(GOROOT)/lib
|
||||
|
||||
$(LIB): $(OFILES)
|
||||
ar rsc $(LIB) $(OFILES)
|
||||
|
||||
$(OFILES): $(HFILES)
|
||||
|
||||
y.tab.c: $(YFILES)
|
||||
yacc $(YFLAGS) $(YFILES)
|
||||
|
||||
clean:
|
||||
rm -f $(OFILES) *.6 6.out $(LIB)
|
||||
|
46
src/libbio/bbuffered.c
Normal file
46
src/libbio/bbuffered.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bbuffered.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
int
|
||||
Bbuffered(Biobuf *bp)
|
||||
{
|
||||
switch(bp->state) {
|
||||
case Bracteof:
|
||||
case Bractive:
|
||||
return -bp->icount;
|
||||
|
||||
case Bwactive:
|
||||
return bp->bsize + bp->ocount;
|
||||
|
||||
case Binactive:
|
||||
return 0;
|
||||
}
|
||||
fprint(2, "Bbuffered: unknown state %d\n", bp->state);
|
||||
return 0;
|
||||
}
|
35
src/libbio/bfildes.c
Normal file
35
src/libbio/bfildes.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bfildes.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
int
|
||||
Bfildes(Biobuf *bp)
|
||||
{
|
||||
|
||||
return bp->fid;
|
||||
}
|
59
src/libbio/bflush.c
Normal file
59
src/libbio/bflush.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bflush.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
int
|
||||
Bflush(Biobuf *bp)
|
||||
{
|
||||
int n, c;
|
||||
|
||||
switch(bp->state) {
|
||||
case Bwactive:
|
||||
n = bp->bsize+bp->ocount;
|
||||
if(n == 0)
|
||||
return 0;
|
||||
c = write(bp->fid, bp->bbuf, n);
|
||||
if(n == c) {
|
||||
bp->offset += n;
|
||||
bp->ocount = -bp->bsize;
|
||||
return 0;
|
||||
}
|
||||
bp->state = Binactive;
|
||||
bp->ocount = 0;
|
||||
break;
|
||||
|
||||
case Bracteof:
|
||||
bp->state = Bractive;
|
||||
|
||||
case Bractive:
|
||||
bp->icount = 0;
|
||||
bp->gbuf = bp->ebuf;
|
||||
return 0;
|
||||
}
|
||||
return Beof;
|
||||
}
|
79
src/libbio/bgetc.c
Normal file
79
src/libbio/bgetc.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bgetc.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
int
|
||||
Bgetc(Biobuf *bp)
|
||||
{
|
||||
int i;
|
||||
|
||||
loop:
|
||||
i = bp->icount;
|
||||
if(i != 0) {
|
||||
bp->icount = i+1;
|
||||
return bp->ebuf[i];
|
||||
}
|
||||
if(bp->state != Bractive) {
|
||||
if(bp->state == Bracteof)
|
||||
bp->state = Bractive;
|
||||
return Beof;
|
||||
}
|
||||
/*
|
||||
* get next buffer, try to keep Bungetsize
|
||||
* characters pre-catenated from the previous
|
||||
* buffer to allow that many ungets.
|
||||
*/
|
||||
memmove(bp->bbuf-Bungetsize, bp->ebuf-Bungetsize, Bungetsize);
|
||||
i = read(bp->fid, bp->bbuf, bp->bsize);
|
||||
bp->gbuf = bp->bbuf;
|
||||
if(i <= 0) {
|
||||
bp->state = Bracteof;
|
||||
if(i < 0)
|
||||
bp->state = Binactive;
|
||||
return Beof;
|
||||
}
|
||||
if(i < bp->bsize) {
|
||||
memmove(bp->ebuf-i-Bungetsize, bp->bbuf-Bungetsize, i+Bungetsize);
|
||||
bp->gbuf = bp->ebuf-i;
|
||||
}
|
||||
bp->icount = -i;
|
||||
bp->offset += i;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
int
|
||||
Bungetc(Biobuf *bp)
|
||||
{
|
||||
|
||||
if(bp->state == Bracteof)
|
||||
bp->state = Bractive;
|
||||
if(bp->state != Bractive)
|
||||
return Beof;
|
||||
bp->icount--;
|
||||
return 1;
|
||||
}
|
62
src/libbio/bgetd.c
Normal file
62
src/libbio/bgetd.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bgetd.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
struct bgetd
|
||||
{
|
||||
Biobuf* b;
|
||||
int eof;
|
||||
};
|
||||
|
||||
static int
|
||||
Bgetdf(void *vp)
|
||||
{
|
||||
int c;
|
||||
struct bgetd *bg = vp;
|
||||
|
||||
c = Bgetc(bg->b);
|
||||
if(c == Beof)
|
||||
bg->eof = 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
int
|
||||
Bgetd(Biobuf *bp, double *dp)
|
||||
{
|
||||
double d;
|
||||
struct bgetd b;
|
||||
|
||||
b.b = bp;
|
||||
b.eof = 0;
|
||||
d = fmtcharstod(Bgetdf, &b);
|
||||
if(b.eof)
|
||||
return -1;
|
||||
Bungetc(bp);
|
||||
*dp = d;
|
||||
return 1;
|
||||
}
|
73
src/libbio/bgetrune.c
Normal file
73
src/libbio/bgetrune.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bgetrune.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <utf.h>
|
||||
|
||||
long
|
||||
Bgetrune(Biobuf *bp)
|
||||
{
|
||||
int c, i;
|
||||
Rune rune;
|
||||
char str[4];
|
||||
|
||||
c = Bgetc(bp);
|
||||
if(c < Runeself) { /* one char */
|
||||
bp->runesize = 1;
|
||||
return c;
|
||||
}
|
||||
str[0] = c;
|
||||
|
||||
for(i=1;;) {
|
||||
c = Bgetc(bp);
|
||||
if(c < 0)
|
||||
return c;
|
||||
str[i++] = c;
|
||||
|
||||
if(fullrune(str, i)) {
|
||||
bp->runesize = chartorune(&rune, str);
|
||||
while(i > bp->runesize) {
|
||||
Bungetc(bp);
|
||||
i--;
|
||||
}
|
||||
return rune;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Bungetrune(Biobuf *bp)
|
||||
{
|
||||
|
||||
if(bp->state == Bracteof)
|
||||
bp->state = Bractive;
|
||||
if(bp->state != Bractive)
|
||||
return Beof;
|
||||
bp->icount -= bp->runesize;
|
||||
bp->runesize = 0;
|
||||
return 1;
|
||||
}
|
179
src/libbio/binit.c
Normal file
179
src/libbio/binit.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/binit.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
enum
|
||||
{
|
||||
MAXBUFS = 20
|
||||
};
|
||||
|
||||
static Biobuf* wbufs[MAXBUFS];
|
||||
static int atexitflag;
|
||||
|
||||
static
|
||||
void
|
||||
batexit(void)
|
||||
{
|
||||
Biobuf *bp;
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAXBUFS; i++) {
|
||||
bp = wbufs[i];
|
||||
if(bp != 0) {
|
||||
wbufs[i] = 0;
|
||||
Bflush(bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
deinstall(Biobuf *bp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAXBUFS; i++)
|
||||
if(wbufs[i] == bp)
|
||||
wbufs[i] = 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
install(Biobuf *bp)
|
||||
{
|
||||
int i;
|
||||
|
||||
deinstall(bp);
|
||||
for(i=0; i<MAXBUFS; i++)
|
||||
if(wbufs[i] == 0) {
|
||||
wbufs[i] = bp;
|
||||
break;
|
||||
}
|
||||
if(atexitflag == 0) {
|
||||
atexitflag = 1;
|
||||
atexit(batexit);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Binits(Biobuf *bp, int f, int mode, unsigned char *p, int size)
|
||||
{
|
||||
|
||||
p += Bungetsize; /* make room for Bungets */
|
||||
size -= Bungetsize;
|
||||
|
||||
switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) {
|
||||
default:
|
||||
fprint(2, "Bopen: unknown mode %d\n", mode);
|
||||
return Beof;
|
||||
|
||||
case OREAD:
|
||||
bp->state = Bractive;
|
||||
bp->ocount = 0;
|
||||
break;
|
||||
|
||||
case OWRITE:
|
||||
install(bp);
|
||||
bp->state = Bwactive;
|
||||
bp->ocount = -size;
|
||||
break;
|
||||
}
|
||||
bp->bbuf = p;
|
||||
bp->ebuf = p+size;
|
||||
bp->bsize = size;
|
||||
bp->icount = 0;
|
||||
bp->gbuf = bp->ebuf;
|
||||
bp->fid = f;
|
||||
bp->flag = 0;
|
||||
bp->rdline = 0;
|
||||
bp->offset = 0;
|
||||
bp->runesize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Binit(Biobuf *bp, int f, int mode)
|
||||
{
|
||||
return Binits(bp, f, mode, bp->b, sizeof(bp->b));
|
||||
}
|
||||
|
||||
Biobuf*
|
||||
Bfdopen(int f, int mode)
|
||||
{
|
||||
Biobuf *bp;
|
||||
|
||||
bp = malloc(sizeof(Biobuf));
|
||||
if(bp == 0)
|
||||
return 0;
|
||||
Binits(bp, f, mode, bp->b, sizeof(bp->b));
|
||||
bp->flag = Bmagic;
|
||||
return bp;
|
||||
}
|
||||
|
||||
Biobuf*
|
||||
Bopen(char *name, int mode)
|
||||
{
|
||||
Biobuf *bp;
|
||||
int f;
|
||||
|
||||
switch(mode&~(OCEXEC|ORCLOSE|OTRUNC)) {
|
||||
default:
|
||||
fprint(2, "Bopen: unknown mode %d\n", mode);
|
||||
return 0;
|
||||
|
||||
case OREAD:
|
||||
f = open(name, OREAD);
|
||||
if(f < 0)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case OWRITE:
|
||||
f = creat(name, 0666);
|
||||
if(f < 0)
|
||||
return 0;
|
||||
}
|
||||
bp = Bfdopen(f, mode);
|
||||
if(bp == 0)
|
||||
close(f);
|
||||
return bp;
|
||||
}
|
||||
|
||||
int
|
||||
Bterm(Biobuf *bp)
|
||||
{
|
||||
|
||||
deinstall(bp);
|
||||
Bflush(bp);
|
||||
if(bp->flag == Bmagic) {
|
||||
bp->flag = 0;
|
||||
close(bp->fid);
|
||||
free(bp);
|
||||
}
|
||||
return 0;
|
||||
}
|
50
src/libbio/boffset.c
Normal file
50
src/libbio/boffset.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/boffset.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "lib9.h"
|
||||
#include <bio.h>
|
||||
|
||||
off_t
|
||||
Boffset(Biobuf *bp)
|
||||
{
|
||||
off_t n;
|
||||
|
||||
switch(bp->state) {
|
||||
default:
|
||||
fprint(2, "Boffset: unknown state %d\n", bp->state);
|
||||
n = Beof;
|
||||
break;
|
||||
|
||||
case Bracteof:
|
||||
case Bractive:
|
||||
n = bp->offset + bp->icount;
|
||||
break;
|
||||
|
||||
case Bwactive:
|
||||
n = bp->offset + (bp->bsize + bp->ocount);
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
54
src/libbio/bprint.c
Normal file
54
src/libbio/bprint.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bprint.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
int
|
||||
Bprint(Biobuf *bp, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *ip, *ep, *out;
|
||||
int n;
|
||||
|
||||
ep = (char*)bp->ebuf;
|
||||
ip = ep + bp->ocount;
|
||||
va_start(ap, fmt);
|
||||
out = vseprint(ip, ep, fmt, ap);
|
||||
va_end(ap);
|
||||
if(out == nil || out >= ep-5) {
|
||||
Bflush(bp);
|
||||
ip = ep + bp->ocount;
|
||||
va_start(ap, fmt);
|
||||
out = vseprint(ip, ep, fmt, ap);
|
||||
va_end(ap);
|
||||
if(out >= ep-5)
|
||||
return Beof;
|
||||
}
|
||||
n = out-ip;
|
||||
bp->ocount += n;
|
||||
return n;
|
||||
}
|
46
src/libbio/bputc.c
Normal file
46
src/libbio/bputc.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bputc.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
int
|
||||
Bputc(Biobuf *bp, int c)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(;;) {
|
||||
i = bp->ocount;
|
||||
if(i) {
|
||||
bp->ebuf[i++] = c;
|
||||
bp->ocount = i;
|
||||
return 0;
|
||||
}
|
||||
if(Bflush(bp) == Beof)
|
||||
break;
|
||||
}
|
||||
return Beof;
|
||||
}
|
49
src/libbio/bputrune.c
Normal file
49
src/libbio/bputrune.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/bputrune.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <utf.h>
|
||||
|
||||
int
|
||||
Bputrune(Biobuf *bp, long c)
|
||||
{
|
||||
Rune rune;
|
||||
char str[4];
|
||||
int n;
|
||||
|
||||
rune = c;
|
||||
if(rune < Runeself) {
|
||||
Bputc(bp, rune);
|
||||
return 1;
|
||||
}
|
||||
n = runetochar(str, &rune);
|
||||
if(n == 0)
|
||||
return Bbad;
|
||||
if(Bwrite(bp, str, n) != n)
|
||||
return Beof;
|
||||
return n;
|
||||
}
|
120
src/libbio/brdline.c
Normal file
120
src/libbio/brdline.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
http://code.google.com/p/inferno-os/source/browse/libbio/brdline.c
|
||||
|
||||
Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com). All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
void*
|
||||
Brdline(Biobuf *bp, int delim)
|
||||
{
|
||||
char *ip, *ep;
|
||||
int i, j;
|
||||
|
||||
i = -bp->icount;
|
||||
if(i == 0) {
|
||||
/*
|
||||
* eof or other error
|
||||
*/
|
||||
if(bp->state != Bractive) {
|
||||
if(bp->state == Bracteof)
|
||||
bp->state = Bractive;
|
||||
bp->rdline = 0;
|
||||
bp->gbuf = bp->ebuf;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* first try in remainder of buffer (gbuf doesn't change)
|
||||
*/
|
||||
ip = (char*)bp->ebuf - i;
|
||||
ep = memchr(ip, delim, i);
|
||||
if(ep) {
|
||||
j = (ep - ip) + 1;
|
||||
bp->rdline = j;
|
||||
bp->icount += j;
|
||||
return ip;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy data to beginning of buffer
|
||||
*/
|
||||
if(i < bp->bsize)
|
||||
memmove(bp->bbuf, ip, i);
|
||||
bp->gbuf = bp->bbuf;
|
||||
|
||||
/*
|
||||
* append to buffer looking for the delim
|
||||
*/
|
||||
ip = (char*)bp->bbuf + i;
|
||||
while(i < bp->bsize) {
|
||||
j = read(bp->fid, ip, bp->bsize-i);
|
||||
if(j <= 0) {
|
||||
/*
|
||||
* end of file with no delim
|
||||
*/
|
||||
memmove(bp->ebuf-i, bp->bbuf, i);
|
||||
bp->rdline = i;
|
||||
bp->icount = -i;
|
||||
bp->gbuf = bp->ebuf-i;
|
||||
return 0;
|
||||
}
|
||||
bp->offset += j;
|
||||
i += j;
|
||||
ep = memchr(ip, delim, j);
|
||||
if(ep) {
|
||||
/*
|
||||
* found in new piece
|
||||
* copy back up and reset everything
|
||||
*/
|
||||
ip = (char*)bp->ebuf - i;
|
||||
if(i < bp->bsize){
|
||||
memmove(ip, bp->bbuf, i);
|
||||
bp->gbuf = (unsigned char*)ip;
|
||||
}
|
||||
j = (ep - (char*)bp->bbuf) + 1;
|
||||
bp->rdline = j;
|
||||
bp->icount = j - i;
|
||||
return ip;
|
||||
}
|
||||
ip += j;
|
||||
}
|
||||
|
||||
/*
|
||||
* full buffer without finding
|
||||
*/
|
||||
bp->rdline = bp->bsize;
|
||||
bp->icount = -bp->bsize;
|
||||
bp->gbuf = bp->bbuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Blinelen(Biobuf *bp)
|
||||
{
|
||||
|
||||
return bp->rdline;
|
||||
}
|
60
src/libbio/brdstr.c
Normal file
60
src/libbio/brdstr.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright © 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
char*
|
||||
Brdstr(Biobuf *bp, int delim, int nulldelim)
|
||||
{
|
||||
char *p, *q, *nq;
|
||||
int n, linelen;
|
||||
|
||||
q = nil;
|
||||
n = 0;
|
||||
for(;;) {
|
||||
p = Brdline(bp, delim);
|
||||
linelen = Blinelen(bp);
|
||||
if(n == 0 && linelen == 0)
|
||||
return nil;
|
||||
nq = realloc(q, n+linelen+1);
|
||||
if(nq == nil) {
|
||||
free(q);
|
||||
return nil;
|
||||
}
|
||||
q = nq;
|
||||
if(p != nil) {
|
||||
memmove(q+n, p, linelen);
|
||||
n += linelen;
|
||||
if(nulldelim)
|
||||
q[n-1] = '\0';
|
||||
break;
|
||||
}
|
||||
if(linelen == 0)
|
||||
break;
|
||||
Bread(bp, q+n, linelen);
|
||||
n += linelen;
|
||||
}
|
||||
q[n] = '\0';
|
||||
return q;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue