summaryrefslogtreecommitdiff
path: root/app/bin/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/fileio.c')
-rw-r--r--app/bin/fileio.c278
1 files changed, 172 insertions, 106 deletions
diff --git a/app/bin/fileio.c b/app/bin/fileio.c
index dcd8b5c..23216b8 100644
--- a/app/bin/fileio.c
+++ b/app/bin/fileio.c
@@ -1,7 +1,5 @@
/** \file fileio.c
- * Loading and saving files. Handles trackplans as well as DXF export.
- *
- * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/fileio.c,v 1.18 2009-05-08 15:28:54 m_fischer Exp $
+ * Loading and saving files. Handles trackplans as well as DXF export.
*/
/* XTrkCad - Model Railroad CAD
@@ -48,6 +46,8 @@
#include <stdint.h>
+#include <assert.h>
+
#include "track.h"
#include "version.h"
#include "common.h"
@@ -75,13 +75,55 @@ EXPORT wBool_t executableOk = FALSE;
static int log_paramFile;
-EXPORT void SetCurDir(
- const char * pathName,
- const char * fileName )
+/**
+ * Get the directory from the current file and store it as current directory
+ * in a global variable and the preferences
+ *
+ * \param pathType IN possible enhancement for file type specific directorys
+ * \param fileName IN fully qualified filename
+ * \return
+ *
+ * \todo split directory and keep directory part
+ */
+
+void SetCurrentPath(
+ const char * pathType,
+ const char * fileName )
{
- memcpy( curDirName, pathName, fileName-pathName );
- curDirName[fileName-pathName-1] = '\0';
- wPrefSetString( "file", "directory", curDirName );
+ char *path;
+ char *copy;
+
+ assert( fileName != NULL );
+ assert( pathType != NULL );
+
+ copy = strdup( fileName );
+ path = strrchr(copy, FILE_SEP_CHAR[ 0 ] );
+ if ( path )
+ {
+ *path = '\0';
+ strcpy( curDirName, copy );
+ wPrefSetString( "file", "directory", curDirName );
+ }
+ free( copy );
+}
+
+/**
+ * Find the filename/extension piece in a fully qualified path
+ *
+ * \param path IN the full path
+ * \return pointer to the filename part
+ */
+
+char *FindName( char *path )
+{
+ char *name;
+ name = strrchr( path, FILE_SEP_CHAR[0] );
+ if (name) {
+ name++;
+ } else {
+ name = path;
+ }
+ return(name );
}
#ifdef WINDOWS
@@ -108,7 +150,7 @@ static int Copyfile( char * fn1, char * fn2 )
#endif
/**
- * Save the old locale and set to new.
+ * Save the old locale and set to new.
*
* \param newlocale IN the new locale to set
* \return pointer to the old locale
@@ -119,14 +161,14 @@ SaveLocale( char *newLocale )
{
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 );
@@ -144,7 +186,7 @@ RestoreLocale( char * locale )
if( locale ) {
setlocale( LC_ALL, locale );
free( locale );
- }
+ }
}
@@ -209,7 +251,7 @@ EXPORT char * GetNextLine( void )
/**
- * Show an error message if problems occur during loading of a param or layout file.
+ * Show an error message if problems occur during loading of a param or layout file.
* The user has the choice to cancel the operation or to continue. If operation is
* canceled the open file is closed.
*
@@ -219,7 +261,7 @@ EXPORT char * GetNextLine( void )
* \return TRUE to continue, FALSE to abort operation
*
*/
-
+
EXPORT int InputError(
char * msg,
BOOL_T showLine,
@@ -228,7 +270,7 @@ EXPORT int InputError(
va_list ap;
char * mp = message;
int ret;
-
+
mp += sprintf( message, "INPUT ERROR: %s:%d\n",
paramFileName, paramLineNum );
va_start( ap, showLine );
@@ -262,7 +304,7 @@ EXPORT void SyntaxError(
*
* \param line IN line to parse
* \param format IN ???
- *
+ *
* \return FALSE in case of parsing error, TRUE on success
*/
@@ -271,9 +313,10 @@ EXPORT BOOL_T GetArgs(
char * format,
... )
{
- unsigned char * cp, * cq;
+ char * cp, * cq;
int argNo;
long * pl;
+ unsigned long *pul;
int * pi;
FLOAT_T *pf;
coOrd p, *pp;
@@ -287,7 +330,7 @@ EXPORT BOOL_T GetArgs(
cp = line;
va_start( ap, format );
for (argNo=1;*format;argNo++,format++) {
- while (isspace(*cp)) cp++;
+ while (isspace((unsigned char)*cp)) cp++;
if (!*cp && strchr( "XZYzc", *format ) == NULL ) {
RestoreLocale(oldLocale);
InputError( "Arg %d: EOL unexpected", TRUE, argNo );
@@ -349,6 +392,16 @@ EXPORT BOOL_T GetArgs(
*pf /= mainD.dpi;
cp = cq;
break;
+ case 'u':
+ pul = va_arg( ap, unsigned long * );
+ *pul = strtoul( cp, &cq, 10 );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected integer", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ break;
case 'l':
pl = va_arg( ap, long * );
*pl = strtol( cp, &cq, 10 );
@@ -406,8 +459,8 @@ EXPORT BOOL_T GetArgs(
break;
case 's':
ps = va_arg( ap, char * );
- while (isspace(*cp)) cp++;
- while (*cp && !isspace(*cp)) *ps++ = *cp++;
+ while (isspace((unsigned char)*cp)) cp++;
+ while (*cp && !isspace((unsigned char)*cp)) *ps++ = *cp++;
*ps++ = '\0';
break;
case 'q':
@@ -445,7 +498,7 @@ EXPORT BOOL_T GetArgs(
break;
case 'c':
qp = va_arg( ap, char * * );
- while (isspace(*cp)) cp++;
+ while (isspace((unsigned char)*cp)) cp++;
if (*cp)
*qp = cp;
else
@@ -470,7 +523,7 @@ EXPORT wBool_t ParseRoomSize(
size.x = strtod( s, &cp );
if (cp != s) {
s = cp;
- while (isspace(*s)) s++;
+ while (isspace((unsigned char)*s)) s++;
if (*s == 'x' || *s == 'X') {
size.y = strtod( ++s, &cp );
if (cp != s) {
@@ -557,7 +610,7 @@ LOG1( log_paramFile, ("ReadParam( %s )\n", fileName ) )
/* empty paramLine */
} else if (strncmp( paramLine, "INCLUDE ", 8 ) == 0) {
cp = &paramLine[8];
- while (*cp && isspace(*cp)) cp++;
+ while (*cp && isspace((unsigned char)*cp)) cp++;
if (!*cp) {
InputError( "INCLUDE - no file name", TRUE );
@@ -605,16 +658,16 @@ LOG1( log_paramFile, ("ReadParam( %s )\n", fileName ) )
/* Close file and reset the locale settings */
if (paramFile) fclose(paramFile);
RestoreLocale( oldLocale );
-
+
NoticeMessage( MSG_PROG_CORRUPTED, _("Ok"), NULL, paramFileName );
return FALSE;
}
}
if (paramFile)fclose( paramFile );
-
+
RestoreLocale( oldLocale );
-
+
return TRUE;
}
@@ -765,7 +818,7 @@ static BOOL_T ReadTrackFile(
paramLineNum++;
if (strlen(paramLine) == (sizeof paramLine) -1 &&
paramLine[(sizeof paramLine)-1] != '\n') {
- if( !(ret = InputError( "Line too long", TRUE )))
+ if( !(ret = InputError( "Line too long", TRUE )))
break;
}
Stripcr( paramLine );
@@ -783,7 +836,7 @@ static BOOL_T ReadTrackFile(
} else if (strncmp( paramLine, "VERSION ", 8 ) == 0) {
paramVersion = strtol( paramLine+8, &cp, 10 );
if (cp)
- while (*cp && isspace(*cp)) cp++;
+ while (*cp && isspace((unsigned char)*cp)) cp++;
if ( paramVersion > iParamVersion ) {
if (cp && *cp) {
NoticeMessage( MSG_UPGRADE_VERSION1, _("Ok"), NULL, paramVersion, iParamVersion, sProdName, cp );
@@ -833,23 +886,23 @@ static BOOL_T ReadTrackFile(
break;
}
}
-
+
if (paramFile)
fclose(paramFile);
if( ret ) {
if (!noSetCurDir)
- SetCurDir( pathName, fileName );
+ SetCurrentPath( LAYOUTPATHKEY, fileName );
if (full) {
strcpy( curPathName, pathName );
curFileName = &curPathName[fileName-pathName];
SetWindowTitle();
}
- }
+ }
RestoreLocale( oldLocale );
-
+
paramFile = NULL;
InfoMessage( "%d", count );
return ret;
@@ -857,20 +910,24 @@ static BOOL_T ReadTrackFile(
EXPORT int LoadTracks(
- const char * pathName,
- const char * fileName,
+ int cnt,
+ char **fileName,
void * data)
{
#ifdef TIME_READTRACKFILE
long time0, time1;
#endif
- if (pathName == NULL)
- return TRUE;
+ char *nameOfFile;
+
+ assert( fileName != NULL );
+ assert( cnt == 1 );
+ //if (fileName == NULL || cnt == 0 )
+ // return TRUE;
+
paramVersion = -1;
wSetCursor( wCursorWait );
Reset();
ClearTracks();
-/* DefaultLayerProperties(); */
ResetLayers();
checkPtMark = changed = 0;
UndoSuspend();
@@ -878,8 +935,10 @@ EXPORT int LoadTracks(
#ifdef TIME_READTRACKFILE
time0 = wGetTimer();
#endif
- if (ReadTrackFile( pathName, fileName, TRUE, FALSE, TRUE )) {
- wMenuListAdd( fileList_ml, 0, fileName, MyStrdup(pathName) );
+ nameOfFile = FindName( fileName[ 0 ] );
+
+ if (ReadTrackFile( fileName[ 0 ], nameOfFile, TRUE, FALSE, TRUE )) {
+ wMenuListAdd( fileList_ml, 0, nameOfFile, MyStrdup(fileName[0]) );
ResolveIndex();
#ifdef TIME_READTRACKFILE
time1 = wGetTimer();
@@ -892,7 +951,6 @@ EXPORT int LoadTracks(
LoadLayerLists();
}
UndoResume();
- /*DoRedraw();*/
Reset();
wSetCursor( wCursorNormal );
return TRUE;
@@ -903,7 +961,7 @@ EXPORT int LoadTracks(
* path.
* \param index IN ignored
* \param label IN ignored
- * \param data IN filename
+ * \param data IN path and filename
*/
EXPORT void DoFileList(
@@ -911,13 +969,9 @@ EXPORT void DoFileList(
char * label,
void * data )
{
- char * fileName, * pathName = (char*)data;
- fileName = strrchr( pathName, FILE_SEP_CHAR[0] );
- if (fileName == NULL)
- fileName = pathName;
- else
- fileName++;
- LoadTracks( pathName, fileName, NULL );
+ char *pathName = (char*)data;
+
+ LoadTracks( 1, &pathName, NULL );
}
@@ -936,7 +990,7 @@ static BOOL_T DoSaveTracks(
RestoreLocale( oldLocale );
NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Track"), fileName, strerror(errno) );
-
+
return FALSE;
}
wSetCursor( wCursorWait );
@@ -969,19 +1023,26 @@ static BOOL_T DoSaveTracks(
static doSaveCallBack_p doAfterSave;
static int SaveTracks(
- const char * pathName,
- const char * fileName,
+ int cnt,
+ char **fileName,
void * data )
{
- if (pathName == NULL)
- return TRUE;
- SetCurDir( pathName, fileName );
- DoSaveTracks( pathName );
- wMenuListAdd( fileList_ml, 0, fileName, MyStrdup(pathName) );
+ char *nameOfFile;
+
+ assert( fileName != NULL );
+ assert( cnt == 1 );
+
+ SetCurrentPath( LAYOUTPATHKEY, fileName[ 0 ] );
+ DoSaveTracks( fileName[ 0 ] );
+
+ nameOfFile = FindName( fileName[ 0 ] );
+ wMenuListAdd( fileList_ml, 0, nameOfFile, MyStrdup(fileName[ 0 ]) );
checkPtMark = changed = 0;
- if (curPathName != pathName)
- strcpy( curPathName, pathName );
- curFileName = &curPathName[fileName-pathName];
+
+ if (curPathName != fileName[ 0 ])
+ strcpy( curPathName, fileName[ 0 ] );
+ curFileName = FindName( curPathName );
+
if (doAfterSave)
doAfterSave();
doAfterSave = NULL;
@@ -998,7 +1059,7 @@ EXPORT void DoSave( doSaveCallBack_p after )
sSourceFilePattern, SaveTracks, NULL );
wFilSelect( saveFile_fs, curDirName );
} else {
- SaveTracks( curPathName, curFileName, NULL );
+ SaveTracks( 1, &curFileName, NULL );
}
SetWindowTitle();
}
@@ -1007,7 +1068,7 @@ EXPORT void DoSaveAs( doSaveCallBack_p after )
{
doAfterSave = after;
if (saveFile_fs == NULL)
- saveFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Save Tracks"),
+ saveFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Save Tracks As"),
sSourceFilePattern, SaveTracks, NULL );
wFilSelect( saveFile_fs, curDirName );
SetWindowTitle();
@@ -1023,8 +1084,8 @@ EXPORT void DoLoad( void )
EXPORT void DoCheckPoint( void )
{
- int rc;
-
+ int rc;
+
if (checkPointingW == NULL) {
ParamRegister( &checkPointingPG );
checkPointingW = ParamCreateDialog( &checkPointingPG, MakeWindowTitle(_("Check Pointing")), NULL, NULL, NULL, FALSE, NULL, F_TOP|F_CENTER, NULL );
@@ -1032,41 +1093,41 @@ EXPORT void DoCheckPoint( void )
rename( checkPtFileName1, checkPtFileName2 );
wShow( checkPointingW );
rc = DoSaveTracks( checkPtFileName1 );
-
+
/* could the check point file be written ok? */
if( rc ) {
/* yes, delete the backup copy of the checkpoint file */
remove( checkPtFileName2 );
} else {
/* no, rename the backup copy back to the checkpoint file name */
- rename( checkPtFileName2, checkPtFileName1 );
- }
+ rename( checkPtFileName2, checkPtFileName1 );
+ }
wHide( checkPointingW );
}
/**
- * Remove all temporary files before exiting.When the program terminates
- * normally through the exit choice, files that are created temporarily are removed:
+ * Remove all temporary files before exiting.When the program terminates
+ * normally through the exit choice, files that are created temporarily are removed:
* xtrkcad.ckp
*
* \param none
* \return none
*
*/
-
+
EXPORT void CleanupFiles( void )
{
if( checkPtFileName1 )
remove( checkPtFileName1 );
-}
+}
/**
- * Check for existance of checkpoint file. Existance of a checkpoint file means that XTrkCAD was not properly
+ * Check for existance of checkpoint file. Existance of a checkpoint file means that XTrkCAD was not properly
* terminated.
*
* \param none
* \return TRUE if exists, FALSE otherwise
- *
+ *
*/
EXPORT int ExistsCheckpoint( void )
@@ -1074,14 +1135,14 @@ EXPORT int ExistsCheckpoint( void )
int len;
char *pattern = sCheckPointF;
char *search;
-
+
struct stat fileStat;
len = strlen( workingDir ) + 1 + strlen( sCheckPointF ) + 1;
checkPtFileName1 = (char*)MyMalloc(len);
sprintf( checkPtFileName1, "%s%s%s", workingDir, FILE_SEP_CHAR, sCheckPointF );
checkPtFileName2 = (char*)MyMalloc(len);
- sprintf( checkPtFileName2, "%s%s%s", workingDir, FILE_SEP_CHAR, sCheckPoint1F );
+ sprintf( checkPtFileName2, "%s%s%s", workingDir, FILE_SEP_CHAR, sCheckPoint1F );
len = strlen( workingDir ) + 1 + strlen( pattern ) + 1;
search = (char*)MyMalloc(len);
@@ -1093,7 +1154,7 @@ EXPORT int ExistsCheckpoint( void )
} else {
MyFree( search );
return FALSE;
- }
+ }
#ifdef LATER
@@ -1101,19 +1162,19 @@ EXPORT int ExistsCheckpoint( void )
dir = opendir( search );
MyFree( search );
-
+
if( dir ) {
closedir( dir );
return TRUE;
} else {
return FALSE;
- }
-#endif
+ }
+#endif
}
/**
- * Load checkpoint file
+ * Load checkpoint file
*
* \return TRUE if exists, FALSE otherwise
*
@@ -1123,7 +1184,7 @@ EXPORT int LoadCheckpoint( void )
{
int len;
char *search;
-
+
paramVersion = -1;
wSetCursor( wCursorWait );
@@ -1167,14 +1228,17 @@ static struct wFilSel_t * exportDXFFile_fs;
static int ImportTracks(
- const char * pathName,
- const char * fileName,
+ int cnt,
+ char **fileName,
void * data )
{
+ char *nameOfFile;
long paramVersionOld = paramVersion;
- if (pathName == NULL)
- return TRUE;
+ assert( fileName != NULL );
+ assert( cnt == 1 );
+
+ nameOfFile = FindName(fileName[ 0 ]);
paramVersion = -1;
wSetCursor( wCursorWait );
Reset();
@@ -1182,7 +1246,7 @@ static int ImportTracks(
ImportStart();
UndoStart( _("Import Tracks"), "importTracks" );
useCurrentLayer = TRUE;
- ReadTrackFile( pathName, fileName, FALSE, FALSE, TRUE );
+ ReadTrackFile( fileName[ 0 ], nameOfFile, FALSE, FALSE, TRUE );
ImportEnd();
/*DoRedraw();*/
EnableCommands();
@@ -1208,32 +1272,33 @@ EXPORT void DoImport( void )
/**
* Export the selected track pieces
*
- * \param pathname IN full path and filename for export file
- * \param filename IN pointer to filename part *within* pathname
+ * \param cnt IN Count of filenames, should always be 1
+ * \param fileName IN array of fileNames with cnt names
* \param data IN unused
* \return FALSE on error, TRUE on success
*/
static int DoExportTracks(
- const char * pathName,
- const char * fileName,
+ int cnt,
+ char **fileName,
void * data )
{
FILE * f;
time_t clock;
char *oldLocale = NULL;
- if (pathName == NULL)
- return TRUE;
- SetCurDir( pathName, fileName );
- f = fopen( pathName, "w" );
+ assert( fileName != NULL );
+ assert( cnt == 1 );
+
+ SetCurrentPath( IMPORTPATHKEY, fileName[ 0 ] );
+ f = fopen( fileName[ 0 ], "w" );
if (f==NULL) {
- NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Export"), fileName, strerror(errno) );
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Export"), fileName[0], strerror(errno) );
return FALSE;
}
oldLocale = SaveLocale("C");
-
+
wSetCursor( wCursorWait );
time(&clock);
fprintf(f,"#%s Version: %s, Date: %s\n", sProdName, sVersion, ctime(&clock) );
@@ -1241,7 +1306,7 @@ static int DoExportTracks(
ExportTracks( f );
fprintf(f, "END\n");
fclose(f);
-
+
RestoreLocale( oldLocale );
Reset();
@@ -1360,19 +1425,20 @@ static drawCmd_t dxfD = {
NULL, &dxfDrawFuncs, 0, 1.0, 0.0, {0.0,0.0}, {0.0,0.0}, Pix2CoOrd, CoOrd2Pix, 100.0 };
static int DoExportDXFTracks(
- const char * pathName,
- const char * fileName,
+ int cnt,
+ char ** fileName,
void * data )
{
time_t clock;
char *oldLocale;
- if (pathName == NULL)
- return TRUE;
- SetCurDir( pathName, fileName );
- dxfF = fopen( pathName, "w" );
+ assert( fileName != NULL );
+ assert( cnt == 1 );
+
+ SetCurrentPath( DXFPATHKEY, fileName[ 0 ] );
+ dxfF = fopen( fileName[0], "w" );
if (dxfF==NULL) {
- NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, "DXF", fileName, strerror(errno) );
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, "DXF", fileName[0], strerror(errno) );
return FALSE;
}
@@ -1486,7 +1552,7 @@ EXPORT BOOL_T EditCut( void )
/**
* Paste clipboard content. XTrackCAD uses a disk file as clipboard replacement. This file is read and the
* content is inserted.
- *
+ *
* \return TRUE if success, FALSE on error (file not found)
*/
@@ -1539,7 +1605,7 @@ EXPORT void FileInit( void )
if (pref != NULL) {
strcpy( curDirName, pref );
} else {
- sprintf( curDirName, "%s%sexamples", libDir, FILE_SEP_CHAR );
+ sprintf( curDirName, "%s%sexamples", libDir, FILE_SEP_CHAR );
}
}