change length or size specifiers in APIs from int to long
add array API (http://cr.yp.to/lib/array.html)
This commit is contained in:
parent
d1df715971
commit
5226dd010d
1
CHANGES
1
CHANGES
@ -1,6 +1,7 @@
|
||||
0.16:
|
||||
add buffer_fromsa (make buffer from stralloc)
|
||||
add API for integer multiply with overflow detection
|
||||
change length counters from int to long for 64-bit platforms
|
||||
|
||||
0.15:
|
||||
man page update (document stralloc return values)
|
||||
|
17
array.h
17
array.h
@ -6,25 +6,26 @@
|
||||
|
||||
typedef struct {
|
||||
char* p;
|
||||
int64 allocated, initialized; /* in bytes */
|
||||
int64 allocated; /* in bytes */
|
||||
uint64 initialized; /* in bytes */
|
||||
|
||||
/* p and allocated nonzero: array is allocated */
|
||||
/* p zero: array is unallocated */
|
||||
/* allocated < 0: array is failed */
|
||||
/* p and allocated zero: array is unallocated */
|
||||
/* p zero and allocated < 0: array is failed */
|
||||
} array;
|
||||
|
||||
void* array_allocate(array* x,int64 membersize,int64 pos);
|
||||
void* array_get(array* x,int64 membersize,int64 pos);
|
||||
void* array_allocate(array* x,uint64 membersize,int64 pos);
|
||||
void* array_get(array* x,uint64 membersize,int64 pos);
|
||||
void* array_start(const array* const x);
|
||||
int64 array_length(const array* const x,int64 membersize);
|
||||
int64 array_length(const array* const x,uint64 membersize);
|
||||
int64 array_bytes(const array* const x);
|
||||
void array_truncate(array* x,int64 membersize,int64 len);
|
||||
void array_truncate(array* x,uint64 membersize,int64 len);
|
||||
void array_trunc(array* x);
|
||||
void array_reset(array* x);
|
||||
void array_fail(array* x);
|
||||
int array_equal(const array* const x,const array* const y);
|
||||
void array_cat(array* to,const array* const from);
|
||||
void array_catb(array* to,const char* from,int64 len);
|
||||
void array_catb(array* to,const char* from,uint64 len);
|
||||
void array_cats(array* to,const char* from);
|
||||
void array_cats0(array* to,const char* from);
|
||||
void array_cat0(array* to);
|
||||
|
@ -1,4 +1,14 @@
|
||||
#ifdef __dietlibc__
|
||||
#include <sys/cdefs.h>
|
||||
#else
|
||||
#define __likely(x) x
|
||||
#define __unlikely(x) x
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include "safemult.h"
|
||||
#include "array.h"
|
||||
#include "byte.h"
|
||||
|
||||
#if 0
|
||||
static array x;
|
||||
@ -39,13 +49,32 @@
|
||||
that, use array_fail.
|
||||
#endif
|
||||
|
||||
void* array_allocate(array* x,int64 membersize,int64 pos) {
|
||||
int64 wanted;
|
||||
if (membersize<128)
|
||||
wanted=(pos+127)&(-128ll); /* round up to multiple of 128 */
|
||||
else
|
||||
wanted=(pos+4095)&(-4096ll); /* round up to 4k pages */
|
||||
/* detect numeric overflow */
|
||||
if (wanted<0) return 0;
|
||||
wanted=membersize*(pos+1);
|
||||
void* array_allocate(array* x,uint64 membersize,int64 pos) {
|
||||
uint64 wanted;
|
||||
if (__unlikely(x->allocated<0)) return 0; /* array is failed */
|
||||
if (__unlikely(pos+1<1)) return 0;
|
||||
/* second case of overflow: pos*membersize too large */
|
||||
if (__unlikely(umult64(membersize,pos+1,&wanted))) return 0;
|
||||
|
||||
if (__unlikely(wanted > x->allocated)) {
|
||||
/* round up a little */
|
||||
if (membersize<8)
|
||||
wanted=(wanted+127)&(-128ll); /* round up to multiple of 128 */
|
||||
else
|
||||
wanted=(wanted+4095)&(-4096ll); /* round up to 4k pages */
|
||||
|
||||
if (__unlikely(wanted<128)) return 0; /* overflow during rounding */
|
||||
|
||||
if (sizeof(size_t) != sizeof(int64) && __unlikely((size_t)(wanted) != wanted))
|
||||
return 0;
|
||||
{
|
||||
char* tmp=realloc(x->p,wanted);
|
||||
if (__unlikely(!tmp)) return 0;
|
||||
x->p=tmp;
|
||||
}
|
||||
x->allocated=wanted;
|
||||
byte_zero(x->p+x->initialized,x->allocated-x->initialized);
|
||||
}
|
||||
x->initialized=pos*membersize;
|
||||
return x->p+pos*membersize;
|
||||
}
|
||||
|
6
array/array_bytes.c
Normal file
6
array/array_bytes.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "array.h"
|
||||
|
||||
int64 array_bytes(const array* const x) {
|
||||
if (x->allocated<0) return -1;
|
||||
return x->initialized;
|
||||
}
|
10
array/array_cat.c
Normal file
10
array/array_cat.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include "array.h"
|
||||
#include "byte.h"
|
||||
|
||||
void array_cat(array* to,const array* const from) {
|
||||
if (from->allocated<0) {
|
||||
array_fail(to);
|
||||
return;
|
||||
}
|
||||
return array_catb(to,from->p,from->initialized);
|
||||
}
|
6
array/array_cat0.c
Normal file
6
array/array_cat0.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "array.h"
|
||||
|
||||
void array_cat0(array* to) {
|
||||
static char zero;
|
||||
array_catb(to,&zero,1);
|
||||
}
|
16
array/array_catb.c
Normal file
16
array/array_catb.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include "array.h"
|
||||
#include "byte.h"
|
||||
|
||||
void array_catb(array* to,const char* from,uint64 len) {
|
||||
long l;
|
||||
if (to->allocated<0) return;
|
||||
if (to->initialized+len<to->initialized) {
|
||||
fail:
|
||||
array_fail(to);
|
||||
return;
|
||||
}
|
||||
l=to->initialized;
|
||||
if (!array_allocate(to,1,to->initialized+len))
|
||||
goto fail;
|
||||
byte_copy(to->p+l,to->initialized-l,from);
|
||||
}
|
9
array/array_cate.c
Normal file
9
array/array_cate.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "array.h"
|
||||
|
||||
void array_cate(array* to,const array* const from,int64 pos,int64 stop) {
|
||||
if (pos<0 || stop<pos) {
|
||||
array_fail(to);
|
||||
return;
|
||||
}
|
||||
array_catb(to,from->p+pos,stop-pos);
|
||||
}
|
6
array/array_cats.c
Normal file
6
array/array_cats.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "array.h"
|
||||
#include "str.h"
|
||||
|
||||
void array_cats(array* to,const char* from) {
|
||||
array_catb(to,from,strlen(from));
|
||||
}
|
6
array/array_cats0.c
Normal file
6
array/array_cats0.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "array.h"
|
||||
#include "str.h"
|
||||
|
||||
void array_cats0(array* to,const char* from) {
|
||||
array_catb(to,from,strlen(from)+1);
|
||||
}
|
7
array/array_equal.c
Normal file
7
array/array_equal.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "byte.h"
|
||||
#include "array.h"
|
||||
|
||||
int array_equal(const array* const x,const array* const y) {
|
||||
if (x->initialized!=y->initialized) return 0;
|
||||
return byte_equal(x->p,x->initialized,y->p);
|
||||
}
|
9
array/array_fail.c
Normal file
9
array/array_fail.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <stdlib.h>
|
||||
#include "array.h"
|
||||
|
||||
void array_fail(array* x) {
|
||||
if (x->p) free(x->p);
|
||||
x->p=0;
|
||||
x->initialized=0;
|
||||
x->allocated=-1;
|
||||
}
|
30
array/array_get.c
Normal file
30
array/array_get.c
Normal file
@ -0,0 +1,30 @@
|
||||
#ifdef __dietlibc__
|
||||
#include <sys/cdefs.h>
|
||||
#else
|
||||
#define __likely(x) x
|
||||
#define __unlikely(x) x
|
||||
#endif
|
||||
#include "safemult.h"
|
||||
#include "array.h"
|
||||
|
||||
#if 0
|
||||
static array x;
|
||||
t *p;
|
||||
int64 pos;
|
||||
|
||||
p = array_get(&x,sizeof(t),pos);
|
||||
|
||||
array_get is similar to array_allocate, but it does not allocate any
|
||||
extra bytes, and it does not initialize any extra bytes. It
|
||||
returns 0 if x is unallocated, for example, or if fewer than
|
||||
(pos+1)*sizeof(t) bytes are initialized.
|
||||
#endif
|
||||
|
||||
void* array_get(array* x,uint64 membersize,int64 pos) {
|
||||
uint64 wanted;
|
||||
if (__unlikely(pos+1<1)) return 0;
|
||||
if (__unlikely(umult64(membersize,pos,&wanted))) return 0;
|
||||
|
||||
if (__unlikely(wanted > x->allocated)) return 0;
|
||||
return x->p+pos*membersize;
|
||||
}
|
6
array/array_length.c
Normal file
6
array/array_length.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "array.h"
|
||||
|
||||
int64 array_length(const array* const x,uint64 membersize) {
|
||||
if (x->allocated<0) return -1;
|
||||
return x->initialized/membersize;
|
||||
}
|
8
array/array_reset.c
Normal file
8
array/array_reset.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include "array.h"
|
||||
|
||||
void array_reset(array* x) {
|
||||
if (x->p) free(x->p);
|
||||
x->p=0;
|
||||
x->allocated=x->initialized=0;
|
||||
}
|
5
array/array_start.c
Normal file
5
array/array_start.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "array.h"
|
||||
|
||||
void* array_start(const array* const x) {
|
||||
return x->p;
|
||||
}
|
5
array/array_trunc.c
Normal file
5
array/array_trunc.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "array.h"
|
||||
|
||||
void array_trunc(array* x) {
|
||||
x->initialized=0;
|
||||
}
|
17
array/array_truncate.c
Normal file
17
array/array_truncate.c
Normal file
@ -0,0 +1,17 @@
|
||||
#ifdef __dietlibc__
|
||||
#include <sys/cdefs.h>
|
||||
#else
|
||||
#define __likely(x) x
|
||||
#define __unlikely(x) x
|
||||
#endif
|
||||
#include "safemult.h"
|
||||
#include "array.h"
|
||||
|
||||
/* I'm not sure I understand what this function is good for */
|
||||
void array_truncate(array* x,uint64 membersize,int64 len) {
|
||||
uint64 wanted;
|
||||
if (__unlikely(len<0)) return;
|
||||
if (__unlikely(umult64(membersize,len,&wanted))) return;
|
||||
if (__unlikely(wanted > x->initialized)) return;
|
||||
x->initialized=wanted;
|
||||
}
|
12
byte.h
12
byte.h
@ -11,29 +11,29 @@
|
||||
|
||||
/* byte_chr returns the smallest integer i between 0 and len-1
|
||||
* inclusive such that one[i] equals needle, or len if not found. */
|
||||
unsigned int byte_chr(const void* haystack, unsigned int len, char needle) __pure__;
|
||||
unsigned long byte_chr(const void* haystack, unsigned long len, char needle) __pure__;
|
||||
|
||||
/* byte_rchr returns the largest integer i between 0 and len-1 inclusive
|
||||
* such that one[i] equals needle, or len if not found. */
|
||||
unsigned int byte_rchr(const void* haystack,unsigned int len,char needle) __pure__;
|
||||
unsigned long byte_rchr(const void* haystack,unsigned long len,char needle) __pure__;
|
||||
|
||||
/* byte_copy copies in[0] to out[0], in[1] to out[1], ... and in[len-1]
|
||||
* to out[len-1]. */
|
||||
void byte_copy(void* out, unsigned int len, const void* in);
|
||||
void byte_copy(void* out, unsigned long len, const void* in);
|
||||
|
||||
/* byte_copyr copies in[len-1] to out[len-1], in[len-2] to out[len-2],
|
||||
* ... and in[0] to out[0] */
|
||||
void byte_copyr(void* out, unsigned int len, const void* in);
|
||||
void byte_copyr(void* out, unsigned long len, const void* in);
|
||||
|
||||
/* byte_diff returns negative, 0, or positive, depending on whether the
|
||||
* string a[0], a[1], ..., a[len-1] is lexicographically smaller
|
||||
* than, equal to, or greater than the string b[0], b[1], ...,
|
||||
* b[len-1]. When the strings are different, byte_diff does not read
|
||||
* bytes past the first difference. */
|
||||
int byte_diff(const void* a, unsigned int len, const void* b) __pure__;
|
||||
int byte_diff(const void* a, unsigned long len, const void* b) __pure__;
|
||||
|
||||
/* byte_zero sets the bytes out[0], out[1], ..., out[len-1] to 0 */
|
||||
void byte_zero(void* out, unsigned len);
|
||||
void byte_zero(void* out, unsigned long len);
|
||||
|
||||
#define byte_equal(s,n,t) (!byte_diff((s),(n),(t)))
|
||||
|
||||
|
@ -4,7 +4,7 @@ byte_chr \- search for a byte in a string
|
||||
.SH SYNTAX
|
||||
.B #include <byte.h>
|
||||
|
||||
int \fBbyte_chr\fP(const char *\fIhaystack\fR,unsigned int \fIlen\fR,char \fIneedle\fR);
|
||||
long \fBbyte_chr\fP(const char *\fIhaystack\fR,unsigned long \fIlen\fR,char \fIneedle\fR);
|
||||
.SH DESCRIPTION
|
||||
\fIbyte_chr\fR returns the smallest integer \fIi\fR between 0 and
|
||||
\fIlen\fR-1 inclusive such that \fIone\fR[\fIi\fR] equals \fIneedle\fR.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/* byte_chr returns the smallest integer i between 0 and len-1
|
||||
* inclusive such that one[i] equals needle, or len it not found. */
|
||||
unsigned int byte_chr(const void* haystack, unsigned int len, char needle) {
|
||||
unsigned long byte_chr(const void* haystack, unsigned long len, char needle) {
|
||||
register char c=needle;
|
||||
register const char* s=haystack;
|
||||
register const char* t=s+len;
|
||||
|
@ -4,7 +4,7 @@ byte_copy \- copy a string
|
||||
.SH SYNTAX
|
||||
.B #include <byte.h>
|
||||
|
||||
void \fBbyte_copy\fP(char *\fIout\fR,unsigned int \fIlen\fR,const char *\fIin\fR);
|
||||
void \fBbyte_copy\fP(char *\fIout\fR,unsigned long \fIlen\fR,const char *\fIin\fR);
|
||||
.SH DESCRIPTION
|
||||
\fIbyte_copy\fR copies \fIin\fR[0] to \fIout\fR[0], \fIin\fR[1] to
|
||||
\fIout\fR[1], etc., and finally \fIin\fR[\fIlen\fR-1] to
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/* byte_copy copies in[0] to out[0], in[1] to out[1], ... and in[len-1]
|
||||
* to out[len-1]. */
|
||||
void byte_copy(void* out, unsigned int len, const void* in) {
|
||||
void byte_copy(void* out, unsigned long len, const void* in) {
|
||||
register char* s=out;
|
||||
register const char* t=in;
|
||||
register const char* u=t+len;
|
||||
|
@ -4,7 +4,7 @@ byte_copyr \- copy a string
|
||||
.SH SYNTAX
|
||||
.B #include <byte.h>
|
||||
|
||||
void \fBbyte_copyr\fP(char *\fIout\fR,unsigned int \fIlen\fR,const char *\fIin\fR);
|
||||
void \fBbyte_copyr\fP(char *\fIout\fR,unsigned long \fIlen\fR,const char *\fIin\fR);
|
||||
.SH DESCRIPTION
|
||||
\fIbyte_copyr\fR copies \fIin\fR[\fIlen\fR-1] to \fIout\fR[\fIlen\fR-1],
|
||||
\fIin\fR[\fIlen\fR-2] to \fIout\fR[\fIlen\fR-2], etc., and
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/* byte_copyr copies in[len-1] to out[len-1], in[len-2] to out[len-2],
|
||||
* ... and in[0] to out[0] */
|
||||
void byte_copyr(void* out, unsigned int len, const void* in) {
|
||||
void byte_copyr(void* out, unsigned long len, const void* in) {
|
||||
register char* s=(char*)out+len;
|
||||
register const char* t=in;
|
||||
register const char* u=t+len;
|
||||
|
@ -4,7 +4,7 @@ byte_diff \- compare two strings
|
||||
.SH SYNTAX
|
||||
.B #include <byte.h>
|
||||
|
||||
int \fBbyte_diff\fP(const char *\fIone\fR,unsigned int \fIlen\fR,const char *\fItwo\fR);
|
||||
int \fBbyte_diff\fP(const char *\fIone\fR,unsigned long \fIlen\fR,const char *\fItwo\fR);
|
||||
.SH DESCRIPTION
|
||||
\fIbyte_diff\fR returns negative, 0, or positive, depending on whether
|
||||
the string \fIone\fR[0], \fIone\fR[1], ..., \fIone\fR[\fIlen\fR-1] is
|
||||
|
@ -5,7 +5,7 @@
|
||||
* than, equal to, or greater than the string one[0], one[1], ...,
|
||||
* one[len-1]. When the strings are different, byte_diff does not read
|
||||
* bytes past the first difference. */
|
||||
int byte_diff(const void* a, unsigned int len, const void* b) {
|
||||
int byte_diff(const void* a, unsigned long len, const void* b) {
|
||||
register const char* s=a;
|
||||
register const char* t=b;
|
||||
register const char* u=t+len;
|
||||
|
@ -4,7 +4,7 @@ byte_equal \- compare two strings
|
||||
.SH SYNTAX
|
||||
.B #include <byte.h>
|
||||
|
||||
int \fBbyte_equal\fP(const char *\fIone\fR,unsigned int \fIlen\fR,const char *\fItwo\fR);
|
||||
int \fBbyte_equal\fP(const char *\fIone\fR,unsigned long \fIlen\fR,const char *\fItwo\fR);
|
||||
.SH DESCRIPTION
|
||||
\fIbyte_equal\fR returns 1 if the strings are equal, 0 otherwise.
|
||||
|
||||
|
@ -4,7 +4,7 @@ byte_rchr \- search for a byte in a string
|
||||
.SH SYNTAX
|
||||
.B #include <byte.h>
|
||||
|
||||
int \fBbyte_rchr\fP(const char *\fIhaystack\fR,unsigned int \fIlen\fR,char \fIneedle\fR);
|
||||
long \fBbyte_rchr\fP(const char *\fIhaystack\fR,unsigned long \fIlen\fR,char \fIneedle\fR);
|
||||
.SH DESCRIPTION
|
||||
\fIbyte_chr\fR returns the largest integer \fIi\fR between 0 and
|
||||
\fIlen\fR-1 inclusive such that \fIone\fR[\fIi\fR] equals \fIneedle\fR.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/* byte_rchr returns the largest integer i between 0 and len-1 inclusive
|
||||
* such that one[i] equals needle, or len if not found. */
|
||||
unsigned int byte_rchr(const void* haystack,unsigned int len,char needle) {
|
||||
unsigned long byte_rchr(const void* haystack,unsigned long len,char needle) {
|
||||
register char c=needle;
|
||||
register const char* s=haystack;
|
||||
register const char* t=s+len;
|
||||
|
@ -4,7 +4,7 @@ byte_zero \- initialize a string
|
||||
.SH SYNTAX
|
||||
.B #include <byte.h>
|
||||
|
||||
void \fBbyte_zero\fP(char *\fIout\fR,unsigned int \fIlen\fR);
|
||||
void \fBbyte_zero\fP(char *\fIout\fR,unsigned long \fIlen\fR);
|
||||
.SH DESCRIPTION
|
||||
\fIbyte_zero\fR sets \fIout\fR[0], \fIout\fR[1], ...,
|
||||
\fIout\fR[\fIlen\fR-1] to 0.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "byte.h"
|
||||
|
||||
/* byte_zero sets the bytes out[0], out[1], ..., out[len-1] to 0 */
|
||||
void byte_zero(void* out, unsigned len) {
|
||||
void byte_zero(void* out, unsigned long len) {
|
||||
register char* s=out;
|
||||
register const char* t=s+len;
|
||||
for (;;) {
|
||||
|
4
case.h
4
case.h
@ -4,12 +4,12 @@
|
||||
/* turn upper case letters to lower case letters, ASCIIZ */
|
||||
extern void case_lowers(char *s);
|
||||
/* turn upper case letters to lower case letters, binary */
|
||||
extern void case_lowerb(char *buf,unsigned int len);
|
||||
extern void case_lowerb(char *buf,unsigned long len);
|
||||
|
||||
/* like str_diff, ignoring case */
|
||||
extern int case_diffs(const char *,const char *);
|
||||
/* like byte_diff, ignoring case */
|
||||
extern int case_diffb(const char *,unsigned int,const char *);
|
||||
extern int case_diffb(const char *,unsigned long,const char *);
|
||||
|
||||
/* like str_start, ignoring case */
|
||||
extern int case_starts(const char *,const char *);
|
||||
|
@ -4,7 +4,7 @@ case_diffb \- compare strings case-insensitively
|
||||
.SH SYNTAX
|
||||
.B #include <case.h>
|
||||
|
||||
int \fBcase_diffb\fP(const char* \fIa\fR,const char* \fIb\fR);
|
||||
int \fBcase_diffb\fP(const char* \fIa\fR,unsigned long \fIlen\fR,const char* \fIb\fR);
|
||||
.SH DESCRIPTION
|
||||
case_diffb is similar to byte_diff. The difference is that for the
|
||||
comparison 'A' == 'a', 'B' == 'b', ..., 'Z' == 'z'.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "case.h"
|
||||
|
||||
int case_diffb(register const char *s,register unsigned int len,register const char *t)
|
||||
int case_diffb(register const char *s,register unsigned long len,register const char *t)
|
||||
{
|
||||
register unsigned char x;
|
||||
register unsigned char y;
|
||||
|
@ -4,7 +4,7 @@ case_lowerb \- compare strings case-insensitively
|
||||
.SH SYNTAX
|
||||
.B #include <case.h>
|
||||
|
||||
int \fBcase_lowerb\fP(char* \fIs\fR,unsigned int \fIlen\fR);
|
||||
void \fBcase_lowerb\fP(char* \fIs\fR,unsigned long \fIlen\fR);
|
||||
.SH DESCRIPTION
|
||||
case_lowerb converts each 'A' to 'a', 'B' to 'b', ..., 'Z' to 'z' in
|
||||
\fIs\fR[0], \fIs\fR[1], ..., \fIs\fR[\fIlen\fR].
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "case.h"
|
||||
|
||||
void case_lowerb(char *s,unsigned int len) {
|
||||
void case_lowerb(char *s,unsigned long len) {
|
||||
unsigned char x;
|
||||
while (len > 0) {
|
||||
--len;
|
||||
|
@ -4,7 +4,7 @@ case_lowers \- compare strings case-insensitively
|
||||
.SH SYNTAX
|
||||
.B #include <case.h>
|
||||
|
||||
int \fBcase_lowers\fP(char* \fIs\fR);
|
||||
void \fBcase_lowers\fP(char* \fIs\fR);
|
||||
.SH DESCRIPTION
|
||||
case_lowers converts each 'A' to 'a', 'B' to 'b', ..., 'Z' to 'z' for
|
||||
each character in \fIs\fR until the first \\0.
|
||||
|
8
fmt.h
8
fmt.h
@ -58,23 +58,23 @@ unsigned int fmt_plusminus(char *dest,int src);
|
||||
unsigned int fmt_minus(char *dest,int src);
|
||||
|
||||
/* copy str to dest until \0 byte, return number of copied bytes. */
|
||||
unsigned int fmt_str(char *dest,const char *src);
|
||||
unsigned long fmt_str(char *dest,const char *src);
|
||||
|
||||
/* copy str to dest until \0 byte or limit bytes copied.
|
||||
* return number of copied bytes. */
|
||||
unsigned int fmt_strn(char *dest,const char *src,unsigned int limit);
|
||||
unsigned long fmt_strn(char *dest,const char *src,unsigned long limit);
|
||||
|
||||
/* "foo" -> " foo"
|
||||
* write padlen-srclen spaces, if that is >= 0. Then copy srclen
|
||||
* characters from src. Truncate only if total length is larger than
|
||||
* maxlen. Return number of characters written. */
|
||||
unsigned int fmt_pad(char* dest,const char* src,unsigned int srclen,unsigned int padlen,unsigned int maxlen);
|
||||
unsigned long fmt_pad(char* dest,const char* src,unsigned long srclen,unsigned long padlen,unsigned long maxlen);
|
||||
|
||||
/* "foo" -> "foo "
|
||||
* append padlen-srclen spaces after dest, if that is >= 0. Truncate
|
||||
* only if total length is larger than maxlen. Return number of
|
||||
* characters written. */
|
||||
unsigned int fmt_fill(char* dest,unsigned int srclen,unsigned int padlen,unsigned int maxlen);
|
||||
unsigned long fmt_fill(char* dest,unsigned long srclen,unsigned long padlen,unsigned long maxlen);
|
||||
|
||||
/* 1 -> "1", 4900 -> "4.9k", 2300000 -> "2.3M" */
|
||||
unsigned int fmt_human(char* dest,unsigned long long l);
|
||||
|
@ -4,9 +4,9 @@ fmt_fill \- append spaces to a string
|
||||
.SH SYNTAX
|
||||
.B #include <fmt.h>
|
||||
|
||||
unsigned int \fBfmt_fill\fP(char *\fIdest\fR,
|
||||
unsigned int \fIsrclen\fR, unsigned int \fIpadlen\fR,
|
||||
unsigned int \fImaxlen\fR);
|
||||
unsigned long \fBfmt_fill\fP(char *\fIdest\fR,
|
||||
unsigned long \fIsrclen\fR, unsigned long \fIpadlen\fR,
|
||||
unsigned long \fImaxlen\fR);
|
||||
.SH DESCRIPTION
|
||||
fmt_fill appends \fIpadlen\fR-\fIsrclen\fR spaces (if that number is
|
||||
positive) to \fIdest\fR (which holds \fIsrclen\fR bytes). It truncates
|
||||
|
@ -4,8 +4,8 @@
|
||||
* append padlen-srclen spaces after dest, if that is >= 0. Truncate
|
||||
* only if total length is larger than maxlen. Return number of
|
||||
* characters written. */
|
||||
unsigned int fmt_fill(char* dest,unsigned int srclen,unsigned int padlen,unsigned int maxlen) {
|
||||
int todo;
|
||||
unsigned long fmt_fill(char* dest,unsigned long srclen,unsigned long padlen,unsigned long maxlen) {
|
||||
long todo;
|
||||
char* olddest=dest;
|
||||
char* max=dest+maxlen;
|
||||
if (dest==0) {
|
||||
|
@ -4,9 +4,9 @@ fmt_pad \- pad a string with spaces.
|
||||
.SH SYNTAX
|
||||
.B #include <fmt.h>
|
||||
|
||||
unsigned int \fBfmt_pad\fP(char *\fIdest\fR, const char *\fIsource\fR,
|
||||
unsigned int \fIsrclen\fR, unsigned int \fIpadlen\fR,
|
||||
unsigned int \fImaxlen\fR);
|
||||
unsigned long \fBfmt_pad\fP(char *\fIdest\fR, const char *\fIsource\fR,
|
||||
unsigned long \fIsrclen\fR, unsigned long \fIpadlen\fR,
|
||||
unsigned long \fImaxlen\fR);
|
||||
.SH DESCRIPTION
|
||||
fmt_pad writes \fIpadlen\fR-\fIsrclen\fR spaces (if that number is
|
||||
positive) and then \fIsrclen\fR characters from \fIsource\fR. It
|
||||
|
@ -4,8 +4,8 @@
|
||||
* write padlen-srclen spaces, if that is >= 0. Then copy srclen
|
||||
* characters from src. Truncate only if total length is larger than
|
||||
* maxlen. Return number of characters written. */
|
||||
unsigned int fmt_pad(char* dest,const char* src,unsigned int srclen,unsigned int padlen,unsigned int maxlen) {
|
||||
int todo;
|
||||
unsigned long fmt_pad(char* dest,const char* src,unsigned long srclen,unsigned long padlen,unsigned long maxlen) {
|
||||
long todo;
|
||||
char* olddest=dest;
|
||||
char* max=dest+maxlen;
|
||||
todo=padlen-srclen;
|
||||
|
@ -4,7 +4,7 @@ fmt_str \- write an ASCII string
|
||||
.SH SYNTAX
|
||||
.B #include <fmt.h>
|
||||
|
||||
unsigned int \fBfmt_str\fP(char *\fIdest\fR,const char *\fIsource\fR);
|
||||
unsigned long \fBfmt_str\fP(char *\fIdest\fR,const char *\fIsource\fR);
|
||||
.SH DESCRIPTION
|
||||
fmt_str copies all leading nonzero bytes from \fIsource\fR to \fIdest\fR
|
||||
and returns the number of bytes it copied.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "fmt.h"
|
||||
|
||||
unsigned int fmt_str(char *out,const char *in) {
|
||||
unsigned long fmt_str(char *out,const char *in) {
|
||||
register char* s=out;
|
||||
register const char* t=in;
|
||||
for (;;) {
|
||||
|
@ -4,8 +4,8 @@ fmt_strn \- write an ASCII string
|
||||
.SH SYNTAX
|
||||
.B #include <fmt.h>
|
||||
|
||||
unsigned int \fBfmt_strn\fP(char *\fIdest\fR,const char *\fIsource\fR,
|
||||
unsigned int maxlen);
|
||||
unsigned long \fBfmt_strn\fP(char *\fIdest\fR,const char *\fIsource\fR,
|
||||
unsigned long maxlen);
|
||||
.SH DESCRIPTION
|
||||
fmt_str copies at most \fImaxlen\fR leading nonzero bytes from
|
||||
\fIsource\fR to \fIdest\fR and returns the number of bytes it copied.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "fmt.h"
|
||||
|
||||
unsigned int fmt_strn(char *out,const char *in,unsigned int limit) {
|
||||
unsigned long fmt_strn(char *out,const char *in,unsigned long limit) {
|
||||
register char* s=out;
|
||||
register const char* t=in;
|
||||
register const char* u=in+limit;
|
||||
|
8
scan.h
8
scan.h
@ -52,18 +52,18 @@ extern unsigned int scan_double(const char *in, double *dest);
|
||||
extern unsigned int scan_plusminus(const char *src,signed int *dest);
|
||||
|
||||
/* return the highest integer n<=limit so that isspace(in[i]) for all 0<=i<=n */
|
||||
extern unsigned int scan_whitenskip(const char *in,unsigned int limit) __pure__;
|
||||
extern unsigned long scan_whitenskip(const char *in,unsigned long limit) __pure__;
|
||||
|
||||
/* return the highest integer n<=limit so that !isspace(in[i]) for all 0<=i<=n */
|
||||
extern unsigned int scan_nonwhitenskip(const char *in,unsigned int limit) __pure__;
|
||||
extern unsigned long scan_nonwhitenskip(const char *in,unsigned long limit) __pure__;
|
||||
|
||||
/* return the highest integer n<=limit so that in[i] is element of
|
||||
* charset (ASCIIZ string) for all 0<=i<=n */
|
||||
extern unsigned int scan_charsetnskip(const char *in,const char *charset,unsigned int limit) __pure__;
|
||||
extern unsigned long scan_charsetnskip(const char *in,const char *charset,unsigned long limit) __pure__;
|
||||
|
||||
/* return the highest integer n<=limit so that in[i] is not element of
|
||||
* charset (ASCIIZ string) for all 0<=i<=n */
|
||||
extern unsigned int scan_noncharsetnskip(const char *in,const char *charset,unsigned int limit) __pure__;
|
||||
extern unsigned long scan_noncharsetnskip(const char *in,const char *charset,unsigned long limit) __pure__;
|
||||
|
||||
/* try to parse ASCII GMT date; does not understand time zones. */
|
||||
/* example dates:
|
||||
|
@ -4,7 +4,7 @@ scan_charsetnskip \- skip characters from set
|
||||
.SH SYNTAX
|
||||
.B #include <scan.h>
|
||||
|
||||
int \fBscan_charsetnskip\fP(const char* \fIsrc\fR, const char* \fIcharset\fR, unsigned int* \fIlimit\fR);
|
||||
long \fBscan_charsetnskip\fP(const char* \fIsrc\fR, const char* \fIcharset\fR, unsigned long* \fIlimit\fR);
|
||||
.SH DESCRIPTION
|
||||
scan_charsetnskip returns the length of the maximum prefix of \fIsrc\fR
|
||||
that consists solely of characters that occur in \fIcharset\fR (up to
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "scan.h"
|
||||
#include <ctype.h>
|
||||
|
||||
unsigned int scan_charsetnskip(const char *s,const char *charset,unsigned int limit) {
|
||||
unsigned long scan_charsetnskip(const char *s,const char *charset,unsigned long limit) {
|
||||
register const char *t=s;
|
||||
register const char *u=t+limit;
|
||||
register const char* i;
|
||||
|
@ -4,7 +4,7 @@ scan_noncharsetnskip \- skip characters not from set
|
||||
.SH SYNTAX
|
||||
.B #include <scan.h>
|
||||
|
||||
int \fBscan_noncharsetnskip\fP(const char* \fIsrc\fR, const char* \fIcharset\fR, unsigned int* \fIlimit\fR);
|
||||
long \fBscan_noncharsetnskip\fP(const char* \fIsrc\fR, const char* \fIcharset\fR, unsigned long* \fIlimit\fR);
|
||||
.SH DESCRIPTION
|
||||
scan_noncharsetnskip returns the length of the maximum prefix of \fIsrc\fR
|
||||
that consists solely of characters that do not occur in \fIcharset\fR
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "scan.h"
|
||||
#include <ctype.h>
|
||||
|
||||
unsigned int scan_noncharsetnskip(const char *s,const char *charset,unsigned int limit) {
|
||||
unsigned long scan_noncharsetnskip(const char *s,const char *charset,unsigned long limit) {
|
||||
register const char *t=s;
|
||||
register const char *u=t+limit;
|
||||
register const char* i;
|
||||
|
@ -4,7 +4,7 @@ scan_nonwhitenskip \- skip non-whitespace
|
||||
.SH SYNTAX
|
||||
.B #include <scan.h>
|
||||
|
||||
int \fBscan_nonwhitenskip\fP(const char *\fIsrc\fR,unsigned int *\fIlimit\fR);
|
||||
long \fBscan_nonwhitenskip\fP(const char *\fIsrc\fR,unsigned long *\fIlimit\fR);
|
||||
.SH DESCRIPTION
|
||||
scan_nonwhitenskip returns the length of the maximum prefix of \fIsrc\fR
|
||||
that consists solely of non-whitespace characters as defined by
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "scan.h"
|
||||
#include <ctype.h>
|
||||
|
||||
unsigned int scan_nonwhitenskip(const char *s,unsigned int limit) {
|
||||
unsigned long scan_nonwhitenskip(const char *s,unsigned long limit) {
|
||||
register const char *t=s;
|
||||
register const char *u=t+limit;
|
||||
while (t<u && !isspace(*t)) ++t;
|
||||
|
@ -4,7 +4,7 @@ scan_whitenskip \- skip whitespace
|
||||
.SH SYNTAX
|
||||
.B #include <scan.h>
|
||||
|
||||
int \fBscan_whitenskip\fP(const char *\fIsrc\fR,unsigned int *\fIlimit\fR);
|
||||
long \fBscan_whitenskip\fP(const char *\fIsrc\fR,unsigned long *\fIlimit\fR);
|
||||
.SH DESCRIPTION
|
||||
scan_whitenskip returns the length of the maximum prefix of \fIsrc\fR
|
||||
that consists solely of whitespace characters as defined by
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "scan.h"
|
||||
#include <ctype.h>
|
||||
|
||||
unsigned int scan_whitenskip(const char *s,unsigned int limit) {
|
||||
unsigned long scan_whitenskip(const char *s,unsigned long limit) {
|
||||
register const char *t=s;
|
||||
register const char *u=t+limit;
|
||||
while (t<u && isspace(*t)) ++t;
|
||||
|
10
str.h
10
str.h
@ -10,7 +10,7 @@
|
||||
|
||||
/* str_copy copies leading bytes from in to out until \0.
|
||||
* return number of copied bytes. */
|
||||
extern unsigned int str_copy(char *out,const char *in);
|
||||
extern unsigned long str_copy(char *out,const char *in);
|
||||
|
||||
/* str_diff returns negative, 0, or positive, depending on whether the
|
||||
* string a[0], a[1], ..., a[n]=='\0' is lexicographically smaller than,
|
||||
@ -25,21 +25,21 @@ extern int str_diff(const char *a,const char *b) __pure__;
|
||||
* If the strings are different, str_diffn does not read bytes past the
|
||||
* first difference. The strings will be considered equal if the first
|
||||
* limit characters match. */
|
||||
extern int str_diffn(const char *a,const char *b,unsigned int limit) __pure__;
|
||||
extern int str_diffn(const char *a,const char *b,unsigned long limit) __pure__;
|
||||
|
||||
#ifdef __dietlibc__
|
||||
#include <string.h>
|
||||
#define str_len(foo) strlen(foo)
|
||||
#else
|
||||
/* str_len returns the index of \0 in s */
|
||||
extern unsigned int str_len(const char *s) __pure__;
|
||||
extern unsigned long str_len(const char *s) __pure__;
|
||||
#endif
|
||||
|
||||
/* str_chr returns the index of the first occurance of needle or \0 in haystack */
|
||||
extern unsigned int str_chr(const char *haystack,char needle) __pure__;
|
||||
extern unsigned long str_chr(const char *haystack,char needle) __pure__;
|
||||
|
||||
/* str_rchr returns the index of the last occurance of needle or \0 in haystack */
|
||||
extern unsigned int str_rchr(const char *haystack,char needle) __pure__;
|
||||
extern unsigned long str_rchr(const char *haystack,char needle) __pure__;
|
||||
|
||||
/* str_start returns 1 if the b is a prefix of a, 0 otherwise */
|
||||
extern int str_start(const char *a,const char *b) __pure__;
|
||||
|
@ -4,7 +4,7 @@ str_chr \- find character in ASCIIZ string
|
||||
.SH SYNTAX
|
||||
.B #include <str.h>
|
||||
|
||||
extern int \fBstr_chr\fP(const char* \fIhaystack\fR,char \fIneedle\fR);
|
||||
extern long \fBstr_chr\fP(const char* \fIhaystack\fR,char \fIneedle\fR);
|
||||
.SH DESCRIPTION
|
||||
str_chr returns the index of the first occurrance of \fIneedle\fR or \\0 in
|
||||
\fIstring\fR.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "str.h"
|
||||
|
||||
unsigned int str_chr(const char *in, char needle) {
|
||||
unsigned long str_chr(const char *in, char needle) {
|
||||
register const char* t=in;
|
||||
register const char c=needle;
|
||||
for (;;) {
|
||||
|
@ -4,7 +4,7 @@ str_copy \- copy an ASCIIZ string
|
||||
.SH SYNTAX
|
||||
.B #include <str.h>
|
||||
|
||||
extern int \fBstr_copy\fP(char* \fIout\fR,const char* \fIin\fR);
|
||||
extern long \fBstr_copy\fP(char* \fIout\fR,const char* \fIin\fR);
|
||||
.SH DESCRIPTION
|
||||
str_copy copies the leading bytes of \fIin\fR to \fIout\fR up to and
|
||||
including the first occurrance of \\0.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "str.h"
|
||||
|
||||
unsigned int str_copy(char *out,const char *in) {
|
||||
unsigned long str_copy(char *out,const char *in) {
|
||||
register char* s=out;
|
||||
register const char* t=in;
|
||||
for (;;) {
|
||||
|
@ -4,7 +4,7 @@ str_diffn \- compare two ASCIIZ strings
|
||||
.SH SYNTAX
|
||||
.B #include <str.h>
|
||||
|
||||
extern int \fBstr_diffn\fP(const char* \fIa\fR,const char* \fIb\fR,unsigned int \fIlimit\fR);
|
||||
extern int \fBstr_diffn\fP(const char* \fIa\fR,const char* \fIb\fR,unsigned long \fIlimit\fR);
|
||||
.SH DESCRIPTION
|
||||
\fBstr_diffn\fR returns negative, 0, or positive, depending on whether the
|
||||
string \fIa\fR[0], \fIa\fR[1], ..., \fIa\fR[n]=='\\0' is
|
||||
|
@ -5,7 +5,7 @@
|
||||
* equal to, or greater than the string b[0], b[1], ..., b[m-1]=='\0'.
|
||||
* When the strings are different, str_diff does not read bytes past the
|
||||
* first difference. */
|
||||
int str_diffn(const char* a, const char* b, unsigned int limit) {
|
||||
int str_diffn(const char* a, const char* b, unsigned long limit) {
|
||||
register const char* s=a;
|
||||
register const char* t=b;
|
||||
register const char* u=t+limit;
|
||||
|
@ -4,7 +4,7 @@ str_len \- find length of ASCIIZ string
|
||||
.SH SYNTAX
|
||||
.B #include <str.h>
|
||||
|
||||
extern int \fBstr_len\fP(const char* \fIstring\fR);
|
||||
extern long \fBstr_len\fP(const char* \fIstring\fR);
|
||||
.SH DESCRIPTION
|
||||
str_len returns the index of the first occurrance of \\0 in
|
||||
\fIstring\fR.
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
#ifdef __dietlibc__
|
||||
#undef str_len
|
||||
unsigned int str_len(const char* in) __attribute__((alias("strlen")));
|
||||
unsigned long str_len(const char* in) __attribute__((alias("strlen")));
|
||||
#else
|
||||
unsigned int str_len(const char* in) {
|
||||
unsigned long str_len(const char* in) {
|
||||
register const char* t=in;
|
||||
for (;;) {
|
||||
if (!*t) break; ++t;
|
||||
|
@ -4,7 +4,7 @@ str_rchr \- find character in ASCIIZ string
|
||||
.SH SYNTAX
|
||||
.B #include <str.h>
|
||||
|
||||
extern int \fBstr_rchr\fP(const char* \fIhaystack\fR,char \fIneedle\fR);
|
||||
extern long \fBstr_rchr\fP(const char* \fIhaystack\fR,char \fIneedle\fR);
|
||||
.SH DESCRIPTION
|
||||
str_rchr returns the index of the last occurrance of needle or the first
|
||||
occurrance of \\0 in \fIstring\fR.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "str.h"
|
||||
|
||||
unsigned int str_rchr(const char *in, char needle) {
|
||||
unsigned long str_rchr(const char *in, char needle) {
|
||||
register const char* t=in;
|
||||
register const char c=needle;
|
||||
register const char* found=0;
|
||||
|
13
test/array.c
Normal file
13
test/array.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <assert.h>
|
||||
#include "array.h"
|
||||
#include "byte.h"
|
||||
|
||||
main() {
|
||||
static array x,y;
|
||||
array_cats(&x,"fnord");
|
||||
array_cats(&y,"foobar");
|
||||
array_cat(&x,&y);
|
||||
array_fail(&y);
|
||||
array_cat(&y,&x);
|
||||
assert(byte_equal(x.p,11,"fnordfoobar"));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user