⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 varmgrc.c

📁 [随书类]Dos6.0源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
*              FVCONST, and FVSTATIC are to be set correctly; FVARRAY & 
*              FVINDEXED will frequently be correct, but may be changed 
*              based on other flags settings; FVVALUESTORED is to
*              be pathologically set to TRUE on input, while 
*              FVEVEREXPLICIT, and FVREDIRECT are to be set FALSE.
*  mkVar - global structure containing MakeVariable inputs for oNam,
*              oTyp, and a(nother) flags word.
*
*  NOTE: All variables are created on even-byte boundaries. This
*        guarantees, in turn, that the value fields of all variables will
*        start on even byte boundaries. We ensure this primarily by the
*        structure definitions in variable.h/.inc.  The primary reason for
*        this is that the shared runtime assumes (and requires) that all
*        string descriptors be on even byte boundaries.
*
*Exit:
*  return value is an error code; either zero is returned (no error),
*  or the same error code as is used by MakeVariable is returned (see
*  MakeVariable, below).
*
*  Also sets module static vm_oVarCur to the offset into mrsCur.bdVar
*  to the new entry, and vm_pVarCur to point to the entry.
*
*Exceptions:
*  none.
*
*******************************************************************************/
ushort NEAR CreateVar(oPVHash, varFlags)
ushort oPVHash;
ushort varFlags;
   {
   var *pVar;
   ushort inFlags = mkVar.flags;	     /* put MakeVariable callers flags
						word in a register	      */
   ushort cbValue = 0;
   ushort cbOTyp;
   ushort *pHash;
   uchar  nmsp_type;
   ushort temp;
   ushort entryFlags;			     /* [11] use this to build up
						[11] the flags word for entry */
   ushort oPrsRef;			     /* [11] 0 or oPrs for function
						[11] ref		      */

   /* if caller to MakeVariable really wanted just a search without modifying
      the variable table, return Internal Error code to indicate that the
      search failed                                                           */
   if (mkVar.flags2 & MV_fDontCreate)
      return (PRS_ER_RP | ER_IER);

   /* The following assertion is made because (if for no other reason ...)
      we assume that the user can still CONTinue if he asks to add a variable
      but we return ER_CN and he backs out of the edit                        */
   DbAssertIf(mkVar.flags & !(FVCOMMON | FVFNNAME | FVFUNCTION), 
                                          !(mkVar.flags2 & MV_fTrashTable))

   if ((mkVar.oTyp == UNDEFINED) && !(mkVar.flags & FVASCLAUSE))
                                    /* reference to a record prior to ...AS...*/
      return (PRS_ER_RP | MSG_BadElemRef); /* [9] */

   /* The following assertion is based on the fact that we're using
      grs.oRsCur in the case that we CAN continue to see if there's an active
      frame on the stack for the active procedure - if so, we return ER_CN    */
   DbAssertIf(oPVHash != UNDEFINED, 
               ((grs.oRsCur & 0x8000) && (prsCur.oVarHash == oPVHash)))
   if ((oPVHash != UNDEFINED) && 
       (grs.otxCONT != UNDEFINED) && 
       !(varFlags & (FVSTATIC | FVSHARED | FVCONST)))
      if (FindORsFrame())           /* TRUE if this proc has an active frame  */
	 return (0x8000 | ER_CN);   /* allow the user to back out of edit     */

   oPrsRef = 0; 		    /* [11] initialize			      */

   entryFlags = varFlags & ~0x07;

   if (inFlags & (FVFORCEARRAY | FVINDEXED))
      if (varFlags & FVFUN)
	 entryFlags |= FVINDEXED;
      else {
	 entryFlags |= (FVARRAY | FVINDEXED);
         /* set the dimension count; if input of zero, assume 1 - - - will end
            up giving Rude Edit later if this turns out to have been wrong    */
         if ((mkVar.cDimensions == 0) && !(inFlags & FVCOMMON))
            cbValue = sizeof(dm);
            /* NOTE: we if a dimension count wasn't specified on a COMMON
                     statement for an array, the execute scanner depends on
                     the cDims field in the variable entry being 0;
                     we depend on that for STATIC arrays, in StdSearch        */
         if ((inFlags & FVSTATIC) && (mkVar.cDimensions > 8))
            return (PRS_ER_RE | MSG_SubCnt); /* 'Wrong number of subscripts'  */
         }
   
   if (!(inFlags & FVIMPLICIT))           /* if pathological input was wrong  */
      entryFlags |= FVEVEREXPLICIT;
                                                      
   inFlags = entryFlags;      /* now use flags as passed BY MakeVariable      */

   /* initialize cbValue for static variable case, to save code later on      */
   cbValue += (inFlags & FVARRAY) ? (sizeof(aStat) + - sizeof(oneChar) +
				     sizeof(dm) * mkVar.cDimensions) :
				    (mkVar.oTyp == ET_FS ? mkVar.fsLength :
				     CbTyp(mkVar.oTyp));

   nmsp_type = NMSP_Variable; /* assume we're not creating a FUNCTION, or 
                                 DEF FN entry                                 */

   if (inFlags & 
      (FVFORMAL | FVCOMMON | FVSTATIC | FVFUNCTION | FVSHARED | FVCONST)) {
      if (inFlags & (FVFORMAL | FVCOMMON | FVFUNCTION)) {
         if (inFlags & FVCOMMON) {
	    entryFlags &= ~FVVALUESTORED;	   /* set that bit to FALSE   */
	    cbValue = (inFlags & FVARRAY ? sizeof(aCom) : sizeof(comRef));
            if (inFlags & FVSHARED)
               nm_mask |= NM_fShared;
            }
         else {                                    /* not COMMON -            */
	    cbValue = sizeof(ushort);
            if (inFlags & FVFUNCTION) {
               nmsp_type = 0;                      /* don't set any name table
                                                      bits                    */
               if ((oPVHash == UNDEFINED) && (mkVar.flags & FVFUNCTION))
                  nm_mask |= NM_fShared;           /* set tNam entry flag  */
               if (mkVar.flags & FVLVAL)           /* retval                  */
		  entryFlags &= ~FVVALUESTORED;    /* set to FALSE for retval */
	       else {
		  if ((oPrsRef =
                     PrsRef(mkVar.oNam,
                            (uchar)((mkVar.flags & FVFUNCTION) ? 
                                       PT_FUNCTION : PT_DEFFN),
			    mkVar.oTyp)) & 0x8000) /* [16] function not found */
                     return (PRS_ER_RP | ER_UF);   /* 'Undefined Function'    */
                  }
               }
            else {   /* FVFORMAL */
	       entryFlags &= ~FVVALUESTORED;	   /* set that bit to FALSE   */
               if (inFlags & FVARRAY)
		  cbValue = sizeof(aFormal);
               }  
            }  /* else - not COMMON */
         }  /* if FORMAL, COMMON, DEF FN, or FUNCTION */
      else                                         /* STATIC,SHARED, or CONST */
         if (inFlags & FVSHARED) {
            if (oPVHash == UNDEFINED)              /* entry going in the tMV  */
               nm_mask |= NM_fShared;
            else {   /* entry going in tPV */
	       entryFlags &= ~FVVALUESTORED;	   /* set to FALSE */
	       cbValue = sizeof(ushort);
               }
            }  /* if SHARED */
         else if (inFlags & FVCONST) {
            if (oPVHash == UNDEFINED)              /* entry going in the tMV  */
               nm_mask = NM_fShared;               /* Always set fShared bit
                                                      so constants are found  */
            }
      }  /* if special case flag is set */
   else {
      if ((grs.oPrsCur != UNDEFINED) && (prsCur.procType == PT_DEFFN))
         oPVHash = UNDEFINED;    /* var ref. belongs in the tMV for DEF's     */
      if ((oPVHash != UNDEFINED) && (!(prsCur.flags & FP_STATIC))) {
	 entryFlags &= ~FVVALUESTORED;	  /* actual value not stored in entry */
         if (inFlags & FVARRAY)
	    cbValue = sizeof(aFrame);
         else
	    cbValue = sizeof(ushort);		   /* size of a frame offset  */
         }
      }  /* no special case flag was set */
   cbValue = ((++cbValue) >> 1) << 1;              /* round up cbValue, to 
                                                      ensure even-byte vars. 
                                                      Note that this MUST be
                                                      done in case of odd-sized
                                                      user-defined types or 
						      fixed-length strings.   */
   cbOTyp = ((mkVar.oTyp > ET_MAX) || (mkVar.oTyp == ET_FS)) ?
		  sizeof(ushort) : 0;

   vm_oVarCur = mrsCur.bdVar.cbLogical + cbOTyp + VAR_STRUCT_SIZE;    /* [11] */

   /* [11] see if namespace ER_DD error BEFORE we try to grow the var table,
      [11] so we don't ask user if he wants to continue and THEN give error   */
   if (nmsp_type)				   /* don't set anything if
                                                      creating a DEF or FUN
                                                      entry (txtmgr does it)  */
      if (CheckONamSpace(mkVar.oNam, nmsp_type))
	 return (PRS_ER_RE | ER_DD);		   /* duplicate definition    */

   temp = cbValue + cbOTyp + VAR_STRUCT_SIZE;
   if (temp < cbValue)			/* [12] 64k wrap occurred	      */
      return (PRS_ER_RE | ER_OM);	/* [12] out of memory		      */
   if (temp = GrowBdVar(temp))
      return (temp);
   pVar = (var *)(mrsCur.bdVar.pb + vm_oVarCur); /* in case table moved    */
   ZeroFill((char *)pVar, cbValue);

   if (cbOTyp) {		      /* oTyp > ET_MAX */
      if (mkVar.oTyp == ET_FS) {
		  *((ushort *)((char *)pVar + VAR_cbFixed)) = mkVar.fsLength;
		  entryFlags |= mkVar.oTyp;
      }
      else
		  *((ushort *)((char *)pVar + VAR_oTyp)) = mkVar.oTyp;
      }
   else
      entryFlags |= mkVar.oTyp;
   
   ONamOf(pVar) = mkVar.oNam;			   /* [11]		      */
   FlagsOf(pVar) = entryFlags;			   /* [11] set entry flags    */
   ValueOf(pVar, oPrs) = oPrsRef;		   /* [11] oPrs or zero       */

   if (nmsp_type) {                                /* don't set anything if
                                                      creating a DEF or FUN
                                                      entry (txtmgr does it)  */
      if (SetONamSpace(mkVar.oNam, nmsp_type))
	 ;					   /* [11] CheckONamSpace will
						      [11] already have caught
						      [11] error, if any      */

      }

   mrsCur.oPastLastVar = mrsCur.bdVar.cbLogical;   /* can always trim table 
                                                      back to oPastLastVar and
                                                      lose no variables       */
   vm_pVarCur = pVar;                              /* an exit value           */

   /* initialize the dim count if:
	the entry is an array AND it's NOT (shared AND in a procedure).
	(If an array is shared and in a procedure it doesn't have a cDims
	field in the var table entry.  The entry is a near pointer to the
	array descriptor defining the array.) */

   if ((FlagsOf(pVar) & FVARRAY) &&
      !((FlagsOf(pVar) & FVSHARED) && (oPVHash != UNDEFINED)))	//[17]
      ValueOf(pVar, aryStat.cDims) = mkVar.cDimensions;
                                                   /* this actually sets
                                                      cDims for all arrays    */

   /* now just have to link the new entry in */

   pHash = (ushort *)(mrsCur.bdVar.pb +
                        ((oPVHash == UNDEFINED) ? 
                              (mkVar.oNam & HASH_MV_NAMMASK) : 
                              (oPVHash + (mkVar.oNam & HASH_PV_NAMMASK))));
   if ((*pHash == 0) || (FlagsOf(pVar) & FVDECLDVAR)) {  
      /* link this entry into start of chain */
      OHashLinkOf(pVar) = *pHash;         /* old start of chain in new entry  */
      *pHash = vm_oVarCur;                /* save offset to new entry         */
      }
   else {   /* link this entry into end of chain */
      OHashLinkOf(pVar) = 0;              /* 0 (or 1) indicates end of chain;
                                             UNDEFINED doesn't do it because
                                             we store a flag in the low bit   */
   pVar = (var *)(mrsCur.bdVar.pb + *pHash);	   /* point to start of chain */
   while (OHashLinkOf(pVar) > 1)		   /* while not end of hash chain	   */
      pVar = (var *)(mrsCur.bdVar.pb + (OHashLinkOf(pVar) & 0xFFFE));
      OHashLinkOf(pVar) |= vm_oVarCur;    /* OR this in rather than assign it
                                             to preserve existing flag value  */
      DbAssert(!(vm_oVarCur & 1))         /* we depend on oVars being on even
                                             byte boundaries for this hashlink
                                             bit flag use, and for SD's       */
      }
   return (vm_fVarFound = FALSE);                  /* var created, not found;
                                                      retval says 'no errors' */
   }  /* CreateVar */


/*##############################################################################
#                                                                              #
#                        Variable Searching                                    #
#                                                                              #

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -