commit 3083708670c7d68411a1d0df96d273b4e1cf5219 Author: leitner Date: Fri Feb 2 17:54:47 2001 +0000 Initial revision diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..946b852 --- /dev/null +++ b/CHANGES @@ -0,0 +1,30 @@ +0.6: + changed name to libowfat + +0.5: + made subdirectories for the different libraries. + moved the sources into the corresponding subdirectory. + imported my man pages from libdjb. + removed fmt_int.c and fmt_uint.c (they are macros in fmt.h). + corrected comment in open.h for open_excl. + wrote new man pages for fmt_double, scan_double, the sign fmt_ and + scan_ routines, the whitespace and charset scan_ routines, and the + str and stralloc routines. + +0.4: + implemented stralloc. + +0.3: + implemented uint16, uint32 and uint64. The header files try to + define shortcut endianness conversion routines that do not convert + anything. + implemented open (I hope I got open_excl right, I couldn't find an + implementationen). + +0.2: + implemented the scan, fmt and str interfaces. + added adapted fmt_double and scan_double from diet libc. + +0.1: + initial release. + implemented the byte interface. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..35664a7 --- /dev/null +++ b/Makefile @@ -0,0 +1,50 @@ +all: t byte.a fmt.a scan.a str.a uint.a open.a stralloc.a unix.a socket.a + +VPATH=str:byte:fmt:scan:uint:open:stralloc:unix:socket + +CC=egcc +#CFLAGS=-I. -pipe -Wall -Os -march=pentiumpro -fomit-frame-pointer -fschedule-insns2 -Wall +CFLAGS=-I. -I../dietlibc/include -pipe -Wall -g #-Os -march=athlon -mcpu=athlon -fomit-frame-pointer -fschedule-insns2 +#CFLAGS=-I../dietlibc/include -I. -pipe -Wall -Os -march=pentiumpro -mcpu=athlon -fomit-frame-pointer -fschedule-insns2 -Wall +#CFLAGS=-I../dietlibc/include -pipe -Os -march=pentiumpro -mcpu=pentiumpro -fomit-frame-pointer -fschedule-insns2 -Wall + +BYTE_OBJS=$(patsubst byte/%.c,%.o,$(wildcard byte/*.c)) +FMT_OBJS=$(patsubst fmt/%.c,%.o,$(wildcard fmt/*.c)) +SCAN_OBJS=$(patsubst scan/%.c,%.o,$(wildcard scan/*.c)) +STR_OBJS=$(patsubst str/%.c,%.o,$(wildcard str/*.c)) +UINT_OBJS=$(patsubst uint/%.c,%.o,$(wildcard uint/*.c)) +OPEN_OBJS=$(patsubst open/%.c,%.o,$(wildcard open/*.c)) +STRA_OBJS=$(patsubst stralloc/%.c,%.o,$(wildcard stralloc/*.c)) +UNIX_OBJS=$(patsubst unix/%.c,%.o,$(wildcard unix/*.c)) +SOCKET_OBJS=$(patsubst socket/%.c,%.o,$(wildcard socket/*.c)) + +$(BYTE_OBJS): byte.h +$(FMT_OBJS): fmt.h +$(SCAN_OBJS): scan.h +$(STR_OBJS): str.h +$(UINT_OBJS): uint16.h uint32.h +$(STRA_OBJS): stralloc.h +$(SOCKET_OBJS): socket.h + +byte.a: $(BYTE_OBJS) +fmt.a: $(FMT_OBJS) +scan.a: $(SCAN_OBJS) +str.a: $(STR_OBJS) +uint.a: $(UINT_OBJS) +open.a: $(OPEN_OBJS) +stralloc.a: $(STRA_OBJS) +unix.a: $(UNIX_OBJS) +socket.a: $(SOCKET_OBJS) + +%.a: + ar cr $@ $^ + +t: t.o socket.a stralloc.a str.a fmt.a scan.a str.a uint.a open.a byte.a + gcc -g -o $@ $^ + +.PHONY: clean tar +clean: + rm -f *.o *.a core t + +tar: + cd .. && tar cIf libowfat.tar.bz2 libowfat diff --git a/byte.h b/byte.h new file mode 100644 index 0000000..c3b3f02 --- /dev/null +++ b/byte.h @@ -0,0 +1,41 @@ +#ifndef BYTE_H +#define BYTE_H + +#include + +#ifndef __pure__ +#define __pure__ +#endif +#ifndef __THROW +#define __THROW +#endif + +/* 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) __THROW __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) __THROW __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) __THROW; + +/* 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) __THROW; + +/* 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) __THROW __pure__; + +/* byte_zero sets the bytes out[0], out[1], ..., out[len-1] to 0 */ +void byte_zero(void* out, unsigned len) __THROW; + +#define byte_equal(s,n,t) (!byte_diff((s),(n),(t))) + +#endif diff --git a/byte/byte_chr.3 b/byte/byte_chr.3 new file mode 100644 index 0000000..3b7bd52 --- /dev/null +++ b/byte/byte_chr.3 @@ -0,0 +1,19 @@ +.TH byte_chr 3 +.SH NAME +byte_chr \- search for a byte in a string +.SH SYNTAX +.B #include + +int \fBbyte_chr\fP(const char *\fIhaystack\fR,unsigned int \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. + +If no such integer exists, byte_chr returns \fIlen\fR. + +byte_chr may read all bytes \fIone\fR[0], \fIone\fR[1], ..., +\fIone\fR[\fIlen\fR-1], even if not all the bytes are relevant to the +answer. + +.SH "SEE ALSO" +byte_rchr(3) diff --git a/byte/byte_chr.c b/byte/byte_chr.c new file mode 100644 index 0000000..c31c567 --- /dev/null +++ b/byte/byte_chr.c @@ -0,0 +1,16 @@ +#include "byte.h" + +/* 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) { + register char c=needle; + register const char* s=haystack; + register const char* t=s+len; + for (;;) { + if (s==t) break; if (*s==c) break; ++s; + if (s==t) break; if (*s==c) break; ++s; + if (s==t) break; if (*s==c) break; ++s; + if (s==t) break; if (*s==c) break; ++s; + } + return s-(const char*)haystack; +} diff --git a/byte/byte_copy.3 b/byte/byte_copy.3 new file mode 100644 index 0000000..6a98506 --- /dev/null +++ b/byte/byte_copy.3 @@ -0,0 +1,14 @@ +.TH byte_copy 3 +.SH NAME +byte_copy \- copy a string +.SH SYNTAX +.B #include + +void \fBbyte_copy\fP(char *\fIout\fR,unsigned int \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 +\fIout\fR[\fIlen\fR-1]. + +.SH "SEE ALSO" +byte_copyr(3) diff --git a/byte/byte_copy.c b/byte/byte_copy.c new file mode 100644 index 0000000..1493ae6 --- /dev/null +++ b/byte/byte_copy.c @@ -0,0 +1,15 @@ +#include "byte.h" + +/* 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) { + register char* s=out; + register const char* t=in; + register const char* u=in+len; + for (;;) { + if (t==u) break; *s=*t; ++s; ++t; + if (t==u) break; *s=*t; ++s; ++t; + if (t==u) break; *s=*t; ++s; ++t; + if (t==u) break; *s=*t; ++s; ++t; + } +} diff --git a/byte/byte_copyr.3 b/byte/byte_copyr.3 new file mode 100644 index 0000000..a60d945 --- /dev/null +++ b/byte/byte_copyr.3 @@ -0,0 +1,14 @@ +.TH byte_copyr 3 +.SH NAME +byte_copyr \- copy a string +.SH SYNTAX +.B #include + +void \fBbyte_copyr\fP(char *\fIout\fR,unsigned int \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 +\fIin\fR[0] to \fIout\fR[0]. + +.SH "SEE ALSO" +byte_copy(3) diff --git a/byte/byte_copyr.c b/byte/byte_copyr.c new file mode 100644 index 0000000..b9f804a --- /dev/null +++ b/byte/byte_copyr.c @@ -0,0 +1,15 @@ +#include "byte.h" + +/* 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) { + register char* s=out+len; + register const char* t=in; + register const char* u=t+len; + for (;;) { + if (t>=u) break; --u; --s; *s=*u; + if (t>=u) break; --u; --s; *s=*u; + if (t>=u) break; --u; --s; *s=*u; + if (t>=u) break; --u; --s; *s=*u; + } +} diff --git a/byte/byte_diff.3 b/byte/byte_diff.3 new file mode 100644 index 0000000..2115734 --- /dev/null +++ b/byte/byte_diff.3 @@ -0,0 +1,18 @@ +.TH byte_diff 3 +.SH NAME +byte_diff \- compare two strings +.SH SYNTAX +.B #include + +int \fBbyte_diff\fP(const char *\fIone\fR,unsigned int \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 +lexicographically smaller than, equal to, or greater than the string +\fIone\fR[0], \fIone\fR[1], ..., \fIone\fR[\fIlen\fR-1]. + +When the strings are different, byte_diff does not read bytes past the +first difference. + +.SH "SEE ALSO" +byte_equal(3) diff --git a/byte/byte_diff.c b/byte/byte_diff.c new file mode 100644 index 0000000..9dbd1a4 --- /dev/null +++ b/byte/byte_diff.c @@ -0,0 +1,21 @@ +#include "byte.h" + +/* byte_diff returns negative, 0, or positive, depending on whether the + * string one[0], one[1], ..., one[len-1] is lexicographically smaller + * 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) { + register const char* s=a; + register const char* t=b; + register const char* u=b+len; + register int j; + j=0; + for (;;) { + if (t==u) break; if ((j=(*s-*t))) break; ++s; ++t; + if (t==u) break; if ((j=(*s-*t))) break; ++s; ++t; + if (t==u) break; if ((j=(*s-*t))) break; ++s; ++t; + if (t==u) break; if ((j=(*s-*t))) break; ++s; ++t; + } + return j; +} diff --git a/byte/byte_equal.3 b/byte/byte_equal.3 new file mode 100644 index 0000000..3840c98 --- /dev/null +++ b/byte/byte_equal.3 @@ -0,0 +1,15 @@ +.TH byte_equal 3 +.SH NAME +byte_equal \- compare two strings +.SH SYNTAX +.B #include + +int \fBbyte_equal\fP(const char *\fIone\fR,unsigned int \fIlen\fR,const char *\fItwo\fR); +.SH DESCRIPTION +\fIbyte_equal\fR returns 1 if the strings are equal, 0 otherwise. + +When the strings are different, byte_equal does not read bytes past the +first difference. + +.SH "SEE ALSO" +byte_diff(3) diff --git a/byte/byte_rchr.3 b/byte/byte_rchr.3 new file mode 100644 index 0000000..9c28f2f --- /dev/null +++ b/byte/byte_rchr.3 @@ -0,0 +1,19 @@ +.TH byte_rchr 3 +.SH NAME +byte_rchr \- search for a byte in a string +.SH SYNTAX +.B #include + +int \fBbyte_rchr\fP(const char *\fIhaystack\fR,unsigned int \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. + +If no such integer exists, byte_chr returns \fIlen\fR. + +byte_rchr may read all bytes \fIone\fR[0], \fIone\fR[1], ..., +\fIone\fR[\fIlen\fR-1], even if not all the bytes are relevant to the +answer. + +.SH "SEE ALSO" +byte_chr(3) diff --git a/byte/byte_rchr.c b/byte/byte_rchr.c new file mode 100644 index 0000000..3b5b58c --- /dev/null +++ b/byte/byte_rchr.c @@ -0,0 +1,16 @@ +#include "byte.h" + +/* 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) { + register char c=needle; + register const char* s=haystack; + register const char* t=s+len; + for (;;) { + --t; if (s<=t) break; if (*t==c) break; + --t; if (s<=t) break; if (*t==c) break; + --t; if (s<=t) break; if (*t==c) break; + --t; if (s<=t) break; if (*t==c) break; + } + return t-s; +} diff --git a/byte/byte_zero.3 b/byte/byte_zero.3 new file mode 100644 index 0000000..f7c051e --- /dev/null +++ b/byte/byte_zero.3 @@ -0,0 +1,13 @@ +.TH byte_zero 3 +.SH NAME +byte_zero \- initialize a string +.SH SYNTAX +.B #include + +void \fBbyte_zero\fP(char *\fIout\fR,unsigned int \fIlen\fR); +.SH DESCRIPTION +\fIbyte_zero\fR sets \fIout\fR[0], \fIout\fR[1], ..., +\fIout\fR[\fIlen\fR-1] to 0. + +.SH "SEE ALSO" +byte_copy(3), byte_copyr(3) diff --git a/byte/byte_zero.c b/byte/byte_zero.c new file mode 100644 index 0000000..520b761 --- /dev/null +++ b/byte/byte_zero.c @@ -0,0 +1,13 @@ +#include "byte.h" + +/* byte_zero sets the bytes out[0], out[1], ..., out[len-1] to 0 */ +void byte_zero(void* out, unsigned len) { + register char* s=out; + register const char* t=s+len; + for (;;) { + if (s==t) break; *s=0; ++s; + if (s==t) break; *s=0; ++s; + if (s==t) break; *s=0; ++s; + if (s==t) break; *s=0; ++s; + } +} diff --git a/fmt.h b/fmt.h new file mode 100644 index 0000000..b190742 --- /dev/null +++ b/fmt.h @@ -0,0 +1,61 @@ +#ifndef FMT_H +#define FMT_H + +#include "str.h" + +#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ +#define FMT_8LONG 44 /* enough space to hold 2^128 - 1 in octal, plus \0 */ +#define FMT_XLONG 33 /* enough space to hold 2^128 - 1 in hexadecimal, plus \0 */ +#define FMT_LEN ((char *) 0) /* convenient abbreviation */ + +/* The formatting routines do not append \0! + * Use them like this: buf[fmt_ulong(buf,number)]=0; */ + +/* convert signed src integer -23 to ASCII '-','2','3', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_long(char *dest,signed long src) __THROW; + +/* convert unsigned src integer 23 to ASCII '2','3', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_ulong(char *dest,unsigned long src) __THROW; + +/* convert unsigned src integer 0x23 to ASCII '2','3', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_xlong(char *dest,unsigned long src) __THROW; + +/* convert unsigned src integer 023 to ASCII '2','3', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_8long(char *dest,unsigned long src) __THROW; + +#define fmt_uint(dest,src) fmt_ulong(dest,src) +#define fmt_int(dest,src) fmt_long(dest,src) +#define fmt_xint(dest,src) fmt_xlong(dest,src) +#define fmt_8int(dest,src) fmt_8long(dest,src) + +/* Like fmt_ulong, but prepend '0' while length is smaller than padto. + * Does not truncate! */ +unsigned int fmt_ulong0(char *,unsigned long src,unsigned int padto) __THROW; + +#define fmt_uint0(buf,src,padto) fmt_ulong0(buf,src,padto) + +/* convert src double 1.7 to ASCII '1','.','7', return length. + * If dest is not NULL, write result to dest */ +unsigned int fmt_double(char *dest, double d,int max,int prec) __THROW; + +/* if src is negative, write '-' and return 1. + * if src is positive, write '+' and return 1. + * otherwise return 0 */ +unsigned int fmt_plusminus(char *dest,int src) __THROW; + +/* if src is negative, write '-' and return 1. + * otherwise return 0. */ +unsigned int fmt_minus(char *dest,int src) __THROW; + +/* copy str to dest until \0 byte, return number of copied bytes. */ +unsigned int fmt_str(char *dest,const char *src) __THROW; + +/* 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) __THROW; + +#endif diff --git a/fmt/fmt_8long.3 b/fmt/fmt_8long.3 new file mode 100644 index 0000000..e068f2d --- /dev/null +++ b/fmt/fmt_8long.3 @@ -0,0 +1,20 @@ +.TH fmt_8long 3 +.SH NAME +fmt_8long \- write an octal ASCII representation of an unsigned long integer +.SH SYNTAX +.B #include + +unsigned int \fBfmt_8long\fP(char *\fIdest\fR,unsigned long \fIsource\fR); +.SH DESCRIPTION +fmt_8long writes an ASCII representation ('0' to '7', base 8) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written. + +fmt_8long does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_8long returns the +number of bytes it would have written. + +For convenience, fmt.h defines the integer FMT_8LONG to be big enough to +contain every possible fmt_8long output plus \\0. +.SH "SEE ALSO" +scan_8long(3) diff --git a/fmt/fmt_8long.c b/fmt/fmt_8long.c new file mode 100644 index 0000000..749832f --- /dev/null +++ b/fmt/fmt_8long.c @@ -0,0 +1,11 @@ +#include "fmt.h" + +unsigned int fmt_8long(char *dest,unsigned long i) { + register unsigned long len,tmp; + /* first count the number of bytes needed */ + for (len=1, tmp=i; tmp>7; ++len) tmp/=8; + if (dest) + for (tmp=i, dest+=len; tmp; tmp/=8) + *--dest = (tmp&7)+'0'; + return len; +} diff --git a/fmt/fmt_double.3 b/fmt/fmt_double.3 new file mode 100644 index 0000000..f243394 --- /dev/null +++ b/fmt/fmt_double.3 @@ -0,0 +1,20 @@ +.TH fmt_double 3 +.SH NAME +fmt_double \- write an ASCII representation of a double +.SH SYNTAX +.B #include + +unsigned int \fBfmt_double\fP(char *\fIdest\fR,double \fId\fR,int +\fImaxlen\fR,int \fIprec\fR); +.SH DESCRIPTION +fmt_double writes an ASCII representation ('0' to '9', base 10) of +\fId\fR to \fIdest\fR and returns the number of bytes written. No more +than \fImaxlen\fR bytes will be written. \fIprec\fR digits will be +written, using scientific notation if necessary. + +fmt_double does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_double returns the +number of bytes it would have written. +.SH "SEE ALSO" +scan_double(3) diff --git a/fmt/fmt_double.c b/fmt/fmt_double.c new file mode 100644 index 0000000..ca7a758 --- /dev/null +++ b/fmt/fmt_double.c @@ -0,0 +1,82 @@ +#include "fmt.h" + +unsigned int fmt_double(char *dest, double d,int maxlen,int prec) { + unsigned long long *x=(unsigned long long *)&d; + /* step 1: extract sign, mantissa and exponent */ + signed int s=*x>>63; + signed long e=((*x>>52)&((1<<11)-1))-1023; +/* unsigned long long m=*x & ((1ull<<52)-1); */ + /* step 2: exponent is base 2, compute exponent for base 10 */ + signed long e10=1+(long)(e*0.30102999566398119802); /* log10(2) */ + /* step 3: calculate 10^e10 */ + int i; + double tmp=10.0; + char *oldbuf=dest; + int initial=1; + int writeok=(dest!=0); + + if (s) { d=-d; if (writeok) *dest='-'; --maxlen; dest++; } + if ((i=e10)>=0) { + while (i>10) { tmp=tmp*1e10; i-=10; } + while (i>1) { tmp=tmp*10; --i; } + } else { + i=(e10=-e10); + while (i>10) { tmp=tmp*1e-10; i-=10; } + while (i>1) { tmp=tmp/10; --i; } + } + while (d/tmp<1) { + --e10; + tmp/=10.0; + } + /* step 4: see if precision is sufficient to display all digits */ + if (e10>prec) { + /* use scientific notation */ + int len=fmt_double(writeok?dest:0,d/tmp,maxlen,prec); + if (len==0) return 0; + maxlen-=len; dest+=len; + if (--maxlen>=0) { + if (writeok) *dest='e'; + ++dest; + } + for (len=1000; len>0; len/=10) { + if (e10>=len || !initial) { + if (--maxlen>=0) { + if (writeok) *dest=(e10/len)+'0'; + ++dest; + } + initial=0; + e10=e10%len; + } + } + if (maxlen>=0) return dest-oldbuf; + return 0; + } + /* step 5: loop through the digits, inserting the decimal point when + * appropriate */ + for (; prec>0; ) { + double tmp2=d/tmp; + char c; + d-=((int)tmp2*tmp); + c=((int)tmp2); + if ((!initial)||c) { + if (--maxlen>=0) { + initial=0; + if (writeok) *dest=c+'0'; + ++dest; + } else + return 0; + --prec; + } + if (tmp>0.5 && tmp<1.5) { + tmp=1e-1; + initial=0; + if (--maxlen>=0) { + if (writeok) *dest='.'; + ++dest; + } else + return 0; + } else + tmp/=10.0; + } + return dest-oldbuf; +} diff --git a/fmt/fmt_long.3 b/fmt/fmt_long.3 new file mode 100644 index 0000000..e918383 --- /dev/null +++ b/fmt/fmt_long.3 @@ -0,0 +1,20 @@ +.TH fmt_long 3 +.SH NAME +fmt_long \- write an ASCII representation of a long integer +.SH SYNTAX +.B #include + +unsigned int \fBfmt_long\fP(char *\fIdest\fR,unsigned int \fIsource\fR); +.SH DESCRIPTION +fmt_long writes an ASCII representation ('-' and '0' to '9', base 10) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written. + +fmt_long does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_long returns the number +of bytes it would have written. + +For convenience, fmt.h defines the integer FMT_ULONG to be big enough to +contain every possible fmt_ulong output plus \\0. +.SH "SEE ALSO" +scan_long(3) diff --git a/fmt/fmt_long.c b/fmt/fmt_long.c new file mode 100644 index 0000000..707b3c8 --- /dev/null +++ b/fmt/fmt_long.c @@ -0,0 +1,9 @@ +#include "fmt.h" + +unsigned int fmt_long(char *dest,long int i) { + if (i<0) { + if (dest) *dest='-'; + return fmt_ulong(dest+1,-i); + } else + return fmt_ulong(dest,i); +} diff --git a/fmt/fmt_minus.3 b/fmt/fmt_minus.3 new file mode 100644 index 0000000..2c439d6 --- /dev/null +++ b/fmt/fmt_minus.3 @@ -0,0 +1,17 @@ +.TH fmt_minus 3 +.SH NAME +fmt_minus \- write '-' for negative integers +.SH SYNTAX +.B #include + +unsigned int \fBfmt_minus\fP(char *\fIdest\fR,signed int \fIsource\fR); +.SH DESCRIPTION +fmt_minus writes '-' if \fIsource\fR is negative, nothing otherwise. It +returns the number of bytes written. + +fmt_minus does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_minus returns the number +of bytes it would have written. +.SH "SEE ALSO" +fmt_plusminus(3), scan_plusminus(3) diff --git a/fmt/fmt_minus.c b/fmt/fmt_minus.c new file mode 100644 index 0000000..a227e39 --- /dev/null +++ b/fmt/fmt_minus.c @@ -0,0 +1,9 @@ +#include "fmt.h" + +unsigned int fmt_minus(char *dest,int i) { + if (i<0) { + if (dest) *dest='-'; + return 1; + } + return 0; +} diff --git a/fmt/fmt_plusminus.3 b/fmt/fmt_plusminus.3 new file mode 100644 index 0000000..de18c2b --- /dev/null +++ b/fmt/fmt_plusminus.3 @@ -0,0 +1,18 @@ +.TH fmt_plusminus 3 +.SH NAME +fmt_plusminus \- write '+' or '-' +.SH SYNTAX +.B #include + +unsigned int \fBfmt_plusminus\fP(char *\fIdest\fR,signed int \fIsource\fR); +.SH DESCRIPTION +fmt_plusminus writes '-' to \fIdest\fR if \fIsource\fR is negative, '+' +if \fIsource\fR is positive, nothing otherwise. It returns the number +of bytes written. + +fmt_plusminus does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_plusminus returns the number +of bytes it would have written. +.SH "SEE ALSO" +fmt_minus(3), scan_plusminus(3) diff --git a/fmt/fmt_plusminus.c b/fmt/fmt_plusminus.c new file mode 100644 index 0000000..02e87b8 --- /dev/null +++ b/fmt/fmt_plusminus.c @@ -0,0 +1,9 @@ +#include "fmt.h" + +unsigned int fmt_plusminus(char *dest,int i) { + if (i) { + if (dest) *dest=(i>=0?'+':'-'); + return 1; + } + return 0; +} diff --git a/fmt/fmt_str.3 b/fmt/fmt_str.3 new file mode 100644 index 0000000..5ba5949 --- /dev/null +++ b/fmt/fmt_str.3 @@ -0,0 +1,18 @@ +.TH fmt_str 3 +.SH NAME +fmt_str \- write an ASCII string +.SH SYNTAX +.B #include + +unsigned int \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. + +fmt_str does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_str returns the number +of bytes it would have written, i.e. the number of leading nonzero bytes +of \fIsource\fR. +.SH "SEE ALSO" +strcpy(3) diff --git a/fmt/fmt_str.c b/fmt/fmt_str.c new file mode 100644 index 0000000..221c33c --- /dev/null +++ b/fmt/fmt_str.c @@ -0,0 +1,13 @@ +#include "fmt.h" + +unsigned int fmt_str(char *out,const char *in) { + register char* s=out; + register const char* t=in; + for (;;) { + if (!*t) break; *s=*t; ++s; ++t; + if (!*t) break; *s=*t; ++s; ++t; + if (!*t) break; *s=*t; ++s; ++t; + if (!*t) break; *s=*t; ++s; ++t; + } + return s-out; +} diff --git a/fmt/fmt_strn.3 b/fmt/fmt_strn.3 new file mode 100644 index 0000000..1e53260 --- /dev/null +++ b/fmt/fmt_strn.3 @@ -0,0 +1,17 @@ +.TH fmt_strn 3 +.SH NAME +fmt_str \- write an ASCII string +.SH SYNTAX +.B #include + +unsigned int \fBfmt_strn\fP(char *\fIdest\fR,const char *\fIsource\fR,unsigned int 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. + +fmt_str does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_strn returns the number +of bytes it would have written. +.SH "SEE ALSO" +strncpy(3) diff --git a/fmt/fmt_strn.c b/fmt/fmt_strn.c new file mode 100644 index 0000000..c0fd0c7 --- /dev/null +++ b/fmt/fmt_strn.c @@ -0,0 +1,14 @@ +#include "fmt.h" + +unsigned int fmt_strn(char *out,const char *in,unsigned int limit) { + register char* s=out; + register const char* t=in; + register const char* u=out+limit; + for (;;) { + if (!*t) break; *s=*t; if (s==u) break; ++s; ++t; + if (!*t) break; *s=*t; if (s==u) break; ++s; ++t; + if (!*t) break; *s=*t; if (s==u) break; ++s; ++t; + if (!*t) break; *s=*t; if (s==u) break; ++s; ++t; + } + return s-out; +} diff --git a/fmt/fmt_uint.3 b/fmt/fmt_uint.3 new file mode 100644 index 0000000..155b4a5 --- /dev/null +++ b/fmt/fmt_uint.3 @@ -0,0 +1,20 @@ +.TH fmt_uint 3 +.SH NAME +fmt_uint \- write an ASCII representation of an unsigned integer +.SH SYNTAX +.B #include + +unsigned int \fBfmt_uint\fP(char *\fIdest\fR,unsigned int \fIsource\fR); +.SH DESCRIPTION +fmt_uint writes an ASCII representation ('0' to '9', base 10) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written. + +fmt_uint does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_uint returns the number +of bytes it would have written. + +For convenience, fmt.h defines the integer FMT_ULONG to be big enough to +contain every possible fmt_uint output plus \\0. +.SH "SEE ALSO" +scan_uint(3), fmt_uint0(3) diff --git a/fmt/fmt_uint0.3 b/fmt/fmt_uint0.3 new file mode 100644 index 0000000..97ed938 --- /dev/null +++ b/fmt/fmt_uint0.3 @@ -0,0 +1,22 @@ +.TH fmt_uint0 3 +.SH NAME +fmt_uint0 \- write a zero-padded ASCII representation of an unsigned integer +.SH SYNTAX +.B #include + +unsigned int \fBfmt_uint0\fP(char *\fIdest\fR, unsigned int \fIsource\fR, unsigned int \fIn\fR); +.SH DESCRIPTION +fmt_uint0 writes an ASCII representation ('0' to '9', base 10) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written. +The output is padded with '0'-bytes until it encompasses at least +\fIn\fR bytes, but it will not be truncated if it does not fit. + +fmt_uint0 does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_uint0 returns the number +of bytes it would have written. + +For convenience, fmt.h defines the integer FMT_ULONG to be big enough to +contain every possible fmt_uint output plus \\0. +.SH "SEE ALSO" +scan_uint(3), fmt_uint(3) diff --git a/fmt/fmt_ulong.3 b/fmt/fmt_ulong.3 new file mode 100644 index 0000000..4baddaf --- /dev/null +++ b/fmt/fmt_ulong.3 @@ -0,0 +1,20 @@ +.TH fmt_ulong 3 +.SH NAME +fmt_ulong \- write an ASCII representation of an unsigned long integer +.SH SYNTAX +.B #include + +unsigned int \fBfmt_ulong\fP(char *\fIdest\fR,unsigned long \fIsource\fR); +.SH DESCRIPTION +fmt_ulong writes an ASCII representation ('0' to '9', base 10) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written. + +fmt_ulong does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_ulong returns the +number of bytes it would have written. + +For convenience, fmt.h defines the integer FMT_ULONG to be big enough to +contain every possible fmt_ulong output plus \\0. +.SH "SEE ALSO" +scan_ulong(3) diff --git a/fmt/fmt_ulong.c b/fmt/fmt_ulong.c new file mode 100644 index 0000000..572c1d3 --- /dev/null +++ b/fmt/fmt_ulong.c @@ -0,0 +1,11 @@ +#include "fmt.h" + +unsigned int fmt_ulong(char *dest,unsigned long i) { + register unsigned long len,tmp; + /* first count the number of bytes needed */ + for (len=1, tmp=i; tmp>9; ++len) tmp/=10; + if (dest) + for (tmp=i, dest+=len; tmp; tmp/=10) + *--dest = (tmp%10)+'0'; + return len; +} diff --git a/fmt/fmt_ulong0.3 b/fmt/fmt_ulong0.3 new file mode 100644 index 0000000..d465f18 --- /dev/null +++ b/fmt/fmt_ulong0.3 @@ -0,0 +1,22 @@ +.TH fmt_ulong0 3 +.SH NAME +fmt_ulong0 \- write a zero-padded ASCII representation of an unsigned long integer +.SH SYNTAX +.B #include + +unsigned int \fBfmt_uint0\fP(char *\fIdest\fR, unsigned long \fIsource\fR, unsigned int \fIn\fR); +.SH DESCRIPTION +fmt_ulong0 writes an ASCII representation ('0' to '9', base 10) of +\fIsource\fR to \fIdest\fR and returns the number of bytes written. +The output is padded with '0'-bytes until it encompasses at least +\fIn\fR bytes, but it will not be truncated if it does not fit. + +fmt_ulong0 does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_ulong0 returns the number +of bytes it would have written. + +For convenience, fmt.h defines the integer FMT_ULONG to be big enough to +contain every possible fmt_ulong output plus \\0. +.SH "SEE ALSO" +scan_ulong(3), fmt_ulong(3) diff --git a/fmt/fmt_ulong0.c b/fmt/fmt_ulong0.c new file mode 100644 index 0000000..5366b33 --- /dev/null +++ b/fmt/fmt_ulong0.c @@ -0,0 +1,15 @@ +#include "fmt.h" + +unsigned int fmt_ulong0(char *dest,unsigned long i,unsigned int pad) { + register unsigned int len; + register unsigned long tmp; + /* first count the number of bytes needed */ + for (len=1, tmp=i; tmp>9; ++len) tmp/=10; + /* now see if we need to pad */ + if (dest) { + while (len + +unsigned int \fBfmt_xlong\fP(char *\fIdest\fR,unsigned long \fIsource\fR); +.SH DESCRIPTION +fmt_xlong writes an ASCII representation ('0' to '9' and 'a' to 'f', +base 16) of \fIsource\fR to \fIdest\fR and returns the number of bytes +written. + +fmt_xlong does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_xlong returns the +number of bytes it would have written. + +For convenience, fmt.h defines the integer FMT_XLONG to be big enough to +contain every possible fmt_xlong output plus \\0. +.SH "SEE ALSO" +scan_xlong(3) diff --git a/fmt/fmt_xlong.c b/fmt/fmt_xlong.c new file mode 100644 index 0000000..77f2cda --- /dev/null +++ b/fmt/fmt_xlong.c @@ -0,0 +1,15 @@ +#include "fmt.h" + +static inline char tohex(char c) { + return c>10?c-10+'a':c+'0'; +} + +unsigned int fmt_xlong(char *dest,unsigned long i) { + register unsigned long len,tmp; + /* first count the number of bytes needed */ + for (len=1, tmp=i; tmp>15; ++len) tmp>>=4; + if (dest) + for (tmp=i, dest+=len; tmp; tmp>>=4) + *--dest = tohex(tmp&15); + return len; +} diff --git a/ip6.h b/ip6.h new file mode 100644 index 0000000..c668707 --- /dev/null +++ b/ip6.h @@ -0,0 +1,28 @@ +#ifndef IP6_H +#define IP6_H + +extern unsigned int ip6_scan(const char *src,char *ip); +extern unsigned int ip6_fmt(char *dest,const char *ip); + +extern unsigned int ip6_scan_flat(const char *src,char *); +extern unsigned int ip6_fmt_flat(char *dest,const char *); + +/* + ip6 address syntax: (h = hex digit), no leading '0' required + 1. hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh:hhhh + 2. any number of 0000 may be abbreviated as "::", but only once + flat ip6 address syntax: + hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh + */ + +#define IP6_FMT 40 + +static const unsigned char V4mappedprefix[12]={0,0,0,0,0,0,0,0,0,0,0xff,0xff}; +static const unsigned char V6loopback[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; +static const unsigned char V6any[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +#define ip6_isv4mapped(ip) (byte_equal(ip,12,V4mappedprefix)) + +static const char ip4loopback[4] = {127,0,0,1}; + +#endif diff --git a/ndelay.h b/ndelay.h new file mode 100644 index 0000000..60b788c --- /dev/null +++ b/ndelay.h @@ -0,0 +1,7 @@ +#ifndef NDELAY_H +#define NDELAY_H + +extern int ndelay_on(int); +extern int ndelay_off(int); + +#endif diff --git a/open.h b/open.h new file mode 100644 index 0000000..6bd1358 --- /dev/null +++ b/open.h @@ -0,0 +1,29 @@ +#ifndef OPEN_H +#define OPEN_H + +#include + +/* open filename for reading and return the file handle or -1 on error */ +extern int open_read(const char *filename) __THROW; + +/* create filename for exclusive write only use (mode 0600) and return + * the file handle or -1 on error */ +extern int open_excl(const char *filename) __THROW; + +/* open filename for appending write only use (mode 0600) + * and return the file handle or -1 on error. + * All write operation will append after the last byte, regardless of + * seeking or other processes also appending to the file. The file will + * be created if it does not exist. */ +extern int open_append(const char *filename) __THROW; + +/* open filename for writing (mode 0644). Create the file if it does + * not exist, truncate it to zero length otherwise. Return the file + * handle or -1 on error. */ +extern int open_trunc(const char *filename) __THROW; + +/* open filename for writing. Create the file if it does not exist. + * Return the file handle or -1 on error. */ +extern int open_write(const char *filename) __THROW; + +#endif diff --git a/open/open_append.3 b/open/open_append.3 new file mode 100644 index 0000000..cfa4f3e --- /dev/null +++ b/open/open_append.3 @@ -0,0 +1,18 @@ +.TH open_append 3 +.SH NAME +open_append \- open a file for appending +.SH SYNTAX +.B #include + +extern int \fBopen_append\fP(const char *\fIfilename\fR); +.SH DESCRIPTION +open_append opens the file \fIfilename\fR for appending write-only use +and returns the file handle. If it does not exist, it will be created +with mode 0600. If there was an error opening or creating the file, +open_append returns -1 and sets errno accordingly. + +All write operations will append after the last byte, regardless of +previous calls to lseek(2) or other processes also appending to the +same file. +.SH "SEE ALSO" +open(2) diff --git a/open/open_append.c b/open/open_append.c new file mode 100644 index 0000000..0250993 --- /dev/null +++ b/open/open_append.c @@ -0,0 +1,7 @@ +#include +#include +#include "open.h" + +extern int open_append(const char *filename) { + return open(filename,O_WRONLY|O_NDELAY|O_APPEND|O_CREAT,0600); +} diff --git a/open/open_excl.3 b/open/open_excl.3 new file mode 100644 index 0000000..30304cb --- /dev/null +++ b/open/open_excl.3 @@ -0,0 +1,22 @@ +.TH open_excl 3 +.SH NAME +open_excl \- open a file for exclusive writing +.SH SYNTAX +.B #include + +extern int \fBopen_excl\fP(const char *\fIfilename\fR); +.SH DESCRIPTION +open_excl opens the file \fIfilename\fR for writing and returns the file +handle. The file may not exist before the call to \fBopen_excl\fR. The +file will be created with mode 0600. + +If there was an error creating the file, open_excl returns -1 +and sets errno accordingly. + +Since open_excl relies on the O_EXCL flag to open, it does not work +reliably over NFS (the NFS protocol is broken) and must be emulated +using a lock file (create a file with a unique file name and link(2) it +to the lock file. Then stat the lock file and see if the link count is +2). +.SH "SEE ALSO" +open(2) diff --git a/open/open_excl.c b/open/open_excl.c new file mode 100644 index 0000000..27a0abb --- /dev/null +++ b/open/open_excl.c @@ -0,0 +1,7 @@ +#include +#include +#include "open.h" + +extern int open_excl(const char *filename) { + return open(filename,O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT|O_EXCL,0600); +} diff --git a/open/open_read.3 b/open/open_read.3 new file mode 100644 index 0000000..f26b735 --- /dev/null +++ b/open/open_read.3 @@ -0,0 +1,13 @@ +.TH open_read 3 +.SH NAME +open_read \- open a file for reading +.SH SYNTAX +.B #include + +extern int \fBopen_read\fP(const char *\fIfilename\fR); +.SH DESCRIPTION +open_read opens the file \fIfilename\fR for reading and returns the file +handle. If there was an error opening the file, open_read returns -1 +and sets errno accordingly. +.SH "SEE ALSO" +open(2) diff --git a/open/open_read.c b/open/open_read.c new file mode 100644 index 0000000..ba6c647 --- /dev/null +++ b/open/open_read.c @@ -0,0 +1,7 @@ +#include +#include +#include "open.h" + +extern int open_read(const char *filename) { + return open(filename,O_RDONLY|O_NDELAY); +} diff --git a/open/open_trunc.3 b/open/open_trunc.3 new file mode 100644 index 0000000..3ee9b48 --- /dev/null +++ b/open/open_trunc.3 @@ -0,0 +1,15 @@ +.TH open_trunc 3 +.SH NAME +open_trunc \- open a file for writing +.SH SYNTAX +.B #include + +extern int \fBopen_trunc\fP(const char *\fIfilename\fR); +.SH DESCRIPTION +open_trunc opens the file \fIfilename\fR for write-only use +and returns the file handle. If the file exists, it will be truncated +to zero bytes length. If it does not exist, it will be created +with mode 0644. If there was an error opening or creating the file, +open_trunc returns -1 and sets errno accordingly. +.SH "SEE ALSO" +open(2) diff --git a/open/open_trunc.c b/open/open_trunc.c new file mode 100644 index 0000000..0919025 --- /dev/null +++ b/open/open_trunc.c @@ -0,0 +1,7 @@ +#include +#include +#include "open.h" + +extern int open_trunc(const char *filename) { + return open(filename,O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT,0644); +} diff --git a/open/open_write.3 b/open/open_write.3 new file mode 100644 index 0000000..cd1c2e8 --- /dev/null +++ b/open/open_write.3 @@ -0,0 +1,14 @@ +.TH open_write 3 +.SH NAME +open_write \- open a file for writing +.SH SYNTAX +.B #include + +extern int \fBopen_write\fP(const char *\fIfilename\fR); +.SH DESCRIPTION +open_write opens the file \fIfilename\fR for write-only use and returns +the file handle. If the file does not exist, it will be created with +mode 0644. If there was an error opening or creating the file, +open_write returns -1 and sets errno accordingly. +.SH "SEE ALSO" +open(2) diff --git a/open/open_write.c b/open/open_write.c new file mode 100644 index 0000000..49c338c --- /dev/null +++ b/open/open_write.c @@ -0,0 +1,7 @@ +#include +#include +#include "open.h" + +extern int open_write(const char *filename) { + return open(filename,O_WRONLY|O_NDELAY); +} diff --git a/scan.h b/scan.h new file mode 100644 index 0000000..bd773b5 --- /dev/null +++ b/scan.h @@ -0,0 +1,61 @@ +#ifndef SCAN_H +#define SCAN_H + +#include +#ifndef __pure__ +#define __pure__ +#endif +#ifndef __THROW +#define __THROW +#endif + +/* interpret src as ASCII decimal number, write number to dest and + * return the number of bytes that were parsed */ +extern unsigned int scan_ulong(const char *src,unsigned long *dest) __THROW; + +/* interpret src as ASCII hexadecimal number, write number to dest and + * return the number of bytes that were parsed */ +extern unsigned int scan_xlong(const char *src,unsigned long *dest) __THROW; + +/* interpret src as ASCII octal number, write number to dest and + * return the number of bytes that were parsed */ +extern unsigned int scan_8long(const char *src,unsigned long *dest) __THROW; + +/* interpret src as signed ASCII decimal number, write number to dest + * and return the number of bytes that were parsed */ +extern unsigned int scan_long(const char *src,signed long *dest) __THROW; + +extern unsigned int scan_uint(const char *src,unsigned int *dest) __THROW; +extern unsigned int scan_xint(const char *src,unsigned int *dest) __THROW; +extern unsigned int scan_8int(const char *src,unsigned int *dest) __THROW; +extern unsigned int scan_int(const char *src,signed int *dest) __THROW; + +extern unsigned int scan_ushort(const char *src,unsigned short *dest) __THROW; +extern unsigned int scan_xshort(const char *src,unsigned short *dest) __THROW; +extern unsigned int scan_8short(const char *src,unsigned short *dest) __THROW; +extern unsigned int scan_short(const char *src,signed short *dest) __THROW; + +/* interpret src as double precision floating point number, + * write number to dest and return the number of bytes that were parsed */ +extern unsigned int scan_double(const char *in, double *dest) __THROW; + +/* if *src=='-', set *dest to -1 and return 1. + * if *src=='+', set *dest to 1 and return 1. + * otherwise set *dest to 1 return 0. */ +extern unsigned int scan_plusminus(const char *src,signed int *dest) __THROW; + +/* 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) __THROW __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) __THROW __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) __THROW __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) __THROW __pure__; + +#endif diff --git a/scan/scan_8int.c b/scan/scan_8int.c new file mode 100644 index 0000000..f5390e0 --- /dev/null +++ b/scan/scan_8int.c @@ -0,0 +1,8 @@ +#include "scan.h" + +unsigned int scan_8int(const char* src,unsigned int* dest) { + unsigned long l; + register int len=scan_8long(src,&l); + *dest=l; + return len; +} diff --git a/scan/scan_8long.3 b/scan/scan_8long.3 new file mode 100644 index 0000000..53c5574 --- /dev/null +++ b/scan/scan_8long.3 @@ -0,0 +1,13 @@ +.TH scan_8long 3 +.SH NAME +scan_8long \- parse an unsigned long integer in octal ASCII representation +.SH SYNTAX +.B #include + +int \fBscan_8long\fP(const char *\fIsrc\fR,unsigned long *\fIdest\fR); +.SH DESCRIPTION +scan_8long parses an unsigned long integer in octal ASCII representation +from \fIsrc\fR and writes the result into \fIdest\fR. It returns the +number of bytes read from \fIsrc\fR. +.SH "SEE ALSO" +scan_xlong(3) diff --git a/scan/scan_8long.c b/scan/scan_8long.c new file mode 100644 index 0000000..a675804 --- /dev/null +++ b/scan/scan_8long.c @@ -0,0 +1,13 @@ +#include "scan.h" + +unsigned int scan_8long(const char *src,unsigned long *dest) { + register const char *tmp=src; + register int l=0; + register unsigned char c; + while ((c=*tmp-'0')<8) { + l=l*8+c; + ++tmp; + } + *dest=l; + return tmp-src; +} diff --git a/scan/scan_8short.c b/scan/scan_8short.c new file mode 100644 index 0000000..5e9d4a1 --- /dev/null +++ b/scan/scan_8short.c @@ -0,0 +1,8 @@ +#include "scan.h" + +unsigned int scan_8short(const char* src,unsigned short* dest) { + unsigned long l; + register int len=scan_8long(src,&l); + *dest=l; + return len; +} diff --git a/scan/scan_charsetnskip.3 b/scan/scan_charsetnskip.3 new file mode 100644 index 0000000..e15afde --- /dev/null +++ b/scan/scan_charsetnskip.3 @@ -0,0 +1,13 @@ +.TH scan_charsetnskip 3 +.SH NAME +scan_charsetnskip \- skip characters from set +.SH SYNTAX +.B #include + +int \fBscan_charsetnskip\fP(const char* \fIsrc\fR, const char* \fIcharset\fR, unsigned int* \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 +and not including the \\0). +.SH "SEE ALSO" +scan_noncharsetnskip(3) diff --git a/scan/scan_charsetnskip.c b/scan/scan_charsetnskip.c new file mode 100644 index 0000000..d6299c8 --- /dev/null +++ b/scan/scan_charsetnskip.c @@ -0,0 +1,15 @@ +#include "scan.h" +#include + +unsigned int scan_charsetnskip(const char *s,const char *charset,unsigned int limit) { + register const char *t=s; + register const char *u=t+limit; + register const char* i; + while (t + +int \fBscan_double\fP(const char *\fIsrc\fR,double *\fIdest\fR); +.SH DESCRIPTION +scan_double parses a floating point number in decimal ASCII representation +from \fIsrc\fR and writes the result into \fIdest\fR. It returns the +number of bytes read from \fIsrc\fR. +.SH "SEE ALSO" +scan_xlong(3), scan_8long(3), fmt_ulong(3) diff --git a/scan/scan_double.c b/scan/scan_double.c new file mode 100644 index 0000000..e92f005 --- /dev/null +++ b/scan/scan_double.c @@ -0,0 +1,51 @@ +#include "scan.h" + +#ifdef __GNUC__ +static inline int isdigit(int c) { return (c>='0' && c<='9'); } +#else +#include +#endif + +unsigned int scan_double(const char *in, double *dest) { + double d=0; + register const char *c=in; + char neg=0; + switch (*c) { + case '-': neg=1; + case '+': c++; break; + default: break; + } + while (isdigit(*c)) { + d=d*10+(*c-'0'); + ++c; + } + if (*c=='.') { + double factor=.1; + while (isdigit(*++c)) { + d=d+(factor*(*c-'0')); + factor/=10; + } + } + if ((*c|32)=='e') { + int exp=0; + char neg=0; + if (c[1]<'0') { + switch (*c) { + case '-': neg=1; + case '+': c++; break; + default: + d=0; + c=in; + goto done; + } + } + while (isdigit(*++c)) + exp=exp*10+(*c-'0'); + while (exp) { /* XXX: this introduces rounding errors */ + d*=10; --exp; + } + } +done: + *dest=d; + return c-in; +} diff --git a/scan/scan_int.c b/scan/scan_int.c new file mode 100644 index 0000000..b881db2 --- /dev/null +++ b/scan/scan_int.c @@ -0,0 +1,8 @@ +#include "scan.h" + +unsigned int scan_int(const char* src,int* dest) { + long l; + register int len=scan_long(src,&l); + *dest=l; + return len; +} diff --git a/scan/scan_long.c b/scan/scan_long.c new file mode 100644 index 0000000..497c919 --- /dev/null +++ b/scan/scan_long.c @@ -0,0 +1,19 @@ +#include "scan.h" + +unsigned int scan_long(const char *src,long *dest) { + register const char *tmp; + register int l; + register unsigned char c; + int neg; + tmp=src; l=0; neg=0; + switch (*tmp) { + case '-': neg=1; + case '+': ++tmp; + } + while ((c=*tmp-'0')<10) { + l=l*10+c; + ++tmp; + } + *dest=(neg?-l:l); + return tmp-src; +} diff --git a/scan/scan_noncharsetnskip.3 b/scan/scan_noncharsetnskip.3 new file mode 100644 index 0000000..4268ad6 --- /dev/null +++ b/scan/scan_noncharsetnskip.3 @@ -0,0 +1,13 @@ +.TH scan_noncharsetnskip 3 +.SH NAME +scan_noncharsetnskip \- skip characters not from set +.SH SYNTAX +.B #include + +int \fBscan_noncharsetnskip\fP(const char* \fIsrc\fR, const char* \fIcharset\fR, unsigned int* \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 +(up to and not including the \\0). +.SH "SEE ALSO" +scan_charsetnskip(3) diff --git a/scan/scan_noncharsetnskip.c b/scan/scan_noncharsetnskip.c new file mode 100644 index 0000000..919aaa7 --- /dev/null +++ b/scan/scan_noncharsetnskip.c @@ -0,0 +1,15 @@ +#include "scan.h" +#include + +unsigned int scan_noncharsetnskip(const char *s,const char *charset,unsigned int limit) { + register const char *t=s; + register const char *u=t+limit; + register const char* i; + while (t + +int \fBscan_nonwhitenskip\fP(const char *\fIsrc\fR,unsigned int *\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 +\fB!isspace\fR. + +Normally, this is everything but ' ', '\\f', '\\n', '\\r', '\\t', '\\v'. +.SH "SEE ALSO" +scan_nonwhitenskip(3) diff --git a/scan/scan_nonwhitenskip.c b/scan/scan_nonwhitenskip.c new file mode 100644 index 0000000..b3b340a --- /dev/null +++ b/scan/scan_nonwhitenskip.c @@ -0,0 +1,9 @@ +#include "scan.h" +#include + +unsigned int scan_nonwhitenskip(const char *s,unsigned int limit) { + register const char *t=s; + register const char *u=t+limit; + while (t + +int \fBscan_plusminus\fP(const char *\fIsrc\fR,int *\fIdest\fR); +.SH DESCRIPTION +scan_plusminus parses an ASCII '+' or '-' sign from \fIsrc\fR, sets +\fIdest\fR 1 or -1, respectively, and returns 1. + +If neither is found, '+' is assumed and 0 is returned. diff --git a/scan/scan_plusminus.c b/scan/scan_plusminus.c new file mode 100644 index 0000000..2906042 --- /dev/null +++ b/scan/scan_plusminus.c @@ -0,0 +1,10 @@ +#include "scan.h" + +unsigned int scan_plusminus(const char *src,signed int *dest) { + *dest=1; + switch (*src) { + case '-': *dest=-1; + case '+': return 1; break; + } + return 0; +} diff --git a/scan/scan_short.c b/scan/scan_short.c new file mode 100644 index 0000000..c4f8331 --- /dev/null +++ b/scan/scan_short.c @@ -0,0 +1,8 @@ +#include "scan.h" + +unsigned int scan_short(const char* src,short* dest) { + long l; + register int len=scan_long(src,&l); + *dest=l; + return len; +} diff --git a/scan/scan_uint.c b/scan/scan_uint.c new file mode 100644 index 0000000..78f4cca --- /dev/null +++ b/scan/scan_uint.c @@ -0,0 +1,8 @@ +#include "scan.h" + +unsigned int scan_uint(const char* src,unsigned int* dest) { + unsigned long l; + register int len=scan_ulong(src,&l); + *dest=l; + return len; +} diff --git a/scan/scan_ulong.3 b/scan/scan_ulong.3 new file mode 100644 index 0000000..2bb02de --- /dev/null +++ b/scan/scan_ulong.3 @@ -0,0 +1,13 @@ +.TH scan_ulong 3 +.SH NAME +scan_ulong \- parse an unsigned long integer in decimal ASCII representation +.SH SYNTAX +.B #include + +int \fBscan_ulong\fP(const char *\fIsrc\fR,unsigned long *\fIdest\fR); +.SH DESCRIPTION +scan_ulong parses an unsigned long integer in decimal ASCII representation +from \fIsrc\fR and writes the result into \fIdest\fR. It returns the +number of bytes read from \fIsrc\fR. +.SH "SEE ALSO" +scan_xlong(3), scan_8long(3), fmt_ulong(3) diff --git a/scan/scan_ulong.c b/scan/scan_ulong.c new file mode 100644 index 0000000..02d3f2b --- /dev/null +++ b/scan/scan_ulong.c @@ -0,0 +1,13 @@ +#include "scan.h" + +unsigned int scan_ulong(const char *src,unsigned long *dest) { + register const char *tmp=src; + register int l=0; + register unsigned char c; + while ((c=*tmp-'0')<10) { + l=l*10+c; + ++tmp; + } + *dest=l; + return tmp-src; +} diff --git a/scan/scan_ushort.c b/scan/scan_ushort.c new file mode 100644 index 0000000..820598a --- /dev/null +++ b/scan/scan_ushort.c @@ -0,0 +1,8 @@ +#include "scan.h" + +unsigned int scan_ushort(const char* src,unsigned short* dest) { + unsigned long l; + register int len=scan_ulong(src,&l); + *dest=l; + return len; +} diff --git a/scan/scan_whitenskip.3 b/scan/scan_whitenskip.3 new file mode 100644 index 0000000..dedd69d --- /dev/null +++ b/scan/scan_whitenskip.3 @@ -0,0 +1,15 @@ +.TH scan_whitenskip 3 +.SH NAME +scan_whitenskip \- skip whitespace +.SH SYNTAX +.B #include + +int \fBscan_whitenskip\fP(const char *\fIsrc\fR,unsigned int *\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 +\fBisspace\fR. + +Normally, this is ' ', '\\f', '\\n', '\\r', '\\t', '\\v'. +.SH "SEE ALSO" +scan_nonwhitenskip(3) diff --git a/scan/scan_whitenskip.c b/scan/scan_whitenskip.c new file mode 100644 index 0000000..756a04a --- /dev/null +++ b/scan/scan_whitenskip.c @@ -0,0 +1,9 @@ +#include "scan.h" +#include + +unsigned int scan_whitenskip(const char *s,unsigned int limit) { + register const char *t=s; + register const char *u=t+limit; + while (t + +int \fBscan_xlong\fP(const char *\fIsrc\fR,unsigned long *\fIdest\fR); +.SH DESCRIPTION +scan_xlong parses an unsigned long integer in hexadecimal ASCII +representation from \fIsrc\fR and writes the result into \fIdest\fR. It +returns the number of bytes read from \fIsrc\fR. + +scan_xlong understands both upper and lower case letters. + +scan_xlong does not expect or understand a "0x" prefix. +.SH "SEE ALSO" +fmt_xlong(3) diff --git a/scan/scan_xlong.c b/scan/scan_xlong.c new file mode 100644 index 0000000..1113433 --- /dev/null +++ b/scan/scan_xlong.c @@ -0,0 +1,23 @@ +#include "scan.h" + +static inline int fromhex(unsigned char c) { + if (c>='0' && c<='9') + return c-'0'; + else if (c>='A' && c<='F') + return c-'A'+10; + else if (c>='a' && c<='f') + return c-'a'+10; + return -1; +} + +unsigned int scan_xlong(const char *src,unsigned long *dest) { + register const char *tmp=src; + register int l=0; + register unsigned char c; + while ((c=fromhex(*tmp))<16) { + l=(l<<4)+c; + ++tmp; + } + *dest=l; + return tmp-src; +} diff --git a/scan/scan_xshort.c b/scan/scan_xshort.c new file mode 100644 index 0000000..52415e8 --- /dev/null +++ b/scan/scan_xshort.c @@ -0,0 +1,8 @@ +#include "scan.h" + +unsigned int scan_xshort(const char* src,unsigned short* dest) { + unsigned long l; + register int len=scan_xlong(src,&l); + *dest=l; + return len; +} diff --git a/socket.h b/socket.h new file mode 100644 index 0000000..2282d86 --- /dev/null +++ b/socket.h @@ -0,0 +1,58 @@ +#ifndef SOCKET_H +#define SOCKET_H + +#include "uint16.h" +#include "uint32.h" + +extern int socket_tcp4(void); +extern int socket_udp4(void); +extern int socket_tcp6(void); +extern int socket_udp6(void); + +#define socket_tcp() socket_tcp4() +#define socket_udp() socket_udp4() + +extern int socket_connect4(int s,const char *ip,uint16); +extern int socket_connect6(int s,const char *ip,uint16,uint32 scope_id); +extern int socket_connected(int s); +extern int socket_bind4(int s,const char *ip,uint16); +extern int socket_bind4_reuse(int s,const char *ip,uint16); +extern int socket_bind6(int s,const char *ip,uint16,uint32 scope_id); +extern int socket_bind6_reuse(int s,const char *ip,uint16,uint32 scope_id); +extern int socket_listen(int s,unsigned int backlog); +extern int socket_accept4(int s,char *ip,uint16 *); +extern int socket_accept6(int s,char *ip,uint16 *,uint32 *scope_id); +extern int socket_recv4(int s,char *buf,unsigned int len,char *ip,uint16 *port); +extern int socket_recv6(int s,char *buf,unsigned int len,char *ip,uint16 *port,uint32 *scope_id); +extern int socket_send4(int s,const char *buf,unsigned int len,const char *ip,uint16 port); +extern int socket_send6(int s,const char *buf,unsigned int len,const char *ip,uint16 port,uint32 scope_id); +extern int socket_local4(int s,char *ip,uint16 *port); +extern int socket_local6(int s,char *ip,uint16 *port,uint32 *scope_id); +extern int socket_remote4(int s,char *ip,uint16 *port); +extern int socket_remote6(int s,char *ip,uint16 *port,uint32 *scope_id); + +/* enable sending udp packets to the broadcast address */ +extern int socket_broadcast(int s); +/* join a multicast group on the given interface */ +extern int socket_mcjoin4(int s,const char *groupip,const char *interface); +extern int socket_mcjoin6(int s,const char *groupip,int); +/* leave a multicast group on the given interface */ +extern int socket_mcleave4(int s,const char *groupip); +extern int socket_mcleave6(int s,const char *groupip); +/* set multicast TTL/hop count for outgoing packets */ +extern int socket_mcttl4(int s,char hops); +extern int socket_mcttl6(int s,char hops); +/* enable multicast loopback */ +extern int socket_mcloop4(int s,char hops); +extern int socket_mcloop6(int s,char hops); + +extern void socket_tryreservein(int s,int size); + +extern const char* socket_getifname(uint32 interface); +extern uint32 socket_getifidx(const char *ifname); + +extern int socket_sendfile(int out,int in,uint32 offset,uint32 bytes); + +extern int noipv6; + +#endif diff --git a/socket/socket_connect4.c b/socket/socket_connect4.c new file mode 100644 index 0000000..141970c --- /dev/null +++ b/socket/socket_connect4.c @@ -0,0 +1,17 @@ +#include +#include +#include + +#include "byte.h" +#include "socket.h" +#include "uint16.h" +#include "uint32.h" + +int socket_connect4(int s,const char *ip,uint16 port) { + struct sockaddr_in si; + byte_zero(&si,sizeof(si)); + si.sin_family=AF_INET; + uint16_pack_big((char*) &si.sin_port,port); + *((uint32*)&si.sin_addr) = *((uint32*)ip); + return (connect(s,(struct sockaddr*)&si,sizeof(si))); +} diff --git a/socket/socket_connect6.c b/socket/socket_connect6.c new file mode 100644 index 0000000..40eea76 --- /dev/null +++ b/socket/socket_connect6.c @@ -0,0 +1,35 @@ +#include +#include "sockaddr_in6.h" +#include "byte.h" +#include "socket.h" +#include "ip6.h" +#include "haveip6.h" +#include "error.h" +#include "uint32.h" + +int socket_connect6(int s,const char ip[16],uint16 port,uint32 scope_id) +{ +#ifdef LIBC_HAS_IP6 + struct sockaddr_in6 sa; + + if (noipv6) { +#endif + if (ip6_isv4mapped(ip)) + return socket_connect4(s,ip+12,port); + if (byte_equal(ip,16,V6loopback)) + return socket_connect4(s,ip4loopback,port); +#ifdef LIBC_HAS_IP6 + } + byte_zero(&sa,sizeof sa); + sa.sin6_family = PF_INET6; + uint16_pack_big((char *) &sa.sin6_port,port); + sa.sin6_flowinfo = 0; + sa.sin6_scope_id = scope_id; + byte_copy((char *) &sa.sin6_addr,16,ip); + + return connect(s,(struct sockaddr *) &sa,sizeof sa); +#else + errno=error_proto; + return -1; +#endif +} diff --git a/socket/socket_tcp4.c b/socket/socket_tcp4.c new file mode 100644 index 0000000..b1ab3e7 --- /dev/null +++ b/socket/socket_tcp4.c @@ -0,0 +1,9 @@ +#include +#include +#include + +#include "socket.h" + +int socket_tcp4(void) { + return socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); +} diff --git a/socket/socket_tcp6.c b/socket/socket_tcp6.c new file mode 100644 index 0000000..3fc7825 --- /dev/null +++ b/socket/socket_tcp6.c @@ -0,0 +1,9 @@ +#include +#include +#include + +#include "socket.h" + +int socket_tcp6(void) { + return socket(PF_INET6,SOCK_STREAM,IPPROTO_TCP); +} diff --git a/socket/socket_udp4.c b/socket/socket_udp4.c new file mode 100644 index 0000000..b9892b4 --- /dev/null +++ b/socket/socket_udp4.c @@ -0,0 +1,9 @@ +#include +#include +#include + +#include "socket.h" + +int socket_udp4(void) { + return socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); +} diff --git a/socket/socket_udp6.c b/socket/socket_udp6.c new file mode 100644 index 0000000..82de50f --- /dev/null +++ b/socket/socket_udp6.c @@ -0,0 +1,9 @@ +#include +#include +#include + +#include "socket.h" + +int socket_udp6(void) { + return socket(PF_INET6,SOCK_DGRAM,IPPROTO_UDP); +} diff --git a/str.h b/str.h new file mode 100644 index 0000000..0b757ee --- /dev/null +++ b/str.h @@ -0,0 +1,46 @@ +#ifndef STR_H +#define STR_H + +#include +#ifndef __pure__ +#define __pure__ +#endif +#ifndef __THROW +#define __THROW +#endif + +/* 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) __THROW; + +/* str_diff returns negative, 0, or positive, depending on whether the + * string a[0], a[1], ..., a[n]=='\0' is lexicographically smaller than, + * equal to, or greater than the string b[0], b[1], ..., b[m-1]=='\0'. + * If the strings are different, str_diff does not read bytes past the + * first difference. */ +extern int str_diff(const char *a,const char *b) __THROW __pure__; + +/* str_diffn returns negative, 0, or positive, depending on whether the + * string a[0], a[1], ..., a[n]=='\0' is lexicographically smaller than, + * equal to, or greater than the string b[0], b[1], ..., b[m-1]=='\0'. + * 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) __THROW __pure__; + +/* str_len returns the index of \0 in s */ +extern unsigned int str_len(const char *s) __THROW __pure__; + +/* str_chr returns the index of the first occurance of needle or \0 in s */ +extern unsigned int str_chr(const char *haystack,char needle) __THROW __pure__; + +/* str_rchr returns the index of the last occurance of needle or \0 in s */ +extern unsigned int str_rchr(const char *haystack,char needle) __THROW __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) __THROW __pure__; + +/* convenience shortcut to test for string equality */ +#define str_equal(s,t) (!str_diff((s),(t))) + +#endif diff --git a/str/str_chr.3 b/str/str_chr.3 new file mode 100644 index 0000000..809df18 --- /dev/null +++ b/str/str_chr.3 @@ -0,0 +1,12 @@ +.TH str_chr 3 +.SH NAME +str_chr \- find character in ASCIIZ string +.SH SYNTAX +.B #include + +extern int \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. +.SH "SEE ALSO" +strchr(3) diff --git a/str/str_chr.c b/str/str_chr.c new file mode 100644 index 0000000..347ef00 --- /dev/null +++ b/str/str_chr.c @@ -0,0 +1,13 @@ +#include "str.h" + +unsigned int str_chr(const char *in, char needle) { + register const char* t=in; + register const char c=needle; + for (;;) { + if (!*t || *t==c) break; ++t; + if (!*t || *t==c) break; ++t; + if (!*t || *t==c) break; ++t; + if (!*t || *t==c) break; ++t; + } + return t-in; +} diff --git a/str/str_copy.3 b/str/str_copy.3 new file mode 100644 index 0000000..1d427d5 --- /dev/null +++ b/str/str_copy.3 @@ -0,0 +1,14 @@ +.TH str_copy 3 +.SH NAME +str_copy \- copy an ASCIIZ string +.SH SYNTAX +.B #include + +extern int \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. + +str_copy returns the number of bytes copied. +.SH "SEE ALSO" +strlen(3) diff --git a/str/str_copy.c b/str/str_copy.c new file mode 100644 index 0000000..48b22c0 --- /dev/null +++ b/str/str_copy.c @@ -0,0 +1,13 @@ +#include "str.h" + +unsigned int str_copy(char *out,const char *in) { + register char* s=out; + register const char* t=in; + for (;;) { + if (!(*s=*t)) break; ++s; ++t; + if (!(*s=*t)) break; ++s; ++t; + if (!(*s=*t)) break; ++s; ++t; + if (!(*s=*t)) break; ++s; ++t; + } + return s-out; +} diff --git a/str/str_diff.3 b/str/str_diff.3 new file mode 100644 index 0000000..563c610 --- /dev/null +++ b/str/str_diff.3 @@ -0,0 +1,17 @@ +.TH str_diff 3 +.SH NAME +str_diff \- compare two ASCIIZ strings +.SH SYNTAX +.B #include + +extern int \fBstr_diff\fP(const char* \fIa\fR,const char* \fIb\fR); +.SH DESCRIPTION +\fBstr_diff\fR returns negative, 0, or positive, depending on whether the +string \fIa\fR[0], \fIa\fR[1], ..., \fIa\fR[n]=='\\0' is +lexicographically smaller than, equal to, or greater than the string +\fIb\fR[0], \fIb\fR[1], ..., \fIb\fR[m-1]=='\\0'. + +If the strings are different, str_diff does not read bytes past the +first difference. +.SH "SEE ALSO" +strlen(3) diff --git a/str/str_diff.c b/str/str_diff.c new file mode 100644 index 0000000..fe74e80 --- /dev/null +++ b/str/str_diff.c @@ -0,0 +1,20 @@ +#include "byte.h" + +/* str_diff returns negative, 0, or positive, depending on whether the + * string a[0], a[1], ..., a[n]=='\0' is lexicographically smaller than, + * 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_diff(const char* a, const char* b) { + register const char* s=a; + register const char* t=b; + register int j; + j=0; + for (;;) { + if ((j=(*s-*t))) break; if (!*t) break; ++s; ++t; + if ((j=(*s-*t))) break; if (!*t) break; ++s; ++t; + if ((j=(*s-*t))) break; if (!*t) break; ++s; ++t; + if ((j=(*s-*t))) break; if (!*t) break; ++s; ++t; + } + return j; +} diff --git a/str/str_diffn.3 b/str/str_diffn.3 new file mode 100644 index 0000000..55874c8 --- /dev/null +++ b/str/str_diffn.3 @@ -0,0 +1,18 @@ +.TH str_diffn 3 +.SH NAME +str_diffn \- compare two ASCIIZ strings +.SH SYNTAX +.B #include + +extern int \fBstr_diffn\fP(const char* \fIa\fR,const char* \fIb\fR,unsigned int \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 +lexicographically smaller than, equal to, or greater than the string +\fIb\fR[0], \fIb\fR[1], ..., \fIb\fR[m-1]=='\\0'. + +If the strings are different, str_diff does not read bytes past the +first difference. The strings will be considered equal if the first +\fIlimit\fR characters match. +.SH "SEE ALSO" +strlen(3) diff --git a/str/str_diffn.c b/str/str_diffn.c new file mode 100644 index 0000000..a54904c --- /dev/null +++ b/str/str_diffn.c @@ -0,0 +1,21 @@ +#include "byte.h" + +/* str_diff returns negative, 0, or positive, depending on whether the + * string a[0], a[1], ..., a[n]=='\0' is lexicographically smaller than, + * 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) { + register const char* s=a; + register const char* t=b; + register const char* u=t+limit; + register int j; + j=0; + for (;;) { + if (t>=u) break; if ((j=(*s-*t))) break; if (!*t) break; ++s; ++t; + if (t>=u) break; if ((j=(*s-*t))) break; if (!*t) break; ++s; ++t; + if (t>=u) break; if ((j=(*s-*t))) break; if (!*t) break; ++s; ++t; + if (t>=u) break; if ((j=(*s-*t))) break; if (!*t) break; ++s; ++t; + } + return j; +} diff --git a/str/str_equal.3 b/str/str_equal.3 new file mode 100644 index 0000000..352ac4c --- /dev/null +++ b/str/str_equal.3 @@ -0,0 +1,15 @@ +.TH str_equal 3 +.SH NAME +str_equal \- compare two ASCIIZ strings +.SH SYNTAX +.B #include + +extern int \fBstr_equal\fP(const char* \fIa\fR,const char* \fIb\fR); +.SH DESCRIPTION +\fBstr_equal\fR returns nonzero if \fIa\fR and \fIb\fR match up to and +including the first occurrance of \\0. + +If the strings are different, str_equal does not read bytes past the +first difference. +.SH "SEE ALSO" +strlen(3) diff --git a/str/str_len.3 b/str/str_len.3 new file mode 100644 index 0000000..e91f3d7 --- /dev/null +++ b/str/str_len.3 @@ -0,0 +1,12 @@ +.TH str_len 3 +.SH NAME +str_len \- find length of ASCIIZ string +.SH SYNTAX +.B #include + +extern int \fBstr_len\fP(const char* \fIstring\fR); +.SH DESCRIPTION +str_len returns the index of the first occurrance of \\0 in +\fIstring\fR. +.SH "SEE ALSO" +strlen(3) diff --git a/str/str_len.c b/str/str_len.c new file mode 100644 index 0000000..cf1541a --- /dev/null +++ b/str/str_len.c @@ -0,0 +1,12 @@ +#include "str.h" + +unsigned int str_len(const char *in) { + register const char* t=in; + for (;;) { + if (!*t) break; ++t; + if (!*t) break; ++t; + if (!*t) break; ++t; + if (!*t) break; ++t; + } + return t-in; +} diff --git a/str/str_rchr.3 b/str/str_rchr.3 new file mode 100644 index 0000000..b649650 --- /dev/null +++ b/str/str_rchr.3 @@ -0,0 +1,12 @@ +.TH str_rchr 3 +.SH NAME +str_rchr \- find character in ASCIIZ string +.SH SYNTAX +.B #include + +extern int \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. +.SH "SEE ALSO" +strchr(3) diff --git a/str/str_rchr.c b/str/str_rchr.c new file mode 100644 index 0000000..261737b --- /dev/null +++ b/str/str_rchr.c @@ -0,0 +1,14 @@ +#include "str.h" + +unsigned int str_rchr(const char *in, char needle) { + register const char* t=in; + register const char c=needle; + register const char* found=0; + for (;;) { + if (!*t) break; if (*t==c) found=t; ++t; + if (!*t) break; if (*t==c) found=t; ++t; + if (!*t) break; if (*t==c) found=t; ++t; + if (!*t) break; if (*t==c) found=t; ++t; + } + return (found?found:t)-in; +} diff --git a/str/str_start.3 b/str/str_start.3 new file mode 100644 index 0000000..2595f85 --- /dev/null +++ b/str/str_start.3 @@ -0,0 +1,11 @@ +.TH str_start 3 +.SH NAME +str_start \- compare prefixes of strings +.SH SYNTAX +.B #include + +extern int \fBstr_start\fP(const char* \fIa\fR,const char* \fIb\fR); +.SH DESCRIPTION +str_start returns 1 if \fIb\fR is a prefix of \fIa\fR, 0 otherwise. +.SH "SEE ALSO" +strncmp(3) diff --git a/str/str_start.c b/str/str_start.c new file mode 100644 index 0000000..14b694b --- /dev/null +++ b/str/str_start.c @@ -0,0 +1,14 @@ +#include "byte.h" + +/* str_start returns 1 if the b is a prefix of a, 0 otherwise */ +int str_start(const char* a, const char* b) { + register const char* s=a; + register const char* t=b; + for (;;) { + if (!*t) return 1; if (*s!=*t) break; ++s; ++t; + if (!*t) return 1; if (*s!=*t) break; ++s; ++t; + if (!*t) return 1; if (*s!=*t) break; ++s; ++t; + if (!*t) return 1; if (*s!=*t) break; ++s; ++t; + } + return 0; +} diff --git a/stralloc.h b/stralloc.h new file mode 100644 index 0000000..57e12ca --- /dev/null +++ b/stralloc.h @@ -0,0 +1,78 @@ +#ifndef STRALLOC_H +#define STRALLOC_H + +#include + +typedef struct stralloc { + char* s; + unsigned int len; + unsigned int a; +} stralloc; + +/* stralloc_ready makes sure that sa has enough space allocated to hold + * len bytes: If sa is not allocated, stralloc_ready allocates at least + * len bytes of space, and returns 1. If sa is already allocated, but + * not enough to hold len bytes, stralloc_ready allocates at least len + * bytes of space, copies the old string into the new space, frees the + * old space, and returns 1. Note that this changes sa.s. */ +extern int stralloc_ready(stralloc* sa,unsigned int len) __THROW; + +/* stralloc_readyplus is like stralloc_ready except that, if sa is + * already allocated, stralloc_readyplus adds the current length of sa + * to len. */ +extern int stralloc_readyplus(stralloc* sa,unsigned int len) __THROW; + +/* stralloc_copyb copies the string buf[0], buf[1], ..., buf[len-1] into + * sa, allocating space if necessary, and returns 1. If it runs out of + * memory, stralloc_copyb leaves sa alone and returns 0. */ +extern int stralloc_copyb(stralloc* sa,const char* buf,unsigned int len) __THROW; + +/* stralloc_copys copies a \0-terminated string from buf into sa, + * without the \0. It is the same as + * stralloc_copyb(&sa,buf,str_len(buf)). */ +extern int stralloc_copys(stralloc* sa,const char* buf) __THROW; + +/* stralloc_copy copies the string stored in sa2 into sa. It is the same + * as stralloc_copyb(&sa,sa2.s,sa2.len). sa2 must already be allocated. */ +extern int stralloc_copy(stralloc* sa,stralloc* sa2) __THROW; + +/* stralloc_catb adds the string buf[0], buf[1], ... buf[len-1] to the + * end of the string stored in sa, allocating space if necessary, and + * returns 1. If sa is unallocated, stralloc_catb is the same as + * stralloc_copyb. If it runs out of memory, stralloc_catb leaves sa + * alone and returns 0. */ +extern int stralloc_catb(stralloc* sa,const char* in,unsigned int len) __THROW; + +/* stralloc_cats is analogous to stralloc_copys */ +extern int stralloc_cats(stralloc* sa,const char* in) __THROW; + +/* stralloc_cat is analogous to stralloc_copy */ +extern int stralloc_cat(stralloc* sa,stralloc* in) __THROW; + +/* stralloc_append adds one byte buf[0] to the end of the string stored + * in sa. It is the same as stralloc_catb(&sa,buf,1). */ +extern int stralloc_append(stralloc* sa,const char* in) __THROW; /* beware: this takes a pointer to 1 char */ + +/* stralloc_starts returns 1 if the \0-terminated string in buf, without + * the terminating \0, is a prefix of the string stored in sa. Otherwise + * it returns 0. sa must already be allocated. */ +extern int stralloc_starts(stralloc* sa,const char* in) __THROW; + +/* stralloc_0 appends \0 */ +#define stralloc_0(sa) stralloc_append(sa,"") + +/* stralloc_catulong0 appends a '0' padded ASCII representation of in */ +extern int stralloc_catulong0(stralloc* sa,unsigned long in,unsigned int n) __THROW; + +/* stralloc_catlong0 appends a '0' padded ASCII representation of in */ +extern int stralloc_catlong0(stralloc* sa,signed long in,unsigned int n) __THROW; + +/* stralloc_free frees the storage associated with sa */ +extern void stralloc_free(stralloc* sa) __THROW; + +#define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0)) +#define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(i),(n))) +#define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(i),(n))) +#define stralloc_catint(sa,i) (stralloc_catlong0((sa),(i),0)) + +#endif diff --git a/stralloc/stralloc_0.3 b/stralloc/stralloc_0.3 new file mode 100644 index 0000000..5e83d48 --- /dev/null +++ b/stralloc/stralloc_0.3 @@ -0,0 +1,13 @@ +.TH stralloc_0 3 +.SH NAME +stralloc_0 \- append \\0 to a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_0\fP(stralloc* \fIsa\fR); +.SH DESCRIPTION +stralloc_0 appends \\0 to a stralloc. + +It is a shortcut for stralloc_append(\fIsa\fR,""). +.SH "SEE ALSO" +stralloc_append(3) diff --git a/stralloc/stralloc_append.3 b/stralloc/stralloc_append.3 new file mode 100644 index 0000000..1bc52a0 --- /dev/null +++ b/stralloc/stralloc_append.3 @@ -0,0 +1,16 @@ +.TH stralloc_append 3 +.SH NAME +stralloc_append \- append a character to a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_append\fP(stralloc* \fIsa\fR,const char* \fIin\fR); +.SH DESCRIPTION +stralloc_append appends the byte from *\fIbuf\fR to the +string stored in \fIsa\fR, allocating space if necessary, and +returns 1. + +If it runs out of memory, stralloc_append leaves \fIsa\fR alone and +returns 0. +.SH "SEE ALSO" +stralloc_copyb(3) diff --git a/stralloc/stralloc_append.c b/stralloc/stralloc_append.c new file mode 100644 index 0000000..068d83b --- /dev/null +++ b/stralloc/stralloc_append.c @@ -0,0 +1,13 @@ +#include "stralloc.h" + +/* stralloc_append adds one byte buf[0] to the end of the string stored + * in sa. It is the same as stralloc_catb(&sa,buf,1). */ +int stralloc_append(stralloc *sa,const char *in) { + if (stralloc_readyplus(sa,1)) { + sa->s[sa->len]=*in; + ++sa->len; + return 1; + } + return 0; +} + diff --git a/stralloc/stralloc_cat.3 b/stralloc/stralloc_cat.3 new file mode 100644 index 0000000..add2caf --- /dev/null +++ b/stralloc/stralloc_cat.3 @@ -0,0 +1,16 @@ +.TH stralloc_cat 3 +.SH NAME +stralloc_cat \- append data to a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_cat\fP(stralloc* \fIsato\fR,stralloc* \fIsafrom\fR); +.SH DESCRIPTION +stralloc_cat appends the string stored in \fIsafrom\fR to \fIsa\fR. It +is the same as +\fBstralloc_catb\fR(&\fIsato\fR, \fIsafrom\fR.s, \fIsafrom\fR.len). +\fIsafrom\fR must already be allocated. + +The data that \fIsa\fR previously contained is overwritten and truncated. +.SH "SEE ALSO" +stralloc_catb(3) diff --git a/stralloc/stralloc_cat.c b/stralloc/stralloc_cat.c new file mode 100644 index 0000000..1c0666b --- /dev/null +++ b/stralloc/stralloc_cat.c @@ -0,0 +1,7 @@ +#include "stralloc.h" +#include "str.h" + +extern int stralloc_cat(stralloc *sa,stralloc *sa2) { + return stralloc_catb(sa,sa2->s,sa2->len); +} + diff --git a/stralloc/stralloc_catb.3 b/stralloc/stralloc_catb.3 new file mode 100644 index 0000000..e04b9be --- /dev/null +++ b/stralloc/stralloc_catb.3 @@ -0,0 +1,14 @@ +.TH stralloc_catb 3 +.SH NAME +stralloc_catb \- append data to a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_catb\fP(stralloc* \fIsa\fR,const char* \fIbuf\fR,unsigned int \fIlen\fR); +.SH DESCRIPTION +stralloc_catb adds the string \fIbuf\fR[0], \fIbuf\fR[1], ... \fIbuf\fR[\fIlen\fR-1] to the +end of the string stored in \fIsa\fR, allocating space if necessary, and +returns 1. If \fIsa\fR is unallocated, stralloc_catb is the same as +stralloc_copyb. If it runs out of memory, stralloc_catb leaves \fIsa\fR +alone and returns 0. + diff --git a/stralloc/stralloc_catb.c b/stralloc/stralloc_catb.c new file mode 100644 index 0000000..ed28912 --- /dev/null +++ b/stralloc/stralloc_catb.c @@ -0,0 +1,16 @@ +#include "byte.h" +#include "stralloc.h" + +/* stralloc_catb adds the string buf[0], buf[1], ... buf[len-1] to the + * end of the string stored in sa, allocating space if necessary, and + * returns 1. If sa is unallocated, stralloc_catb is the same as + * stralloc_copyb. If it runs out of memory, stralloc_catb leaves sa + * alone and returns 0. */ +int stralloc_catb(stralloc *sa,const char *buf,unsigned int len) { + if (stralloc_readyplus(sa,len)) { + byte_copy(sa->s+sa->len,len,buf); + sa->len+=len; + return 1; + } + return 0; +} diff --git a/stralloc/stralloc_catlong0.3 b/stralloc/stralloc_catlong0.3 new file mode 100644 index 0000000..5938170 --- /dev/null +++ b/stralloc/stralloc_catlong0.3 @@ -0,0 +1,15 @@ +.TH stralloc_catlong0 3 +.SH NAME +stralloc_catlong0 \- append an integer to a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_catlong0\fP(stralloc* \fIsa\fR, unsigned long \fIin\fR, unsigned int \fIn\fR); +.SH DESCRIPTION +stralloc_catlong0 converts in to a string using \fBfmt_long0\fR and +appends the result to \fIsa\fR, allocating memory as necessary. + +If there was a memory allocation failure, stralloc_catlong0 returns 0, +else 1. +.SH "SEE ALSO" +fmt_long0(3) diff --git a/stralloc/stralloc_catlong0.c b/stralloc/stralloc_catlong0.c new file mode 100644 index 0000000..66c6160 --- /dev/null +++ b/stralloc/stralloc_catlong0.c @@ -0,0 +1,11 @@ +#include "stralloc.h" +#include "fmt.h" + +int stralloc_catlong0(stralloc *sa,signed long in,unsigned int n) { + if (stralloc_readyplus(sa,fmt_minus(0,in)+fmt_ulong0(0,in,n))) { + sa->len+=fmt_minus(sa->s+sa->len,in); + sa->len+=fmt_ulong0(sa->s+sa->len,in>=0?in:-in,n); + return 1; + } else + return 0; +} diff --git a/stralloc/stralloc_cats.3 b/stralloc/stralloc_cats.3 new file mode 100644 index 0000000..fa0a5e2 --- /dev/null +++ b/stralloc/stralloc_cats.3 @@ -0,0 +1,15 @@ +.TH stralloc_cats 3 +.SH NAME +stralloc_cats \- append data to a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_cats\fP(stralloc* \fIsa\fR,const char* \fIbuf\fR); +.SH DESCRIPTION +stralloc_cats appends a \\0-terminated string from \fIbuf\fR to the +end of the string stored in \fIsa\fR, allocating space if necessary, and +returns 1. If \fIsa\fR is unallocated, stralloc_cats is the same as +stralloc_copys. If it runs out of memory, stralloc_cats leaves \fIsa\fR +alone and returns 0. +.SH "SEE ALSO" +stralloc_copyb(3) diff --git a/stralloc/stralloc_cats.c b/stralloc/stralloc_cats.c new file mode 100644 index 0000000..483f099 --- /dev/null +++ b/stralloc/stralloc_cats.c @@ -0,0 +1,7 @@ +#include "stralloc.h" +#include "str.h" + +extern int stralloc_cats(stralloc *sa,const char *buf) { + return stralloc_catb(sa,buf,str_len(buf)); +} + diff --git a/stralloc/stralloc_catulong0.3 b/stralloc/stralloc_catulong0.3 new file mode 100644 index 0000000..c2a8bd7 --- /dev/null +++ b/stralloc/stralloc_catulong0.3 @@ -0,0 +1,15 @@ +.TH stralloc_catulong0 3 +.SH NAME +stralloc_catulong0 \- append an integer to a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_catulong0\fP(stralloc* \fIsa\fR, unsigned long \fIin\fR, unsigned int \fIn\fR); +.SH DESCRIPTION +stralloc_catulong0 converts in to a string using \fBfmt_ulong0\fR and +appends the result to \fIsa\fR, allocating memory as necessary. + +If there was a memory allocation failure, stralloc_catulong0 returns 0, +else 1. +.SH "SEE ALSO" +fmt_ulong0(3) diff --git a/stralloc/stralloc_catulong0.c b/stralloc/stralloc_catulong0.c new file mode 100644 index 0000000..f0f8eba --- /dev/null +++ b/stralloc/stralloc_catulong0.c @@ -0,0 +1,10 @@ +#include "stralloc.h" +#include "fmt.h" + +int stralloc_catulong0(stralloc *sa,unsigned long in,unsigned int n) { + if (stralloc_readyplus(sa,fmt_ulong0(0,in,n))) { + sa->len+=fmt_ulong0(sa->s+sa->len,in,n); + return 1; + } else + return 0; +} diff --git a/stralloc/stralloc_copy.3 b/stralloc/stralloc_copy.3 new file mode 100644 index 0000000..49e4a6c --- /dev/null +++ b/stralloc/stralloc_copy.3 @@ -0,0 +1,16 @@ +.TH stralloc_copy 3 +.SH NAME +stralloc_copy \- copy data into a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_copy\fP(stralloc* \fIsato\fR,stralloc* \fIsafrom\fR); +.SH DESCRIPTION +stralloc_copy copies the string stored in \fIsafrom\fR into \fIsa\fR. It +is the same as +\fBstralloc_copyb\fR(&\fIsato\fR, \fIsafrom\fR.s, \fIsafrom\fR.len). +\fIsafrom\fR must already be allocated. + +The data that \fIsa\fR previously contained is overwritten and truncated. +.SH "SEE ALSO" +stralloc_copyb(3) diff --git a/stralloc/stralloc_copy.c b/stralloc/stralloc_copy.c new file mode 100644 index 0000000..3504e68 --- /dev/null +++ b/stralloc/stralloc_copy.c @@ -0,0 +1,7 @@ +#include "stralloc.h" +#include "str.h" + +extern int stralloc_copy(stralloc *sa,stralloc *sa2) { + return stralloc_copyb(sa,sa2->s,sa2->len); +} + diff --git a/stralloc/stralloc_copyb.3 b/stralloc/stralloc_copyb.3 new file mode 100644 index 0000000..93dd1f3 --- /dev/null +++ b/stralloc/stralloc_copyb.3 @@ -0,0 +1,13 @@ +.TH stralloc_copyb 3 +.SH NAME +stralloc_copyb \- copy data into a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_copyb\fP(stralloc* \fIsa\fR,const char* \fIbuf\fR,unsigned int \fIlen\fR); +.SH DESCRIPTION +stralloc_copyb makes sure that \fIsa\fR has enough space allocated to hold +\fIlen\fR bytes. Then it copies the first \fIlen\fR bytes from +\fIbuf\fR into the stralloc. + +The data that \fIsa\fR previously contained is overwritten and truncated. diff --git a/stralloc/stralloc_copyb.c b/stralloc/stralloc_copyb.c new file mode 100644 index 0000000..0729874 --- /dev/null +++ b/stralloc/stralloc_copyb.c @@ -0,0 +1,14 @@ +#include "byte.h" +#include "stralloc.h" + +/* stralloc_copyb copies the string buf[0], buf[1], ..., buf[len-1] into + * sa, allocating space if necessary, and returns 1. If it runs out of + * memory, stralloc_copyb leaves sa alone and returns 0. */ +int stralloc_copyb(stralloc *sa,const char *buf,unsigned int len) { + if (stralloc_ready(sa,len)) { + sa->len=len; + byte_copy(sa->s,len,buf); + return 1; + } + return 0; +} diff --git a/stralloc/stralloc_copys.3 b/stralloc/stralloc_copys.3 new file mode 100644 index 0000000..f6f339d --- /dev/null +++ b/stralloc/stralloc_copys.3 @@ -0,0 +1,15 @@ +.TH stralloc_copys 3 +.SH NAME +stralloc_copys \- copy data into a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_copys\fP(stralloc* \fIsa\fR,const char* \fIbuf\fR); +.SH DESCRIPTION +stralloc_copys copies a \\0-terminated string from \fIbuf\fR into +\fIsa\fR, without the \\0. It is the same as +\fBstralloc_copyb\fR(&\fIsa\fR, \fIbuf\fR, str_len(\fIbuf\fR)). + +The data that \fIsa\fR previously contained is overwritten and truncated. +.SH "SEE ALSO" +stralloc_copyb(3) diff --git a/stralloc/stralloc_copys.c b/stralloc/stralloc_copys.c new file mode 100644 index 0000000..80360ea --- /dev/null +++ b/stralloc/stralloc_copys.c @@ -0,0 +1,7 @@ +#include "stralloc.h" +#include "str.h" + +extern int stralloc_copys(stralloc *sa,const char *buf) { + return stralloc_copyb(sa,buf,str_len(buf)); +} + diff --git a/stralloc/stralloc_free.3 b/stralloc/stralloc_free.3 new file mode 100644 index 0000000..c10a2e3 --- /dev/null +++ b/stralloc/stralloc_free.3 @@ -0,0 +1,12 @@ +.TH stralloc_free 3 +.SH NAME +stralloc_free \- free storage associated with a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_free\fP(stralloc* \fIsa\fR); +.SH DESCRIPTION +stralloc_free returns the storage associated with \fIsa\fR to the +system. Afterwards, the stralloc is unallocated. +.SH "SEE ALSO" +stralloc_ready(3) diff --git a/stralloc/stralloc_free.c b/stralloc/stralloc_free.c new file mode 100644 index 0000000..c5e5a4d --- /dev/null +++ b/stralloc/stralloc_free.c @@ -0,0 +1,7 @@ +#include +#include "stralloc.h" + +void stralloc_free(stralloc *sa) { + if (sa->s) free(sa->s); + sa->s=0; +} diff --git a/stralloc/stralloc_ready.3 b/stralloc/stralloc_ready.3 new file mode 100644 index 0000000..1dcabba --- /dev/null +++ b/stralloc/stralloc_ready.3 @@ -0,0 +1,16 @@ +.TH stralloc_ready 3 +.SH NAME +stralloc_ready \- provide space in a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_ready\fP(stralloc* \fIsa\fR,unsigned int \fIlen\fR); +.SH DESCRIPTION +stralloc_ready makes sure that \fIsa\fR has enough space allocated to hold +\fIlen\fR bytes: If \fIsa\fR is not allocated, stralloc_ready allocates at least +\fIlen\fR bytes of space, and returns 1. If \fIsa\fR is already allocated, but +not enough to hold \fIlen\fR bytes, stralloc_ready allocates at least \fIlen\fR +bytes of space, copies the old string into the new space, frees the +old space, and returns 1. Note that this changes \fIsa\fR.s. +.SH "SEE ALSO" +stralloc_readyplus(3) diff --git a/stralloc/stralloc_ready.c b/stralloc/stralloc_ready.c new file mode 100644 index 0000000..6de7018 --- /dev/null +++ b/stralloc/stralloc_ready.c @@ -0,0 +1,20 @@ +#include "stralloc.h" +#include + +/* stralloc_ready makes sure that sa has enough space allocated to hold + * len bytes: If sa is not allocated, stralloc_ready allocates at least + * len bytes of space, and returns 1. If sa is already allocated, but + * not enough to hold len bytes, stralloc_ready allocates at least len + * bytes of space, copies the old string into the new space, frees the + * old space, and returns 1. Note that this changes sa.s. */ +int stralloc_ready(stralloc *sa,unsigned int len) { + register int wanted=len+(len>>3)+30; /* heuristic from djb */ + if (!sa->s || sa->as,wanted))) + return 0; + sa->a=wanted; + sa->s=tmp; + } + return 1; +} diff --git a/stralloc/stralloc_readyplus.3 b/stralloc/stralloc_readyplus.3 new file mode 100644 index 0000000..dfba9a0 --- /dev/null +++ b/stralloc/stralloc_readyplus.3 @@ -0,0 +1,18 @@ +.TH stralloc_readyplus 3 +.SH NAME +stralloc_readyplus \- provide space in a stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_readyplus\fP(stralloc* \fIsa\fR,unsigned int \fIlen\fR); +.SH DESCRIPTION +stralloc_readyplus makes sure that \fIsa\fR has enough space allocated +to hold an additional \fIlen\fR bytes: If \fIsa\fR is not allocated, +stralloc_ready allocates at least \fIlen\fR bytes of space, and returns +1. If \fIsa\fR is already allocated, but not enough to hold \fIlen\fR +additional bytes, stralloc_ready allocates at least +\fIsa\fR->len+\fIlen\fR bytes of space, copies the old string into the +new space, frees the old space, and returns 1. Note that this changes +\fIsa\fR.s. +.SH "SEE ALSO" +stralloc_ready(3) diff --git a/stralloc/stralloc_readyplus.c b/stralloc/stralloc_readyplus.c new file mode 100644 index 0000000..3140164 --- /dev/null +++ b/stralloc/stralloc_readyplus.c @@ -0,0 +1,12 @@ +#include "stralloc.h" +#include + +/* stralloc_readyplus is like stralloc_ready except that, if sa is + * already allocated, stralloc_readyplus adds the current length of sa + * to len. */ +int stralloc_readyplus(stralloc *sa,unsigned int len) { + if (sa->s) + return stralloc_ready(sa,sa->len+len); + else + return stralloc_ready(sa,len); +} diff --git a/stralloc/stralloc_starts.3 b/stralloc/stralloc_starts.3 new file mode 100644 index 0000000..5c49623 --- /dev/null +++ b/stralloc/stralloc_starts.3 @@ -0,0 +1,13 @@ +.TH stralloc_starts 3 +.SH NAME +stralloc_starts \- check if string is prefix of stralloc +.SH SYNTAX +.B #include + +extern int \fBstralloc_starts\fP(stralloc* \fIsa\fR,const char* \fIin\fR); +.SH DESCRIPTION +stralloc_starts returns 1 if the \\0-terminated string in \fIbuf\fR, without +the terminating \\0, is a prefix of the string stored in \fIsa\fR. Otherwise +it returns 0. \fIsa\fR must already be allocated. +.SH "SEE ALSO" +str_starts(3) diff --git a/stralloc/stralloc_starts.c b/stralloc/stralloc_starts.c new file mode 100644 index 0000000..ff011a1 --- /dev/null +++ b/stralloc/stralloc_starts.c @@ -0,0 +1,9 @@ +#include "stralloc.h" +#include "byte.h" +#include "str.h" + +extern int stralloc_starts(stralloc *sa,const char *in) { + register int len=str_len(in); + return (len<=sa->len && !byte_diff(sa->s,len,in)); +} + diff --git a/t.c b/t.c new file mode 100644 index 0000000..be35080 --- /dev/null +++ b/t.c @@ -0,0 +1,44 @@ +#include "fmt.h" +#include "scan.h" +#include "str.h" +#include "uint16.h" +#include "uint32.h" +#include "stralloc.h" +#include "socket.h" + +#define rdtscl(low) \ + __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") + +int main(int argc,char* argv[]) { + int s=socket_tcp4(); + char ip[4]={127,0,0,1}; + int t=socket_connect4(s,ip,80); +#if 0 + char buf[100]="foo bar baz fnord "; + char buf2[100]="foo braz fnord"; + long a,b,c; + long i=0,j=0,k=0; + double d; + uint32 l,m,n; + stralloc sa={0}; + stralloc_copys(&sa,"fnord"); + stralloc_catlong0(&sa,-23,5); + stralloc_append(&sa,"\n"); + printf("%d %d\n",str_equal("fnord","fnord1"),str_equal("fnord1","fnord")); + write(1,sa.s,sa.len); + printf("%d %d\n",stralloc_starts(&sa,"fnord"),stralloc_starts(&sa,"fnord\na")); + + l=0xdeadbeef; + uint32_pack_big((char*)&m,l); + uint32_unpack_big((char*)&m,&n); + printf("%x %x %x\n",l,m,n); + + rdtscl(a); +/* i=scan_double("3.1415",&d); */ + rdtscl(b); + /*byte_zero_djb(buf,j); */ + rdtscl(c); + printf("%lu %lu\n",b-a,c-b); +#endif +} + diff --git a/uint/uint16_pack.3 b/uint/uint16_pack.3 new file mode 100644 index 0000000..1891e58 --- /dev/null +++ b/uint/uint16_pack.3 @@ -0,0 +1,18 @@ +.TH uint16_pack 3 +.SH NAME +uint16_pack \- write an unsigned little-endian 16-bit integer +.SH SYNTAX +.B #include + +uint16 \fIu\fR; + +void \fBuint16_pack\fP(char \fIs\fR[2],uint16 \fIu\fR); +.SH DESCRIPTION +uint16 is a 16-bit unsigned integer type, normally either unsigned int +or unsigned long. + +uint16_unpack portably reads a uint16 as stored on a little-endian +architecture from \fIs\fR and writes it info \fIr\fR in the native byte order. + +.SH "SEE ALSO" +uint16_unpack(3), uint16_pack_big(3) diff --git a/uint/uint16_pack.c b/uint/uint16_pack.c new file mode 100644 index 0000000..3a2eb8f --- /dev/null +++ b/uint/uint16_pack.c @@ -0,0 +1,8 @@ +#define NO_UINT16_MACROS +#include "uint16.h" +#include + +void uint16_pack(char *out,uint16 in) { + out[0]=in&255; + out[1]=in>>8; +} diff --git a/uint/uint16_pack_big.3 b/uint/uint16_pack_big.3 new file mode 100644 index 0000000..de4e089 --- /dev/null +++ b/uint/uint16_pack_big.3 @@ -0,0 +1,19 @@ +.TH uint16_pack_big 3 +.SH NAME +uint16_pack_big \- write an unsigned big-endian 16-bit integer +.SH SYNTAX +.B #include + +uint16 \fIu\fR; + +void \fBuint16_pack_big\fP(char \fIs\fR[2],uint16 \fIu\fR); +.SH DESCRIPTION +uint16 is a 16-bit unsigned integer type, normally either unsigned int +or unsigned long. + +uint16_unpack_big portably reads a uint16 as stored on a big-endian +architecture (i.e. in network byte order) from \fIs\fR and writes it +info \fIr\fR in the native byte order. + +.SH "SEE ALSO" +uint16_unpack_big(3), uint16_pack(3) diff --git a/uint/uint16_pack_big.c b/uint/uint16_pack_big.c new file mode 100644 index 0000000..6b8efe4 --- /dev/null +++ b/uint/uint16_pack_big.c @@ -0,0 +1,8 @@ +#define NO_UINT16_MACROS +#include "uint16.h" +#include + +void uint16_pack_big(char *out,uint16 in) { + out[0]=in>>8; + out[1]=in&255; +} diff --git a/uint/uint16_unpack.3 b/uint/uint16_unpack.3 new file mode 100644 index 0000000..8e0134a --- /dev/null +++ b/uint/uint16_unpack.3 @@ -0,0 +1,18 @@ +.TH uint16_unpack 3 +.SH NAME +uint16_unpack \- read an unsigned little-endian 16-bit integer +.SH SYNTAX +.B #include + +uint16 \fIu\fR; + +void \fBuint16_unpack\fP(const char \fIs\fR[2],uint16 *\fIu\fR); +.SH DESCRIPTION +uint16 is a 16-bit unsigned integer type, normally either unsigned int +or unsigned long. + +uint16_unpack portably reads a uint16 as stored on a little-endian +architecture from \fIs\fR and writes it info \fIr\fR in the native byte order. + +.SH "SEE ALSO" +uint16_pack(3), uint16_unpack_big(3) diff --git a/uint/uint16_unpack.c b/uint/uint16_unpack.c new file mode 100644 index 0000000..7716a7c --- /dev/null +++ b/uint/uint16_unpack.c @@ -0,0 +1,6 @@ +#define NO_UINT16_MACROS +#include "uint16.h" + +void uint16_unpack(const char *in,uint16 *out) { + *out = ((unsigned short)((unsigned char) in[1]) << 8) + (unsigned char)in[0]; +} diff --git a/uint/uint16_unpack_big.3 b/uint/uint16_unpack_big.3 new file mode 100644 index 0000000..8fa8461 --- /dev/null +++ b/uint/uint16_unpack_big.3 @@ -0,0 +1,19 @@ +.TH uint16_unpack_big 3 +.SH NAME +uint16_unpack_big \- read an unsigned big-endian 16-bit integer +.SH SYNTAX +.B #include + +uint16 \fIu\fR; + +void \fBuint16_unpack_big\fP(const char \fIs\fR[2],uint16 *\fIu\fR); +.SH DESCRIPTION +uint16 is a 16-bit unsigned integer type, normally either unsigned int +or unsigned long. + +uint16_unpack_big portably reads a uint16 as stored on a big-endian +architecture (i.e. in network byte order) from \fIs\fR and writes it +info \fIr\fR in the native byte order. + +.SH "SEE ALSO" +uint16_pack_big(3), uint16_unpack(3) diff --git a/uint/uint16_unpack_big.c b/uint/uint16_unpack_big.c new file mode 100644 index 0000000..5763e2b --- /dev/null +++ b/uint/uint16_unpack_big.c @@ -0,0 +1,6 @@ +#define NO_UINT16_MACROS +#include "uint16.h" + +void uint16_unpack_big(const char *in,uint16 *out) { + *out = ((unsigned short)((unsigned char) in[0]) << 8) + (unsigned char)in[1]; +} diff --git a/uint/uint32_pack.3 b/uint/uint32_pack.3 new file mode 100644 index 0000000..d200950 --- /dev/null +++ b/uint/uint32_pack.3 @@ -0,0 +1,18 @@ +.TH uint32_pack 3 +.SH NAME +uint32_pack \- write an unsigned little-endian 32-bit integer +.SH SYNTAX +.B #include + +uint32 \fIu\fR; + +void \fBuint32_pack\fP(char \fIs\fR[4],uint32 \fIu\fR); +.SH DESCRIPTION +uint32 is a 32-bit unsigned integer type, normally either unsigned int +or unsigned long. + +uint32_unpack portably reads a uint32 as stored on a little-endian +architecture from \fIs\fR and writes it info \fIr\fR in the native byte order. + +.SH "SEE ALSO" +uint32_unpack(3), uint32_pack_big(3) diff --git a/uint/uint32_pack.c b/uint/uint32_pack.c new file mode 100644 index 0000000..7d8fee5 --- /dev/null +++ b/uint/uint32_pack.c @@ -0,0 +1,10 @@ +#define NO_UINT32_MACROS +#include "uint32.h" +#include + +void uint32_pack(char *out,uint32 in) { + *out=in&0xff; in>>=8; + *++out=in&0xff; in>>=8; + *++out=in&0xff; in>>=8; + *++out=in&0xff; +} diff --git a/uint/uint32_pack_big.3 b/uint/uint32_pack_big.3 new file mode 100644 index 0000000..460d56d --- /dev/null +++ b/uint/uint32_pack_big.3 @@ -0,0 +1,19 @@ +.TH uint32_pack_big 3 +.SH NAME +uint32_pack_big \- write an unsigned big-endian 32-bit integer +.SH SYNTAX +.B #include + +uint32 \fIu\fR; + +void \fBuint32_pack_big\fP(char \fIs\fR[4],uint32 \fIu\fR); +.SH DESCRIPTION +uint32 is a 32-bit unsigned integer type, normally either unsigned int +or unsigned long. + +uint32_unpack_big portably reads a uint32 as stored on a big-endian +architecture (i.e. in network byte order) from \fIs\fR and writes it +info \fIr\fR in the native byte order. + +.SH "SEE ALSO" +uint32_unpack_big(3), uint32_pack(3) diff --git a/uint/uint32_pack_big.c b/uint/uint32_pack_big.c new file mode 100644 index 0000000..777c181 --- /dev/null +++ b/uint/uint32_pack_big.c @@ -0,0 +1,10 @@ +#define NO_UINT32_MACROS +#include "uint32.h" +#include + +void uint32_pack_big(char *out,uint32 in) { + out[3]=in&0xff; in>>=8; + out[2]=in&0xff; in>>=8; + out[1]=in&0xff; in>>=8; + out[0]=in&0xff; +} diff --git a/uint/uint32_unpack.3 b/uint/uint32_unpack.3 new file mode 100644 index 0000000..406944c --- /dev/null +++ b/uint/uint32_unpack.3 @@ -0,0 +1,18 @@ +.TH uint32_unpack 3 +.SH NAME +uint32_unpack \- read an unsigned little-endian 32-bit integer +.SH SYNTAX +.B #include + +uint32 \fIu\fR; + +void \fBuint32_unpack\fP(const char \fIs\fR[4],uint32 *\fIu\fR); +.SH DESCRIPTION +uint32 is a 32-bit unsigned integer type, normally either unsigned int +or unsigned long. + +uint32_unpack portably reads a uint32 as stored on a little-endian +architecture from \fIs\fR and writes it info \fIr\fR in the native byte order. + +.SH "SEE ALSO" +uint32_pack(3), uint32_unpack_big(3) diff --git a/uint/uint32_unpack.c b/uint/uint32_unpack.c new file mode 100644 index 0000000..ce45a9e --- /dev/null +++ b/uint/uint32_unpack.c @@ -0,0 +1,9 @@ +#define NO_UINT32_MACROS +#include "uint32.h" + +void uint32_unpack(const char *in,uint32 *out) { + *out = (((uint32)(unsigned char)in[3])<<24) | + (((uint32)(unsigned char)in[2])<<16) | + (((uint32)(unsigned char)in[1])<<8) | + (uint32)(unsigned char)in[0]; +} diff --git a/uint/uint32_unpack_big.3 b/uint/uint32_unpack_big.3 new file mode 100644 index 0000000..03fe601 --- /dev/null +++ b/uint/uint32_unpack_big.3 @@ -0,0 +1,19 @@ +.TH uint32_unpack_big 3 +.SH NAME +uint32_unpack_big \- read an unsigned big-endian 32-bit integer +.SH SYNTAX +.B #include + +uint32 \fIu\fR; + +void \fBuint32_unpack_big\fP(const char \fIs\fR[4],uint32 *\fIu\fR); +.SH DESCRIPTION +uint32 is a 32-bit unsigned integer type, normally either unsigned int +or unsigned long. + +uint32_unpack_big portably reads a uint32 as stored on a big-endian +architecture (i.e. in network byte order) from \fIs\fR and writes it +info \fIr\fR in the native byte order. + +.SH "SEE ALSO" +uint32_pack_big(3), uint32_unpack(3) diff --git a/uint/uint32_unpack_big.c b/uint/uint32_unpack_big.c new file mode 100644 index 0000000..9e7bdda --- /dev/null +++ b/uint/uint32_unpack_big.c @@ -0,0 +1,9 @@ +#define NO_UINT32_MACROS +#include "uint32.h" + +void uint32_unpack_big(const char *in,uint32 *out) { + *out = (((uint32)(unsigned char)in[0])<<24) | + (((uint32)(unsigned char)in[1])<<16) | + (((uint32)(unsigned char)in[2])<<8) | + (uint32)(unsigned char)in[3]; +} diff --git a/uint16.h b/uint16.h new file mode 100644 index 0000000..1b7f07a --- /dev/null +++ b/uint16.h @@ -0,0 +1,41 @@ +#ifndef UINT16_H +#define UINT16_H + +#include + +typedef unsigned short uint16; + +#ifdef NO_UINT16_MACROS +extern void uint16_pack(char *out,uint16 in) __THROW; +extern void uint16_pack_big(char *out,uint16 in) __THROW; +extern void uint16_unpack(const char *in,uint16* out) __THROW; +extern void uint16_unpack_big(const char *in,uint16* out) __THROW; +#else + +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +#define uint16_pack(out,in) (*(short*)(out)=(in)) + +extern void uint16_pack_big(char *out,uint16 in) __THROW; + +#define uint16_unpack(in,out) (*(out)=*(short*)(in)) + +extern void uint16_unpack_big(const char *in,uint16* out) __THROW; + +#else + +extern void uint16_pack(char *out,uint16 in) __THROW; + +#define uint16_pack_big(out,in) (*(short*)(out)=(in)) + +extern void uint16_unpack(const char *in,uint16* out) __THROW; + +#define uint16_unpack_big(in,out) (*(out)=*(short*)(in)) + +#endif + +#endif + +#endif diff --git a/uint32.h b/uint32.h new file mode 100644 index 0000000..747f36b --- /dev/null +++ b/uint32.h @@ -0,0 +1,41 @@ +#ifndef UINT32_H +#define UINT32_H + +#include + +typedef unsigned int uint32; + +#ifdef NO_UINT32_MACROS +extern void uint32_pack(char *out,uint32 in) __THROW; +extern void uint32_pack_big(char *out,uint32 in) __THROW; +extern void uint32_unpack(const char *in,uint32* out) __THROW; +extern void uint32_unpack_big(const char *in,uint32* out) __THROW; +#else + +#include + +#if __BYTE_ORDER == __LITTLE_ENDIAN + +#define uint32_pack(out,in) (*(uint32*)(out)=(in)) + +extern void uint32_pack_big(char *out,uint32 in) __THROW; + +#define uint32_unpack(in,out) (*(out)=*(uint32*)(in)) + +extern void uint32_unpack_big(const char *in,uint32* out) __THROW; + +#else + +extern void uint32_pack(char *out,uint32 in) __THROW; + +#define uint32_pack_big(out,in) (*(uint32*)(out)=(in)) + +extern void uint32_unpack(const char *in,uint32* out) __THROW; + +#define uint32_unpack_big(in,out) (*(out)=*(uint32*)(in)) + +#endif + +#endif + +#endif diff --git a/uint64.h b/uint64.h new file mode 100644 index 0000000..59bc45b --- /dev/null +++ b/uint64.h @@ -0,0 +1,13 @@ +#ifndef UINT64_H +#define UINT64_H + +#include +#include + +#if __WORDSIZE == 64 +typedef unsigned long uint64; +#else +typedef unsigned long long uint64; +#endif + +#endif diff --git a/unix/ndelay_off.3 b/unix/ndelay_off.3 new file mode 100644 index 0000000..d5fc695 --- /dev/null +++ b/unix/ndelay_off.3 @@ -0,0 +1,18 @@ +.TH ndelay_off 3 +.SH NAME +ndelay_off \- put file descriptor in non-blocking mode +.SH SYNTAX +.B #include + +extern int \fBndelay_off\fP(int \fIfd\fR); +.SH DESCRIPTION +ndelay_off puts a file descriptor in blocking mode. Reading from and +writing to blocking network sockets, FIFOs or device files will possibly +not return immediately but wait on more input or buffer space for +output. + +If an error occurred, ndelay_off will return nonzero and set \fIerrno\fR +accordingly. + +.SH "SEE ALSO" +fcntl(2), ndelay_on(3) diff --git a/unix/ndelay_off.c b/unix/ndelay_off.c new file mode 100644 index 0000000..036083e --- /dev/null +++ b/unix/ndelay_off.c @@ -0,0 +1,12 @@ +#include +#include + +#include "ndelay.h" + +#ifndef O_NDELAY +#define O_NDELAY O_NONBLOCK +#endif + +int ndelay_on(int fd) { + return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NDELAY); +} diff --git a/unix/ndelay_on.3 b/unix/ndelay_on.3 new file mode 100644 index 0000000..21f84bb --- /dev/null +++ b/unix/ndelay_on.3 @@ -0,0 +1,18 @@ +.TH ndelay_on 3 +.SH NAME +ndelay_on \- put file descriptor in non-blocking mode +.SH SYNTAX +.B #include + +extern int \fBndelay_on\fP(int \fIfd\fR); +.SH DESCRIPTION +ndelay_on puts a file descriptor in non-blocking mode. Reading from and +writing to non-blocking network sockets, FIFOs or device files will +return immediately, even if not as many bytes have been processed as +were specified. + +If an error occurred, ndelay_on will return nonzero and set \fIerrno\fR +accordingly. + +.SH "SEE ALSO" +fcntl(2), ndelay_off(3) diff --git a/unix/ndelay_on.c b/unix/ndelay_on.c new file mode 100644 index 0000000..fc80eb2 --- /dev/null +++ b/unix/ndelay_on.c @@ -0,0 +1,12 @@ +#include +#include + +#include "ndelay.h" + +#ifndef O_NDELAY +#define O_NDELAY O_NONBLOCK +#endif + +int ndelay_on(int fd) { + return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NDELAY); +}