summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libkern/charstod.c96
-rw-r--r--libkern/cleanname.c17
-rw-r--r--libkern/dofmt.c1
-rw-r--r--libkern/fcallfmt.c16
-rw-r--r--libkern/fmtdef.h17
-rw-r--r--libkern/fmtprint.c6
-rw-r--r--libkern/fmtvprint.c9
-rw-r--r--libkern/pow10.c31
-rw-r--r--libkern/qsort.c3
-rw-r--r--libkern/rune.c195
-rw-r--r--libkern/tokenize.c54
-rw-r--r--libkern/utflen.c3
-rw-r--r--libkern/utfrrune.c3
-rw-r--r--libkern/utfrune.c3
-rw-r--r--libkern/vseprint.c5
-rw-r--r--libkern/vsmprint.c15
-rw-r--r--libkern/vsnprint.c4
17 files changed, 299 insertions, 179 deletions
diff --git a/libkern/charstod.c b/libkern/charstod.c
index 203e5379..10d0b220 100644
--- a/libkern/charstod.c
+++ b/libkern/charstod.c
@@ -1,4 +1,4 @@
-#include <lib9.h>
+#include "lib9.h"
/*
* Reads a floating-point number by interpreting successive characters
@@ -7,62 +7,74 @@
* necessary to back up the input stream up one byte after calling charstod.
*/
+#define ADVANCE *s++ = c; if(s>=e) return NaN(); c = (*f)(vp)
+
double
charstod(int(*f)(void*), void *vp)
{
- double num, dem;
- int neg, eneg, dig, exp, c;
-
- num = 0;
- neg = 0;
- dig = 0;
- exp = 0;
- eneg = 0;
+ char str[400], *s, *e, *start;
+ int c;
+ s = str;
+ e = str + sizeof str - 1;
c = (*f)(vp);
while(c == ' ' || c == '\t')
c = (*f)(vp);
if(c == '-' || c == '+'){
- if(c == '-')
- neg = 1;
- c = (*f)(vp);
+ ADVANCE;
}
+ start = s;
while(c >= '0' && c <= '9'){
- num = num*10 + c-'0';
- c = (*f)(vp);
+ ADVANCE;
}
- if(c == '.')
- c = (*f)(vp);
- while(c >= '0' && c <= '9'){
- num = num*10 + c-'0';
- dig++;
- c = (*f)(vp);
+ if(c == '.'){
+ ADVANCE;
+ while(c >= '0' && c <= '9'){
+ ADVANCE;
+ }
}
- if(c == 'e' || c == 'E'){
- c = (*f)(vp);
+ if(s > start && (c == 'e' || c == 'E')){
+ ADVANCE;
if(c == '-' || c == '+'){
- if(c == '-'){
- dig = -dig;
- eneg = 1;
- }
- c = (*f)(vp);
+ ADVANCE;
}
while(c >= '0' && c <= '9'){
- exp = exp*10 + c-'0';
- c = (*f)(vp);
+ ADVANCE;
}
+ }else if(s == start && (c == 'i' || c == 'I')){
+ ADVANCE;
+ if(c != 'n' && c != 'N')
+ return NaN();
+ ADVANCE;
+ if(c != 'f' && c != 'F')
+ return NaN();
+ ADVANCE;
+ if(c != 'i' && c != 'I')
+ return NaN();
+ ADVANCE;
+ if(c != 'n' && c != 'N')
+ return NaN();
+ ADVANCE;
+ if(c != 'i' && c != 'I')
+ return NaN();
+ ADVANCE;
+ if(c != 't' && c != 'T')
+ return NaN();
+ ADVANCE;
+ if(c != 'y' && c != 'Y')
+ return NaN();
+ ADVANCE; /* so caller can back up uniformly */
+ USED(c);
+ }else if(s == str && (c == 'n' || c == 'N')){
+ ADVANCE;
+ if(c != 'a' && c != 'A')
+ return NaN();
+ ADVANCE;
+ if(c != 'n' && c != 'N')
+ return NaN();
+ ADVANCE; /* so caller can back up uniformly */
+ USED(c);
}
- exp -= dig;
- if(exp < 0){
- exp = -exp;
- eneg = !eneg;
- }
- dem = pow10(exp);
- if(eneg)
- num /= dem;
- else
- num *= dem;
- if(neg)
- return -num;
- return num;
+ *s = 0;
+ return strtod(str, &s);
}
diff --git a/libkern/cleanname.c b/libkern/cleanname.c
index fb8f370a..c9e539a5 100644
--- a/libkern/cleanname.c
+++ b/libkern/cleanname.c
@@ -8,9 +8,10 @@ char*
cleanname(char *name)
{
char *p, *q, *dotdot;
- int rooted;
+ int rooted, erasedprefix;
rooted = name[0] == '/';
+ erasedprefix = 0;
/*
* invariants:
@@ -23,9 +24,11 @@ cleanname(char *name)
while(*p) {
if(p[0] == '/') /* null element */
p++;
- else if(p[0] == '.' && SEP(p[1]))
+ else if(p[0] == '.' && SEP(p[1])) {
+ if(p == name)
+ erasedprefix = 1;
p += 1; /* don't count the separator in case it is nul */
- else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
+ } else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
p += 2;
if(q > dotdot) { /* can backtrack */
while(--q > dotdot && *q != '/')
@@ -37,6 +40,8 @@ cleanname(char *name)
*q++ = '.';
dotdot = q;
}
+ if(q == name)
+ erasedprefix = 1; /* erased entire path via dotdot */
} else { /* real path element */
if(q != name+rooted)
*q++ = '/';
@@ -47,5 +52,11 @@ cleanname(char *name)
if(q == name) /* empty string is really ``.'' */
*q++ = '.';
*q = '\0';
+ if(erasedprefix && name[0] == '#'){
+ /* this was not a #x device path originally - make it not one now */
+ memmove(name+2, name, strlen(name)+1);
+ name[0] = '.';
+ name[1] = '/';
+ }
return name;
}
diff --git a/libkern/dofmt.c b/libkern/dofmt.c
index 0f47c85d..2aedb3a4 100644
--- a/libkern/dofmt.c
+++ b/libkern/dofmt.c
@@ -75,7 +75,6 @@ dofmt(Fmt *f, char *fmt)
if(fmt == nil)
return -1;
}
- return 0; /* not reached */
}
void *
diff --git a/libkern/fcallfmt.c b/libkern/fcallfmt.c
index e8659b2e..e35872ef 100644
--- a/libkern/fcallfmt.c
+++ b/libkern/fcallfmt.c
@@ -1,12 +1,18 @@
/*
- * Copyright © 2001, 2002 Lucent Technologies Inc. All rights reserved.
- * Use, distribution etc are subject to the terms of the
- * Lucent Technologies Inc. Plan 9 Open Source Licence Agreement
- * available at http://plan9.bell-labs.com/plan9dist/license.html
+ * 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 <lib9.h>
-#include <fcall.h>
+#include "fcall.h"
static uint dumpsome(char*, char*, char*, long);
static void fdirconv(char*, char*, Dir*);
diff --git a/libkern/fmtdef.h b/libkern/fmtdef.h
index d8f3680f..9b0e9782 100644
--- a/libkern/fmtdef.h
+++ b/libkern/fmtdef.h
@@ -1,4 +1,17 @@
/*
+ * 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.
@@ -83,3 +96,7 @@ void _fmtunlock(void);
t += runetochar(t, &_rune);\
}\
}while(0)
+
+#ifndef va_copy
+#define va_copy(a, b) ((a) = (b))
+#endif
diff --git a/libkern/fmtprint.c b/libkern/fmtprint.c
index c93cb315..549049a3 100644
--- a/libkern/fmtprint.c
+++ b/libkern/fmtprint.c
@@ -29,14 +29,16 @@ fmtprint(Fmt *f, char *fmt, ...)
f->flags = 0;
f->width = 0;
f->prec = 0;
- va = f->args;
+ va_copy(va, f->args);
+ va_end(f->args);
va_start(f->args, fmt);
n = dofmt(f, fmt);
va_end(f->args);
f->flags = 0;
f->width = 0;
f->prec = 0;
- f->args = va;
+ va_copy(f->args, va);
+ va_end(va);
if(n >= 0)
return 0;
return n;
diff --git a/libkern/fmtvprint.c b/libkern/fmtvprint.c
index 6682cd33..8e7c1f45 100644
--- a/libkern/fmtvprint.c
+++ b/libkern/fmtvprint.c
@@ -29,13 +29,16 @@ fmtvprint(Fmt *f, char *fmt, va_list args)
f->flags = 0;
f->width = 0;
f->prec = 0;
- va = f->args;
- f->args = args;
+ va_copy(va, f->args);
+ va_end(f->args);
+ va_copy(f->args, args);
n = dofmt(f, fmt);
f->flags = 0;
f->width = 0;
f->prec = 0;
- f->args = va;
+ va_end(f->args);
+ va_copy(f->args, va);
+ va_end(va);
if(n >= 0)
return 0;
return n;
diff --git a/libkern/pow10.c b/libkern/pow10.c
index 933f5d13..f2d01ae8 100644
--- a/libkern/pow10.c
+++ b/libkern/pow10.c
@@ -1,4 +1,7 @@
-#include <lib9.h>
+#ifdef LINUX_386
+#define _MATH_H
+#endif
+#include "lib9.h"
/*
* this table might overflow 127-bit exponent representations.
@@ -8,17 +11,25 @@
* 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,
+ 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,
+ 1.0e70, 1.0e71, 1.0e72, 1.0e73, 1.0e74, 1.0e75, 1.0e76, 1.0e77, 1.0e78, 1.0e79,
+ 1.0e80, 1.0e81, 1.0e82, 1.0e83, 1.0e84, 1.0e85, 1.0e86, 1.0e87, 1.0e88, 1.0e89,
+ 1.0e90, 1.0e91, 1.0e92, 1.0e93, 1.0e94, 1.0e95, 1.0e96, 1.0e97, 1.0e98, 1.0e99,
+ 1.0e100,1.0e101,1.0e102,1.0e103,1.0e104,1.0e105,1.0e106,1.0e107,1.0e108,1.0e109,
+ 1.0e110,1.0e111,1.0e112,1.0e113,1.0e114,1.0e115,1.0e116,1.0e117,1.0e118,1.0e119,
+ 1.0e120,1.0e121,1.0e122,1.0e123,1.0e124,1.0e125,1.0e126,1.0e127,1.0e128,1.0e129,
+ 1.0e130,1.0e131,1.0e132,1.0e133,1.0e134,1.0e135,1.0e136,1.0e137,1.0e138,1.0e139,
+ 1.0e140,1.0e141,1.0e142,1.0e143,1.0e144,1.0e145,1.0e146,1.0e147,1.0e148,1.0e149,
+ 1.0e150,1.0e151,1.0e152,1.0e153,1.0e154,1.0e155,1.0e156,1.0e157,1.0e158,1.0e159,
};
double
@@ -31,7 +42,7 @@ pow10(int n)
if(n < sizeof(tab)/sizeof(tab[0]))
return 1/tab[n];
m = n/2;
- return pow10(-m) * pow10(m-n);
+ return 1/(pow10(m) * pow10(n-m));
}
if(n < sizeof(tab)/sizeof(tab[0]))
return tab[n];
diff --git a/libkern/qsort.c b/libkern/qsort.c
index 3388891c..922538de 100644
--- a/libkern/qsort.c
+++ b/libkern/qsort.c
@@ -2,6 +2,7 @@
* qsort -- simple quicksort
*/
+#include "lib9.h"
typedef
struct
{
@@ -116,7 +117,7 @@ qsort(void *va, long n, long es, int (*cmp)(void*, void*))
s.cmp = cmp;
s.es = es;
s.swap = swapi;
- if(((long)va | es) % sizeof(long))
+ if(((uintptr)va | es) % sizeof(long))
s.swap = swapb;
qsorts((char*)va, n, &s);
}
diff --git a/libkern/rune.c b/libkern/rune.c
index d3cb28e0..f969a2e6 100644
--- a/libkern/rune.c
+++ b/libkern/rune.c
@@ -1,25 +1,23 @@
#include "lib9.h"
+#define Bit(i) (7-(i))
+/* N 0's preceded by i 1's, T(Bit(2)) is 1100 0000 */
+#define T(i) (((1 << (Bit(i)+1))-1) ^ 0xFF)
+/* 0000 0000 0000 0111 1111 1111 */
+#define RuneX(i) ((1 << (Bit(i) + ((i)-1)*Bitx))-1)
+
enum
{
- Bit1 = 7,
- Bitx = 6,
- Bit2 = 5,
- Bit3 = 4,
- Bit4 = 3,
+ Bitx = Bit(1),
- 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 */
+ Tx = T(1), /* 1000 0000 */
+ Rune1 = (1<<(Bit(0)+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */
- 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 */
- Maskx = (1<<Bitx)-1, /* 0011 1111 */
- Testx = Maskx ^ 0xFF, /* 1100 0000 */
+ SurrogateMin = 0xD800,
+ SurrogateMax = 0xDFFF,
Bad = Runeerror,
};
@@ -27,49 +25,42 @@ enum
int
chartorune(Rune *rune, char *str)
{
- int c, c1, c2;
- long l;
+ int c[UTFmax], i;
+ Rune l;
/*
- * one character sequence
+ * N character sequence
* 00000-0007F => T1
+ * 00080-007FF => T2 Tx
+ * 00800-0FFFF => T3 Tx Tx
+ * 10000-10FFFF => T4 Tx Tx Tx
*/
- 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;
+ c[0] = *(uchar*)(str);
+ if(c[0] < Tx){
+ *rune = c[0];
+ return 1;
}
+ l = c[0];
- /*
- * 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)
+ for(i = 1; i < UTFmax; i++) {
+ c[i] = *(uchar*)(str+i);
+ c[i] ^= Tx;
+ if(c[i] & Testx)
goto bad;
- *rune = l;
- return 3;
+ l = (l << Bitx) | c[i];
+ if(c[0] < T(i + 2)) {
+ l &= RuneX(i + 1);
+ if(i == 1) {
+ if(c[0] < T(2) || l <= Rune1)
+ goto bad;
+ } else if(l <= RuneX(i) || l > Runemax)
+ goto bad;
+ if (i == 2 && SurrogateMin <= l && l <= SurrogateMax)
+ goto bad;
+ *rune = l;
+ return i + 1;
+ }
}
/*
@@ -83,12 +74,9 @@ bad:
int
runetochar(char *str, Rune *rune)
{
- long c;
+ int i, j;
+ Rune c;
- /*
- * one character sequence
- * 00000-0007F => 00-7F
- */
c = *rune;
if(c <= Rune1) {
str[0] = c;
@@ -96,67 +84,82 @@ runetochar(char *str, Rune *rune)
}
/*
+ * one character sequence
+ * 00000-0007F => 00-7F
* 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
+ * four character sequence (21-bit value)
+ * 10000-1FFFFF => T4 Tx Tx Tx
+ * If the Rune is out of range or a surrogate half,
+ * convert it to the error rune.
+ * Do this test when i==3 because the error rune encodes to three bytes.
+ * Doing it earlier would duplicate work, since an out of range
+ * Rune wouldn't have fit in one or two bytes.
*/
- str[0] = T3 | (c >> 2*Bitx);
- str[1] = Tx | ((c >> 1*Bitx) & Maskx);
- str[2] = Tx | (c & Maskx);
- return 3;
+ for(i = 2; i < UTFmax + 1; i++){
+ if(i == 3){
+ if(c > Runemax)
+ c = Runeerror;
+ if(SurrogateMin <= c && c <= SurrogateMax)
+ c = Runeerror;
+ }
+ if (c <= RuneX(i) || i == UTFmax ) {
+ str[0] = T(i) | (c >> (i - 1)*Bitx);
+ for(j = 1; j < i; j++)
+ str[j] = Tx | ((c >> (i - j - 1)*Bitx) & Maskx);
+ return i;
+ }
+ }
+ return UTFmax;
}
int
runelen(long c)
{
- if(c <= Rune1)
- return 1;
- if(c <= Rune2)
- return 2;
- return 3;
+ Rune rune;
+ char str[10];
+
+ rune = c;
+ return runetochar(str, &rune);
}
int
-runenlen(Rune *r, int l)
+runenlen(Rune *r, int nrune)
{
- int n;
- long c;
+ int nb, i;
+ Rune c;
- n = 0;
- while(l--) {
+ nb = 0;
+ while(nrune--) {
c = *r++;
- if(c <= Rune1)
- n += 1;
- else
- if(c <= Rune2)
- n += 2;
- else
- n += 3;
+ if(c <= Rune1){
+ nb++;
+ } else {
+ for(i = 2; i < UTFmax + 1; i++)
+ if(c <= RuneX(i) || i == UTFmax){
+ nb += i;
+ break;
+ }
+ }
}
- return n;
+ 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;
+ int i;
+ Rune c;
+
+ if(n <= 0)
+ return 0;
+ c = *(uchar*)str;
+ if(c < Tx)
+ return 1;
+ for(i = 3; i < UTFmax + 1; i++)
+ if(c < T(i))
+ return n >= i - 1;
+ return n >= UTFmax;
}
diff --git a/libkern/tokenize.c b/libkern/tokenize.c
index 1b222c52..790b7c2a 100644
--- a/libkern/tokenize.c
+++ b/libkern/tokenize.c
@@ -3,14 +3,14 @@
static char qsep[] = " \t\r\n";
static char*
-qtoken(char *s)
+qtoken(char *s, char *sep)
{
int quoting;
char *t;
quoting = 0;
t = s; /* s is output string, t is input string */
- while(*t!='\0' && (quoting || utfrune(qsep, *t)==nil)){
+ while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
if(*t != '\''){
*s++ = *t++;
continue;
@@ -40,6 +40,54 @@ qtoken(char *s)
return t;
}
+static char*
+etoken(char *t, char *sep)
+{
+ int quoting;
+
+ /* move to end of next token */
+ quoting = 0;
+ while(*t!='\0' && (quoting || utfrune(sep, *t)==nil)){
+ if(*t != '\''){
+ t++;
+ continue;
+ }
+ /* *t is a quote */
+ if(!quoting){
+ quoting = 1;
+ t++;
+ continue;
+ }
+ /* quoting and we're on a quote */
+ if(t[1] != '\''){
+ /* end of quoted section; absorb closing quote */
+ t++;
+ quoting = 0;
+ continue;
+ }
+ /* doubled quote; fold one quote into two */
+ t += 2;
+ }
+ return t;
+}
+
+int
+gettokens(char *s, char **args, int maxargs, char *sep)
+{
+ int nargs;
+
+ for(nargs=0; nargs<maxargs; nargs++){
+ while(*s!='\0' && utfrune(sep, *s)!=nil)
+ *s++ = '\0';
+ if(*s == '\0')
+ break;
+ args[nargs] = s;
+ s = etoken(s, sep);
+ }
+
+ return nargs;
+}
+
int
tokenize(char *s, char **args, int maxargs)
{
@@ -51,7 +99,7 @@ tokenize(char *s, char **args, int maxargs)
if(*s == '\0')
break;
args[nargs] = s;
- s = qtoken(s);
+ s = qtoken(s, qsep);
}
return nargs;
diff --git a/libkern/utflen.c b/libkern/utflen.c
index a588bbd1..4ba9593c 100644
--- a/libkern/utflen.c
+++ b/libkern/utflen.c
@@ -1,4 +1,4 @@
-#include <lib9.h>
+#include "lib9.h"
int
utflen(char *s)
@@ -18,5 +18,4 @@ utflen(char *s)
s += chartorune(&rune, s);
n++;
}
- return 0;
}
diff --git a/libkern/utfrrune.c b/libkern/utfrrune.c
index b4594321..fc7af34f 100644
--- a/libkern/utfrrune.c
+++ b/libkern/utfrrune.c
@@ -1,4 +1,4 @@
-#include <lib9.h>
+#include "lib9.h"
char*
utfrrune(char *s, long c)
@@ -26,5 +26,4 @@ utfrrune(char *s, long c)
s1 = s;
s += c1;
}
- return 0;
}
diff --git a/libkern/utfrune.c b/libkern/utfrune.c
index 9925af81..b7ccc8b0 100644
--- a/libkern/utfrune.c
+++ b/libkern/utfrune.c
@@ -1,4 +1,4 @@
-#include <lib9.h>
+#include "lib9.h"
char*
utfrune(char *s, long c)
@@ -25,5 +25,4 @@ utfrune(char *s, long c)
return s;
s += n;
}
- return 0;
}
diff --git a/libkern/vseprint.c b/libkern/vseprint.c
index 7b23d55b..1e31f76a 100644
--- a/libkern/vseprint.c
+++ b/libkern/vseprint.c
@@ -12,6 +12,7 @@
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*/
#include "lib9.h"
+#include "fmtdef.h"
char*
vseprint(char *buf, char *e, char *fmt, va_list args)
@@ -27,8 +28,10 @@ vseprint(char *buf, char *e, char *fmt, va_list args)
f.flush = nil;
f.farg = nil;
f.nfmt = 0;
- f.args = args;
+ va_copy(f.args, args);
dofmt(&f, fmt);
+ va_end(f.args);
*(char*)f.to = '\0';
return f.to;
}
+
diff --git a/libkern/vsmprint.c b/libkern/vsmprint.c
index 44789be5..0e18fe44 100644
--- a/libkern/vsmprint.c
+++ b/libkern/vsmprint.c
@@ -20,6 +20,8 @@ fmtStrFlush(Fmt *f)
char *s;
int n;
+ if(f->start == nil)
+ return 0;
n = (int)f->farg;
n += 256;
f->farg = (void*)n;
@@ -41,7 +43,7 @@ fmtstrinit(Fmt *f)
{
int n;
- f->runes = 0;
+ memset(f, 0, sizeof(*f));
n = 32;
f->start = malloc(n);
if(f->start == nil)
@@ -65,10 +67,13 @@ vsmprint(char *fmt, va_list args)
if(fmtstrinit(&f) < 0)
return nil;
- f.args = args;
+ va_copy(f.args, args);
n = dofmt(&f, fmt);
- if(n < 0)
+ va_end(f.args);
+ if(n < 0){
+ free(f.start);
+ f.start = nil;
return nil;
- *(char*)f.to = '\0';
- return f.start;
+ }
+ return fmtstrflush(&f);
}
diff --git a/libkern/vsnprint.c b/libkern/vsnprint.c
index 841d142c..2006cfb3 100644
--- a/libkern/vsnprint.c
+++ b/libkern/vsnprint.c
@@ -12,6 +12,7 @@
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*/
#include "lib9.h"
+#include "fmtdef.h"
int
vsnprint(char *buf, int len, char *fmt, va_list args)
@@ -27,8 +28,9 @@ vsnprint(char *buf, int len, char *fmt, va_list args)
f.flush = nil;
f.farg = nil;
f.nfmt = 0;
- f.args = args;
+ va_copy(f.args, args);
dofmt(&f, fmt);
+ va_end(f.args);
*(char*)f.to = '\0';
return (char*)f.to - buf;
}