Beispiel #1
0
int main(int argc, char **argv)
{
  FILE *fileID;
  COLUMN_DATA_STRUCTURES *columnValues;
  PARAMETER_DATA_STRUCTURES *parameterValues;

  SDDS_DATASET SDDS_dataset;
  SCANNED_ARG *s_arg;
  long i, j, k, n, i_arg;
  int32_t rows;
  int32_t maxRows=10000, initRows=10000, row;
  long par, col, page, size, readline=1, fillin=0;
  int32_t ptrSize=0;
  char *input, *output, s[1024], *ptr, *ptr2, data[10240],temp[10240];
  unsigned long pipeFlags=0,majorOrderFlag;
  long noWarnings=0, tmpfile_used=0, columnOrder=0, whitespace=1;
  short shortValue;
  int32_t longValue;
  float floatValue;
  double doubleValue;
  char stringValue[SDDS_MAXLINE];
  char characterValue;
  char buffer[124], buffer2[124];
  long *parameterIndex, *columnIndex;

  long binary=0, noRowCount=0, inputBinary=0, count=0;
  char separator;
  char commentCharacters[20];
  short checkComment=0;
  short commentFound;
  long parameters=0, columns=0;
  long skiplines=0;
  short abort=0, recover=1, columnMajorOrder=0;

  input = output = NULL;
  separator = ' ';
  columnValues = NULL;
  parameterValues = NULL;

  parameterIndex = columnIndex = NULL;

  SDDS_RegisterProgramName(argv[0]);
  argc = scanargs(&s_arg, argc, argv);
  if (argc<3) 
    bomb(NULL, USAGE);
  
  for (i_arg=1; i_arg<argc; i_arg++) {
    if (s_arg[i_arg].arg_type==OPTION) {
      switch (match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
      case SET_MAJOR_ORDER:
        majorOrderFlag=0;
        s_arg[i_arg].n_items -=1;
        if (s_arg[i_arg].n_items>0 &&
            (!scanItemList(&majorOrderFlag, s_arg[i_arg].list+1, &s_arg[i_arg].n_items, 0,
                           "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
                           "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER,
                            NULL)))
          SDDS_Bomb("invalid -majorOrder syntax/values");
        if (majorOrderFlag&SDDS_COLUMN_MAJOR_ORDER)
          columnMajorOrder=1;
        else if (majorOrderFlag&SDDS_ROW_MAJOR_ORDER)
          columnMajorOrder=0;
        break;
      case SET_OUTPUTMODE:
	if (s_arg[i_arg].n_items!=2)
	  SDDS_Bomb("invalid -outputMode syntax");
	switch (match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
	case ASCII_MODE:
	  binary = 0;
	  break;
	case BINARY_MODE:
	  binary = 1;
	  break;
	default:
	  SDDS_Bomb("invalid -outputMode syntax");
	  break;
	}
	break;
      case SET_INPUTMODE:
	if (s_arg[i_arg].n_items!=2)
	  SDDS_Bomb("invalid -inputMode syntax");
	switch (match_string(s_arg[i_arg].list[1], mode_name, MODES, 0)) {
	case ASCII_MODE:
	  inputBinary = 0;
	  break;
	case BINARY_MODE:
	  inputBinary = 1;
	  break;
	default:
	  SDDS_Bomb("invalid -inputMode syntax");
	  break;
	}
	break;
      case SET_SEPARATOR:
	if (s_arg[i_arg].n_items!=2)
	  SDDS_Bomb("invalid -separator syntax");
	separator = s_arg[i_arg].list[1][0];
        whitespace = 0;
	break;
      case SET_COMMENT:
	if (s_arg[i_arg].n_items!=2)
	  SDDS_Bomb("invalid -commentCharacters syntax");
	sprintf(commentCharacters, "%s", s_arg[i_arg].list[1]);
        checkComment=1;
	break;
      case SET_FILLIN:
        fillin=1;
        break;
      case SET_NOROWCOUNT:
	if (s_arg[i_arg].n_items!=1)
	  SDDS_Bomb("invalid -noRowCount syntax");
	noRowCount = 1;
	break;
      case SET_ORDER:
	if (s_arg[i_arg].n_items!=2)
	  SDDS_Bomb("invalid -order syntax");
	switch (match_string(s_arg[i_arg].list[1], order_names, ORDERS, 0)) {
	case ROW_ORDER:
	  columnOrder = 0;
	  break;
	case COLUMN_ORDER:
	  columnOrder = 1;
	  break;
	default:
	  SDDS_Bomb("invalid -order syntax");
	  break;
	}
	break;
      case SET_PARAMETER:
	if (s_arg[i_arg].n_items<3)
	  SDDS_Bomb("invalid -parameter syntax");
        count=1;
	parameters++;
	parameterValues = trealloc(parameterValues, sizeof(*parameterValues)*(parameters));
        SDDS_CopyString(&parameterValues[parameters-1].name, s_arg[i_arg].list[1]);
	parameterValues[parameters-1].units = NULL;
	parameterValues[parameters-1].description = NULL;
	parameterValues[parameters-1].symbol = NULL;
	switch (match_string(s_arg[i_arg].list[2], type_name, DATATYPES, 0)) {
	case TYPE_SHORT:
	  parameterValues[parameters-1].type = SDDS_SHORT;
	  break;
	case TYPE_LONG:
	  parameterValues[parameters-1].type = SDDS_LONG;
	  break;
	case TYPE_FLOAT:
	  parameterValues[parameters-1].type = SDDS_FLOAT;
	  break;
	case TYPE_DOUBLE:
	  parameterValues[parameters-1].type = SDDS_DOUBLE;
	  break;
	case TYPE_STRING:
	  parameterValues[parameters-1].type = SDDS_STRING;
	  break;
	case TYPE_CHARACTER:
	  parameterValues[parameters-1].type = SDDS_CHARACTER;
	  break;
	default:
	  SDDS_Bomb("invalid -parameter type");
	  break;
	}
	for (i=3;i<s_arg[i_arg].n_items;i++) {
	  if (!(ptr=strchr(s_arg[i_arg].list[i], '=')))
	    SDDS_Bomb("invalid -parameter syntax");
	  *ptr++ = 0;	
	  switch (match_string(s_arg[i_arg].list[i], header_elements, HEADERELEMENTS, 0)) {
	  case HEADER_UNITS:
            SDDS_CopyString(&parameterValues[parameters-1].units, ptr);
	    break;
	  case HEADER_DESCRIPTION:
            SDDS_CopyString(&parameterValues[parameters-1].description, ptr);
	    break;
	  case HEADER_SYMBOL:
            SDDS_CopyString(&parameterValues[parameters-1].symbol, ptr);
	    break;
	  case HEADER_COUNT:
	    if (sscanf(ptr, "%ld", &count)!=1 ||
                count<=0)
              SDDS_Bomb("invalid parameter count value");
            sprintf(buffer, "%s", parameterValues[parameters-1].name);
            sprintf(buffer2, "%s1", buffer);
            free(parameterValues[parameters-1].name);
            SDDS_CopyString(&parameterValues[parameters-1].name, buffer2);
	    break;
	  default:
	    SDDS_Bomb("invalid -parameter syntax");
	    break;
	  } 
	}
        
        for (i=2;i<=count;i++) {
          parameters++;
          parameterValues = trealloc(parameterValues, sizeof(*parameterValues)*(parameters));
          sprintf(buffer2, "%s%ld", buffer, i);
          SDDS_CopyString(&parameterValues[parameters-1].name, buffer2);
          parameterValues[parameters-1].units = NULL;
          parameterValues[parameters-1].description = NULL;
          parameterValues[parameters-1].symbol = NULL;
          parameterValues[parameters-1].type = parameterValues[parameters-2].type;
          if (parameterValues[parameters-2].units)
            SDDS_CopyString(&parameterValues[parameters-1].units, parameterValues[parameters-2].units);
          if (parameterValues[parameters-2].description)
            SDDS_CopyString(&parameterValues[parameters-1].description, parameterValues[parameters-2].description);
          if (parameterValues[parameters-2].symbol)
            SDDS_CopyString(&parameterValues[parameters-1].symbol, parameterValues[parameters-2].symbol);
        }
        
	break;
      case SET_COLUMN:
	if (s_arg[i_arg].n_items<3)
	  SDDS_Bomb("invalid -column syntax");
        count=1;
	columns++;
	columnValues = trealloc(columnValues, sizeof(*columnValues)*(columns));
        SDDS_CopyString(&columnValues[columns-1].name, s_arg[i_arg].list[1]);
	columnValues[columns-1].elements = 0;
	columnValues[columns-1].values = NULL;
	columnValues[columns-1].stringValues = NULL;
	columnValues[columns-1].units = NULL;
	columnValues[columns-1].description = NULL;
	columnValues[columns-1].symbol = NULL;
	columnValues[columns-1].skip = 0;

	switch (match_string(s_arg[i_arg].list[2], type_name, DATATYPES, 0)) {
	case TYPE_SHORT:
	  columnValues[columns-1].type = SDDS_SHORT;
	  break;
	case TYPE_LONG:
	  columnValues[columns-1].type = SDDS_LONG;
	  break;
	case TYPE_FLOAT:
	  columnValues[columns-1].type = SDDS_FLOAT;
	  break;
	case TYPE_DOUBLE:
	  columnValues[columns-1].type = SDDS_DOUBLE;
	  break;
	case TYPE_STRING:
	  columnValues[columns-1].type = SDDS_STRING;
	  break;
	case TYPE_CHARACTER:
	  columnValues[columns-1].type = SDDS_CHARACTER;
	  break;
	default:
	  SDDS_Bomb("invalid -column type");
	  break;
	}
	for (i=3;i<s_arg[i_arg].n_items;i++) {
	  if (!(ptr=strchr(s_arg[i_arg].list[i], '=')))
	    SDDS_Bomb("invalid -column syntax");
	  *ptr++ = 0;	
	  switch (match_string(s_arg[i_arg].list[i], header_elements, HEADERELEMENTS, 0)) {
	  case HEADER_UNITS:
            SDDS_CopyString(&columnValues[columns-1].units, ptr);
	    break;
	  case HEADER_DESCRIPTION:
            SDDS_CopyString(&columnValues[columns-1].description, ptr);
	    break;
	  case HEADER_SYMBOL:
            SDDS_CopyString(&columnValues[columns-1].symbol, ptr);
	    break;
	  case HEADER_COUNT:
	    if (sscanf(ptr, "%ld", &count)!=1 ||
                count<=0)
              SDDS_Bomb("invalid column count value");
            sprintf(buffer, "%s", columnValues[columns-1].name);
            sprintf(buffer2, "%s1", buffer);
            free(columnValues[columns-1].name);
            SDDS_CopyString(&columnValues[columns-1].name, buffer2);
	    break;
	  default:
	    SDDS_Bomb("invalid -column syntax");
	    break;
	  }
	}
        
        for (i=2;i<=count;i++) {
          columns++;
          columnValues = trealloc(columnValues, sizeof(*columnValues)*(columns));
          sprintf(buffer2, "%s%ld", buffer, i);
          SDDS_CopyString(&columnValues[columns-1].name, buffer2);
          columnValues[columns-1].elements = 0;
          columnValues[columns-1].values = NULL;
          columnValues[columns-1].stringValues = NULL;
          columnValues[columns-1].units = NULL;
          columnValues[columns-1].description = NULL;
          columnValues[columns-1].symbol = NULL;
          columnValues[columns-1].type = columnValues[columns-2].type;
          if (columnValues[columns-2].units)
            SDDS_CopyString(&columnValues[columns-1].units, columnValues[columns-2].units);
          if (columnValues[columns-2].description)
            SDDS_CopyString(&columnValues[columns-1].description, columnValues[columns-2].description);
          if (columnValues[columns-2].symbol)
            SDDS_CopyString(&columnValues[columns-1].symbol, columnValues[columns-2].symbol);
        }
        
	break;
      case SET_SKIPCOLUMN:
	if (s_arg[i_arg].n_items!=2)
	  SDDS_Bomb("invalid -skipcolumn syntax");
        count=1;
	columns++;
	columnValues = trealloc(columnValues, sizeof(*columnValues)*(columns));
        columnValues[columns-1].name = NULL;
	columnValues[columns-1].elements = 0;
	columnValues[columns-1].values = NULL;
	columnValues[columns-1].stringValues = NULL;
	columnValues[columns-1].units = NULL;
	columnValues[columns-1].description = NULL;
	columnValues[columns-1].symbol = NULL;
	columnValues[columns-1].skip = 1;

	switch (match_string(s_arg[i_arg].list[1], type_name, DATATYPES, 0)) {
	case TYPE_SHORT:
	  columnValues[columns-1].type = SDDS_SHORT;
	  break;
	case TYPE_LONG:
	  columnValues[columns-1].type = SDDS_LONG;
	  break;
	case TYPE_FLOAT:
	  columnValues[columns-1].type = SDDS_FLOAT;
	  break;
	case TYPE_DOUBLE:
	  columnValues[columns-1].type = SDDS_DOUBLE;
	  break;
	case TYPE_STRING:
	  columnValues[columns-1].type = SDDS_STRING;
	  break;
	case TYPE_CHARACTER:
	  columnValues[columns-1].type = SDDS_CHARACTER;
	  break;
	default:
	  SDDS_Bomb("invalid -skipcolumn type");
	  break;
	}        
	break;
      case SET_PIPE:
	if (!processPipeOption(s_arg[i_arg].list+1, s_arg[i_arg].n_items-1, &pipeFlags))
	  SDDS_Bomb("invalid -pipe syntax");
	break;
      case SET_NOWARNINGS:
	if (s_arg[i_arg].n_items!=1)
	  SDDS_Bomb("invalid -nowarnings syntax");
	noWarnings = 1;
	break;
      case SET_SKIPLINES:
	if (s_arg[i_arg].n_items!=2 ||
	    sscanf(s_arg[i_arg].list[1], "%ld", &skiplines)!=1 ||
	    skiplines<=0)
	  SDDS_Bomb("invalid -skiplines syntax");
	break;
      default:
	fprintf(stderr, "error: unknown switch: %s\n", s_arg[i_arg].list[0]);
	exit(1);
	break;
      }
    } else {
      if (input == NULL) {
	input = s_arg[i_arg].list[0];
      } else if (output == NULL) {
	output = s_arg[i_arg].list[0];
      } else {
	fprintf(stderr, "too many filenames");
	exit(1);
      }
    }
  }
  
  processFilenames("plaindata2sdds", &input, &output, pipeFlags, noWarnings, &tmpfile_used);

  if (!columns && !parameters)
    SDDS_Bomb("you must specify one of the -column or the -parameter options");

  if (skiplines && inputBinary)
    SDDS_Bomb("-skiplines does not work with binary input files");
  
  if (!input) {
    if (inputBinary) {
#if defined(_WIN32)
      if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
	fprintf(stderr, "error: unable to set stdin to binary mode\n");
	exit(1);
      }      
#endif
    }
    fileID = stdin;
  } else {
    if (!fexists(input)) {
      fprintf(stderr, "input file not found\n");
      exit(1);
    }
    if (inputBinary) {
      fileID = fopen(input, "rb");
    } else {
      fileID = fopen(input, "r");
    }
  }
  if (fileID == NULL) {
    fprintf(stderr, "unable to open input file for reading\n");
    exit(1);
  }
  
  if (!SDDS_InitializeOutput(&SDDS_dataset, binary?SDDS_BINARY:SDDS_ASCII,
                             1, NULL, NULL, output))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    
  SDDS_dataset.layout.data_mode.column_major = columnMajorOrder;
  
  if (parameters) {
    parameterIndex = tmalloc(sizeof(*parameterIndex)*parameters);
  }
  if (columns) {
    columnIndex = tmalloc(sizeof(*columnIndex)*columns);
  }

  for (i=0; i<parameters; i++) {
    if ((parameterIndex[i] = 
         SDDS_DefineParameter(&SDDS_dataset, parameterValues[i].name, parameterValues[i].symbol,
			      parameterValues[i].units, parameterValues[i].description, NULL, 
                           parameterValues[i].type, 0))<0) {
      sprintf(s, "Problem defining parameter %s.", parameterValues[i].name);
      SDDS_SetError(s);
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
  }
  for (i=0; i<columns; i++) {
    if (columnValues[i].skip)
      continue;
    if ((columnIndex[i] = 
         SDDS_DefineColumn(&SDDS_dataset, columnValues[i].name, columnValues[i].symbol, \
			   columnValues[i].units, columnValues[i].description, NULL, 
                           columnValues[i].type, 0))<0) {
      sprintf(s, "Problem defining column %s.", columnValues[i].name);
      SDDS_SetError(s);
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
  }

  if (!SDDS_WriteLayout(&SDDS_dataset))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);

  if (!SDDS_StartPage(&SDDS_dataset, initRows))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);


  row = par = col = page = 0;
  while (inputBinary) {
    row = par = col = 0;
    
    if (fread(&rows,sizeof(rows),1,fileID) != 1) {
      if (page == 0) {
	SDDS_SetError("Unable to read number of rows");
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
      } else {
        if (!SDDS_Terminate(&SDDS_dataset))
          SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
        for (k=0;k<columns;k++) {
          if (columnValues[k].type == SDDS_STRING) {
            SDDS_FreeStringArray(columnValues[k].stringValues,columnValues[k].elements);
          } else {
            free(columnValues[k].values);
          }
        }
	return 0;
      }
    }
    page++;

    for (par=0;par<parameters;par++) {
      
      switch (parameterValues[par].type) {
      case SDDS_SHORT:
	if (fread(&shortValue,2,1,fileID) != 1) {
     	  SDDS_SetError("Unable to read short parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,shortValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_LONG:
	if (fread(&longValue,4,1,fileID) != 1) {
     	  SDDS_SetError("Unable to read long parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,longValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_FLOAT:
	if (fread(&floatValue,4,1,fileID) != 1) {
     	  SDDS_SetError("Unable to read float parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,floatValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_DOUBLE:
	if (fread(&doubleValue,8,1,fileID) != 1) {
     	  SDDS_SetError("Unable to read double parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,doubleValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_STRING:
	if (fread(&size,4,1,fileID) != 1) {
     	  SDDS_SetError("Unable to read string parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	}
        if (size>SDDS_MAXLINE-1)
          SDDS_Bomb("String is too long");
	if (size > 0) {
	  if (fread(&stringValue,size,1,fileID) != 1) {
	    SDDS_SetError("Unable to read string parameter");
	    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	  }
          stringValue[size] = 0;
	} else {
	  strcpy(stringValue,"");
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,stringValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_CHARACTER:
	if (fread(&characterValue,1,1,fileID) != 1) {
     	  SDDS_SetError("Unable to read character parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,characterValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      }
    }
    for (i=0;i<columns;i++) {
	if (rows > columnValues[i].elements) {
	  if (columnValues[i].type == SDDS_STRING) {
	    columnValues[i].stringValues = AllocateColumnStringData(columnValues[i].stringValues, rows, columnValues[i].elements);
	  } else {
	    columnValues[i].values = AllocateColumnData(columnValues[i].type, columnValues[i].values, rows);
          }
	  columnValues[i].elements = rows;
	}
    }
    if (columnOrder) {
      for (col=0;col<columns;col++) {
	switch (columnValues[col].type) {
	case SDDS_SHORT:
	  for (i=0;i<rows;i++) {
	    if (fread((short*)(columnValues[col].values)+i,2,1,fileID) != 1) {
	      SDDS_SetError("Unable to read short column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	  }
	  break;
	case SDDS_LONG:
	  for (i=0;i<rows;i++) {
	    if (fread((int32_t*)(columnValues[col].values)+i,4,1,fileID) != 1) {
	      SDDS_SetError("Unable to read long column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	  }
	  break;
	case SDDS_FLOAT:
	  for (i=0;i<rows;i++) {
	    if (fread((float*)(columnValues[col].values)+i,4,1,fileID) != 1) {
	      SDDS_SetError("Unable to read float column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }      
	  }
	  break;
	case SDDS_DOUBLE:
	  for (i=0;i<rows;i++) {
	    if (fread((double*)(columnValues[col].values)+i,8,1,fileID) != 1) {
	      SDDS_SetError("Unable to read double double");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	  }
	  break;
	case SDDS_STRING:
	  for (i=0;i<rows;i++) {
	    if (fread(&size,4,1,fileID) != 1) {
	      SDDS_SetError("Unable to read string column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
            if (size>SDDS_MAXLINE-1)
              SDDS_Bomb("String is too long");
            columnValues[col].stringValues[i] = malloc(size + 1);
	    if (size > 0) {
	      if (fread(columnValues[col].stringValues[i],size,1,fileID) != 1) {
		SDDS_SetError("Unable to read string column");
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	      }
              columnValues[col].stringValues[i][size] = 0;
	    } else {
	      strcpy(columnValues[col].stringValues[i],"");
	    }
	  }
	  break;
	case SDDS_CHARACTER:
	  for (i=0;i<rows;i++) {
	    if (fread((char*)(columnValues[col].values)+i,1,1,fileID) != 1) {
	      SDDS_SetError("Unable to read character column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	  }
	  break;
	}
      }
    } else {
      for (i=0;i<rows;i++) {
	for (col=0;col<columns;col++) {
	  switch (columnValues[col].type) {
	  case SDDS_SHORT:
	    if (fread((short*)(columnValues[col].values)+i,2,1,fileID) != 1) {
	      SDDS_SetError("Unable to read short column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	    break;
	  case SDDS_LONG:
	    if (fread((int32_t*)(columnValues[col].values)+i,4,1,fileID) != 1) {
	      SDDS_SetError("Unable to read long column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	    break;
	  case SDDS_FLOAT:
	    if (fread((float*)(columnValues[col].values)+i,4,1,fileID) != 1) {
	      SDDS_SetError("Unable to read float column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }      
	    break;
	  case SDDS_DOUBLE:
	    if (fread(((double*)(columnValues[col].values)+i),8,1,fileID) != 1) {
	      SDDS_SetError("Unable to read double column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	    break;
	  case SDDS_STRING:
	    if (fread(&size,4,1,fileID) != 1) {
	      SDDS_SetError("Unable to read string column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
            if (size>SDDS_MAXLINE-1)
              SDDS_Bomb("String is too long");
            columnValues[col].stringValues[i] = malloc(size + 1);
	    if (size > 0) {
	      if (fread(columnValues[col].stringValues[i],size,1,fileID) != 1) {
		SDDS_SetError("Unable to read string column");
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	      }
              columnValues[col].stringValues[i][size] = 0;
	    } else {
	      strcpy(columnValues[col].stringValues[i],"");
	    }
	    break;
	  case SDDS_CHARACTER:
	    if (fread(((char*)(columnValues[col].values)+i),1,1,fileID) != 1) {
	      SDDS_SetError("Unable to read character column");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	    break;
	  }
	}
      }
    }
    if (rows > maxRows) {
      if (!SDDS_LengthenTable(&SDDS_dataset, rows - maxRows)) {
	SDDS_SetError("Unable to lengthen table");
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
      }
      maxRows = rows;
    }
    j=n;
    for (i=0;i<columns;i++) {
      if (columnValues[i].skip)
	continue;
      if (columnValues[i].type == SDDS_STRING) {
	SetColumnData(columnValues[i].type, &SDDS_dataset, columnValues[i].stringValues, rows, n);
      } else {
	SetColumnData(columnValues[i].type, &SDDS_dataset, columnValues[i].values, rows, n);
      }
      n++;
    }
    
    if (!SDDS_WritePage(&SDDS_dataset)) {
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
    }
    maxRows = 10000;
    if (!SDDS_StartPage(&SDDS_dataset, initRows))
      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  }
  
  row = par = col = n = 0;
  rows = -1;
  ptr = NULL;
  ptr = SDDS_Malloc(sizeof(*ptr)*(ptrSize=2048));
  /*  ptr2 = NULL;
      ptr2 = SDDS_Malloc(sizeof(*ptr)*(ptrSize=2048));*/
  ptr[0] = 0;
  while (1) {
    if (readline) {
      while (skiplines > 0) {
	fgets(ptr, ptrSize, fileID);
	skiplines--;
      }
      if (!fgetsSkipCommentsResize(&ptr,&ptrSize,fileID, '!'))
	break;
      commentFound=0;
      if (checkComment) {
        for (i=0; i<strlen(commentCharacters); i++) {
          if (ptr[0] == commentCharacters[i]) {
            commentFound=1;
          }
        }
      }
      if (commentFound == 1) {
        continue;
      }
      if (ptr[strlen(ptr)-1] == '\n')
        ptr[strlen(ptr)-1] = 0;
      strcpy(temp,ptr);
      /*skip empty lines*/
      if (getToken(temp,data,10240,separator,whitespace)<0)
        continue;
    } else {
      readline = 1;
    }
    if (par < parameters) {
      switch (parameterValues[par].type) {
      case SDDS_SHORT:
	if (sscanf(ptr,"%hd",&shortValue) != 1) {
	  SDDS_SetError("Invalid short parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,shortValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_LONG:
	if (sscanf(ptr,"%" SCNd32 ,&longValue) != 1) {
	  SDDS_SetError("Invalid long parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,longValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_FLOAT:
        ConvertDNotationToENotation(ptr);
	if (sscanf(ptr,"%f",&floatValue) != 1) {
	  SDDS_SetError("Invalid float parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,floatValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_DOUBLE:
        ConvertDNotationToENotation(ptr);
	if (sscanf(ptr,"%lf",&doubleValue) != 1) {
	  SDDS_SetError("Invalid double parameter");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	}
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,doubleValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_STRING:
	SDDS_GetToken(ptr,stringValue,SDDS_MAXLINE);
	SDDS_InterpretEscapes(stringValue);
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,stringValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      case SDDS_CHARACTER:
	SDDS_InterpretEscapes(ptr);
	characterValue = ptr[0];
	if (!SDDS_SetParameters(&SDDS_dataset,SDDS_SET_BY_INDEX|SDDS_PASS_BY_VALUE,par,characterValue,-1))
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	break;
      }
      par++;
    } else if ((rows == -1) && (!noRowCount)) {
      if (sscanf(ptr,"%ld",&rows) != 1) {
	SDDS_SetError("Invalid row count");
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
    } else if ((columns > 0) && ((row < rows) || (noRowCount)))  {

      if (columnOrder) {

	if (noRowCount) {
	  cp_str(&ptr2,ptr);
	  rows = 0;
	  while (getToken(ptr2,data,10240,separator,whitespace) >= 0) {
	    rows++;
          }
          free(ptr2);
	}

	if (rows > columnValues[col].elements) {
	  if (columnValues[col].type == SDDS_STRING) {
	    columnValues[col].stringValues = AllocateColumnStringData(columnValues[col].stringValues, rows, columnValues[col].elements);
	  } else {
	    columnValues[col].values = AllocateColumnData(columnValues[col].type, columnValues[col].values, rows);
          }
	  columnValues[col].elements = rows;
	}
	switch (columnValues[col].type) {
	case SDDS_SHORT:
	  for (row=0;row<rows;row++) {
	    if (getToken(ptr,data,10240,separator,whitespace) < 0) {
	      SDDS_SetError("Invalid short column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
	    if (sscanf(data,"%hd",((short*)(columnValues[col].values)+row)) != 1) {
	      SDDS_SetError("Invalid short column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
	  }
	  break;
	case SDDS_LONG:
	  for (row=0;row<rows;row++) {
	    if (getToken(ptr,data,10240,separator,whitespace) < 0) {
	      SDDS_SetError("Invalid long column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
	    if (sscanf(data,"%" SCNd32,((int32_t*)(columnValues[col].values)+row)) != 1) {
	      SDDS_SetError("Invalid long column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
	  }
	  break;
	case SDDS_FLOAT:
	  for (row=0;row<rows;row++) {
	    if (getToken(ptr,data,10240,separator,whitespace) < 0) {
	      SDDS_SetError("Invalid float column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
            ConvertDNotationToENotation(data);
	    if (sscanf(data,"%f",((float*)(columnValues[col].values)+row)) != 1) {
	      SDDS_SetError("Invalid float column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
	  }
	  break;
	case SDDS_DOUBLE:
	  for (row=0;row<rows;row++) {
	    if (getToken(ptr,data,10240,separator,whitespace) < 0) {
	      SDDS_SetError("Invalid double column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
            ConvertDNotationToENotation(data);
	    if (sscanf(data,"%lf",((double*)(columnValues[col].values)+row)) != 1) {
	      SDDS_SetError("Invalid double column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
	  }
	  break;
	case SDDS_STRING:
	  for (row=0;row<rows;row++) {
	    if (getToken(ptr,data,10240,separator,whitespace) < 0) {
	      SDDS_SetError("Invalid string column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
	    SDDS_InterpretEscapes(data);
            columnValues[col].stringValues[row] = malloc(strlen(data) + 1);
	    strcpy(columnValues[col].stringValues[row],data);
	  }
	  break;
	case SDDS_CHARACTER:
	  for (row=0;row<rows;row++) {
	    if (getToken(ptr,data,10240,separator,whitespace) < 0) {
	      SDDS_SetError("Invalid character column element");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	    }
	    SDDS_InterpretEscapes(data);
	    *((char*)(columnValues[col].values)+row) = data[0];
	  }
	  break;
	}
	if (rows > maxRows) {
	  if (!SDDS_LengthenTable(&SDDS_dataset, rows - maxRows)) {
	    SDDS_SetError("Unable to lengthen table");
	    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	  }
	  maxRows = rows;
	}
	if (columnValues[col].skip == 0) {
	  if (columnValues[col].type == SDDS_STRING) {
	    SetColumnData(columnValues[col].type, &SDDS_dataset, columnValues[col].stringValues, rows, col);
	  } else {
	    SetColumnData(columnValues[col].type, &SDDS_dataset, columnValues[col].values, rows, col);
	  }
	  n++;
	}
	col++;
	row = 0;
      } else {
	if (noRowCount) {
	  if (row == 0) {
	    rows = 3;
	  } else if (row == rows - 1) {
	    rows = rows + 3;
	    for (i=0;i<columns;i++) {
	      if (rows > columnValues[i].elements) {
		if (columnValues[i].type == SDDS_STRING) {
		  columnValues[i].stringValues = AllocateColumnStringData(columnValues[i].stringValues, rows, columnValues[i].elements);
		} else {
		  columnValues[i].values = AllocateColumnData(columnValues[i].type, columnValues[i].values, rows);
                }
	      }
	      columnValues[i].elements = rows;
	    }
	  }
	}
	if (row == 0) 
	  for (i=0;i<columns;i++) {
	    if (rows > columnValues[i].elements) {
	      if (columnValues[i].type == SDDS_STRING) {
		columnValues[i].stringValues = AllocateColumnStringData(columnValues[i].stringValues, rows, columnValues[i].elements);
	      } else {
		columnValues[i].values = AllocateColumnData(columnValues[i].type, columnValues[i].values, rows);
              }
	    }
	    columnValues[i].elements = rows;
	  }

	if (noRowCount) {
	  cp_str(&ptr2,ptr);
	  i = 0;
	  while (getToken(ptr2,data,10240,separator,whitespace) >= 0)
	    i++;
          free(ptr2);
	  if ((i != columns) && (parameters>0 && i==1)) {
	    if (row > 0) {
	      if (row > maxRows) {
		if (!SDDS_LengthenTable(&SDDS_dataset, row - maxRows)) {
		  SDDS_SetError("Unable to lengthen table");
		  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
		}
		maxRows = row;
	      }
	      n=0;
	      for (j=0;j<columns;j++) {
		if (columnValues[j].skip)
		  continue;
		if (columnValues[j].type == SDDS_STRING) {
		  SetColumnData(columnValues[j].type, &SDDS_dataset, columnValues[j].stringValues, row, n);
		} else {
		  SetColumnData(columnValues[j].type, &SDDS_dataset, columnValues[j].values, row, n);
		}
		n++;
	      }
	      if (!SDDS_WritePage(&SDDS_dataset))
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	      maxRows = 10000;
	      if (!SDDS_StartPage(&SDDS_dataset, initRows))
		SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
	      row = par = col = 0;
	      rows = -1;
	    }
	    readline = 0;
	    continue;
	  }
	}

	for (i=0;i<columns;i++) {
	  if (getToken(ptr,data,10240,separator,whitespace) < 0) {
            if (!fillin) {
              SDDS_SetError("Invalid column element");
              SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
            } else {
              switch (columnValues[i].type) {
              case SDDS_SHORT:
              case SDDS_LONG:
              case SDDS_FLOAT:
              case SDDS_DOUBLE:
                data[0]='0';
                data[1]='\0';
                break;
              case SDDS_STRING:  
              case SDDS_CHARACTER:
                data[0]='\0';
                break;
              }
            }
	  }

	  switch (columnValues[i].type) {
	  case SDDS_SHORT:
	    if (sscanf(data,"%hd",((short*)(columnValues[i].values)+row)) != 1) {
              if (recover) {
                abort=1;
                row--;
              } else {
                SDDS_SetError("Invalid short column element");
                SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
              }
            }
	    break;
	  case SDDS_LONG:
	    if (sscanf(data,"%" SCNd32,((int32_t*)(columnValues[i].values)+row)) != 1) {
              if (recover) {
                abort=1;
                row--;
              } else {
                SDDS_SetError("Invalid long column element");
                SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
              }
            }
	    break;
	  case SDDS_FLOAT:
            ConvertDNotationToENotation(data);
	    if (sscanf(data,"%f",((float*)(columnValues[i].values)+row)) != 1) {
              if (recover) {
                abort=1;
                row--;
              } else {
                SDDS_SetError("Invalid float column element");
                SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
              }
            }
	    break;
	  case SDDS_DOUBLE:
            ConvertDNotationToENotation(data);
	    if (sscanf(data,"%lf",((double*)(columnValues[i].values)+row)) != 1) {
              if (recover) {
                abort=1;
                row--;
              } else {
                SDDS_SetError("Invalid double column element");
                SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
              }
	    }
	    break;
	  case SDDS_STRING:
	    SDDS_InterpretEscapes(data);
            columnValues[i].stringValues[row] = malloc(strlen(data) + 1);
	    strcpy(columnValues[i].stringValues[row],data);
	    break;
	  case SDDS_CHARACTER:
	    SDDS_InterpretEscapes(data);
	    *((char*)(columnValues[i].values)+row) = data[0];
	    break;
	  }

          if (recover && abort) {
            break;
          }
        }
	row++;
	if ((row == rows) && (!noRowCount)) {
	  if (rows > maxRows) {
	    if (!SDDS_LengthenTable(&SDDS_dataset, rows - maxRows)) {
	      SDDS_SetError("Unable to lengthen table");
	      SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	    }
	    maxRows = rows;
	  }
	  n=0;
	  for (i=0;i<columns;i++) {
	    if (columnValues[i].skip)
	      continue;
	    if (columnValues[i].type == SDDS_STRING) {
	      SetColumnData(columnValues[i].type, &SDDS_dataset, columnValues[i].stringValues, rows, n);
	    } else {
	      SetColumnData(columnValues[i].type, &SDDS_dataset, columnValues[i].values, rows, n);
	    }
	    n++;
	  }
	}
      }
    }
    if ((par == parameters) && 
	(((!noRowCount) && (rows != -1)) || (noRowCount)) && 
	(((columnOrder) && (col == columns)) || ((columns > 0) && (row == rows)) || (columns == 0))) {
      if (!SDDS_WritePage(&SDDS_dataset)) {
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
      maxRows = 10000;
      if (!SDDS_StartPage(&SDDS_dataset, initRows))
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      
      row = par = col = 0;
      rows = -1;
    }
    ptr[0] = 0;
  }

  if (noRowCount) {
    if (row > 0) {
      if (row > maxRows) {
	if (!SDDS_LengthenTable(&SDDS_dataset, row - maxRows)) {
	  SDDS_SetError("Unable to lengthen table");
	  SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors); 
	}
	maxRows = row;
      }
      n=0;
      for (j=0;j<columns;j++) {
	if (columnValues[j].skip)
	  continue;
	if (columnValues[j].type == SDDS_STRING) {
	  SetColumnData(columnValues[j].type, &SDDS_dataset, columnValues[j].stringValues, row, n);
	} else {
	  SetColumnData(columnValues[j].type, &SDDS_dataset, columnValues[j].values, row, n);
	}
	n++;
      }
      if (!SDDS_WritePage(&SDDS_dataset)) {
	SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
      }
      maxRows = 10000;
    }
  }
  for (i=0;i<columns;i++) {
    if (columnValues[i].type == SDDS_STRING) {
      for (j=0;j<columnValues[i].elements;j++) {
	free(columnValues[i].stringValues[j]);
      }
      free(columnValues[i].stringValues);
    } else {
      free(columnValues[i].values);
    }
    if (columnValues[i].name) free(columnValues[i].name);
    if (columnValues[i].units) free(columnValues[i].units);
    if (columnValues[i].description) free(columnValues[i].description);
    if (columnValues[i].symbol) free(columnValues[i].symbol);

  }
  for (i=0;i<parameters;i++) {
    free(parameterValues[i].name);
    if (parameterValues[i].units) free(parameterValues[i].units);
    if (parameterValues[i].description) free(parameterValues[i].description);
    if (parameterValues[i].symbol) free(parameterValues[i].symbol);
  }
  if (columnValues) free(columnValues);
  if (parameterValues) free(parameterValues);
  if (columnIndex) free(columnIndex);
  if (parameterIndex) free(parameterIndex);
  if (ptr) free(ptr);
  if (!SDDS_Terminate(&SDDS_dataset))
    SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors|SDDS_EXIT_PrintErrors);
  free_scanargs(&s_arg,argc);
  return 0;
}
/*
 * Modifies the attributes of an item currently in the listview.
 */
void CFolderView::ModifyItemInternal(TCHAR *FileName)
{
	HANDLE			hFirstFile;
	ULARGE_INTEGER	ulFileSize;
	LVITEM			lvItem;
	TCHAR			FullFileName[MAX_PATH];
	BOOL			bFolder;
	BOOL			res;
	int				iItem;
	int				iItemInternal = -1;

	iItem = LocateFileItemIndex(FileName);

	/* Although an item may not have been added to the listview
	yet, it is critical that its' size still be updated if
	neccesary.
	It is possible (and quite likely) that the file add and
	modified messages will be sent in the same group, meaning
	that when the modification message is processed, the item
	is not in the listview, but it still needs to be updated.
	Therefore, instead of searching for items soley in the
	listview, also look through the list of pending file
	additions. */

	if(iItem == -1)
	{
		/* The item doesn't exist in the listview. This can
		happen when a file has been created with a non-zero
		size, but an item has not yet been inserted into
		the listview.
		Search through the list of items waiting to be
		inserted, so that files the have just been created
		can be updated without them residing within the
		listview. */
		list<AwaitingAdd_t>::iterator itr;

		for(itr = m_AwaitingAddList.begin();itr!= m_AwaitingAddList.end();itr++)
		{
			if(lstrcmp(m_pwfdFiles[itr->iItemInternal].cFileName,FileName) == 0)
			{
				iItemInternal = itr->iItemInternal;
				break;
			}
		}
	}
	else
	{
		/* The item exists in the listview. Determine its
		internal index from its listview information. */
		lvItem.mask		= LVIF_PARAM;
		lvItem.iItem	= iItem;
		lvItem.iSubItem	= 0;
		res = ListView_GetItem(m_hListView,&lvItem);

		if(res != FALSE)
			iItemInternal = (int)lvItem.lParam;
	}

	if(iItemInternal != -1)
	{
		/* Is this item a folder? */
		bFolder = (m_pwfdFiles[iItemInternal].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
			FILE_ATTRIBUTE_DIRECTORY;

		ulFileSize.LowPart = m_pwfdFiles[iItemInternal].nFileSizeLow;
		ulFileSize.HighPart = m_pwfdFiles[iItemInternal].nFileSizeHigh;

		m_ulTotalDirSize.QuadPart -= ulFileSize.QuadPart;

		if(ListView_GetItemState(m_hListView,iItem,LVIS_SELECTED)
		== LVIS_SELECTED)
		{
			ulFileSize.LowPart = m_pwfdFiles[iItemInternal].nFileSizeLow;
			ulFileSize.HighPart = m_pwfdFiles[iItemInternal].nFileSizeHigh;

			m_ulFileSelectionSize.QuadPart -= ulFileSize.QuadPart;
		}

		StringCchCopy(FullFileName,SIZEOF_ARRAY(FullFileName),m_CurDir);
		PathAppend(FullFileName,FileName);

		hFirstFile = FindFirstFile(FullFileName,&m_pwfdFiles[iItemInternal]);

		if(hFirstFile != INVALID_HANDLE_VALUE)
		{
			ulFileSize.LowPart = m_pwfdFiles[iItemInternal].nFileSizeLow;
			ulFileSize.HighPart = m_pwfdFiles[iItemInternal].nFileSizeHigh;

			m_ulTotalDirSize.QuadPart += ulFileSize.QuadPart;

			if(ListView_GetItemState(m_hListView,iItem,LVIS_SELECTED)
				== LVIS_SELECTED)
			{
				ulFileSize.LowPart = m_pwfdFiles[iItemInternal].nFileSizeLow;
				ulFileSize.HighPart = m_pwfdFiles[iItemInternal].nFileSizeHigh;

				m_ulFileSelectionSize.QuadPart += ulFileSize.QuadPart;
			}

			if((m_pwfdFiles[iItemInternal].dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ==
				FILE_ATTRIBUTE_HIDDEN)
			{
				ListView_SetItemState(m_hListView,iItem,LVIS_CUT,LVIS_CUT);
			}
			else
				ListView_SetItemState(m_hListView,iItem,0,LVIS_CUT);

			if(m_ViewMode == VM_DETAILS)
			{
				list<Column_t>::iterator itrColumn;
				int iColumnIndex = 0;

				if(m_pActiveColumnList != NULL)
				{
					for(itrColumn = m_pActiveColumnList->begin();itrColumn != m_pActiveColumnList->end();itrColumn++)
					{
						if(itrColumn->bChecked)
						{
							SetColumnData(itrColumn->id,iItem,iColumnIndex++);
						}
					}
				}
			}

			FindClose(hFirstFile);
		}
		else
		{
			/* The file may not exist if, for example, it was
			renamed just after a file with the same name was
			deleted. If this does happen, a modification
			message will likely be sent out after the file
			has been renamed, indicating the new items properties.
			However, the files' size will be subtracted on
			modification. If the internal structures still hold
			the old size, the total directory size will become
			corrupted. */
			m_pwfdFiles[iItemInternal].nFileSizeLow		= 0;
			m_pwfdFiles[iItemInternal].nFileSizeHigh	= 0;
		}
	}
}