Subject: strings (3 of 3) Newsgroups: mod.sources Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 112 Submitted by: #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # strpack.c # strpbrk.c # strpref.c # strrchr.c # strrepl.c # strrev.c # strrpt.c # strspn.c # strsuff.c # strtok.c # strtrans.c # strtrim.c # strxcat.c # strxcpy.c # strxmov.c # strxncat.c # strxncpy.c # strxnmov.c # substr.c # xstring.3c sed 's/^X//' << 'SHAR_EOF' > strpack.c X/* File : strpack.c X Author : Richard A. O'Keefe. X Updated: 20 April 1984 X Defines: strpack() X X strpack(dst, src, set, c) X copies characters from src to dst, stopping when it finds a NUL. If X c is NUL, characters in set are not copied to dst. If c is not NUL, X sequences of characters from set are copied as a single c. X strpack(d, s, " \t", ' ') can be used to compress white space, X strpack(d, s, " \t", NUL) to eliminate it. To translate characters X in set to c without compressing runs, see strtrans(). The result is X the address of the NUL byte now terminating dst. Note that dst may X safely be the same as src. X*/ X X#include "strings.h" X#include "_str2set.h" X Xchar *strpack(dst, src, set, c) X register _char_ *dst, *src; X char *set; X register int c; X { X register int chr; X X _str2set(set); X while (chr = *src++) { X if (_set_vec[chr] == _set_ctr) { X while ((chr = *src++) && _set_vec[chr] == _set_ctr) ; X if (c) *dst++ = c; /* 1. If you don't want trailing */ X if (!chr) break; /* 2. things turned into "c", swap */ X } /* lines 1 and 2. */ X *dst++ = chr; X } X *dst = 0; X return dst; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strpbrk.c X/* File : strpbrk.c X Author : Richard A. O'Keefe. X Updated: 11 April 1984 X Defines: strpbrk() X X strpbrk(s1, s2) returns NullS if no character of s2 occurs in s1, or X a pointer to the first character of s1 which occurs in s2 if there X is one. It generalises strchr (v7=index). It wouldn't be useful to X consider NUL as part of s2, as that would occur in every s1. X*/ X X#include "strings.h" X#include "_str2set.h" X Xchar *strpbrk(str, set) X register _char_ *str; X char *set; X { X _str2set(set); X while (_set_vec[*str] != _set_ctr) X if (!*str++) return NullS; X return str; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strpref.c X/* File : strpref.c X Author : Richard A. O'Keefe. X Updated: 11 April 1984 X Defines: strpref() X X strpref(src, prefix) X checks whether prefix is a prefix of src. If it is not, the result X is NullS. If it is, the result is a pointer to the first character X of src after the prefix (src+strlen(prefix)). You can use this in a X conditional as a test: if (strpref(....)), but this is only portable X provided you remember to declare strpref() properly or use strings.h X as if (...) tests numbers against 0 and pointers against a suitable X cast of 0; there is no guarantee that (char*)0 is represented by the X same bit pattern as (int)0. X*/ X X#include "strings.h" X Xchar *strpref(src, prefix) X register char *src, *prefix; X { X while (*prefix) if (*src++ != *prefix++) return NullS; X return src; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strrchr.c X/* File : strrchr.c X Author : Richard A. O'Keefe. X Updated: 10 April 1984 X Defines: strrchr(), rindex() X X strrchr(s, c) returns a pointer to the last place in s where c X occurs, or NullS if c does not occur in s. This function is called X rindex in V7 and 4.?bsd systems; while not ideal the name is clearer X than strrchr, so rindex remains in strings.h as a macro. NB: X strrchr looks for single characters, not for sets or strings. The X parameter 'c' is declared 'int' so it will go in a register; if your X C compiler is happy with register char change it to that. X*/ X X#include "strings.h" X Xchar *strrchr(s, c) X register _char_ *s; X register int c; X { X register char *t; X X t = NullS; X do if (*s == c) t = s; while (*s++); X return t; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strrepl.c X/* File : strrepl.c X Author : Richard A. O'Keefe. X Updated: 23 April 1984 X Defines: strrepl() X X strrepl(dst, src, pat, rep, times) copies src to dst, replacing the X first "times" non-overlapping instances of pat by rep. pat is not a X regex(3) pattern, it is a literal string which must be matched X exactly. As a special hack, since strfind claims to find "" just X once at the end of the src string, strrepl does a strcat when pat is X an empty string "". If times <= 0, it is just strmov. X X The result is a pointer to the NUL which now terminates dst. X X BEWARE: even when rep is shorter than pat it is NOT necessarily safe X for dst to be the same as src. ALWAYS make sure dst and src do not/ X will not overlap. You have been warned. X X There really ought to be a strnrepl with a bound for the size of the X destination string, but there isn't. X*/ X X#include "strings.h" X#include "_str2pat.h" X Xchar *strrepl(dst, src, pat, rep, times) X char *dst, *src, *pat, *rep; X int times; X { X register char *s, *p; X register int c, lastch; X X pat = _str2pat(pat); X if (times <= 0) { X for (p = dst, s = src; *p++ = *s++; ) ; X return p-1; X } X if (_pat_lim < 0) { X for (p = dst, s = src; *p++ = *s++; ) ; X for (--p, s = rep; *p++ = *s++; ) ; X return p-1; X } X /* The pattern is non-empty and times is positive */ X c = _pat_lim, lastch = pat[c]; X for (;;) { X for (s = src, p = dst; --c >= 0; ) X if (!(*p++ = *s++)) return p-1; X c = *s, src = s, dst = p; X if (c == lastch) { X for (s -= _pat_lim, p = pat; *p; ) X if (*s++ != *p++) goto not_yet; X for (p = dst-_pat_lim, s = rep; *p++ = *s++; ) ; X --p; X if (--times == 0) { X for (s = src; *p++ = *++s; ) ; X return p-1; X } X dst = p, src++, c = _pat_lim; X } else { Xnot_yet: c = _pat_vec[c]; X } X } X } SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strrev.c X/* File : strrev.c X Author : Richard A. O'Keefe. X Updated: 1 June 1984 X Defines: strrev() X X strrev(dst, src) X copies all the characters of src to dst, in REVERSE order. Dst is X properly terminated with a NUL character. There is no result. X Example: strrev(x, "able was I er") moves "re I saw elba" to x. X X Note: this function is perfectly happy to reverse a string into the X same place, strrev(x, x) will work. That is why it looks so hairy. X It will not work for partially overlapping source and destination. X*/ X X#include "strings.h" X Xvoid strrev(dsta, srca) X register char *dsta, *srca; X { X register char *dstz, *srcz; X register int t; /* should be char */ X X for (srcz = srca; *srcz++; ) ; X srcz--; X dstz = dsta+(srcz-srca); X /* Now srcz points to the NUL terminating src, X and dstz points to where the terminating NUL for dst belongs. X */ X *dstz = NUL; X while (srcz > srca) { X /* This is guaranteed safe by K&R, since srcz and srca X point "into the same array". X */ X t = *--srcz; X *--dstz = *srca++; X *dsta++ = t; X } X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strrpt.c X/* File : strrpt.c X Author : Richard A. O'Keefe. X Updated: 20 April 1984 X Defines: strrpt() X X strrpt(dst, src, k) "RePeaTs" the string src into dst k times. E.g. X strrpt(dst, "hack ", 2) will move "hack hack" to dst. If k <= 0 it X does nothing. The result is the number of characters moved, except X for the closing NUL. src may be "" but may not of course be NullS. X*/ X X#include "strings.h" X Xint strrpt(dst, src, k) X register char *dst; X char *src; X int k; X { X char *save; X X for (save = dst; --k >= 0; --dst) { X register char *p; X for (p = src; *dst++ = *p++; ) ; X } X return dst-save; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strspn.c X/* File : strspn.c X Author : Richard A. O'Keefe. X Updated: 11 April 1984 X Defines: strspn() X X strspn(s1, s2) returns the length of the longest prefix of s1 X consisting entirely of characters in s2. NUL is not considered to X be in s2, and _str2set will not include it in the set. X*/ X X#include "strings.h" X#include "_str2set.h" X Xint strspn(str, set) X register _char_ *str; X char *set; X { X register int L; X X _str2set(set); X for (L = 0; _set_vec[*str++] == _set_ctr; L++) ; X return L; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strsuff.c X/* File : strsuff.c X Author : Richard A. O'Keefe. X Updated: 11 April 1984 X Defines: strsuff() X X strsuff(src, suffix) X checks whether suffix is a suffix of src. If it is not, the result X is NullS. If it is, the result is a pointer to the character of src X where suffix starts (which is the same as src+strlen(src)-strlen(prefix) ). X See strpref.c for a comment about using if (strsuff(...)) in C. X*/ X X#include "strings.h" X Xchar *strsuff(src, suffix) X register char *src, *suffix; X { X register int L; /* length of suffix */ X X for (L = 0; *suffix++; L++) X if (!*src++) return NullS; X while (*src++) ; X for (--src, --suffix; --L >= 0; ) X if (*--src != *--suffix) return NullS; X return src; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strtok.c X/* File : strtok.c X Author : Richard A. O'Keefe. X Updated: 11 April 1984 X Defines: istrtok(), strtok() X X strtok(src, set) X skips over initial characters of src[] which occur in set[]. X The result is a pointer to the first character of src[] X which does not occur in set[]. It then skips until it finds X a character which does occur in set[], and changes it to NUL. X If src is NullS, it is as if you had specified the place X just after the last NUL was written. If src[] contains no X characters which are not in set[] (e.g. if src == "") the X result is NullS. X X To read a sequence of words separated by spaces you might write X p = strtok(sequence, " "); X while (p) {process_word(p); p = strtok(NullS, " ");} X This is unpleasant, so there is also a function X X istrtok(src, set) X which builds the set and notes the source string for future X reference. With this function, you can write X X for (istrtok(wordlist, " \t"); p = strtok(NullS, NullS); ) X process_word(p); X*/ X X#include "strings.h" X#include "_str2set.h" X Xstatic char *oldSrc = ""; X Xvoid istrtok(src, set) X char *src, *set; X { X _str2set(set); X if (src != NullS) oldSrc = src; X } X X Xchar *strtok(src, set) X register char *src; X char *set; X { X char *save; X X _str2set(set); X if (src == NullS) src = oldSrc; X while (_set_vec[*src] == _set_ctr) src++; X if (!*src) return NullS; X save = src; X while (_set_vec[*++src] != _set_ctr) ; X *src++ = NUL; X oldSrc = src; X return save; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strtrans.c X/* File : strtrans.c X Author : Richard A. O'Keefe. X Updated: 2 June 1984 X Defines: strtrans() X X strtrans(dst, src, from, to) X copies characters from src[] to dst[], stopping when dst gets a NUL X character, translating characters in from[] to the corresponding X characters in to[]. Courtesy of _str2map, if from or to is null its X previous value will be used, and if both are NullS the table won't X be rebuilt. Note that copying stops when a NUL is put into dst[], X which can normally happen only when a NUL has been fetched from X src[], but if you have built your own translation table it may be X earlier (if some character is mapped to NUL) or later (if NUL is X mapped to something else). No value is returned. X X The VaxAsm version only works from strlen(src) < 2^16. X*/ X X#include "strings.h" X#include "_str2map.h" X X#if VaxAsm X Xvoid strtrans(dst, src, from, to) X _char_ *dst, *src, *from, *to; X { X _str2map(0, from, to); X asm("movtuc $65535,*8(ap),$0,__map_vec,$65535,*4(ap)"); X /* That stops when the "escape" is found, and we want to move it */ X asm("movb $0,(r5)"); X } X X#else ~VaxAsm X Xvoid strtrans(dst, src, from, to) X register _char_ *dst, *src; X _char_ *from, *to; X { X _str2map(0, from, to); X while (*dst++ = _map_vec[*src++]) ; X } X X#endif VaxAsm X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strtrim.c X/* File : strtrim.c X Author : Richard A. O'Keefe. X Updated: 20 April 1984 X Defines: strtrim() X X strtrim(dst, src, set, ends) X copies src to dst, but will skip leading characters in set if "ends" X is <= 0, and will skip trailing characters in set if ends is >= 0. X Thus there are three cases: X ends < 0 : trim a prefix X ends = 0 : trim a prefix and a suffix both X ends > 0 : trim a suffix X To compress internal runs, see strpack. The normal use of this is X strtrim(buffer, buffer, " \t", 0); The result is the address of the X NUL which now terminates dst. X*/ X X#include "strings.h" X#include "_str2set.h" X Xchar *strtrim(dst, src, set, ends) X register char *dst, *src; X char *set; X int ends; X { X _str2set(set); X if (ends <= 0) { X while (_set_vec[*src] == _set_ctr) src++; X } X if (ends >= 0) { X register int chr; X register char *save = dst; X while (chr = *src++) { X *dst++ = chr; X if (_set_vec[chr] != _set_ctr) save = dst; X } X dst = save, *dst = NUL; X } else { X while (*dst++ = *src++) ; X --dst; X } X return dst; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strxcat.c X/* File : strxcat.c X Author : Richard A. O'Keefe. X Updated: 25 may 1984 X Defines: strxcat() X X strxcat(dst, src1, ..., srcn, NullS) X moves the concatenation of dst,src1,...,srcn to dst, terminates it X with a NUL character, and returns the original value of dst. X It is just like strcat except that it concatenates multiple sources. X Equivalence: strxcat(d, s1, ..., sn) <=> strxcpy(d, d, s1, ..., sn). X Beware: the last argument should be the null character pointer. X Take VERY great care not to omit it! Also be careful to use NullS X and NOT to use 0, as on some machines 0 is not the same size as a X character pointer, or not the same bit pattern as NullS. X*/ X X#include "strings.h" X#include X X/*VARARGS*/ Xchar *strxcat(va_alist) X va_dcl X { X va_list pvar; X register char *dst, *src; X char *bogus; X X va_start(pvar); X dst = va_arg(pvar, char *); X bogus = dst; X while (*dst) dst++; X src = va_arg(pvar, char *); X while (src != NullS) { X while (*dst++ = *src++) ; X dst--; X src = va_arg(pvar, char *); X } X return bogus; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strxcpy.c X/* File : strxcpy.c X Author : Richard A. O'Keefe. X Updated: 25 may 1984 X Defines: strxcpy() X X strxcpy(dst, src1, ..., srcn, NullS) X moves the concatenation of src1,...,srcn to dst, terminates it X with a NUL character, and returns the original value of dst. X It is just like strcpy except that it concatenates multiple sources. X Beware: the last argument should be the null character pointer. X Take VERY great care not to omit it! Also be careful to use NullS X and NOT to use 0, as on some machines 0 is not the same size as a X character pointer, or not the same bit pattern as NullS. X*/ X X#include "strings.h" X#include X X/*VARARGS*/ Xchar *strxcpy(va_alist) X va_dcl X { X va_list pvar; X register char *dst, *src; X char *bogus; X X va_start(pvar); X dst = va_arg(pvar, char *); X bogus = dst; X src = va_arg(pvar, char *); X while (src != NullS) { X while (*dst++ = *src++) ; X dst--; X src = va_arg(pvar, char *); X } X *dst = NUL; /* there might have been no sources! */ X return bogus; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strxmov.c X/* File : strxmov.c X Author : Richard A. O'Keefe. X Updated: 25 may 1984 X Defines: strxmov() X X strxmov(dst, src1, ..., srcn, NullS) X moves the concatenation of src1,...,srcn to dst, terminates it X with a NUL character, and returns a pointer to the terminating NUL. X It is just like strmov except that it concatenates multiple sources. X Beware: the last argument should be the null character pointer. X Take VERY great care not to omit it! Also be careful to use NullS X and NOT to use 0, as on some machines 0 is not the same size as a X character pointer, or not the same bit pattern as NullS. X*/ X X#include "strings.h" X#include X X/*VARARGS*/ Xchar *strxmov(va_alist) X va_dcl X { X va_list pvar; X register char *dst, *src; X X va_start(pvar); X dst = va_arg(pvar, char *); X src = va_arg(pvar, char *); X while (src != NullS) { X while (*dst++ = *src++) ; X dst--; X src = va_arg(pvar, char *); X } X *dst = NUL; /* there might have been no sources! */ X return dst; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strxncat.c X/* File : strxncat.c X Author : Richard A. O'Keefe. X Updated: 2 June 1984 X Defines: strxncat() X X strxncat(dst, len, src1, ..., srcn, NullS) X moves the first len bytes of the concatenation of dst,src1,...,srcn X to dst, terminating it with a NUL character unless len runs out, and X returns the original value of dst. X It is just like strcat except that it concatenates multiple sources. X Roughly, strxncat(d, L, s1, ..., sn) <=> strxncpy(d, L, d, s1, ..., sn). X Beware: the last argument should be the null character pointer. X Take VERY great care not to omit it! Also be careful to use NullS X and NOT to use 0, as on some machines 0 is not the same size as a X character pointer, or not the same bit pattern as NullS. X X Note: strxncat is like strncat in that it will add at most one NUL, X and may in consequence move fewer than len characters. No so the X strxncpy and strxnmov routines, which resemble strncpy and strnmov. X*/ X X#include "strings.h" X#include X X/*VARARGS*/ Xchar *strxncat(va_alist) X va_dcl X { X va_list pvar; X register char *dst, *src; X register int len; X char *bogus; X X va_start(pvar); X dst = va_arg(pvar, char *); X bogus = dst; X len = va_arg(pvar, int); X while (*dst) X if (--len < 0) return bogus; X else dst++; X src = va_arg(pvar, char *); X while (src != NullS) { X do if (--len < 0) return bogus; X while (*dst++ = *src++); X dst--; X src = va_arg(pvar, char *); X } X return bogus; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strxncpy.c X/* File : strxncpy.c X Author : Richard A. O'Keefe. X Updated: 25 may 1984 X Defines: strxncpy() X X strxncpy(dst, len, src1, ..., srcn, NullS) X moves the first len characters of the concatenation of src1,...,srcn X to dst. If there aren't that many characters, a NUL character will X be added to the end of dst to terminate it properly. This gives the X same effect as calling strxcpy(buff, src1, ..., srcn, NullS) with a X large enough buffer, and then calling strncpy(dst, buff, len). X It is just like strncpy except that it concatenates multiple sources. X Beware: the last argument should be the null character pointer. X Take VERY great care not to omit it! Also be careful to use NullS X and NOT to use 0, as on some machines 0 is not the same size as a X character pointer, or not the same bit pattern as NullS. X X Note: strxncpy is like strncpy in that it always moves EXACTLY len X characters; dst will be padded on the right with NUL characters as X needed. strxnmov does the same. strxncat, like strncat, does NOT. X*/ X X#include "strings.h" X#include X X/*VARARGS*/ Xchar *strxncpy(va_alist) X va_dcl X { X va_list pvar; X register char *dst, *src; X register int len; X char *bogus; X X va_start(pvar); X dst = va_arg(pvar, char *); X bogus = dst; X len = va_arg(pvar, int); X src = va_arg(pvar, char *); X while (src != NullS) { X do if (--len < 0) return bogus; X while (*dst++ = *src++); X dst--; X src = va_arg(pvar, char *); X } X for (src = dst; --len >= 0; *dst++ = NUL) ; X return bogus; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > strxnmov.c X/* File : strxnmov.c X Author : Richard A. O'Keefe. X Updated: 2 June 1984 X Defines: strxnmov() X X strxnmov(dst, len, src1, ..., srcn, NullS) X moves the first len characters of the concatenation of src1,...,srcn X to dst. If there aren't that many characters, a NUL character will X be added to the end of dst to terminate it properly. This gives the X same effect as calling strxcpy(buff, src1, ..., srcn, NullS) with a X large enough buffer, and then calling strnmov(dst, buff, len). X It is just like strnmov except that it concatenates multiple sources. X Beware: the last argument should be the null character pointer. X Take VERY great care not to omit it! Also be careful to use NullS X and NOT to use 0, as on some machines 0 is not the same size as a X character pointer, or not the same bit pattern as NullS. X X Note: strxnmov is like strnmov in that it always moves EXACTLY len X characters; dst will be padded on the right with NUL characters as X needed. strxncpy does the same. strxncat, like strncat, does NOT. X*/ X X#include "strings.h" X#include X X/*VARARGS*/ Xchar *strxnmov(va_alist) X va_dcl X { X va_list pvar; X register char *dst, *src; X register int len; X X va_start(pvar); X dst = va_arg(pvar, char *); X len = va_arg(pvar, int); X src = va_arg(pvar, char *); X while (src != NullS) { X do if (--len < 0) return dst; X while (*dst++ = *src++); X dst--; X src = va_arg(pvar, char *); X } X for (src = dst; --len >= 0; *dst++ = NUL) ; X return src; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > substr.c X/* File : substr.c X Author : Richard A. O'Keefe. X Updated: 25 May 1984 X Defines: substr() X X substr(destination, source, offset, length) X copies length bytes from source+offset to destination, stopping X early if a NUL is encountered. The difference between this and X strncpy(destination, source+offset, length) X is that if the offset is negative, it has the same effect as 0, X and if it exceeds strlen(source), it has the same effect as X strlen(source). If either of these boundaries is hit, or if X a NUL is encountered before length bytes have been moved, the X value of errno will be EDOM, otherwise it is guaranteed to be 0. X That is: X errno == 0 <=> (0 <= offset <= strlen(source) X && 0 <= length && <= strlen(source)-offset) X You may accept the sensible result produced when these boundary X conditions are violated, or you may treat it as an error, as you X will. There is an algebra of sequences in which this treatment X of boundary conditions makes sense. X X After the substring of source is moved to destination, a NUL byte X is moved to terminate the string, and the result is a pointer to X this NUL byte, ready to have new stuff stuck on the end. X X I suppose this should be called strsub, but I can't stick it. X*/ X X#include "strings.h" X#include X Xextern int errno; /* why isn't this in errno.h?? */ X X Xchar *substr(dst, src, off, len) X register char *dst, *src; X register int off, len; X { X errno = off < 0 || len < 0 ? EDOM : 0; X X while (--off >= 0) X if (!*src++) { /* We've hit the end */ X errno = EDOM; /* report boundary violation */ X *dst = NUL; /* return empty string */ X return dst; X } X while (--len >= 0) X if (!(*dst++ = *src++)) { /* We've hit the end */ X errno = EDOM; X return dst-1; /* dst is already terminated */ X } X *dst = NUL; /* terminate dst with NUL */ X return dst; X } X SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > xstring.3c X.TH XSTRING 3C local X.SH NAME Xstrxcat, strxncat, strxcpy, strxncpy, strxmov, strxnmov \- string operations with variable number of arguments X.SH SYNOPSIS X.nf X.PP X.B "#include " X.PP X.B "char \(**strxcat(dst, src1, src2, ..., NullS)" X.B " char \(**dst, \(**src1, \(**src2, ...;" X.PP X.B "char \(**strxncat(dst, len, src1, src2, ..., NullS)" X.B " char \(**dst, \(**src1, \(**src2, ...;" X.B " int len;" X.PP X.B "char \(**strxcpy(dst, src1, src2, ..., NullS)" X.B " char \(**dst, \(**src1, \(**src2, ...;" X.PP X.B "char \(**strxncpy(dst, len, src1, src2, ..., NullS)" X.B " char \(**dst, \(**src1, \(**src2, ...;" X.B " int len;" X.PP X.B "char \(**strxmov(dst, src1, src2, ..., NullS)" X.B " char \(**dst, \(**src1, \(**src2, ...;" X.PP X.B "char \(**strxnmov(dst, len, src1, src2, ..., NullS)" X.B " char \(**dst, \(**src1, \(**src2, ...;" X.B " int len;" X.SH DESCRIPTION XThese functions operate on null-terminated strings. XThey are equivalent to the corresponding functions X.IR strcat (3c), X.IR strncat (3c), X.IR strmov (3c), X.IR strnmov (3c), X.IR strcpy (3c), Xand X.IR strncpy (3c), Xexcept that they allow more than one source string to be supplied. X.IR Strxcat , X.IR strxncat , X.IR strxcpy , Xand X.I strxncpy Xreturn their first argument (the destination pointer). X.I Strxmov Xand X.I strxnmov Xreturn a pointer to just after the last non-NUL character Xmoved to the destination. This is the same convention that Xis used throughout the strings package. XExcept as implied by the length parameter X.IR len , Xthey do not check for overflow of any receiving string. X.PP X.I Strxcat Xappends a copy of the strings X.IR src1 , X.IR src2 , Xand so on, to X.IR dst . XThe resulting string will always be NUL-terminated. X.I Strxncat Xcopies at most X.I len Xcharacters. XThe resulting string will be NUL-terminated if fewer than X.I len Xcharacters were moved. At most one NUL is added. X.PP X.I Strxcpy Xcopies the strings X.IR src1 , X.IR src2 , Xand so on, into X.IR dst . X.I Strxncpy Xcopies at most X.I len Xcharacters. XThe resulting string will not be null-terminated if X.I len Xor more characters were in the source strings. XBy analogy with X.IR strncpy , X.I dst Xwill be padded on the right with NUL characters to exactly X.I len Xbytes. X.PP XApart from their return value, X.I strxmov Xand X.I strxnmov Xhave the same effect as X.I strxcpy Xand X.IR strxncpy . X.SH CAVEATS XThe placement for the X.I len Xvariable is different from the placement in the functions X.IR strncat (3c), X.IR strncpy (3c), Xand X.IR strnmov (3c). SHAR_EOF exit