home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / strings / part3 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  26.1 KB

  1. Subject: strings (3 of 3)
  2. Newsgroups: mod.sources
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 4, Issue 112
  6. Submitted by: <talcott!wjh12!maynard!campbell>
  7.  
  8. #!/bin/sh
  9. # shar:    Shell Archiver
  10. #    Run the following text with /bin/sh to create:
  11. #    strpack.c
  12. #    strpbrk.c
  13. #    strpref.c
  14. #    strrchr.c
  15. #    strrepl.c
  16. #    strrev.c
  17. #    strrpt.c
  18. #    strspn.c
  19. #    strsuff.c
  20. #    strtok.c
  21. #    strtrans.c
  22. #    strtrim.c
  23. #    strxcat.c
  24. #    strxcpy.c
  25. #    strxmov.c
  26. #    strxncat.c
  27. #    strxncpy.c
  28. #    strxnmov.c
  29. #    substr.c
  30. #    xstring.3c
  31. sed 's/^X//' << 'SHAR_EOF' > strpack.c
  32. X/*  File   : strpack.c
  33. X    Author : Richard A. O'Keefe.
  34. X    Updated: 20 April 1984
  35. X    Defines: strpack()
  36. X
  37. X    strpack(dst, src, set, c)
  38. X    copies characters from src to dst, stopping when it finds a NUL.  If
  39. X    c is NUL, characters in set are not copied to dst.  If c is not NUL,
  40. X    sequences of characters from set are copied as a single c.
  41. X    strpack(d, s, " \t", ' ') can be used to compress white space,
  42. X    strpack(d, s, " \t", NUL) to eliminate it.  To translate  characters
  43. X    in  set to c without compressing runs, see strtrans(). The result is
  44. X    the address of the NUL byte now terminating dst.  Note that dst  may
  45. X    safely be the same as src.
  46. X*/
  47. X
  48. X#include "strings.h"
  49. X#include "_str2set.h"
  50. X
  51. Xchar *strpack(dst, src, set, c)
  52. X    register _char_ *dst, *src;
  53. X    char *set;
  54. X    register int c;
  55. X    {
  56. X    register int chr;
  57. X
  58. X    _str2set(set);
  59. X    while (chr = *src++) {
  60. X        if (_set_vec[chr] == _set_ctr) {
  61. X        while ((chr = *src++) && _set_vec[chr] == _set_ctr) ;
  62. X        if (c) *dst++ = c;    /* 1. If you don't want trailing */
  63. X        if (!chr) break;    /* 2. things turned into "c", swap */
  64. X        }                /* lines 1 and 2. */
  65. X        *dst++ = chr;
  66. X    }
  67. X    *dst = 0;
  68. X    return dst;
  69. X    }
  70. X
  71. SHAR_EOF
  72. sed 's/^X//' << 'SHAR_EOF' > strpbrk.c
  73. X/*  File   : strpbrk.c
  74. X    Author : Richard A. O'Keefe.
  75. X    Updated: 11 April 1984
  76. X    Defines: strpbrk()
  77. X
  78. X    strpbrk(s1, s2) returns NullS if no character of s2 occurs in s1, or
  79. X    a pointer to the first character of s1 which occurs in s2  if  there
  80. X    is one.  It generalises strchr (v7=index).  It wouldn't be useful to
  81. X    consider NUL as part of s2, as that would occur in every s1.
  82. X*/
  83. X
  84. X#include "strings.h"
  85. X#include "_str2set.h"
  86. X
  87. Xchar *strpbrk(str, set)
  88. X    register _char_ *str;
  89. X    char *set;
  90. X    {
  91. X    _str2set(set);
  92. X    while (_set_vec[*str] != _set_ctr)
  93. X        if (!*str++) return NullS;
  94. X    return str;
  95. X    }
  96. X
  97. SHAR_EOF
  98. sed 's/^X//' << 'SHAR_EOF' > strpref.c
  99. X/*  File   : strpref.c
  100. X    Author : Richard A. O'Keefe.
  101. X    Updated: 11 April 1984
  102. X    Defines: strpref()
  103. X
  104. X    strpref(src, prefix)
  105. X    checks whether prefix is a prefix of src.  If it is not, the  result
  106. X    is  NullS.  If it is, the result is a pointer to the first character
  107. X    of src after the prefix (src+strlen(prefix)).  You can use this in a
  108. X    conditional as a test: if (strpref(....)), but this is only portable
  109. X    provided you remember to declare strpref() properly or use strings.h
  110. X    as if (...) tests numbers against 0 and pointers against a suitable
  111. X    cast of 0; there is no guarantee that (char*)0 is represented by the
  112. X    same bit pattern as (int)0.
  113. X*/
  114. X
  115. X#include "strings.h"
  116. X
  117. Xchar *strpref(src, prefix)
  118. X    register char *src, *prefix;
  119. X    {
  120. X    while (*prefix) if (*src++ != *prefix++) return NullS;
  121. X    return src;
  122. X    }
  123. X
  124. SHAR_EOF
  125. sed 's/^X//' << 'SHAR_EOF' > strrchr.c
  126. X/*  File   : strrchr.c
  127. X    Author : Richard A. O'Keefe.
  128. X    Updated: 10 April 1984
  129. X    Defines: strrchr(), rindex()
  130. X
  131. X    strrchr(s, c) returns a pointer to the  last  place  in  s  where  c
  132. X    occurs,  or  NullS if c does not occur in s. This function is called
  133. X    rindex in V7 and 4.?bsd systems; while not ideal the name is clearer
  134. X    than strrchr, so rindex  remains  in  strings.h  as  a  macro.   NB:
  135. X    strrchr  looks  for single characters, not for sets or strings.  The
  136. X    parameter 'c' is declared 'int' so it will go in a register; if your
  137. X    C compiler is happy with register char change it to that.
  138. X*/
  139. X
  140. X#include "strings.h"
  141. X
  142. Xchar *strrchr(s, c)
  143. X    register _char_ *s;
  144. X    register int c;
  145. X    {
  146. X    register char *t;
  147. X
  148. X    t = NullS;
  149. X    do if (*s == c) t = s; while (*s++);
  150. X    return t;
  151. X    }
  152. X
  153. SHAR_EOF
  154. sed 's/^X//' << 'SHAR_EOF' > strrepl.c
  155. X/*  File   : strrepl.c
  156. X    Author : Richard A. O'Keefe.
  157. X    Updated: 23 April 1984
  158. X    Defines: strrepl()
  159. X
  160. X    strrepl(dst, src, pat, rep, times) copies src to dst, replacing  the
  161. X    first "times" non-overlapping instances of pat by rep.  pat is not a
  162. X    regex(3) pattern, it is a  literal  string  which  must  be  matched
  163. X    exactly.   As  a  special hack, since strfind claims to find "" just
  164. X    once at the end of the src string, strrepl does a strcat when pat is
  165. X    an empty string "".  If times <= 0, it is just strmov.
  166. X
  167. X    The result is a pointer to the NUL which now terminates dst.
  168. X
  169. X    BEWARE: even when rep is shorter than pat it is NOT necessarily safe
  170. X    for dst to be the same as src.  ALWAYS make sure dst and src do not/
  171. X    will not overlap.  You have been warned.
  172. X
  173. X    There really ought to be a strnrepl with a bound for the size of the
  174. X    destination string, but there isn't.
  175. X*/
  176. X
  177. X#include "strings.h"
  178. X#include "_str2pat.h"
  179. X
  180. Xchar *strrepl(dst, src, pat, rep, times)
  181. X    char *dst, *src, *pat, *rep;
  182. X    int times;
  183. X    {
  184. X    register char *s, *p;
  185. X    register int c, lastch;
  186. X
  187. X    pat = _str2pat(pat);
  188. X    if (times <= 0) {
  189. X        for (p = dst, s = src; *p++ = *s++; ) ;
  190. X        return p-1;
  191. X    }
  192. X    if (_pat_lim < 0) {
  193. X        for (p = dst, s = src; *p++ = *s++; ) ;
  194. X        for (--p, s = rep; *p++ = *s++; ) ;
  195. X        return p-1;
  196. X     }
  197. X    /*  The pattern is non-empty and times is positive  */
  198. X    c = _pat_lim, lastch = pat[c];
  199. X    for (;;) {
  200. X        for (s = src, p = dst; --c >= 0; )
  201. X        if (!(*p++ = *s++)) return p-1;
  202. X        c = *s, src = s, dst = p;
  203. X        if (c == lastch) {
  204. X        for (s -= _pat_lim, p = pat; *p; )
  205. X            if (*s++ != *p++) goto not_yet;
  206. X        for (p = dst-_pat_lim, s = rep; *p++ = *s++; ) ;
  207. X        --p;
  208. X        if (--times == 0) {
  209. X            for (s = src; *p++ = *++s; ) ;
  210. X            return p-1;
  211. X        }
  212. X        dst = p, src++, c = _pat_lim;
  213. X        } else {
  214. Xnot_yet:    c = _pat_vec[c];
  215. X        }
  216. X    }
  217. X    }
  218. SHAR_EOF
  219. sed 's/^X//' << 'SHAR_EOF' > strrev.c
  220. X/*  File   : strrev.c
  221. X    Author : Richard A. O'Keefe.
  222. X    Updated: 1 June 1984
  223. X    Defines: strrev()
  224. X
  225. X    strrev(dst, src)
  226. X    copies all the characters of src to dst, in REVERSE order.   Dst is
  227. X    properly terminated with a NUL character.  There is no result.
  228. X    Example: strrev(x, "able was I er") moves "re I saw elba" to x.
  229. X
  230. X    Note: this function is perfectly happy to reverse a string into the
  231. X    same place, strrev(x, x) will work.  That is why it looks so hairy.
  232. X    It will not work for partially overlapping source and destination.
  233. X*/
  234. X
  235. X#include "strings.h"
  236. X
  237. Xvoid strrev(dsta, srca)
  238. X    register char *dsta, *srca;
  239. X    {
  240. X    register char *dstz, *srcz;
  241. X    register int t;            /* should be char */
  242. X
  243. X    for (srcz = srca; *srcz++; ) ;
  244. X    srcz--;
  245. X    dstz = dsta+(srcz-srca);
  246. X    /*  Now srcz points to the NUL terminating src,
  247. X        and dstz points to where the terminating NUL for dst belongs.
  248. X    */
  249. X    *dstz = NUL;
  250. X    while (srcz > srca) {
  251. X        /*  This is guaranteed safe by K&R, since srcz and srca
  252. X        point "into the same array".
  253. X        */
  254. X        t = *--srcz;
  255. X        *--dstz = *srca++;
  256. X        *dsta++ = t;
  257. X    }
  258. X    }
  259. X
  260. SHAR_EOF
  261. sed 's/^X//' << 'SHAR_EOF' > strrpt.c
  262. X/*  File   : strrpt.c
  263. X    Author : Richard A. O'Keefe.
  264. X    Updated: 20 April 1984
  265. X    Defines: strrpt()
  266. X
  267. X    strrpt(dst, src, k) "RePeaTs" the string src into dst k times.  E.g.
  268. X    strrpt(dst, "hack ", 2) will move "hack hack" to dst.  If k <= 0 it
  269. X    does nothing.  The result is the number of characters moved, except
  270. X    for the closing NUL.  src may be "" but may not of course be NullS.
  271. X*/
  272. X
  273. X#include "strings.h"
  274. X
  275. Xint strrpt(dst, src, k)
  276. X    register char *dst;
  277. X    char *src;
  278. X    int k;
  279. X    {
  280. X    char *save;
  281. X
  282. X    for (save = dst; --k >= 0; --dst) {
  283. X        register char *p;
  284. X        for (p = src; *dst++ = *p++; ) ;
  285. X    }
  286. X    return dst-save;
  287. X    }
  288. X
  289. SHAR_EOF
  290. sed 's/^X//' << 'SHAR_EOF' > strspn.c
  291. X/*  File   : strspn.c
  292. X    Author : Richard A. O'Keefe.
  293. X    Updated: 11 April 1984
  294. X    Defines: strspn()
  295. X
  296. X    strspn(s1, s2) returns the  length  of  the  longest  prefix  of  s1
  297. X    consisting  entirely  of characters in s2.  NUL is not considered to
  298. X    be in s2, and _str2set will not include it in the set.
  299. X*/
  300. X
  301. X#include "strings.h"
  302. X#include "_str2set.h"
  303. X
  304. Xint strspn(str, set)
  305. X    register _char_ *str;
  306. X    char *set;
  307. X    {
  308. X    register int L;
  309. X
  310. X    _str2set(set);
  311. X    for (L = 0; _set_vec[*str++] == _set_ctr; L++) ;
  312. X    return L;
  313. X    }
  314. X
  315. SHAR_EOF
  316. sed 's/^X//' << 'SHAR_EOF' > strsuff.c
  317. X/*  File   : strsuff.c
  318. X    Author : Richard A. O'Keefe.
  319. X    Updated: 11 April 1984
  320. X    Defines: strsuff()
  321. X
  322. X    strsuff(src, suffix)
  323. X    checks whether suffix is a suffix of src.  If it is not, the  result
  324. X    is NullS.  If it is, the result is a pointer to the character of src
  325. X    where suffix starts (which is the same as src+strlen(src)-strlen(prefix) ).
  326. X    See strpref.c for a comment about using if (strsuff(...)) in C.
  327. X*/
  328. X
  329. X#include "strings.h"
  330. X
  331. Xchar *strsuff(src, suffix)
  332. X    register char *src, *suffix;
  333. X    {
  334. X    register int L;    /* length of suffix */
  335. X
  336. X    for (L = 0; *suffix++; L++)
  337. X        if (!*src++) return NullS;
  338. X    while (*src++) ;
  339. X    for (--src, --suffix; --L >= 0; )
  340. X        if (*--src != *--suffix) return NullS;
  341. X    return src;
  342. X    }
  343. X
  344. SHAR_EOF
  345. sed 's/^X//' << 'SHAR_EOF' > strtok.c
  346. X/*  File   : strtok.c
  347. X    Author : Richard A. O'Keefe.
  348. X    Updated: 11 April 1984
  349. X    Defines: istrtok(), strtok()
  350. X
  351. X    strtok(src, set)
  352. X    skips over initial characters of src[] which occur in set[].
  353. X    The result is a pointer to the first character of src[]
  354. X    which does not occur in set[].  It then skips until it finds
  355. X    a character which does occur in set[], and changes it to NUL.
  356. X    If src is NullS, it is as if you had specified the place
  357. X    just after the last NUL was written.  If src[] contains no
  358. X    characters which are not in set[] (e.g. if src == "") the
  359. X    result is NullS.
  360. X
  361. X    To read a sequence of words separated by spaces you might write
  362. X    p = strtok(sequence, " ");
  363. X    while (p) {process_word(p); p = strtok(NullS, " ");}
  364. X    This is unpleasant, so there is also a function
  365. X
  366. X    istrtok(src, set)
  367. X    which builds the set and notes the source string for future
  368. X    reference.  With this function, you can write
  369. X
  370. X    for (istrtok(wordlist, " \t"); p = strtok(NullS, NullS); )
  371. X        process_word(p);
  372. X*/
  373. X
  374. X#include "strings.h"
  375. X#include "_str2set.h"
  376. X
  377. Xstatic    char    *oldSrc = "";
  378. X
  379. Xvoid istrtok(src, set)
  380. X    char *src, *set;
  381. X    {
  382. X    _str2set(set);
  383. X    if (src != NullS) oldSrc = src;
  384. X    }
  385. X
  386. X
  387. Xchar *strtok(src, set)
  388. X    register char *src;
  389. X    char *set;
  390. X    {
  391. X    char *save;
  392. X
  393. X    _str2set(set);
  394. X    if (src == NullS) src = oldSrc;
  395. X    while (_set_vec[*src] == _set_ctr) src++;
  396. X    if (!*src) return NullS;
  397. X    save = src;
  398. X    while (_set_vec[*++src] != _set_ctr) ;
  399. X    *src++ = NUL;
  400. X    oldSrc = src;
  401. X    return save;
  402. X    }
  403. X
  404. SHAR_EOF
  405. sed 's/^X//' << 'SHAR_EOF' > strtrans.c
  406. X/*  File   : strtrans.c
  407. X    Author : Richard A. O'Keefe.
  408. X    Updated: 2 June 1984
  409. X    Defines: strtrans()
  410. X
  411. X    strtrans(dst, src, from, to)
  412. X    copies characters from src[] to dst[], stopping when dst gets a  NUL
  413. X    character,  translating  characters  in  from[] to the corresponding
  414. X    characters in to[]. Courtesy of _str2map, if from or to is null  its
  415. X    previous  value  will be used, and if both are NullS the table won't
  416. X    be rebuilt.  Note that copying stops when a NUL is put  into  dst[],
  417. X    which  can  normally  happen  only  when a NUL has been fetched from
  418. X    src[], but if you have built your own translation table  it  may  be
  419. X    earlier  (if  some  character  is mapped to NUL) or later (if NUL is
  420. X    mapped to something else).  No value is returned.
  421. X
  422. X    The VaxAsm version only works from strlen(src) < 2^16.
  423. X*/
  424. X
  425. X#include "strings.h"
  426. X#include "_str2map.h"
  427. X
  428. X#if    VaxAsm
  429. X
  430. Xvoid strtrans(dst, src, from, to)
  431. X    _char_ *dst, *src, *from, *to;
  432. X    {
  433. X    _str2map(0, from, to);
  434. X    asm("movtuc $65535,*8(ap),$0,__map_vec,$65535,*4(ap)");
  435. X    /*  That stops when the "escape" is found, and we want to move it */
  436. X    asm("movb $0,(r5)");
  437. X    }
  438. X
  439. X#else  ~VaxAsm
  440. X
  441. Xvoid strtrans(dst, src, from, to)
  442. X    register _char_ *dst, *src;
  443. X    _char_ *from, *to;
  444. X    {
  445. X    _str2map(0, from, to);
  446. X    while (*dst++ = _map_vec[*src++]) ;
  447. X    }
  448. X
  449. X#endif    VaxAsm
  450. X
  451. SHAR_EOF
  452. sed 's/^X//' << 'SHAR_EOF' > strtrim.c
  453. X/*  File   : strtrim.c
  454. X    Author : Richard A. O'Keefe.
  455. X    Updated: 20 April 1984
  456. X    Defines: strtrim()
  457. X
  458. X    strtrim(dst, src, set, ends)
  459. X    copies src to dst, but will skip leading characters in set if "ends"
  460. X    is <= 0, and will skip trailing characters in set if ends is >= 0.
  461. X    Thus there are three cases:
  462. X    ends < 0 :    trim a prefix
  463. X    ends = 0 :    trim a prefix and a suffix both
  464. X    ends > 0 :    trim a suffix
  465. X    To compress internal runs, see strpack.  The normal use of this is
  466. X    strtrim(buffer, buffer, " \t", 0);  The result is the address of the
  467. X    NUL which now terminates dst.
  468. X*/
  469. X
  470. X#include "strings.h"
  471. X#include "_str2set.h"
  472. X
  473. Xchar *strtrim(dst, src, set, ends)
  474. X    register char *dst, *src;
  475. X    char *set;
  476. X    int ends;
  477. X    {
  478. X    _str2set(set);
  479. X    if (ends <= 0) {
  480. X        while (_set_vec[*src] == _set_ctr) src++;
  481. X    }
  482. X    if (ends >= 0) {
  483. X        register int chr;
  484. X        register char *save = dst;
  485. X        while (chr = *src++) {
  486. X        *dst++ = chr;
  487. X        if (_set_vec[chr] != _set_ctr) save = dst;
  488. X        }
  489. X        dst = save, *dst = NUL;
  490. X    } else {
  491. X        while (*dst++ = *src++) ;
  492. X        --dst;
  493. X    }
  494. X    return dst;
  495. X    }
  496. X
  497. SHAR_EOF
  498. sed 's/^X//' << 'SHAR_EOF' > strxcat.c
  499. X/*  File   : strxcat.c
  500. X    Author : Richard A. O'Keefe.
  501. X    Updated: 25 may 1984
  502. X    Defines: strxcat()
  503. X
  504. X    strxcat(dst, src1, ..., srcn, NullS)
  505. X    moves the concatenation of dst,src1,...,srcn to dst, terminates it
  506. X    with a NUL character, and returns the original value of dst.
  507. X    It is just like strcat except that it concatenates multiple sources.
  508. X    Equivalence: strxcat(d, s1, ..., sn) <=> strxcpy(d, d, s1, ..., sn).
  509. X    Beware: the last argument should be the null character pointer.
  510. X    Take VERY great care not to omit it!  Also be careful to use NullS
  511. X    and NOT to use 0, as on some machines 0 is not the same size as a
  512. X    character pointer, or not the same bit pattern as NullS.
  513. X*/
  514. X
  515. X#include "strings.h"
  516. X#include <varargs.h>
  517. X
  518. X/*VARARGS*/
  519. Xchar *strxcat(va_alist)
  520. X    va_dcl
  521. X    {
  522. X    va_list pvar;
  523. X    register char *dst, *src;
  524. X    char *bogus;
  525. X
  526. X    va_start(pvar);
  527. X    dst = va_arg(pvar, char *);
  528. X    bogus = dst;
  529. X    while (*dst) dst++;
  530. X    src = va_arg(pvar, char *);
  531. X    while (src != NullS) {
  532. X        while (*dst++ = *src++) ;
  533. X        dst--;
  534. X        src = va_arg(pvar, char *);
  535. X    }
  536. X    return bogus;
  537. X    }
  538. X
  539. SHAR_EOF
  540. sed 's/^X//' << 'SHAR_EOF' > strxcpy.c
  541. X/*  File   : strxcpy.c
  542. X    Author : Richard A. O'Keefe.
  543. X    Updated: 25 may 1984
  544. X    Defines: strxcpy()
  545. X
  546. X    strxcpy(dst, src1, ..., srcn, NullS)
  547. X    moves the concatenation of src1,...,srcn to dst, terminates it
  548. X    with a NUL character, and returns the original value of dst.
  549. X    It is just like strcpy except that it concatenates multiple sources.
  550. X    Beware: the last argument should be the null character pointer.
  551. X    Take VERY great care not to omit it!  Also be careful to use NullS
  552. X    and NOT to use 0, as on some machines 0 is not the same size as a
  553. X    character pointer, or not the same bit pattern as NullS.
  554. X*/
  555. X
  556. X#include "strings.h"
  557. X#include <varargs.h>
  558. X
  559. X/*VARARGS*/
  560. Xchar *strxcpy(va_alist)
  561. X    va_dcl
  562. X    {
  563. X    va_list pvar;
  564. X    register char *dst, *src;
  565. X    char *bogus;
  566. X
  567. X    va_start(pvar);
  568. X    dst = va_arg(pvar, char *);
  569. X    bogus = dst;
  570. X    src = va_arg(pvar, char *);
  571. X    while (src != NullS) {
  572. X        while (*dst++ = *src++) ;
  573. X        dst--;
  574. X        src = va_arg(pvar, char *);
  575. X    }
  576. X    *dst = NUL;    /* there might have been no sources! */
  577. X    return bogus;
  578. X    }
  579. X
  580. SHAR_EOF
  581. sed 's/^X//' << 'SHAR_EOF' > strxmov.c
  582. X/*  File   : strxmov.c
  583. X    Author : Richard A. O'Keefe.
  584. X    Updated: 25 may 1984
  585. X    Defines: strxmov()
  586. X
  587. X    strxmov(dst, src1, ..., srcn, NullS)
  588. X    moves the concatenation of src1,...,srcn to dst, terminates it
  589. X    with a NUL character, and returns a pointer to the terminating NUL.
  590. X    It is just like strmov except that it concatenates multiple sources.
  591. X    Beware: the last argument should be the null character pointer.
  592. X    Take VERY great care not to omit it!  Also be careful to use NullS
  593. X    and NOT to use 0, as on some machines 0 is not the same size as a
  594. X    character pointer, or not the same bit pattern as NullS.
  595. X*/
  596. X
  597. X#include "strings.h"
  598. X#include <varargs.h>
  599. X
  600. X/*VARARGS*/
  601. Xchar *strxmov(va_alist)
  602. X    va_dcl
  603. X    {
  604. X    va_list pvar;
  605. X    register char *dst, *src;
  606. X
  607. X    va_start(pvar);
  608. X    dst = va_arg(pvar, char *);
  609. X    src = va_arg(pvar, char *);
  610. X    while (src != NullS) {
  611. X        while (*dst++ = *src++) ;
  612. X        dst--;
  613. X        src = va_arg(pvar, char *);
  614. X    }
  615. X    *dst = NUL;    /* there might have been no sources! */
  616. X    return dst;
  617. X    }
  618. X
  619. SHAR_EOF
  620. sed 's/^X//' << 'SHAR_EOF' > strxncat.c
  621. X/*  File   : strxncat.c
  622. X    Author : Richard A. O'Keefe.
  623. X    Updated: 2 June 1984
  624. X    Defines: strxncat()
  625. X
  626. X    strxncat(dst, len, src1, ..., srcn, NullS)
  627. X    moves the first len bytes of the concatenation of dst,src1,...,srcn
  628. X    to dst, terminating it with a NUL character unless len runs out, and
  629. X    returns the original value of dst.
  630. X    It is just like strcat except that it concatenates multiple sources.
  631. X    Roughly, strxncat(d, L, s1, ..., sn) <=> strxncpy(d, L, d, s1, ..., sn).
  632. X    Beware: the last argument should be the null character pointer.
  633. X    Take VERY great care not to omit it!  Also be careful to use NullS
  634. X    and NOT to use 0, as on some machines 0 is not the same size as a
  635. X    character pointer, or not the same bit pattern as NullS.
  636. X
  637. X    Note: strxncat is like strncat in that it will add at most one NUL,
  638. X    and may in consequence move fewer than len characters.  No so the
  639. X    strxncpy and strxnmov routines, which resemble strncpy and strnmov.
  640. X*/
  641. X
  642. X#include "strings.h"
  643. X#include <varargs.h>
  644. X
  645. X/*VARARGS*/
  646. Xchar *strxncat(va_alist)
  647. X    va_dcl
  648. X    {
  649. X    va_list pvar;
  650. X    register char *dst, *src;
  651. X    register int len;
  652. X    char *bogus;
  653. X
  654. X    va_start(pvar);
  655. X    dst = va_arg(pvar, char *);
  656. X    bogus = dst;
  657. X    len = va_arg(pvar, int);
  658. X    while (*dst)
  659. X        if (--len < 0) return bogus;
  660. X        else dst++;
  661. X    src = va_arg(pvar, char *);
  662. X    while (src != NullS) {
  663. X        do if (--len < 0) return bogus;
  664. X        while (*dst++ = *src++);
  665. X        dst--;
  666. X        src = va_arg(pvar, char *);
  667. X    }
  668. X    return bogus;
  669. X    }
  670. X
  671. SHAR_EOF
  672. sed 's/^X//' << 'SHAR_EOF' > strxncpy.c
  673. X/*  File   : strxncpy.c
  674. X    Author : Richard A. O'Keefe.
  675. X    Updated: 25 may 1984
  676. X    Defines: strxncpy()
  677. X
  678. X    strxncpy(dst, len, src1, ..., srcn, NullS)
  679. X    moves the first len characters of the concatenation of src1,...,srcn
  680. X    to dst.  If there aren't that many characters, a NUL character will
  681. X    be added to the end of dst to terminate it properly.  This gives the
  682. X    same effect as calling strxcpy(buff, src1, ..., srcn, NullS) with a
  683. X    large enough buffer, and then calling strncpy(dst, buff, len).
  684. X    It is just like strncpy except that it concatenates multiple sources.
  685. X    Beware: the last argument should be the null character pointer.
  686. X    Take VERY great care not to omit it!  Also be careful to use NullS
  687. X    and NOT to use 0, as on some machines 0 is not the same size as a
  688. X    character pointer, or not the same bit pattern as NullS.
  689. X
  690. X    Note: strxncpy is like strncpy in that it always moves EXACTLY len
  691. X    characters; dst will be padded on the right with NUL characters as
  692. X    needed.  strxnmov does the same.  strxncat, like strncat, does NOT.
  693. X*/
  694. X
  695. X#include "strings.h"
  696. X#include <varargs.h>
  697. X
  698. X/*VARARGS*/
  699. Xchar *strxncpy(va_alist)
  700. X    va_dcl
  701. X    {
  702. X    va_list pvar;
  703. X    register char *dst, *src;
  704. X    register int len;
  705. X    char *bogus;
  706. X
  707. X    va_start(pvar);
  708. X    dst = va_arg(pvar, char *);
  709. X    bogus = dst;
  710. X    len = va_arg(pvar, int);
  711. X    src = va_arg(pvar, char *);
  712. X    while (src != NullS) {
  713. X        do if (--len < 0) return bogus;
  714. X        while (*dst++ = *src++);
  715. X        dst--;
  716. X        src = va_arg(pvar, char *);
  717. X    }
  718. X    for (src = dst; --len >= 0; *dst++ = NUL) ;
  719. X    return bogus;
  720. X    }
  721. X
  722. SHAR_EOF
  723. sed 's/^X//' << 'SHAR_EOF' > strxnmov.c
  724. X/*  File   : strxnmov.c
  725. X    Author : Richard A. O'Keefe.
  726. X    Updated: 2 June 1984
  727. X    Defines: strxnmov()
  728. X
  729. X    strxnmov(dst, len, src1, ..., srcn, NullS)
  730. X    moves the first len characters of the concatenation of src1,...,srcn
  731. X    to dst.  If there aren't that many characters, a NUL character will
  732. X    be added to the end of dst to terminate it properly.  This gives the
  733. X    same effect as calling strxcpy(buff, src1, ..., srcn, NullS) with a
  734. X    large enough buffer, and then calling strnmov(dst, buff, len).
  735. X    It is just like strnmov except that it concatenates multiple sources.
  736. X    Beware: the last argument should be the null character pointer.
  737. X    Take VERY great care not to omit it!  Also be careful to use NullS
  738. X    and NOT to use 0, as on some machines 0 is not the same size as a
  739. X    character pointer, or not the same bit pattern as NullS.
  740. X
  741. X    Note: strxnmov is like strnmov in that it always moves EXACTLY len
  742. X    characters; dst will be padded on the right with NUL characters as
  743. X    needed.  strxncpy does the same.  strxncat, like strncat, does NOT.
  744. X*/
  745. X
  746. X#include "strings.h"
  747. X#include <varargs.h>
  748. X
  749. X/*VARARGS*/
  750. Xchar *strxnmov(va_alist)
  751. X    va_dcl
  752. X    {
  753. X    va_list pvar;
  754. X    register char *dst, *src;
  755. X    register int len;
  756. X
  757. X    va_start(pvar);
  758. X    dst = va_arg(pvar, char *);
  759. X    len = va_arg(pvar, int);
  760. X    src = va_arg(pvar, char *);
  761. X    while (src != NullS) {
  762. X        do if (--len < 0) return dst;
  763. X        while (*dst++ = *src++);
  764. X        dst--;
  765. X        src = va_arg(pvar, char *);
  766. X    }
  767. X    for (src = dst; --len >= 0; *dst++ = NUL) ;
  768. X    return src;
  769. X    }
  770. X
  771. SHAR_EOF
  772. sed 's/^X//' << 'SHAR_EOF' > substr.c
  773. X/*  File   : substr.c
  774. X    Author : Richard A. O'Keefe.
  775. X    Updated: 25 May 1984
  776. X    Defines: substr()
  777. X
  778. X    substr(destination, source, offset, length)
  779. X    copies length bytes from source+offset to destination, stopping
  780. X    early if a NUL is encountered.  The difference between this and
  781. X    strncpy(destination, source+offset, length)
  782. X    is that if the offset is negative, it has the same effect as 0,
  783. X    and if it exceeds strlen(source), it has the same effect as
  784. X    strlen(source).  If either of these boundaries is hit, or if
  785. X    a NUL is encountered before length bytes have been moved, the
  786. X    value of errno will be EDOM, otherwise it is guaranteed to be 0.
  787. X    That is:
  788. X    errno == 0 <=> (0 <= offset <= strlen(source)
  789. X            && 0 <= length && <= strlen(source)-offset)
  790. X    You may accept the sensible result produced when these boundary
  791. X    conditions are violated, or you may treat it as an error, as you
  792. X    will.  There is an algebra of sequences in which this treatment
  793. X    of boundary conditions makes sense.
  794. X
  795. X    After the substring of source is moved to destination, a NUL byte
  796. X    is moved to terminate the string, and the result is a pointer to
  797. X    this NUL byte, ready to have new stuff stuck on the end.
  798. X
  799. X    I suppose this should be called strsub, but I can't stick it.
  800. X*/
  801. X
  802. X#include "strings.h"
  803. X#include <errno.h>
  804. X
  805. Xextern    int    errno;            /* why isn't this in errno.h?? */
  806. X
  807. X
  808. Xchar *substr(dst, src, off, len)
  809. X    register char *dst, *src;
  810. X    register int off, len;
  811. X    {
  812. X    errno = off < 0 || len < 0 ? EDOM : 0;
  813. X
  814. X    while (--off >= 0)
  815. X        if (!*src++) {        /* We've hit the end */
  816. X        errno = EDOM;        /* report boundary violation */
  817. X        *dst = NUL;        /* return empty string */
  818. X        return dst;
  819. X        }
  820. X    while (--len >= 0)
  821. X        if (!(*dst++ = *src++)) {    /* We've hit the end */
  822. X        errno = EDOM;
  823. X        return dst-1;        /* dst is already terminated */
  824. X        }
  825. X    *dst = NUL;            /* terminate dst with NUL */
  826. X    return dst;
  827. X    }
  828. X
  829. SHAR_EOF
  830. sed 's/^X//' << 'SHAR_EOF' > xstring.3c
  831. X.TH XSTRING 3C local
  832. X.SH NAME
  833. Xstrxcat, strxncat, strxcpy, strxncpy, strxmov, strxnmov \- string operations with variable number of arguments
  834. X.SH SYNOPSIS
  835. X.nf
  836. X.PP
  837. X.B "#include <strings.h>"
  838. X.PP
  839. X.B "char \(**strxcat(dst, src1, src2, ..., NullS)"
  840. X.B "    char \(**dst, \(**src1, \(**src2, ...;"
  841. X.PP
  842. X.B "char \(**strxncat(dst, len, src1, src2, ..., NullS)"
  843. X.B "    char \(**dst, \(**src1, \(**src2, ...;"
  844. X.B "    int len;"
  845. X.PP
  846. X.B "char \(**strxcpy(dst, src1, src2, ..., NullS)"
  847. X.B "    char \(**dst, \(**src1, \(**src2, ...;"
  848. X.PP
  849. X.B "char \(**strxncpy(dst, len, src1, src2, ..., NullS)"
  850. X.B "    char \(**dst, \(**src1, \(**src2, ...;"
  851. X.B "    int len;"
  852. X.PP
  853. X.B "char \(**strxmov(dst, src1, src2, ..., NullS)"
  854. X.B "    char \(**dst, \(**src1, \(**src2, ...;"
  855. X.PP
  856. X.B "char \(**strxnmov(dst, len, src1, src2, ..., NullS)"
  857. X.B "    char \(**dst, \(**src1, \(**src2, ...;"
  858. X.B "    int len;"
  859. X.SH DESCRIPTION
  860. XThese functions operate on null-terminated strings.
  861. XThey are equivalent to the corresponding functions
  862. X.IR strcat (3c),
  863. X.IR strncat (3c),
  864. X.IR strmov (3c),
  865. X.IR strnmov (3c),
  866. X.IR strcpy (3c),
  867. Xand
  868. X.IR strncpy (3c),
  869. Xexcept that they allow more than one source string to be supplied.
  870. X.IR Strxcat ,
  871. X.IR strxncat ,
  872. X.IR strxcpy ,
  873. Xand
  874. X.I strxncpy
  875. Xreturn their first argument (the destination pointer).
  876. X.I Strxmov
  877. Xand
  878. X.I strxnmov
  879. Xreturn a pointer to just after the last non-NUL character
  880. Xmoved to the destination.  This is the same convention that
  881. Xis used throughout the strings package.
  882. XExcept as implied by the length parameter
  883. X.IR len ,
  884. Xthey do not check for overflow of any receiving string.
  885. X.PP
  886. X.I Strxcat
  887. Xappends a copy of the strings
  888. X.IR src1 ,
  889. X.IR src2 ,
  890. Xand so on, to
  891. X.IR dst .
  892. XThe resulting string will always be NUL-terminated.
  893. X.I Strxncat
  894. Xcopies at most
  895. X.I len
  896. Xcharacters.
  897. XThe resulting string will be NUL-terminated if fewer than
  898. X.I len
  899. Xcharacters were moved.  At most one NUL is added.
  900. X.PP
  901. X.I Strxcpy
  902. Xcopies the strings
  903. X.IR src1 ,
  904. X.IR src2 ,
  905. Xand so on, into
  906. X.IR dst .
  907. X.I Strxncpy
  908. Xcopies at most
  909. X.I len
  910. Xcharacters.
  911. XThe resulting string will not be null-terminated if
  912. X.I len
  913. Xor more characters were in the source strings.
  914. XBy analogy with
  915. X.IR strncpy ,
  916. X.I dst
  917. Xwill be padded on the right with NUL characters to exactly
  918. X.I len
  919. Xbytes.
  920. X.PP
  921. XApart from their return value,
  922. X.I strxmov
  923. Xand
  924. X.I strxnmov
  925. Xhave the same effect as
  926. X.I strxcpy
  927. Xand
  928. X.IR strxncpy .
  929. X.SH CAVEATS
  930. XThe placement for the
  931. X.I len
  932. Xvariable is different from the placement in the functions
  933. X.IR strncat (3c),
  934. X.IR strncpy (3c),
  935. Xand
  936. X.IR strnmov (3c).
  937. SHAR_EOF
  938. exit
  939.  
  940.  
  941.