testexecmgmt/ucc/Source/DynamicsConfigurationLibrary/file_utilities.cpp
changeset 0 3da2a79470a7
equal deleted inserted replaced
-1:000000000000 0:3da2a79470a7
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 * System Includes
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include <stdio.h>
       
    22 #include <assert.h>
       
    23 #include <errno.h>
       
    24 #include <stdlib.h>
       
    25 #ifndef WIN32
       
    26 #include <unistd.h>
       
    27 #else
       
    28 #include <io.h>
       
    29 #endif
       
    30 #include <assert.h>
       
    31  
       
    32 
       
    33 /******************************************************************************************************
       
    34  *
       
    35  * Local Includes
       
    36  *
       
    37  *****************************************************************************************************/
       
    38 #include "file_utilities.h"
       
    39 
       
    40 
       
    41 /******************************************************************************************************
       
    42  *
       
    43  * Definitions
       
    44  *
       
    45  *****************************************************************************************************/
       
    46 #define TEMPFILE_SUFFIX               "XXXXXX"
       
    47 #define MAXLINESIZE                    2048
       
    48 #define COPYBUFFER                     2048
       
    49 #define TEMPFILENAMESIZE               128
       
    50 #define INSERT_TEMPFILE_PREFIX         "insert_tempfile."
       
    51 
       
    52 #define MIN(a,b)                       (((a)<(b))?a:b)
       
    53 
       
    54 
       
    55 /******************************************************************************************************
       
    56  *
       
    57  * Prototypes
       
    58  *
       
    59  *****************************************************************************************************/
       
    60 #ifdef WIN32
       
    61 static int mkstemp( char *aString );
       
    62 #endif
       
    63 
       
    64 
       
    65 /******************************************************************************************************
       
    66  *
       
    67  * PRIVATE METHOD: OpenTempfile
       
    68  *
       
    69  *****************************************************************************************************/
       
    70 FILE *OpenTempfile( char *aFilenamePrefix, char *aFilename, int aLen, char *aMode, int *aSystemError )
       
    71 {
       
    72   int err, prefix_len;
       
    73   FILE *fp;
       
    74 
       
    75   // check params
       
    76   assert( aFilenamePrefix != NULL );
       
    77   assert( aFilename != NULL );
       
    78   assert( aSystemError != NULL );
       
    79   assert( aLen > (strlen(TEMPFILE_SUFFIX) + 1) );
       
    80   *aSystemError = 0;
       
    81 
       
    82   // copy the prefix into the buffer
       
    83   prefix_len = MIN( strlen(aFilenamePrefix), (aLen - strlen(TEMPFILE_SUFFIX) - 1) );
       
    84   memcpy( aFilename, aFilenamePrefix, prefix_len );
       
    85 
       
    86   // copy the template into the buffer and NULL terminate
       
    87   memcpy( &(aFilename[prefix_len]), TEMPFILE_SUFFIX, strlen(TEMPFILE_SUFFIX) );
       
    88   aFilename[prefix_len + strlen(TEMPFILE_SUFFIX)] = 0;
       
    89   
       
    90   // get the filename
       
    91   err = mkstemp( aFilename );
       
    92   if( err == -1 ) { 
       
    93     *aSystemError = errno;
       
    94     return NULL;
       
    95   }
       
    96 
       
    97   // now open the file
       
    98   fp = fopen( aFilename, aMode );
       
    99   if( fp == NULL ) {
       
   100     *aSystemError = errno;
       
   101   }
       
   102   return fp;
       
   103 }
       
   104 
       
   105 
       
   106 /******************************************************************************************************
       
   107  *
       
   108  * PRIVATE METHOD: CopyFileByPtr
       
   109  *
       
   110  *****************************************************************************************************/
       
   111 TFUError CopyFileByPtr( FILE *aSource, FILE *aDest, int *aSystemError )
       
   112 {
       
   113   char buff[COPYBUFFER];
       
   114   int bytes_read, bytes_written;
       
   115 
       
   116   // check params
       
   117   assert( aSource != NULL );
       
   118   assert( aDest != NULL );
       
   119   assert( aSystemError != NULL );
       
   120   *aSystemError = 0;
       
   121 
       
   122   // now copy all the bytes
       
   123   while( 1 ) {
       
   124 
       
   125     // read from the source
       
   126     bytes_read = fread( buff, 1, COPYBUFFER, aSource );
       
   127     assert( bytes_read >= 0 );
       
   128 
       
   129     // check for read errors 
       
   130     if( ferror(aSource) != 0 ) {
       
   131       *aSystemError = errno;
       
   132       return FUE_READ_ERROR;
       
   133     }
       
   134 
       
   135     // if some bytes were read then write to the destination
       
   136     bytes_written = fwrite( buff, 1, bytes_read, aDest );
       
   137     assert( bytes_written >= 0 );
       
   138 
       
   139     // check for write errors
       
   140     if( bytes_written != bytes_read ) {
       
   141       *aSystemError = errno;
       
   142       return FUE_WRITE_ERROR;
       
   143     }
       
   144 
       
   145     // check for eof 
       
   146     if( feof(aSource) != 0 ) {
       
   147       return FUE_NONE;
       
   148     }
       
   149   }
       
   150 
       
   151   // done
       
   152   assert( !"INVALID CODE PATH" );
       
   153   return FUE_NONE;
       
   154 }
       
   155 
       
   156 
       
   157 /******************************************************************************************************
       
   158  *
       
   159  * PRIVATE METHOD: CopyFileByName
       
   160  *
       
   161  *****************************************************************************************************/
       
   162 TFUError CopyFileByName( char *aSource, char *aDest, int *aSystemError )
       
   163 {
       
   164   FILE *fpsrc, *fpdst;
       
   165   TFUError err;
       
   166 
       
   167   // check params
       
   168   assert( aSource != NULL );
       
   169   assert( aDest != NULL );
       
   170   assert( aSystemError != NULL );
       
   171   *aSystemError = 0;
       
   172 
       
   173   // open the source filename
       
   174   fpsrc = fopen( aSource, "r" );
       
   175   if( fpsrc == NULL ) {
       
   176     *aSystemError = errno;
       
   177     return FUE_OPEN_ERROR;
       
   178   }
       
   179 
       
   180   // open the dest filename
       
   181   fpdst = fopen( aDest, "w" );
       
   182   if( fpdst == NULL ) {
       
   183     fclose( fpsrc );
       
   184     *aSystemError = errno;
       
   185     return FUE_OPEN_ERROR;
       
   186   }
       
   187   
       
   188   // copy the files
       
   189   err = CopyFileByPtr( fpsrc, fpdst, aSystemError );
       
   190 
       
   191   // close the files
       
   192   fflush( fpsrc );
       
   193   fflush( fpdst );
       
   194   fclose( fpsrc );
       
   195   fclose( fpdst );
       
   196 
       
   197   // if the copy failed then remove the new file
       
   198   if( err != FUE_NONE ) {
       
   199     unlink( aDest );
       
   200   }
       
   201 
       
   202   // done
       
   203   return err;      
       
   204 }
       
   205 
       
   206 
       
   207 /******************************************************************************************************
       
   208  *
       
   209  * PRIVATE METHOD: InsertLine
       
   210  *
       
   211  *****************************************************************************************************/
       
   212 TFUError InsertLine( char *aFilename, int aLineNumber, char *aLine, int aLineSize, int aReplaceFlag, int *aSystemError )
       
   213 {
       
   214   char buff[COPYBUFFER], tempfilename[TEMPFILENAMESIZE];
       
   215   int i, end_of_file, err, insert_line_logic, line_inserted = 0;
       
   216   TFUError rv;
       
   217   FILE *fp_dest, *fp_source;
       
   218 
       
   219   // check params
       
   220   assert( aFilename != NULL );
       
   221   assert( (aLine != NULL) || (aLineSize == 0) );
       
   222   assert( aSystemError != NULL );
       
   223   assert( aLineNumber > 0 );
       
   224   *aSystemError = 0;
       
   225 
       
   226   // open the file
       
   227   fp_source = fopen( aFilename, "r" );
       
   228   if( fp_source == NULL ) {
       
   229     *aSystemError = errno;
       
   230     return FUE_OPEN_SOURCE_ERROR;
       
   231   }
       
   232 
       
   233   // now open the tempfile
       
   234   fp_dest = OpenTempfile( INSERT_TEMPFILE_PREFIX, tempfilename, TEMPFILENAMESIZE, "w", aSystemError );
       
   235   if( fp_dest == NULL ) {
       
   236     fclose( fp_source );
       
   237     return FUE_OPEN_TEMP_ERROR;
       
   238   }
       
   239 
       
   240   // now copy all files until we get to the target line - add the new line - then keep going
       
   241   for( i = 1; ; i++ ) {
       
   242     
       
   243     // read the next line from the source file 
       
   244     fgets( buff, COPYBUFFER, fp_source );
       
   245 
       
   246     // check for errors
       
   247     if( ferror(fp_source) != 0 ) {
       
   248       *aSystemError = errno;
       
   249       rv = FUE_READ_ERROR;
       
   250       break;
       
   251     }
       
   252 
       
   253     // see if we want to insert the newline at this point: we do if the user specified to insert before 
       
   254     // this line OR if we have hit the end of the file. In both cases there must be something to insert.
       
   255     end_of_file = feof( fp_source );
       
   256     insert_line_logic = ((aLineNumber == i) || ((line_inserted == 0)&&(end_of_file != 0)));
       
   257     if( (insert_line_logic != 0) && (aLineSize > 0) ) {
       
   258       fwrite( aLine, 1, aLineSize, fp_dest );
       
   259       if( ferror(fp_dest) != 0 ) {
       
   260 	*aSystemError = errno;
       
   261 	rv = FUE_WRITE_ERROR;
       
   262 	break;
       
   263       }
       
   264       fputc( '\n', fp_dest );
       
   265       line_inserted = 1;
       
   266     }
       
   267     
       
   268     // if we have hit the end of the file then we are done
       
   269     if( end_of_file != 0 ) {
       
   270       rv = FUE_NONE;
       
   271       break;
       
   272     }
       
   273 
       
   274     // write the line just read -- unless we just inserted a line and the replace flag is set
       
   275     if( (insert_line_logic == 0) || (aReplaceFlag == 0) ) {
       
   276       fwrite( buff, 1, strlen(buff), fp_dest );
       
   277       if( ferror(fp_dest) != 0 ) {
       
   278 		*aSystemError = errno;
       
   279 		rv = FUE_WRITE_ERROR;
       
   280 		break;
       
   281       }
       
   282     }
       
   283     
       
   284     // go to next line
       
   285   }
       
   286 
       
   287   // close both files
       
   288   fflush( fp_source );
       
   289   fflush( fp_dest );
       
   290   fclose( fp_source );
       
   291   fclose( fp_dest );
       
   292 
       
   293   // if we were successful then remove the original file and rename the new file to the original 
       
   294   // filename -- otherwise just remove the tempfile
       
   295   if( rv == FUE_NONE ) {
       
   296     unlink( aFilename );
       
   297     err = rename( tempfilename, aFilename );
       
   298     if( err != 0 ) {
       
   299       *aSystemError = errno;
       
   300       rv = FUE_RENAME_ERROR;
       
   301       unlink( tempfilename );
       
   302     }
       
   303   } else {
       
   304     unlink( tempfilename );
       
   305   }
       
   306       
       
   307   // done
       
   308   return rv;
       
   309 }
       
   310 
       
   311 
       
   312 /******************************************************************************************************
       
   313  *
       
   314  * PRIVATE METHOD: GetLine
       
   315  *
       
   316  *****************************************************************************************************/
       
   317 TFUError GetLine( char *aFilename, int aLineNumber, char *aBuffer, int aBufferSize, int *aSystemError )
       
   318 {
       
   319   FILE *fp;
       
   320   char *cline;
       
   321   int i;
       
   322 
       
   323   // check params
       
   324   assert( aLineNumber >= 0 );
       
   325   assert( aBuffer != NULL );
       
   326   assert( aSystemError != NULL );
       
   327   *aSystemError = 0;
       
   328 
       
   329   // open the file
       
   330   fp = fopen( aFilename, "r" );
       
   331   if( fp == NULL ) {
       
   332     *aSystemError = errno;
       
   333     return FUE_OPEN_ERROR;
       
   334   }
       
   335 
       
   336   // read through the file until finding the appropriate line
       
   337   for( i = 0; i < aLineNumber; i++ ) {
       
   338     cline = fgets( aBuffer, aBufferSize, fp );
       
   339     if( cline == NULL )
       
   340       break;
       
   341   }
       
   342 
       
   343   // done with the file
       
   344   fflush( fp );
       
   345   fclose( fp );
       
   346 
       
   347   // if cline is null then we reached the end-of-file
       
   348   if( cline == NULL ) {
       
   349     return FUE_END_OF_FILE;
       
   350   }
       
   351 
       
   352   // otherwise just return -- the line is in the buffer
       
   353   return FUE_NONE;
       
   354 }
       
   355 
       
   356 
       
   357 /******************************************************************************************************
       
   358  *
       
   359  * PRIVATE METHOD: FindMatchingLines
       
   360  *
       
   361  *****************************************************************************************************/
       
   362 TFUError FindMatchingLines( char *aFilename, char *aToken, int *aLineList, int *aListSize, int *aSystemError )
       
   363 {
       
   364   int list_capacity, i, match;
       
   365   char cline[MAXLINESIZE], *cptr, *token_start, *token_end;
       
   366   FILE *fp;
       
   367   TFUError rv;
       
   368 
       
   369   // check params
       
   370   assert( aFilename != NULL );
       
   371   assert( aToken != NULL );
       
   372   assert( aLineList != NULL );
       
   373   assert( aListSize != NULL );
       
   374   assert( aSystemError != NULL );
       
   375   list_capacity = *aListSize;
       
   376   *aListSize = 0;
       
   377   *aSystemError = 0;
       
   378 
       
   379   // open the file
       
   380   fp = fopen( aFilename, "r" );
       
   381   if( fp == NULL ) {
       
   382     *aSystemError = errno;
       
   383     return FUE_OPEN_ERROR;
       
   384   }
       
   385 
       
   386   // now read through the line and look for a line starting with the passed token (after whitespace and '#')
       
   387   for( i = 1; ; i++ ) {
       
   388     
       
   389     // read the next line
       
   390     cptr = fgets( cline, MAXLINESIZE, fp );
       
   391     
       
   392     // check for errors
       
   393     if( ferror(fp) != 0 ) {
       
   394       *aSystemError = errno;
       
   395       rv = FUE_READ_ERROR;
       
   396       break;
       
   397     }
       
   398 
       
   399     // check for end of file
       
   400     if( cptr == NULL ) {
       
   401       rv =  FUE_NONE;
       
   402       break;
       
   403     }
       
   404 
       
   405     // remove any whitespace (' ' + '\t') and hashes to find the start of the token
       
   406     for( token_start = cline; (*token_start == ' ') || (*token_start == '\t') || (*token_start == '#'); token_start++ )
       
   407       ;
       
   408 
       
   409     // now find the end of the token
       
   410     for( token_end = token_start; (*token_end != ' ') && (*token_end != '\t') && (*token_end != '\n') && (*token_end != 0); token_end++ ) 
       
   411       ;
       
   412 
       
   413     // null terminate the token - no need to save the old value
       
   414     *token_end = 0;
       
   415 
       
   416     // now compare the tokens and add the match
       
   417     match = strcmp( token_start, aToken );
       
   418     if( (match == 0) && ((*aListSize) < list_capacity) ) {
       
   419 		aLineList[(*aListSize)++] = i;
       
   420     }
       
   421 	
       
   422     // and do it all again
       
   423   }
       
   424 
       
   425   // close up the file and return
       
   426   fflush( fp );
       
   427   fclose( fp );
       
   428 
       
   429   // done
       
   430   return rv;
       
   431 }
       
   432 
       
   433 
       
   434 /******************************************************************************************************
       
   435  *
       
   436  * PRIVATE METHOD: FindMatchingLinesByRawPrefix
       
   437  *
       
   438  *****************************************************************************************************/
       
   439 TFUError FindMatchingLinesByRawPrefix( char *aFilename, char *aToken, int *aLineList, int *aListSize, int *aSystemError )
       
   440 {
       
   441   int list_capacity, i, match, token_length;
       
   442   char cline[MAXLINESIZE], *cptr;
       
   443   FILE *fp;
       
   444   TFUError rv;
       
   445 
       
   446   // check params
       
   447   assert( aFilename != NULL );
       
   448   assert( aToken != NULL );
       
   449   assert( aLineList != NULL );
       
   450   assert( aListSize != NULL );
       
   451   assert( aSystemError != NULL );
       
   452   list_capacity = *aListSize;
       
   453   *aListSize = 0;
       
   454   *aSystemError = 0;
       
   455 
       
   456   // get the length of the passed token
       
   457   token_length = strlen( aToken );
       
   458   assert( token_length > 0 );
       
   459 
       
   460   // open the file
       
   461   fp = fopen( aFilename, "r" );
       
   462   if( fp == NULL ) {
       
   463     *aSystemError = errno;
       
   464     return FUE_OPEN_ERROR;
       
   465   }
       
   466 
       
   467   // now read through the line and look for a line starting with the passed token
       
   468   for( i = 1; ; i++ ) {
       
   469     
       
   470     // read the next line
       
   471     cptr = fgets( cline, MAXLINESIZE, fp );
       
   472     
       
   473     // check for errors
       
   474     if( ferror(fp) != 0 ) {
       
   475       *aSystemError = errno;
       
   476       rv = FUE_READ_ERROR;
       
   477       break;
       
   478     }
       
   479 
       
   480     // check for end of file
       
   481     if( cptr == NULL ) {
       
   482       rv =  FUE_NONE;
       
   483       break;
       
   484     }
       
   485 
       
   486 
       
   487     // now compare the tokens and add the match
       
   488     match = strncmp( cptr, aToken, token_length );
       
   489     if( (match == 0) && ((*aListSize) < list_capacity) ) {
       
   490 		aLineList[(*aListSize)++] = i;
       
   491     }
       
   492 	
       
   493     // and do it all again
       
   494   }
       
   495 
       
   496   // close up the file and return
       
   497   fflush( fp );
       
   498   fclose( fp );
       
   499 
       
   500   // done
       
   501   return rv;
       
   502 }
       
   503 
       
   504 
       
   505 /******************************************************************************************************
       
   506  *
       
   507  * PRIVATE METHOD: GetFileLineCount
       
   508  *
       
   509  *****************************************************************************************************/
       
   510 TFUError GetFileLineCount( char *aFilename, int *aLineCount, int *aSystemError )
       
   511 {
       
   512   FILE *fp;
       
   513   char cline[MAXLINESIZE], *cptr;
       
   514 
       
   515   // check params
       
   516   assert( aFilename != NULL );
       
   517   assert( aLineCount != NULL );
       
   518   assert( aSystemError != NULL );
       
   519   *aLineCount = *aSystemError = 0;
       
   520 
       
   521   // open the file
       
   522   fp = fopen( aFilename, "r" );
       
   523   if( fp == NULL ) {
       
   524     *aSystemError = errno;
       
   525     return FUE_OPEN_ERROR;
       
   526   }
       
   527 
       
   528   // read through the file and count the number of lines
       
   529   while( 1 ) {
       
   530     cptr = fgets( cline, MAXLINESIZE, fp );
       
   531     if( cptr == NULL )
       
   532       break;
       
   533     (*aLineCount)++;
       
   534   }
       
   535 
       
   536   // done with the file
       
   537   fclose( fp );
       
   538 
       
   539   // otherwise just return -- the line is in the buffer
       
   540   return FUE_NONE;
       
   541 }
       
   542 
       
   543 
       
   544 /******************************************************************************************************
       
   545  *
       
   546  * PRIVATE METHOD: mkstemp
       
   547  *
       
   548  *****************************************************************************************************/
       
   549 #ifdef WIN32
       
   550 int mkstemp( char *aString )
       
   551 {
       
   552 	char *ptr;
       
   553 	ptr = _mktemp( aString );
       
   554 	if( ptr == NULL ) {
       
   555 		return -1;
       
   556 	}
       
   557 	return 0;
       
   558 }
       
   559 #endif