home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacWT 0.9 / wt Mac Source / StringUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-10  |  12.3 KB  |  649 lines  |  [TEXT/CWIE]

  1. /*
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Collection of String Utilities for DTS Sample code
  5. **
  6. **    File:        StringUtils.c
  7. **
  8. **    Copyright © 1988-1993 Apple Computer, Inc.
  9. **    All rights reserved.
  10. */
  11.  
  12. /* You may incorporate this sample code into your applications without
  13. ** restriction, though the sample code has been provided "AS IS" and the
  14. ** responsibility for its operation is 100% yours.  However, what you are
  15. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  16. ** after having made changes. If you're going to re-distribute the source,
  17. ** we require that you make it clear in the source that the code was
  18. ** descended from Apple Sample Code, but that you've made changes. */
  19.  
  20. #ifndef __MEMORY__
  21. #include <Memory.h>
  22. #endif
  23.  
  24. #ifndef __STRINGUTILS__
  25. #include "StringUtils.h"
  26. #endif
  27.  
  28.  
  29.  
  30. /* These functions should be linked into whatever segment holds main().  This will
  31. ** guarantee that the functions will always be in memory when called.  It is important
  32. ** that they are in memory, because if a pointer is passed in that points into an
  33. ** unlocked handle, the mere fact that the code needs to get loaded may cause the
  34. ** handle that is pointed into to move.  If you stick to these string functions,
  35. ** you will not have to worry about the handle moving when the string function is
  36. ** called.  If you have your own string functions, and you wish the same safety
  37. ** factor, link the string handling code into the same segment as main(), as you
  38. ** do with these string functions. */
  39.  
  40. static short    gBase;
  41. static Boolean    gHandleChars;
  42.  
  43.  
  44.  
  45. /*****************************************************************************/
  46. /*****************************************************************************/
  47. /*****************************************************************************/
  48.  
  49.  
  50.  
  51. /* Return the length of the c-string.  (Same as strlen, but this function isn't
  52. ** part of the string library.  The entire library may be more than you wish to
  53. ** link into the code segment that holds main, so this (and other) standard
  54. ** library function has been duplicated here. */
  55.  
  56. short    clen(char *cptr)
  57. {
  58.     short    i;
  59.  
  60.     for (i = 0; cptr[i]; ++i) {};
  61.     return(i);
  62. }
  63.  
  64.  
  65.  
  66. /*****************************************************************************/
  67.  
  68.  
  69.  
  70. /* Catenate two c-strings. */
  71.  
  72. char    *ccat(char *s1, char *s2)
  73. {
  74.     ccpy(s1 + clen(s1), s2);
  75.     return(s1);
  76. }
  77.  
  78.  
  79.  
  80. /*****************************************************************************/
  81.  
  82.  
  83.  
  84. /* Copy a c-string. */
  85.  
  86. char    *ccpy(char *s1, char *s2)
  87. {
  88.     char    *c1, *c2;
  89.  
  90.     c1 = s1;
  91.     c2 = s2;
  92.     while ((*c1++ = *c2++) != 0) {};
  93.     return(s1);
  94. }
  95.  
  96.  
  97.  
  98. /*****************************************************************************/
  99.  
  100.  
  101.  
  102. /* Compare two pascal-strings. */
  103.  
  104. short    pcmp(StringPtr s1, StringPtr s2)
  105. {
  106.     short    i, len;
  107.     char    j;
  108.  
  109.     if ((len = s1[0]) > s2[0]) len = s2[0];
  110.  
  111.     for (i = 1; i <= len; ++i) {
  112.         j = s1[i] - s2[i];
  113.         if (j) return(j);
  114.     }
  115.  
  116.     return(s1[0] - s2[0]);
  117. }
  118.  
  119.  
  120.  
  121. /*****************************************************************************/
  122.  
  123.  
  124.  
  125. /* Catenate two pascal-strings. */
  126.  
  127. void    pcat(StringPtr d, StringPtr s)
  128. {
  129.     short    i, j;
  130.  
  131.     if (((j = s[0]) + d[0]) > 255)
  132.         j = 255 - d[0];
  133.             /* Limit dest string to 255. */
  134.  
  135.     for (i = 0; i < j;) d[++d[0]] = s[++i];
  136. }
  137.  
  138.  
  139.  
  140. /*****************************************************************************/
  141.  
  142.  
  143.  
  144. /* Copy a pascal-string. */
  145.  
  146. void    pcpy(StringPtr d, StringPtr s)
  147. {
  148.     short    i;
  149.  
  150.     i = *s;
  151.     do {
  152.         d[i] = s[i];
  153.     } while (i--);
  154. }
  155.  
  156.  
  157.  
  158. /*****************************************************************************/
  159.  
  160.  
  161.  
  162. /* Convert a c-string to a pascal-string. */
  163.  
  164. void    c2p(char *cptr)
  165. {
  166.     char    len;
  167.  
  168.     BlockMove(cptr, cptr + 1, len = clen(cptr));
  169.     *cptr = len;
  170. }
  171.  
  172.  
  173.  
  174. /*****************************************************************************/
  175.  
  176.  
  177.  
  178. /* Convert a pascal-string to a c-string. */
  179.  
  180. void    p2c(StringPtr cptr)
  181. {
  182.     unsigned char    len;
  183.  
  184.     BlockMove(cptr + 1, cptr, len = *cptr);
  185.     cptr[len] = 0;
  186. }
  187.  
  188.  
  189.  
  190. /*****************************************************************************/
  191. /*****************************************************************************/
  192. /*****************************************************************************/
  193.  
  194.  
  195.  
  196. /* Catenate a single character multiple times onto the designated string. */
  197.  
  198. void    ccatchr(char *cptr, char c, short count)
  199. {
  200.     ccpychr(cptr + clen(cptr), c, count);
  201. }
  202.  
  203.  
  204.  
  205. /*****************************************************************************/
  206.  
  207.  
  208.  
  209. /* Convert the value into text for the base-10 number and catenate it to
  210. ** the designated string.  The value is assumed to be signed.  If you wish
  211. ** to have an unsigned decimal value, call ccatnum with a base of 10. */
  212.  
  213. void    ccatdec(char *cptr, long v)
  214. {
  215.     ccatnum(cptr + clen(cptr), v, -10);        /* Catenate value base 10, signed. */
  216. }
  217.  
  218.  
  219.  
  220. /*****************************************************************************/
  221.  
  222.  
  223.  
  224. /* Convert the value into text for base-16, format it, and catenate it to the
  225. ** designated string.  ccatnum could be used, since it handles multiple bases,
  226. ** but ccathex allows for additional common formatting and padding of the
  227. ** hex value. */
  228.  
  229. void    ccathex(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  230. {
  231.     char    str[33], *sptr;
  232.     short    len;
  233.  
  234.     cptr += clen(cptr);            /* We're appending, so point to the end of the string. */
  235.     ccpynum(str, v, 16);        /* Generate minimum-digit hex value. */
  236.  
  237.     if ((len = clen(sptr = str)) > maxApnd)
  238.         sptr = str + len - maxApnd;
  239.  
  240.     if ((len = clen(sptr)) < minApnd)
  241.         if (padChr)
  242.             ccatchr(cptr, padChr, (minApnd - len));
  243.                 /* if we have a pad character, and if necessary, pad the string. */
  244.  
  245.     ccat(cptr, sptr);            /* Add the hex digits to the string. */
  246. }
  247.  
  248.  
  249.  
  250. /*****************************************************************************/
  251.  
  252.  
  253.  
  254. /* Convert the value into text for the designated base.  Catenate the text to
  255. ** the designated string. */
  256.  
  257. void    ccatnum(char *cptr, long v, short base)
  258. {
  259.     ccpynum(cptr + clen(cptr), v, base);
  260. }
  261.  
  262.  
  263.  
  264. /*****************************************************************************/
  265.  
  266.  
  267.  
  268. void    ccpychr(char *cptr, char c, short count)
  269. {
  270.     for (;count--; ++cptr) *cptr = c;
  271.     *cptr = 0;
  272. }
  273.  
  274.  
  275.  
  276. /*****************************************************************************/
  277.  
  278.  
  279.  
  280. void    ccpydec(char *cptr, long v)
  281. {
  282.     ccpynum(cptr, v, -10);
  283. }
  284.  
  285.  
  286.  
  287. /*****************************************************************************/
  288.  
  289.  
  290.  
  291. void    ccpyhex(char *cptr, char padChr, short minApnd, short maxApnd, long v)
  292. {
  293.     cptr[0] = 0;
  294.     ccathex(cptr, padChr, minApnd, maxApnd, v);
  295. }
  296.  
  297.  
  298.  
  299. /*****************************************************************************/
  300.  
  301.  
  302.  
  303. void    ccpynum(char *cptr, long v, short base)
  304. {
  305.     pcpynum((StringPtr)cptr, v, base);
  306.     p2c((StringPtr)cptr);
  307. }
  308.  
  309.  
  310.  
  311. /*****************************************************************************/
  312. /*****************************************************************************/
  313. /*****************************************************************************/
  314.  
  315.  
  316.  
  317. long    c2dec(char *cptr, short *charsUsed)
  318. {
  319.     return(c2num(cptr, 10, charsUsed));
  320. }
  321.  
  322.  
  323.  
  324. /*****************************************************************************/
  325.  
  326.  
  327.  
  328. long    c2hex(char *cptr, short *charsUsed)
  329. {
  330.     return(c2num(cptr, 16, charsUsed));
  331. }
  332.  
  333.  
  334.  
  335. /*****************************************************************************/
  336.  
  337.  
  338.  
  339. long    c2num(char *cptr, short base, short *charsUsed)
  340. {
  341.     Boolean    firstDigit;
  342.     short    i, sgn;
  343.     short    c;
  344.     long    val;
  345.  
  346.     sgn = 1;
  347.     for (firstDigit = false, val = 0, i = 0;;) {
  348.         c = cptr[i++];
  349.         if (base == 256) {
  350.             if (!c) break;
  351.             if (c == '\'') {
  352.                 ++i;
  353.                 break;
  354.             }
  355.             val *= base;
  356.             val += c;
  357.             continue;
  358.         }
  359.         if (c == '-') {
  360.             if (firstDigit) break;
  361.             if (sgn == -1)  break;
  362.             sgn = -1;
  363.             continue;
  364.         }
  365.         if (c == '$') {
  366.             if (firstDigit) break;
  367.             base = 16;
  368.             continue;
  369.         }
  370.         if (gHandleChars) {
  371.             if (c == '\'') {
  372.                 if (firstDigit) break;
  373.                 base = 256;
  374.                 continue;
  375.             }
  376.         }
  377.         if ((!firstDigit) && (c == ' ')) continue;
  378.         c -= '0';
  379.         if (c > 16) c -= 7;        /* Make 'A' a 10, etc. */
  380.         if (c > 32) c -= 32;    /* Make lower-case upper-case. */
  381.         if (c < 0) break;
  382.         if (c >= base) break;
  383.         val *= base;
  384.         val += (c * sgn);
  385.         firstDigit = true;
  386.     }
  387.  
  388.     if (charsUsed) *charsUsed = --i;
  389.  
  390.     gBase = base;
  391.     return(val);
  392. }
  393.  
  394.  
  395.  
  396. /*****************************************************************************/
  397.  
  398.  
  399.  
  400. short    GetLastBase(Boolean handleChars)
  401. {
  402.     gHandleChars = handleChars;
  403.     return(gBase);
  404. }
  405.  
  406.  
  407.  
  408. /*****************************************************************************/
  409. /*****************************************************************************/
  410. /*****************************************************************************/
  411.  
  412.  
  413.  
  414. /* Catenate a single character multiple times onto the designated string. */
  415.  
  416. void    pcatchr(StringPtr pptr, char c, short count)
  417. {
  418.     while (count--) pptr[++(pptr[0])] = c;
  419. }
  420.  
  421.  
  422.  
  423. /*****************************************************************************/
  424.  
  425.  
  426.  
  427. void    pcatdec(StringPtr pptr, long v)
  428. {
  429.     pcatnum(pptr, v, -10);
  430. }
  431.  
  432.  
  433.  
  434. /*****************************************************************************/
  435.  
  436.  
  437.  
  438. void    pcathex(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  439. {
  440.     char    str[33];
  441.  
  442.     ccpyhex(str, padChr, minApnd, maxApnd, v);
  443.     c2p(str);
  444.     pcat(pptr, (StringPtr)str);
  445. }
  446.  
  447.  
  448.  
  449. /*****************************************************************************/
  450.  
  451.  
  452.  
  453. long    pcatnum(StringPtr pptr, long v, short base)
  454. {
  455.     unsigned long    j, vv;
  456.  
  457.     vv = v;
  458.     if (base < 0) {
  459.         base = -base;
  460.         if (v < 0) {
  461.             pptr[++*pptr] = '-';
  462.             vv = -vv;
  463.         }
  464.     }
  465.     j = 0;
  466.     if (vv >= base)
  467.         j = pcatnum(pptr, vv / base, base);
  468.  
  469.     pptr[++*pptr] = "0123456789ABCDEF"[vv - j];
  470.     return(base * vv);
  471. }
  472.  
  473.  
  474.  
  475. /*****************************************************************************/
  476.  
  477.  
  478.  
  479. void    pcpychr(StringPtr pptr, char c, short count)
  480. {
  481.     pptr[0] = 0;
  482.     pcatchr(pptr, c, count);
  483. }
  484.  
  485.  
  486.  
  487. /*****************************************************************************/
  488.  
  489.  
  490.  
  491. void    pcpydec(StringPtr pptr, long v)
  492. {
  493.     *pptr = 0;
  494.     pcatdec(pptr, v);
  495. }
  496.  
  497.  
  498.  
  499. /*****************************************************************************/
  500.  
  501.  
  502.  
  503. void    pcpynum(StringPtr pptr, long v, short base)
  504. {
  505.     *pptr = 0;
  506.     pcatnum(pptr, v, base);
  507. }
  508.  
  509.  
  510.  
  511. /*****************************************************************************/
  512.  
  513.  
  514.  
  515. void    pcpyhex(StringPtr pptr, char padChr, short minApnd, short maxApnd, long v)
  516. {
  517.     *pptr = 0;
  518.     pcathex(pptr, padChr, minApnd, maxApnd, v);
  519. }
  520.  
  521.  
  522.  
  523. /*****************************************************************************/
  524.  
  525.  
  526.  
  527. long    p2dec(StringPtr pptr, short *charsUsed)
  528. {
  529.     return(p2num(pptr, 10, charsUsed));
  530. }
  531.  
  532.  
  533.  
  534. /*****************************************************************************/
  535.  
  536.  
  537.  
  538. long    p2hex(StringPtr pptr, short *charsUsed)
  539. {
  540.     return(p2num(pptr, 16, charsUsed));
  541. }
  542.  
  543.  
  544.  
  545. /*****************************************************************************/
  546.  
  547.  
  548.  
  549. long    p2num(StringPtr pptr, short base, short *charsUsed)
  550. {
  551.     long    val;
  552.  
  553.     p2c(pptr);
  554.     val = c2num((char *)pptr, base, charsUsed);
  555.     c2p((char *)pptr);
  556.     return(val);
  557. }
  558.  
  559.  
  560.  
  561. /*****************************************************************************/
  562. /*****************************************************************************/
  563. /*****************************************************************************/
  564.  
  565.  
  566.  
  567. short    GetHexByte(char *cptr)
  568. {
  569.     short    val, i, chr;
  570.  
  571.     for (val = 0, i = 0; i < 2; ++i) {
  572.         chr = cptr[i];
  573.         if (chr == '=') return(cptr[++i]);
  574.         if (chr == '≈') {
  575.             chr = cptr[++i];
  576.             if ((chr >= 'a') && (chr <= 'z')) chr -= 32;
  577.             return(chr);
  578.         }
  579.         if (chr > 'F')
  580.             chr -= 0x20;
  581.         if (chr > '9')
  582.             chr -= ('A' - '9' - 1);
  583.         val = (val << 4) + chr - '0';
  584.     }
  585.     return(val);
  586. }
  587.  
  588.  
  589.  
  590. /*****************************************************************************/
  591.  
  592.  
  593.  
  594. Boolean    EqualHandle(void *h1, void *h2)
  595. {
  596.     long    s1, s2;
  597.     Ptr        p1, p2;
  598.  
  599.     if ((h1) && (!h2)) return(false);
  600.     if ((h2) && (!h1)) return(false);
  601.     if ((s1 = GetHandleSize((Handle)h1)) != (s2 = GetHandleSize((Handle)h2))) return(false);
  602.  
  603.     p1 = *(Handle)h1;
  604.     p2 = *(Handle)h2;
  605.     for (s1 = 0; s1 < s2; ++s1)
  606.         if (p1[s1] != p2[s1]) return(false);
  607.         
  608.     return(true);
  609. }
  610.  
  611.  
  612.  
  613. /*****************************************************************************/
  614.  
  615.  
  616.  
  617. Boolean    EqualData(void *v1, void *v2, long size)
  618. {
  619.     Ptr        p1, p2;
  620.     long    ii;
  621.  
  622.     if ((v1) && (!v2)) return(false);
  623.     if ((v2) && (!v1)) return(false);
  624.  
  625.     p1 = (Ptr)v1;
  626.     p2 = (Ptr)v2;
  627.     for (ii = 0; ii < size; ++ii)
  628.         if (p1[ii] != p2[ii]) return(false);
  629.         
  630.     return(true);
  631. }
  632.  
  633.  
  634.  
  635. /*****************************************************************************/
  636.  
  637.  
  638.  
  639. void    SetMem(void *vptr, unsigned char c, unsigned long len)
  640. {
  641.     Ptr    ptr;
  642.  
  643.     ptr = (Ptr)vptr;
  644.     while (len--) *ptr++ = c;
  645. }
  646.  
  647.  
  648.  
  649.