Subject: strings (1 of 3) Newsgroups: mod.sources Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 110 Submitted by: This is a public domain strings package written by Richard O'Keefe (whose net address I've lost) that was originally posted to net.sources about two years ago. Just about every Unix-oid strings function you've ever heard of is here. I haven't touched any of this code; I'm just reposting it. I have used many of the routines and all the ones I've used work. The package is very well put together and coded -- hats off to Richard. -- Larry Campbell The Boston Software Works, Inc. ARPA: maynard.UUCP:campbell@harvard.ARPA 120 Fulton Street UUCP: {harvard,cbosgd}!wjh12!maynard!campbell Boston MA 02109 #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Makefile # READ-ME # _c2type.c # _str2map.c # _str2map.h # _str2pat.c # _str2pat.h # _str2set.c # _str2set.h # ascii.h # bcmp.c # bcopy.c # bfill.c # bmove.c # bzero.c # ctypes.dem # ctypes.h # ffs.c # getopt.3 # getopt.c # int2str.c # memccpy.c # memchr.c # memcmp.c # memcpy.c # memmov.c # memory.h # memrchr.c # memrev.c # memset.c # memtrans.c sed 's/^X//' << 'SHAR_EOF' > Makefile X# File : strings.d/Makefile X# Author : Richard A. O'Keefe. X# Updated: 2 June 1984. X# Purpose: UNIX make(1)file for the strings library. X X# If you are not using a Vax, or if your strings might be 2^16 X# characters long or longer, use X# CFLAGS=-O X# On the Vax we can use the string instructions some but not all the time. XCFLAGS=-O -DVaxAsm X X# The SIII functions are the ones described in the System III X# string(3) manual page, and also in ctype(3), atoi(3). X XSIII=strcat.o strncat.o strcmp.o strncmp.o strcpy.o strncpy.o strlen.o\ X strchr.o strrchr.o strpbrk.o strspn.o strcspn.o strtok.o\ X _c2type.o str2int.o getopt.o X X# The Sys5 functions are the ones described in the System V X# memory(3C) manual page. mem{mov,rchr,rev} are in "mine". X XSys5=memccpy.o memchr.o memcmp.o memcpy.o memmov.o memrchr.o memset.o X X# The BSD2 functions are the ones described in the 4.2bsd X# bstring(3) manual page, plus a couple of my additions. X# All except ffs have VAX-specific machine code versions. X XBSD2=bcmp.o bcopy.o bfill.o bmove.o bzero.o ffs.o X X# The "xstr" functions are Tony Hansen's "xstring(3c)" package with X# some additions of mine. All the code is mine, the names are his. X# It is not clear whether his strxncpy pads with NULs as strncpy does. X# In this package str[x]n{cpy,mov} all pad to exactly len chars with NUL. X Xxstr=strxcat.o strxcpy.o strxmov.o strxncat.o strxncpy.o strxnmov.o X X# The "mine" functions are the ones which are entirely my own X# invention, though they are supposed to fit into the SIII conventions. X Xmine=strmov.o strnmov.o strrpt.o strnrpt.o strend.o strnlen.o strcpbrk.o\ X strpack.o strcpack.o strtrans.o strntrans.o strpref.o strsuff.o\ X strtrim.o strctrim.o strfield.o strkey.o int2str.o substr.o\ X strnend.o strconc.o strrev.o strnrev.o _str2map.o _str2set.o\ X memmov.o memrchr.o memrev.o X X# The "find" functions are my code, but they are based on published X# work by Boyer, Moore, and Hospool. (See _str2pat.c.) X Xfind=strfind.o strrepl.o X Xstrings.a: ${SIII} ${Sys5} ${BSD2} ${xstr} ${mine} ${find} X rm strings.a; ar rc strings.a *.o; ranlib strings.a X Xscan=strpbrk.o strcprbk.o strspn.o strcspn.o strpack.o strcpack.o \ X strtrim.o strctrim.o strtok.o X X${scan} _str2set.o: _str2set.h X Xtran=strtrans.o strntrans.o X X${tran} _str2map.o: _str2map.h X X${find}: _str2pat.h X Xstr2int.o: ctypes.h X X${SIII} ${Sys5} ${BSD2} ${mine} ${xstr} ${find}: strings.h X Xclean: X -rm *.o X X# The compilations should be done with the sources and headers in the X# same directory. However, users should find everything in the proper X# places: /usr/include/{strings,memory}.h and /usr/lib/strings.a X# /usr/local/lib would be ok. Why is there no /usr/local/include? X Xinstall: X cp memory.h strings.h /usr/include X mv strings.a /usr/lib SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > READ-ME XFile : READ-ME XAuthor : Richard A. O'Keefe. XUpdated: 1 June 1984. XPurpose: Explain the new strings package. X X The UNIX string libraries (described in the string(3) manual page) Xdiffer from UNIX to UNIX (e.g. strtok is not in V7 or 4.1bsd). Worse, Xthe sources are not in the public domain, so that if there is a string Xroutine which is nearly what you want but not quite you can't take a Xcopy and modify it. And of course C programmers on non-UNIX systems Xare at the mercy of their supplier. X X This package was designed to let me do reasonable things with C's Xstrings whatever UNIX (V7, PaNiX, UX63, 4.1bsd) I happen to be using. XEverything in the System III manual is here and does just what the S3 Xmanual says it does. There are also lots of new goodies. I'm sorry Xabout the names, but the routines do have to work on asphyxiated-at- Xbirth systems which truncate identifiers. The convention is that a Xroutine is called X str [n] [c] XIf there is an "n", it means that the function takes an (int) "length" Xargument, which bounds the number of characters to be moved or looked Xat. If the function has a "set" argument, a "c" in the name indicates Xthat the complement of the set is used. Functions or variables whose Xnames start with _ are support routines which aren't really meant for Xgeneral use. I don't know what the "p" is doing in "strpbrk", but it Xis there in the S3 manual so it's here too. "istrtok" does not follow Xthis rule, but with 7 letters what can you do? X X I have included new versions of atoi(3) and atol(3) as well. They Xuse a new primitive str2int, which takes a pair of bounds and a radix, Xand does much more thorough checking than the normal atoi and atol do. XThe result returned by atoi & atol is valid if and only if errno == 0. XThere is also an output conversion routine int2str, with itoa and ltoa Xas interface macros. Only after writing int2str did I notice that the Xstr2int routine has no provision for unsigned numbers. On reflection, XI don't greatly care. I'm afraid that int2str may depend on your "C" Xcompiler in unexpected ways. Do check the code with -S. X X Several of these routines have "asm" inclusions conditional on the XVaxAsm option. These insertions can make the routines which have them Xquite a bit faster, but there is a snag. The VAX architects, for some Xreason best known to themselves and their therapists, decided that all X"strings" were shorter than 2^16 bytes. Even when the length operands Xare in 32-bit registers, only 16 bits count. So the "asm" versions do Xnot work for long strings. If you can guarantee that all your strings Xwill be short, define VaxAsm in the makefile, but in general, and when Xusing other machines, do not define it. X X Thanks to someone on the net who saw the first posting of strings, Xand sent me a formatted copy of the System V memory(3C) manual page, I Xhave been able to include versions of these routines. The convention Xis that they are called X mem{operation}([dst,] ... , len) Xwhere operation is cpy, cmp, chr, and so on, and len is how many bytes Xto move or test. Note that this is different from the strn functions, X str{operation} -- stop when you find a NUL character X strn{operation} -- stop when len is exhausted or you find NUL X mem{operation} -- stop when len is exhausted X b{operation} -- stop when len is exhausted Xbut the b family has different argument orders or different results or Xboth. In particular, note that my implementation of bcmp does conform Xto the letter of the 4.2bsd manual page, but I decided to make it give Xa value I have often wanted, which is not like the value of strcmp. As Xthe System V manual page is more explicit about the return code memcmp XDOES return a value like strcmp, so you may prefer to use it. BEWARE: Xthe "c" in the name mem-c-cpy doesn't mean what it does in the System3 Xnames, it's more like mem-chr-cpy. X X To use this library, you need the "strings.a" library file and the X"strings.h" header file. The other header files are for compiling the Xlibrary itself, though if you are hacking extensions you may find them Xuseful. General users really shouldn't see them. I've defined a few Xmacros I find useful in "strings.h"; if you have no need for "index", X"rindex", "streql", and "beql", just edit them out. On the 4.1bsd Xsystem I am using, having all these functions 'extern' does not mean Xthat they will all be loaded; only the ones you call are. When using Xlesser systems you may find it necessary to break strings.h up or you Xcould get by with just adding "extern" declarations for functions as Xyou need them. Note that as many of these functions have names Xmatching "standard C library" names (by design, this is after all a Xreplacement/reimplementation of part of that library) you may have to Xtalk the loader into loading this library first. Again, I've found no Xproblems on 4.1bsd. X X A note on character comparison. The various UNIX manuals come out Xand say explicitly that the *cmp and *chr routines use the computer's X"native" character comparison. That is, on a PDP-11, VAX-11, and some Xother machines, signed character comparison is used, and the byte 0377 Xwill never be located (use -1). On IBM 370s and many other machines, Xunsigned character comparison is used, and the byte -1 can't be found. X(Use 0377.) If you have occasion to use 8-bit byte values in calls to X*chr functions, it would be nice if the package looked after making it Xwork portably. I thought about that, and decided not to do it, as you Xmight *want* to write VAX code that didn't find 128, and might rely on Xthe current effect. However, you should be able to use 8-bit values in Xa portable fashion if you ask, and that the package DOES do for you. XThere is a macro X int2char(c) Xwhich takes the bottom 8 bits of c on a machine with unsigned character Xcomparison or sign-extends them on a machine with signed comparison. It Xis up to you to use this macro in appropriate places. It is up to who- Xever installs the package to make sure that the right definition is put Xin and the wrong one commented out. X X You may wonder at my failure to provide manual pages for this code. XFor the things in V7, 4.?, or SIII, you should be able to use whichever Xmanual page came with that system, and anything I might write would be Xso like it as to raise suspicions of violating AT&T copyrights. In the Xsources you will find comments which provide far more documentation for Xthese routines than AT&T ever provided for their strings stuff, I just Xdon't happen to have put it in nroff -man form. Had I done so, the *.3 Xfiles would have outbulked the .c files! X X There is a manual page for the strx family of routines. It was the Xwork of Tony Hansen, of AT&T Information Systems Lincroft NJ. It is not Xclear whether I should distribute this manual page or not, but as these Xfunctions are not likely to documented anywhere else I decided to risk Xit. There is no risk in the *code* however. His posting to net.sources Xarrived at Edinburgh with just the reason for reposting, and the manual Xpage. The code is my own work based on his manual page. Indeed, I had Xalready written strx[n]mov, using different names. X X These files are in the public domain. This includes getopt.c, which Xis the work of Henry Spencer, University of Toronto Zoology, who says of Xit "None of this software is derived from Bell software. I had no access Xto the source for Bell's versions at the time I wrote it. This software Xis hereby explicitly placed in the public domain. It may be used for Xany purpose on any machine by anyone." I would greatly prefer it if *my* Xmaterial received no military use. X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > _c2type.c X/* File : _c2type.c X Author : Richard A. O'Keefe. X Updated: 23 April 1984 X Purpose: Map character codes to types X X The mapping used here is such that we can use it for converting X numbers expressed in a variety of radices to binary as well as for X classifying characters. X*/ X Xchar _c2type[129] = X { 37, /* EOF == -1 */ X 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 39, 39, 39, 39, 37, 37, X 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, X 38, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, X 00, 01, 02, 03, 04, 05, 06, 07, 8, 9, 36, 36, 36, 36, 36, 36, X 36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, X 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, X 36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, X 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36 X }; X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > _str2map.c X/* File : _str2map.c X Author : Richard A. O'Keefe. X Updated: 20 April 1984 X Defines: _map_vec[], _str2map(). X X _str2map(option, from, to) constructs a translation table. If from X or to is NullS, the same string is used as last time, so if you want X to translate a whole lot of strings using the same mapping you don't X have to reconstruct it each time. The options are X X 0: initialise the map to the identity function, X then map each from[i] to the corresponding to[i]. X If to[] is shorter than from[], its last character is X repeated as often as needed. X X 1: as 0, but don't initialise the map. X X 2: initialise the map to send every character to to[0], X then map each from[i] to itself. X X For example, to build a map which forces letters to lower case but X sends everything else to blank, call X X _str2map(2, "abcdefghijklmnopqrstuvwxyz", " "); X _str2map(1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"); X X Only strtrans() and strntrans() in this package call _str2map; if X you want to build your own maps this way you can "fool" them into X using it, as when the two strings are NullS they don't change the X map. As an extra-special dubious *hack*, _map_vec has an extra NUL X character at the end, so after calling _str2map(0, "", ""), you can X use _map_vec+1 as a string of the 127 non-NUL characters (or if the X _AlphabetSize is 256, of the 255 non-NUL characters). X*/ X X#include "strings.h" X#include "_str2map.h" X Xstatic _char_ *oldFrom = "?"; Xstatic char *oldTo = "?"; X Xchar _map_vec[_AlphabetSize+1]; X Xvoid _str2map(option, from, to) X int option; X register _char_ *from; X register char *to; X { X register int i, c; X X if (from == NullS && to == NullS) return; X if (from == NullS) from = oldFrom; else oldFrom = from; X if (to == NullS) to = oldTo; else oldTo = to; X switch (option) { X case 0: X for (i = _AlphabetSize; --i >= 0; _map_vec[i] = i) ; X case 1: X while (i = *from++) { X _map_vec[i] = *to++; X if (!*to) { X c = *--to; X while (i = *from++) _map_vec[i] = c; X return; X } X } X return; X case 2: X c = *to; X for (i = _AlphabetSize; --i >= 0; _map_vec[i] = c) ; X while (c = *from++) _map_vec[c] = c; X return; X } X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > _str2map.h X/* File : _str2map.h X Author : Richard A. O'Keefe. X Updated: 11 April 1984 X Purpose: Definitions from _str2map.c X*/ X Xextern char _map_vec[_AlphabetSize+1]; Xextern void _str2map(/*int,_char_^,char^*/); X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > _str2pat.c X/* File : _str2pat.c X Author : Richard A. O'Keefe. X Updated: 2 June 1984 X Defines: _pat_lim, _pat_vec[], _str2pat() X X Searching in this package is done by an algorithm due to R. Nigel X Hospool, described in Software Practice & Experience 1980, p505. X Elsewhere I have a version of it which does exact case or either X case match, word more or literal mode, forwards or backwards, and X will look for the Nth instance. For most applications that is too X much and a simple exact case forward search will do. Hospool's X algorithm is a simplification of the Boyer-Moore algorithm which X doesn't guarantee linear time, but in practice is very good indeed. X X _str2pat(pat) builds a search table for the string pat. As usual in X this pacakge, if pat == NullS, the table is not changed and the last X search string is re-used. To support this, _str2pat returns the X actual search string. X*/ X X#include "strings.h" X#include "_str2pat.h" X Xint _pat_lim; Xint _pat_vec[_AlphabetSize]; Xstatic _char_ *oldPat = ""; X X X_char_ *_str2pat(pat) X register _char_ *pat; X { X register int L, i; X X if (pat == NullS) pat = oldPat; else oldPat = pat; X for (L = 0; *pat++; L++) ; X for (i = _AlphabetSize; --i >= 0; _pat_vec[i] = L) ; X for (pat = oldPat, i = L; --i > 0; _pat_vec[*pat++] = i) ; X _pat_lim = --L; X return oldPat; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > _str2pat.h X/* File : _str2pat.h X Author : Richard A. O'Keefe. X Updated: 20 April 1984 X Purpose: Definitions from _str2pat.c X*/ X Xextern int _pat_lim; Xextern int _pat_vec[]; Xextern _char_ *_str2pat(/*_char_^*/); X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > _str2set.c X/* File : _str2set.c X Author : Richard A. O'Keefe. X Updated: 20 April 1984 X Defines: _set_ctr, _set_vec[], _str2set(). X Purpose: Convert a character string to a set. X*/ X X/* The obvious way of representing a set of characters is as a X vector of 0s and 1s. The snag with that is that to convert a X string to such a vector, we have to clear all the elements to X 0, and then set the elements corresponding to characters in X the string to 1, so the cost is O(|alphabet|+|string|). This X package uses another method, where there is a vector of small X numbers and a counter. A character is in the current set if X and only if the corresponding element of the vector is equal X to the current value of the counter. Every so often the X vector elements would overflow and we have to clear the X vector, but the cost is reduced to O(|string|+1). X X Note that NUL ('\0') will never be in any set built by str2set. X X While this method reduces the cost of building a set, it would X be useful to avoid it entirely. So when the "set" argument is X NullS the set is not changed. Use NullS to mean "the same set X as before." MaxPosChar is the largest integer value which can X be stored in a "char". Although we might get a slightly wider X range by using "unsigned char", "char" may be cheaper (as on a X PDP-11). By all means change the number from 127 if your C is X one of those that treats char as unsigned, but don't change it X just because _AlphabetSize is 256, the two are unrelated. And X don't dare change it on a VAX: it is built into the asm code! X*/ X X#include "strings.h" X#include "_str2set.h" X X#if CharsAreSigned X#define MaxPosChar 127 X#else ~CharsAreSigned X#define MaxPosChar 255 X#endif CharsAreSigned X Xint _set_ctr = MaxPosChar; Xchar _set_vec[_AlphabetSize]; X X Xvoid _str2set(set) X register char *set; X { X if (set == NullS) return; X if (++_set_ctr == MaxPosChar+1) { X#if VaxAsm X asm("movc5 $0,4(ap),$0,$128,__set_vec"); X#else ~VaxAsm X register char *w = &_set_vec[_AlphabetSize]; X do *--w = NUL; while (w != &_set_vec[0]); X#endif VaxAsm X _set_ctr = 1; X } X while (*set) _set_vec[*set++] = _set_ctr; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > _str2set.h X/* File : _str2set.h X Updated: 10 April 1984 X Purpose: External declarations for strprbk, strspn, strcspn &c X Copyright (C) 1984 Richard A. O'Keefe. X*/ X Xextern int _set_ctr; Xextern char _set_vec[]; Xextern void _str2set(/*char^*/); X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > ascii.h X/* File : strings.d/ascii.h X Author : Richard A. O'Keefe X Updated: 28 April 1984 X Purpose: Define Ascii mnemonics. X X This file defines the ASCII control characters. Note that these X names refer to their use in communication; it is an ERROR to use X these names to talk about keyboard commands. For example, DO NOT X use EOT when you mean "end of file", as many people prefer ^Z (if X the Ascii code were taken seriously, EOT would log you off and X hang up the line as well). Similarly, DO NOT use DEL when you X mean "interrupt", many people prefer ^C. When writing a screen X editor, you should speak of tocntrl('C') rather than ETX (see the X header file "ctypes.h"). X*/ X X#define NUL '\000' /* null character */ X#define SOH '\001' /* Start Of Heading, start of message */ X#define STX '\002' /* Start Of Text, end of address */ X#define ETX '\003' /* End of TeXt, end of message */ X#define EOT '\004' /* End Of Transmission */ X#define ENQ '\005' /* ENQuiry "who are you" */ X#define ACK '\006' /* (positive) ACKnowledge */ X#define BEL '\007' /* ring the BELl */ X#define BS '\010' /* BackSpace */ X#define HT '\011' /* Horizontal Tab */ X#define TAB '\011' /* an unofficial name for HT */ X#define LF '\012' /* Line Feed (does not imply cr) */ X#define NL '\012' /* unix unofficial name for LF: new line */ X#define VT '\013' /* Vertical Tab */ X#define FF '\014' /* Form Feed (new page starts AFTER this) */ X#define CR '\015' /* Carriage Return */ X#define SO '\016' /* Shift Out; select alternate character set */ X#define SI '\017' /* Shift In; select ASCII again */ X#define DLE '\020' /* Data Link Escape */ X#define DC1 '\021' /* Device Control 1 */ X#define XON '\021' /* transmitter on, resume output */ X#define DC2 '\022' /* Device Control 2 (auxiliary on) */ X#define DC3 '\023' /* Device Control 3 */ X#define XOFF '\023' /* transmitter off, suspend output */ X#define DC4 '\024' /* Device Control 4 (auxiliary off) */ X#define NAK '\025' /* Negative AcKnowledge (signal error) */ X#define SYN '\026' /* SYNchronous idle */ X#define ETB '\027' /* End of Transmission Block, logical end of medium */ X#define CAN '\030' /* CANcel */ X#define EM '\031' /* End of Medium */ X#define SUB '\032' /* SUBstitute */ X#define ESC '\033' /* ESCape */ X#define FS '\034' /* File Separator */ X#define GS '\035' /* Group Separator */ X#define RS '\036' /* Record Separator */ X#define US '\037' /* Unit Separator */ X#define SP '\040' /* SPace */ X#define DEL '\177' /* DELete, rubout */ X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > bcmp.c X/* File : bcmp.c X Author : Richard A. O'Keefe. X Updated: 23 April 1984 X Defines: bcmp() X X bcmp(s1, s2, len) returns 0 if the "len" bytes starting at "s1" are X identical to the "len" bytes starting at "s2", non-zero if they are X different. The 4.2bsd manual page doesn't say what non-zero value X is returned, though the BUGS note says that it takes its parameters X backwards from strcmp. This suggests that it is something like X for (; --len >= 0; s1++, s2++) X if (*s1 != *s2) return *s2-*s1; X return 0; X There, I've told you how to do it. As the manual page doesn't come X out and *say* that this is the result, I tried to figure out what a X useful result might be. (I'd forgotten than strncmp stops when it X hits a NUL, which the above does not do.) What I came up with was: X the result is the number of bytes in the differing tails. That is, X after you've skipped the equal parts, how many characters are left? X To put it another way, N-bcmp(s1,s2,N) is the number of equal bytes X (the size of the common prefix). After deciding on this definition X I discovered that the CMPC3 instruction does exactly what I wanted. X The code assumes that N is non-negative. X X Note: the "b" routines are there to exploit certain VAX order codes, X but the CMPC3 instruction will only test 65535 characters. The asm X code is presented for your interest and amusement. X*/ X X#include "strings.h" X X#if VaxAsm X Xint bcmp(s1, s2, len) X char *s1, *s2; X int len; X { X asm("cmpc3 12(ap),*4(ap),*8(ap)"); X } X X#else ~VaxAsm X Xint bcmp(s1, s2, len) X register char *s1, *s2; X register int len; X { X while (--len >= 0 && *s1++ == *s2++) ; X return len+1; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > bcopy.c X/* File : bcopy.c X Author : Richard A. O'Keefe. X Updated: 23 April 1984 X Defines: bcopy() X X bcopy(src, dst, len) moves exactly "len" bytes from the source "src" X to the destination "dst". It does not check for NUL characters as X strncpy() and strnmov() do. Thus if your C compiler doesn't support X structure assignment, you can simulate it with X bcopy(&from, &to, sizeof from); X BEWARE: the first two arguments are the other way around from almost X everything else. I'm sorry about that, but that's the way it is in X the 4.2bsd manual, though they list it as a bug. For a version with X the arguments the right way around, use bmove(). X No value is returned. X X Note: the "b" routines are there to exploit certain VAX order codes, X but the MOVC3 instruction will only move 65535 characters. The asm X code is presented for your interest and amusement. X*/ X X#include "strings.h" X X#if VaxAsm X Xvoid bcopy(src, dst, len) X char *src, *dst; X int len; X { X asm("movc3 12(ap),*4(ap),*8(ap)"); X } X X#else ~VaxAsm X Xvoid bcopy(src, dst, len) X register char *src, *dst; X register int len; X { X while (--len >= 0) *dst++ = *src++; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > bfill.c X/* File : bfill.c X Author : Richard A. O'Keefe. X Updated: 23 April 1984 X Defines: bfill() X X bfill(dst, len, fill) moves "len" fill characters to "dst". X Thus to set a buffer to 80 spaces, do bfill(buff, 80, ' '). X X Note: the "b" routines are there to exploit certain VAX order codes, X but the MOVC5 instruction will only move 65535 characters. The asm X code is presented for your interest and amusement. X*/ X X#include "strings.h" X X#if VaxAsm X Xvoid bfill(dst, len, fill) X char *dst; X int len; X int fill; /* actually char */ X { X asm("movc5 $0,*4(ap),12(ap),8(ap),*4(ap)"); X } X X#else ~VaxAsm X Xvoid bfill(dst, len, fill) X register char *dst; X register int len; X register int fill; /* char */ X { X while (--len >= 0) *dst++ = fill; X X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > bmove.c X/* File : bmove.c X Author : Richard A. O'Keefe. X Updated: 23 April 1984 X Defines: bmove() X X bmove(dst, src, len) moves exactly "len" bytes from the source "src" X to the destination "dst". It does not check for NUL characters as X strncpy() and strnmov() do. Thus if your C compiler doesn't support X structure assignment, you can simulate it with X bmove(&to, &from, sizeof from); X The standard 4.2bsd routine for this purpose is bcopy. But as bcopy X has its first two arguments the other way around you may find this a X bit easier to get right. X No value is returned. X X Note: the "b" routines are there to exploit certain VAX order codes, X but the MOVC3 instruction will only move 65535 characters. The asm X code is presented for your interest and amusement. X*/ X X#include "strings.h" X X#if VaxAsm X Xvoid bmove(dst, src, len) X char *dst, *src; X int len; X { X asm("movc3 12(ap),*8(ap),*4(ap)"); X } X X#else ~VaxAsm X Xvoid bmove(dst, src, len) X register char *dst, *src; X register int len; X { X while (--len >= 0) *dst++ = *src++; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > bzero.c X/* File : bzero.c X Author : Richard A. O'Keefe. X Updated: 23 April 1984 X Defines: bzero() X X bzero(dst, len) moves "len" 0 bytes to "dst". X Thus to clear a disc buffer to 0s do bzero(buffer, BUFSIZ). X X Note: the "b" routines are there to exploit certain VAX order codes, X but the MOVC5 instruction will only move 65535 characters. The asm X code is presented for your interest and amusement. X*/ X X#include "strings.h" X X#if VaxAsm X Xvoid bzero(dst, len) X char *dst; X int len; X { X asm("movc5 $0,*4(ap),$0,8(ap),*4(ap)"); X } X X#else ~VaxAsm X Xvoid bzero(dst, len) X register char *dst; X register int len; X { X while (--len >= 0) *dst++ = 0; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > ctypes.dem XEOF . . . . . . . . . # . . X Xch DD? OD? XD? AN? AF? LC? UC? PT? PR? CT? SP? EL? X^@ . . . . . . . . . # . . X^A . . . . . . . . . # . . X^B . . . . . . . . . # . . X^C . . . . . . . . . # . . X^D . . . . . . . . . # . . X^E . . . . . . . . . # . . X^F . . . . . . . . . # . . X^G . . . . . . . . . # . . X^H . . . . . . . . . # . . X^I . . . . . . . . . # # . X^J . . . . . . . . . # # # X^K . . . . . . . . . # # # X^L . . . . . . . . . # # # X^M . . . . . . . . . # # # X^N . . . . . . . . . # . . X^O . . . . . . . . . # . . X Xch DD? OD? XD? AN? AF? LC? UC? PT? PR? CT? SP? EL? X^P . . . . . . . . . # . . X^Q . . . . . . . . . # . . X^R . . . . . . . . . # . . X^S . . . . . . . . . # . . X^T . . . . . . . . . # . . X^U . . . . . . . . . # . . X^V . . . . . . . . . # . . X^W . . . . . . . . . # . . X^X . . . . . . . . . # . . X^Y . . . . . . . . . # . . X^Z . . . . . . . . . # . . X^[ . . . . . . . . . # . . X^\ . . . . . . . . . # . . X^] . . . . . . . . . # . . X^^ . . . . . . . . . # . . X^_ . . . . . . . . . # . . X Xch DD? OD? XD? AN? AF? LC? UC? PT? PR? CT? SP? EL? X . . . . . . . . # . # . X! . . . . . . . # # . . . X" . . . . . . . # # . . . X# . . . . . . . # # . . . X$ . . . . . . . # # . . . X% . . . . . . . # # . . . X& . . . . . . . # # . . . X' . . . . . . . # # . . . X( . . . . . . . # # . . . X) . . . . . . . # # . . . X* . . . . . . . # # . . . X+ . . . . . . . # # . . . X, . . . . . . . # # . . . X- . . . . . . . # # . . . X. . . . . . . . # # . . . X/ . . . . . . . # # . . . X Xch DD? OD? XD? AN? AF? LC? UC? PT? PR? CT? SP? EL? X0 # # # # . . . . # . . . X1 # # # # . . . . # . . . X2 # # # # . . . . # . . . X3 # # # # . . . . # . . . X4 # # # # . . . . # . . . X5 # # # # . . . . # . . . X6 # # # # . . . . # . . . X7 # # # # . . . . # . . . X8 # . # # . . . . # . . . X9 # . # # . . . . # . . . X: . . . . . . . # # . . . X; . . . . . . . # # . . . X< . . . . . . . # # . . . X= . . . . . . . # # . . . X> . . . . . . . # # . . . X? . . . . . . . # # . . . X Xch DD? OD? XD? AN? AF? LC? UC? PT? PR? CT? SP? EL? X@ . . . . . . . # # . . . XA . . # # # . # . # . . . XB . . # # # . # . # . . . XC . . # # # . # . # . . . XD . . # # # . # . # . . . XE . . # # # . # . # . . . XF . . # # # . # . # . . . XG . . . # # . # . # . . . XH . . . # # . # . # . . . XI . . . # # . # . # . . . XJ . . . # # . # . # . . . XK . . . # # . # . # . . . XL . . . # # . # . # . . . XM . . . # # . # . # . . . XN . . . # # . # . # . . . XO . . . # # . # . # . . . X Xch DD? OD? XD? AN? AF? LC? UC? PT? PR? CT? SP? EL? XP . . . # # . # . # . . . XQ . . . # # . # . # . . . XR . . . # # . # . # . . . XS . . . # # . # . # . . . XT . . . # # . # . # . . . XU . . . # # . # . # . . . XV . . . # # . # . # . . . XW . . . # # . # . # . . . XX . . . # # . # . # . . . XY . . . # # . # . # . . . XZ . . . # # . # . # . . . X[ . . . . . . . # # . . . X\ . . . . . . . # # . . . X] . . . . . . . # # . . . X^ . . . . . . . # # . . . X_ . . . . . . . # # . . . X Xch DD? OD? XD? AN? AF? LC? UC? PT? PR? CT? SP? EL? X` . . . . . . . # # . . . Xa . . # # # # . . # . . . Xb . . # # # # . . # . . . Xc . . # # # # . . # . . . Xd . . # # # # . . # . . . Xe . . # # # # . . # . . . Xf . . # # # # . . # . . . Xg . . . # # # . . # . . . Xh . . . # # # . . # . . . Xi . . . # # # . . # . . . Xj . . . # # # . . # . . . Xk . . . # # # . . # . . . Xl . . . # # # . . # . . . Xm . . . # # # . . # . . . Xn . . . # # # . . # . . . Xo . . . # # # . . # . . . X Xch DD? OD? XD? AN? AF? LC? UC? PT? PR? CT? SP? EL? Xp . . . # # # . . # . . . Xq . . . # # # . . # . . . Xr . . . # # # . . # . . . Xs . . . # # # . . # . . . Xt . . . # # # . . # . . . Xu . . . # # # . . # . . . Xv . . . # # # . . # . . . Xw . . . # # # . . # . . . Xx . . . # # # . . # . . . Xy . . . # # # . . # . . . Xz . . . # # # . . # . . . X{ . . . . . . . # # . . . X| . . . . . . . # # . . . X} . . . . . . . # # . . . X~ . . . . . . . # # . . . XDEL . . . . . . . # . # . . SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > ctypes.h X/* File : ctypes.h X Author : Richard A. O'Keefe. X Updated: 26 April 1984 X Purpose: Reimplement the UNIX ctype(3) library. X X isaneol(c) means that c is a line terminating character. X isalnum, ispunct, isspace, and isaneol are defined on the X range -1..127, i.e. on ASCII U {EOF}, while all the other X macros are defined for any integer. X X isodigit(c) checks for Octal digits. X isxdigit(c) checkx for heXadecimal digits. X*/ X X#define isdigit(c) ((unsigned)((c)-'0') < 10) X#define islower(c) ((unsigned)((c)-'a') < 26) X#define isupper(c) ((unsigned)((c)-'A') < 26) X#define isprint(c) ((unsigned)((c)-' ') < 95) X#define iscntrl(c) ((unsigned)((c)-' ') >= 95) X#define isascii(c) ((unsigned)(c) < 128) X#define isalpha(c) ((unsigned)(((c)|32)-'a') < 26) X Xextern char _c2type[]; X X#define isalnum(c) (_c2type[(c)+1] < 36) X#define ispunct(c) (_c2type[(c)+1] == 36) X#define isspace(c) (_c2type[(c)+1] > 37) X#define isaneol(c) (_c2type[(c)+1] > 38) X X#define isxdigit(c) (_c2type[(c)+1] < 16) X#define isodigit(c) ((unsigned)((c)-'0') < 8) X X/* The following "conversion" macros have been in some versions of UNIX X but are not in all. tocntrl is new. The original motivation for ^? X being a name for DEL was that (x)^64 mapped A..Z to ^A..^Z and also X ? to DEL. The trouble is that this trick doesn't work for lower case X letters. The version given here is not mine. I wish it was. It has X the nice property that DEL is mapped to itself (so does EOF). X tolower(c) and toupper(c) are only defined when isalpha(c). X*/ X#define tolower(c) ((c)|32) X#define toupper(c) ((c)&~32) X#define tocntrl(c) (((((c)+1)&~96)-1)&127) X#define toascii(c) ((c)&127) X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > ffs.c X/* File : ffs.c X Author : Richard A. O'Keefe. X Updated: 20 April 1984 X Defines: ffs(), ffc() X X ffs(i) returns the index of the least significant 1 bit in i, X where 1 means the least significant bit and 32 means the X most significant bit, or returns -1 if i is 0. X X ffc(i) returns the index of the least significant 0 bit in i, X where 1 means the least significant bit and 32 means the X most significant bit, or returns -1 if i is ~0. X X These functions mimic the VAX FFS and FFC instructions, except that X the latter return much more sensible values. This file only exists X to make it easier to move 4.2bsd programs to System III (which is X rather like moving up from a Rolls Royce to a model T Ford), and so X I haven't bother with assembly code versions. X*/ X X#include "strings.h" X Xint ffs(i) X register int i; X { X register int N; X X for (N = 8*sizeof(int); --N >= 0; i >>= 1) X if (i&1) return 8*sizeof(int)-N; X return -1; X } X Xint ffc(i) X register int i; X { X register int N; X X for (N = 8*sizeof(int); --N >= 0; i >>= 1) X if (!(i&1)) return 8*sizeof(int)-N; X return -1; X } X X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > getopt.3 X.TH GETOPT 3 local X.DA 25 March 1982 X.SH NAME Xgetopt \- get option letter from argv X.SH SYNOPSIS X.ft B Xint getopt(argc, argv, optstring) X.br Xint argc; X.br Xchar **argv; X.br Xchar *optstring; X.sp Xextern char *optarg; X.br Xextern int optind; X.ft X.SH DESCRIPTION X.I Getopt Xreturns the next option letter in X.I argv Xthat matches a letter in X.IR optstring . X.I Optstring Xis a string of recognized option letters; Xif a letter is followed by a colon, the option is expected to have Xan argument that may or may not be separated from it by white space. X.I Optarg Xis set to point to the start of the option argument on return from X.IR getopt . X.PP X.I Getopt Xplaces in X.I optind Xthe X.I argv Xindex of the next argument to be processed. XBecause X.I optind Xis external, it is normally initialized to zero automatically Xbefore the first call to X.IR getopt . X.PP XWhen all options have been processed (i.e., up to the first Xnon-option argument), X.I getopt Xreturns X.BR EOF . XThe special option X.B \-\- Xmay be used to delimit the end of the options; X.B EOF Xwill be returned, and X.B \-\- Xwill be skipped. X.SH SEE ALSO Xgetopt(1) X.SH DIAGNOSTICS X.I Getopt Xprints an error message on X.I stderr Xand returns a question mark X.RB ( ? ) Xwhen it encounters an option letter not included in X.IR optstring . X.SH EXAMPLE XThe following code fragment shows how one might process the arguments Xfor a command that can take the mutually exclusive options X.B a Xand X.BR b , Xand the options X.B f Xand X.BR o , Xboth of which require arguments: X.PP X.RS X.nf Xmain(argc, argv) X int argc; X char **argv; X { X int c; X extern int optind; X extern char *optarg; X \&. X \&. X \&. X while ((c = getopt(argc, argv, "abf:o:")) != EOF) { X switch (c) { X case 'a': X if (bflg) errflg++; else aflg++; X break; X case 'b': X if (aflg) errflg++; else bflg++; X break; X case 'f': X ifile = optarg; X break; X case 'o': X ofile = optarg; X break; X case '?': X default: X errflg++; X break; X } X } X if (errflg) { X fprintf(stderr, "Usage: ..."); X exit(2); X } X for (; optind < argc; optind++) { X \&. X \&. X \&. X } X \&. X \&. X \&. X } X.RE X.PP XA template similar to this can be found in X.IR /usr/pub/template.c . X.SH HISTORY XWritten by Henry Spencer, working from a Bell Labs manual page. XBehavior believed identical to the Bell version. X.SH BUGS XIt is not obvious how X`\-' Xstanding alone should be treated; this version treats it as Xa non-option argument, which is not always right. X.PP XOption arguments are allowed to begin with `\-'; Xthis is reasonable but reduces the amount of error checking possible. X.PP X.I Getopt Xis quite flexible but the obvious price must be paid: there is much Xit could do that it doesn't, like Xchecking mutually exclusive options, checking type of Xoption arguments, etc. SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > getopt.c X/* File : getopt.c X Author : Henry Spencer, University of Toronto X Updated: 28 April 1984 X Purpose: get option letter from argv. X*/ X X#include X#include "strings.h" X Xchar *optarg; /* Global argument pointer. */ Xint optind = 0; /* Global argv index. */ X Xint getopt(argc, argv, optstring) X int argc; X char *argv[]; X char *optstring; X { X register int c; X register char *place; X static char *scan = NullS; /* Private scan pointer. */ X X optarg = NullS; X X if (scan == NullS || *scan == '\0') { X if (optind == 0) optind++; X if (optind >= argc) return EOF; X place = argv[optind]; X if (place[0] != '-' || place[1] == '\0') return EOF; X optind++; X if (place[1] == '-' && place[2] == '\0') return EOF; X scan = place+1; X } X X c = *scan++; X place = index(optstring, c); X if (place == NullS || c == ':') { X fprintf(stderr, "%s: unknown option %c\n", argv[0], c); X return '?'; X } X if (*++place == ':') { X if (*scan != '\0') { X optarg = scan, scan = NullS; X } else { X optarg = argv[optind], optind++; X } X } X return c; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > int2str.c X/* File : int2str.c X Author : Richard A. O'Keefe X Updated: 30 April 1984 X Defines: int2str(), itoa(), ltoa() X X int2str(dst, radix, val) X converts the (long) integer "val" to character form and moves it to X the destination string "dst" followed by a terminating NUL. The X result is normally a pointer to this NUL character, but if the radix X is dud the result will be NullS and nothing will be changed. X X If radix is -2..-36, val is taken to be SIGNED. X If radix is 2.. 36, val is taken to be UNSIGNED. X That is, val is signed if and only if radix is. You will normally X use radix -10 only through itoa and ltoa, for radix 2, 8, or 16 X unsigned is what you generally want. X X _dig_vec is public just in case someone has a use for it. X The definitions of itoa and ltoa are actually macros in strings.h, X but this is where the code is. X*/ X X#include "strings.h" X Xchar _dig_vec[] = X "0123456789abcdefghijklmnopqrstuvwxyz"; X X Xchar *int2str(dst, radix, val) X register char *dst; X register int radix; X register long val; X { X char buffer[33]; X register char *p; X X if (radix < 0) { X if (radix < -36 || radix > -2) return NullS; X if (val < 0) { X *dst++ = '-'; X val = -val; X } X radix = -radix; X } else { X if (radix > 36 || radix < 2) return NullS; X } X /* The slightly contorted code which follows is due to the X fact that few machines directly support unsigned long / and %. X Certainly the VAX C compiler generates a subroutine call. In X the interests of efficiency (hollow laugh) I let this happen X for the first digit only; after that "val" will be in range so X that signed integer division will do. Sorry 'bout that. X CHECK THE CODE PRODUCED BY YOUR C COMPILER. The first % and / X should be unsigned, the second % and / signed, but C compilers X tend to be extraordinarily sensitive to minor details of style. X This works on a VAX, that's all I claim for it. X */ X p = &buffer[32]; X *p = '\0'; X *--p = _dig_vec[(unsigned long)val%(unsigned long)radix]; X val = (unsigned long)val/(unsigned long)radix; X while (val != 0) *--p = _dig_vec[val%radix], val /= radix; X while (*dst++ = *p++) ; X return dst-1; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memccpy.c X/* File : memccpy.c X Author : Richard A. O'Keefe. X Updated: 25 May 1984 X Defines: memccpy() X X memccpy(dst, src, chr, len) X copies bytes from src to dst until either len bytes have been moved X or a byte equal to chr has been moved. In the former case it gives X NullS as the value, in the latter a pointer to just after the place X where "chr" was moved to in dst. Note that copying stops after the X first instance of "chr", and that remaining characters in "dst" are X not changed in any way, no NUL being inserted or anything. X X See the "Character Comparison" section in the READ-ME file. X*/ X X#include "strings.h" X Xchar *memccpy(dst, src, chr, len) X register char *dst, *src; X register int chr; /* should be char */ X register int len; X { X while (--len >= 0) X if ((*dst++ = *src++) == chr) return dst; X return NullS; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memchr.c X/* File : memchr.c X Author : Richard A. O'Keefe. X Updated: 25 May 1984 X Defines: memchr() X X memchr(src, chr, len) X searches the memory area pointed to by src extending for len bytes, X looking for an occurrence of the byte value chr. It returns NullS X if there is no such occurrence. Otherwise it returns a pointer to X the FIRST such occurrence. X X See the "Character Comparison" section in the READ-ME file. X*/ X X#include "strings.h" X X#if VaxAsm X Xchar *memchr(src, chr, len) X char *src; X char chr; X int len; X { X asm("locc 8(ap),12(ap),*4(ap)"); X asm("bneq L1"); X asm("movl r1,r0"); X asm("L1: ret"); X } X X#else ~VaxAsm X Xchar *memchr(src, chr, len) X register char *src; X register int chr; /* should be char */ X register int len; X { X while (--len >= 0) X if (*src++ == chr) return src-1; X return NullS; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memcmp.c X/* File : memcmp.c X Author : Richard A. O'Keefe. X Updated: 25 May 1984 X Defines: memcmp() X X memcmp(lhs, rhs, len) X compares the two memory areas lhs[0..len-1] ?? rhs[0..len-1]. It X returns an integer less than, equal to, or greater than 0 according X as lhs[-] is lexicographically less than, equal to, or greater than X rhs[-]. Note that this is not at all the same as bcmp, which tells X you *where* the difference is but not what. X X Note: suppose we have int x, y; then memcmp(&x, &y, sizeof x) need X not bear any relation to x-y. This is because byte order is machine X dependent, and also, some machines have integer representations that X are shorter than a machine word and two equal integers might have X different values in the spare bits. On a ones complement machine, X -0 == 0, but the bit patterns are different. X X This could have a Vax assembly code version, but as the return value X is not the value left behind by the cmpc3 instruction I haven't X bothered. X*/ X Xint memcmp(lhs, rhs, len) X register char *lhs, *rhs; X register int len; X { X while (--len >= 0) X if (*lhs++ != *rhs++) return lhs[-1]-rhs[-1]; X return 0; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memcpy.c X/* File : memcpy.c X Author : Richard A. O'Keefe. X Updated: 25 May 1984 X Defines: memcpy() X X memcpy(dst, src, len) X moves len bytes from src to dst. The result is dst. This is not X the same as strncpy or strnmov, while move a maximum of len bytes X and stop early if they hit a NUL character. This moves len bytes X exactly, no more, no less. See also bcopy() and bmove() which do X not return a value but otherwise do the same job. X X Note: the VAX assembly code version can only handle 0 <= len < 2^16. X It is presented for your interest and amusement. X*/ X X#include "strings.h" X X#if VaxAsm X Xchar *memcpy(dst, src, len) X char *dst, *src; X int len; X { X asm("movc3 12(ap),*8(ap),*4(ap)"); X return dst; X } X X#else ~VaxAsm X Xchar *memcpy(dst, src, len) X char *dst; X register char *src; X register int len; X { X register char *d; X X for (d = dst; --len >= 0; *d++ = *src++) ; X return dst; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memmov.c X/* File : memmov.c X Author : Richard A. O'Keefe. X Updated: 25 May 1984 X Defines: memmov() X X memmov(dst, src, len) X moves len bytes from src to dst. The result is dst+len. X This is to memcpy as str[n]mov is to str[n]cpy, that is, it moves X exactly the same bytes but returns a pointer to just after the X the last changed byte. You can concatenate blocks pa for la, X pb for lb, pc for lc into area pd by doing X memmov(memmov(memmov(pd, pa, la), pb, lb), pc, lc); X Unlike strnmov, memmov does not stop when it hits a NUL byte. X X Note: the VAX assembly code version can only handle 0 <= len < 2^16. X It is presented for your interest and amusement. X*/ X X#include "strings.h" X X#if VaxAsm X Xchar *memmov(dst, src, len) X char *dst, *src; X int len; X { X asm("movc3 12(ap),*8(ap),*4(ap)"); X return dst+len; X } X X#else ~VaxAsm X Xchar *memmov(dst, src, len) X register char *dst, *src; X register int len; X { X while (--len >= 0) *dst++ = *src++; X return dst; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memory.h X/* File : memory.h X Author : Richard A. O'Keefe. X Updated: 1 June 1984 X Purpose: Header file for the System V "memory(3C)" package. X X All the functions in this package are the original work of Richard X A. O'Keefe. Any resemblance between them and any functions in AT&T X or other licensed software is due entirely to my use of the System V X memory(3C) manual page as a specification. See the READ-ME to find X the conditions under which this material may be used and copied. X X The System V manual says that the mem* functions are declared in the X file. This file is also included in the file, X but it does no harm to #include both in either order. X*/ X X#ifndef memeql X X#define memeql !memcmp Xextern int memcmp(/*char^,char^,int*/); Xextern char *memcpy(/*char^,char^,int*/); Xextern char *memccpy(/*char^,char^,char,int*/); Xextern char *memset(/*char^,char,int*/); Xextern char *memchr(/*char^,char,int*/); Xextern char *memrchr(/*char^,char,int*/); Xextern char *memmov(/*char^,char^,int*/); Xextern void memrev(/*char^,char^,int*/); X X#endif memeql X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memrchr.c X/* File : memrchr.c X Author : Richard A. O'Keefe. X Updated: 25 May 1984 X Defines: memrchr() X X memrchr(src, chr, len) X searches the memory area pointed to by src extending for len bytes, X looking for an occurrence of the byte value chr. It returns NullS X if there is no such occurrence. Otherwise it returns a pointer to X the LAST such occurrence. X X See the "Character Comparison" section in the READ-ME file. X*/ X X#include "strings.h" X Xchar *memrchr(src, chr, len) X register char *src; X register int chr; /* should be char */ X register int len; X { X register char *ans; X for (ans = NullS; --len >= 0; src++) X if (*src == chr) ans = src; X return ans; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memrev.c X/* File : memrev.c X Author : Richard A. O'Keefe. X Updated: 1 June 1984 X Defines: memrev() X X memrev(dst, src, len) X moves len bytes from src to dst, in REVERSE order. NUL characters X receive no special treatment, they are moved like the rest. It is X to strrev as memcpy is to strcpy. X X Note: this function is perfectly happy to reverse a block into the X same place, memrev(x, x, L) will work. X It will not work for partially overlapping source and destination. X*/ X X#include "strings.h" X Xvoid memrev(dsta, srca, len) X register char *dsta, *srca; X int len; X { X register char *dstz, *srcz; X register int t; X X if (len <= 0) return; X srcz = srca+len; X dstz = dsta+len; X while (srcz > srca) { X t = *--srcz; X *--dstz = *srca++; X *dsta++ = t; X } X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memset.c X/* File : memset.c X Author : Richard A. O'Keefe. X Updated: 25 May 1984 X Defines: memset() X X memset(dst, chr, len) X fills the memory area dst[0..len-1] with len bytes all equal to chr. X The result is dst. See also bfill(), which has no return value and X puts the last two arguments the other way around. X X Note: the VAX assembly code version can only handle 0 <= len < 2^16. X It is presented for your interest and amusement. X*/ X X#include "strings.h" X X#if VaxAsm X Xchar *memset(dst, chr, len) X char *dst; X int chr; /* should be char */ X int len; X { X asm("movc5 $0,*4(ap),8(ap),12(ap),*4(ap)"); X return dst; X } X X#else ~VaxAsm X Xchar *memset(dst, chr, len) X char *dst; X register int chr; /* should be char */ X register int len; X { X register char *d; X X for (d = dst; --len >= 0; *d++ = chr) ; X return dst; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > memtrans.c X/* File : memtrans.c X Author : Richard A. O'Keefe. X Updated: 2 June 1984 X Defines: memtrans() X X memtrans(dst, src, from, to, len) X copies exactly len characters from src[] to dst[], translating chars X in from[] to corresponding characters in to[]. From[] and to[] are X handled by _str2map. BEWARE: _str2map normally expects characters in X the range 0..127. The Vax MOVTC instruction thinks its table is 256 X bytes long; if you want to translate arbitrary bytes you'd better be X sure that the _map_vec array is 256 bytes long. As distributed, the X memtrans function is only for translating ASCII (to 8-bit codes). X X The VaxAsm code can only handle 0 <= len < 2^16, and is presented as X usual for your interest and amusement. Why *do* designers of 32-bit X machines put 16-bit limits on strings? (Dec aren't the only ones.) X*/ X X#include "strings.h" X#include "_str2map.h" X X#if VaxAsm X Xvoid memtrans(dst, src, from, to, len) X _char_ *dst, *src, *from, *to; X int len; X { X _str2map(0, from, to); X asm("movtc 20(ap),*8(ap),$0,__map_vec,20(ap),*4(ap)"); X } X X#else ~VaxAsm X Xvoid memtrans(dst, src, from, to, len) X register _char_ *dst, *src; X _char_ *from, *to; X register int len; X { X _str2map(0, from, to); X while (--len >= 0) *dst++ = _map_vec[*src++]; X } X X#endif VaxAsm X SHAR_EOF exit