diff --git a/CHANGES b/CHANGES index 64322dc..4a2a3f1 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,7 @@ 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 + add array API from http://cr.yp.to/lib/array.html 0.15: man page update (document stralloc return values) diff --git a/array/array_allocate.3 b/array/array_allocate.3 new file mode 100644 index 0000000..2a13c0a --- /dev/null +++ b/array/array_allocate.3 @@ -0,0 +1,51 @@ +.TH array_allocate 3 +.SH NAME +array_allocate \- make sure array has at least n elements allocated +.SH SYNTAX +.B #include + +void* \fBarray_allocate\fP(array* \fIx\fR, uint64 \fImembersize\fR, int64 \fIpos\fR); + + array \fIx\fR; + int64 \fIpos\fR; + \fIt\fR* p = array_allocate(&\fIx\fR,sizeof(\fIt\fR),\fIpos\fR); + +.SH DESCRIPTION +array_allocate makes sure that enough bytes are allocated in \fIx\fR for +at least \fIpos\fR+1 objects of type \fIt\fR. (The size of \fIt\fR must +be positive; otherwise the effects are undefined.) If not enough bytes +are allocated (or \fIx\fR is unallocated), array_allocate allocates more +bytes, moving the dynamically allocated region if necessary. +array_allocate often allocates somewhat more bytes than necessary, to +save time later. + +array_allocate then makes sure that the number of bytes initialized +covers at least those \fIpos\fR+1 objects. If not enough bytes are +initialized, array_allocate initializes more bytes (setting them to 0), +up to exactly the end of the \fIpos\fR+1st object. + +array_allocate then returns a pointer to the \fIpos\fR+1st object; i.e., +object number \fIpos\fR, with objects numbered starting at 0. This +pointer can be used to change or inspect the object. The pointer can +continue to be used through subsequent calls to array_get, array_start, +array_length, and array_bytes, but it must not be used after any other +operations on this array. + +If something goes wrong, array_allocate returns 0, setting \fBerrno\fR +appropriately, without touching \fIx\fR. In particular, array_allocate +returns 0 if + +.sp 1 +.IP \(bu +\fIx\fR has failed, or +.IP \(bu +\fIpos\fR is negative, or +.IP \(bu +not enough memory is available. +.PP + +array_allocate does \fInot\fR change \fIx\fR to have failed; if you want +to do that, use array_fail. + +.SH "SEE ALSO" +array_get(3), array_start(3), array_fail(3) diff --git a/array/array_bytes.3 b/array/array_bytes.3 new file mode 100644 index 0000000..f6cb400 --- /dev/null +++ b/array/array_bytes.3 @@ -0,0 +1,19 @@ +.TH array_bytes 3 +.SH NAME +array_bytes \- get number of allocated members in array +.SH SYNTAX +.B #include + +int64 \fBarray_bytes\fP(array* \fIx\fR); + + array \fIx\fR; + int64 bytes = array_bytes(&\fIx\fR); + +.SH DESCRIPTION +array_bytes returns the number of initialized bytes in \fIx\fR, without +regard to \fIt\fR. + +If \fIx\fR is unallocated, array_length and array_bytes return 0. + +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_length(3) diff --git a/array/array_cat.3 b/array/array_cat.3 new file mode 100644 index 0000000..c3e4fc3 --- /dev/null +++ b/array/array_cat.3 @@ -0,0 +1,26 @@ +.TH array_cat 3 +.SH NAME +array_cat \- append one array to another +.SH SYNTAX +.B #include + +void \fBarray_cat\fP(array* \fIx\fR,array* \fIy\fR); + + array \fIx\fR; + array \fIy\fR; + array_cat(&\fIx\fR,&\fIy\fR); + +.SH DESCRIPTION +array_cat appends \fIy\fR to \fIx\fR; i.e., it changes \fIx\fR, +allocating more space if necessary, so that the initialized bytes in +\fIx\fR are the previously initialized bytes in \fIx\fR followed by a +copy of the initialized bytes in \fIy\fR. + +If \fIx\fR has failed, array_cat has no effect. + +If \fIy\fR has failed, array_cat switches \fIx\fR to have failed. + +If not enough memory is available, array_cat switches \fIx\fR to have failed. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_reset(3), +array_catb(3), array_cats(3), array_cats0(3), array_cate(3) diff --git a/array/array_cat0.3 b/array/array_cat0.3 new file mode 100644 index 0000000..863f9cc --- /dev/null +++ b/array/array_cat0.3 @@ -0,0 +1,18 @@ +.TH array_cat0 3 +.SH NAME +array_cat0 \- append 0 byte to an array +.SH SYNTAX +.B #include + +void \fBarray_cat0\fP(array* \fIx\fR); + + array \fIx\fR; + array_cat0(&\fIx\fR); + +.SH DESCRIPTION +array_cat0 appends a 0-byte to the array \fIx\fR. + +array_cat0 handles failure in the same way as array_cat. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_reset(3), +array_cat(3), array_catb(3), array_cats(3), array_cats0(3), array_cate(3) diff --git a/array/array_catb.3 b/array/array_catb.3 new file mode 100644 index 0000000..d31742d --- /dev/null +++ b/array/array_catb.3 @@ -0,0 +1,20 @@ +.TH array_catb 3 +.SH NAME +array_catb \- append bytes to an array +.SH SYNTAX +.B #include + +void \fBarray_catb\fP(array* \fIx\fR,const char* \fIy\fR,int64 \fIlen\fR); + + array \fIx\fR; + const char* \fIy\fR; + int64 \fIlen\fR; + array_catb(&\fIx\fR,\fIy\fR,\fIlen\fR); + +.SH DESCRIPTION +array_catb appends the bytes \fIy\fR[0], \fIy\fR[1], ..., +\fIy\fR[\fIlen\fR-1] to the array \fIx\fR. It handles failure in the +same way as array_cat. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_reset(3), +array_cat(3), array_cats(3), array_cats0(3), array_cate(3) diff --git a/array/array_cate.3 b/array/array_cate.3 new file mode 100644 index 0000000..caee793 --- /dev/null +++ b/array/array_cate.3 @@ -0,0 +1,22 @@ +.TH array_cate 3 +.SH NAME +array_cate \- append subset of one array to another array +.SH SYNTAX +.B #include + +void \fBarray_cate\fP(array* \fIx\fR,array* \fIy\fR, int64 \fIpos\fR,int64 \fIstop\fR); + + array \fIx\fR; + array \fIy\fR; + int64 \fIpos\fR; + int64 \fIstop\fR; + array_cate(&\fIx\fR,\fIy\fR,\fIpos\fR,\fIstop\fR); + +.SH DESCRIPTION +array_cate is like array_cat, but uses only byte positions \fIpos\fR +through \fIstop\fR-1 in \fIy\fR. It fails if \fIpos\fR negative, or if +\fIstop\fR is smaller than \fIpos\fR, or if the number of initialized +bytes in \fIy\fR is smaller than \fIstop\fR. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_reset(3), +array_cat(3), array_cats(3), array_cats0(3), array_cate(3) diff --git a/array/array_cats.3 b/array/array_cats.3 new file mode 100644 index 0000000..cb9f8a9 --- /dev/null +++ b/array/array_cats.3 @@ -0,0 +1,20 @@ +.TH array_cats 3 +.SH NAME +array_cats \- append C string to an array +.SH SYNTAX +.B #include + +void \fBarray_cats\fP(array* \fIx\fR,const char* \fIy\fR); + + array \fIx\fR; + array_cats(&\fIx\fR,"fnord"); + +.SH DESCRIPTION +array_cats appends the contents of the 0-terminated string \fIy\fR, not +including the terminating 0 byte, to the array \fIx\fR. + +array_cats handles failure in the same way as array_cat. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_reset(3), +array_cat(3), array_catb(3), array_cats0(3), array_cate(3), +array_cat0(3) diff --git a/array/array_cats0.3 b/array/array_cats0.3 new file mode 100644 index 0000000..400cb22 --- /dev/null +++ b/array/array_cats0.3 @@ -0,0 +1,19 @@ +.TH array_cats0 3 +.SH NAME +array_cats0 \- append C string to an array +.SH SYNTAX +.B #include + +void \fBarray_cats0\fP(array* \fIx\fR,const char* \fIy\fR); + + array \fIx\fR; + array_cats0(&\fIx\fR,"fnord"); + +.SH DESCRIPTION +array_cats0 appends the contents of the 0-terminated string \fIy\fR, +including the terminating 0 byte, to the array \fIx\fR. + +array_cats0 handles failure in the same way as array_cat. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_reset(3), +array_cat(3), array_catb(3), array_cats(3), array_cate(3) diff --git a/array/array_equal.3 b/array/array_equal.3 new file mode 100644 index 0000000..1adf0f1 --- /dev/null +++ b/array/array_equal.3 @@ -0,0 +1,32 @@ +.TH array_equal 3 +.SH NAME +array_equal \- compare two arrays for equality +.SH SYNTAX +.B #include + +int \fBarray_equal\fP(array* \fIx\fR,array* \fIy\fR); + + array \fIx\fR; + array \fIy\fR; + array_equal(&\fIx\fR,&\fIy\fR); + +.SH DESCRIPTION +array_equal returns nonzero if x and y have the same contents: i.e., + +.sp 1 +.IP \(bu +\fIx\fR and \fIy\fR are both unallocated; or +.IP \(bu +\fIx\fR is unallocated, \fIy\fR is allocated, and \fIy\fR has no +initialized bytes; or +.IP \(bu +\fIx\fR is allocated, \fIy\fR is unallocated, and \fIx\fR has no +initialized bytes; or +.IP \(bu +\fIx\fR and \fIy\fR are both allocated and have the same sequence of +initialized bytes. +.PP + +Otherwise it returns 0. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_reset(3) diff --git a/array/array_fail.3 b/array/array_fail.3 new file mode 100644 index 0000000..f8fc888 --- /dev/null +++ b/array/array_fail.3 @@ -0,0 +1,21 @@ +.TH array_fail 3 +.SH NAME +array_fail \- switch array to have failed +.SH SYNTAX +.B #include + +void \fBarray_fail\fP(array* \fIx\fR); + + array \fIx\fR; + array_fail(&\fIx\fR); + +.SH DESCRIPTION +If \fIx\fR is allocated, array_fail frees the region that \fIx\fR points +to, and switches \fIx\fR to have failed. + +If \fIx\fR is unallocated, array_fail simply switches \fIx\fR to have +failed. + +If \fIx\fR has already failed, array_fail has no effect. +.SH "SEE ALSO" +array_allocate(3), array_reset(3) diff --git a/array/array_get.3 b/array/array_get.3 new file mode 100644 index 0000000..747a0d4 --- /dev/null +++ b/array/array_get.3 @@ -0,0 +1,20 @@ +.TH array_get 3 +.SH NAME +array_get \- get pointer to nth element in array +.SH SYNTAX +.B #include + +void* \fBarray_get\fP(array* \fIx\fR, uint64 \fImembersize\fR, int64 \fIpos\fR); + + array \fIx\fR; + int64 \fIpos\fR; + \fIt\fR* p = array_get(&\fIx\fR,sizeof(\fIt\fR),\fIpos\fR); + +.SH DESCRIPTION +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 \fIx\fR is unallocated, for example, or if fewer than +(\fIpos\fR+1)*sizeof(\fIt\fR) bytes are initialized. + +.SH "SEE ALSO" +array_allocate(3), array_fail(3), array_start(3) diff --git a/array/array_length.3 b/array/array_length.3 new file mode 100644 index 0000000..8fea5bf --- /dev/null +++ b/array/array_length.3 @@ -0,0 +1,20 @@ +.TH array_length 3 +.SH NAME +array_length \- get number of allocated members in array +.SH SYNTAX +.B #include + +int64 \fBarray_length\fP(array* \fIx\fR,uint64 \fImembersize\fR); + + array \fIx\fR; + int64 members = array_length(&\fIx\fR,sizeof(\fIt\fR)); + +.SH DESCRIPTION +array_length returns the number of initialized bytes in \fIx\fR, divided +by the size of \fIt\fR. In other words, array_get will succeed for +positions 0 through array_length-1; it will fail for position +array_length. + +If \fIx\fR is unallocated, array_length and array_bytes return 0. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_bytes(3) diff --git a/array/array_reset.3 b/array/array_reset.3 new file mode 100644 index 0000000..3a5f87d --- /dev/null +++ b/array/array_reset.3 @@ -0,0 +1,23 @@ +.TH array_reset 3 +.SH NAME +array_reset \- deallocate array +.SH SYNTAX +.B #include + +void \fBarray_reset\fP(array* \fIx\fR); + + array \fIx\fR; + array_reset(&\fIx\fR); + +.SH DESCRIPTION +If \fIx\fR is allocated, array_reset frees the region that \fIx\fR +points to, and switches \fIx\fR to being unallocated. + +If \fIx\fR x has failed, array_reset simply switches \fIx\fR to being +unallocated. + +If \fIx\fR x is unallocated, array_reset has no effect. + +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_trunc(3), +array_truncate(3) diff --git a/array/array_start.3 b/array/array_start.3 new file mode 100644 index 0000000..3bd8cb5 --- /dev/null +++ b/array/array_start.3 @@ -0,0 +1,16 @@ +.TH array_start 3 +.SH NAME +array_start \- get pointer to first element in array +.SH SYNTAX +.B #include + +void* \fBarray_start\fP(array* \fIx\fR); + + array \fIx\fR; + \fIt\fR* \fIp\fR = array_start(&\fIx\fR); + +.SH DESCRIPTION +array_start is the same as array_get with \fIpos\fR equal to 0. + +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3) diff --git a/array/array_trunc.3 b/array/array_trunc.3 new file mode 100644 index 0000000..b718454 --- /dev/null +++ b/array/array_trunc.3 @@ -0,0 +1,16 @@ +.TH array_trunc 3 +.SH NAME +array_trunc \- reduce number of initialized bytes +.SH SYNTAX +.B #include + +void \fBarray_trunc\fP(array* \fIx\fR); + + array \fIx\fR; + array_trunc(&\fIx\fR); + +.SH DESCRIPTION +array_trunc is the same as array_truncate with \fIlen\fR equal to 0. +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_truncate(3), +array_reset(3) diff --git a/array/array_truncate.3 b/array/array_truncate.3 new file mode 100644 index 0000000..7918a1e --- /dev/null +++ b/array/array_truncate.3 @@ -0,0 +1,24 @@ +.TH array_truncate 3 +.SH NAME +array_truncate \- reduce number of initialized bytes +.SH SYNTAX +.B #include + +void \fBarray_truncate\fP(array* \fIx\fR, uint64 \fImembersize\fR, int64 \fIlen\fR); + + array_truncate(&\fIx\fR,sizeof(\fIt\fR),\fIlen\fR); + +.SH DESCRIPTION +array_truncate reduces the number of initialized bytes in \fIx\fR to +exactly \fIlen\fR*sizeof(\fIt\fR). If the number of initialized bytes +was already this small (or smaller), array_truncate has no effect. If +\fIlen\fR is negative, array_truncate has no effect. If \fIx\fR is +unallocated, array_truncate has no effect. If \fIx\fR has failed, +array_truncate has no effect. + +array_truncate does not change the allocation in \fIx\fR. If you want to free +the memory used by \fIx\fR, use array_reset. + +.SH "SEE ALSO" +array_allocate(3), array_get(3), array_fail(3), array_trunc(3), +array_reset(3)