diff options
Diffstat (limited to 'app/bin/fileio.c')
| -rw-r--r-- | app/bin/fileio.c | 305 | 
1 files changed, 138 insertions, 167 deletions
diff --git a/app/bin/fileio.c b/app/bin/fileio.c index cb0c8de..0a2e576 100644 --- a/app/bin/fileio.c +++ b/app/bin/fileio.c @@ -20,32 +20,6 @@   *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   */ -#include <stdlib.h> -#include <stdio.h> -#ifndef WINDOWS -#include <unistd.h> -#include <dirent.h> -#include <errno.h> -#endif -#include <math.h> -#include <ctype.h> -#include <string.h> -#include <time.h> -#include <ctype.h> -#ifdef WINDOWS -	#include <io.h> -	#define W_OK (2) -	#define access	_access -	#include <windows.h> -#endif -#include <sys/stat.h> -#include <stdarg.h> -#include <locale.h> - -#include <stdint.h> - -#include <assert.h> -  #include <cJSON.h>  #include "archive.h" @@ -58,25 +32,22 @@  #include "draw.h"  #include "fileio.h"  #include "fcntl.h" -#include "i18n.h"  #include "layout.h"  #include "manifest.h" -#include "messages.h"  #include "misc.h"  #include "param.h"  #include "include/paramfile.h"  #include "paths.h"  #include "track.h" -#include "utility.h"  #include "version.h"  #include "dynstring.h" +#include "common-ui.h" -#ifdef WINDOWS +#ifdef UTFCONVERT  #include "include/utf8convert.h" -#endif // WINDOWS - +#endif // UTFCONVERT -/*#define TIME_READTRACKFILE*/ +EXPORT dynArr_t paramProc_da;  #define COPYBLOCKSIZE	1024 @@ -92,7 +63,6 @@ EXPORT wBool_t bExample = FALSE;  EXPORT wBool_t bReadOnly = FALSE; -  #ifdef WINDOWS  #define rename( F1, F2 ) Copyfile( F1, F2 ) @@ -116,43 +86,46 @@ static int Copyfile( char * fn1, char * fn2 )  }  #endif -/** - * Save the old locale and set to new. - * - * \param newlocale IN the new locale to set - * \return    pointer to the old locale - */ - -char * -SaveLocale( char *newLocale ) +// +// Locale handling +// SetCLocale is called before reading/writing any data files (.xtc, .xti, .xtq, .cus...) +// SetUserLocale is called after +// Calls can be nested: C, C, User, User +//  +static char * sUserLocale = NULL;	// current user locale +static long lCLocale = 0;		// locale state: > 0 C locale, <= 0 user locale +static long nCLocale = 0;		// total # of setlocals calls +static int log_locale = 0;		// logging +static int log_timereadfile = 0; + +EXPORT void SetCLocale()  { -	char *oldLocale; -	char *saveLocale = NULL; - -	/* get old locale setting */ -	oldLocale = setlocale(LC_ALL, NULL); - -	/* allocate memory to save */ -	if (oldLocale) -		saveLocale = strdup( oldLocale ); - -	setlocale(LC_ALL, newLocale ); - -	return( saveLocale ); +	if ( sUserLocale == NULL ) { +		sUserLocale = MyStrdup( setlocale( LC_ALL, NULL ) ); +	} +	if ( lCLocale == 0 ) { +		LOG( log_locale, 1, ( "Set C Locale: %ld\n", ++nCLocale ) ); +		setlocale( LC_ALL, "C" ); +	} +	lCLocale++; +	if ( lCLocale > 1 ) { +		LOG( log_locale, 3, ( "SetClocale - C! %ld\n", nCLocale) ); +	} else if ( lCLocale < 1 ) { +		LOG( log_locale, 2, ( "SetClocale - User! %ld\n", nCLocale) ); +	}  } -/** - * Restore a previously saved locale. - * - * \param locale IN return value from earlier call to SaveLocale - */ - -void -RestoreLocale( char * locale ) +EXPORT void SetUserLocale()  { -	if( locale ) { -		setlocale( LC_ALL, locale ); -		free( locale ); +	if ( lCLocale == 1 ) { +		LOG( log_locale, 1, ( "Set %s Locale: %ld\n", sUserLocale, ++nCLocale ) ); +		setlocale( LC_ALL, sUserLocale ); +	} +	lCLocale--; +	if ( lCLocale < 0 ) { +		LOG( log_locale, 2, ("SetUserLocale - User! %ld\n", nCLocale) ); +	} else if ( lCLocale > 0 ) { +		LOG( log_locale, 3, ("SetUserLocale - C! %ld\n", nCLocale) );  	}  } @@ -304,10 +277,10 @@ EXPORT BOOL_T GetArgs(  	char * ps;  	char ** qp;  	va_list ap; -	char *oldLocale = NULL;  	char * sError = NULL; -	oldLocale = SaveLocale("C"); +	if ( lCLocale < 1 ) +		LOG( log_locale, 1, ( "GetArgs: not in C locale\n" ) );  	cp = line;  	va_start( ap, format ); @@ -453,7 +426,7 @@ EXPORT BOOL_T GetArgs(  			} else {  				message[0] = '\0';  			} -#ifdef WINDOWS +#ifdef UTFCONVERT  			ConvertUTF8ToSystem(message);  #endif  			*qp = (char*)ConvertFromEscapedText(message); @@ -471,7 +444,6 @@ EXPORT BOOL_T GetArgs(  		}  	}  	va_end( ap ); -	RestoreLocale(oldLocale);  	if ( sError ) {  		InputError( sError, TRUE, cp );  		return FALSE; @@ -484,7 +456,7 @@ EXPORT BOOL_T GetArgs(  wBool_t IsEND( char * sEnd )  {  	char * cp; -	wBool_t bAllowNakedENDs = paramVersion < 12; +	wBool_t bAllowNakedENDs = paramVersion < VERSION_NONAKEDENDS;  	for( cp = paramLine; *cp && (isspace( *cp ) || *cp == '\t'); cp++ );  	if ( strncmp( cp, sEnd, strlen(sEnd) ) == 0 )  		cp += strlen( sEnd ); @@ -526,11 +498,11 @@ ReadMultilineText()  	string = MyStrdup(DynStringToCStr(¬eText));  	string[strlen(string) - 1] = '\0'; -#ifdef WINDOWS +#ifdef UTFCONVERT  	if (wIsUTF8(string)) {  		ConvertUTF8ToSystem(string);  	} -#endif // WINDOWS +#endif // UTFCONVERT  	DynStringFree(¬eText);  	return(string); @@ -585,7 +557,7 @@ EXPORT char * PutTitle( char * cp )  {  	static char *title;  	char * tp; -	unsigned cnt = strlen(cp) * 2 + 3;		// add 3 for quotes and terminating \0 +	size_t cnt = strlen(cp) * 2 + 3;		// add 3 for quotes and terminating \0  	if (!title) {  		title = MyMalloc(cnt); @@ -608,14 +580,14 @@ EXPORT char * PutTitle( char * cp )  		NoticeMessage( _("putTitle: title too long: %s"), _("Ok"), NULL, title );  	*tp = '\0'; -#ifdef WINDOWS +#ifdef UTFCONVERT  	if(RequiresConvToUTF8(title)) {  		char *out = MyMalloc(cnt); -		wSystemToUTF8(title, out, cnt); +		wSystemToUTF8(title, out, (unsigned int)cnt);  		strcpy(title, out);  		MyFree(out);  	} -#endif // WINDOWS +#endif // UTFCONVERT  	return title;  } @@ -654,11 +626,6 @@ static struct wFilSel_t * loadFile_fs = NULL;  static struct wFilSel_t * saveFile_fs = NULL;  static struct wFilSel_t * examplesFile_fs = NULL; -static wWin_p checkPointingW; -static paramData_t checkPointingPLs[] = { -   {    PD_MESSAGE, N_("Check Pointing") } }; -static paramGroup_t checkPointingPG = { "checkpoint", 0, checkPointingPLs, sizeof checkPointingPLs/sizeof checkPointingPLs[0] }; -  static char * checkPtFileName1;  static char * checkPtFileName2;  static char * checkPtFileNameBackup; @@ -685,22 +652,17 @@ static BOOL_T ReadTrackFile(  	coOrd roomSize;  	long scale;  	char * cp; -	char *oldLocale = NULL;  	int ret = TRUE; -	oldLocale = SaveLocale( "C" ); -  	paramFile = fopen( pathName, "r" );  	if (paramFile == NULL) { -		/* Reset the locale settings */ -		RestoreLocale( oldLocale ); -  		if ( complain )  			NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, sProdName, pathName, strerror(errno) ); -  		return FALSE;  	} +	SetCLocale(); +	checkPtFileNameBackup = NULL;  	paramLineNum = 0;  	paramFileName = strdup( fileName ); @@ -754,14 +716,14 @@ static BOOL_T ReadTrackFile(  			if( !(ret = InputError( "unknown command", TRUE )))  				break;  		} else if (strncmp( paramLine, "TITLE1 ", 7 ) == 0) { -#ifdef WINDOWS +#ifdef UTFCONVERT  			ConvertUTF8ToSystem(paramLine + 7); -#endif // WINDOWS +#endif // UTFCONVERT  			SetLayoutTitle(paramLine + 7);  		} else if (strncmp( paramLine, "TITLE2 ", 7 ) == 0) { -#ifdef WINDOWS +#ifdef UTFCONVERT  			ConvertUTF8ToSystem(paramLine + 7); -#endif // WINDOWS +#endif // UTFCONVERT  			SetLayoutSubtitle(paramLine + 7);  		} else if (strncmp( paramLine, "ROOMSIZE", 8 ) == 0) {  			if ( ParseRoomSize( paramLine+8, &roomSize ) ) { @@ -812,10 +774,9 @@ static BOOL_T ReadTrackFile(  	 if (skipLines>0)  		 NoticeMessage( MSG_LAYOUT_LINES_SKIPPED, _("Ok"), NULL, paramFileName, skipLines); -	RestoreLocale( oldLocale ); -  	paramFile = NULL; +	SetUserLocale();  	free(paramFileName);      paramFileName = NULL;  	InfoMessage( "%d", count ); @@ -827,9 +788,6 @@ int LoadTracks(  		char **fileName,  		void * data)  { -#ifdef TIME_READTRACKFILE -	long time0, time1; -#endif  	char *nameOfFile = NULL;  	char *extOfFile; @@ -837,6 +795,15 @@ int LoadTracks(  	assert( fileName != NULL );  	assert( cnt == 1 ); +	nameOfFile = FindFilename(fileName[0]); + +	// Make sure it exists and it is readable +	if (access(fileName[0], R_OK) != 0) +	{ +		NoticeMessage(MSG_OPEN_FAIL, _("Continue"), NULL, _("Track"), nameOfFile, _("Not Found")); +		return FALSE; +	} +  	if ( ! bExample )  		SetCurrentPath(LAYOUTPATHKEY, fileName[0]);  	bReadOnly = bExample; @@ -846,13 +813,10 @@ int LoadTracks(  	ClearTracks();  	ResetLayers();  	checkPtMark = changed = 0; -	LayoutBackGroundInit(TRUE);   //Keep values of background -> will be overriden my archive +	if (!data) +		LayoutBackGroundInit(TRUE);   //Keep values of background -> will be overriden by archive  	UndoSuspend();  	useCurrentLayer = FALSE; -#ifdef TIME_READTRACKFILE -	time0 = wGetTimer(); -#endif -	nameOfFile = FindFilename( fileName[ 0 ] );   /*    * Support zipped filetype @@ -952,6 +916,7 @@ int LoadTracks(  	char *copyOfFileName = MyStrdup(fileName[0]); +	unsigned long time0 = wGetTimer();  	if (loadXTC && ReadTrackFile( full_path, FindFilename( fileName[0]), TRUE, TRUE, TRUE )) {  		nameOfFile = NULL; @@ -968,15 +933,11 @@ int LoadTracks(  		ResolveIndex(); -#ifdef TIME_READTRACKFILE -		time1 = wGetTimer(); -		printf( "time= %ld ms \n", time1-time0 ); -#endif -		RecomputeElevations(); +		LOG( log_timereadfile, 1, ( "Read time (%s) = %lu mS \n", fileName[0], wGetTimer()-time0 ) ); +		RecomputeElevations(NULL);  		AttachTrains();  		DoChangeNotification( CHANGE_ALL );  		DoUpdateTitles(); -		LoadLayerLists();  		LayerSetCounts();  	} @@ -984,6 +945,8 @@ int LoadTracks(  	free(full_path);  	full_path = NULL; +	UpdateLayerDlg(curLayer); +  	UndoResume();  	Reset();  	wSetCursor( mainD.d, defaultCursor ); @@ -994,7 +957,7 @@ int LoadTracks(   * Load the layout specified by data. Filename may contain a full   * path.   * \param index IN ignored - * \param label IN ignored + * \param label IN if not NULL - during startup - set flag to not load background   * \param data IN path and filename   */ @@ -1005,28 +968,26 @@ EXPORT void DoFileList(  {  	char *pathName = (char*)data;  	bExample = FALSE; -	LoadTracks( 1, &pathName, NULL ); +	if (label) +		LoadTracks( 1, &pathName, I2VP(1)); +	else +		LoadTracks( 1, &pathName, NULL );  } -  static BOOL_T DoSaveTracks(  		const char * fileName )  {  	FILE * f;  	time_t clock;  	BOOL_T rc = TRUE; -	char *oldLocale = NULL; -	oldLocale = SaveLocale( "C" );  	f = fopen( fileName, "w" );  	if (f==NULL) { -		RestoreLocale( oldLocale ); -  		NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Track"), fileName, strerror(errno) ); -  		return FALSE;  	} +	SetCLocale();  	wSetCursor( mainD.d, wCursorWait );  	time(&clock);  	rc &= fprintf(f,"#%s Version: %s, Date: %s\n", sProdName, sVersion, ctime(&clock) )>0; @@ -1047,10 +1008,9 @@ static BOOL_T DoSaveTracks(  	fclose(f);  	bReadOnly = FALSE; -	RestoreLocale( oldLocale ); -  	checkPtMark = changed;  	wSetCursor( mainD.d, defaultCursor ); +	SetUserLocale();  	return rc;  } @@ -1160,7 +1120,7 @@ static int SaveTracks(  			CopyDependency(background,DependencyDir);  		//The details are stored into the manifest - TODO use arrays for files, locations -		char *oldLocale = SaveLocale("C"); +		SetCLocale();  		char* json_Manifest = CreateManifest(nameOfFile, background, "includes");  		char * manifest_file; @@ -1174,7 +1134,7 @@ static int SaveTracks(  		} else {  			NoticeMessage( MSG_MANIFEST_FAIL, _("Continue"), NULL, manifest_file );  		} -		RestoreLocale(oldLocale); +		SetUserLocale();  		free(manifest_file);  		free(json_Manifest); @@ -1203,33 +1163,46 @@ static int SaveTracks(  	return TRUE;  } +EXPORT void SetAutoSave() { +	if (saveFile_fs == NULL) +		saveFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("AutoSave Tracks As"), +			sSourceFilePattern, SaveTracks, NULL ); +	wFilSelect( saveFile_fs, GetCurrentPath(LAYOUTPATHKEY)); +	checkPtMark = 1; +	SetWindowTitle(); +	CleanupFiles();  //Remove old checkpoint +	SaveState(); + +} -EXPORT void DoSave( doSaveCallBack_p after ) +EXPORT void DoSave( void * doAfterSaveVP )  { -	doAfterSave = after; +	doAfterSave = doAfterSaveVP;  	if ( bReadOnly || *(GetLayoutFilename()) == '\0') {  		if (saveFile_fs == NULL)  			saveFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Save Tracks"),  				sSourceFilePattern, SaveTracks, NULL );  		wFilSelect( saveFile_fs, GetCurrentPath(LAYOUTPATHKEY)); -		changed = checkPtMark = 1; +		checkPtMark = 1;  	} else {  		char *temp = GetLayoutFullPath();  		SaveTracks( 1, &temp, NULL );  	}  	SetWindowTitle(); +	CleanupFiles();  //Remove old checkpoint  	SaveState();  } -EXPORT void DoSaveAs( doSaveCallBack_p after ) +EXPORT void DoSaveAs( void * doAfterSaveVP )  { -	doAfterSave = after; +	doAfterSave = doAfterSaveVP;  	if (saveFile_fs == NULL)  		saveFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Save Tracks As"),  			sSaveFilePattern, SaveTracks, NULL );  	wFilSelect( saveFile_fs, GetCurrentPath(LAYOUTPATHKEY)); -	changed = checkPtMark = 1; +	checkPtMark = 1;  	SetWindowTitle(); +	CleanupFiles();  //Remove old checkpoint  	SaveState();  } @@ -1242,6 +1215,7 @@ EXPORT void DoLoad( void )  	wFilSelect( loadFile_fs, GetCurrentPath(LAYOUTPATHKEY));  	paste_offset = zero;  	cursor_offset = zero; +	CleanupFiles();  //Remove old checkpoint  	SaveState();  } @@ -1251,11 +1225,12 @@ EXPORT void DoExamples( void )  	if (examplesFile_fs == NULL) {  		static wBool_t bExample = TRUE;  		examplesFile_fs = wFilSelCreate( mainW, FS_LOAD, 0, _("Example Tracks"), -			sSourceFilePattern, LoadTracks, &bExample ); +			sSourceFilePattern, LoadTracks, NULL );  	}  	bExample = TRUE;  	sprintf( message, "%s" FILE_SEP_CHAR "examples" FILE_SEP_CHAR, libDir );  	wFilSelect( examplesFile_fs, message ); +	CleanupFiles();  //Remove old checkpoint  	SaveState();  } @@ -1273,12 +1248,8 @@ EXPORT void DoCheckPoint( void )  		MakeFullpath(&checkPtFileNameBackup, workingDir, sCheckPointBF, NULL);  	} -	if (checkPointingW == NULL) { -		ParamRegister( &checkPointingPG ); -		checkPointingW = ParamCreateDialog( &checkPointingPG, MakeWindowTitle(_("Check Pointing")), NULL, NULL, NULL, FALSE, NULL, F_TOP|F_CENTER, NULL ); -	}  	rename( checkPtFileName1, checkPtFileName2 ); -	//wShow( checkPointingW ); +  	rc = DoSaveTracks( checkPtFileName1 );  	/* could the check point file be written ok? */ @@ -1305,7 +1276,6 @@ EXPORT void DoCheckPoint( void )  		rename( checkPtFileName2, checkPtFileName1 );  	} -	//wHide( checkPointingW );  	wShow( mainW );  } @@ -1398,12 +1368,16 @@ EXPORT int LoadCheckpoint( BOOL_T sameName )  			}  		} else SetLayoutFullPath(""); -		RecomputeElevations(); +		RecomputeElevations(NULL);  		AttachTrains();  		DoChangeNotification( CHANGE_ALL );  		DoUpdateTitles(); +  	} else SetLayoutFullPath(""); +	LayerSetCounts(); +	UpdateLayerDlg(curLayer); +  	Reset();  	UndoResume(); @@ -1474,14 +1448,14 @@ static int ImportTracks(  	EnableCommands();  	wSetCursor( mainD.d, defaultCursor );  	paramVersion = paramVersionOld; -	DoCommandB( (void*)(intptr_t)selectCmdInx ); +	DoCommandB( I2VP(selectCmdInx) );  	SelectRecount();  	return TRUE;  }  EXPORT void DoImport( void * type )  { -	importAsModule = (int)(long)type; +	importAsModule = (int)VP2L(type);  	if (importFile_fs == NULL)  		importFile_fs = wFilSelCreate( mainW, FS_LOAD, 0, _("Import Tracks"),  			sImportFilePattern, ImportTracks, NULL ); @@ -1506,7 +1480,6 @@ static int DoExportTracks(  {  	FILE * f;  	time_t clock; -	char *oldLocale = NULL;  	assert( fileName != NULL );  	assert( cnt == 1 ); @@ -1518,7 +1491,7 @@ static int DoExportTracks(  		return FALSE;  	} -	oldLocale = SaveLocale("C"); +	SetCLocale();  	wSetCursor( mainD.d, wCursorWait );  	time(&clock); @@ -1529,7 +1502,7 @@ static int DoExportTracks(  	fprintf(f, "%s\n", END_TRK_FILE);  	fclose(f); -	RestoreLocale( oldLocale ); +	SetUserLocale();  	Reset();  	wSetCursor( mainD.d, defaultCursor ); @@ -1538,7 +1511,7 @@ static int DoExportTracks(  } -EXPORT void DoExport( void ) +EXPORT void DoExport( void * unused )  {  	if (selectedTrackCount <= 0) {  		ErrorMessage( MSG_NO_SELECTED_TRK ); @@ -1552,42 +1525,43 @@ EXPORT void DoExport( void )  } -EXPORT BOOL_T EditCopy( void ) +EXPORT wBool_t editStatus = TRUE; + +EXPORT void EditCopy( void * unused )  { +	editStatus = FALSE;  	FILE * f;  	time_t clock; -	char *oldLocale = NULL;  	if (selectedTrackCount <= 0) {  		ErrorMessage( MSG_NO_SELECTED_TRK ); -		return FALSE; +		return;  	}  	f = fopen( clipBoardN, "w" );  	if (f == NULL) {  		NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Clipboard"), clipBoardN, strerror(errno) ); -		return FALSE; +		return;  	} -	oldLocale = SaveLocale("C"); +	SetCLocale();  	time(&clock);  	fprintf(f,"#%s Version: %s, Date: %s\n", sProdName, sVersion, ctime(&clock) );  	fprintf(f, "VERSION %d %s\n", iParamVersion, PARAMVERSIONVERSION );  	ExportTracks(f, &paste_offset);  	fprintf(f, "%s\n", END_TRK_FILE ); -	RestoreLocale(oldLocale); +	SetUserLocale();  	fclose(f); -	return TRUE; +	editStatus = TRUE;  } -EXPORT BOOL_T EditCut( void ) +EXPORT void EditCut( void * unused )  { -	if (!EditCopy()) -		return FALSE; +	EditCopy(NULL); +	if ( !editStatus ) return;  	SelectDelete(); -	return TRUE;  } @@ -1598,13 +1572,10 @@ EXPORT BOOL_T EditCut( void )   * \return    TRUE if success, FALSE on error (file not found)   */ -BOOL_T EditPastePlace( wBool_t inPlace ) +static BOOL_T EditPastePlace( wBool_t inPlace )  {  	BOOL_T rc = TRUE; -	char *oldLocale = NULL; - -	oldLocale = SaveLocale("C");  	wSetCursor( mainD.d, wCursorWait );  	Reset(); @@ -1631,23 +1602,21 @@ BOOL_T EditPastePlace( wBool_t inPlace )  	/*DoRedraw();*/  	EnableCommands();  	wSetCursor( mainD.d, defaultCursor ); -	DoCommandB( (void*)(intptr_t)selectCmdInx ); +	DoCommandB( I2VP(selectCmdInx) );  	SelectRecount();  	UpdateAllElevations(); -	RestoreLocale(oldLocale);  	return rc;  } -EXPORT BOOL_T EditPaste( void) { -	return EditPastePlace(FALSE); +EXPORT void EditPaste( void * unused ) { +	editStatus = EditPastePlace(FALSE);  } - -EXPORT BOOL_T EditClone( void ) { -	BOOL_T rc = TRUE; -	if (!EditCopy()) return FALSE; -	if (!EditPastePlace(TRUE)) return FALSE; -	return rc; + +EXPORT void EditClone( void * unused ) { +	EditCopy( NULL ); +	if ( !editStatus ) return; +	editStatus = EditPastePlace(TRUE);  }  /***************************************************************************** @@ -1667,4 +1636,6 @@ EXPORT void FileInit( void )  	SetLayoutFullPath("");  		MakeFullpath(&clipBoardN, workingDir, sClipboardF, NULL); +	log_locale = LogFindIndex( "locale" ); +	log_timereadfile = LogFindIndex( "timereadfile" );  }  | 
