home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / language / icon / Source / Iconx / C / Ocat < prev    next >
Encoding:
Text File  |  1990-07-19  |  2.8 KB  |  122 lines

  1. /*
  2.  * File: ocat.c
  3.  *  Contents: cat, lconcat
  4.  */
  5.  
  6. #include "../h/config.h"
  7. #include "../h/rt.h"
  8. #include "rproto.h"
  9.  
  10.  
  11. /*
  12.  * x || y - concatenate strings x and y.
  13.  */
  14.  
  15. OpDcl(cater,2,"||")
  16.    {
  17.    char sbuf1[MaxCvtLen];    /* buffers for conversion to string */
  18.    char sbuf2[MaxCvtLen];
  19.  
  20.    /*
  21.     *  Convert arguments to strings if necessary.
  22.     */
  23.    if (cvstr(&Arg1, sbuf1) == CvtFail) 
  24.       RunErr(103, &Arg1);
  25.    if (cvstr(&Arg2, sbuf2) == CvtFail) 
  26.       RunErr(103, &Arg2);
  27.  
  28.    if (StrLoc(Arg1) + StrLen(Arg1) == strfree) {
  29.       /*
  30.        * The end of Arg1 is at the end of the string space.  Hence,
  31.        *  Arg1 was the last string allocated.  Arg1 is not copied.
  32.        *  Instead, Arg2 is appended to the string space and the
  33.        *  result is pointed to the start of Arg1.
  34.        *  Space is only needed for the string being appended
  35.        */
  36.       if (strreq(StrLen(Arg2)) == Error) 
  37.      RunErr(0, NULL);
  38.       StrLoc(Arg0) = StrLoc(Arg1);
  39.       }
  40.    else {
  41.       /*
  42.        * Ensure space for the resulting concatenated string
  43.        */
  44.       if (strreq(StrLen(Arg1) + StrLen(Arg2)) == Error) 
  45.      RunErr(0, NULL);
  46.       /*
  47.        * Otherwise, append Arg1 to the end of the string space and
  48.        *  point the result to the start of Arg1.
  49.        */
  50.       StrLoc(Arg0) = alcstr(StrLoc(Arg1),StrLen(Arg1));
  51.       }
  52.  
  53.    /*
  54.     * Append Arg2 to the end of the string space.
  55.     */
  56.    alcstr(StrLoc(Arg2),StrLen(Arg2));
  57.    /*
  58.     *  Set the length of the result and return.
  59.     */
  60.    StrLen(Arg0) = StrLen(Arg1) + StrLen(Arg2);
  61.    Return;
  62.    }
  63.  
  64. /*
  65.  * x ||| y - concatenate lists x and y.
  66.  */
  67.  
  68. OpDcl(lconcat,2,"|||")
  69.    {
  70.    register struct b_list *bp1, *bp2;
  71.    register struct b_lelem *lp1, *lp2;
  72.    word size1, size2;
  73.  
  74.    /*
  75.     * x and y must be lists.
  76.     */
  77.    if (Arg1.dword != D_List) 
  78.       RunErr(108, &Arg1);
  79.    if (Arg2.dword != D_List) 
  80.       RunErr(108, &Arg2);
  81.  
  82.    /*
  83.     * Get the size of both lists.
  84.     */
  85.    size1 = BlkLoc(Arg1)->list.size;
  86.    size2 = BlkLoc(Arg2)->list.size;
  87.  
  88.    /*
  89.     * Make a copy of both lists.
  90.     */
  91.    if (cplist(&Arg1, &Arg1, (word)1, size1 + 1) == Error) 
  92.       RunErr(0, NULL);
  93.    if (cplist(&Arg2, &Arg2, (word)1, size2 + 1) == Error) 
  94.       RunErr(0, NULL);
  95.  
  96.    /*
  97.     * Get a pointer to both lists.  bp1 points to the copy of Arg1 and is
  98.     *  the list that will be returned.
  99.     */
  100.    bp1 = (struct b_list *) BlkLoc(Arg1);
  101.    bp2 = (struct b_list *) BlkLoc(Arg2);
  102.  
  103.    /*
  104.     * Perform the concatenation by hooking the lists together.
  105.     */
  106.    lp1 = (struct b_lelem *) bp1->listtail;
  107.    lp2 = (struct b_lelem *) bp2->listhead;
  108.  
  109.    lp1->listnext = (union block *) lp2;
  110.  
  111.    lp2->listprev = (union block *) lp1;
  112.  
  113.    /*
  114.     * Adjust the size field to reflect the length of the concatenated lists.
  115.     */
  116.    bp1->size = size1 + size2;
  117.    bp1->listtail = bp2->listtail;
  118.  
  119.    Arg0 = Arg1;
  120.    Return;
  121.    }
  122.