1252 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1252 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* i4create.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifdef __TURBOC__
 | 
						|
   #pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef S4INDEX_OFF
 | 
						|
#ifndef S4OFF_WRITE
 | 
						|
 | 
						|
static INDEX4 *i4createLow( DATA4 *, const char *, const TAG4INFO * ) ;
 | 
						|
 | 
						|
INDEX4 *S4FUNCTION i4create( DATA4 *d4, const char *fileName, const TAG4INFO *tagData )
 | 
						|
{
 | 
						|
   INDEX4 *index ;
 | 
						|
 | 
						|
   #ifndef S4OFF_OPTIMIZE
 | 
						|
      #ifndef S4CLIENT
 | 
						|
         CODE4 *c4 ;
 | 
						|
         #ifdef S4LOW_MEMORY
 | 
						|
            int hasOpt ;
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4VBASIC
 | 
						|
      if ( c4parm_check( d4, 2, E95301 ) )
 | 
						|
         return 0 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( d4 == 0 || tagData == 0 )
 | 
						|
      {
 | 
						|
         error4( 0, e4parm_null, E95301 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifndef S4OFF_OPTIMIZE
 | 
						|
      #ifndef S4CLIENT
 | 
						|
         c4 = d4->codeBase ;
 | 
						|
         #ifdef S4LOW_MEMORY
 | 
						|
            if ( c4->hasOpt )
 | 
						|
            {
 | 
						|
               hasOpt = 1 ;
 | 
						|
               code4optSuspend( c4 ) ;
 | 
						|
            }
 | 
						|
            else
 | 
						|
               hasOpt = 0 ;
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   index = i4createLow( d4, fileName, tagData ) ;
 | 
						|
 | 
						|
   #ifndef S4CLIENT
 | 
						|
      #ifndef S4OFF_OPTIMIZE
 | 
						|
         #ifndef N4OTHER
 | 
						|
            if ( index != 0 )
 | 
						|
               file4optimizeLow( &index->indexFile->file, c4->optimize, OPT4INDEX, 0, index->indexFile ) ;
 | 
						|
         #endif
 | 
						|
         #ifdef S4LOW_MEMORY
 | 
						|
            if ( hasOpt )
 | 
						|
               code4optRestart( c4 ) ;
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   return index ;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef S4CLIENT
 | 
						|
static INDEX4 *i4createLow( DATA4 *d4, const char *fileName, const TAG4INFO *tagData )
 | 
						|
{
 | 
						|
   CONNECTION4 *connection ;
 | 
						|
   CONNECTION4INDEX_CREATE_INFO_IN dataIn ;
 | 
						|
   CONNECTION4INDEX_CREATE_INFO_OUT *dataOut ;
 | 
						|
   CONNECTION4TAG_INFO tinfo ;
 | 
						|
   unsigned int j, len, len2, len3, offset ;
 | 
						|
   TAG4 *tag ;
 | 
						|
   char ext[4] ;
 | 
						|
   TAG4 *tagPtr ;
 | 
						|
   INDEX4 *i4 ;
 | 
						|
   CODE4 *c4 ;
 | 
						|
   char buf[258] ;
 | 
						|
   int i, rc ;
 | 
						|
 | 
						|
   c4 = d4->codeBase ;
 | 
						|
 | 
						|
   if ( fileName != 0 )
 | 
						|
   {
 | 
						|
      if ( strlen( fileName ) == 0 )   /* empty name disallowed */
 | 
						|
      {
 | 
						|
         error4describe( c4, e4name, E81717, fileName, 0, 0 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      if ( dfile4index( d4->dataFile, fileName ) )
 | 
						|
      {
 | 
						|
         error4describe( c4, e4name, E81703, fileName, 0, 0 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( code4indexFormat( c4 ) == r4ntx )   /* disallow .ntx extensions */
 | 
						|
      {
 | 
						|
         u4nameRetExt( ext, 3, fileName ) ;
 | 
						|
         if ( memcmp( ext, "NTX", 3 ) == 0 )
 | 
						|
         {
 | 
						|
            ext[sizeof(ext)-1] = 0 ;
 | 
						|
            error4describe( c4, e4name, E81720, fileName, ext, 0 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   if ( d4->dataFile == 0 )
 | 
						|
      return 0 ;
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return 0 ;
 | 
						|
   error4set( c4, 0 ) ;  /* Make sure it is not 'r4unique' or 'r4noCreate'. */
 | 
						|
 | 
						|
   memset( &dataIn, 0, sizeof( CONNECTION4INDEX_CREATE_INFO_IN ) ) ;
 | 
						|
   connection = d4->dataFile->connection ;
 | 
						|
   if ( connection == 0 )
 | 
						|
   {
 | 
						|
      error4( c4, e4parm, E95301 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
   connection4assign( connection, CON4INDEX_CREATE, data4clientId( d4 ), data4serverId( d4 ) ) ;
 | 
						|
   for( i = 0 ; tagData[i].name != 0; i++ )
 | 
						|
      ;
 | 
						|
   if ( fileName == 0 )
 | 
						|
      dataIn.isProduction = 1 ;
 | 
						|
   else
 | 
						|
   {
 | 
						|
      u4ncpy( dataIn.indexFileName, fileName, LEN4PATH ) ;
 | 
						|
      c4upper( dataIn.indexFileName ) ;
 | 
						|
   }
 | 
						|
   dataIn.numTags = i ;
 | 
						|
   dataIn.safety = c4->safety ;
 | 
						|
   dataIn.readOnly = c4->readOnly ;  /* catalog purposes */
 | 
						|
   connection4addData( connection, &dataIn, sizeof(CONNECTION4INDEX_CREATE_INFO_IN), 0 ) ;
 | 
						|
   len = 0 ;
 | 
						|
   offset = sizeof( CONNECTION4INDEX_CREATE_INFO_IN ) ;
 | 
						|
   for ( j = 0 ; j != dataIn.numTags ; j++ )
 | 
						|
   {
 | 
						|
      len = strlen( tagData[j].name ) + 1 ;
 | 
						|
      offset += sizeof( CONNECTION4TAG_INFO ) ;
 | 
						|
      tinfo.name.offset = offset ;
 | 
						|
      len2 = strlen( tagData[j].expression ) + 1 ;
 | 
						|
      offset += len ;
 | 
						|
      tinfo.expression.offset = offset ;
 | 
						|
      offset += len2 ;
 | 
						|
      if ( tagData[j].filter == 0 )
 | 
						|
      {
 | 
						|
         len3 = 0 ;
 | 
						|
         tinfo.filter.offset = 0 ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
         len3 = strlen( tagData[j].filter ) + 1 ;
 | 
						|
         tinfo.filter.offset = offset ;
 | 
						|
      }
 | 
						|
      offset += len3 ;
 | 
						|
      tinfo.unique = tagData[j].unique ;
 | 
						|
      tinfo.descending = tagData[j].descending ;
 | 
						|
      connection4addData( connection, &tinfo, sizeof(CONNECTION4TAG_INFO), 1 ) ;
 | 
						|
      connection4addData( connection, tagData[j].name, len, 0 ) ;
 | 
						|
      connection4addData( connection, tagData[j].expression, len2, 0 ) ;
 | 
						|
      if ( len3 != 0 )
 | 
						|
         connection4addData( connection, tagData[j].filter, len3, 0 ) ;
 | 
						|
   }
 | 
						|
   connection4send( connection ) ;
 | 
						|
   rc = connection4receive( connection ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
   {
 | 
						|
      #ifdef E4STACK
 | 
						|
         error4stack( c4, rc, E95301 ) ;
 | 
						|
      #endif
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
   if ( connection4type( connection ) != CON4INDEX_CREATE )
 | 
						|
   {
 | 
						|
      error4( c4, e4connection, E81705 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   rc = connection4status( connection ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
   {
 | 
						|
      connection4errorDescribe( connection, c4, rc, E95301, fileName, 0, 0 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( rc == r4unique )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   if ( connection4len( connection ) != sizeof( CONNECTION4INDEX_CREATE_INFO_OUT ) )
 | 
						|
   {
 | 
						|
      error4( c4, e4packetLen, E95301 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   dataOut = ( CONNECTION4INDEX_CREATE_INFO_OUT *)connection4data( connection ) ;
 | 
						|
 | 
						|
   if ( dataOut->lockedDatafile == 1 )
 | 
						|
      d4->dataFile->fileLock = d4 ;
 | 
						|
 | 
						|
   c4->openForCreate = 1 ;
 | 
						|
   if ( fileName == 0 )
 | 
						|
   {
 | 
						|
      i4 = 0 ;
 | 
						|
      switch( code4indexFormat( c4 ) )
 | 
						|
      {
 | 
						|
         case r4ntx:
 | 
						|
         case r4ndx:
 | 
						|
            for( i = 0 ; tagData[i].name != 0; i++ )
 | 
						|
            {
 | 
						|
               if ( i == 0 )
 | 
						|
               {
 | 
						|
                  tag = t4openLow( d4, 0, tagData[i].name, d4->alias ) ;
 | 
						|
                  if ( tag == 0 )
 | 
						|
                     break ;
 | 
						|
                  i4 = tag->index ;
 | 
						|
                  if ( i4 == 0 )
 | 
						|
                     break ;
 | 
						|
                  u4ncpy( i4->alias, d4->alias, sizeof( i4->alias ) ) ;
 | 
						|
                  u4ncpy( i4->indexFile->accessName, d4->dataFile->accessName, sizeof( i4->indexFile->accessName ) ) ;
 | 
						|
               }
 | 
						|
               else
 | 
						|
               {
 | 
						|
                  tag = t4open( d4, i4, tagData[i].name ) ;
 | 
						|
                  if ( tag == 0 )
 | 
						|
                     break ;
 | 
						|
               }
 | 
						|
            }
 | 
						|
            break ;
 | 
						|
         default:
 | 
						|
            u4namePiece( buf, sizeof( buf ), dfile4name( d4->dataFile ), 1, 0 ) ;
 | 
						|
            u4nameExt( buf, sizeof(buf), code4indexExtension( d4->codeBase ), 1 ) ;
 | 
						|
            i4 = i4open( d4, buf ) ;
 | 
						|
            break ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
   else
 | 
						|
      i4 = i4open( d4, fileName ) ;
 | 
						|
   c4->openForCreate = 0 ;
 | 
						|
 | 
						|
   if ( i4 != 0 )
 | 
						|
   {
 | 
						|
      for ( i = 0 ; tagData[i].name != 0 ; i++ )
 | 
						|
      {
 | 
						|
         tagPtr = d4tag( d4, tagData[i].name ) ;
 | 
						|
         if ( tagPtr == 0 )
 | 
						|
         {
 | 
						|
            error4describe( c4, e4name, E81406, d4alias( d4 ), tagData[i].name, 0 ) ;
 | 
						|
            i4close( i4 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
         t4uniqueSetLow( tagPtr, tagData[i].unique, 0 ) ;
 | 
						|
      }
 | 
						|
   }
 | 
						|
 | 
						|
   d4->recNum = -1 ;
 | 
						|
   d4->recNumOld = -1 ;
 | 
						|
   memset( d4->record, ' ', dfile4recWidth( d4->dataFile ) ) ;
 | 
						|
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      i4->isValid = 1 ;
 | 
						|
   #endif
 | 
						|
   return i4 ;
 | 
						|
}
 | 
						|
 | 
						|
#else  /* S4CLIENT */
 | 
						|
 | 
						|
#ifndef N4OTHER
 | 
						|
static INDEX4 *i4createLow( DATA4 *d4, const char *fileName, const TAG4INFO *tagData )
 | 
						|
{
 | 
						|
   DATA4FILE *data ;
 | 
						|
   INDEX4FILE *indexFile ;
 | 
						|
   TAG4 *tagPtr ;
 | 
						|
   INDEX4 *i4 ;
 | 
						|
   CODE4 *c4 ;
 | 
						|
   char buf[258] ;
 | 
						|
   int i, rc ;
 | 
						|
   #ifdef S4FOX
 | 
						|
      #ifdef S4DATA_ALIGN
 | 
						|
         unsigned int size, delta ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   c4 = d4->codeBase ;
 | 
						|
 | 
						|
   #ifndef S4OFF_MULTI
 | 
						|
      if ( fileName == 0 )  /* must have file open exclusively, since the lock handling changes, potentially causing multi-user failures */
 | 
						|
      #ifdef S4SERVER
 | 
						|
         if ( d4->accessMode != OPEN4DENY_RW )
 | 
						|
         {
 | 
						|
            error4( c4, e4create, E81306 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      #else
 | 
						|
         if ( d4->dataFile->file.lowAccessMode != OPEN4DENY_RW )
 | 
						|
         {
 | 
						|
            error4( c4, e4create, E81306 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
   #endif  /* S4OFF_MULTI */
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( code4indexExtension( d4->codeBase ) == 0 )
 | 
						|
      {
 | 
						|
         error4( c4, e4struct, E91707 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
   if ( fileName )
 | 
						|
      u4nameCurrent( buf, sizeof( buf ), fileName ) ;
 | 
						|
   else
 | 
						|
      u4nameCurrent( buf, sizeof( buf ), dfile4name( d4->dataFile ) ) ;
 | 
						|
   u4nameExt( buf, sizeof(buf), code4indexExtension( c4 ), ( fileName == 0 ? 1 : 0 ) ) ;
 | 
						|
   #ifndef S4CASE_SEN
 | 
						|
      c4upper( buf ) ;
 | 
						|
   #endif
 | 
						|
   if ( dfile4index( d4->dataFile, buf ) )
 | 
						|
   {
 | 
						|
      error4describe( c4, e4name, E81703, buf, 0, 0 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( d4->dataFile == 0 )
 | 
						|
      return 0 ;
 | 
						|
   data = d4->dataFile ;
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return 0 ;
 | 
						|
   error4set( c4, 0 ) ;  /* Make sure it is not 'r4unique' or 'r4noCreate'. */
 | 
						|
 | 
						|
   #ifndef S4SINGLE
 | 
						|
      if ( d4lockFile( d4 ) )
 | 
						|
      {
 | 
						|
         error4( c4, e4lock, E85309 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   i4 = (INDEX4 *)mem4createAlloc( c4, &c4->indexMemory, c4->memStartIndex, sizeof(INDEX4), c4->memExpandIndex, 0 ) ;
 | 
						|
   if ( i4 == 0 )
 | 
						|
   {
 | 
						|
      #ifdef E4STACK
 | 
						|
         error4stack( c4, e4memory, E95301 ) ;
 | 
						|
      #endif
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   i4->codeBase = c4 ;
 | 
						|
   i4->data = d4 ;
 | 
						|
 | 
						|
   indexFile = (INDEX4FILE *)mem4createAlloc( c4, &c4->index4fileMemory, c4->memStartIndexFile, sizeof(INDEX4FILE), c4->memExpandIndexFile, 0 ) ;
 | 
						|
   if ( indexFile == 0 )
 | 
						|
   {
 | 
						|
      #ifdef E4STACK
 | 
						|
         error4stack( c4, e4memory, E95301 ) ;
 | 
						|
      #endif
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
   indexFile->codeBase = c4 ;
 | 
						|
   indexFile->dataFile = data ;
 | 
						|
 | 
						|
   indexFile->userCount = 1 ;
 | 
						|
   i4->indexFile = indexFile ;
 | 
						|
   rc = file4create( &indexFile->file, c4, buf, 1 ) ;
 | 
						|
   if ( rc )
 | 
						|
   {
 | 
						|
      if ( rc > 0 )
 | 
						|
         error4set( c4, rc ) ;
 | 
						|
 | 
						|
      i4close( i4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   l4add( &data->indexes, indexFile ) ;
 | 
						|
   l4add( &d4->indexes, i4 ) ;
 | 
						|
 | 
						|
   #ifdef S4STAND_ALONE
 | 
						|
      if ( fileName == 0 )
 | 
						|
         u4namePiece( i4->accessName, sizeof( i4->accessName ), d4->alias, 0, 0 ) ;
 | 
						|
      else
 | 
						|
      {
 | 
						|
         if ( strlen( fileName ) > sizeof( i4->accessName ) - 1 )
 | 
						|
         {
 | 
						|
            error4( c4, e4name, E95301 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
         strcpy( i4->accessName, fileName ) ;
 | 
						|
      }
 | 
						|
      c4upper( i4->accessName ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4FOX
 | 
						|
      indexFile->blockMemory = mem4create( c4, c4->memStartBlock,
 | 
						|
           (sizeof(B4BLOCK)) + B4BLOCK_SIZE - (sizeof(B4STD_HEADER)) - (sizeof(B4NODE_HEADER)), c4->memExpandBlock, 0 ) ;
 | 
						|
      if ( indexFile->blockMemory == 0 )
 | 
						|
      {
 | 
						|
         i4close( i4 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( c4->tagMemory == 0 )
 | 
						|
      {
 | 
						|
         c4->tagMemory = mem4create( c4, c4->memStartTag, sizeof(TAG4), c4->memExpandTag, 0 ) ;
 | 
						|
         if ( c4->tagMemory == 0 )
 | 
						|
            return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( c4->tagFileMemory == 0 )
 | 
						|
      {
 | 
						|
         c4->tagFileMemory = mem4create( c4, c4->memStartTagFile, sizeof(TAG4FILE), c4->memExpandTagFile, 0 ) ;
 | 
						|
         if ( c4->tagFileMemory == 0 )
 | 
						|
            return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      indexFile->tagIndex = (TAG4FILE *) mem4alloc( c4->tagFileMemory ) ;
 | 
						|
      if ( indexFile->tagIndex == 0 )
 | 
						|
         return 0 ;
 | 
						|
 | 
						|
      indexFile->tagIndex->codeBase = c4 ;
 | 
						|
      indexFile->tagIndex->indexFile = indexFile ;
 | 
						|
      indexFile->tagIndex->header.typeCode = 0xE0 ;  /* compound, compact */
 | 
						|
      indexFile->tagIndex->header.filterLen = 1 ;
 | 
						|
      indexFile->tagIndex->header.filterPos = 1 ;
 | 
						|
      indexFile->tagIndex->header.exprLen = 1 ;
 | 
						|
      indexFile->tagIndex->header.exprPos = 0 ;
 | 
						|
      indexFile->tagIndex->header.keyLen = 10 ;
 | 
						|
      indexFile->tagIndex->header.signature = 0x01 ;
 | 
						|
      #ifdef S4DATA_ALIGN
 | 
						|
         size = (unsigned int)sizeof(long) + indexFile->tagIndex->header.keyLen ;
 | 
						|
         delta = 4 - size % 4 ;
 | 
						|
         indexFile->tagIndex->builtKeyMemory = mem4create( c4, 3, size + delta, 2, 0 ) ;
 | 
						|
      #else
 | 
						|
         indexFile->tagIndex->builtKeyMemory = mem4create( c4, 3, (unsigned int)sizeof(long) + indexFile->tagIndex->header.keyLen + 1, 2, 0 ) ;
 | 
						|
      #endif
 | 
						|
      if ( tfile4setCollatingSeq( indexFile->tagIndex, sort4machine ) < 0 )     /* tag of tags is always machine */
 | 
						|
         return 0 ;
 | 
						|
      if ( tfile4setCodePage( indexFile->tagIndex, d4->codePage ) < 0 )
 | 
						|
         return 0 ;
 | 
						|
 | 
						|
      u4namePiece( indexFile->tagIndex->alias, sizeof(indexFile->tagIndex->alias), buf, 0, 0 ) ;
 | 
						|
      c4upper( indexFile->tagIndex->alias ) ;
 | 
						|
 | 
						|
      tagPtr = 0 ;
 | 
						|
      for ( i = 0; tagData[i].name; i++ )
 | 
						|
      {
 | 
						|
         tagPtr = (TAG4 *)mem4alloc( c4->tagMemory ) ;
 | 
						|
         if ( tagPtr == 0 )
 | 
						|
            break ;
 | 
						|
 | 
						|
         tagPtr->tagFile = (TAG4FILE *)mem4alloc( c4->tagFileMemory ) ;
 | 
						|
         if ( tagPtr->tagFile == 0 )
 | 
						|
            break ;
 | 
						|
 | 
						|
         tagPtr->index = i4 ;
 | 
						|
         tagPtr->tagFile->codeBase = c4 ;
 | 
						|
         tagPtr->tagFile->indexFile = indexFile ;
 | 
						|
 | 
						|
         #ifdef S4FOX
 | 
						|
            if ( tfile4setCollatingSeq( tagPtr->tagFile, c4->collatingSequence ) < 0 )
 | 
						|
               return 0 ;
 | 
						|
            if ( tfile4setCodePage( tagPtr->tagFile, d4->codePage ) < 0 )
 | 
						|
               return 0 ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         u4ncpy( tagPtr->tagFile->alias, tagData[i].name, sizeof(tagPtr->tagFile->alias) ) ;
 | 
						|
         c4upper( tagPtr->tagFile->alias ) ;
 | 
						|
 | 
						|
         tagPtr->tagFile->header.signature = 0x01 ;
 | 
						|
         tagPtr->tagFile->header.typeCode = 0x60 ;  /* compact */
 | 
						|
         if ( tagData[i].unique )
 | 
						|
         {
 | 
						|
            #ifdef S4FOX
 | 
						|
               if ( tagData[i].unique == r4candidate || tagData[i].unique == e4candidate )
 | 
						|
                  tagPtr->tagFile->header.typeCode += 0x04 ;
 | 
						|
               else
 | 
						|
            #endif
 | 
						|
               tagPtr->tagFile->header.typeCode += 0x01 ;
 | 
						|
            tagPtr->errUnique = tagData[i].unique ;
 | 
						|
 | 
						|
            #ifdef S4FOX
 | 
						|
               if ( tagData[i].unique != e4unique && tagData[i].unique != r4unique &&
 | 
						|
                    tagData[i].unique != r4uniqueContinue && tagData[i].unique != r4candidate &&
 | 
						|
                    tagData[i].unique != e4candidate )
 | 
						|
            #else
 | 
						|
               if ( tagData[i].unique != e4unique && tagData[i].unique != r4unique && tagData[i].unique != r4uniqueContinue )
 | 
						|
            #endif
 | 
						|
            {
 | 
						|
               error4describe( c4, e4tagInfo, E85301, tagData[i].name, 0, 0 ) ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         if ( tagData[i].descending)
 | 
						|
         {
 | 
						|
            tagPtr->tagFile->header.descending = 1 ;
 | 
						|
            #ifdef E4PARM_HIGH
 | 
						|
               if ( tagData[i].descending != r4descending )
 | 
						|
               {
 | 
						|
                  error4describe( c4, e4tagInfo, E85302, tagData[i].name, 0, 0 ) ;
 | 
						|
                  break ;
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
         }
 | 
						|
 | 
						|
         if ( tagData[i].expression == 0 )
 | 
						|
         {
 | 
						|
            error4describe( c4, e4tagInfo, E85303, tagData[i].name, tagData[i].expression, 0 ) ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
 | 
						|
         tagPtr->tagFile->expr = expr4parseLow( d4, tagData[i].expression, tagPtr->tagFile ) ;
 | 
						|
         if ( tagPtr->tagFile->expr == 0 )
 | 
						|
         {
 | 
						|
            if ( error4code( c4 ) >= 0 )
 | 
						|
               error4( c4, e4memory, E95301 ) ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
 | 
						|
         tagPtr->tagFile->header.exprLen = (short) (strlen( tagPtr->tagFile->expr->source ) + 1) ;
 | 
						|
         if ( tagPtr->tagFile->header.exprLen > I4MAX_EXPR_SIZE )
 | 
						|
         {
 | 
						|
            error4describe( c4, e4tagInfo, E85304, tagData[i].name, tagData[i].expression, 0 ) ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         if ( tagData[i].filter != 0 )
 | 
						|
            if ( *( tagData[i].filter ) != '\0' )
 | 
						|
            {
 | 
						|
               tagPtr->tagFile->header.typeCode += 0x08 ;
 | 
						|
               tagPtr->tagFile->filter = expr4parseLow( d4, tagData[i].filter, tagPtr->tagFile ) ;
 | 
						|
               if (tagPtr->tagFile->filter)
 | 
						|
                  tagPtr->tagFile->header.filterLen = (short)strlen( tagPtr->tagFile->filter->source ) ;
 | 
						|
            }
 | 
						|
         tagPtr->tagFile->header.filterLen++ ;  /* minimum of 1, for the '\0' */
 | 
						|
         if ( tagPtr->tagFile->header.filterLen > I4MAX_EXPR_SIZE )
 | 
						|
         {
 | 
						|
            error4describe( c4, e4tagInfo, E85304, tagData[i].name, tagData[i].filter, 0 ) ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         tagPtr->tagFile->header.filterPos = tagPtr->tagFile->header.exprLen ;
 | 
						|
 | 
						|
         if ( error4code( c4 ) < 0 )
 | 
						|
            break ;
 | 
						|
         l4add( &indexFile->tags, tagPtr->tagFile ) ;
 | 
						|
         l4add( &i4->tags, tagPtr ) ;
 | 
						|
         tagPtr = 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( error4code( c4 ) < 0 )
 | 
						|
      {
 | 
						|
         if ( tagPtr != 0 )
 | 
						|
         {
 | 
						|
            if ( tagPtr->tagFile != 0 )
 | 
						|
               mem4free( c4->tagFileMemory, tagPtr->tagFile ) ;
 | 
						|
            mem4free( c4->tagMemory, tagPtr ) ;
 | 
						|
         }
 | 
						|
         i4close( i4 );
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #else                /* if not S4FOX   */
 | 
						|
      indexFile->header.two = 2 ;
 | 
						|
      u4yymmdd( indexFile->header.createDate ) ;
 | 
						|
 | 
						|
      if ( fileName == 0 )
 | 
						|
         indexFile->header.isProduction = 1 ;
 | 
						|
 | 
						|
      indexFile->header.numSlots = 0x30 ;
 | 
						|
      indexFile->header.slotSize = 0x20 ;
 | 
						|
 | 
						|
      u4namePiece( indexFile->header.dataName, sizeof( indexFile->header.dataName ), data->file.name, 0, 0 ) ;
 | 
						|
      indexFile->header.blockChunks = (short)(c4->memSizeBlock/512) ;
 | 
						|
 | 
						|
      #ifdef E4MISC
 | 
						|
         if ( indexFile->header.blockChunks < 2 || indexFile->header.blockChunks > 63 )   /* disallowed for compatibility reasons */
 | 
						|
         {
 | 
						|
            error4describe( c4, e4info, E85305, fileName, 0, 0 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
 | 
						|
      indexFile->header.blockRw = (short)(indexFile->header.blockChunks * I4MULTIPLY) ;
 | 
						|
 | 
						|
      indexFile->blockMemory = mem4create( c4, c4->memStartBlock,
 | 
						|
                                     (sizeof(B4BLOCK)) + indexFile->header.blockRw -
 | 
						|
                                     (sizeof(B4KEY_DATA)) - (sizeof(short)) - (sizeof(char[6])),
 | 
						|
                                     c4->memExpandBlock, 0 ) ;
 | 
						|
      if ( indexFile->blockMemory == 0 )
 | 
						|
      {
 | 
						|
         i4close( i4 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      tagPtr = 0 ;
 | 
						|
      for ( i = 0 ; tagData[i].name ; i++ )
 | 
						|
      {
 | 
						|
         indexFile->header.numTags++ ;
 | 
						|
 | 
						|
         if ( c4->tagMemory == 0 )
 | 
						|
         {
 | 
						|
            c4->tagMemory = mem4create( c4, c4->memStartTag, sizeof(TAG4), c4->memExpandTag, 0 ) ;
 | 
						|
            if ( c4->tagMemory == 0 )
 | 
						|
               break ;
 | 
						|
         }
 | 
						|
 | 
						|
         if ( c4->tagFileMemory == 0 )
 | 
						|
         {
 | 
						|
            c4->tagFileMemory = mem4create( c4, c4->memStartTagFile, sizeof(TAG4FILE), c4->memExpandTagFile, 0 ) ;
 | 
						|
            if ( c4->tagFileMemory == 0 )
 | 
						|
               break ;
 | 
						|
         }
 | 
						|
 | 
						|
         tagPtr = (TAG4 *)mem4alloc( c4->tagMemory ) ;
 | 
						|
         if ( tagPtr == 0 )
 | 
						|
            break ;
 | 
						|
         memset( (void *)tagPtr,0, sizeof(TAG4) ) ;
 | 
						|
         tagPtr->index = i4 ;
 | 
						|
 | 
						|
         tagPtr->tagFile = (TAG4FILE *)mem4alloc( c4->tagFileMemory ) ;
 | 
						|
         if ( tagPtr->tagFile == 0 )
 | 
						|
            break ;
 | 
						|
         memset( (void *)tagPtr->tagFile,0, sizeof(TAG4FILE) ) ;
 | 
						|
         tagPtr->tagFile->codeBase = c4 ;
 | 
						|
         tagPtr->tagFile->indexFile = indexFile ;
 | 
						|
 | 
						|
         u4ncpy( tagPtr->tagFile->alias, tagData[i].name, sizeof(tagPtr->tagFile->alias) ) ;
 | 
						|
         c4upper( tagPtr->tagFile->alias ) ;
 | 
						|
 | 
						|
         tagPtr->tagFile->header.typeCode  = 0x10 ;
 | 
						|
         if ( tagData[i].unique )
 | 
						|
         {
 | 
						|
            tagPtr->tagFile->header.typeCode += 0x40 ;
 | 
						|
            tagPtr->tagFile->header.unique = 0x4000 ;
 | 
						|
            tagPtr->errUnique = tagData[i].unique ;
 | 
						|
 | 
						|
            #ifdef S4FOX
 | 
						|
               if ( tagData[i].unique != e4unique && tagData[i].unique != r4unique &&
 | 
						|
                    tagData[i].unique != r4uniqueContinue && tagData[i].unique != r4candidate &&
 | 
						|
                    tagData[i].unique != e4candidate )
 | 
						|
            #else
 | 
						|
               if ( tagData[i].unique != e4unique && tagData[i].unique != r4unique &&tagData[i].unique != r4uniqueContinue )
 | 
						|
            #endif
 | 
						|
            {
 | 
						|
               error4describe( c4, e4tagInfo, E85301, tagData[i].name, 0, 0 ) ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         if ( tagData[i].descending)
 | 
						|
         {
 | 
						|
            tagPtr->tagFile->header.typeCode += 0x08 ;
 | 
						|
            #ifdef E4PARM_HIGH
 | 
						|
               if ( tagData[i].descending != r4descending )
 | 
						|
               {
 | 
						|
                  error4describe( c4, e4tagInfo, E85302, tagData[i].name, 0, 0 ) ;
 | 
						|
                  break ;
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
         }
 | 
						|
 | 
						|
         if ( tagData[i].expression == 0 )
 | 
						|
         {
 | 
						|
            error4describe( c4, e4tagInfo, E85303, tagData[i].name, tagData[i].expression, 0 ) ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
 | 
						|
         tagPtr->tagFile->expr = expr4parseLow( d4, tagData[i].expression, tagPtr->tagFile ) ;
 | 
						|
         if ( tagPtr->tagFile->expr == 0 )
 | 
						|
         {
 | 
						|
            if ( error4code( c4 ) >= 0 )
 | 
						|
               error4( c4, e4memory, E95301 ) ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         if ( expr4type( tagPtr->tagFile->expr ) == r4log )  /* disallowed in MDX */
 | 
						|
         {
 | 
						|
            error4( c4, e4index, E82901 ) ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
 | 
						|
         if ( tagData[i].filter != 0 )
 | 
						|
            if ( *(tagData[i].filter) != '\0' )
 | 
						|
               tagPtr->tagFile->filter = expr4parseLow( d4, tagData[i].filter, tagPtr->tagFile ) ;
 | 
						|
 | 
						|
         if ( error4code( c4 ) < 0 )
 | 
						|
            break ;
 | 
						|
         l4add( &indexFile->tags, tagPtr->tagFile ) ;
 | 
						|
         l4add( &i4->tags, tagPtr ) ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( error4code( c4 ) < 0 )
 | 
						|
      {
 | 
						|
         if ( tagPtr != 0 )
 | 
						|
         {
 | 
						|
            if ( tagPtr->tagFile != 0 )
 | 
						|
               mem4free( c4->tagFileMemory, tagPtr->tagFile ) ;
 | 
						|
            mem4free( c4->tagMemory, tagPtr ) ;
 | 
						|
         }
 | 
						|
         i4close( i4 );
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      if ( indexFile->header.numTags > 47 )
 | 
						|
      {
 | 
						|
         i4close( i4 );
 | 
						|
         error4describe( c4, e4tagInfo, E85306, fileName, 0, 0 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   i4->indexFile = indexFile ;
 | 
						|
   rc = i4reindex( i4 ) ;
 | 
						|
 | 
						|
   if ( rc == r4unique || rc < 0 )
 | 
						|
   {
 | 
						|
      error4set( c4, r4unique ) ;
 | 
						|
      i4close( i4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( fileName == 0 )
 | 
						|
   {
 | 
						|
      data->hasMdxMemo |= 1 ;  /* or for fox 3.0 which uses this setting with 0x02 bit for memo */
 | 
						|
      #ifdef S4STAND_ALONE
 | 
						|
         d4->dataFile->openMdx = 1 ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      #ifdef S4FOX
 | 
						|
         file4write( &data->file, (long)(( 4 + ( sizeof( S4LONG ) ) + 2 * ( sizeof( short ) ) + ( sizeof( char[16] ) ) )),
 | 
						|
                     &(indexFile->dataFile->hasMdxMemo), sizeof( char ) ) ;
 | 
						|
      #else
 | 
						|
         file4write( &data->file, (long)(( 4 + ( sizeof( S4LONG ) ) + 2 * ( sizeof( short ) ) + ( sizeof( char[16] ) ) )),
 | 
						|
                     &(indexFile->dataFile->hasMdxMemo), sizeof( indexFile->dataFile->hasMdxMemo ) ) ;
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
   if ( error4code( c4 ) < 0 || error4code( c4 ) == r4unique )
 | 
						|
   {
 | 
						|
      i4close( i4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4STAND_ALONE
 | 
						|
      if ( fileName != 0 )
 | 
						|
      {
 | 
						|
         #ifdef E4MISC
 | 
						|
            if ( strlen( fileName ) > sizeof( i4->accessName ) )
 | 
						|
            {
 | 
						|
               error4describe( c4, e4name, E95301, fileName, 0, 0 ) ;
 | 
						|
               i4close( i4 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
         u4ncpy( i4->accessName, fileName, sizeof( i4->accessName ) - 1 ) ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      i4->isValid = 1 ;
 | 
						|
   #endif
 | 
						|
   return i4 ;
 | 
						|
}
 | 
						|
 | 
						|
#else /* N4OTHER */
 | 
						|
 | 
						|
static INDEX4 *i4createLow( DATA4 *d4, const char *fileName, const TAG4INFO *tagData )
 | 
						|
{
 | 
						|
   INDEX4 *i4 ;
 | 
						|
   CODE4 *c4 ;
 | 
						|
   char buf[258], ext[4] ;
 | 
						|
   int i, rc ;
 | 
						|
   char buffer[1024] ;
 | 
						|
   FILE4SEQ_WRITE seqwrite ;
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( fileName )
 | 
						|
      {
 | 
						|
         if ( d4index( d4, fileName ) )
 | 
						|
         {
 | 
						|
            error4describe( d4->codeBase, e4name, E81703, fileName, 0, 0 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
         u4namePiece( buf, sizeof( buf ), fileName, 0, 1 ) ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   c4 = d4->codeBase ;
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return 0 ;
 | 
						|
   error4set( c4, 0 ) ;  /* Make sure it is not 'r4unique' or 'r4noCreate'. */
 | 
						|
 | 
						|
   if ( fileName != 0 )
 | 
						|
      if ( code4indexFormat( c4 ) == r4ntx )   /* disallow .ntx extensions */
 | 
						|
      {
 | 
						|
         u4nameRetExt( ext, 3, fileName ) ;
 | 
						|
         if ( memcmp( ext, "NTX", 3 ) == 0 )
 | 
						|
         {
 | 
						|
            ext[sizeof(ext)-1] = 0 ;
 | 
						|
            error4describe( c4, e4name, E81720, fileName, ext, 0 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
 | 
						|
   #ifndef S4SINGLE
 | 
						|
      if ( d4lockFile( d4 ) != 0 )
 | 
						|
         return 0 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   i4 = (INDEX4 *)mem4createAlloc( c4, &c4->indexMemory, c4->memStartIndex, sizeof(INDEX4), c4->memExpandIndex, 0 ) ;
 | 
						|
 | 
						|
   if ( i4 == 0 )
 | 
						|
   {
 | 
						|
      #ifdef E4STACK
 | 
						|
         error4stack( c4, e4memory, E95301 ) ;
 | 
						|
      #endif
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   i4->codeBase = c4 ;
 | 
						|
   i4->data = d4 ;
 | 
						|
 | 
						|
   memset( buf, 0, sizeof( buf ) ) ;
 | 
						|
 | 
						|
   if ( fileName )  /* create a group file */
 | 
						|
   {
 | 
						|
      u4ncpy( buf, fileName, sizeof( buf ) ) ;
 | 
						|
      u4ncpy( i4->accessName, fileName, sizeof( i4->accessName ) ) ;
 | 
						|
      c4upper( i4->accessName ) ;
 | 
						|
 | 
						|
      u4nameExt( buf, sizeof( buf ), "CGP", 0 ) ;
 | 
						|
      c4upper( buf ) ;
 | 
						|
 | 
						|
      rc = file4create( &i4->file, c4, buf, 1 ) ;
 | 
						|
      if ( rc )
 | 
						|
      {
 | 
						|
         if ( rc > 0 )
 | 
						|
            error4set( c4, rc ) ;
 | 
						|
 | 
						|
         file4close( &i4->file ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      file4seqWriteInit( &seqwrite, &i4->file, 0L, buffer, sizeof( buffer ) ) ;
 | 
						|
 | 
						|
      /* create the group file */
 | 
						|
      for ( i = 0; tagData[i].name; i++ )
 | 
						|
      {
 | 
						|
         file4seqWrite( &seqwrite, tagData[i].name, strlen( tagData[i].name ) ) ;
 | 
						|
         file4seqWrite( &seqwrite, "\r\n", 1 ) ;
 | 
						|
      }
 | 
						|
 | 
						|
      file4seqWriteFlush( &seqwrite ) ;
 | 
						|
 | 
						|
      file4close ( &i4->file ) ;
 | 
						|
 | 
						|
      #ifndef S4SINGLE
 | 
						|
         if ( rc )
 | 
						|
         {
 | 
						|
            if ( rc > 0 )
 | 
						|
               error4set( c4, rc ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
      i4->path = buf ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
   {
 | 
						|
      u4ncpy( i4->accessName, d4->alias, sizeof( i4->accessName ) ) ;
 | 
						|
      c4upper( i4->accessName ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   l4add( &d4->indexes, i4 ) ;
 | 
						|
 | 
						|
   /* now create the actual tag files */
 | 
						|
   for ( i = 0 ; tagData[i].name ; i++ )
 | 
						|
      if ( t4create( d4, &tagData[i], i4 ) == 0 )
 | 
						|
      {
 | 
						|
         i4close( i4 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
   if ( error4code( c4 ) < 0 || error4code( c4 ) == r4unique )
 | 
						|
   {
 | 
						|
      i4close( i4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( i4reindex( i4 ) == r4unique )
 | 
						|
   {
 | 
						|
      i4close( i4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      i4->isValid = 1 ;
 | 
						|
   #endif
 | 
						|
   return i4 ;
 | 
						|
}
 | 
						|
 | 
						|
/* this function does not reindex if an 'i4ndx' is passed as a parameter */
 | 
						|
/* this allows several creations before an actual reindex must occur */
 | 
						|
TAG4 *S4FUNCTION t4create( DATA4 *d4, const TAG4INFO *tagData, INDEX4 *i4ndx )
 | 
						|
{
 | 
						|
   CODE4  *c4 ;
 | 
						|
   INDEX4 *i4 ;
 | 
						|
   char   buf[258] ;
 | 
						|
   TAG4 *t4 ;
 | 
						|
   TAG4FILE *tfile ;
 | 
						|
   int rc, oldTagErr ;
 | 
						|
   #ifndef S4OFF_OPTIMIZE
 | 
						|
      #ifdef S4LOW_MEMORY
 | 
						|
         int hasOpt ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4VBASIC
 | 
						|
      if ( c4parm_check( d4, 2, E95302 ) )
 | 
						|
         return 0 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( d4 == 0 || tagData == 0 )
 | 
						|
      {
 | 
						|
         error4( 0, e4parm, E95302 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      #ifdef S4NDX
 | 
						|
         if ( ( tagData->filter != 0 && *(tagData->filter) != '\0' ) || tagData->descending != 0 )
 | 
						|
         {
 | 
						|
            error4describe( 0, e4parm, E83507, tagData->name, 0, 0 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
 | 
						|
      u4namePiece( buf, sizeof( buf ), tagData->name, 0, 0 ) ;
 | 
						|
 | 
						|
      if ( error4code( d4->codeBase ) < 0 )
 | 
						|
         return 0 ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   c4 = d4->codeBase ;
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return 0 ;
 | 
						|
 | 
						|
   oldTagErr = c4->errTagName ;
 | 
						|
   c4->errTagName = 0 ;
 | 
						|
   if ( d4tag( d4, buf ) )
 | 
						|
   {
 | 
						|
      error4describe( c4, e4name, E85308, buf, 0, 0 ) ;
 | 
						|
      c4->errTagName = oldTagErr ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
   c4->errTagName = oldTagErr ;
 | 
						|
 | 
						|
   error4set( c4, 0 ) ;  /* Make sure it is not 'r4unique' or 'r4noCreate'. */
 | 
						|
 | 
						|
   #ifndef S4OFF_OPTIMIZE
 | 
						|
      #ifdef S4LOW_MEMORY
 | 
						|
         if ( c4->hasOpt )
 | 
						|
         {
 | 
						|
            hasOpt = 1 ;
 | 
						|
            code4optSuspend( c4 ) ;
 | 
						|
         }
 | 
						|
         else
 | 
						|
            hasOpt = 0 ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( i4ndx == 0 )   /* must create an index for the tag */
 | 
						|
   {
 | 
						|
      if ( c4->indexMemory == 0 )
 | 
						|
         c4->indexMemory = mem4create( c4, c4->memStartIndex, sizeof(INDEX4),
 | 
						|
                                        c4->memExpandIndex, 0 ) ;
 | 
						|
      if ( c4->indexMemory == 0 )
 | 
						|
         return 0 ;
 | 
						|
      i4 = (INDEX4 *) mem4alloc( c4->indexMemory ) ;
 | 
						|
      if ( i4 == 0 )
 | 
						|
      {
 | 
						|
         #ifdef E4STACK
 | 
						|
            error4stack( c4, e4memory, E95302 ) ;
 | 
						|
         #endif
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
      i4->data = d4 ;
 | 
						|
      i4->codeBase = c4 ;
 | 
						|
      #ifdef E4PARM_HIGH
 | 
						|
         u4namePiece( buf, sizeof( buf ), i4->accessName, 0, 0 ) ;
 | 
						|
         if ( d4index( d4, buf ) )
 | 
						|
         {
 | 
						|
            error4( d4->codeBase, e4parm, E81704 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
      u4namePiece( i4->accessName, sizeof( i4->accessName ), tagData->name, 0, 0 ) ;
 | 
						|
      c4upper( i4->accessName ) ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      i4 = i4ndx ;
 | 
						|
 | 
						|
   if ( c4->tagMemory == 0 )
 | 
						|
   {
 | 
						|
      c4->tagMemory = mem4create( c4, c4->memStartTag, sizeof(TAG4), c4->memExpandTag, 0 ) ;
 | 
						|
      if ( c4->tagMemory == 0 )
 | 
						|
         return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( c4->tagFileMemory == 0 )
 | 
						|
   {
 | 
						|
      c4->tagFileMemory = mem4create( c4, c4->memStartTagFile, sizeof(TAG4FILE), c4->memExpandTagFile, 0 ) ;
 | 
						|
      if ( c4->tagFileMemory == 0 )
 | 
						|
         return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   t4 = (TAG4 *)mem4alloc( c4->tagMemory ) ;
 | 
						|
   if ( t4 == 0 )
 | 
						|
   {
 | 
						|
      #ifdef E4STACK
 | 
						|
         error4stack( c4, e4memory, E95302 ) ;
 | 
						|
      #endif
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   t4->index = i4 ;
 | 
						|
 | 
						|
   t4->tagFile = (TAG4FILE *) mem4alloc( c4->tagFileMemory ) ;
 | 
						|
   if ( t4->tagFile == 0 )
 | 
						|
   {
 | 
						|
      #ifdef E4STACK
 | 
						|
         error4stack( c4, e4memory, E95302 ) ;
 | 
						|
      #endif
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   tfile = t4->tagFile ;
 | 
						|
   tfile->codeBase = c4 ;
 | 
						|
   tfile->userCount = 1 ;
 | 
						|
 | 
						|
   if ( tfile->blockMemory == 0 )
 | 
						|
      tfile->blockMemory = mem4create( c4, c4->memStartBlock, sizeof(B4BLOCK) + B4BLOCK_SIZE -
 | 
						|
                                     (sizeof(B4KEY_DATA)) - (sizeof(short)) - (sizeof(char[2])),
 | 
						|
                                     c4->memExpandBlock, 0 ) ;
 | 
						|
 | 
						|
   if ( tfile->blockMemory == 0 )
 | 
						|
   {
 | 
						|
      if ( tfile != 0 )
 | 
						|
         mem4free( c4->tagFileMemory, tfile ) ;
 | 
						|
      mem4free( c4->tagMemory, t4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   if ( i4ndx != 0 && i4->path != 0)
 | 
						|
   {
 | 
						|
      rc = u4namePath( buf, sizeof(buf), i4ndx->path ) ;
 | 
						|
      u4ncpy( buf+rc, tagData->name, sizeof(buf)-rc - 1 ) ;
 | 
						|
   }
 | 
						|
   else
 | 
						|
      u4ncpy( buf, tagData->name, sizeof(buf) - 1 ) ;
 | 
						|
 | 
						|
   c4upper(buf) ;
 | 
						|
 | 
						|
   #ifdef S4NDX
 | 
						|
      #ifdef S4CASE_SEN
 | 
						|
         u4nameExt( buf, sizeof(buf), "ndx", 0 ) ;
 | 
						|
      #else
 | 
						|
         u4nameExt( buf, sizeof(buf), "NDX", 0 ) ;
 | 
						|
      #endif
 | 
						|
   #else
 | 
						|
      #ifdef S4CLIPPER
 | 
						|
         #ifdef S4CASE_SEN
 | 
						|
            u4nameExt( buf, sizeof(buf), "ntx", 0 ) ;
 | 
						|
         #else
 | 
						|
            u4nameExt( buf, sizeof(buf), "NTX", 0 ) ;
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   u4namePiece( tfile->alias, sizeof( tfile->alias ), tagData->name, 0, 0 ) ;
 | 
						|
   c4upper( tfile->alias ) ;
 | 
						|
 | 
						|
   #ifdef E4ANALYZE
 | 
						|
      if ( tfile == 0 )
 | 
						|
      {
 | 
						|
         mem4free( c4->tagMemory, t4 ) ;
 | 
						|
         error4( c4, e4info, E95302 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   rc = file4create( &tfile->file, c4, buf, 1 ) ;
 | 
						|
   if ( rc )
 | 
						|
   {
 | 
						|
      t4close( t4 ) ;
 | 
						|
      if ( rc > 0 )
 | 
						|
         c4->errorCode = rc ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifndef S4OFF_OPTIMIZE
 | 
						|
      file4optimizeLow( &tfile->file, c4->optimize, OPT4INDEX, 0, tfile ) ;
 | 
						|
      #ifdef S4LOW_MEMORY
 | 
						|
         if ( hasOpt )
 | 
						|
            code4optRestart( c4 ) ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( tagData->unique )
 | 
						|
   {
 | 
						|
      #ifdef S4NDX
 | 
						|
         tfile->header.unique = 0x4000 ;
 | 
						|
      #else
 | 
						|
         #ifdef S4CLIPPER
 | 
						|
            tfile->header.unique = 0x01 ;
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
 | 
						|
      t4->errUnique = tagData->unique ;
 | 
						|
 | 
						|
      #ifdef E4PARM_HIGH
 | 
						|
         #ifdef S4FOX
 | 
						|
            if ( tagData->unique != e4unique && tagData->unique != r4unique
 | 
						|
                 tagData->unique != r4uniqueContinue && tagData->unique != r4candidate &&
 | 
						|
                 tagData[i].unique != e4candidate )
 | 
						|
         #else
 | 
						|
            if ( tagData->unique != e4unique && tagData->unique != r4unique && tagData->unique != r4uniqueContinue )
 | 
						|
         #endif
 | 
						|
         {
 | 
						|
            t4close( t4 ) ;
 | 
						|
            error4describe( c4, e4tagInfo, E85301, tagData->name, 0, 0 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4CLIPPER
 | 
						|
      if ( tagData->descending)
 | 
						|
      {
 | 
						|
         tfile->header.descending = 1 ;
 | 
						|
         #ifdef E4PARM_HIGH
 | 
						|
            if ( tagData->descending != r4descending )
 | 
						|
            {
 | 
						|
               t4close( t4 ) ;
 | 
						|
               error4describe( c4, e4tagInfo, E85302, tagData->name, 0, 0 ) ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( tagData->expression == 0 )
 | 
						|
      {
 | 
						|
         t4close( t4 ) ;
 | 
						|
         error4describe( c4, e4tagInfo, E85303, tagData->name, tagData->expression, 0 ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( (short) (strlen( tagData->expression ) + 1) > I4MAX_EXPR_SIZE )
 | 
						|
   {
 | 
						|
      t4close( t4 ) ;
 | 
						|
      error4describe( c4, e4tagInfo, E85304, tagData->name, tagData->expression, 0 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
   tfile->expr = expr4parseLow( d4, tagData->expression, tfile ) ;
 | 
						|
   if ( tfile->expr == 0 )
 | 
						|
   {
 | 
						|
      t4close( t4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifdef S4CLIPPER
 | 
						|
      if ( tagData->filter != 0 )
 | 
						|
      {
 | 
						|
         if ( ( strlen( tagData->filter ) + 1 ) > I4MAX_EXPR_SIZE )
 | 
						|
         {
 | 
						|
            t4close( t4 ) ;
 | 
						|
            error4describe( c4, e4tagInfo, E85304, tagData->name, tagData->filter, 0 ) ;
 | 
						|
            return 0 ;
 | 
						|
         }
 | 
						|
         if ( *( tagData->filter ) != '\0' )
 | 
						|
            tfile->filter = expr4parseLow( d4, tagData->filter, tfile ) ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4NDX
 | 
						|
      t4->header.eof = 2 ;
 | 
						|
      t4->header.root = 1 ;
 | 
						|
   #else
 | 
						|
      #ifdef S4CLIPPER
 | 
						|
         tfile->header.eof = 0 ;
 | 
						|
         tfile->header.root = 1024 ;
 | 
						|
         tfile->header.keyLen = c4->numericStrLen ;
 | 
						|
         tfile->header.keyDec = c4->decimals ;
 | 
						|
         if ( tfile->expr->type == r4num )
 | 
						|
         {
 | 
						|
            tfile->header.keyLen = tfile->expr->keyLen ;
 | 
						|
            tfile->header.keyDec = tfile->expr->keyDec ;
 | 
						|
         }
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
   {
 | 
						|
      t4close( t4 ) ;
 | 
						|
      return 0 ;
 | 
						|
   }
 | 
						|
 | 
						|
   /* add the tag to the index list */
 | 
						|
   l4add( &i4->tags, t4 ) ;
 | 
						|
 | 
						|
   if ( i4ndx == 0 )   /* single create, so reindex now */
 | 
						|
   {
 | 
						|
      if ( t4reindex( t4 ) == r4unique )
 | 
						|
      {
 | 
						|
         t4close( t4 ) ;
 | 
						|
         error4set( c4, r4unique ) ;
 | 
						|
         return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      l4add( &i4->data->indexes, i4 ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   l4add( &d4->dataFile->tagfiles, tfile ) ;
 | 
						|
   if ( d4->dataFile->indexLocked == 1 )   /* index locked, so lock this tag as well */
 | 
						|
      tfile4lock( tfile, data4serverId( d4 ) ) ;
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      t4->isValid = 1 ;
 | 
						|
   #endif
 | 
						|
   return t4 ;
 | 
						|
}
 | 
						|
#endif   /* N4OTHER */
 | 
						|
 | 
						|
#endif /* S4CLIENT */
 | 
						|
 | 
						|
#endif   /* S4OFF_WRITE */
 | 
						|
#endif   /* S4OFF_INDEX */
 | 
						|
 | 
						|
#ifdef S4VB_DOS
 | 
						|
 | 
						|
INDEX4 * i4create_v ( DATA4  *d4, char near *name, TAG4INFO *t4 )
 | 
						|
{
 | 
						|
   return i4create( d4, c4str(name), t4 ) ;
 | 
						|
}
 | 
						|
 | 
						|
INDEX4 * i4createProd ( DATA4  *d4, TAG4INFO *t4 )
 | 
						|
{
 | 
						|
   return i4create( d4, 0, t4 ) ;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |