Move utf, fmt. Small header file changes.
This commit is contained in:
parent
5a8e63b2f0
commit
91c13e54b5
73 changed files with 5771 additions and 3 deletions
19
src/lib9/fmt/LICENSE
Normal file
19
src/lib9/fmt/LICENSE
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This is a Unix port of the Plan 9 formatted I/O package.
|
||||
|
||||
Please send comments about the packaging
|
||||
to Russ Cox <rsc@post.harvard.edu>.
|
||||
|
||||
19
src/lib9/fmt/NOTICE
Normal file
19
src/lib9/fmt/NOTICE
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This is a Unix port of the Plan 9 formatted I/O package.
|
||||
|
||||
Please send comments about the packaging
|
||||
to Russ Cox <rsc@post.harvard.edu>.
|
||||
|
||||
19
src/lib9/fmt/README
Normal file
19
src/lib9/fmt/README
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
This is a Unix port of the Plan 9 formatted I/O package.
|
||||
|
||||
Please send comments about the packaging
|
||||
to Russ Cox <rsc@post.harvard.edu>.
|
||||
|
||||
85
src/lib9/fmt/charstod.c
Normal file
85
src/lib9/fmt/charstod.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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;
|
||||
}
|
||||
558
src/lib9/fmt/dofmt.c
Normal file
558
src/lib9/fmt/dofmt.c
Normal file
|
|
@ -0,0 +1,558 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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;
|
||||
}
|
||||
return 0; /* not reached */
|
||||
}
|
||||
|
||||
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 charactes
|
||||
*/
|
||||
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;
|
||||
w = f->width;
|
||||
fl = f->flags;
|
||||
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(m < me)
|
||||
return -1;
|
||||
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;
|
||||
w = f->width;
|
||||
fl = f->flags;
|
||||
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 p, i;
|
||||
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(i = 0; i < p; i++)
|
||||
if(s[i] == 0)
|
||||
break;
|
||||
return __fmtcpy(f, s, utfnlen(s, i), i); /* BUG?: won't print a partial rune at end */
|
||||
}
|
||||
|
||||
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[70], *p, *conv;
|
||||
uvlong vu;
|
||||
ulong u;
|
||||
int neg, base, i, n, fl, w, isv;
|
||||
|
||||
neg = 0;
|
||||
fl = f->flags;
|
||||
isv = 0;
|
||||
vu = 0;
|
||||
u = 0;
|
||||
/*
|
||||
* Unsigned verbs
|
||||
*/
|
||||
switch(f->r){
|
||||
case 'o':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 'X':
|
||||
fl |= FmtUnsigned;
|
||||
break;
|
||||
}
|
||||
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";
|
||||
switch(f->r){
|
||||
case 'd':
|
||||
case 'i':
|
||||
base = 10;
|
||||
break;
|
||||
case 'u':
|
||||
base = 10;
|
||||
break;
|
||||
case 'x':
|
||||
base = 16;
|
||||
break;
|
||||
case 'X':
|
||||
base = 16;
|
||||
conv = "0123456789ABCDEF";
|
||||
break;
|
||||
case 'b':
|
||||
base = 2;
|
||||
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;
|
||||
}
|
||||
}else{
|
||||
fl &= ~(FmtSign|FmtSpace); /* no + for unsigned conversions */
|
||||
}
|
||||
p = buf + sizeof buf - 1;
|
||||
n = 0;
|
||||
if(isv){
|
||||
while(vu){
|
||||
i = vu % base;
|
||||
vu /= base;
|
||||
if((fl & FmtComma) && n % 4 == 3){
|
||||
*p-- = ',';
|
||||
n++;
|
||||
}
|
||||
*p-- = conv[i];
|
||||
n++;
|
||||
}
|
||||
}else{
|
||||
while(u){
|
||||
i = u % base;
|
||||
u /= base;
|
||||
if((fl & FmtComma) && n % 4 == 3){
|
||||
*p-- = ',';
|
||||
n++;
|
||||
}
|
||||
*p-- = conv[i];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if(n == 0){
|
||||
if(!(fl & FmtPrec) || f->prec != 0){
|
||||
*p-- = '0';
|
||||
n = 1;
|
||||
}
|
||||
fl &= ~FmtSharp;
|
||||
}
|
||||
for(w = f->prec; n < w && p > buf+3; n++)
|
||||
*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))){
|
||||
for(w = f->width; n < w && p > buf+3; n++)
|
||||
*p-- = '0';
|
||||
f->width = 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 |= 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;
|
||||
}
|
||||
61
src/lib9/fmt/dorfmt.c
Normal file
61
src/lib9/fmt/dorfmt.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
/* format the output into f->to and return the number of characters fmted */
|
||||
|
||||
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 = f->to;
|
||||
rs = 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 = f->to;
|
||||
s = 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 = __fmtdispatch(f, fmt, 1);
|
||||
if(fmt == nil)
|
||||
return -1;
|
||||
}
|
||||
return 0; /* not reached */
|
||||
}
|
||||
28
src/lib9/fmt/errfmt.c
Normal file
28
src/lib9/fmt/errfmt.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 <errno.h>
|
||||
#include <string.h>
|
||||
#include "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
__errfmt(Fmt *f)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = strerror(errno);
|
||||
return fmtstrcpy(f, s);
|
||||
}
|
||||
610
src/lib9/fmt/fltfmt.c
Normal file
610
src/lib9/fmt/fltfmt.c
Normal file
|
|
@ -0,0 +1,610 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
#include "nan.h"
|
||||
|
||||
enum
|
||||
{
|
||||
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,
|
||||
};
|
||||
|
||||
static double
|
||||
pow10(int n)
|
||||
{
|
||||
double d;
|
||||
int neg;
|
||||
|
||||
neg = 0;
|
||||
if(n < 0){
|
||||
if(n < DBL_MIN_10_EXP){
|
||||
return 0.;
|
||||
}
|
||||
neg = 1;
|
||||
n = -n;
|
||||
}else if(n > DBL_MAX_10_EXP){
|
||||
return HUGE_VAL;
|
||||
}
|
||||
if(n < (int)(sizeof(pows10)/sizeof(pows10[0])))
|
||||
d = pows10[n];
|
||||
else{
|
||||
d = pows10[sizeof(pows10)/sizeof(pows10[0]) - 1];
|
||||
for(;;){
|
||||
n -= sizeof(pows10)/sizeof(pows10[0]) - 1;
|
||||
if(n < (int)(sizeof(pows10)/sizeof(pows10[0]))){
|
||||
d *= pows10[n];
|
||||
break;
|
||||
}
|
||||
d *= pows10[sizeof(pows10)/sizeof(pows10[0]) - 1];
|
||||
}
|
||||
}
|
||||
if(neg){
|
||||
return 1./d;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
static int
|
||||
xadd(char *a, int n, int v)
|
||||
{
|
||||
char *b;
|
||||
int c;
|
||||
|
||||
if(n < 0 || n >= NSIGNIF)
|
||||
return 0;
|
||||
for(b = a+n; b >= a; b--) {
|
||||
c = *b + v;
|
||||
if(c <= '9') {
|
||||
*b = c;
|
||||
return 0;
|
||||
}
|
||||
*b = '0';
|
||||
v = 1;
|
||||
}
|
||||
*a = '1'; /* overflow adding */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
xsub(char *a, int n, int v)
|
||||
{
|
||||
char *b;
|
||||
int c;
|
||||
|
||||
for(b = a+n; b >= a; b--) {
|
||||
c = *b - v;
|
||||
if(c >= '0') {
|
||||
*b = c;
|
||||
return 0;
|
||||
}
|
||||
*b = '9';
|
||||
v = 1;
|
||||
}
|
||||
*a = '9'; /* underflow subtracting */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
xaddexp(char *p, int e)
|
||||
{
|
||||
char se[9];
|
||||
int i;
|
||||
|
||||
*p++ = 'e';
|
||||
if(e < 0) {
|
||||
*p++ = '-';
|
||||
e = -e;
|
||||
}
|
||||
i = 0;
|
||||
while(e) {
|
||||
se[i++] = e % 10 + '0';
|
||||
e /= 10;
|
||||
}
|
||||
if(i == 0) {
|
||||
*p++ = '0';
|
||||
} else {
|
||||
while(i > 0)
|
||||
*p++ = se[--i];
|
||||
}
|
||||
*p++ = '\0';
|
||||
}
|
||||
|
||||
static char*
|
||||
xdodtoa(char *s1, double f, int chr, int prec, int *decpt, int *rsign)
|
||||
{
|
||||
char s2[NSIGNIF+10];
|
||||
double g, h;
|
||||
int e, d, i;
|
||||
int c2, sign, oerr;
|
||||
|
||||
if(chr == 'F')
|
||||
chr = 'f';
|
||||
if(prec > NSIGNIF)
|
||||
prec = NSIGNIF;
|
||||
if(prec < 0)
|
||||
prec = 0;
|
||||
if(__isNaN(f)) {
|
||||
*decpt = 9999;
|
||||
*rsign = 0;
|
||||
strcpy(s1, "nan");
|
||||
return &s1[3];
|
||||
}
|
||||
sign = 0;
|
||||
if(f < 0) {
|
||||
f = -f;
|
||||
sign++;
|
||||
}
|
||||
*rsign = sign;
|
||||
if(__isInf(f, 1) || __isInf(f, -1)) {
|
||||
*decpt = 9999;
|
||||
strcpy(s1, "inf");
|
||||
return &s1[3];
|
||||
}
|
||||
|
||||
e = 0;
|
||||
g = f;
|
||||
if(g != 0) {
|
||||
frexp(f, &e);
|
||||
e = (int)(e * .301029995664);
|
||||
if(e >= -150 && e <= +150) {
|
||||
d = 0;
|
||||
h = f;
|
||||
} else {
|
||||
d = e/2;
|
||||
h = f * pow10(-d);
|
||||
}
|
||||
g = h * pow10(d-e);
|
||||
while(g < 1) {
|
||||
e--;
|
||||
g = h * pow10(d-e);
|
||||
}
|
||||
while(g >= 10) {
|
||||
e++;
|
||||
g = h * pow10(d-e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* convert NSIGNIF digits and convert
|
||||
* back to get accuracy.
|
||||
*/
|
||||
for(i=0; i<NSIGNIF; i++) {
|
||||
d = (int)g;
|
||||
s1[i] = d + '0';
|
||||
g = (g - d) * 10;
|
||||
}
|
||||
s1[i] = 0;
|
||||
|
||||
/*
|
||||
* try decimal rounding to eliminate 9s
|
||||
*/
|
||||
c2 = prec + 1;
|
||||
if(chr == 'f')
|
||||
c2 += e;
|
||||
oerr = errno;
|
||||
if(c2 >= NSIGNIF-2) {
|
||||
strcpy(s2, s1);
|
||||
d = e;
|
||||
s1[NSIGNIF-2] = '0';
|
||||
s1[NSIGNIF-1] = '0';
|
||||
xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
|
||||
g = fmtstrtod(s1, nil);
|
||||
if(g == f)
|
||||
goto found;
|
||||
if(xadd(s1, NSIGNIF-3, 1)) {
|
||||
e++;
|
||||
xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
|
||||
}
|
||||
g = fmtstrtod(s1, nil);
|
||||
if(g == f)
|
||||
goto found;
|
||||
strcpy(s1, s2);
|
||||
e = d;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert back so s1 gets exact answer
|
||||
*/
|
||||
for(d = 0; d < 10; d++) {
|
||||
xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
|
||||
g = fmtstrtod(s1, nil);
|
||||
if(f > g) {
|
||||
if(xadd(s1, NSIGNIF-1, 1))
|
||||
e--;
|
||||
continue;
|
||||
}
|
||||
if(f < g) {
|
||||
if(xsub(s1, NSIGNIF-1, 1))
|
||||
e++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
found:
|
||||
errno = oerr;
|
||||
|
||||
/*
|
||||
* sign
|
||||
*/
|
||||
d = 0;
|
||||
i = 0;
|
||||
|
||||
/*
|
||||
* round & adjust 'f' digits
|
||||
*/
|
||||
c2 = prec + 1;
|
||||
if(chr == 'f'){
|
||||
if(xadd(s1, c2+e, 5))
|
||||
e++;
|
||||
c2 += e;
|
||||
if(c2 < 0){
|
||||
c2 = 0;
|
||||
e = -prec - 1;
|
||||
}
|
||||
}else{
|
||||
if(xadd(s1, c2, 5))
|
||||
e++;
|
||||
}
|
||||
if(c2 > NSIGNIF){
|
||||
c2 = NSIGNIF;
|
||||
}
|
||||
|
||||
*decpt = e + 1;
|
||||
|
||||
/*
|
||||
* terminate the converted digits
|
||||
*/
|
||||
s1[c2] = '\0';
|
||||
return &s1[c2];
|
||||
}
|
||||
|
||||
/*
|
||||
* this function works like the standard dtoa, if you want it.
|
||||
*/
|
||||
#if 0
|
||||
static char*
|
||||
__dtoa(double f, int mode, int ndigits, int *decpt, int *rsign, char **rve)
|
||||
{
|
||||
static char s2[NSIGNIF + 10];
|
||||
char *es;
|
||||
int chr, prec;
|
||||
|
||||
switch(mode) {
|
||||
/* like 'e' */
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
chr = 'e';
|
||||
break;
|
||||
/* like 'g' */
|
||||
case 0:
|
||||
case 1:
|
||||
default:
|
||||
chr = 'g';
|
||||
break;
|
||||
/* like 'f' */
|
||||
case 3:
|
||||
case 5:
|
||||
case 7:
|
||||
case 9:
|
||||
chr = 'f';
|
||||
break;
|
||||
}
|
||||
|
||||
if(chr != 'f' && ndigits){
|
||||
ndigits--;
|
||||
}
|
||||
prec = ndigits;
|
||||
if(prec > NSIGNIF)
|
||||
prec = NSIGNIF;
|
||||
if(ndigits == 0)
|
||||
prec = NSIGNIF;
|
||||
es = xdodtoa(s2, f, chr, prec, decpt, rsign);
|
||||
|
||||
/*
|
||||
* strip trailing 0
|
||||
*/
|
||||
for(; es > s2 + 1; es--){
|
||||
if(es[-1] != '0'){
|
||||
break;
|
||||
}
|
||||
}
|
||||
*es = '\0';
|
||||
if(rve != NULL)
|
||||
*rve = es;
|
||||
return s2;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
fmtzdotpad(Fmt *f, int n, int pt)
|
||||
{
|
||||
char *t, *s;
|
||||
int i;
|
||||
Rune *rt, *rs;
|
||||
|
||||
if(f->runes){
|
||||
rt = (Rune*)f->to;
|
||||
rs = (Rune*)f->stop;
|
||||
for(i = 0; i < n; i++){
|
||||
if(i == pt){
|
||||
FMTRCHAR(f, rt, rs, '.');
|
||||
}
|
||||
FMTRCHAR(f, rt, rs, '0');
|
||||
}
|
||||
f->nfmt += rt - (Rune*)f->to;
|
||||
f->to = rt;
|
||||
}else{
|
||||
t = (char*)f->to;
|
||||
s = (char*)f->stop;
|
||||
for(i = 0; i < n; i++){
|
||||
if(i == pt){
|
||||
FMTCHAR(f, t, s, '.');
|
||||
}
|
||||
FMTCHAR(f, t, s, '0');
|
||||
}
|
||||
f->nfmt += t - (char *)f->to;
|
||||
f->to = t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__efgfmt(Fmt *fmt)
|
||||
{
|
||||
double f;
|
||||
char s1[NSIGNIF+10];
|
||||
int e, d, n;
|
||||
int c1, c2, c3, c4, ucase, sign, chr, prec, fl;
|
||||
|
||||
f = va_arg(fmt->args, double);
|
||||
prec = FDEFLT;
|
||||
fl = fmt->flags;
|
||||
fmt->flags = 0;
|
||||
if(fl & FmtPrec)
|
||||
prec = fmt->prec;
|
||||
chr = fmt->r;
|
||||
ucase = 0;
|
||||
if(chr == 'E'){
|
||||
chr = 'e';
|
||||
ucase = 1;
|
||||
}else if(chr == 'F'){
|
||||
chr = 'f';
|
||||
ucase = 1;
|
||||
}else if(chr == 'G'){
|
||||
chr = 'g';
|
||||
ucase = 1;
|
||||
}
|
||||
if(prec > 0 && chr == 'g')
|
||||
prec--;
|
||||
if(prec < 0)
|
||||
prec = 0;
|
||||
|
||||
xdodtoa(s1, f, chr, prec, &e, &sign);
|
||||
e--;
|
||||
if(*s1 == 'i' || *s1 == 'n'){
|
||||
if(ucase){
|
||||
if(*s1 == 'i'){
|
||||
strcpy(s1, "INF");
|
||||
}else{
|
||||
strcpy(s1, "NAN");
|
||||
}
|
||||
}
|
||||
fmt->flags = fl & (FmtWidth|FmtLeft);
|
||||
return __fmtcpy(fmt, (const void*)s1, 3, 3);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy into final place
|
||||
* c1 digits of leading '0'
|
||||
* c2 digits from conversion
|
||||
* c3 digits of trailing '0'
|
||||
* c4 digits after '.'
|
||||
*/
|
||||
c1 = 0;
|
||||
c2 = prec + 1;
|
||||
c3 = 0;
|
||||
c4 = prec;
|
||||
switch(chr) {
|
||||
default:
|
||||
chr = 'e';
|
||||
break;
|
||||
case 'g':
|
||||
/*
|
||||
* decide on 'e' of 'f' style convers
|
||||
*/
|
||||
if(e >= -4 && e <= prec) {
|
||||
c1 = -e;
|
||||
c4 = prec - e;
|
||||
chr = 'h'; /* flag for 'f' style */
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
c1 = -e;
|
||||
if(c1 > prec)
|
||||
c1 = prec + 1;
|
||||
c2 += e;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* clean up c1 c2 and c3
|
||||
*/
|
||||
if(c1 < 0)
|
||||
c1 = 0;
|
||||
if(c2 < 0)
|
||||
c2 = 0;
|
||||
if(c2 > NSIGNIF) {
|
||||
c3 = c2-NSIGNIF;
|
||||
c2 = NSIGNIF;
|
||||
}
|
||||
|
||||
/*
|
||||
* trim trailing zeros for %g
|
||||
*/
|
||||
if(!(fl & FmtSharp)
|
||||
&& (chr == 'g' || chr == 'h')){
|
||||
if(c4 >= c3){
|
||||
c4 -= c3;
|
||||
c3 = 0;
|
||||
}else{
|
||||
c3 -= c4;
|
||||
c4 = 0;
|
||||
}
|
||||
while(c4 && c2 > 1 && s1[c2 - 1] == '0'){
|
||||
c4--;
|
||||
c2--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* calculate the total length
|
||||
*/
|
||||
n = c1 + c2 + c3;
|
||||
if(sign || (fl & (FmtSign|FmtSpace)))
|
||||
n++;
|
||||
if(c4 || (fl & FmtSharp)){
|
||||
n++;
|
||||
}
|
||||
if(chr == 'e' || chr == 'g'){
|
||||
n += 4;
|
||||
if(e >= 100)
|
||||
n++;
|
||||
}
|
||||
|
||||
/*
|
||||
* pad to width if right justified
|
||||
*/
|
||||
if((fl & (FmtWidth|FmtLeft)) == FmtWidth && n < fmt->width){
|
||||
if(fl & FmtZero){
|
||||
c1 += fmt->width - n;
|
||||
}else{
|
||||
if(__fmtpad(fmt, fmt->width - n) < 0){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sign
|
||||
*/
|
||||
d = 0;
|
||||
if(sign)
|
||||
d = '-';
|
||||
else if(fl & FmtSign)
|
||||
d = '+';
|
||||
else if(fl & FmtSpace)
|
||||
d = ' ';
|
||||
if(d && fmtrune(fmt, d) < 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy digits
|
||||
*/
|
||||
c4 = c1 + c2 + c3 - c4;
|
||||
if(c1 > 0){
|
||||
if(fmtzdotpad(fmt, c1, c4) < 0){
|
||||
return -1;
|
||||
}
|
||||
c4 -= c1;
|
||||
}
|
||||
d = 0;
|
||||
if(c4 >= 0 && c4 < c2){
|
||||
if(__fmtcpy(fmt, s1, c4, c4) < 0 || fmtrune(fmt, '.') < 0)
|
||||
return -1;
|
||||
d = c4;
|
||||
c2 -= c4;
|
||||
c4 = -1;
|
||||
}
|
||||
if(__fmtcpy(fmt, (const void*)(s1 + d), c2, c2) < 0){
|
||||
return -1;
|
||||
}
|
||||
c4 -= c2;
|
||||
if(c3 > 0){
|
||||
if(fmtzdotpad(fmt, c3, c4) < 0){
|
||||
return -1;
|
||||
}
|
||||
c4 -= c3;
|
||||
}
|
||||
|
||||
/*
|
||||
* strip trailing '0' on g conv
|
||||
*/
|
||||
if((fl & FmtSharp) && c4 == 0 && fmtrune(fmt, '.') < 0){
|
||||
return -1;
|
||||
}
|
||||
if(chr == 'e' || chr == 'g') {
|
||||
d = 0;
|
||||
if(ucase)
|
||||
s1[d++] = 'E';
|
||||
else
|
||||
s1[d++] = 'e';
|
||||
c1 = e;
|
||||
if(c1 < 0) {
|
||||
s1[d++] = '-';
|
||||
c1 = -c1;
|
||||
} else
|
||||
s1[d++] = '+';
|
||||
if(c1 >= 100) {
|
||||
s1[d++] = c1/100 + '0';
|
||||
c1 = c1%100;
|
||||
}
|
||||
s1[d++] = c1/10 + '0';
|
||||
s1[d++] = c1%10 + '0';
|
||||
if(__fmtcpy(fmt, s1, d, d) < 0){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if((fl & (FmtWidth|FmtLeft)) == (FmtWidth|FmtLeft) && n < fmt->width){
|
||||
if(__fmtpad(fmt, fmt->width - n) < 0){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
221
src/lib9/fmt/fmt.c
Normal file
221
src/lib9/fmt/fmt.c
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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 */
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
/* lock by calling __fmtlock, __fmtunlock */
|
||||
int nfmt;
|
||||
Convfmt fmt[Maxfmt];
|
||||
} fmtalloc;
|
||||
|
||||
static Convfmt knownfmt[] = {
|
||||
' ', __flagfmt,
|
||||
'#', __flagfmt,
|
||||
'%', __percentfmt,
|
||||
'+', __flagfmt,
|
||||
',', __flagfmt,
|
||||
'-', __flagfmt,
|
||||
'C', __runefmt, /* Plan 9 addition */
|
||||
'E', __efgfmt,
|
||||
'F', __efgfmt, /* ANSI only */
|
||||
'G', __efgfmt,
|
||||
'L', __flagfmt, /* ANSI only */
|
||||
'S', __runesfmt, /* Plan 9 addition */
|
||||
'X', __ifmt,
|
||||
'b', __ifmt, /* Plan 9 addition */
|
||||
'c', __charfmt,
|
||||
'd', __ifmt,
|
||||
'e', __efgfmt,
|
||||
'f', __efgfmt,
|
||||
'g', __efgfmt,
|
||||
'h', __flagfmt,
|
||||
'i', __ifmt, /* ANSI only */
|
||||
'l', __flagfmt,
|
||||
'n', __countfmt,
|
||||
'o', __ifmt,
|
||||
'p', __ifmt,
|
||||
'r', __errfmt,
|
||||
's', __strfmt,
|
||||
'u', __flagfmt, /* in Unix, __ifmt */
|
||||
'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, Fmts f)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
121
src/lib9/fmt/fmtdef.h
Normal file
121
src/lib9/fmt/fmtdef.h
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#define uchar _fmtuchar
|
||||
#define ushort _fmtushort
|
||||
#define uint _fmtuint
|
||||
#define ulong _fmtulong
|
||||
#define vlong _fmtvlong
|
||||
#define uvlong _fmtuvlong
|
||||
|
||||
#define USED(x) if(x);else
|
||||
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
#ifndef NOVLONGS
|
||||
typedef unsigned long long uvlong;
|
||||
typedef long long vlong;
|
||||
#endif
|
||||
|
||||
#define nil 0 /* cannot be ((void*)0) because used for function pointers */
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
void *__fmtflush(Fmt*, void*, int);
|
||||
void *__fmtdispatch(Fmt*, void*, int);
|
||||
int __floatfmt(Fmt*, double);
|
||||
int __fmtpad(Fmt*, int);
|
||||
int __rfmtpad(Fmt*, int);
|
||||
int __fmtFdFlush(Fmt*);
|
||||
|
||||
int __efgfmt(Fmt*);
|
||||
int __charfmt(Fmt*);
|
||||
int __runefmt(Fmt*);
|
||||
int __runesfmt(Fmt*);
|
||||
int __countfmt(Fmt*);
|
||||
int __flagfmt(Fmt*);
|
||||
int __percentfmt(Fmt*);
|
||||
int __ifmt(Fmt*);
|
||||
int __strfmt(Fmt*);
|
||||
int __badfmt(Fmt*);
|
||||
int __fmtcpy(Fmt*, const void*, int, int);
|
||||
int __fmtrcpy(Fmt*, const void*, int n);
|
||||
int __errfmt(Fmt *f);
|
||||
|
||||
double __fmtpow10(int);
|
||||
|
||||
void __fmtlock(void);
|
||||
void __fmtunlock(void);
|
||||
|
||||
#define FMTCHAR(f, t, s, c)\
|
||||
do{\
|
||||
if(t + 1 > (char*)s){\
|
||||
t = __fmtflush(f, t, 1);\
|
||||
if(t != nil)\
|
||||
s = f->stop;\
|
||||
else\
|
||||
return -1;\
|
||||
}\
|
||||
*t++ = c;\
|
||||
}while(0)
|
||||
|
||||
#define FMTRCHAR(f, t, s, c)\
|
||||
do{\
|
||||
if(t + 1 > (Rune*)s){\
|
||||
t = __fmtflush(f, t, sizeof(Rune));\
|
||||
if(t != nil)\
|
||||
s = 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 = __fmtflush(f, t, _runelen);\
|
||||
if(t != nil)\
|
||||
s = f->stop;\
|
||||
else\
|
||||
return -1;\
|
||||
}\
|
||||
if(r < Runeself)\
|
||||
*t++ = r;\
|
||||
else{\
|
||||
_rune = r;\
|
||||
t += runetochar(t, &_rune);\
|
||||
}\
|
||||
}while(0)
|
||||
46
src/lib9/fmt/fmtfd.c
Normal file
46
src/lib9/fmt/fmtfd.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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*)fd;
|
||||
f->nfmt = 0;
|
||||
return 0;
|
||||
}
|
||||
33
src/lib9/fmt/fmtfdflush.c
Normal file
33
src/lib9/fmt/fmtfdflush.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 <unistd.h>
|
||||
#include "fmt.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((int)f->farg, f->start, n) != n)
|
||||
return 0;
|
||||
f->to = f->start;
|
||||
return 1;
|
||||
}
|
||||
28
src/lib9/fmt/fmtlock.c
Normal file
28
src/lib9/fmt/fmtlock.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
void
|
||||
__fmtlock(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
__fmtunlock(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
47
src/lib9/fmt/fmtprint.c
Normal file
47
src/lib9/fmt/fmtprint.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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 = f->args;
|
||||
va_start(f->args, fmt);
|
||||
n = dofmt(f, fmt);
|
||||
va_end(f->args);
|
||||
f->flags = 0;
|
||||
f->width = 0;
|
||||
f->prec = 0;
|
||||
f->args = va;
|
||||
if(n >= 0)
|
||||
return 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
262
src/lib9/fmt/fmtquote.c
Normal file
262
src/lib9/fmt/fmtquote.c
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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-=w){
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
w = f->width;
|
||||
fl = f->flags;
|
||||
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 outlen;
|
||||
Rune *r;
|
||||
char *s;
|
||||
Quoteinfo q;
|
||||
|
||||
f->flags &= ~FmtPrec; /* ignored for %q %Q, so disable for %s %S in easy case */
|
||||
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, -1, 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;
|
||||
}
|
||||
40
src/lib9/fmt/fmtrune.c
Normal file
40
src/lib9/fmt/fmtrune.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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;
|
||||
}
|
||||
65
src/lib9/fmt/fmtstr.c
Normal file
65
src/lib9/fmt/fmtstr.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
static int
|
||||
fmtStrFlush(Fmt *f)
|
||||
{
|
||||
char *s;
|
||||
int n;
|
||||
|
||||
n = (int)f->farg;
|
||||
n += 256;
|
||||
f->farg = (void*)n;
|
||||
s = (char*)f->start;
|
||||
f->start = realloc(s, n);
|
||||
if(f->start == nil){
|
||||
f->start = s;
|
||||
return 0;
|
||||
}
|
||||
f->to = (char*)f->start + ((char*)f->to - s);
|
||||
f->stop = (char*)f->start + n - 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
fmtstrinit(Fmt *f)
|
||||
{
|
||||
int n;
|
||||
|
||||
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*)n;
|
||||
f->nfmt = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char*
|
||||
fmtstrflush(Fmt *f)
|
||||
{
|
||||
*(char*)f->to = '\0';
|
||||
f->to = f->start;
|
||||
return (char*)f->start;
|
||||
}
|
||||
46
src/lib9/fmt/fmtvprint.c
Normal file
46
src/lib9/fmt/fmtvprint.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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 = f->args;
|
||||
f->args = args;
|
||||
n = dofmt(f, fmt);
|
||||
f->flags = 0;
|
||||
f->width = 0;
|
||||
f->prec = 0;
|
||||
f->args = va;
|
||||
if(n >= 0)
|
||||
return 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
28
src/lib9/fmt/fprint.c
Normal file
28
src/lib9/fmt/fprint.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "fmt.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;
|
||||
}
|
||||
57
src/lib9/fmt/mkfile
Normal file
57
src/lib9/fmt/mkfile
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
PLAN9=../..
|
||||
<$PLAN9/src/mkhdr
|
||||
|
||||
LIB=libfmt.a
|
||||
|
||||
NUM=\
|
||||
charstod.$O\
|
||||
pow10.$O\
|
||||
|
||||
# Could add errfmt, but we want to pick it up from lib9 instead.
|
||||
OFILES=\
|
||||
dofmt.$O\
|
||||
errfmt.$O\
|
||||
fltfmt.$O\
|
||||
fmt.$O\
|
||||
fmtfd.$O\
|
||||
fmtfdflush.$O\
|
||||
fmtlock.$O\
|
||||
fmtprint.$O\
|
||||
fmtquote.$O\
|
||||
fmtrune.$O\
|
||||
fmtstr.$O\
|
||||
fmtvprint.$O\
|
||||
fprint.$O\
|
||||
nan64.$O\
|
||||
print.$O\
|
||||
runefmtstr.$O\
|
||||
runeseprint.$O\
|
||||
runesmprint.$O\
|
||||
runesnprint.$O\
|
||||
runesprint.$O\
|
||||
runevseprint.$O\
|
||||
runevsmprint.$O\
|
||||
runevsnprint.$O\
|
||||
seprint.$O\
|
||||
smprint.$O\
|
||||
snprint.$O\
|
||||
sprint.$O\
|
||||
strtod.$O\
|
||||
vfprint.$O\
|
||||
vseprint.$O\
|
||||
vsmprint.$O\
|
||||
vsnprint.$O\
|
||||
$NUM\
|
||||
|
||||
HFILES=\
|
||||
fmtdef.h\
|
||||
$PLAN9/include/fmt.h\
|
||||
|
||||
<$PLAN9/src/mksyslib
|
||||
|
||||
$NAN.$O: nan.h
|
||||
strtod.$O: nan.h
|
||||
|
||||
test: $LIB test.$O
|
||||
$CC -o test test.$O $LIB -L$PLAN9/lib -lutf
|
||||
|
||||
4
src/lib9/fmt/nan.h
Normal file
4
src/lib9/fmt/nan.h
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
extern double __NaN(void);
|
||||
extern double __Inf(int);
|
||||
extern int __isNaN(double);
|
||||
extern int __isInf(double, int);
|
||||
76
src/lib9/fmt/nan64.c
Normal file
76
src/lib9/fmt/nan64.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 "nan.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define _NEEDLL
|
||||
#endif
|
||||
|
||||
typedef unsigned long long uvlong;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
#ifdef _NEEDLL
|
||||
static uvlong uvnan = 0x7FF0000000000001LL;
|
||||
static uvlong uvinf = 0x7FF0000000000000LL;
|
||||
static uvlong uvneginf = 0xFFF0000000000000LL;
|
||||
#else
|
||||
static uvlong uvnan = 0x7FF0000000000001;
|
||||
static uvlong uvinf = 0x7FF0000000000000;
|
||||
static uvlong uvneginf = 0xFFF0000000000000;
|
||||
#endif
|
||||
|
||||
double
|
||||
__NaN(void)
|
||||
{
|
||||
uvlong *p;
|
||||
|
||||
/* gcc complains about "return *(double*)&uvnan;" */
|
||||
p = &uvnan;
|
||||
return *(double*)p;
|
||||
}
|
||||
|
||||
int
|
||||
__isNaN(double d)
|
||||
{
|
||||
uvlong x;
|
||||
double *p;
|
||||
|
||||
p = &d;
|
||||
x = *(uvlong*)p;
|
||||
return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
|
||||
}
|
||||
|
||||
double
|
||||
__Inf(int sign)
|
||||
{
|
||||
uvlong *p;
|
||||
|
||||
if(sign < 0)
|
||||
p = &uvinf;
|
||||
else
|
||||
p = &uvneginf;
|
||||
return *(double*)p;
|
||||
}
|
||||
|
||||
int
|
||||
__isInf(double d, int sign)
|
||||
{
|
||||
uvlong x;
|
||||
double *p;
|
||||
|
||||
p = &d;
|
||||
x = *(uvlong*)p;
|
||||
if(sign == 0)
|
||||
return x==uvinf || x==uvneginf;
|
||||
else if(sign > 0)
|
||||
return x==uvinf;
|
||||
else
|
||||
return x==uvneginf;
|
||||
}
|
||||
|
||||
|
||||
57
src/lib9/fmt/pow10.c
Normal file
57
src/lib9/fmt/pow10.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.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);
|
||||
}
|
||||
28
src/lib9/fmt/print.c
Normal file
28
src/lib9/fmt/print.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "fmt.h"
|
||||
|
||||
int
|
||||
print(char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
n = vfprint(1, fmt, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
65
src/lib9/fmt/runefmtstr.c
Normal file
65
src/lib9/fmt/runefmtstr.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
static int
|
||||
runeFmtStrFlush(Fmt *f)
|
||||
{
|
||||
Rune *s;
|
||||
int n;
|
||||
|
||||
n = (int)f->farg;
|
||||
n += 256;
|
||||
f->farg = (void*)n;
|
||||
s = (Rune*)f->start;
|
||||
f->start = realloc(s, sizeof(Rune)*n);
|
||||
if(f->start == nil){
|
||||
f->start = s;
|
||||
return 0;
|
||||
}
|
||||
f->to = (Rune*)f->start + ((Rune*)f->to - s);
|
||||
f->stop = (Rune*)f->start + n - 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
runefmtstrinit(Fmt *f)
|
||||
{
|
||||
int n;
|
||||
|
||||
f->runes = 1;
|
||||
n = 32;
|
||||
f->start = malloc(sizeof(Rune)*n);
|
||||
if(f->start == nil)
|
||||
return -1;
|
||||
f->to = f->start;
|
||||
f->stop = (Rune*)f->start + n - 1;
|
||||
f->flush = runeFmtStrFlush;
|
||||
f->farg = (void*)n;
|
||||
f->nfmt = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Rune*
|
||||
runefmtstrflush(Fmt *f)
|
||||
{
|
||||
*(Rune*)f->to = '\0';
|
||||
f->to = f->start;
|
||||
return f->start;
|
||||
}
|
||||
30
src/lib9/fmt/runeseprint.c
Normal file
30
src/lib9/fmt/runeseprint.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
Rune*
|
||||
runeseprint(Rune *buf, Rune *e, char *fmt, ...)
|
||||
{
|
||||
Rune *p;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
p = runevseprint(buf, e, fmt, args);
|
||||
va_end(args);
|
||||
return p;
|
||||
}
|
||||
30
src/lib9/fmt/runesmprint.c
Normal file
30
src/lib9/fmt/runesmprint.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
Rune*
|
||||
runesmprint(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
Rune *p;
|
||||
|
||||
va_start(args, fmt);
|
||||
p = runevsmprint(fmt, args);
|
||||
va_end(args);
|
||||
return p;
|
||||
}
|
||||
31
src/lib9/fmt/runesnprint.c
Normal file
31
src/lib9/fmt/runesnprint.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
runesnprint(Rune *buf, int len, char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
n = runevsnprint(buf, len, fmt, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
|
||||
30
src/lib9/fmt/runesprint.c
Normal file
30
src/lib9/fmt/runesprint.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
runesprint(Rune *buf, char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
n = runevsnprint(buf, 256, fmt, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
39
src/lib9/fmt/runevseprint.c
Normal file
39
src/lib9/fmt/runevseprint.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
Rune*
|
||||
runevseprint(Rune *buf, Rune *e, char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
|
||||
if(e <= buf)
|
||||
return nil;
|
||||
f.runes = 1;
|
||||
f.start = buf;
|
||||
f.to = buf;
|
||||
f.stop = e - 1;
|
||||
f.flush = nil;
|
||||
f.farg = nil;
|
||||
f.nfmt = 0;
|
||||
f.args = args;
|
||||
dofmt(&f, fmt);
|
||||
*(Rune*)f.to = '\0';
|
||||
return (Rune*)f.to;
|
||||
}
|
||||
|
||||
37
src/lib9/fmt/runevsmprint.c
Normal file
37
src/lib9/fmt/runevsmprint.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* print into an allocated string buffer
|
||||
*/
|
||||
Rune*
|
||||
runevsmprint(char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
int n;
|
||||
|
||||
if(runefmtstrinit(&f) < 0)
|
||||
return nil;
|
||||
f.args = args;
|
||||
n = dofmt(&f, fmt);
|
||||
if(n < 0)
|
||||
return nil;
|
||||
*(Rune*)f.to = '\0';
|
||||
return (Rune*)f.start;
|
||||
}
|
||||
38
src/lib9/fmt/runevsnprint.c
Normal file
38
src/lib9/fmt/runevsnprint.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
int
|
||||
runevsnprint(Rune *buf, int len, char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
|
||||
if(len <= 0)
|
||||
return -1;
|
||||
f.runes = 1;
|
||||
f.start = buf;
|
||||
f.to = buf;
|
||||
f.stop = buf + len - 1;
|
||||
f.flush = nil;
|
||||
f.farg = nil;
|
||||
f.nfmt = 0;
|
||||
f.args = args;
|
||||
dofmt(&f, fmt);
|
||||
*(Rune*)f.to = '\0';
|
||||
return (Rune*)f.to - buf;
|
||||
}
|
||||
27
src/lib9/fmt/seprint.c
Normal file
27
src/lib9/fmt/seprint.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 "fmt.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;
|
||||
}
|
||||
27
src/lib9/fmt/smprint.c
Normal file
27
src/lib9/fmt/smprint.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 "fmt.h"
|
||||
|
||||
char*
|
||||
smprint(char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *p;
|
||||
|
||||
va_start(args, fmt);
|
||||
p = vsmprint(fmt, args);
|
||||
va_end(args);
|
||||
return p;
|
||||
}
|
||||
28
src/lib9/fmt/snprint.c
Normal file
28
src/lib9/fmt/snprint.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 "fmt.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;
|
||||
}
|
||||
|
||||
27
src/lib9/fmt/sprint.c
Normal file
27
src/lib9/fmt/sprint.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 "fmt.h"
|
||||
|
||||
int
|
||||
sprint(char *buf, char *fmt, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
n = vsnprint(buf, 65536, fmt, args); /* big number, but sprint is deprecated anyway */
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
539
src/lib9/fmt/strtod.c
Normal file
539
src/lib9/fmt/strtod.c
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "fmt.h"
|
||||
#include "nan.h"
|
||||
|
||||
#ifndef nelem
|
||||
#define nelem(x) (sizeof(x)/sizeof *(x))
|
||||
#endif
|
||||
#define nil ((void*)0)
|
||||
#define ulong _fmtulong
|
||||
typedef unsigned long ulong;
|
||||
|
||||
static ulong
|
||||
umuldiv(ulong a, ulong b, ulong c)
|
||||
{
|
||||
double d;
|
||||
|
||||
d = ((double)a * (double)b) / (double)c;
|
||||
if(d >= 4294967295.)
|
||||
d = 4294967295.;
|
||||
return (ulong)d;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will convert to arbitrary precision
|
||||
* floating point entirely in multi-precision fixed.
|
||||
* The answer is the closest floating point number to
|
||||
* the given decimal number. Exactly half way are
|
||||
* rounded ala ieee rules.
|
||||
* Method is to scale input decimal between .500 and .999...
|
||||
* with external power of 2, then binary search for the
|
||||
* closest mantissa to this decimal number.
|
||||
* Nmant is is the required precision. (53 for ieee dp)
|
||||
* Nbits is the max number of bits/word. (must be <= 28)
|
||||
* Prec is calculated - the number of words of fixed mantissa.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
Nbits = 28, /* bits safely represented in a ulong */
|
||||
Nmant = 53, /* bits of precision required */
|
||||
Prec = (Nmant+Nbits+1)/Nbits, /* words of Nbits each to represent mantissa */
|
||||
Sigbit = 1<<(Prec*Nbits-Nmant), /* first significant bit of Prec-th word */
|
||||
Ndig = 1500,
|
||||
One = (ulong)(1<<Nbits),
|
||||
Half = (ulong)(One>>1),
|
||||
Maxe = 310,
|
||||
|
||||
Fsign = 1<<0, /* found - */
|
||||
Fesign = 1<<1, /* found e- */
|
||||
Fdpoint = 1<<2, /* found . */
|
||||
|
||||
S0 = 0, /* _ _S0 +S1 #S2 .S3 */
|
||||
S1, /* _+ #S2 .S3 */
|
||||
S2, /* _+# #S2 .S4 eS5 */
|
||||
S3, /* _+. #S4 */
|
||||
S4, /* _+#.# #S4 eS5 */
|
||||
S5, /* _+#.#e +S6 #S7 */
|
||||
S6, /* _+#.#e+ #S7 */
|
||||
S7, /* _+#.#e+# #S7 */
|
||||
};
|
||||
|
||||
static int xcmp(char*, char*);
|
||||
static int fpcmp(char*, ulong*);
|
||||
static void frnorm(ulong*);
|
||||
static void divascii(char*, int*, int*, int*);
|
||||
static void mulascii(char*, int*, int*, int*);
|
||||
|
||||
typedef struct Tab Tab;
|
||||
struct Tab
|
||||
{
|
||||
int bp;
|
||||
int siz;
|
||||
char* cmp;
|
||||
};
|
||||
|
||||
double
|
||||
fmtstrtod(const char *as, char **aas)
|
||||
{
|
||||
int na, ex, dp, bp, c, i, flag, state;
|
||||
ulong low[Prec], hig[Prec], mid[Prec];
|
||||
double d;
|
||||
char *s, a[Ndig];
|
||||
|
||||
flag = 0; /* Fsign, Fesign, Fdpoint */
|
||||
na = 0; /* number of digits of a[] */
|
||||
dp = 0; /* na of decimal point */
|
||||
ex = 0; /* exonent */
|
||||
|
||||
state = S0;
|
||||
for(s=(char*)as;; s++) {
|
||||
c = *s;
|
||||
if(c >= '0' && c <= '9') {
|
||||
switch(state) {
|
||||
case S0:
|
||||
case S1:
|
||||
case S2:
|
||||
state = S2;
|
||||
break;
|
||||
case S3:
|
||||
case S4:
|
||||
state = S4;
|
||||
break;
|
||||
|
||||
case S5:
|
||||
case S6:
|
||||
case S7:
|
||||
state = S7;
|
||||
ex = ex*10 + (c-'0');
|
||||
continue;
|
||||
}
|
||||
if(na == 0 && c == '0') {
|
||||
dp--;
|
||||
continue;
|
||||
}
|
||||
if(na < Ndig-50)
|
||||
a[na++] = c;
|
||||
continue;
|
||||
}
|
||||
switch(c) {
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\v':
|
||||
case '\f':
|
||||
case '\r':
|
||||
case ' ':
|
||||
if(state == S0)
|
||||
continue;
|
||||
break;
|
||||
case '-':
|
||||
if(state == S0)
|
||||
flag |= Fsign;
|
||||
else
|
||||
flag |= Fesign;
|
||||
case '+':
|
||||
if(state == S0)
|
||||
state = S1;
|
||||
else
|
||||
if(state == S5)
|
||||
state = S6;
|
||||
else
|
||||
break; /* syntax */
|
||||
continue;
|
||||
case '.':
|
||||
flag |= Fdpoint;
|
||||
dp = na;
|
||||
if(state == S0 || state == S1) {
|
||||
state = S3;
|
||||
continue;
|
||||
}
|
||||
if(state == S2) {
|
||||
state = S4;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
if(state == S2 || state == S4) {
|
||||
state = S5;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* clean up return char-pointer
|
||||
*/
|
||||
switch(state) {
|
||||
case S0:
|
||||
if(xcmp(s, "nan") == 0) {
|
||||
if(aas != nil)
|
||||
*aas = s+3;
|
||||
goto retnan;
|
||||
}
|
||||
case S1:
|
||||
if(xcmp(s, "infinity") == 0) {
|
||||
if(aas != nil)
|
||||
*aas = s+8;
|
||||
goto retinf;
|
||||
}
|
||||
if(xcmp(s, "inf") == 0) {
|
||||
if(aas != nil)
|
||||
*aas = s+3;
|
||||
goto retinf;
|
||||
}
|
||||
case S3:
|
||||
if(aas != nil)
|
||||
*aas = (char*)as;
|
||||
goto ret0; /* no digits found */
|
||||
case S6:
|
||||
s--; /* back over +- */
|
||||
case S5:
|
||||
s--; /* back over e */
|
||||
break;
|
||||
}
|
||||
if(aas != nil)
|
||||
*aas = s;
|
||||
|
||||
if(flag & Fdpoint)
|
||||
while(na > 0 && a[na-1] == '0')
|
||||
na--;
|
||||
if(na == 0)
|
||||
goto ret0; /* zero */
|
||||
a[na] = 0;
|
||||
if(!(flag & Fdpoint))
|
||||
dp = na;
|
||||
if(flag & Fesign)
|
||||
ex = -ex;
|
||||
dp += ex;
|
||||
if(dp < -Maxe){
|
||||
errno = ERANGE;
|
||||
goto ret0; /* underflow by exp */
|
||||
} else
|
||||
if(dp > +Maxe)
|
||||
goto retinf; /* overflow by exp */
|
||||
|
||||
/*
|
||||
* normalize the decimal ascii number
|
||||
* to range .[5-9][0-9]* e0
|
||||
*/
|
||||
bp = 0; /* binary exponent */
|
||||
while(dp > 0)
|
||||
divascii(a, &na, &dp, &bp);
|
||||
while(dp < 0 || a[0] < '5')
|
||||
mulascii(a, &na, &dp, &bp);
|
||||
|
||||
/* close approx by naive conversion */
|
||||
mid[0] = 0;
|
||||
mid[1] = 1;
|
||||
for(i=0; c=a[i]; i++) {
|
||||
mid[0] = mid[0]*10 + (c-'0');
|
||||
mid[1] = mid[1]*10;
|
||||
if(i >= 8)
|
||||
break;
|
||||
}
|
||||
low[0] = umuldiv(mid[0], One, mid[1]);
|
||||
hig[0] = umuldiv(mid[0]+1, One, mid[1]);
|
||||
for(i=1; i<Prec; i++) {
|
||||
low[i] = 0;
|
||||
hig[i] = One-1;
|
||||
}
|
||||
|
||||
/* binary search for closest mantissa */
|
||||
for(;;) {
|
||||
/* mid = (hig + low) / 2 */
|
||||
c = 0;
|
||||
for(i=0; i<Prec; i++) {
|
||||
mid[i] = hig[i] + low[i];
|
||||
if(c)
|
||||
mid[i] += One;
|
||||
c = mid[i] & 1;
|
||||
mid[i] >>= 1;
|
||||
}
|
||||
frnorm(mid);
|
||||
|
||||
/* compare */
|
||||
c = fpcmp(a, mid);
|
||||
if(c > 0) {
|
||||
c = 1;
|
||||
for(i=0; i<Prec; i++)
|
||||
if(low[i] != mid[i]) {
|
||||
c = 0;
|
||||
low[i] = mid[i];
|
||||
}
|
||||
if(c)
|
||||
break; /* between mid and hig */
|
||||
continue;
|
||||
}
|
||||
if(c < 0) {
|
||||
for(i=0; i<Prec; i++)
|
||||
hig[i] = mid[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only hard part is if even/odd roundings wants to go up */
|
||||
c = mid[Prec-1] & (Sigbit-1);
|
||||
if(c == Sigbit/2 && (mid[Prec-1]&Sigbit) == 0)
|
||||
mid[Prec-1] -= c;
|
||||
break; /* exactly mid */
|
||||
}
|
||||
|
||||
/* normal rounding applies */
|
||||
c = mid[Prec-1] & (Sigbit-1);
|
||||
mid[Prec-1] -= c;
|
||||
if(c >= Sigbit/2) {
|
||||
mid[Prec-1] += Sigbit;
|
||||
frnorm(mid);
|
||||
}
|
||||
goto out;
|
||||
|
||||
ret0:
|
||||
return 0;
|
||||
|
||||
retnan:
|
||||
return __NaN();
|
||||
|
||||
retinf:
|
||||
/*
|
||||
* Unix strtod requires these. Plan 9 would return Inf(0) or Inf(-1). */
|
||||
errno = ERANGE;
|
||||
if(flag & Fsign)
|
||||
return -HUGE_VAL;
|
||||
return HUGE_VAL;
|
||||
|
||||
out:
|
||||
d = 0;
|
||||
for(i=0; i<Prec; i++)
|
||||
d = d*One + mid[i];
|
||||
if(flag & Fsign)
|
||||
d = -d;
|
||||
d = ldexp(d, bp - Prec*Nbits);
|
||||
if(d == 0){ /* underflow */
|
||||
errno = ERANGE;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
static void
|
||||
frnorm(ulong *f)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
c = 0;
|
||||
for(i=Prec-1; i>0; i--) {
|
||||
f[i] += c;
|
||||
c = f[i] >> Nbits;
|
||||
f[i] &= One-1;
|
||||
}
|
||||
f[0] += c;
|
||||
}
|
||||
|
||||
static int
|
||||
fpcmp(char *a, ulong* f)
|
||||
{
|
||||
ulong tf[Prec];
|
||||
int i, d, c;
|
||||
|
||||
for(i=0; i<Prec; i++)
|
||||
tf[i] = f[i];
|
||||
|
||||
for(;;) {
|
||||
/* tf *= 10 */
|
||||
for(i=0; i<Prec; i++)
|
||||
tf[i] = tf[i]*10;
|
||||
frnorm(tf);
|
||||
d = (tf[0] >> Nbits) + '0';
|
||||
tf[0] &= One-1;
|
||||
|
||||
/* compare next digit */
|
||||
c = *a;
|
||||
if(c == 0) {
|
||||
if('0' < d)
|
||||
return -1;
|
||||
if(tf[0] != 0)
|
||||
goto cont;
|
||||
for(i=1; i<Prec; i++)
|
||||
if(tf[i] != 0)
|
||||
goto cont;
|
||||
return 0;
|
||||
}
|
||||
if(c > d)
|
||||
return +1;
|
||||
if(c < d)
|
||||
return -1;
|
||||
a++;
|
||||
cont:;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
divby(char *a, int *na, int b)
|
||||
{
|
||||
int n, c;
|
||||
char *p;
|
||||
|
||||
p = a;
|
||||
n = 0;
|
||||
while(n>>b == 0) {
|
||||
c = *a++;
|
||||
if(c == 0) {
|
||||
while(n) {
|
||||
c = n*10;
|
||||
if(c>>b)
|
||||
break;
|
||||
n = c;
|
||||
}
|
||||
goto xx;
|
||||
}
|
||||
n = n*10 + c-'0';
|
||||
(*na)--;
|
||||
}
|
||||
for(;;) {
|
||||
c = n>>b;
|
||||
n -= c<<b;
|
||||
*p++ = c + '0';
|
||||
c = *a++;
|
||||
if(c == 0)
|
||||
break;
|
||||
n = n*10 + c-'0';
|
||||
}
|
||||
(*na)++;
|
||||
xx:
|
||||
while(n) {
|
||||
n = n*10;
|
||||
c = n>>b;
|
||||
n -= c<<b;
|
||||
*p++ = c + '0';
|
||||
(*na)++;
|
||||
}
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
static Tab tab1[] =
|
||||
{
|
||||
1, 0, "",
|
||||
3, 1, "7",
|
||||
6, 2, "63",
|
||||
9, 3, "511",
|
||||
13, 4, "8191",
|
||||
16, 5, "65535",
|
||||
19, 6, "524287",
|
||||
23, 7, "8388607",
|
||||
26, 8, "67108863",
|
||||
27, 9, "134217727",
|
||||
};
|
||||
|
||||
static void
|
||||
divascii(char *a, int *na, int *dp, int *bp)
|
||||
{
|
||||
int b, d;
|
||||
Tab *t;
|
||||
|
||||
d = *dp;
|
||||
if(d >= (int)(nelem(tab1)))
|
||||
d = (int)(nelem(tab1))-1;
|
||||
t = tab1 + d;
|
||||
b = t->bp;
|
||||
if(memcmp(a, t->cmp, t->siz) > 0)
|
||||
d--;
|
||||
*dp -= d;
|
||||
*bp += b;
|
||||
divby(a, na, b);
|
||||
}
|
||||
|
||||
static void
|
||||
mulby(char *a, char *p, char *q, int b)
|
||||
{
|
||||
int n, c;
|
||||
|
||||
n = 0;
|
||||
*p = 0;
|
||||
for(;;) {
|
||||
q--;
|
||||
if(q < a)
|
||||
break;
|
||||
c = *q - '0';
|
||||
c = (c<<b) + n;
|
||||
n = c/10;
|
||||
c -= n*10;
|
||||
p--;
|
||||
*p = c + '0';
|
||||
}
|
||||
while(n) {
|
||||
c = n;
|
||||
n = c/10;
|
||||
c -= n*10;
|
||||
p--;
|
||||
*p = c + '0';
|
||||
}
|
||||
}
|
||||
|
||||
static Tab tab2[] =
|
||||
{
|
||||
1, 1, "", /* dp = 0-0 */
|
||||
3, 3, "125",
|
||||
6, 5, "15625",
|
||||
9, 7, "1953125",
|
||||
13, 10, "1220703125",
|
||||
16, 12, "152587890625",
|
||||
19, 14, "19073486328125",
|
||||
23, 17, "11920928955078125",
|
||||
26, 19, "1490116119384765625",
|
||||
27, 19, "7450580596923828125", /* dp 8-9 */
|
||||
};
|
||||
|
||||
static void
|
||||
mulascii(char *a, int *na, int *dp, int *bp)
|
||||
{
|
||||
char *p;
|
||||
int d, b;
|
||||
Tab *t;
|
||||
|
||||
d = -*dp;
|
||||
if(d >= (int)(nelem(tab2)))
|
||||
d = (int)(nelem(tab2))-1;
|
||||
t = tab2 + d;
|
||||
b = t->bp;
|
||||
if(memcmp(a, t->cmp, t->siz) < 0)
|
||||
d--;
|
||||
p = a + *na;
|
||||
*bp -= b;
|
||||
*dp += d;
|
||||
*na += d;
|
||||
mulby(a, p+d, p, b);
|
||||
}
|
||||
|
||||
static int
|
||||
xcmp(char *a, char *b)
|
||||
{
|
||||
int c1, c2;
|
||||
|
||||
while(c1 = *b++) {
|
||||
c2 = *a++;
|
||||
if(isupper(c2))
|
||||
c2 = tolower(c2);
|
||||
if(c1 != c2)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
4
src/lib9/fmt/strtod.h
Normal file
4
src/lib9/fmt/strtod.h
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
extern double __NaN(void);
|
||||
extern double __Inf(int);
|
||||
extern double __isNaN(double);
|
||||
extern double __isInf(double, int);
|
||||
39
src/lib9/fmt/test.c
Normal file
39
src/lib9/fmt/test.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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>
|
||||
#include "fmt.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 %.18\n", 2e25, 2e25);
|
||||
print("%2.18g\n", 1.0);
|
||||
print("%f\n", 3.1415927/4);
|
||||
print("%d\n", 23);
|
||||
print("%i\n", 23);
|
||||
return 0;
|
||||
}
|
||||
31
src/lib9/fmt/vfprint.c
Normal file
31
src/lib9/fmt/vfprint.c
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 "fmt.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));
|
||||
f.args = args;
|
||||
n = dofmt(&f, fmt);
|
||||
if(n > 0 && __fmtFdFlush(&f) == 0)
|
||||
return -1;
|
||||
return n;
|
||||
}
|
||||
37
src/lib9/fmt/vseprint.c
Normal file
37
src/lib9/fmt/vseprint.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include "fmt.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;
|
||||
f.args = args;
|
||||
dofmt(&f, fmt);
|
||||
*(char*)f.to = '\0';
|
||||
return (char*)f.to;
|
||||
}
|
||||
|
||||
36
src/lib9/fmt/vsmprint.c
Normal file
36
src/lib9/fmt/vsmprint.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "fmt.h"
|
||||
#include "fmtdef.h"
|
||||
|
||||
/*
|
||||
* print into an allocated string buffer
|
||||
*/
|
||||
char*
|
||||
vsmprint(char *fmt, va_list args)
|
||||
{
|
||||
Fmt f;
|
||||
int n;
|
||||
|
||||
if(fmtstrinit(&f) < 0)
|
||||
return nil;
|
||||
f.args = args;
|
||||
n = dofmt(&f, fmt);
|
||||
if(n < 0)
|
||||
return nil;
|
||||
*(char*)f.to = '\0';
|
||||
return (char*)f.start;
|
||||
}
|
||||
37
src/lib9/fmt/vsnprint.c
Normal file
37
src/lib9/fmt/vsnprint.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "fmt.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;
|
||||
f.args = args;
|
||||
dofmt(&f, fmt);
|
||||
*(char*)f.to = '\0';
|
||||
return (char*)f.to - buf;
|
||||
}
|
||||
13
src/lib9/utf/LICENSE
Normal file
13
src/lib9/utf/LICENSE
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
13
src/lib9/utf/NOTICE
Normal file
13
src/lib9/utf/NOTICE
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
13
src/lib9/utf/README
Normal file
13
src/lib9/utf/README
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
17
src/lib9/utf/lib9.h
Normal file
17
src/lib9/utf/lib9.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include <string.h>
|
||||
#include "utf.h"
|
||||
|
||||
#define nil ((void*)0)
|
||||
|
||||
#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;
|
||||
|
||||
31
src/lib9/utf/mkfile
Normal file
31
src/lib9/utf/mkfile
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
PLAN9=../..
|
||||
<$PLAN9/src/mkhdr
|
||||
|
||||
LIB=libutf.a
|
||||
|
||||
OFILES=\
|
||||
rune.$O\
|
||||
runestrcat.$O\
|
||||
runestrchr.$O\
|
||||
runestrcmp.$O\
|
||||
runestrcpy.$O\
|
||||
runestrdup.$O\
|
||||
runestrlen.$O\
|
||||
runestrecpy.$O\
|
||||
runestrncat.$O\
|
||||
runestrncmp.$O\
|
||||
runestrncpy.$O\
|
||||
runestrrchr.$O\
|
||||
runestrstr.$O\
|
||||
runetype.$O\
|
||||
utfecpy.$O\
|
||||
utflen.$O\
|
||||
utfnlen.$O\
|
||||
utfrrune.$O\
|
||||
utfrune.$O\
|
||||
utfutf.$O\
|
||||
|
||||
HFILES=\
|
||||
$PLAN9/include/utf.h\
|
||||
|
||||
<$PLAN9/src/mksyslib
|
||||
177
src/lib9/utf/rune.c
Normal file
177
src/lib9/utf/rune.c
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "utf.h"
|
||||
#include "utfdef.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;
|
||||
}
|
||||
25
src/lib9/utf/runestrcat.c
Normal file
25
src/lib9/utf/runestrcat.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
Rune*
|
||||
runestrcat(Rune *s1, Rune *s2)
|
||||
{
|
||||
|
||||
runestrcpy(runestrchr(s1, 0), s2);
|
||||
return s1;
|
||||
}
|
||||
35
src/lib9/utf/runestrchr.c
Normal file
35
src/lib9/utf/runestrchr.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
Rune*
|
||||
runestrchr(Rune *s, Rune c)
|
||||
{
|
||||
Rune c0 = c;
|
||||
Rune c1;
|
||||
|
||||
if(c == 0) {
|
||||
while(*s++)
|
||||
;
|
||||
return s-1;
|
||||
}
|
||||
|
||||
while(c1 = *s++)
|
||||
if(c1 == c0)
|
||||
return s-1;
|
||||
return 0;
|
||||
}
|
||||
35
src/lib9/utf/runestrcmp.c
Normal file
35
src/lib9/utf/runestrcmp.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
int
|
||||
runestrcmp(Rune *s1, Rune *s2)
|
||||
{
|
||||
Rune c1, c2;
|
||||
|
||||
for(;;) {
|
||||
c1 = *s1++;
|
||||
c2 = *s2++;
|
||||
if(c1 != c2) {
|
||||
if(c1 > c2)
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
if(c1 == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
28
src/lib9/utf/runestrcpy.c
Normal file
28
src/lib9/utf/runestrcpy.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
Rune*
|
||||
runestrcpy(Rune *s1, Rune *s2)
|
||||
{
|
||||
Rune *os1;
|
||||
|
||||
os1 = s1;
|
||||
while(*s1++ = *s2++)
|
||||
;
|
||||
return os1;
|
||||
}
|
||||
30
src/lib9/utf/runestrdup.c
Normal file
30
src/lib9/utf/runestrdup.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
Rune*
|
||||
runestrdup(Rune *s)
|
||||
{
|
||||
Rune *ns;
|
||||
|
||||
ns = malloc(sizeof(Rune)*(runestrlen(s) + 1));
|
||||
if(ns == 0)
|
||||
return 0;
|
||||
|
||||
return runestrcpy(ns, s);
|
||||
}
|
||||
32
src/lib9/utf/runestrecpy.c
Normal file
32
src/lib9/utf/runestrecpy.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
Rune*
|
||||
runestrecpy(Rune *s1, Rune *es1, Rune *s2)
|
||||
{
|
||||
if(s1 >= es1)
|
||||
return s1;
|
||||
|
||||
while(*s1++ = *s2++){
|
||||
if(s1 == es1){
|
||||
*--s1 = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return s1;
|
||||
}
|
||||
24
src/lib9/utf/runestrlen.c
Normal file
24
src/lib9/utf/runestrlen.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
long
|
||||
runestrlen(Rune *s)
|
||||
{
|
||||
|
||||
return runestrchr(s, 0) - s;
|
||||
}
|
||||
32
src/lib9/utf/runestrncat.c
Normal file
32
src/lib9/utf/runestrncat.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
Rune*
|
||||
runestrncat(Rune *s1, Rune *s2, long n)
|
||||
{
|
||||
Rune *os1;
|
||||
|
||||
os1 = s1;
|
||||
s1 = runestrchr(s1, 0);
|
||||
while(*s1++ = *s2++)
|
||||
if(--n < 0) {
|
||||
s1[-1] = 0;
|
||||
break;
|
||||
}
|
||||
return os1;
|
||||
}
|
||||
37
src/lib9/utf/runestrncmp.c
Normal file
37
src/lib9/utf/runestrncmp.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
int
|
||||
runestrncmp(Rune *s1, Rune *s2, long n)
|
||||
{
|
||||
Rune c1, c2;
|
||||
|
||||
while(n > 0) {
|
||||
c1 = *s1++;
|
||||
c2 = *s2++;
|
||||
n--;
|
||||
if(c1 != c2) {
|
||||
if(c1 > c2)
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
if(c1 == 0)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
33
src/lib9/utf/runestrncpy.c
Normal file
33
src/lib9/utf/runestrncpy.c
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
Rune*
|
||||
runestrncpy(Rune *s1, Rune *s2, long n)
|
||||
{
|
||||
int i;
|
||||
Rune *os1;
|
||||
|
||||
os1 = s1;
|
||||
for(i = 0; i < n; i++)
|
||||
if((*s1++ = *s2++) == 0) {
|
||||
while(++i < n)
|
||||
*s1++ = 0;
|
||||
return os1;
|
||||
}
|
||||
return os1;
|
||||
}
|
||||
30
src/lib9/utf/runestrrchr.c
Normal file
30
src/lib9/utf/runestrrchr.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
Rune*
|
||||
runestrrchr(Rune *s, Rune c)
|
||||
{
|
||||
Rune *r;
|
||||
|
||||
if(c == 0)
|
||||
return runestrchr(s, 0);
|
||||
r = 0;
|
||||
while(s = runestrchr(s, c))
|
||||
r = s++;
|
||||
return r;
|
||||
}
|
||||
44
src/lib9/utf/runestrstr.c
Normal file
44
src/lib9/utf/runestrstr.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "utf.h"
|
||||
#include "utfdef.h"
|
||||
|
||||
/*
|
||||
* Return pointer to first occurrence of s2 in s1,
|
||||
* 0 if none
|
||||
*/
|
||||
Rune*
|
||||
runestrstr(Rune *s1, Rune *s2)
|
||||
{
|
||||
Rune *p, *pa, *pb;
|
||||
int c0, c;
|
||||
|
||||
c0 = *s2;
|
||||
if(c0 == 0)
|
||||
return s1;
|
||||
s2++;
|
||||
for(p=runestrchr(s1, c0); p; p=runestrchr(p+1, c0)) {
|
||||
pa = p;
|
||||
for(pb=s2;; pb++) {
|
||||
c = *pb;
|
||||
if(c == 0)
|
||||
return p;
|
||||
if(c != *++pa)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
1152
src/lib9/utf/runetype.c
Normal file
1152
src/lib9/utf/runetype.c
Normal file
File diff suppressed because it is too large
Load diff
14
src/lib9/utf/utfdef.h
Normal file
14
src/lib9/utf/utfdef.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#define uchar _utfuchar
|
||||
#define ushort _utfushort
|
||||
#define uint _utfuint
|
||||
#define ulong _utfulong
|
||||
#define vlong _utfvlong
|
||||
#define uvlong _utfuvlong
|
||||
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#define nil ((void*)0)
|
||||
36
src/lib9/utf/utfecpy.c
Normal file
36
src/lib9/utf/utfecpy.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.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;
|
||||
}
|
||||
38
src/lib9/utf/utflen.c
Normal file
38
src/lib9/utf/utflen.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.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++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
41
src/lib9/utf/utfnlen.c
Normal file
41
src/lib9/utf/utfnlen.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "utf.h"
|
||||
#include "utfdef.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;
|
||||
}
|
||||
46
src/lib9/utf/utfrrune.c
Normal file
46
src/lib9/utf/utfrrune.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 "utf.h"
|
||||
#include "utfdef.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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
45
src/lib9/utf/utfrune.c
Normal file
45
src/lib9/utf/utfrune.c
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "utf.h"
|
||||
#include "utfdef.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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
41
src/lib9/utf/utfutf.c
Normal file
41
src/lib9/utf/utfutf.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* The authors of this software are Rob Pike and Ken Thompson.
|
||||
* Copyright (c) 2002 by Lucent Technologies.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose without fee is hereby granted, provided that this entire notice
|
||||
* is included in all copies of any software which is or includes a copy
|
||||
* or modification of this software and in all copies of the supporting
|
||||
* documentation for such software.
|
||||
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
|
||||
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
|
||||
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "utf.h"
|
||||
#include "utfdef.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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue