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:
Rob Pike 2008-06-12 13:26:16 -07:00
parent a40a79829f
commit 69b74c3953
106 changed files with 9552 additions and 12 deletions

117
include/bio.h Normal file
View 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
View 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
View 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
View 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
View 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

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load diff

47
src/lib9/utf/utfdef.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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