int main(int argc, char** argv)
{
	char* srcFileName1;
	char* srcFileName2;
	char* dstFileName;

	GDALDataset* srcDS1, *srcDS2;
	GDALDataset* dstDS;

	if(argc != 4)
		error("Usage: prog infile1 infile2 outfile");

	srcFileName1 = argv[1];
	srcFileName2 = argv[2];
	dstFileName = argv[3];

	GDALAllRegister();

	srcDS1 = (GDALDataset*) GDALOpen( srcFileName1, GA_ReadOnly );
	srcDS2 = (GDALDataset*) GDALOpen( srcFileName2, GA_ReadOnly );

	if(srcDS1 == NULL || srcDS2 == NULL)
		error("Could not open source dataset");

	printf("Got image %d x %d x %d\n",
	      srcDS1->GetRasterXSize(),
	      srcDS1->GetRasterYSize(),
	      srcDS1->GetRasterCount()
	);
	printf("Got image %d x %d x %d\n",
	      srcDS2->GetRasterXSize(),
	      srcDS2->GetRasterYSize(),
	      srcDS2->GetRasterCount()
	);
	if((srcDS1->GetRasterXSize() != srcDS2->GetRasterXSize()) || 
           (srcDS1->GetRasterYSize() != srcDS2->GetRasterYSize()) ||
	   (srcDS1->GetRasterCount() != srcDS2->GetRasterCount()))
		fprintf(stderr, "Warning: Source dataset geometries should match!\n");

	int x_size, y_size, n_bands;
	x_size = MY_MAX(srcDS1->GetRasterXSize(), srcDS2->GetRasterXSize());
	y_size = MY_MAX(srcDS1->GetRasterYSize(), srcDS2->GetRasterYSize());
	n_bands = MY_MIN(srcDS1->GetRasterCount(), srcDS2->GetRasterCount());

	dstDS = CreateOutputDataset(dstFileName, 
	                            x_size, y_size, n_bands
	                           );

	if(dstDS == NULL)
		error("Could not create destination dataset");

	CalcFFT(srcDS1, srcDS2, dstDS);

	delete srcDS1;
	delete srcDS2;
	delete dstDS;

	return 0;	
}
/* ------------------------------------------------------------------------ */
void myReshape(int w, int h) {
    w = MY_MAX(w,200);
    h = MY_MAX(h,200);
    WindHeight = h;
    WindWidth = w;
    glutReshapeWindow(w,h);
    glViewport(0,0,w,h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    FOVratio  = (float)w / (float)h; /* keep world coord x/y ratio == 1 */
    gluPerspective(FOVangle, FOVratio, ClipNear, ClipFar);
    glMatrixMode(GL_MODELVIEW);
} /* myReshape() */
示例#3
0
my_bool my_init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
                              void *init_buffer, uint init_alloc, 
                              uint alloc_increment)
{
  DBUG_ENTER("init_dynamic_array");
  if (!alloc_increment)
  {
    alloc_increment=MY_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
    if (init_alloc > 8 && alloc_increment > init_alloc * 2)
      alloc_increment=init_alloc*2;
  }

  if (!init_alloc)
  {
    init_alloc=alloc_increment;
    init_buffer= 0;
  }
  array->elements=0;
  array->max_element=init_alloc;
  array->alloc_increment=alloc_increment;
  array->size_of_element=element_size;
  if ((array->buffer= init_buffer))
    DBUG_RETURN(FALSE);
  /* 
    Since the dynamic array is usable even if allocation fails here malloc
    should not throw an error
  */
  if (!(array->buffer= (uchar*) my_malloc(key_memory_array_buffer,
                                          element_size*init_alloc, MYF(0))))
    array->max_element=0;
  DBUG_RETURN(FALSE);
} 
示例#4
0
static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
		       ulong max_records)
{
  uint i,recbuffer,records_in_block;

  max_records= MY_MAX(min_records, max_records);
  if (!max_records)
    max_records= 1000;			/* As good as quess as anything */
  recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
  records_in_block= max_records / 10;
  if (records_in_block < 10 && max_records)
    records_in_block= 10;
  if (!records_in_block || records_in_block*recbuffer >
      (my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
    records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
		      HP_MAX_LEVELS) / recbuffer + 1;
  block->records_in_block= records_in_block;
  block->recbuffer= recbuffer;
  block->last_allocated= 0L;

  for (i= 0; i <= HP_MAX_LEVELS; i++)
    block->level_info[i].records_under_level=
      (!i ? 1 : i == 1 ? records_in_block :
       HP_PTRS_IN_NOD * block->level_info[i - 1].records_under_level);
}
示例#5
0
static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
		       ulong max_records)
{
  uint i,recbuffer,records_in_block;

  /*
    If not min_records and max_records are given, optimize for 1000 rows
  */
  if (!min_records)
    min_records= MY_MIN(1000, max_records);
  if (!max_records)
    max_records= MY_MAX(min_records, 1000);

  /*
    We don't want too few records_in_block as otherwise the overhead of
    of the HP_PTRS block will be too notable
  */
  records_in_block= MY_MAX(1000, min_records);
  records_in_block= MY_MIN(records_in_block, max_records);
  /* If big max_records is given, allocate bigger blocks */
  records_in_block= MY_MAX(records_in_block, max_records / 10);
  /* We don't want too few blocks per row either */
  if (records_in_block < 10)
    records_in_block= 10;

  recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
  /*
    Don't allocate more than my_default_record_cache_size per level.
    The + 1 is there to ensure that we get at least 1 row per level (for
    the exceptional case of very long rows)
  */
  if (records_in_block*recbuffer >
      (my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
    records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
                       HP_MAX_LEVELS) / recbuffer + 1;
  block->records_in_block= records_in_block;
  block->recbuffer= recbuffer;
  block->last_allocated= 0L;

  for (i= 0; i <= HP_MAX_LEVELS; i++)
    block->level_info[i].records_under_level=
      (!i ? 1 : i == 1 ? records_in_block :
       HP_PTRS_IN_NOD * block->level_info[i - 1].records_under_level);
}
char *create_Custom_XML_Head (struct field_list fl)
{
	char *XML_Head = NULL;
	int i = 0, j = 0;

	XML_Head = (char *) create_Blank_XML_Head_Open ();

	if (fl.fieldCount >= 0)
	{
		for (i = 0; i < fl.fieldCount; i++)
		{
			int static_attr = 0;
			for ( j = 0; j < blank_attr_count; j++)
			{
				char *buff1 = NULL;
				char *buff2 = NULL;
				buff1 = my_strtolower( blank_attr_list[j]);
				buff2 = my_strtolower(fl.fields[i]);
				if (strncmp (buff1, buff2, MY_MAX(buff1,buff2) ) == 0 )
					static_attr = 1;
				free (buff1);
				free (buff2);
			}
			for ( j = 0; j < blank_field_count; j++)
			{
				char *buff1 = NULL;
				char *buff2 = NULL;
				buff1 = my_strtolower(blank_field_list[j]);
				buff2 = my_strtolower(fl.fields[i]);
				if (strncmp (buff1,buff2, MY_MAX(buff1, buff2)) == 0 )
					static_attr = 1;
			}
			if (static_attr == 0)
			{
				XML_Head = check_Buff_Size (XML_Head, &iXML_Head_Size, 100);
				sprintf(XML_Head + strlen(XML_Head), "<sphinx:attr name=\"%s\" type=\"%s\" />\n", fl.fields[i],fl.types[i]);
			}
		}
	}
	//close head (schema)
	XML_Head = check_Buff_Size (XML_Head, &iXML_Head_Size, 21);
	sprintf (XML_Head + strlen(XML_Head), "</sphinx:schema>\n\n");
	return XML_Head;
}
示例#7
0
int STRBLK::GetMaxLength(void)
  {
  int i, n;

  for (i = n = 0; i < Nval; i++)
    if (Strp[i])
      n = MY_MAX(n, (signed)strlen(Strp[i]));

  return n;
  } // end of GetMaxLength
static void CALL_API external_reduct_op( void* in_targ_array, void* inout_targ_array
  , int* len, RTOp_Datatype* datatype )
{
  /* inout_dot_prod += in_dot_prod */
  RTOp_value_type /* index past the size members */
    *in_targs    = (RTOp_value_type*)in_targ_array    + 3,
    *inout_targs = (RTOp_value_type*)inout_targ_array + 3;
  int i;
  for( i = 0; i < *len; ++i, inout_targs += 4, in_targs += 4 )
    *inout_targs = MY_MAX(*inout_targs,*in_targs);
}
int RTOp_reduct_max_value(
  const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
  , RTOp_ReductTarget in_targ_obj, RTOp_ReductTarget inout_targ_obj )
{
  /* inout_dot_prod += in_dot_prod */
  *((RTOp_value_type*)inout_targ_obj)
    = MY_MAX( *((RTOp_value_type*)inout_targ_obj)
          ,*((RTOp_value_type*)in_targ_obj)
      );
  return 0;
}
示例#10
0
int CHRBLK::GetMaxLength(void)
  {
  int i, n;

  for (i = n = 0; i < Nval; i++)
    if (!IsNull(i)) {
      GetValPtrEx(i);
      n = MY_MAX(n, (signed)strlen(Valp));
      } // endif null

  return n;
  } // end of GetMaxLength
示例#11
0
int TYPBLK<TYPE>::GetMaxLength(void)
  {
  char buf[64];
  int i, n, m;

  for (i = n = 0; i < Nval; i++) {
    m = sprintf(buf, Fmt, Typp[i]);
    n = MY_MAX(n, m);
    } // endfor i

  return n;
  } // end of GetMaxLength
char * check_Field_type (char *test)
{
	char *types[] = {
			"int",
			"string",
			"bigint",
			"timestamp",
			"float",
			"json"
	};

	int types_count = sizeof (types) / sizeof (char *);
	int i = 0;
	int type_index = -1;
	int test_OK = 0;
	for ( i = 0; i < types_count; i++)
	{
		char *buff1 = NULL;
		char *buff2 = NULL;
		buff1 = my_strtolower(types[i]);
		buff2 = my_strtolower(test);

		if (strncmp (buff1,buff2, MY_MAX(buff1, buff2)) == 0 )
			type_index = i;
	}

	if (type_index >= 0 && type_index < types_count)
		return types[type_index];
	if (strncmp (my_strtolower(test) ,my_strtolower("str"), MY_MAX(my_strtolower(test), my_strtolower("str"))) == 0 )
		return "string";
	if (strncmp (my_strtolower(test) ,my_strtolower("integer"), MY_MAX(my_strtolower(test), my_strtolower("integer"))) == 0 )
		return "int";
	if (strncmp (my_strtolower(test) ,my_strtolower("time"), MY_MAX(my_strtolower(test), my_strtolower("time"))) == 0 )
		return "timestamp";
	if (strncmp (my_strtolower(test) ,my_strtolower("biginteger"), MY_MAX(my_strtolower(test), my_strtolower("biginteger"))) == 0 )
		return "bigint";

	return NULL;
}
/*
  Returns a valid lvalue pointer to the element number 'idx'.
  Allocates memory if necessary.
*/
void *lf_dynarray_lvalue(LF_DYNARRAY *array, uint idx)
{
  void * ptr, * volatile * ptr_ptr= 0;
  int i;

  for (i= LF_DYNARRAY_LEVELS-1; idx < dynarray_idxes_in_prev_levels[i]; i--)
    /* no-op */;
  ptr_ptr= &array->level[i];
  idx-= dynarray_idxes_in_prev_levels[i];
  for (; i > 0; i--)
  {
    if (!(ptr= *ptr_ptr))
    {
      void *alloc= my_malloc(key_memory_lf_dynarray,
                             LF_DYNARRAY_LEVEL_LENGTH * sizeof(void *),
                             MYF(MY_WME|MY_ZEROFILL));
      if (unlikely(!alloc))
        return(NULL);
      if (my_atomic_casptr(ptr_ptr, &ptr, alloc))
        ptr= alloc;
      else
        my_free(alloc);
    }
    ptr_ptr= ((void **)ptr) + idx / dynarray_idxes_in_prev_level[i];
    idx%= dynarray_idxes_in_prev_level[i];
  }
  if (!(ptr= *ptr_ptr))
  {
    uchar *alloc, *data;
    alloc= my_malloc(key_memory_lf_dynarray,
                     LF_DYNARRAY_LEVEL_LENGTH * array->size_of_element +
                     MY_MAX(array->size_of_element, sizeof(void *)),
                     MYF(MY_WME|MY_ZEROFILL));
    if (unlikely(!alloc))
      return(NULL);
    /* reserve the space for free() address */
    data= alloc + sizeof(void *);
    { /* alignment */
      intptr mod= ((intptr)data) % array->size_of_element;
      if (mod)
        data+= array->size_of_element - mod;
    }
    ((void **)data)[-1]= alloc; /* free() will need the original pointer */
    if (my_atomic_casptr(ptr_ptr, &ptr, data))
      ptr= data;
    else
      my_free(alloc);
  }
  return ((uchar*)ptr) + array->size_of_element * idx;
}
示例#14
0
文件: fsm.c 项目: EighthByte/ophcrack
/*-------------------------------------------------------------------------*/
message_t *fsm_handle_preload(fsm_t *fsm, message_t *msg) {
  ophcrack_t *crack = fsm->crack;
  scheduler_t *sched = crack->sched;

  // If the preloading of the tables is finished, then we start
  // searching into the tables.

  if (msg->kind == msg_done) {
    msg_done_t *done = (msg_done_t*)msg->data;
    int nthreads = sched->nthreads;
    int n;    

    if (done->kind == preload_all) {
      assert(fsm->psize_curr <= fsm->psize_total);

      // Check that the tables have been correctly preloaded.

//      if (fsm->psize_curr < fsm->psize_total)
//	ophcrack_preload_check(crack);

      // This is necessary to prevent the status bar from indicating
      // that a preload task is 'waiting' if no preloading occured.

      fsm->psize_curr  = 1;
      fsm->psize_total = 1;

      // Start the work tasks.

      for (n=0; n < MY_MAX(1, nthreads-1); ++n)
	if (ophcrack_next(crack) == 0) break;

      // If no tasks have been scheduled, then we schedule a fake task
      // which will possibly trigger the 'done(all)' message if it is
      // the last one to be executed. This trick is required since the
      // brute force might still be running, therefore we should not
      // stop here, but wait until the 'done(all)' message is
      // received.

      if (n == 0) {
	ophtask_t *task = ophtask_alloc(find);
	scheduler_add(sched, task, low);
      }

      fsm->state = st_work1;
    }
  }

  return msg;
}
示例#15
0
gaspi_return_t my_fun (double * const a,
                       double * const b,
                       double * const r,
                       gaspi_state_t const state,
                       const gaspi_number_t num,
                       const gaspi_size_t elem_size,
                       const gaspi_timeout_t tout)
{
    gaspi_number_t i;

    for (i = 0; i < num; i++)
    {
        r[i] = MY_MAX(a[i], b[i]);
    }

    return GASPI_SUCCESS;
}
示例#16
0
int TDBCSV::EstimatedLength(PGLOBAL g)
  {
  if (trace)
    htrc("EstimatedLength: Fields=%d Columns=%p\n", Fields, Columns);
     
  if (!Fields) {
    PCSVCOL colp;

    for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
      if (!colp->IsSpecial() && !colp->IsVirtual())  // A true column
        Fields = MY_MAX(Fields, (int)colp->Fldnum);

    if (Columns)
      Fields++;           // Fldnum was 0 based

    } // endif Fields

  return (int)Fields;   // Number of separators if all fields are null
  } // end of Estimated Length
示例#17
0
void freeze_size(DYNAMIC_ARRAY *array)
{
  uint elements=MY_MAX(array->elements,1);

  /*
    Do nothing if we are using a static buffer
  */
  if (array->buffer == (uchar *)(array + 1))
    return;
    
  if (array->buffer && array->max_element != elements)
  {
    array->buffer=(uchar*) my_realloc(key_memory_array_buffer,
                                      array->buffer,
                                     elements*array->size_of_element,
                                     MYF(MY_WME));
    array->max_element=elements;
  }
}
示例#18
0
static int RTOp_ROp_norms_apply_op_norm_inf(
  const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
  , const int num_vecs, const struct RTOp_SubVector vecs[]
  , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
  , RTOp_ReductTarget targ_obj )
{
  RTOp_index_type        sub_dim;
  const RTOp_value_type  *v0_val;
  ptrdiff_t              v0_val_s;
  register RTOp_index_type k;
  RTOp_value_type        *norm = NULL;

  /* */
  /* Validate the input */
  /* */
  if( num_vecs != 1 )
    return RTOp_ERR_INVALID_NUM_VECS;
  if( num_targ_vecs != 0 )
    return RTOp_ERR_INVALID_NUM_TARG_VECS;
  assert(targ_obj);
  assert(vecs);

  /* */
  /* Get pointers to data */
  /* */

  /* v0 */
  sub_dim        = vecs[0].sub_dim;
  v0_val         = vecs[0].values;
  v0_val_s       = vecs[0].values_stride;

  /* */
  /* Perform the reduction */
  /* */
  norm = (RTOp_value_type*)targ_obj;
  for( k = 0; k < sub_dim; ++k, v0_val += v0_val_s )
    *norm = MY_MAX( fabs(*v0_val), (*(RTOp_value_type*)targ_obj) );  /* ||v[0]||_inf */

  return 0; /* success? */
}
示例#19
0
PSZ ARRAY::MakeArrayList(PGLOBAL g)
  {
  char   *p, *tp;
  int    i;
  size_t  z, len = 2;

  if (Type == TYPE_LIST)
    return "(?" "?" "?)";             // To be implemented

  z = MY_MAX(24, GetTypeSize(Type, Len) + 4);
  tp = (char*)PlugSubAlloc(g, NULL, z);

  for (i = 0; i < Nval; i++) {
    Value->SetValue_pvblk(Vblp, i);
    Value->Print(g, tp, z);
    len += strlen(tp);
    } // enfor i

  if (trace)
    htrc("Arraylist: len=%d\n", len);

  p = (char *)PlugSubAlloc(g, NULL, len);
  strcpy(p, "(");

  for (i = 0; i < Nval;) {
    Value->SetValue_pvblk(Vblp, i);
    Value->Print(g, tp, z);
    strcat(p, tp);
    strcat(p, (++i == Nval) ? ")" : ",");
    } // enfor i

  if (trace)
    htrc("Arraylist: newlen=%d\n", strlen(p));

  return p;
  } // end of MakeArrayList
示例#20
0
int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
	      uint columns, MI_COLUMNDEF *recinfo,
	      uint uniques, MI_UNIQUEDEF *uniquedefs,
	      MI_CREATE_INFO *ci,uint flags)
{
  register uint i,j;
  File UNINIT_VAR(dfile), UNINIT_VAR(file);
  int errpos,save_errno, create_mode= O_RDWR | O_TRUNC;
  myf create_flag;
  uint fields,length,max_key_length,packed,pointer,real_length_diff,
       key_length,info_length,key_segs,options,min_key_length_skip,
       base_pos,long_varchar_count,varchar_length,
       max_key_block_length,unique_key_parts,fulltext_keys,offset;
  uint aligned_key_start, block_length;
  uint internal_table= flags & HA_CREATE_INTERNAL_TABLE;
  ulong reclength, real_reclength,min_pack_length;
  char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
  ulong pack_reclength;
  ulonglong tot_length,max_rows, tmp;
  enum en_fieldtype type;
  MYISAM_SHARE share;
  MI_KEYDEF *keydef,tmp_keydef;
  MI_UNIQUEDEF *uniquedef;
  HA_KEYSEG *keyseg,tmp_keyseg;
  MI_COLUMNDEF *rec;
  ulong *rec_per_key_part;
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
  MI_CREATE_INFO tmp_create_info;
  DBUG_ENTER("mi_create");
  DBUG_PRINT("enter", ("keys: %u  columns: %u  uniques: %u  flags: %u",
                      keys, columns, uniques, flags));

  if (!ci)
  {
    memset(&tmp_create_info, 0, sizeof(tmp_create_info));
    ci=&tmp_create_info;
  }

  if (keys + uniques > MI_MAX_KEY || columns == 0)
  {
    DBUG_RETURN(my_errno=HA_WRONG_CREATE_OPTION);
  }

  errpos=0;
  options=0;
  memset(&share, 0, sizeof(share));

  if (flags & HA_DONT_TOUCH_DATA)
  {
    if (!(ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD))
      options=ci->old_options &
	(HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD |
	 HA_OPTION_READ_ONLY_DATA | HA_OPTION_CHECKSUM |
	 HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
    else
      options=ci->old_options &
	(HA_OPTION_CHECKSUM | HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE);
  }

  if (ci->reloc_rows > ci->max_rows)
    ci->reloc_rows=ci->max_rows;		/* Check if wrong parameter */

  if (!(rec_per_key_part=
	(ulong*) my_malloc((keys + uniques)*MI_MAX_KEY_SEG*sizeof(long),
			   MYF(MY_WME | MY_ZEROFILL))))
    DBUG_RETURN(my_errno);

	/* Start by checking fields and field-types used */

  reclength=varchar_length=long_varchar_count=packed=
    min_pack_length=pack_reclength=0;
  for (rec=recinfo, fields=0 ;
       fields != columns ;
       rec++,fields++)
  {
    reclength+=rec->length;
    if ((type=(enum en_fieldtype) rec->type) != FIELD_NORMAL &&
	type != FIELD_CHECK)
    {
      packed++;
      if (type == FIELD_BLOB)
      {
	share.base.blobs++;
	if (pack_reclength != INT_MAX32)
	{
	  if (rec->length == 4+portable_sizeof_char_ptr)
	    pack_reclength= INT_MAX32;
	  else
	    pack_reclength+=(1 << ((rec->length-portable_sizeof_char_ptr)*8)); /* Max blob length */
	}
      }
      else if (type == FIELD_SKIP_PRESPACE ||
	       type == FIELD_SKIP_ENDSPACE)
      {
	if (pack_reclength != INT_MAX32)
	  pack_reclength+= rec->length > 255 ? 2 : 1;
	min_pack_length++;
      }
      else if (type == FIELD_VARCHAR)
      {
	varchar_length+= rec->length-1;          /* Used for min_pack_length */
	packed--;
	pack_reclength++;
        min_pack_length++;
        /* We must test for 257 as length includes pack-length */
        if (test(rec->length >= 257))
	{
	  long_varchar_count++;
	  pack_reclength+= 2;			/* May be packed on 3 bytes */
	}
      }
      else if (type != FIELD_SKIP_ZERO)
      {
	min_pack_length+=rec->length;
	packed--;				/* Not a pack record type */
      }
    }
    else					/* FIELD_NORMAL */
      min_pack_length+=rec->length;
  }
  if ((packed & 7) == 1)
  {				/* Bad packing, try to remove a zero-field */
    while (rec != recinfo)
    {
      rec--;
      if (rec->type == (int) FIELD_SKIP_ZERO && rec->length == 1)
      {
        /*
          NOTE1: here we change a field type FIELD_SKIP_ZERO ->
          FIELD_NORMAL
        */
	rec->type=(int) FIELD_NORMAL;
	packed--;
	min_pack_length++;
	break;
      }
    }
  }

  if (packed || (flags & HA_PACK_RECORD))
    options|=HA_OPTION_PACK_RECORD;	/* Must use packed records */
  /* We can't use checksum with static length rows */
  if (!(options & HA_OPTION_PACK_RECORD))
    options&= ~HA_OPTION_CHECKSUM;
  if (!(options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
    min_pack_length+= varchar_length;
  if (flags & HA_CREATE_TMP_TABLE)
  {
    options|= HA_OPTION_TMP_TABLE;
    create_mode|= O_EXCL | O_NOFOLLOW;
  }
  if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
  {
    options|= HA_OPTION_CHECKSUM;
    min_pack_length++;
  }
  if (flags & HA_CREATE_DELAY_KEY_WRITE)
    options|= HA_OPTION_DELAY_KEY_WRITE;
  if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
    options|= HA_OPTION_RELIES_ON_SQL_LAYER;

  packed=(packed+7)/8;
  if (pack_reclength != INT_MAX32)
    pack_reclength+= reclength+packed +
      test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_OPTION_PACK_RECORD));
  min_pack_length+=packed;

  if (!ci->data_file_length && ci->max_rows)
  {
    if (pack_reclength == INT_MAX32 ||
             (~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength)
      ci->data_file_length= ~(ulonglong) 0;
    else
      ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength;
  }
  else if (!ci->max_rows)
    ci->max_rows=(ha_rows) (ci->data_file_length/(min_pack_length +
					 ((options & HA_OPTION_PACK_RECORD) ?
					  3 : 0)));

  if (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD))
    pointer=mi_get_pointer_length(ci->data_file_length,myisam_data_pointer_size);
  else
    pointer=mi_get_pointer_length(ci->max_rows,myisam_data_pointer_size);
  if (!(max_rows=(ulonglong) ci->max_rows))
    max_rows= ((((ulonglong) 1 << (pointer*8)) -1) / min_pack_length);


  real_reclength=reclength;
  if (!(options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_PACK_RECORD)))
  {
    if (reclength <= pointer)
      reclength=pointer+1;		/* reserve place for delete link */
  }
  else
    reclength+= long_varchar_count;	/* We need space for varchar! */

  max_key_length=0; tot_length=0 ; key_segs=0;
  fulltext_keys=0;
  max_key_block_length=0;
  share.state.rec_per_key_part=rec_per_key_part;
  share.state.key_root=key_root;
  share.state.key_del=key_del;
  if (uniques)
  {
    max_key_block_length= myisam_block_size;
    max_key_length=	  MI_UNIQUE_HASH_LENGTH + pointer;
  }

  for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
  {

    share.state.key_root[i]= HA_OFFSET_ERROR;
    min_key_length_skip=length=real_length_diff=0;
    key_length=pointer;
    if (keydef->flag & HA_SPATIAL)
    {
#ifdef HAVE_SPATIAL
      /* BAR TODO to support 3D and more dimensions in the future */
      uint sp_segs=SPDIMS*2;
      keydef->flag=HA_SPATIAL;

      if (flags & HA_DONT_TOUCH_DATA)
      {
        /*
           called by myisamchk - i.e. table structure was taken from
           MYI file and SPATIAL key *does have* additional sp_segs keysegs.
           keydef->seg here points right at the GEOMETRY segment,
           so we only need to decrease keydef->keysegs.
           (see recreate_table() in mi_check.c)
        */
        keydef->keysegs-=sp_segs-1;
      }

      for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ;
	   j++, keyseg++)
      {
        if (keyseg->type != HA_KEYTYPE_BINARY &&
	    keyseg->type != HA_KEYTYPE_VARBINARY1 &&
            keyseg->type != HA_KEYTYPE_VARBINARY2)
        {
          my_errno=HA_WRONG_CREATE_OPTION;
          goto err_no_lock;
        }
      }
      keydef->keysegs+=sp_segs;
      key_length+=SPLEN*sp_segs;
      length++;                              /* At least one length byte */
      min_key_length_skip+=SPLEN*2*SPDIMS;
#else
      my_errno= HA_ERR_UNSUPPORTED;
      goto err_no_lock;
#endif /*HAVE_SPATIAL*/
    }
    else if (keydef->flag & HA_FULLTEXT)
    {
      keydef->flag=HA_FULLTEXT | HA_PACK_KEY | HA_VAR_LENGTH_KEY;
      options|=HA_OPTION_PACK_KEYS;             /* Using packed keys */

      for (j=0, keyseg=keydef->seg ; (int) j < keydef->keysegs ;
	   j++, keyseg++)
      {
        if (keyseg->type != HA_KEYTYPE_TEXT &&
	    keyseg->type != HA_KEYTYPE_VARTEXT1 &&
            keyseg->type != HA_KEYTYPE_VARTEXT2)
        {
          my_errno=HA_WRONG_CREATE_OPTION;
          goto err_no_lock;
        }
        if (!(keyseg->flag & HA_BLOB_PART) &&
	    (keyseg->type == HA_KEYTYPE_VARTEXT1 ||
             keyseg->type == HA_KEYTYPE_VARTEXT2))
        {
          /* Make a flag that this is a VARCHAR */
          keyseg->flag|= HA_VAR_LENGTH_PART;
          /* Store in bit_start number of bytes used to pack the length */
          keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1)?
                              1 : 2);
        }
      }

      fulltext_keys++;
      key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN;
      length++;                              /* At least one length byte */
      min_key_length_skip+=HA_FT_MAXBYTELEN;
      real_length_diff=HA_FT_MAXBYTELEN-FT_MAX_WORD_LEN_FOR_SORT;
    }
    else
    {
      /* Test if prefix compression */
      if (keydef->flag & HA_PACK_KEY)
      {
	/* Can't use space_compression on number keys */
	if ((keydef->seg[0].flag & HA_SPACE_PACK) &&
	    keydef->seg[0].type == (int) HA_KEYTYPE_NUM)
	  keydef->seg[0].flag&= ~HA_SPACE_PACK;

	/* Only use HA_PACK_KEY when first segment is a variable length key */
	if (!(keydef->seg[0].flag & (HA_SPACE_PACK | HA_BLOB_PART |
				     HA_VAR_LENGTH_PART)))
	{
	  /* pack relative to previous key */
	  keydef->flag&= ~HA_PACK_KEY;
	  keydef->flag|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
	}
	else
	{
	  keydef->seg[0].flag|=HA_PACK_KEY;	/* for easyer intern test */
	  keydef->flag|=HA_VAR_LENGTH_KEY;
	  options|=HA_OPTION_PACK_KEYS;		/* Using packed keys */
	}
      }
      if (keydef->flag & HA_BINARY_PACK_KEY)
	options|=HA_OPTION_PACK_KEYS;		/* Using packed keys */

      if (keydef->flag & HA_AUTO_KEY && ci->with_auto_increment)
	share.base.auto_key=i+1;
      for (j=0, keyseg=keydef->seg ; j < keydef->keysegs ; j++, keyseg++)
      {
	/* numbers are stored with high by first to make compression easier */
	switch (keyseg->type) {
	case HA_KEYTYPE_SHORT_INT:
	case HA_KEYTYPE_LONG_INT:
	case HA_KEYTYPE_FLOAT:
	case HA_KEYTYPE_DOUBLE:
	case HA_KEYTYPE_USHORT_INT:
	case HA_KEYTYPE_ULONG_INT:
	case HA_KEYTYPE_LONGLONG:
	case HA_KEYTYPE_ULONGLONG:
	case HA_KEYTYPE_INT24:
	case HA_KEYTYPE_UINT24:
	case HA_KEYTYPE_INT8:
	  keyseg->flag|= HA_SWAP_KEY;
          break;
        case HA_KEYTYPE_VARTEXT1:
        case HA_KEYTYPE_VARTEXT2:
        case HA_KEYTYPE_VARBINARY1:
        case HA_KEYTYPE_VARBINARY2:
          if (!(keyseg->flag & HA_BLOB_PART))
          {
            /* Make a flag that this is a VARCHAR */
            keyseg->flag|= HA_VAR_LENGTH_PART;
            /* Store in bit_start number of bytes used to pack the length */
            keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 ||
                                 keyseg->type == HA_KEYTYPE_VARBINARY1) ?
                                1 : 2);
          }
          break;
	default:
	  break;
	}
	if (keyseg->flag & HA_SPACE_PACK)
	{
          DBUG_ASSERT(!(keyseg->flag & HA_VAR_LENGTH_PART));
	  keydef->flag |= HA_SPACE_PACK_USED | HA_VAR_LENGTH_KEY;
	  options|=HA_OPTION_PACK_KEYS;		/* Using packed keys */
	  length++;				/* At least one length byte */
	  min_key_length_skip+=keyseg->length;
	  if (keyseg->length >= 255)
	  {					/* prefix may be 3 bytes */
	    min_key_length_skip+=2;
	    length+=2;
	  }
	}
	if (keyseg->flag & (HA_VAR_LENGTH_PART | HA_BLOB_PART))
	{
          DBUG_ASSERT(!test_all_bits(keyseg->flag,
                                    (HA_VAR_LENGTH_PART | HA_BLOB_PART)));
	  keydef->flag|=HA_VAR_LENGTH_KEY;
	  length++;				/* At least one length byte */
	  options|=HA_OPTION_PACK_KEYS;		/* Using packed keys */
	  min_key_length_skip+=keyseg->length;
	  if (keyseg->length >= 255)
	  {					/* prefix may be 3 bytes */
	    min_key_length_skip+=2;
	    length+=2;
	  }
	}
	key_length+= keyseg->length;
	if (keyseg->null_bit)
	{
	  key_length++;
	  options|=HA_OPTION_PACK_KEYS;
	  keyseg->flag|=HA_NULL_PART;
	  keydef->flag|=HA_VAR_LENGTH_KEY | HA_NULL_PART_KEY;
	}
      }
    } /* if HA_FULLTEXT */
    key_segs+=keydef->keysegs;
    if (keydef->keysegs > MI_MAX_KEY_SEG)
    {
      my_errno=HA_WRONG_CREATE_OPTION;
      goto err_no_lock;
    }
    /*
      key_segs may be 0 in the case when we only want to be able to
      add on row into the table. This can happen with some DISTINCT queries
      in MySQL
    */
    if ((keydef->flag & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME &&
	key_segs)
      share.state.rec_per_key_part[key_segs-1]=1L;
    length+=key_length;
    /* Get block length for key, if defined by user */
    block_length= (keydef->block_length ? 
                   my_round_up_to_next_power(keydef->block_length) :
                   myisam_block_size);
    block_length= MY_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
    block_length= MY_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);

    keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
                                                 pointer,MI_MAX_KEYPTR_SIZE,
                                                 block_length);
    if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
        length >= MI_MAX_KEY_BUFF)
    {
      my_errno=HA_WRONG_CREATE_OPTION;
      goto err_no_lock;
    }
    set_if_bigger(max_key_block_length,keydef->block_length);
    keydef->keylength= (uint16) key_length;
    keydef->minlength= (uint16) (length-min_key_length_skip);
    keydef->maxlength= (uint16) length;

    if (length > max_key_length)
      max_key_length= length;
    tot_length+= (max_rows/(ulong) (((uint) keydef->block_length-5)/
				    (length*2)))*
      (ulong) keydef->block_length;
  }
  for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
    key_del[i]=HA_OFFSET_ERROR;

  unique_key_parts=0;
  for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++)
  {
    uniquedef->key=keys+i;
    unique_key_parts+=uniquedef->keysegs;
    share.state.key_root[keys+i]= HA_OFFSET_ERROR;
    tot_length+= (max_rows/(ulong) (((uint) myisam_block_size-5)/
                         ((MI_UNIQUE_HASH_LENGTH + pointer)*2)))*
                         (ulong) myisam_block_size;
  }
  keys+=uniques;				/* Each unique has 1 key */
  key_segs+=uniques;				/* Each unique has 1 key seg */

  base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
	    max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH*
	    MI_STATE_KEYBLOCK_SIZE+
	    key_segs*MI_STATE_KEYSEG_SIZE);
  info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
			       keys * MI_KEYDEF_SIZE+
			       uniques * MI_UNIQUEDEF_SIZE +
			       (key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
			       columns*MI_COLUMNDEF_SIZE);
  DBUG_PRINT("info", ("info_length: %u", info_length));
  /* There are only 16 bits for the total header length. */
  if (info_length > 65535)
  {
    my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
                    "indexes and/or unique constraints.",
                    MYF(0), name + dirname_length(name));
    my_errno= HA_WRONG_CREATE_OPTION;
    goto err_no_lock;
  }

  bmove(share.state.header.file_version,(uchar*) myisam_file_magic,4);
  ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
			HA_OPTION_COMPRESS_RECORD |
			HA_OPTION_TEMP_COMPRESS_RECORD: 0);
  mi_int2store(share.state.header.options,ci->old_options);
  mi_int2store(share.state.header.header_length,info_length);
  mi_int2store(share.state.header.state_info_length,MI_STATE_INFO_SIZE);
  mi_int2store(share.state.header.base_info_length,MI_BASE_INFO_SIZE);
  mi_int2store(share.state.header.base_pos,base_pos);
  share.state.header.language= (ci->language ?
				ci->language : default_charset_info->number);
  share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;

  share.state.dellink = HA_OFFSET_ERROR;
  share.state.process=	(ulong) getpid();
  share.state.unique=	(ulong) 0;
  share.state.update_count=(ulong) 0;
  share.state.version=	(ulong) time((time_t*) 0);
  share.state.sortkey=  (ushort) ~0;
  share.state.auto_increment=ci->auto_increment;
  share.options=options;
  share.base.rec_reflength=pointer;
  /* Get estimate for index file length (this may be wrong for FT keys) */
  tmp= (tot_length + max_key_block_length * keys *
	MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH;
  /*
    use maximum of key_file_length we calculated and key_file_length value we
    got from MYI file header (see also myisampack.c:save_state)
  */
  share.base.key_reflength=
    mi_get_pointer_length(MY_MAX(ci->key_file_length, tmp), 3);
  share.base.keys= share.state.header.keys= keys;
  share.state.header.uniques= uniques;
  share.state.header.fulltext_keys= fulltext_keys;
  mi_int2store(share.state.header.key_parts,key_segs);
  mi_int2store(share.state.header.unique_key_parts,unique_key_parts);

  mi_set_all_keys_active(share.state.key_map, keys);
  aligned_key_start= my_round_up_to_next_power(max_key_block_length ?
                                               max_key_block_length :
                                               myisam_block_size);

  share.base.keystart= share.state.state.key_file_length=
    MY_ALIGN(info_length, aligned_key_start);
  share.base.max_key_block_length=max_key_block_length;
  share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
  share.base.records=ci->max_rows;
  share.base.reloc=  ci->reloc_rows;
  share.base.reclength=real_reclength;
  share.base.pack_reclength=reclength+ test(options & HA_OPTION_CHECKSUM);
  share.base.max_pack_length=pack_reclength;
  share.base.min_pack_length=min_pack_length;
  share.base.pack_bits=packed;
  share.base.fields=fields;
  share.base.pack_fields=packed;

  /* max_data_file_length and max_key_file_length are recalculated on open */
  if (options & HA_OPTION_TMP_TABLE)
    share.base.max_data_file_length=(my_off_t) ci->data_file_length;

  share.base.min_block_length=
    (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
     ! share.base.blobs) ?
    MY_MAX(share.base.pack_reclength, MI_MIN_BLOCK_LENGTH) :
    MI_EXTEND_BLOCK_LENGTH;
  if (! (flags & HA_DONT_TOUCH_DATA))
    share.state.create_time= (long) time((time_t*) 0);

  if (!internal_table)
    mysql_mutex_lock(&THR_LOCK_myisam);

  /*
    NOTE: For test_if_reopen() we need a real path name. Hence we need
    MY_RETURN_REAL_PATH for every fn_format(filename, ...).
  */
  if (ci->index_file_name)
  {
    char *iext= strrchr(ci->index_file_name, '.');
    int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
    if (options & HA_OPTION_TMP_TABLE)
    {
      char *path;
      /* chop off the table name, tempory tables use generated name */
      if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
        *path= '\0';
      fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
                MY_REPLACE_DIR | MY_UNPACK_FILENAME |
                MY_RETURN_REAL_PATH | MY_APPEND_EXT);
    }
    else
    {
      fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
                MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
                (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
    }
    fn_format(linkname, name, "", MI_NAME_IEXT,
              MY_UNPACK_FILENAME|MY_APPEND_EXT);
    linkname_ptr=linkname;
    /*
      Don't create the table if the link or file exists to ensure that one
      doesn't accidently destroy another table.
    */
    create_flag=0;
  }
  else
  {
    char *iext= strrchr(name, '.');
    int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
    fn_format(filename, name, "", MI_NAME_IEXT,
              MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
              (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
    linkname_ptr=0;
    /* Replace the current file */
    create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
  }

  /*
    If a MRG_MyISAM table is in use, the mapped MyISAM tables are open,
    but no entry is made in the table cache for them.
    A TRUNCATE command checks for the table in the cache only and could
    be fooled to believe, the table is not open.
    Pull the emergency brake in this situation. (Bug #8306)

    NOTE: The filename is compared against unique_file_name of every
    open table. Hence we need a real path here.
  */
  if (!internal_table && test_if_reopen(filename))
  {
    my_printf_error(0, "MyISAM table '%s' is in use "
                    "(most likely by a MERGE table). Try FLUSH TABLES.",
                    MYF(0), name + dirname_length(name));
    my_errno= HA_ERR_TABLE_EXIST;
    goto err;
  }

  if ((file= mysql_file_create_with_symlink(mi_key_file_kfile,
                                            linkname_ptr, filename, 0,
                                            create_mode,
                                            MYF(MY_WME | create_flag))) < 0)
    goto err;
  errpos=1;

  if (!(flags & HA_DONT_TOUCH_DATA))
  {
    {
      if (ci->data_file_name)
      {
        char *dext= strrchr(ci->data_file_name, '.');
        int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);

        if (options & HA_OPTION_TMP_TABLE)
        {
          char *path;
          /* chop off the table name, tempory tables use generated name */
          if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
            *path= '\0';
          fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
                    MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
        }
        else
        {
          fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
                    MY_UNPACK_FILENAME |
                    (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
        }

	fn_format(linkname, name, "",MI_NAME_DEXT,
	          MY_UNPACK_FILENAME | MY_APPEND_EXT);
	linkname_ptr=linkname;
	create_flag=0;
      }
      else
      {
	fn_format(filename,name,"", MI_NAME_DEXT,
	          MY_UNPACK_FILENAME | MY_APPEND_EXT);
	linkname_ptr=0;
        create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD;
      }
      if ((dfile=
           mysql_file_create_with_symlink(mi_key_file_dfile,
                                          linkname_ptr, filename, 0,
                                          create_mode,
                                          MYF(MY_WME | create_flag))) < 0)
	goto err;
    }
    errpos=3;
  }

  DBUG_PRINT("info", ("write state info and base info"));
  if (mi_state_info_write(file, &share.state, 2) ||
      mi_base_info_write(file, &share.base))
    goto err;
#ifndef DBUG_OFF
  if ((uint) mysql_file_tell(file, MYF(0)) != base_pos + MI_BASE_INFO_SIZE)
  {
    uint pos=(uint) mysql_file_tell(file, MYF(0));
    DBUG_PRINT("warning",("base_length: %d  != used_length: %d",
			  base_pos+ MI_BASE_INFO_SIZE, pos));
  }
#endif

  /* Write key and keyseg definitions */
  DBUG_PRINT("info", ("write key and keyseg definitions"));
  for (i=0 ; i < share.base.keys - uniques; i++)
  {
    uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0;

    if (mi_keydef_write(file, &keydefs[i]))
      goto err;
    for (j=0 ; j < keydefs[i].keysegs-sp_segs ; j++)
      if (mi_keyseg_write(file, &keydefs[i].seg[j]))
       goto err;
#ifdef HAVE_SPATIAL
    for (j=0 ; j < sp_segs ; j++)
    {
      HA_KEYSEG sseg;
      sseg.type=SPTYPE;
      sseg.language= 7;                         /* Binary */
      sseg.null_bit=0;
      sseg.bit_start=0;
      sseg.bit_end=0;
      sseg.bit_length= 0;
      sseg.bit_pos= 0;
      sseg.length=SPLEN;
      sseg.null_pos=0;
      sseg.start=j*SPLEN;
      sseg.flag= HA_SWAP_KEY;
      if (mi_keyseg_write(file, &sseg))
        goto err;
    }
#endif
  }
  /* Create extra keys for unique definitions */
  offset= real_reclength - uniques * MI_UNIQUE_HASH_LENGTH;
  memset(&tmp_keydef, 0, sizeof(tmp_keydef));
  memset(&tmp_keyseg, 0, sizeof(tmp_keyseg));
  for (i=0; i < uniques ; i++)
  {
    tmp_keydef.keysegs=1;
    tmp_keydef.flag=		HA_UNIQUE_CHECK;
    tmp_keydef.block_length=	(uint16)myisam_block_size;
    tmp_keydef.keylength=	MI_UNIQUE_HASH_LENGTH + pointer;
    tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
    tmp_keyseg.type=		MI_UNIQUE_HASH_TYPE;
    tmp_keyseg.length=		MI_UNIQUE_HASH_LENGTH;
    tmp_keyseg.start=		offset;
    offset+=			MI_UNIQUE_HASH_LENGTH;
    if (mi_keydef_write(file,&tmp_keydef) ||
	mi_keyseg_write(file,(&tmp_keyseg)))
      goto err;
  }

  /* Save unique definition */
  DBUG_PRINT("info", ("write unique definitions"));
  for (i=0 ; i < share.state.header.uniques ; i++)
  {
    HA_KEYSEG *keyseg_end;
    keyseg= uniquedefs[i].seg;
    if (mi_uniquedef_write(file, &uniquedefs[i]))
      goto err;
    for (keyseg= uniquedefs[i].seg, keyseg_end= keyseg+ uniquedefs[i].keysegs;
         keyseg < keyseg_end;
         keyseg++)
    {
      switch (keyseg->type) {
      case HA_KEYTYPE_VARTEXT1:
      case HA_KEYTYPE_VARTEXT2:
      case HA_KEYTYPE_VARBINARY1:
      case HA_KEYTYPE_VARBINARY2:
        if (!(keyseg->flag & HA_BLOB_PART))
        {
          keyseg->flag|= HA_VAR_LENGTH_PART;
          keyseg->bit_start= ((keyseg->type == HA_KEYTYPE_VARTEXT1 ||
                               keyseg->type == HA_KEYTYPE_VARBINARY1) ?
                              1 : 2);
        }
        break;
      default:
        break;
      }
      if (mi_keyseg_write(file, keyseg))
	goto err;
    }
  }
  DBUG_PRINT("info", ("write field definitions"));
  for (i=0 ; i < share.base.fields ; i++)
    if (mi_recinfo_write(file, &recinfo[i]))
      goto err;

#ifndef DBUG_OFF
  if ((uint) mysql_file_tell(file, MYF(0)) != info_length)
  {
    uint pos= (uint) mysql_file_tell(file, MYF(0));
    DBUG_PRINT("warning",("info_length: %d  != used_length: %d",
			  info_length, pos));
  }
#endif

	/* Enlarge files */
  DBUG_PRINT("info", ("enlarge to keystart: %lu", (ulong) share.base.keystart));
  if (mysql_file_chsize(file, (ulong) share.base.keystart, 0, MYF(0)))
    goto err;

  if (! (flags & HA_DONT_TOUCH_DATA))
  {
#ifdef USE_RELOC
    if (mysql_file_chsize(dfile, share.base.min_pack_length*ci->reloc_rows,
                          0, MYF(0)))
      goto err;
#endif
    errpos=2;
    if (mysql_file_close(dfile, MYF(0)))
      goto err;
  }
  errpos=0;
  if (!internal_table)
    mysql_mutex_unlock(&THR_LOCK_myisam);
  if (mysql_file_close(file, MYF(0)))
    goto err_no_lock;
  my_free(rec_per_key_part);
  DBUG_RETURN(0);

err:
  if (!internal_table)
    mysql_mutex_unlock(&THR_LOCK_myisam);

err_no_lock:
  save_errno=my_errno;
  switch (errpos) {
  case 3:
    (void) mysql_file_close(dfile, MYF(0));
    /* fall through */
  case 2:
  if (! (flags & HA_DONT_TOUCH_DATA))
    mysql_file_delete_with_symlink(mi_key_file_dfile,
                                   fn_format(filename, name, "", MI_NAME_DEXT,
                                             MY_UNPACK_FILENAME | MY_APPEND_EXT),
                                   MYF(0));
    /* fall through */
  case 1:
    (void) mysql_file_close(file, MYF(0));
    if (! (flags & HA_DONT_TOUCH_DATA))
      mysql_file_delete_with_symlink(mi_key_file_kfile,
                                     fn_format(filename, name, "", MI_NAME_IEXT,
                                               MY_UNPACK_FILENAME | MY_APPEND_EXT),
                                     MYF(0));
  }
  my_free(rec_per_key_part);
  DBUG_RETURN(my_errno=save_errno);		/* return the fatal errno */
}
void PR9774(int *s) {
    for (int i = 0; i < MY_MAX(2, 3); i++) // no-warning
        s[i] = 0;
}
示例#22
0
bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col, 
                       const char *ocr, const char *rank)
  {
  char   *pn, *colist;
  int     i, k, m, n = 0, c = 0, j = qrp->Nblin;
  bool    rk, b = false;
  PCOLRES crp;

  if (!col || !*col) {
    strcpy(g->Message, "Missing colist");
    return true;
    } // endif col

  // Prepare the column list
  colist = PlugDup(g, col);
  m = PrepareColist(colist);

  if ((rk = (rank && *rank))) {
    if (m == 1) {
      strcpy(g->Message, "Cannot handle one column colist and rank");
      return true;
      } // endif m

    for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
      n = MY_MAX(n, (signed)strlen(pn));

    } // endif k
             
  // Default occur column name is the 1st colist column name
  if (!ocr || !*ocr)
    ocr = colist;

  /**********************************************************************/
  /*  Replace the columns of the colist by the rank and occur columns.  */
  /**********************************************************************/
  for (i = 0; i < qrp->Nblin; i++) {
    for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
      if (!stricmp(pn, qrp->Colresp->Kdata->GetCharValue(i)))
        break;

    if (k < m) {
      // This column belongs to colist
      if (rk) {
        // Place the rank column here
        for (crp = qrp->Colresp; crp; crp = crp->Next)
          switch (crp->Fld) {
            case FLD_NAME:  crp->Kdata->SetValue((char*)rank, i); break;
            case FLD_TYPE:  crp->Kdata->SetValue(TYPE_STRING, i); break;
            case FLD_PREC:  crp->Kdata->SetValue(n, i);           break;
            case FLD_SCALE: crp->Kdata->SetValue(0, i);           break;
            case FLD_NULL:  crp->Kdata->SetValue(0, i);           break;
            case FLD_REM:   crp->Kdata->Reset(i);                 break;
            default: ;   // Ignored by CONNECT
            } // endswich Fld
    
        rk = false;
      } else if (!b) {
        // First remaining listed column, will be the occur column
        for (crp = qrp->Colresp; crp; crp = crp->Next)
          switch (crp->Fld) {
            case FLD_NAME: crp->Kdata->SetValue((char*)ocr, i); break;
            case FLD_REM:  crp->Kdata->Reset(i);                break;
            default: ;   // Nothing to do
            } // endswich Fld
    
        b = true;
      } else if (j == qrp->Nblin)
        j = i;     // Column to remove

      c++;
    } else if (j < i) {
      // Move this column in empty spot
      for (crp = qrp->Colresp; crp; crp = crp->Next)
        crp->Kdata->Move(i, j);

      j++;
    } // endif k

    } // endfor i

  // Check whether all columns of the list where found
  if (c < m) {
    strcpy(g->Message, "Some colist columns are not in the source table");
    return true;
    } // endif crp

  /**********************************************************************/
  /*  Set the number of columns of the table.                           */
  /**********************************************************************/
  qrp->Nblin = j;
  return false;
  } // end of OcrColumns
示例#23
0
bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col, 
                       const char *ocr, const char *rank)
  {
  char   *pn, *colist;
  int     i, k, m, n = 0, c = 0;
  bool    rk, b = false;
  PCOLRES crp, rcrp, *pcrp;

  if (!col || !*col) {
    strcpy(g->Message, "Missing colist");
    return true;
    } // endif col

  // Prepare the column list
  colist = PlugDup(g, col);
  m = PrepareColist(colist);

  if ((rk = (rank && *rank)))
    for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
      n = MY_MAX(n, (signed)strlen(pn));
             
  // Default occur column name is the 1st colist column name
  if (!ocr || !*ocr)
    ocr = colist;

  /**********************************************************************/
  /*  Replace the columns of the colist by the rank and occur columns.  */
  /**********************************************************************/
  for (i = 0, pcrp = &qrp->Colresp; crp = *pcrp; ) {
    for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1))
      if (!stricmp(pn, crp->Name))
        break;

    if (k < m) {
      // This column belongs to colist
      c++;

      if (!b) {
        if (rk) {
          // Add the rank column here
          rcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
          memset(rcrp, 0, sizeof(COLRES));
          rcrp->Next = crp;
          rcrp->Name = (char*)rank;
          rcrp->Type = TYPE_STRING;
          rcrp->Length = n;
          rcrp->Ncol = ++i;
          *pcrp = rcrp;
        } // endif rk

        // First remaining listed column, will be the occur column
        crp->Name = (char*)ocr;
        b = true;
      } else {
        *pcrp = crp->Next;     // Remove this column
        continue;
      } // endif b

      } // endif k

    crp->Ncol = ++i;
    pcrp = &crp->Next;
    } // endfor pcrp

  // Check whether all columns of the list where found
  if (c < m) {
    strcpy(g->Message, "Some colist columns are not in the source table");
    return true;
    } // endif crp

  /**********************************************************************/
  /*  Set the number of columns of the table.                           */
  /**********************************************************************/
  qrp->Nblin = i;
  return false;
  } // end of OcrSrcCols
示例#24
0
PQRYRES WMIColumns(PGLOBAL g, char *nsp, char *cls, bool info)
  {
  static int  buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
                          TYPE_INT,   TYPE_INT, TYPE_SHORT};
  static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE,   FLD_TYPENAME,
                          FLD_PREC, FLD_LENGTH, FLD_SCALE};
  static unsigned int len, length[] = {0, 6, 8, 10, 10, 6};
  int     i = 0, n = 0, ncol = sizeof(buftyp) / sizeof(int);
  int     lng, typ, prec;
  LONG    low, upp;
  BSTR    propname;
  VARIANT val;
  CIMTYPE type;
  HRESULT res;
  PWMIUT  wp; 
  SAFEARRAY *prnlist = NULL;
  PQRYRES qrp = NULL;
  PCOLRES crp;

  if (!info) {
    /*******************************************************************/
    /*  Initialize WMI if not done yet.                                */
    /*******************************************************************/
    if (!(wp = InitWMI(g, nsp, cls)))
      return NULL;

    /*******************************************************************/
    /*  Get the number of properties to return.                        */
    /*******************************************************************/
    res = wp->Cobj->Get(bstr_t("__Property_Count"), 0, &val, NULL, NULL);

    if (FAILED(res)) {
      sprintf(g->Message, "failed Get(__Property_Count) res=%d\n", res);
      goto err;
      }  // endif res

    if (!(n = val.lVal)) {
      sprintf(g->Message, "Class %s in %s has no properties\n",
                          cls, nsp);
      goto err;
      }  // endif res

    /*******************************************************************/
    /*  Get max property name length.                                  */
    /*******************************************************************/
    res = wp->Cobj->GetNames(NULL, 
          WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, 
          NULL, &prnlist);

    if (FAILED(res)) {
      sprintf(g->Message, "failed GetNames res=%d\n", res);
      goto err;
      }  // endif res

    res = SafeArrayGetLBound(prnlist, 1, &low);
    res = SafeArrayGetUBound(prnlist, 1, &upp);

    for (long i = low; i <= upp; i++) {
      // Get this property name.
      res = SafeArrayGetElement(prnlist, &i, &propname);

      if (FAILED(res)) {
        sprintf(g->Message, "failed GetArrayElement res=%d\n", res);
        goto err;
        }  // endif res

      len = (unsigned)SysStringLen(propname);
      length[0] = MY_MAX(length[0], len);
      } // enfor i

    res = SafeArrayDestroy(prnlist);
  } else
    length[0] = 128;

  /*********************************************************************/
  /*  Allocate the structures used to refer to the result set.         */
  /*********************************************************************/
  qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
                          buftyp, fldtyp, length, false, true);

  if (info || !qrp)
    return qrp;

  /*********************************************************************/
  /*  Now get the results into blocks.                                 */
  /*********************************************************************/
  res = wp->Cobj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);

  if (FAILED(res)) {
    sprintf(g->Message, "failed BeginEnumeration hr=%d\n", res);
    qrp = NULL;
    goto err;
    }  // endif hr

  while (TRUE) {
    res = wp->Cobj->Next(0, &propname, &val, &type, NULL);

    if (FAILED(res)) {
      sprintf(g->Message, "failed getting Next hr=%d\n", res);
      qrp = NULL;
      goto err;
    }  else if (res == WBEM_S_NO_MORE_DATA) {
      VariantClear(&val);
      break;
    } // endif res

    if (i >= n)
      break;                 // Should never happen
    else
      prec = 0;

    switch (type) {
      case CIM_STRING:
        typ = TYPE_STRING;
        lng = 255;
        prec = 1;   // Case insensitive
        break;
      case CIM_SINT32:                          
      case CIM_UINT32:
      case CIM_BOOLEAN:
        typ = TYPE_INT;
        lng = 11;
        break;
      case CIM_SINT8:
      case CIM_UINT8:
        typ = TYPE_TINY;
        lng = 4;
        break;
      case CIM_SINT16:
      case CIM_UINT16:
        typ = TYPE_SHORT;
        lng = 6;
        break;
      case CIM_REAL64:
      case CIM_REAL32:
        prec = 2;
        typ = TYPE_DOUBLE;
        lng = 15;
        break;
      case CIM_SINT64:
      case CIM_UINT64:
        typ = TYPE_BIGINT;
        lng = 20;
        break;
      case CIM_DATETIME:
        typ = TYPE_DATE;
        lng = 19;
        break;
      case CIM_CHAR16:
        typ = TYPE_STRING;
        lng = 16;
        break;
      case CIM_EMPTY:
        typ = TYPE_STRING;
        lng = 24;             // ???
        break;
      default:
        qrp->BadLines++;
        goto suite;
      } // endswitch type

    crp = qrp->Colresp;                    // Column Name
    crp->Kdata->SetValue(_com_util::ConvertBSTRToString(propname), i);
    crp = crp->Next;                       // Data Type
    crp->Kdata->SetValue(typ, i);
    crp = crp->Next;                       // Type Name
    crp->Kdata->SetValue(GetTypeName(typ), i);
    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue(lng, i);
    crp = crp->Next;                       // Length
    crp->Kdata->SetValue(lng, i);
    crp = crp->Next;                       // Scale (precision)
    crp->Kdata->SetValue(prec, i);
    i++;

 suite:
    SysFreeString(propname);
    VariantClear(&val);
    } // endfor i

  qrp->Nblin = i;

 err:
  // Cleanup
  wp->Cobj->Release();
  wp->Svc->Release();
  wp->Svc = NULL;    // MUST be set to NULL  (why?)
  CoUninitialize();

  /*********************************************************************/
  /*  Return the result pointer for use by GetData routines.           */
  /*********************************************************************/
  return qrp;
  } // end of WMIColumns
示例#25
0
static void create_record(uchar *record,uint rownr)
{
  uchar *pos;
  bzero((char*) record,MAX_REC_LENGTH);
  record[0]=1;					/* delete marker */
  if (rownr == 0 && keyinfo[0].seg[0].null_bit)
    record[0]|=keyinfo[0].seg[0].null_bit;	/* Null key */

  pos=record+1;
  if (recinfo[1].type == FIELD_BLOB)
  {
    uint tmp;
    uchar *ptr;
    create_key_part(blob_key,rownr);
    tmp=strlen((char*) blob_key);
    int4store(pos,tmp);
    ptr=blob_key;
    memcpy(pos+4, &ptr, sizeof(char*));
    pos+=recinfo[1].length;
  }
  else if (recinfo[1].type == FIELD_VARCHAR)
  {
    uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
    create_key_part(pos+pack_length,rownr);
    tmp= strlen((char*) pos+pack_length);
    if (pack_length == 1)
      *(uchar*) pos= (uchar) tmp;
    else
      int2store(pos,tmp);
    pos+= recinfo[1].length;
  }
  else
  {
    create_key_part(pos,rownr);
    pos+=recinfo[1].length;
  }
  if (recinfo[2].type == FIELD_BLOB)
  {
    uint tmp;
    uchar *ptr;;
    sprintf((char*) blob_record,"... row: %d", rownr);
    strappend((char*) blob_record,MY_MAX(MAX_REC_LENGTH-rownr,10),' ');
    tmp=strlen((char*) blob_record);
    int4store(pos,tmp);
    ptr=blob_record;
    memcpy(pos+4, &ptr, sizeof(char*));
  }
  else if (recinfo[2].type == FIELD_VARCHAR)
  {
    uint tmp, pack_length= HA_VARCHAR_PACKLENGTH(recinfo[1].length-1);
    sprintf((char*) pos+pack_length, "... row: %d", rownr);
    tmp= strlen((char*) pos+pack_length);
    if (pack_length == 1)
      *pos= (uchar) tmp;
    else
      int2store(pos,tmp);
  }
  else
  {
    sprintf((char*) pos,"... row: %d", rownr);
    strappend((char*) pos,recinfo[2].length,' ');
  }
}
示例#26
0
static char *process_args(const CHARSET_INFO *cs, char *to, char *end,
                          const char* fmt, size_t arg_index, va_list ap)
{
  ARGS_INFO args_arr[MAX_ARGS];
  PRINT_INFO print_arr[MAX_PRINT_INFO];
  uint idx= 0, arg_count= arg_index;

start:
  /* Here we are at the beginning of positional argument, right after $ */
  arg_index--;
  print_arr[idx].flags= 0;
  if (*fmt == '`')
  {
    print_arr[idx].flags|= ESCAPED_ARG;
    fmt++;
  }
  if (*fmt == '-')
    fmt++;
  print_arr[idx].length= print_arr[idx].width= 0;
  /* Get print length */
  if (*fmt == '*')
  {          
    fmt++;
    fmt= get_length(fmt, &print_arr[idx].length, &print_arr[idx].flags);
    print_arr[idx].length--;    
    DBUG_ASSERT(*fmt == '$' && print_arr[idx].length < MAX_ARGS);
    args_arr[print_arr[idx].length].arg_type= 'd';
    args_arr[print_arr[idx].length].have_longlong= 0;
    print_arr[idx].flags|= LENGTH_ARG;
    arg_count= MY_MAX(arg_count, print_arr[idx].length + 1);
    fmt++;
  }
  else
    fmt= get_length(fmt, &print_arr[idx].length, &print_arr[idx].flags);
  
  if (*fmt == '.')
  {
    fmt++;
    /* Get print width */
    if (*fmt == '*')
    {
      fmt++;
      fmt= get_width(fmt, &print_arr[idx].width);
      print_arr[idx].width--;
      DBUG_ASSERT(*fmt == '$' && print_arr[idx].width < MAX_ARGS);
      args_arr[print_arr[idx].width].arg_type= 'd';
      args_arr[print_arr[idx].width].have_longlong= 0;
      print_arr[idx].flags|= WIDTH_ARG;
      arg_count= MY_MAX(arg_count, print_arr[idx].width + 1);
      fmt++;
    }
    else
      fmt= get_width(fmt, &print_arr[idx].width);
  }
  else
    print_arr[idx].width= SIZE_T_MAX;

  fmt= check_longlong(fmt, &args_arr[arg_index].have_longlong);
  if (*fmt == 'p')
    args_arr[arg_index].have_longlong= (sizeof(void *) == sizeof(longlong));
  args_arr[arg_index].arg_type= print_arr[idx].arg_type= *fmt;
  
  print_arr[idx].arg_idx= arg_index;
  print_arr[idx].begin= ++fmt;

  while (*fmt && *fmt != '%')
    fmt++;

  if (!*fmt)                                  /* End of format string */
  {
    uint i;
    print_arr[idx].end= fmt;
    /* Obtain parameters from the list */
    for (i= 0 ; i < arg_count; i++)
    {
      switch (args_arr[i].arg_type) {
      case 's':
      case 'b':
        args_arr[i].str_arg= va_arg(ap, char *);
        break;
      case 'f':
      case 'g':
        args_arr[i].double_arg= va_arg(ap, double);
        break;
      case 'd':
      case 'i':
      case 'u':
      case 'x':
      case 'X':
      case 'o':
      case 'p':
        if (args_arr[i].have_longlong)
          args_arr[i].longlong_arg= va_arg(ap,longlong);
        else if (args_arr[i].arg_type == 'd' || args_arr[i].arg_type == 'i')
          args_arr[i].longlong_arg= va_arg(ap, int);
        else
          args_arr[i].longlong_arg= va_arg(ap, uint);
        break;
      case 'c':
        args_arr[i].longlong_arg= va_arg(ap, int);
        break;
      default:
        DBUG_ASSERT(0);
      }
    }
示例#27
0
PARRAY MakeValueArray(PGLOBAL g, PPARM pp)
  {
  int    n, valtyp = 0;
  size_t len = 0;
  PARRAY par;
  PPARM  parmp;

  if (!pp)
    return NULL;

  /*********************************************************************/
  /*  New version with values coming in a list.                        */
  /*********************************************************************/
  if ((valtyp = pp->Type) != TYPE_STRING)
    len = 1;

 	if (trace)
 		htrc("valtyp=%d len=%d\n", valtyp, len);
  		
  /*********************************************************************/
  /*  Firstly check the list and count the number of values in it.     */
  /*********************************************************************/
  for (n = 0, parmp = pp; parmp; n++, parmp = parmp->Next)
    if (parmp->Type != valtyp) {
      sprintf(g->Message, MSG(BAD_PARAM_TYPE), "MakeValueArray", parmp->Type);
      return NULL;
    } else if (valtyp == TYPE_STRING)
      len = MY_MAX(len, strlen((char*)parmp->Value));

  /*********************************************************************/
  /*  Make an array object with one block of the proper size.          */
  /*********************************************************************/
  par = new(g) ARRAY(g, valtyp, n, (int)len);

  if (par->GetResultType() == TYPE_ERROR)
    return NULL;          // Memory allocation error in ARRAY

  /*********************************************************************/
  /*  All is right now, fill the array block.                          */
  /*********************************************************************/
  for (parmp = pp; parmp; parmp = parmp->Next)
    switch (valtyp) {
      case TYPE_STRING:
        par->AddValue(g, (PSZ)parmp->Value);
        break;
      case TYPE_SHORT:
        par->AddValue(g, *(short*)parmp->Value);
        break;
      case TYPE_INT:
        par->AddValue(g, *(int*)parmp->Value);
        break;
      case TYPE_DOUBLE:
        par->AddValue(g, *(double*)parmp->Value);
        break;
      case TYPE_PCHAR:
        par->AddValue(g, parmp->Value);
        break;
      case TYPE_VOID:
        // Integer stored inside pp->Value
        par->AddValue(g, parmp->Intval);
        break;
      } // endswitch valtyp

  /*********************************************************************/
  /*  Send back resulting array.                                       */
  /*********************************************************************/
  return par;
  } // end of MakeValueArray
示例#28
0
bool TDBFMT::OpenDB(PGLOBAL g)
  {
  Linenum = 0;

  if (Mode == MODE_INSERT || Mode == MODE_UPDATE) {
    sprintf(g->Message, MSG(FMT_WRITE_NIY), "FMT");
    return true;                    // NIY
    } // endif Mode

  if (Use != USE_OPEN && Columns) {
    // Make the formats used to read records
    PSZ     pfm;
    int     i, n;
    PCSVCOL colp;
    PCOLDEF cdp;
    PDOSDEF tdp = (PDOSDEF)To_Def;

    for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
      if (!colp->IsSpecial() && !colp->IsVirtual())  // a true column
        Fields = MY_MAX(Fields, (int)colp->Fldnum);

    if (Columns)
      Fields++;                // Fldnum was 0 based

    To_Fld = PlugSubAlloc(g, NULL, Lrecl + 1);
    FldFormat = (PSZ*)PlugSubAlloc(g, NULL, sizeof(PSZ) * Fields);
    memset(FldFormat, 0, sizeof(PSZ) * Fields);
    FmtTest = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);
    memset(FmtTest, 0, sizeof(int) * Fields);

    // Get the column formats
    for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
      if (!cdp->IsVirtual() && (i = cdp->GetOffset() - 1) < Fields) {
        if (!(pfm = cdp->GetFmt())) {
          sprintf(g->Message, MSG(NO_FLD_FORMAT), i + 1, Name);
          return true;
          } // endif pfm

        // Roughly check the Fmt format
        if ((n = strlen(pfm) - 2) < 4) {
          sprintf(g->Message, MSG(BAD_FLD_FORMAT), i + 1, Name);
          return true;
          } // endif n

        FldFormat[i] = (PSZ)PlugSubAlloc(g, NULL, n + 5);
        strcpy(FldFormat[i], pfm);

        if (!strcmp(pfm + n, "%m")) {
          // This is a field that can be missing. Flag it so it can
          // be handled with special processing.
          FldFormat[i][n+1] = 'n';  // To have sscanf normal processing
          FmtTest[i] = 2;
        } else if (i+1 < Fields && strcmp(pfm + n, "%n")) {
          // There are trailing characters after the field contents
          // add a marker for the next field start position.
          strcat(FldFormat[i], "%n");
          FmtTest[i] = 1;
        } // endif's

        } // endif i

    } // endif Use

  return TDBCSV::OpenDB(g);
  } // end of OpenDB
示例#29
0
PQRYRES CSVColumns(PGLOBAL g, const char *fn, char sep, char q,
                   int hdr, int mxr, bool info)
  {
  static int  buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING,
                          TYPE_INT,   TYPE_INT, TYPE_SHORT};
  static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE,   FLD_TYPENAME,
                          FLD_PREC, FLD_LENGTH, FLD_SCALE};
  static unsigned int length[] = {6, 6, 8, 10, 10, 6};
  char   *p, *colname[MAXCOL], dechar, filename[_MAX_PATH], buf[4096];
  int     i, imax, hmax, n, nerr, phase, blank, digit, dec, type;
  int     ncol = sizeof(buftyp) / sizeof(int);
  int     num_read = 0, num_max = 10000000;     // Statistics
  int     len[MAXCOL], typ[MAXCOL], prc[MAXCOL];
  FILE   *infile;
  PQRYRES qrp;
  PCOLRES crp;

  if (info) {
    imax = hmax = 0;
    length[0] = 128;
    goto skipit;
    } // endif info

//      num_max = atoi(p+1);             // Max num of record to test
#if defined(WIN32)
  if (sep == ',' || strnicmp(setlocale(LC_NUMERIC, NULL), "French", 6))
    dechar = '.';
  else
    dechar = ',';
#else   // !WIN32
  dechar = '.';
#endif  // !WIN32

  if (trace)
    htrc("File %s sep=%c q=%c hdr=%d mxr=%d\n",
          SVP(fn), sep, q, hdr, mxr);

  if (!fn) {
    strcpy(g->Message, MSG(MISSING_FNAME));
    return NULL;
    } // endif fn

  imax = hmax = nerr = 0;
  mxr = MY_MAX(0, mxr);

  for (i = 0; i < MAXCOL; i++) {
    colname[i] = NULL;
    len[i] = 0;
    typ[i] = TYPE_UNKNOWN;
    prc[i] = 0;
    } // endfor i

  /*********************************************************************/
  /*  Open the input file.                                             */
  /*********************************************************************/
  PlugSetPath(filename, fn, PlgGetDataPath(g));

  if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "r")))
    return NULL;

  if (hdr) {
    /*******************************************************************/
    /*  Make the column names from the first line.                     */
    /*******************************************************************/
    phase = 0;

    if (fgets(buf, sizeof(buf), infile)) {
      n = strlen(buf) + 1;
      buf[n - 2] = '\0';
#if defined(UNIX)
      // The file can be imported from Windows 
      if (buf[n - 3] == '\r')
        buf[n - 3] = 0;
#endif   // UNIX
      p = (char*)PlugSubAlloc(g, NULL, n);
      memcpy(p, buf, n);

      //skip leading blanks
      for (; *p == ' '; p++) ;

      if (q && *p == q) {
        // Header is quoted
        p++;
        phase = 1;
        } // endif q

      colname[0] = p;
    } else {
      sprintf(g->Message, MSG(FILE_IS_EMPTY), fn);
      goto err;
    } // endif's

    for (i = 1; *p; p++)
      if (phase == 1 && *p == q) {
        *p = '\0';
        phase = 0;
      } else if (*p == sep && !phase) {
        *p = '\0';

        //skip leading blanks
        for (; *(p+1) == ' '; p++) ;

        if (q && *(p+1) == q) {
          // Header is quoted
          p++;
          phase = 1;
          } // endif q

        colname[i++] = p + 1;
        } // endif sep

    num_read++;
    imax = hmax = i;

    for (i = 0; i < hmax; i++)
      length[0] = MY_MAX(length[0], strlen(colname[i]));

    } // endif hdr

  for (num_read++; num_read <= num_max; num_read++) {
    /*******************************************************************/
    /*  Now start the reading process. Read one line.                  */
    /*******************************************************************/
    if (fgets(buf, sizeof(buf), infile)) {
      n = strlen(buf);
      buf[n - 1] = '\0';
#if defined(UNIX)
      // The file can be imported from Windows 
      if (buf[n - 2] == '\r')
        buf[n - 2] = 0;
#endif   // UNIX
    } else if (feof(infile)) {
      sprintf(g->Message, MSG(EOF_AFTER_LINE), num_read -1);
      break;
    } else {
      sprintf(g->Message, MSG(ERR_READING_REC), num_read, fn);
      goto err;
    } // endif's

    /*******************************************************************/
    /*  Make the test for field lengths.                               */
    /*******************************************************************/
    i = n = phase = blank = digit = dec = 0;

    for (p = buf; *p; p++)
      if (*p == sep) {
        if (phase != 1) {
          if (i == MAXCOL - 1) {
            sprintf(g->Message, MSG(TOO_MANY_FIELDS), num_read, fn);
            goto err;
            } // endif i

          if (n) {
            len[i] = MY_MAX(len[i], n);
            type = (digit || (dec && n == 1)) ? TYPE_STRING
                 : (dec) ? TYPE_DOUBLE : TYPE_INT;
            typ[i] = MY_MIN(type, typ[i]);
            prc[i] = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
            } // endif n

          i++;
          n = phase = blank = digit = dec = 0;
        } else          // phase == 1
          n++;

      } else if (*p == ' ') {
        if (phase < 2)
          n++;

        if (blank)
          digit = 1;

      } else if (*p == q) {
        if (phase == 0) {
          if (blank)
            if (++nerr > mxr) {
              sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
              goto err;
            } else
              goto skip;

          n = 0;
          phase = digit = 1;
        } else if (phase == 1) {
          if (*(p+1) == q) {
            // This is currently not implemented for CSV tables
//          if (++nerr > mxr) {
//            sprintf(g->Message, MSG(QUOTE_IN_QUOTE), num_read);
//            goto err;
//          } else
//            goto skip;

            p++;
            n++;
          } else
            phase = 2;

        } else if (++nerr > mxr) {      // phase == 2
          sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
          goto err;
        } else
          goto skip;

      } else {
        if (phase == 2)
          if (++nerr > mxr) {
            sprintf(g->Message, MSG(MISPLACED_QUOTE), num_read);
            goto err;
          } else
            goto skip;

        // isdigit cannot be used here because of debug assert
        if (!strchr("0123456789", *p)) {
          if (!digit && *p == dechar)
            dec = 1;                    // Decimal point found
          else if (blank || !(*p == '-' || *p == '+'))
            digit = 1;

        } else if (dec)
          dec++;                        // More decimals

        n++;
        blank = 1;
      } // endif's *p

    if (phase == 1)
      if (++nerr > mxr) {
        sprintf(g->Message, MSG(UNBALANCE_QUOTE), num_read);
        goto err;
      } else
        goto skip;

    if (n) {
      len[i] = MY_MAX(len[i], n);
      type = (digit || n == 0 || (dec && n == 1)) ? TYPE_STRING
           : (dec) ? TYPE_DOUBLE : TYPE_INT;
      typ[i] = MY_MIN(type, typ[i]);
      prc[i]  = MY_MAX((typ[i] == TYPE_DOUBLE) ? (dec - 1) : 0, prc[i]);
      } // endif n

    imax = MY_MAX(imax, i+1);
   skip: ;                  // Skip erroneous line
    } // endfor num_read

  if (trace) {
    htrc("imax=%d Lengths:", imax);

    for (i = 0; i < imax; i++)
      htrc(" %d", len[i]);

    htrc("\n");
  } // endif trace

  fclose(infile);

 skipit:
  if (trace)
    htrc("CSVColumns: imax=%d hmax=%d len=%d\n",
                      imax, hmax, length[0]);

  /*********************************************************************/
  /*  Allocate the structures used to refer to the result set.         */
  /*********************************************************************/
  qrp = PlgAllocResult(g, ncol, imax, IDS_COLUMNS + 3,
                          buftyp, fldtyp, length, false, false);
  if (info || !qrp)
    return qrp;

  qrp->Nblin = imax;

  /*********************************************************************/
  /*  Now get the results into blocks.                                 */
  /*********************************************************************/
  for (i = 0; i < imax; i++) {
    if (i >= hmax) {
      sprintf(buf, "COL%.3d", i+1);
      p = buf;
    } else
      p = colname[i];

    if (typ[i] == TYPE_UNKNOWN)            // Void column
      typ[i] = TYPE_STRING;

    crp = qrp->Colresp;                    // Column Name
    crp->Kdata->SetValue(p, i);
    crp = crp->Next;                       // Data Type
    crp->Kdata->SetValue(typ[i], i);
    crp = crp->Next;                       // Type Name
    crp->Kdata->SetValue(GetTypeName(typ[i]), i);
    crp = crp->Next;                       // Precision
    crp->Kdata->SetValue(len[i], i);
    crp = crp->Next;                       // Length
    crp->Kdata->SetValue(len[i], i);
    crp = crp->Next;                       // Scale (precision)
    crp->Kdata->SetValue(prc[i], i);
    } // endfor i

  /*********************************************************************/
  /*  Return the result pointer for use by GetData routines.           */
  /*********************************************************************/
  return qrp;

 err:
  fclose(infile);
  return NULL;
  } // end of CSVCColumns
示例#30
0
bool TDBCSV::OpenDB(PGLOBAL g)
  {
  bool    rc = false;
  PCOLDEF cdp;
  PDOSDEF tdp = (PDOSDEF)To_Def;

  if (Use != USE_OPEN && (Columns || Mode == MODE_UPDATE)) {
    // Allocate the storage used to read (or write) records
    int     i, len;
    PCSVCOL colp;

    if (!Fields)              // May have been set in TABFMT::OpenDB
      if (Mode != MODE_UPDATE && Mode != MODE_INSERT) {
        for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
          if (!colp->IsSpecial() && !colp->IsVirtual())
            Fields = MY_MAX(Fields, (int)colp->Fldnum);

        if (Columns)
          Fields++;           // Fldnum was 0 based

      } else
        for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
          if (!cdp->IsVirtual())
            Fields++;

    Offset = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);
    Fldlen = (int*)PlugSubAlloc(g, NULL, sizeof(int) * Fields);

    if (Mode == MODE_INSERT || Mode == MODE_UPDATE) {
      Field = (PSZ*)PlugSubAlloc(g, NULL, sizeof(PSZ) * Fields);
      Fldtyp = (bool*)PlugSubAlloc(g, NULL, sizeof(bool) * Fields);
      } // endif Mode

    for (i = 0; i < Fields; i++) {
      Offset[i] = 0;
      Fldlen[i] = 0;

      if (Field) {
        Field[i] = NULL;
        Fldtyp[i] = false;
        } // endif Field

      } // endfor i

    if (Field)
      // Prepare writing fields
      if (Mode != MODE_UPDATE) {
        for (colp = (PCSVCOL)Columns; colp; colp = (PCSVCOL)colp->Next)
          if (!colp->IsSpecial() && !colp->IsVirtual()) {
            i = colp->Fldnum;
            len = colp->GetLength();
            Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
            Field[i][len] = '\0';
            Fldlen[i] = len;
            Fldtyp[i] = IsTypeNum(colp->GetResultType());
            } // endif colp

      } else     // MODE_UPDATE
        for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
          if (!cdp->IsVirtual()) {
            i = cdp->GetOffset() - 1;
            len = cdp->GetLength();
            Field[i] = (PSZ)PlugSubAlloc(g, NULL, len + 1);
            Field[i][len] = '\0';
            Fldlen[i] = len;
            Fldtyp[i] = IsTypeNum(cdp->GetType());
            } // endif cdp

    } // endif Use

  if (Header) {
    // Check that the Lrecl is at least equal to the header line length
    int     headlen = 0;
    PCOLDEF cdp;
    PDOSDEF tdp = (PDOSDEF)To_Def;

    for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
      headlen += strlen(cdp->GetName()) + 3;  // 3 if names are quoted

    if (headlen > Lrecl) {
      Lrecl = headlen;
      Txfp->Lrecl = headlen;
      } // endif headlen

    } // endif Header

  Nerr = 0;
  rc = TDBDOS::OpenDB(g);

  if (!rc && Mode == MODE_UPDATE && To_Kindex)
    // Because KINDEX::Init is executed in mode READ, we must restore
    // the Fldlen array that was modified when reading the table file.
    for (cdp = tdp->GetCols(); cdp; cdp = cdp->GetNext())
      Fldlen[cdp->GetOffset() - 1] = cdp->GetLength();

  return rc;
  } // end of OpenDB