1035 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1035 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* i4addtag.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifndef S4UNIX
 | 
						|
   #ifdef __TURBOC__
 | 
						|
      #pragma hdrstop
 | 
						|
   #endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4CLIENT
 | 
						|
#ifndef S4INDEX_OFF
 | 
						|
 | 
						|
#ifndef S4OFF_WRITE
 | 
						|
 | 
						|
#ifdef S4NDX
 | 
						|
int i4getLastKey( TAG4FILE *t4, char *keyData, long forBlock )
 | 
						|
{
 | 
						|
   int rc = 0 ;
 | 
						|
   B4BLOCK *tempBlock ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( forBlock <= 0 || t4 == 0 || keyData == 0 )
 | 
						|
         return error4( 0, e4parm, E95401 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   /* must get block forBlock, then find the last key */
 | 
						|
   tempBlock = b4alloc( t4, forBlock ) ;
 | 
						|
   if ( tempBlock == 0 )
 | 
						|
      return -1 ;
 | 
						|
 | 
						|
   if ( file4readAll( &t4->file, I4MULTIPLY * forBlock, &tempBlock->nKeys, B4BLOCK_SIZE ) < 0 )
 | 
						|
      return -1 ;
 | 
						|
 | 
						|
   b4goEof( tempBlock ) ;
 | 
						|
   if ( b4leaf( tempBlock ) )
 | 
						|
      rc = 2 ;
 | 
						|
   else
 | 
						|
      rc = b4getLastKey( tempBlock, keyData ) ;
 | 
						|
 | 
						|
   b4free( tempBlock ) ;
 | 
						|
 | 
						|
   return rc ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef N4OTHER
 | 
						|
 | 
						|
#ifdef S4FOX
 | 
						|
/* (temporary) fix for FoxPro multi-user compatibility
 | 
						|
   swaps parent and right blocks */
 | 
						|
#ifndef S4OFF_MULTI
 | 
						|
static long tfile4swap( B4BLOCK *parent, B4BLOCK *left )
 | 
						|
{
 | 
						|
   long tempFb ;
 | 
						|
   #ifdef S4BYTE_SWAP
 | 
						|
      S4LONG longVal ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   tempFb = left->fileBlock ;
 | 
						|
   left->fileBlock = parent->fileBlock ;
 | 
						|
   parent->fileBlock = tempFb ;
 | 
						|
 | 
						|
   /* now update neighbours */
 | 
						|
   if ( left->header.rightNode != -1 )
 | 
						|
   {
 | 
						|
      #ifdef S4BYTE_SWAP
 | 
						|
         longVal = x4reverseLong( (void *)&left->fileBlock ) ;
 | 
						|
         file4write( &parent->tag->indexFile->file, left->header.rightNode + 2*sizeof(short),
 | 
						|
                     &longVal, sizeof( left->header.leftNode ) ) ;
 | 
						|
      #else
 | 
						|
         file4write( &parent->tag->indexFile->file, left->header.rightNode + 2*sizeof(short),
 | 
						|
                     &left->fileBlock, sizeof( left->header.leftNode ) ) ;
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   if ( left->header.leftNode != -1 )
 | 
						|
   {
 | 
						|
      #ifdef S4BYTE_SWAP
 | 
						|
         longVal = x4reverseLong( (void *)&left->fileBlock ) ;
 | 
						|
         file4write( &parent->tag->indexFile->file, left->header.leftNode + 2*sizeof(short),
 | 
						|
                     &longVal, sizeof( left->header.rightNode ) ) ;
 | 
						|
      #else
 | 
						|
         file4write( &parent->tag->indexFile->file, left->header.leftNode + 2*sizeof(short),
 | 
						|
                     &left->fileBlock, sizeof( left->header.rightNode ) ) ;
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   if ( parent->header.rightNode != -1 )
 | 
						|
   {
 | 
						|
      #ifdef S4BYTE_SWAP
 | 
						|
         longVal = x4reverseLong( (void *)&parent->fileBlock ) ;
 | 
						|
         file4write( &parent->tag->indexFile->file, parent->header.rightNode + 2*sizeof(short),
 | 
						|
                     &longVal, sizeof( parent->header.leftNode ) ) ;
 | 
						|
      #else
 | 
						|
         file4write( &parent->tag->indexFile->file, parent->header.rightNode + 2*sizeof(short),
 | 
						|
                     &parent->fileBlock, sizeof( parent->header.leftNode ) ) ;
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   if ( parent->header.leftNode != -1 )
 | 
						|
   {
 | 
						|
      #ifdef S4BYTE_SWAP
 | 
						|
         longVal = x4reverseLong( (void *)&parent->fileBlock ) ;
 | 
						|
         file4write( &parent->tag->indexFile->file, parent->header.leftNode + 2*sizeof(short),
 | 
						|
                     &longVal, sizeof( parent->header.rightNode ) ) ;
 | 
						|
      #else
 | 
						|
         file4write( &parent->tag->indexFile->file, parent->header.leftNode + 2*sizeof(short),
 | 
						|
                     &parent->fileBlock, sizeof( parent->header.rightNode ) ) ;
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   return left->fileBlock ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
/* errUnique must be 0 if the tag is not unique, otherwise must contain unique error */
 | 
						|
static int tfile4addDo( TAG4FILE *t4, const unsigned char *keyInfo, const long recIn, short int errUnique )
 | 
						|
{
 | 
						|
   CODE4 *c4 ;
 | 
						|
   INDEX4FILE *i4 ;
 | 
						|
   B4BLOCK *oldBlock, *rootBlock, *newBlock ;
 | 
						|
   int rc ;
 | 
						|
   long  oldFileBlock, extendBlock, rec ;
 | 
						|
   #ifdef S4FOX
 | 
						|
      int  keyOn, didAdd ;
 | 
						|
      long rec1 = 0L ;
 | 
						|
      long rec2 = 0L ;
 | 
						|
      const unsigned char *tempKey = 0 ;
 | 
						|
      int doInsert, updateReqd ;
 | 
						|
   #else
 | 
						|
      int isBranch ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   rec = recIn ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E95402 ) ;
 | 
						|
      if ( keyInfo == 0 || rec < 1 )
 | 
						|
         return error4( t4->codeBase, e4parm_null, E95402 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   c4 = t4->codeBase ;
 | 
						|
   i4 = t4->indexFile ;
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   #ifdef S4FOX
 | 
						|
      if ( t4->expr != 0 )
 | 
						|
         switch( errUnique )  /* ensure not a null add if r4/e4 candidate */
 | 
						|
         {
 | 
						|
            case r4candidate:
 | 
						|
               if ( expr4nullLow( t4->expr, 1 ) == 1 )
 | 
						|
                  return r4unique ;
 | 
						|
               break ;
 | 
						|
            case e4candidate:
 | 
						|
               if ( expr4nullLow( t4->expr, 1 ) == 1 )
 | 
						|
                  return error4describe( c4, e4unique, E95402, tfile4alias( t4 ), i4->file.name, 0 ) ;
 | 
						|
               break ;
 | 
						|
            default:
 | 
						|
               break ;
 | 
						|
         }
 | 
						|
 | 
						|
      rc = tfile4go( t4, keyInfo, rec, 1 ) ;
 | 
						|
   #else
 | 
						|
      rc = tfile4seek( t4, keyInfo, t4->header.keyLen ) ;
 | 
						|
   #endif
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( c4, rc, E95402 ) ;
 | 
						|
 | 
						|
   #ifdef S4FOX
 | 
						|
      if ( rc == 0 )
 | 
						|
      {
 | 
						|
         switch( errUnique )
 | 
						|
         {
 | 
						|
            case e4unique:
 | 
						|
            case e4candidate:
 | 
						|
               return error4describe( c4, e4unique, E95402, tfile4alias( t4 ), i4->file.name, 0 ) ;
 | 
						|
            case r4candidate :
 | 
						|
               return r4unique ;
 | 
						|
            default:
 | 
						|
               break ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
      if ( errUnique && rc == r4found )
 | 
						|
   #else
 | 
						|
      if ( errUnique && rc == 0 )
 | 
						|
   #endif
 | 
						|
      {
 | 
						|
         switch ( errUnique )
 | 
						|
         {
 | 
						|
            #ifdef S4FOX
 | 
						|
               case e4candidate:
 | 
						|
            #endif
 | 
						|
            case e4unique:
 | 
						|
               return error4describe( c4, e4unique, E95402, tfile4alias( t4 ), i4->file.name, 0 ) ;
 | 
						|
            #ifdef S4FOX
 | 
						|
               case r4candidate:
 | 
						|
            #endif
 | 
						|
            case r4unique:
 | 
						|
               return r4unique ;
 | 
						|
            case r4uniqueContinue:
 | 
						|
               return r4uniqueContinue ;
 | 
						|
            default:
 | 
						|
               break ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
   if ( t4->filter && !t4->hasKeys )
 | 
						|
   {
 | 
						|
      file4write(&t4->indexFile->file, t4->headerOffset+sizeof(t4->header)+222, (char *) "\0", (int) 1 ) ;
 | 
						|
      t4->hasKeys = (char)1 ;
 | 
						|
      #ifdef S4MDX
 | 
						|
         t4->hadKeys = (char)0 ;
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   oldBlock = tfile4block( t4 ) ;
 | 
						|
   oldFileBlock = 0 ;
 | 
						|
 | 
						|
   #ifdef S4FOX
 | 
						|
      doInsert = 1 ;
 | 
						|
      updateReqd = 0 ;
 | 
						|
      didAdd = 1 ;
 | 
						|
 | 
						|
      for( ;; )
 | 
						|
      {
 | 
						|
         if ( doInsert == 1 )
 | 
						|
         {
 | 
						|
            i4->tagIndex->header.version = i4->versionOld + 1 ;
 | 
						|
            if ( oldBlock == 0 )
 | 
						|
            {
 | 
						|
               /* Must create a new root block */
 | 
						|
               extendBlock = index4extend( i4 ) ;
 | 
						|
               if ( extendBlock < 0 )
 | 
						|
                  return (int)extendBlock ;
 | 
						|
 | 
						|
               rootBlock = b4alloc( t4, extendBlock) ;
 | 
						|
               if ( rootBlock == 0 )
 | 
						|
                  return -1 ;
 | 
						|
 | 
						|
               rootBlock->header.leftNode = -1 ;
 | 
						|
               rootBlock->header.rightNode = -1 ;
 | 
						|
               rootBlock->header.nodeAttribute = 1 ;
 | 
						|
 | 
						|
               l4add( &t4->blocks, rootBlock ) ;
 | 
						|
 | 
						|
               #ifndef S4OFF_MULTI
 | 
						|
                  if ( t4->indexFile->file.lowAccessMode != OPEN4DENY_RW )
 | 
						|
                  {
 | 
						|
                     oldFileBlock = tfile4swap( rootBlock, (B4BLOCK *)l4last( &t4->saved ) ) ;
 | 
						|
                     if ( oldFileBlock < 0 )
 | 
						|
                        return -1 ;
 | 
						|
                  }
 | 
						|
 | 
						|
               #endif
 | 
						|
 | 
						|
               b4top( rootBlock ) ;
 | 
						|
               b4insert( rootBlock, tempKey, rec, rec2, 1 ) ;
 | 
						|
               b4insert( rootBlock, keyInfo, oldFileBlock, rec1, 1 ) ;
 | 
						|
               t4->header.root = rootBlock->fileBlock ;
 | 
						|
               t4->rootWrite = 1 ;
 | 
						|
               if ( didAdd == 0 )
 | 
						|
                  return 1 ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
 | 
						|
            if ( (rc = b4insert( oldBlock, keyInfo, rec, rec1, 0 )) != 1 )
 | 
						|
            {
 | 
						|
               if ( rc == 0 )
 | 
						|
               {
 | 
						|
                  if ( b4leaf( oldBlock ) )
 | 
						|
                  {
 | 
						|
                     tempKey = keyInfo ;
 | 
						|
                     rec2 = rec ;
 | 
						|
                  }
 | 
						|
                  if ( oldBlock->keyOn == oldBlock->header.nKeys - 1 )
 | 
						|
                     updateReqd = 1 ;
 | 
						|
                  doInsert = 0 ;
 | 
						|
                  continue ;
 | 
						|
               }
 | 
						|
               else
 | 
						|
                  return rc ;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
               l4pop( &t4->blocks ) ;
 | 
						|
               keyOn = oldBlock->keyOn ;
 | 
						|
 | 
						|
               /* The new block's end key gets added to the block just up */
 | 
						|
               newBlock= tfile4split( t4, oldBlock ) ;
 | 
						|
               if ( newBlock == 0 )
 | 
						|
                  return -1 ;
 | 
						|
 | 
						|
               l4add( &t4->saved, oldBlock ) ;
 | 
						|
 | 
						|
               if ( keyOn < oldBlock->header.nKeys )
 | 
						|
               {
 | 
						|
                  b4go( oldBlock, (long)keyOn ) ;
 | 
						|
                  rc = b4insert( oldBlock, keyInfo, rec, rec1, 0 ) ;
 | 
						|
               }
 | 
						|
               else
 | 
						|
               {
 | 
						|
                  b4go( newBlock, (long)(keyOn - oldBlock->header.nKeys) ) ;
 | 
						|
                  rc = b4insert( newBlock, keyInfo, rec, rec1, 0 ) ;
 | 
						|
                  if ( rc == 0 )  /* if there was room to insert and on the key, need to change the upper block entry */
 | 
						|
                     if ( newBlock->keyOn == newBlock->header.nKeys - 1 )
 | 
						|
                        updateReqd = 1 ;
 | 
						|
               }
 | 
						|
 | 
						|
               if ( rc == 1 )  /* was not possible to insert the key */
 | 
						|
                  didAdd = 0 ;
 | 
						|
 | 
						|
               #ifdef E4INDEX_VERIFY
 | 
						|
                  rc = b4verify( oldBlock ) ;
 | 
						|
                  if ( rc < 0 )
 | 
						|
                     return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
                  rc = b4verify( newBlock ) ;
 | 
						|
                  if ( rc < 0 )
 | 
						|
                     return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
               #endif
 | 
						|
 | 
						|
               /* Now add to the block just up */
 | 
						|
               b4goEof( oldBlock ) ;
 | 
						|
               oldBlock->keyOn-- ;
 | 
						|
 | 
						|
               keyInfo = b4keyKey( oldBlock, oldBlock->keyOn ) ;
 | 
						|
               oldFileBlock = oldBlock->fileBlock ;
 | 
						|
               rec1 = b4recNo( oldBlock, oldBlock->keyOn ) ;
 | 
						|
 | 
						|
               rec = newBlock->fileBlock ;
 | 
						|
               rc = b4flush(newBlock) ;
 | 
						|
               if ( rc < 0 )
 | 
						|
                  return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
 | 
						|
               b4goEof( newBlock ) ;
 | 
						|
               newBlock->keyOn-- ;
 | 
						|
 | 
						|
               tempKey = (unsigned char *)c4->savedKey ;
 | 
						|
               memcpy( (void *)tempKey, (void *)b4keyKey( newBlock, newBlock->keyOn ), (unsigned int)t4->header.keyLen ) ;
 | 
						|
               rec2 = b4recNo( newBlock, newBlock->keyOn ) ;
 | 
						|
               if( newBlock->keyOn == newBlock->header.nKeys - 1 )
 | 
						|
                  updateReqd = 1 ;
 | 
						|
               b4free( newBlock ) ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         else
 | 
						|
            l4add( &t4->saved, l4pop( &t4->blocks ) ) ;
 | 
						|
 | 
						|
         oldBlock = (B4BLOCK *)t4->blocks.lastNode ;
 | 
						|
 | 
						|
         if ( oldBlock == 0 )
 | 
						|
         {
 | 
						|
            if ( doInsert == 0 )
 | 
						|
            {
 | 
						|
               if ( didAdd == 0 )
 | 
						|
                  return 1 ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         else
 | 
						|
            if ( updateReqd )  /* may have to update a parent block */
 | 
						|
            {
 | 
						|
               if ( b4brReplace( oldBlock, tempKey, rec2 ) < 0 )
 | 
						|
                  return -1 ;
 | 
						|
               if ( oldBlock->keyOn != oldBlock->header.nKeys - 1 )  /* done reqd updates */
 | 
						|
                  updateReqd = 0 ;
 | 
						|
            }
 | 
						|
      }
 | 
						|
   #else              /* if not S4FOX  */
 | 
						|
      i4->changed = 1 ;
 | 
						|
      t4->changed = 1 ;
 | 
						|
      t4->header.version++ ;
 | 
						|
 | 
						|
      for(;;)
 | 
						|
      {
 | 
						|
         if ( oldBlock == 0 )
 | 
						|
         {
 | 
						|
            /* Must create a new root block */
 | 
						|
            extendBlock = index4extend(i4) ;
 | 
						|
            if ( extendBlock < 0 )
 | 
						|
               return (int) extendBlock ;
 | 
						|
 | 
						|
            rootBlock = b4alloc( t4, extendBlock) ;
 | 
						|
            if ( rootBlock == 0 )
 | 
						|
               return -1 ;
 | 
						|
 | 
						|
            l4add( &t4->blocks, rootBlock ) ;
 | 
						|
 | 
						|
            b4insert( rootBlock, keyInfo, oldFileBlock ) ;
 | 
						|
            b4insert( rootBlock, keyInfo, rec ) ;
 | 
						|
            rootBlock->nKeys-- ;
 | 
						|
            t4->header.root = rootBlock->fileBlock ;
 | 
						|
            t4->rootWrite  = 1 ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
         if ( oldBlock->nKeys < oldBlock->tag->header.keysMax )
 | 
						|
         {
 | 
						|
            b4insert( oldBlock, keyInfo, rec ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
 | 
						|
         l4pop( &t4->blocks ) ;
 | 
						|
 | 
						|
         isBranch  = b4leaf( oldBlock )  ?  0 : 1 ;
 | 
						|
 | 
						|
         /* NNNNOOOO  N - New, O - Old */
 | 
						|
         /* The new block's end key gets added to the block just up */
 | 
						|
         newBlock= tfile4split( t4, oldBlock ) ;
 | 
						|
         if ( newBlock == 0 )
 | 
						|
            return -1 ;
 | 
						|
 | 
						|
         l4add( &t4->saved, newBlock ) ;
 | 
						|
 | 
						|
         newBlock->nKeys -= (short)isBranch ;
 | 
						|
         if ( newBlock->keyOn < (newBlock->nKeys+isBranch) )
 | 
						|
            b4insert( newBlock, keyInfo, rec ) ;
 | 
						|
         else
 | 
						|
            b4insert( oldBlock, keyInfo, rec ) ;
 | 
						|
 | 
						|
         #ifdef E4INDEX_VERIFY
 | 
						|
            rc = b4verify( oldBlock ) ;
 | 
						|
            if ( rc < 0 )
 | 
						|
               return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
            rc = b4verify( newBlock ) ;
 | 
						|
            if ( rc < 0 )
 | 
						|
               return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         /* Now add to the block just up */
 | 
						|
         newBlock->keyOn = b4lastpos(newBlock) ;
 | 
						|
 | 
						|
         keyInfo = b4keyKey( newBlock, newBlock->keyOn ) ;
 | 
						|
         rec = newBlock->fileBlock ;
 | 
						|
 | 
						|
         oldFileBlock = oldBlock->fileBlock ;
 | 
						|
         if ( b4flush(oldBlock) < 0 )
 | 
						|
            return -1 ;
 | 
						|
 | 
						|
         b4free( oldBlock ) ;
 | 
						|
         oldBlock = (B4BLOCK *) t4->blocks.lastNode ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
}
 | 
						|
 | 
						|
int tfile4add( TAG4FILE *t4, const unsigned char *keyInfo, const long recIn, short int errUnique )
 | 
						|
{
 | 
						|
   #ifdef S4FOX
 | 
						|
      int rc ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4FOX
 | 
						|
      /* in fox case the tfile4add might not actually add the key */
 | 
						|
      for( ;; )
 | 
						|
      {
 | 
						|
         rc = tfile4addDo( t4, keyInfo, recIn, errUnique ) ;
 | 
						|
         if ( rc != 1 )
 | 
						|
            return rc ;
 | 
						|
      }
 | 
						|
   #else
 | 
						|
      return tfile4addDo( t4, keyInfo, recIn, errUnique ) ;
 | 
						|
   #endif
 | 
						|
}
 | 
						|
 | 
						|
int t4addCalc( TAG4 *t4, long rec )
 | 
						|
{
 | 
						|
   int len ;
 | 
						|
   unsigned char *ptr ;
 | 
						|
   TAG4FILE *tfile ;
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      TAG4KEY_REMOVED *removed ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 || rec < 1 )
 | 
						|
         return error4( 0, e4parm, E95403 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   tfile = t4->tagFile ;
 | 
						|
 | 
						|
   if ( error4code( tfile->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   if ( tfile->filter )
 | 
						|
      if ( !expr4true( tfile->filter ) )
 | 
						|
         return 0;
 | 
						|
 | 
						|
   len = tfile4exprKey( tfile, (unsigned char **)&ptr ) ;
 | 
						|
   if ( len < 0 )
 | 
						|
      return error4stack( tfile->codeBase, len, E95403 ) ;
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( len != tfile->header.keyLen )
 | 
						|
         return error4describe( tfile->codeBase, e4index, E95403, tfile4alias( tfile ), 0, 0 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      if ( code4tranStatus( tfile->codeBase ) == r4active && ( t4unique( t4 ) == r4unique ||
 | 
						|
           t4unique( t4 ) == e4unique
 | 
						|
           #ifdef S4FOX
 | 
						|
              || t4unique( t4 ) == r4candidate
 | 
						|
           #endif
 | 
						|
           ) )  /* just remove from the removed list */
 | 
						|
      {
 | 
						|
         removed = t4keyFind( t4, rec,(char *)ptr ) ;
 | 
						|
         /* if found it means it is already there, so just remove from list */
 | 
						|
         if ( removed != 0 )
 | 
						|
         {
 | 
						|
            l4remove( &t4->removedKeys, removed ) ;
 | 
						|
            u4free( removed ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
         removed = t4keyFind( t4, 0L, (char *)ptr ) ;
 | 
						|
         if ( removed != 0 )
 | 
						|
         {
 | 
						|
            if ( tfile4remove( tfile, removed->key, removed->recno ) < 0 )
 | 
						|
               return -1 ;
 | 
						|
            l4remove( &t4->removedKeys, removed ) ;
 | 
						|
            u4free( removed ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
   return tfile4add( tfile, (unsigned char *)ptr, rec, t4unique( t4 ) ) ;
 | 
						|
}
 | 
						|
 | 
						|
#endif  /*  ifndef N4OTHER  */
 | 
						|
 | 
						|
 | 
						|
#ifdef N4OTHER
 | 
						|
 | 
						|
#ifdef S4NDX
 | 
						|
int tfile4add( TAG4FILE *t4, unsigned char *keyInfo, long rec, short int errUnique )
 | 
						|
{
 | 
						|
   CODE4 *c4 ;
 | 
						|
   INDEX4 *i4 ;
 | 
						|
   B4BLOCK *oldBlock, *rootBlock, *newBlock, *wchBlock ;
 | 
						|
   int rc, isBranch ;
 | 
						|
   long  oldFileBlock, extendBlock ;
 | 
						|
   char keyData[I4MAX_KEY_SIZE+1] ;    /* temporary storage for the key data (max size 100) */
 | 
						|
   char key2data[I4MAX_KEY_SIZE+1] ;
 | 
						|
   B4KEY_DATA *atNew ;
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E95402 ) ;
 | 
						|
      if ( keyInfo == 0 || rec < 1 )
 | 
						|
         return error4( t4->codeBase, e4parm_null, E95402 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   c4 = t4->codeBase ;
 | 
						|
   i4 = t4->index ;
 | 
						|
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   rc = tfile4go( t4, (char *)keyInfo, rec, 1 ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( c4, rc, E95402 ) ;
 | 
						|
 | 
						|
   if ( rc == 0 && t4unique( t4 ) == e4unique )
 | 
						|
      return error4describe( c4, e4unique, E95402, tfile4alias( t4 ), i4->file.name, 0 ) ;
 | 
						|
 | 
						|
   if ( rc == r4found || rc == 0 )
 | 
						|
   {
 | 
						|
      switch ( t4unique( t4 ) )
 | 
						|
      {
 | 
						|
         case e4unique:
 | 
						|
            return error4describe( c4, e4unique, E95402, tfile4alias( t4 ), i4->file.name, 0 ) ;
 | 
						|
         case r4unique:
 | 
						|
            return r4unique ;
 | 
						|
         case r4uniqueContinue:
 | 
						|
            return r4uniqueContinue ;
 | 
						|
         default:
 | 
						|
            break ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   oldBlock = tfile4block( t4 ) ;
 | 
						|
   oldFileBlock = 0 ;
 | 
						|
 | 
						|
   t4->header.version = t4->header.oldVersion + 1 ;
 | 
						|
 | 
						|
   for(;;)
 | 
						|
   {
 | 
						|
      if ( oldBlock == 0 )
 | 
						|
      {
 | 
						|
         /* Must create a new root block */
 | 
						|
         extendBlock = tfile4extend( t4 ) ;
 | 
						|
         if ( extendBlock < 0 )
 | 
						|
            return (int)extendBlock ;
 | 
						|
 | 
						|
         rootBlock = b4alloc( t4, extendBlock ) ;
 | 
						|
         if ( rootBlock == 0 )
 | 
						|
            return -1 ;
 | 
						|
 | 
						|
         l4add( &t4->blocks, rootBlock ) ;
 | 
						|
 | 
						|
         i4getLastKey( t4, keyData, oldFileBlock ) ;
 | 
						|
 | 
						|
         b4insert( rootBlock, keyData, 0L, oldFileBlock ) ;
 | 
						|
         b4append( rootBlock, rec ) ;
 | 
						|
         t4->header.root = rootBlock->fileBlock ;
 | 
						|
         t4->rootWrite  = 1 ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( b4room( oldBlock ) )
 | 
						|
      {
 | 
						|
         if ( b4leaf( oldBlock ) )
 | 
						|
            b4insert( oldBlock, keyInfo, rec, 0L ) ;
 | 
						|
         else
 | 
						|
         {
 | 
						|
            b4getLastKey( oldBlock, keyData ) ;
 | 
						|
            if ( oldBlock->keyOn >= oldBlock->nKeys  )  /*insert at end done different */
 | 
						|
            {
 | 
						|
               b4insert( oldBlock, keyData, 0L, oldFileBlock ) ;
 | 
						|
               b4append( oldBlock, rec ) ;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
               atNew = b4key( oldBlock, oldBlock->keyOn ) ;
 | 
						|
               atNew->pointer = rec ;
 | 
						|
               b4insert( oldBlock, keyData, 0L, oldFileBlock ) ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      l4pop( &t4->blocks ) ;
 | 
						|
      isBranch  = b4leaf( oldBlock )  ?  0 : 1 ;
 | 
						|
 | 
						|
      /* NNNNOOOO  N - New, O - Old */
 | 
						|
      /* The new block's end key gets added to the block just up */
 | 
						|
      newBlock= tfile4split( t4, oldBlock ) ;
 | 
						|
      if ( newBlock == 0 )
 | 
						|
         return -1 ;
 | 
						|
 | 
						|
      l4add( &t4->saved, newBlock ) ;
 | 
						|
 | 
						|
      /* which block should do the insertion ? */
 | 
						|
      if ( oldBlock->keyOn < (oldBlock->nKeys + isBranch) )
 | 
						|
         wchBlock = oldBlock ;
 | 
						|
      else wchBlock = newBlock ;
 | 
						|
 | 
						|
      if ( b4leaf( wchBlock ) )
 | 
						|
         b4insert( wchBlock, keyInfo, rec, 0L ) ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         b4getLastKey( wchBlock, keyData ) ;
 | 
						|
         if ( wchBlock->keyOn >= wchBlock->nKeys )  /* insert at end done different */
 | 
						|
         {
 | 
						|
            b4insert( wchBlock, keyData, 0L, oldFileBlock ) ;
 | 
						|
            b4append( wchBlock, rec ) ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
               atNew = b4key( wchBlock, wchBlock->keyOn ) ;
 | 
						|
               atNew->pointer = rec ;
 | 
						|
               b4insert( wchBlock, keyData, 0L, oldFileBlock ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
      #ifdef E4INDEX_VERIFY
 | 
						|
         rc = b4verify( oldBlock ) ;
 | 
						|
         if ( rc < 0 )
 | 
						|
            return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
         rc = b4verify( newBlock ) ;
 | 
						|
         if ( rc < 0 )
 | 
						|
            return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      /* Now add to the block just up */
 | 
						|
      newBlock->keyOn = b4lastpos(newBlock) ;
 | 
						|
 | 
						|
      keyInfo = b4keyKey( newBlock, newBlock->keyOn ) ;
 | 
						|
      rec = newBlock->fileBlock ;
 | 
						|
 | 
						|
      if( !b4leaf( newBlock ) )
 | 
						|
         if ( b4getLastKey( newBlock, key2data ) != 4)
 | 
						|
            keyInfo = (unsigned char *)key2data ;
 | 
						|
 | 
						|
      oldBlock->keyOn = b4lastpos( oldBlock ) ;
 | 
						|
      memcpy( keyData, b4keyKey( oldBlock, oldBlock->keyOn ), t4->header.keyLen ) ;
 | 
						|
 | 
						|
      oldFileBlock = oldBlock->fileBlock ;
 | 
						|
      if ( b4flush( oldBlock ) < 0 )
 | 
						|
         return -1 ;
 | 
						|
      b4free( oldBlock ) ;
 | 
						|
      oldBlock = (B4BLOCK *) t4->blocks.lastNode ;
 | 
						|
   }
 | 
						|
}
 | 
						|
#else
 | 
						|
#ifdef S4CLIPPER
 | 
						|
int tfile4add( TAG4FILE *t4, unsigned char *keyInfo, const long recNum, short int errUnique )
 | 
						|
{
 | 
						|
   CODE4 *c4 ;
 | 
						|
   B4BLOCK *oldBlock, *rootBlock, *newBlock, *wchBlock ;
 | 
						|
   int rc ;
 | 
						|
   long  oldFileBlock, extendBlock, newFileBlock, rec ;
 | 
						|
   B4KEY_DATA *atNew ;
 | 
						|
   unsigned char oldKeyPtr[ I4MAX_KEY_SIZE ] ;
 | 
						|
   unsigned char keyData[I4MAX_KEY_SIZE+1] ;    /* temporary storage for the key data (max size 100) */
 | 
						|
   unsigned short int oldDesc ;
 | 
						|
   #ifndef S4OFF_MULTI
 | 
						|
      int dSet, incPos ;
 | 
						|
      #ifdef E4ANALYZE_ALL
 | 
						|
         long findVal ;
 | 
						|
         int trc ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E95402 ) ;
 | 
						|
      if ( keyInfo == 0 || recNum < 1 )
 | 
						|
         return error4( t4->codeBase, e4parm_null, E95402 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   rec = recNum ;
 | 
						|
   c4 = t4->codeBase ;
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   oldDesc = t4->header.descending ;
 | 
						|
   tfile4descending( t4, 0 ) ;
 | 
						|
 | 
						|
   rc = tfile4seek( t4, (char *)keyInfo, t4->header.keyLen ) ;
 | 
						|
 | 
						|
   #ifndef S4OFF_MULTI
 | 
						|
      /* for run-time multi-user compatibility with Clipper, must perform
 | 
						|
         the insertion at the end of the list of keys.  This is slower than
 | 
						|
         CodeBase's insertion at the beginning (i.e. S4OFF_MULTI is defined) */
 | 
						|
      if ( rc == 0 && errUnique == 0 )
 | 
						|
      {
 | 
						|
         for( dSet = 0, incPos = t4->header.keyLen - 1 ; dSet == 0 && incPos >=0 ; incPos-- )
 | 
						|
            if ( keyInfo[incPos] != 0xFF )
 | 
						|
            {
 | 
						|
               keyInfo[incPos]++ ;
 | 
						|
               dSet = 1 ;
 | 
						|
               if ( tfile4seek( t4, (char *)keyInfo, t4->header.keyLen ) < 0 )
 | 
						|
                  return -1 ;
 | 
						|
               keyInfo[incPos]-- ;
 | 
						|
               #ifdef E4ANALYZE_ALL
 | 
						|
                  findVal = tfile4recNo( t4 ) ;
 | 
						|
               #endif
 | 
						|
            }
 | 
						|
         #ifdef E4ANALYZE_ALL
 | 
						|
            rc = tfile4seek( t4, (char *)keyInfo, t4->header.keyLen ) ;
 | 
						|
            if ( rc != 0 || errUnique != 0 )
 | 
						|
               findVal = -2L ;
 | 
						|
            for(;;)
 | 
						|
            {
 | 
						|
               if ( (*t4->cmp)( tfile4keyData( t4 )->value, keyInfo, t4->header.keyLen ) == 0 )
 | 
						|
               {
 | 
						|
                  trc = tfile4skip( t4, 1L ) ;
 | 
						|
                  if ( trc == 0L )
 | 
						|
                  {
 | 
						|
                     b4goEof( tfile4block( t4 ) ) ;
 | 
						|
                     break ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
               else
 | 
						|
                  break ;
 | 
						|
            }
 | 
						|
            if ( tfile4recNo( t4 ) != findVal )
 | 
						|
               return error4( c4, e4index, E85402 ) ;
 | 
						|
         #endif
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   tfile4descending( t4, oldDesc ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( c4, rc, E95402 ) ;
 | 
						|
 | 
						|
   if ( rc == 0 )
 | 
						|
   {
 | 
						|
      switch ( errUnique )
 | 
						|
      {
 | 
						|
         case e4unique:
 | 
						|
            #ifdef N4OTHER
 | 
						|
               return error4describe( c4, e4unique, E95402, tfile4alias( t4 ), t4->file.name, 0 ) ;
 | 
						|
            #else
 | 
						|
               return error4describe( c4, e4unique, E95402, tfile4alias( t4 ), t4->indexFile->file.name, 0 ) ;
 | 
						|
            #endif
 | 
						|
         case r4unique:
 | 
						|
            return r4unique ;
 | 
						|
         case r4uniqueContinue:
 | 
						|
            return r4uniqueContinue ;
 | 
						|
         default:
 | 
						|
            break ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   oldBlock = tfile4block(t4) ;
 | 
						|
   oldFileBlock = 0 ;
 | 
						|
   newFileBlock = 0 ;
 | 
						|
 | 
						|
   t4->header.version = (short)(t4->header.oldVersion + 1L) ;
 | 
						|
 | 
						|
   while( !b4leaf( oldBlock ) )
 | 
						|
   {
 | 
						|
      rc = tfile4down( t4 ) ;
 | 
						|
      if ( rc < 0 || rc == 2 )
 | 
						|
         return -1 ;
 | 
						|
      oldBlock = tfile4block( t4 ) ;
 | 
						|
      if ( b4leaf( oldBlock ) )
 | 
						|
         oldBlock->keyOn = b4lastpos( oldBlock ) + 1 ;
 | 
						|
      else
 | 
						|
         oldBlock->keyOn = b4lastpos( oldBlock ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   for(;;)
 | 
						|
   {
 | 
						|
      if ( oldBlock == 0 )
 | 
						|
      {
 | 
						|
         /* Must create a new root block */
 | 
						|
         extendBlock = tfile4extend( t4 ) ;
 | 
						|
         if ( extendBlock < 0 )
 | 
						|
            return (int) extendBlock ;
 | 
						|
 | 
						|
         rootBlock = b4alloc( t4, extendBlock) ;
 | 
						|
         if ( rootBlock == 0 )
 | 
						|
            return -1 ;
 | 
						|
 | 
						|
         l4add( &t4->blocks, rootBlock ) ;
 | 
						|
 | 
						|
         /* need to set root first so that b4insert() will record that current
 | 
						|
            block is the root block, which is vital to its functioning */
 | 
						|
         t4->header.root = rootBlock->fileBlock * 512 ;
 | 
						|
         b4insert( rootBlock, keyInfo, rec, oldFileBlock ) ;
 | 
						|
         b4append( rootBlock, newFileBlock ) ;
 | 
						|
 | 
						|
         t4->rootWrite  = 1 ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( b4room( oldBlock ) )
 | 
						|
      {
 | 
						|
         if ( b4leaf( oldBlock ) )
 | 
						|
            b4insert( oldBlock, keyInfo, rec, 0L ) ;
 | 
						|
         else   /* update the current pointer, add the new branch */
 | 
						|
         {
 | 
						|
            #ifdef E4ANALYZE
 | 
						|
               if ( oldBlock->nKeys == 0 )
 | 
						|
                  return error4( t4->codeBase, e4index, E95402 ) ;
 | 
						|
            #endif
 | 
						|
               atNew = b4key( oldBlock, oldBlock->keyOn ) ;
 | 
						|
               atNew->pointer = newFileBlock * 512 ;
 | 
						|
               b4insert( oldBlock, keyInfo, rec, oldFileBlock ) ;
 | 
						|
         }
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      l4pop( &t4->blocks ) ;
 | 
						|
 | 
						|
      /* NNNNOOOO  N - New, O - Old */
 | 
						|
      /* The new block's end key gets added to the block just up */
 | 
						|
      if ( oldBlock->keyOn < (t4->header.keysHalf + ( b4leaf( oldBlock ) ? 0 : 1 ) ) )
 | 
						|
      {
 | 
						|
         newBlock= tfile4split( t4, oldBlock, 0 ) ;
 | 
						|
         if ( newBlock == 0 )
 | 
						|
            return -1 ;
 | 
						|
         wchBlock = oldBlock ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         newBlock= tfile4split( t4, oldBlock, 1 ) ;
 | 
						|
         if ( newBlock == 0 )
 | 
						|
            return -1 ;
 | 
						|
         wchBlock = newBlock ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( b4leaf( wchBlock ) )
 | 
						|
      {
 | 
						|
         b4insert( wchBlock, keyInfo, rec, 0L ) ;
 | 
						|
         if ( newBlock->nKeys <= t4->header.keysHalf )   /* add a key from the old block!, must have info in newBlock because oldBlock gets deleted below */
 | 
						|
         {
 | 
						|
            #ifdef E4ANALYZE
 | 
						|
               if ( oldBlock->nKeys <= t4->header.keysHalf )  /* impossible */
 | 
						|
                  #ifdef N4OTHER
 | 
						|
                     return error4describe( t4->codeBase, e4index, E81601, tfile4alias( t4 ), t4->file.name, 0 ) ;
 | 
						|
                  #else
 | 
						|
                     return error4describe( t4->codeBase, e4index, E81601, tfile4alias( t4 ), t4->indexFile->file.name, 0 ) ;
 | 
						|
                  #endif
 | 
						|
            #endif
 | 
						|
            oldBlock->keyOn = oldBlock->nKeys - 1 ;
 | 
						|
            memcpy( keyData, b4keyKey( oldBlock, oldBlock->keyOn ), t4->header.keyLen ) ;
 | 
						|
            keyInfo = keyData ;
 | 
						|
            rec = b4key( oldBlock, oldBlock->keyOn )->num ;
 | 
						|
            b4remove( oldBlock ) ;
 | 
						|
            newBlock->keyOn = 0 ;
 | 
						|
            b4insert( newBlock, keyInfo, rec, 0 ) ;
 | 
						|
         }
 | 
						|
         newBlock->keyOn = 0 ;
 | 
						|
         memcpy( keyData, b4keyKey( newBlock, newBlock->keyOn ), t4->header.keyLen ) ;
 | 
						|
         keyInfo = keyData ;
 | 
						|
         rec = b4key( newBlock, newBlock->keyOn )->num ;
 | 
						|
         b4remove( newBlock ) ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         /* now get the key to place upwards */
 | 
						|
         if ( wchBlock->nKeys == 0 )   /* treat like a root block */
 | 
						|
         {
 | 
						|
            if ( wchBlock == oldBlock )  /* not a problem if number of keys very small ?? */
 | 
						|
            {
 | 
						|
               if ( wchBlock->keyOn == 1 )   /* at end, so must combine with new block alterations */
 | 
						|
               {
 | 
						|
                  wchBlock->nKeys = 1 ;  /* now reset to the proper value */
 | 
						|
                  /* don't actually need to do an insert, just set the file block value */
 | 
						|
                  /* but need to copy values in so that later copy for data gives correct results */
 | 
						|
                  memcpy( b4keyKey( oldBlock, 1), keyData, t4->header.keyLen ) ;
 | 
						|
                  b4key( oldBlock, 1 )->num = rec ;
 | 
						|
                  atNew = b4key( oldBlock, 1 ) ;
 | 
						|
                  atNew->pointer = oldFileBlock * 512 ;
 | 
						|
                  atNew = b4key( newBlock, 0 ) ;  /* currently set to old value, reset to new */
 | 
						|
                  atNew->pointer = newFileBlock * 512 ;
 | 
						|
               }
 | 
						|
               else  /* simple insert */
 | 
						|
               {
 | 
						|
                  wchBlock->nKeys = 1 ;  /* to get a proper insert */
 | 
						|
                  b4insert( wchBlock, keyInfo, rec, oldFileBlock ) ;
 | 
						|
                  atNew = b4key( wchBlock, 1 ) ;
 | 
						|
                  atNew->pointer = newFileBlock * 512 ;
 | 
						|
                  memcpy( oldKeyPtr, b4keyKey( oldBlock, 1 ), t4->header.keyLen ) ;
 | 
						|
                  keyInfo = oldKeyPtr ;
 | 
						|
                  rec = b4key( oldBlock, 1 )->num ;
 | 
						|
                  wchBlock->nKeys = 1 ;  /* now reset to the proper value */
 | 
						|
               }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
               b4insert( wchBlock, keyInfo, rec, oldFileBlock ) ;
 | 
						|
               b4append( wchBlock, newFileBlock ) ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            if ( wchBlock->keyOn > wchBlock->nKeys && wchBlock == oldBlock )
 | 
						|
            {
 | 
						|
               atNew = b4key( newBlock, 0 ) ;
 | 
						|
               atNew->pointer = newFileBlock * 512 ;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
               atNew = b4key( wchBlock, wchBlock->keyOn ) ;
 | 
						|
               atNew->pointer = newFileBlock * 512 ;
 | 
						|
            }
 | 
						|
            b4insert( wchBlock, keyInfo, rec, oldFileBlock ) ;
 | 
						|
         }
 | 
						|
         memcpy( oldKeyPtr, b4keyKey( oldBlock, b4lastpos( oldBlock )), t4->header.keyLen ) ;
 | 
						|
         keyInfo = oldKeyPtr ;
 | 
						|
         rec = b4key( oldBlock, b4lastpos( oldBlock ) )->num ;
 | 
						|
      }
 | 
						|
 | 
						|
      #ifdef E4INDEX_VERIFY
 | 
						|
         rc = b4verify( oldBlock ) ;
 | 
						|
         if ( rc < 0 )
 | 
						|
            return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
         rc = b4verify( newBlock ) ;
 | 
						|
         if ( rc < 0 )
 | 
						|
            return error4stack( t4->codeBase, rc, E91642 ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      l4add( &t4->saved, newBlock ) ;
 | 
						|
      newFileBlock = newBlock->fileBlock ;
 | 
						|
      oldFileBlock = oldBlock->fileBlock ;
 | 
						|
      if ( b4flush( oldBlock ) < 0 )
 | 
						|
         return -1 ;
 | 
						|
      b4free( oldBlock ) ;
 | 
						|
      oldBlock = (B4BLOCK *) t4->blocks.lastNode ;
 | 
						|
   }
 | 
						|
}
 | 
						|
#endif  /* ifdef S4CLIPPER   */
 | 
						|
#endif  /* ifdef S4NDX    */
 | 
						|
 | 
						|
int t4addCalc( TAG4 *t4, long rec )
 | 
						|
{
 | 
						|
   int rc ;
 | 
						|
   char *ptr ;
 | 
						|
   TAG4FILE *tfile ;
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      TAG4KEY_REMOVED *removed ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( t4 == 0 || rec < 1 )
 | 
						|
         return error4( 0, e4parm, E95403 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   tfile = t4->tagFile ;
 | 
						|
 | 
						|
   if ( error4code( tfile->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   #ifdef S4CLIPPER
 | 
						|
      if ( tfile->filter )
 | 
						|
         if ( !expr4true( tfile->filter ) )
 | 
						|
            return 0;
 | 
						|
   #endif
 | 
						|
 | 
						|
   rc = tfile4exprKey( tfile, (unsigned char **)&ptr ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return error4stack( tfile->codeBase, rc, E95403 ) ;
 | 
						|
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      if ( code4tranStatus( tfile->codeBase ) == r4active && ( t4unique( t4 ) == r4unique ||
 | 
						|
           t4unique( t4 ) == e4unique
 | 
						|
           #ifdef S4FOX
 | 
						|
              || t4unique( t4 ) == r4candidate
 | 
						|
           #endif
 | 
						|
           ) )  /* just remove from the removed list */
 | 
						|
      {
 | 
						|
         removed = t4keyFind( t4, 0L, ptr ) ;
 | 
						|
         if ( removed != 0 )
 | 
						|
         {
 | 
						|
            if ( tfile4remove( tfile, removed->key, removed->recno ) < 0 )
 | 
						|
               return -1 ;
 | 
						|
            l4remove( &t4->removedKeys, removed ) ;
 | 
						|
            u4free( removed ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
   return tfile4add( tfile, (unsigned char *)ptr, rec, t4unique( t4 ) ) ;
 | 
						|
}
 | 
						|
 | 
						|
#endif  /* ifdef N4OTHER */
 | 
						|
#endif  /* S4OFF_WRITE */
 | 
						|
#endif  /* S4INDEX_OFF */
 | 
						|
#endif
 |