File:  [Research Unix] / researchv10dc / cmd / icon / src / iconx / lscan.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:34 2018 UTC (8 years, 3 months ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Dan Cross

/*
 * File: lscan.c
 *  Contents: bscan, escan
 */

#include "../h/rt.h"

/*
 * bscan - set &subject and &pos upon entry to a scanning expression.
 *
 *  Arguments are:
 *	cargp[-2] - new value for &subject
 *	cargp[-1] - saved value of &subject
 *	cargp[0]  - saved value of &pos
 */

#define newsubj (cargp[-2])
#define savsubj (cargp[-1])
#define savpos	(cargp[0])

LibDcl(bscan,2,"?")
   {
   char sbuf[MaxCvtLen];
   extern char *alcstr();
   struct descrip tsubject;

   /*
    * Make a copy of the value for &subject and convert it to a string.
    */
   tsubject = newsubj;
   DeRef(tsubject);
   switch (cvstr(&tsubject, sbuf)) {
      case NULL:
	 runerr(103, &tsubject);

      case Cvt:
	 /*
	  * The new value for &subject wasn't a string.  Allocate the
	  *  new value and fall through.
	  */
	 strreq(StrLen(tsubject));
	 StrLoc(tsubject) = alcstr(StrLoc(tsubject), StrLen(tsubject));

      case NoCvt:
	 /*
	  * Establish a new &subject value and set &pos to 1.
	  */
	 k_subject = tsubject;
	 k_pos = 1;
      }
   Suspend;

   /*
    * bscan has been resumed. Restore the old &subject and &pos values
    *  and fail.
    */
   k_subject = savsubj;
   k_pos = IntVal(savpos);
   Fail;
   }


/*
 * escan - restore &subject and &pos at the end of a scanning expression.
 *
 *  Arguments:
 *    Arg0 - value being scanned
 *    Arg1 - old value of &subject
 *    Arg2 - old value of &pos
 *    Arg3 - result of the scanning expression
 *
 * The result of the scanning expression is dereferenced if it refers to &subject
 *  or &pos, then copied to the first argument (the last three will
 *  be popped when escan returns).  Then the previous values of &subject
 *  and &pos are restored.
 *
 * Escan suspends once it has restored the old &subject; on failure
 *  the new &subject and &pos are "unrestored", and the failure is
 *  propagated into the using clause.
 */

LibDcl(escan,3,"escan")
   {
   struct descrip tmp;

   /*
    * If the result of the scanning expression is &subject or &pos,
    *  it is dereferenced.
    */
   if (((word)BlkLoc(Arg3) == (word)&tvky_sub) || ((word)BlkLoc(Arg3) == (word)&tvky_pos))
      DeRef(Arg3);

   /*
    * Copy the result of the scanning expression into Arg0, which will
    *  be the result of the scan.
    */
   Arg0 = Arg3;

   /*
    * Swap new and old values of &subject, leaving the new value in Arg1.
    */
   tmp = k_subject;
   k_subject = Arg1;
   Arg1 = tmp;

   /*
    * Swap new and old values of &pos, leaving the new value in Arg2.
    */
   tmp = Arg2;
   IntVal(Arg2) = k_pos;
   k_pos = IntVal(tmp);

   /*
    * Suspend the value of the scanning expression.
    */
   Suspend;

   /*
    * Upon resumption, restore the new values for &subject and &pos
    *  and fail.
    */
   k_subject = Arg1;
   k_pos = IntVal(Arg2);

   Fail;
   }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.