int FileUtils::PrintLines(string fname)
{
   char line[1024];

   int ret;

   ret = OpenFileForRead(fname);
   if(!ret) return -1;

   ret = AllocBuffer();
   if(!ret) return -1;
   ret = FirstRead();
   if(!ret) 
   {
      Release();
      return -1;
   }
   while(1)
   {
      ret = GetLine(line,1024);
      
      Trim(line);
      MakeLower(line);
      cout<<"|"<<line<<"|"<<endl;
      if(ret) break;
   }
   Release();
   return 1;
}
int ProcessOptions::ParseFile(const char *filespec, POVMSObjectPtr obj)
{
	ITextStream *file = NULL;
	const char *currentsection = NULL;
	char *sectionname = NULL;
	char *filename = NULL;
	int err = kNoErr;
	POVMSObjectPtr section = NULL;
	int currentline = 1;

	// split the INI files specification into filename and optional section name
	err = Parse_INI_Specification(filespec, filename, sectionname);
	if(err == kNoErr)
	{
		file = OpenFileForRead(filename, obj);
		if(file == NULL)
		{
			// all errors here are non-fatal, the calling code has to decide if an error is fatal
			ParseError("Cannot open INI file '%s'.", filename);
			err= kCannotOpenFileErr;
		}
	}

	if(err == kNoErr)
	{
		int token = 0;

		// apply options prior to any named section
		section = obj;

		// read the whole file to the end
		while((file->eof() == false) && (err == kNoErr))
		{
			currentline += Parse_INI_Skip_Space(file, true);

			token = file->getchar();

			// INI file section name
			if(token == '[')
			{
				// free old section name, if any
				if(currentsection != NULL)
					delete[] currentsection;

				// read until the section name end marker
				currentsection = Parse_INI_String(file, ']');

				// if the user specified a section name, compare the two and enable reading
				if((sectionname != NULL) && (currentsection != NULL))
				{
					if(pov_stricmp(currentsection, sectionname) == 0)
						section = obj; // named section matches specified section name, apply options
					else
						section = NULL; // named section does not match specified section name, ignore options
				}
				// if there was no user specified section name, ignore all named sections
				else
					section = NULL; // no section name was specified, ignore options in named section
			}
			// skip lines that do not belong to the desired sections
			else if(section == NULL)
			{
				currentline += Parse_INI_Skip_Line(file);
			}
			// fully process lines in desired sections
			else
			{
				switch(token)
				{
					// end of file
					case EOF:
						break;
					// quoted string
					case '\"':
					case '\'':
						err = kFalseErr;
						break;
					// POV-Ray-style INI file with command-line switch
					case '+':
					case '-':
					// POV-Ray-style INI file with system specific command-line switch on some systems (i.e. Windos)
					#if(FILENAME_SEPARATOR != '/')
					case '/':
					#endif
						err = Parse_INI_Switch(file, token, section);
						break;
					// INI file comment
					case ';':
					case '#':
						currentline += Parse_INI_Skip_Line(file);
						break;
					// INI file option
					default:
						if(isalnum(token) || (token == '_'))
						{
							file->ungetchar(token);
							ITextStream::FilePos backtrackpos = file->tellg();
							err = Parse_INI_Option(file, section);
							// only one option is allowed per line
							if(err == kNoErr)
								currentline += Parse_INI_Skip_Line(file);
							else if(err == kParseErr)
							{
								file->seekg(backtrackpos);
								err = kFalseErr;
							}
						}
						else
							err = kFalseErr;
						break;
				}

				// if nothing else was appropriate, assume it is some other kind of string requiring special attention
				if(err == kFalseErr)
				{
					char *plainstring = NULL;

					if((token == '\"') || (token == '\''))
						plainstring = Parse_INI_String(file, token, true);
					// if there were no quotes, just read up to the next space or newline
					else
						plainstring = Parse_INI_String(file, -1, true);

					err = ProcessUnknownString(plainstring, obj);

					if(plainstring != NULL)
						delete[] plainstring;
				}
			}
		}

		// all errors here are non-fatal, the calling code has to decide if an error is fatal
		if(err != kNoErr)
		{
			if(currentsection != NULL)
			{
				ParseErrorAt(file,
				             "Cannot continue to process INI file '%s' due to a parse error in line %d section '%s'.\n"
				             "This is not a valid INI file. Check the file for syntax errors, correct them, and try again!\n"
				             "Valid options in INI files are explained in detail in the reference part of the documentation.",
				             filename, currentline, currentsection);
			}
			else
			{
				ParseErrorAt(file,
				             "Cannot continue to process INI file '%s' due to a parse error in line %d.\n"
				             "This is not a valid INI file. Check the file for syntax errors, correct them, and try again!\n"
				             "Valid options in INI files are explained in detail in the reference part of the documentation.",
				             filename, currentline);
			}
		}

		if(currentsection != NULL)
			delete[] currentsection;
	}

	if(filename != NULL)
		delete[] filename;

	if(sectionname != NULL)
		delete[] sectionname;

	if(file != NULL)
		delete file;

	return err;
}
void FileUtils::qsortfile(string m_fname1,char delimiter) 
{
   // TODO: Add your control notification handler code here
   char line[10240];
   Ref* refseq=NULL;

   if(m_fname1 == "")
   {
      cout<<"please input a file for sort!"<<endl;
      return;
   }


   int ret;
   int total = CountLines(m_fname1);

   ret = OpenFileForRead(m_fname1);
   if(!ret) return;
   ret = OpenFileForWrite(m_fname1);
   if(!ret) return;

   ret = AllocBuffer();
   if(!ret) return;
   ret = FirstRead();
   if(!ret) 
   {
      Release();
      return;
   }

   refseq = new Ref[50000];
   if(!refseq)
   {
      Release();
      return;
   }

   cout<<"Begin to process:"<<endl;
   int k = 0;
   int count = 0;
   while(k < total)
   {
      ret = GetLine(line,10240);

      string buffer = line;
      count = GetFieldsNum(buffer,delimiter);
   
      for(int j=0;j<count;j++)
      {
         string field = GetField(buffer,j+1,delimiter);

         strcpy(refseq[k].field[j],field.c_str());
      }

      cout<<"...";
      k++;
   }
   
   qsort(refseq,k,sizeof(Ref),cmp); 

   char line1[1024];
   line1[0] = '\0';

   //write the sorted resuts to file
   for(int j=0; j<k;j++)
   {
      strcpy(line1,"");
      for(int kk=0;kk<count-1;kk++)
      {
         strcat(line1,refseq[j].field[kk]);
         strcat(line1,"\t");
      }
      strcat(line1,refseq[j].field[count-1]);
      WriteLine(line1);
   }
   LastWrite();

   delete[] refseq;
   Release();   
}