home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / language / icon / Source / Iconx / C / Fxarm < prev    next >
Encoding:
Text File  |  1991-05-24  |  7.1 KB  |  385 lines

  1.  
  2. /*
  3.  * Prototypes.
  4.  */
  5.  
  6. hidden int expand_wildcard Params((dptr, dptr));
  7. extern char *dirscan Params((const char *));
  8.  
  9. #include "kernel.h"
  10. #include "swis.h"
  11.  
  12. /*
  13.  * Swi(swi,r0,r1,...)
  14.  */
  15. FncDclV(Swi)
  16.    {
  17.     unsigned int swi_num;
  18.     word nslots;
  19.     int i;
  20.     char sbuf[MaxCvtLen];
  21.  
  22.     struct b_list *hp;
  23.     struct b_lelem *bp;
  24.  
  25.     _kernel_swi_regs regs;
  26.  
  27.     if (nargs < 1)
  28.     RunErr(-101, NULL);
  29.  
  30. /*
  31.  * Get the SWI number from Arg1.
  32.  */
  33.     if (Qual(Arg1))
  34.     {
  35.     qtos(&Arg1,sbuf);
  36.  
  37.     regs.r[1] = (int)StrLoc(Arg1);
  38.     if (_kernel_swi(OS_SWINumberFromString,®s,®s) != NULL)
  39.         RunErr(-216, NULL);
  40.  
  41.     swi_num = regs.r[0];
  42.     }
  43.     else switch(Type(Arg1))
  44.     {
  45.     case T_Integer:
  46.         swi_num = (int)IntVal(Arg1);
  47.         break;
  48.     default:
  49.         RunErr(123,&Arg1);
  50.     }
  51.  
  52. /*
  53.  * Pick up the register values from the following arguments
  54.  */
  55.     for (i = 2; i <= nargs; ++i)
  56.     {
  57.     if (cvint(&Arg(i)) == CvtFail)
  58.         RunErr(101,&Arg(i));
  59.  
  60.     regs.r[i-2] = (int)IntVal(Arg(i));
  61.     }
  62.  
  63.     for (i = nargs-1; i < 10; ++i)
  64.     regs.r[i] = 0;
  65.  
  66.     if (_kernel_swi(swi_num,®s,®s) != NULL)
  67.        Fail;
  68.  
  69. /*
  70.  * Return the values.
  71.  */
  72.     nslots = Max(MinListSlots,10);
  73.     if (blkreq((word)sizeof(struct b_list) + sizeof(struct b_lelem) +
  74.     (nslots - 1) * sizeof(struct descrip)) == Error)
  75.     {
  76.     RunErr(0, NULL);
  77.     }
  78.  
  79.     hp = alclist((word)10);
  80.     bp = alclstb(nslots,(word)0,(word)10);
  81.     hp->listhead = hp->listtail = (union block *) bp;
  82.  
  83. /* returns [r0,r1,r2,r3,r4,r5,r6,r7,r8,r9] */
  84.  
  85.     MakeInt((uword)regs.r[0],&(bp->lslots[0]));
  86.     MakeInt((uword)regs.r[1],&(bp->lslots[1]));
  87.     MakeInt((uword)regs.r[2],&(bp->lslots[2]));
  88.     MakeInt((uword)regs.r[3],&(bp->lslots[3]));
  89.     MakeInt((uword)regs.r[4],&(bp->lslots[4]));
  90.     MakeInt((uword)regs.r[5],&(bp->lslots[5]));
  91.     MakeInt((uword)regs.r[6],&(bp->lslots[6]));
  92.     MakeInt((uword)regs.r[7],&(bp->lslots[7]));
  93.     MakeInt((uword)regs.r[8],&(bp->lslots[8]));
  94.     MakeInt((uword)regs.r[9],&(bp->lslots[9]));
  95.  
  96.     ArgType(0) = D_List;
  97.     Arg(0).vword.bptr = (union block *) hp;
  98.     Return;
  99.    }
  100.  
  101. /*
  102.  * peek(addr,len)
  103.  */
  104.  
  105. FncDcl(Peek,2)
  106. {
  107.    if (defshort(&Arg2,1) == Error) {
  108.        RunErr(0, NULL);
  109.    }
  110.  
  111.    switch (Type(Arg1)) {
  112.     case T_Integer:
  113.         StrLoc(Arg0) = (char *)(Arg1.vword.integr);
  114.         break;
  115.     default:
  116.         RunErr(101,&Arg1);
  117.    }
  118.  
  119.    switch (Type(Arg2)) {
  120.     case T_Integer:
  121.         StrLen(Arg0) = Arg2.vword.integr;
  122.         break;
  123.     default:
  124.         RunErr(101, &Arg2);
  125.    }
  126.  
  127.    Return;
  128. }
  129.  
  130. /*
  131.  * poke(addr,s)
  132.  */
  133.  
  134. FncDcl(Poke,2)
  135. {
  136.    register char *s1,*s2;
  137.    register word l;
  138.    char *addr;
  139.  
  140.    switch (Type(Arg1)) {
  141.     case T_Integer:
  142.         addr = (char *)(Arg1.vword.integr);
  143.         break;
  144.     default:
  145.         RunErr(101,&Arg1);
  146.    }
  147.  
  148.    if (!Qual(Arg2)) {
  149.       RunErr(103, &Arg2);
  150.    }
  151.  
  152.    l = StrLen(Arg2);
  153.    s1 = StrLoc(Arg2);
  154.    s2 = addr;
  155.  
  156.    memcopy(s2,s1,l);     /* Copy... */
  157.  
  158.    Return;
  159. }
  160.  
  161. /*
  162.  * Getspace(i)
  163.  */
  164.  
  165. FncDcl(GetSpace,1)
  166. {
  167.     char *addr;
  168.     uword u;
  169.     int size;
  170.  
  171.     if (cvint(&Arg1) == CvtFail) {
  172.     RunErr(101, &Arg1);
  173.     }
  174.  
  175.     size = (int)IntVal(Arg1);
  176.     addr = (char *)calloc(size,sizeof(char));
  177.     if (addr == NULL)
  178.     Fail;
  179.  
  180.     u = (uword)addr;
  181.     MakeInt(u,&Arg0);
  182.     Return;
  183. }
  184.  
  185. /*
  186.  * FreeSpace(a)
  187.  */
  188.  
  189. FncDcl(FreeSpace,1)
  190. {
  191.    uword u;
  192.    char *addr;
  193.  
  194.    switch (Type(Arg1)) {
  195.     case T_Integer:
  196.        u = Arg1.vword.integr;
  197.        break;
  198.     default:
  199.         RunErr(101, &Arg1);
  200.    }
  201.    addr = (char *)u;
  202.    free((pointer)addr);
  203.    Return;
  204. }
  205.  
  206. /*
  207.  * Wildcard(l)
  208.  */
  209.  
  210. FncDcl(Wildcard,1)
  211. {
  212.     word nslots;
  213.  
  214.     register struct b_list *hp;
  215.     register struct b_lelem *bp;
  216.     register dptr dp;
  217.     register union block *pb;
  218.     int i, j;
  219.  
  220.     /*
  221.      * Create an initially empty list. This list will be used to
  222.      * build the final result.
  223.      */
  224.     nslots = MinListSlots;
  225.  
  226.     if (blkreq((word)sizeof(struct b_list) + sizeof(struct b_lelem) +
  227.     (nslots - 1) * sizeof(struct descrip)) == Error)
  228.     {
  229.     RunErr(0, NULL);
  230.     }
  231.  
  232.     hp = alclist((word)0);
  233.     bp = alclstb(nslots,(word)0,(word)0);
  234.     hp->listhead = hp->listtail = (union block *) bp;
  235.  
  236.     /*
  237.      * Put the new empty list into Arg0, for safe keeping if a
  238.      * garbage collection occurs
  239.      */
  240.     ArgType(0) = D_List;
  241.     Arg(0).vword.bptr = (union block *) hp;
  242.  
  243.     /*
  244.      * Now, we are ready to start adding in the file names. If Arg1
  245.      * is a list, we must handle each element in turn. Otherwise,
  246.      * we convert Arg1 to a string, and handle it once. We use the
  247.      * auxiliary function expand_wildcard to expand each value in
  248.      * turn.
  249.      */
  250.     if (ArgType(1) == D_List)
  251.     {
  252.     pb = BlkLoc(Arg1);
  253.     for (pb = pb->list.listhead; pb != NULL; pb = pb->lelem.listnext)
  254.     {
  255.         for (i = 0; i < pb->lelem.nused; ++i)
  256.         {
  257.         j = pb->lelem.first + i;
  258.         if (j >= pb->lelem.nslots)
  259.             j -= pb->lelem.nslots;
  260.  
  261.         dp = &pb->lelem.lslots[j];
  262.         BlkLoc(Arg1) = pb;    /* save in Arg1 as pb is untended */
  263.  
  264.         if (expand_wildcard(&Arg0, dp) == Error)
  265.             RunErr(0, NULL);
  266.  
  267.         pb = BlkLoc(Arg1);    /* pb is untended, so must reset */
  268.         }
  269.     }
  270.     }
  271.     else
  272.     {
  273.     if (expand_wildcard(&Arg0, &Arg1) == Error)
  274.         RunErr(0, NULL);
  275.     }
  276.  
  277.     Return;
  278. }
  279.  
  280. hidden int expand_wildcard (arg, dp)
  281. dptr arg;
  282. dptr dp;
  283. {
  284.     register word i;
  285.     register struct b_list *hp;
  286.     register struct b_lelem *bp;
  287.  
  288.     int len;
  289.     char *name;
  290.     char sbuf[MaxCvtLen];
  291.  
  292.     /*
  293.      * Convert the filename pattern to a string
  294.      */
  295.     switch (cvstr(dp,sbuf))
  296.     {
  297.     case Cvt:
  298.         break;        /* Already null-terminated */
  299.  
  300.     case NoCvt:
  301.         qtos(dp,sbuf);
  302.         break;
  303.  
  304.     default:
  305.         RetError(103, *dp);
  306.     }
  307.  
  308.     for (name = dirscan(StrLoc(*dp)); name; name = dirscan(0))
  309.     {
  310.     /*
  311.      * Request space for the new string now, to avoid the need
  312.      * for setting up hp and bp repeatedly later
  313.      */
  314.     len = strlen(name);
  315.     if (strreq(len) == Error)
  316.         return Error;
  317.  
  318.     /*
  319.      * Point hp at the list-header block and bp at the
  320.      * last list-element block.
  321.      */
  322.     hp = (struct b_list *) BlkLoc(*arg);
  323.     bp = (struct b_lelem *) hp->listtail;
  324.  
  325.     /*
  326.      * If the last list-element block is full, allocate a new
  327.      * list-element block, make it the last list-element block,
  328.      * and make it the next block of the former last list-element
  329.      * block.
  330.      */
  331.     if (bp->nused >= bp->nslots)
  332.     {
  333.         /*
  334.          * Set i to the size of block to allocate.
  335.          */
  336.         i = hp->size / 2;
  337.         if (i < MinListSlots)
  338.         i = MinListSlots;
  339.  
  340.         /*
  341.          * Ensure space for a new list element block.  If the block
  342.          * can't be allocated, try smaller blocks.
  343.          */
  344.         while (blkreq((word)sizeof(struct b_lelem) +
  345.             i * sizeof(struct descrip)) == Error)
  346.         {
  347.         i /= 4;
  348.         if (i < MinListSlots)
  349.             return Error;
  350.         }
  351.  
  352.         /*
  353.          * Reset hp in case there was a garbage collection.
  354.          */
  355.         hp = (struct b_list *) BlkLoc(*arg);
  356.  
  357.         bp = alclstb(i, (word)0, (word)0);
  358.         hp->listtail->lelem.listnext = (union block *) bp;
  359.         bp->listprev = hp->listtail;
  360.         hp->listtail = (union block *) bp;
  361.     }
  362.  
  363.     /*
  364.      * Set i to position of new last element
  365.      */
  366.     i = bp->first + bp->nused;
  367.     if (i >= bp->nslots)
  368.         i -= bp->nslots;
  369.  
  370.     /*
  371.      * Now create a new string descriptor, and add it to the list
  372.      */
  373.     StrLen(bp->lslots[i]) = len;
  374.     StrLoc(bp->lslots[i]) = alcstr(name, len);
  375.  
  376.     /*
  377.      * Adjust block usage count and current list size.
  378.      */
  379.     bp->nused++;
  380.     hp->size++;
  381.     }
  382.  
  383.     return Success;
  384. }
  385.