From a14a7a0ccc9de76aeab0b2e4bbf58f1a79deedc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 3 Jul 2024 10:19:30 +0200 Subject: New upstream version 5.3.0GA --- app/wlib/gtklib/wpref.c | 310 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 214 insertions(+), 96 deletions(-) (limited to 'app/wlib/gtklib/wpref.c') diff --git a/app/wlib/gtklib/wpref.c b/app/wlib/gtklib/wpref.c index 3494ba2..356dd95 100644 --- a/app/wlib/gtklib/wpref.c +++ b/app/wlib/gtklib/wpref.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -26,6 +26,7 @@ #include #include #include +#include #define GTK_DISABLE_SINGLE_INCLUDES #define GDK_DISABLE_DEPRECATED @@ -47,6 +48,8 @@ extern char wConfigName[]; static char appLibDir[BUFSIZ]; static char appWorkDir[BUFSIZ]; static char userHomeDir[BUFSIZ]; + +static char *profileFile; /* @@ -58,13 +61,13 @@ static char userHomeDir[BUFSIZ]; */ -/** Find the directory where configuration files, help, demos etc are installed. +/** Find the directory where configuration files, help, demos etc are installed. * The search order is: * 1. Directory specified by the XTRKCADLIB environment variable * 2. Directory specified by XTRKCAD_INSTALL_PREFIX/share/xtrkcad * 3. /usr/share/xtrkcad * 4. /usr/local/share/xtrkcad - * + * * \return pointer to directory name */ @@ -79,13 +82,19 @@ const char * wGetAppLibDir( void ) return appLibDir; } - for (cp=wlibGetAppName(),ep=envvar; *cp; cp++,ep++) + for (cp=wlibGetAppName(),ep=envvar; *cp; cp++,ep++) { *ep = toupper(*cp); - strcpy( ep, "LIB" ); + } +#ifndef __APPLE__ + if ( strstr( XTRKCAD_VERSION, "Beta" ) != NULL ) { + strcat( ep, "BETA" ); + } +#endif + strcat( ep, "LIB" ); ep = getenv( envvar ); if (ep != NULL) { if ((stat( ep, &buf) == 0 ) && S_ISDIR( buf.st_mode)) { - strncpy( appLibDir, ep, sizeof appLibDir ); + strncpy( appLibDir, ep, sizeof(appLibDir) -1 ); //printf( "wAppLbDir=%s\n", appLibDir ); return appLibDir; } @@ -100,13 +109,18 @@ const char * wGetAppLibDir( void ) char * dir1 = "/usr/share/"; char * dir2 = "/usr/local/share/"; + char * beta = ""; if ( strstr( XTRKCAD_VERSION, "Beta" ) != NULL ) { dir1 = "/usr/local/share/"; dir2 = "/usr/share/"; +#ifndef __APPLE__ + beta = "-beta"; +#endif } strcpy( appLibDir, dir1 ); strcat( appLibDir, wlibGetAppName() ); + strcat( appLibDir, beta ); if ((stat( appLibDir, &buf) == 0 ) && S_ISDIR( buf.st_mode)) { //printf( "wAppLbDir=%s\n", appLibDir ); return appLibDir; @@ -120,14 +134,14 @@ const char * wGetAppLibDir( void ) } sprintf( msg, - _("The required configuration files could not be located in the expected location.\n\n" - "Usually this is an installation problem. Make sure that these files are installed in either \n" - " ../share/xtrkcad or\n" - " /usr/share/%s or\n" - " /usr/local/share/%s\n" - "If this is not possible, the environment variable %s must contain " - "the name of the correct directory."), - wlibGetAppName(), wlibGetAppName(), envvar ); + _("The required configuration files could not be located in the expected location.\n\n" + "Usually this is an installation problem. Make sure that these files are installed in either \n" + " ../share/xtrkcad or\n" + " /usr/share/%s or\n" + " /usr/local/share/%s\n" + "If this is not possible, the environment variable %s must contain " + "the name of the correct directory."), + wlibGetAppName(), wlibGetAppName(), envvar ); wNoticeEx( NT_ERROR, msg, _("Ok"), NULL ); appLibDir[0] = '\0'; wExit(0); @@ -144,20 +158,26 @@ const char * wGetAppLibDir( void ) const char * wGetAppWorkDir( - void ) + void ) { char tmp[BUFSIZ+20]; char * homeDir; DIR *dirp; - - if (appWorkDir[0] != '\0') + + if (appWorkDir[0] != '\0') { return appWorkDir; + } if ((homeDir = getenv( "HOME" )) == NULL) { wNoticeEx( NT_ERROR, _("HOME is not set"), _("Exit"), NULL); wExit(0); } sprintf( appWorkDir, "%s/.%s", homeDir, wlibGetAppName() ); +#ifndef __APPLE__ + if ( strstr( XTRKCAD_VERSION, "Beta" ) != NULL ) { + strcat( appWorkDir, "-beta" ); + } +#endif if ( (dirp = opendir(appWorkDir)) != NULL ) { closedir(dirp); } else { @@ -166,18 +186,18 @@ const char * wGetAppWorkDir( wNoticeEx( NT_ERROR, tmp, _("Exit"), NULL ); wExit(0); } else { - /* - * check for default configuration file and copy to + /* + * check for default configuration file and copy to * the workdir if it exists */ struct stat stFileInfo; char appEtcConfig[BUFSIZ]; sprintf( appEtcConfig, "/etc/%s.rc", wlibGetAppName()); - + if ( stat( appEtcConfig, &stFileInfo ) == 0 ) { char copyConfigCmd[(BUFSIZ * 2) + 3]; sprintf( copyConfigCmd, "cp %s %s", appEtcConfig, appWorkDir ); - int rc = system( copyConfigCmd ); + system( copyConfigCmd ); } } } @@ -194,16 +214,17 @@ const char * wGetAppWorkDir( const char *wGetUserHomeDir( void ) { char *homeDir; - - if( userHomeDir[ 0 ] != '\0' ) + + if( userHomeDir[ 0 ] != '\0' ) { return userHomeDir; - + } + if ((homeDir = getenv( "HOME" )) == NULL) { wNoticeEx( NT_ERROR, _("HOME is not set"), _("Exit"), NULL); wExit(0); } else { strcpy( userHomeDir, homeDir ); - } + } return userHomeDir; } @@ -218,62 +239,101 @@ const char *wGetUserHomeDir( void ) */ typedef struct { - char * section; - char * name; - wBool_t present; - wBool_t dirty; - char * val; - } prefs_t; + char * section; + char * name; + wBool_t present; + wBool_t dirty; + char * val; +} prefs_t; dynArr_t prefs_da; #define prefs(N) DYNARR_N(prefs_t,prefs_da,N) wBool_t prefInitted = FALSE; +/** + * Define the name of the configuration file. Needed size is calculated, allocated and + * initialized with the filename + * + * \param name overwrite default configuration + */ + +void static +wlibSetProfileFilename(char *name) +{ + const char *workDir; + + workDir = wGetAppWorkDir(); + if (name && name[0]) { + size_t length; + length = snprintf(profileFile, 0, "%s", name); + profileFile = malloc(length + sizeof(NULL)); + snprintf( profileFile, length, "%s", name ); + } else { + size_t length; + length = snprintf(profileFile, 0, "%s/%s.rc", workDir, wConfigName ); + profileFile = malloc(length + sizeof(NULL)); + length = snprintf(profileFile, length+sizeof(NULL), "%s/%s.rc", workDir, wConfigName ); + } +} + + +/** + * Get the name of the configuration file. + * + * \return pointer to the filename. + * + */ + +char * +wGetProfileFilename() +{ + return(profileFile); +} + /** * Read the configuration file into memory */ static void readPrefs( char * name, wBool_t update ) { - char tmp[BUFSIZ], *np, *vp, *cp; - const char * workDir; + char tmp[BUFSIZ+32], *np, *vp, *cp; FILE * prefFile; prefs_t * p; prefInitted = TRUE; - workDir = wGetAppWorkDir(); - if (name && name[0]) - sprintf( tmp, "%s", name ); - else - sprintf( tmp, "%s/%s.rc", workDir, wConfigName ); - prefFile = fopen( tmp, "r" ); - if (prefFile == NULL) + wlibSetProfileFilename(name); + + prefFile = fopen( profileFile, "r" ); + if (prefFile == NULL) { + // First run, no .rc file yet return; + } while ( ( fgets(tmp, sizeof tmp, prefFile) ) != NULL ) { char *sp; - + sp = tmp; - while ( *sp==' ' || *sp=='\t' ) sp++; - if ( *sp == '\n' || *sp == '#' ) + while ( *sp==' ' || *sp=='\t' ) { sp++; } + if ( *sp == '\n' || *sp == '#' ) { continue; + } np = strchr( sp, '.' ); if (np == NULL) { wNoticeEx( NT_INFORMATION, tmp, _("Continue"), NULL ); continue; } *np++ = '\0'; - while ( *np==' ' || *np=='\t' ) np++; + while ( *np==' ' || *np=='\t' ) { np++; } vp = strchr( np, ':' ); if (vp == NULL) { wNoticeEx( NT_INFORMATION, tmp, _("Continue"), NULL ); continue; } *vp++ = '\0'; - while ( *vp==' ' || *vp=='\t' ) vp++; + while ( *vp==' ' || *vp=='\t' ) { vp++; } cp = vp + strlen(vp) -1; - while ( cp >= vp && (*cp=='\n' || *cp==' ' || *cp=='\t') ) cp--; + while ( cp >= vp && (*cp=='\n' || *cp==' ' || *cp=='\t') ) { cp--; } cp[1] = '\0'; if (update) { - for (int i=0;iname,np)==0 && strcmp(p->section,sp)==0) { p->val = strdup(vp); @@ -302,19 +362,21 @@ static void readPrefs( char * name, wBool_t update ) */ void wPrefSetString( - const char * section, /* Section */ - const char * name, /* Name */ - const char * sval ) /* Value */ + const char * section, /* Section */ + const char * name, /* Name */ + const char * sval ) /* Value */ { prefs_t * p; - if (!prefInitted) + if (!prefInitted) { readPrefs("", FALSE); - + } + for (p=&prefs(0); p<&prefs(prefs_da.cnt); p++) { if ( strcmp( p->section, section ) == 0 && strcmp( p->name, name ) == 0 ) { - if (p->val) + if (p->val) { free(p->val); + } p->dirty = TRUE; p->val = (sval?strdup( sval ):NULL); return; @@ -336,14 +398,15 @@ void wPrefSetString( */ char * wPrefGetStringBasic( - const char * section, /* Section */ - const char * name ) /* Name */ + const char * section, /* Section */ + const char * name ) /* Name */ { prefs_t * p; - if (!prefInitted) + if (!prefInitted) { readPrefs("", FALSE); - + } + for (p=&prefs(0); p<&prefs(prefs_da.cnt); p++) { if ( strcmp( p->section, section ) == 0 && strcmp( p->name, name ) == 0 ) { return p->val; @@ -360,10 +423,10 @@ char * wPrefGetStringBasic( * \param lval IN value to save */ - void wPrefSetInteger( - const char * section, /* Section */ - const char * name, /* Name */ - long lval ) /* Value */ +void wPrefSetInteger( + const char * section, /* Section */ + const char * name, /* Name */ + long lval ) /* Value */ { char tmp[20]; @@ -382,13 +445,13 @@ char * wPrefGetStringBasic( */ wBool_t wPrefGetIntegerBasic( - const char * section, /* Section */ - const char * name, /* Name */ - long * res, /* Address of result */ - long def ) /* Default value */ + const char * section, /* Section */ + const char * name, /* Name */ + long * res, /* Address of result */ + long def ) /* Default value */ { const char * cp; - char *cp1; + char *cp1; cp = wPrefGetStringBasic( section, name ); if (cp == NULL) { @@ -404,17 +467,17 @@ wBool_t wPrefGetIntegerBasic( } /** - * Save a float value in the preferences file. + * Save a float value in the preferences file. * * \param section IN the file section into which the value should be saved * \param name IN the name of the preference * \param lval IN the value */ - void wPrefSetFloat( - const char * section, /* Section */ - const char * name, /* Name */ - double lval ) /* Value */ +void wPrefSetFloat( + const char * section, /* Section */ + const char * name, /* Name */ + double lval ) /* Value */ { char tmp[20]; @@ -434,13 +497,13 @@ wBool_t wPrefGetIntegerBasic( wBool_t wPrefGetFloatBasic( - const char * section, /* Section */ - const char * name, /* Name */ - double * res, /* Address of result */ - double def ) /* Default value */ + const char * section, /* Section */ + const char * name, /* Name */ + double * res, /* Address of result */ + double def ) /* Default value */ { const char * cp; - char *cp1; + char *cp1; cp = wPrefGetStringBasic( section, name ); if (cp == NULL) { @@ -455,62 +518,117 @@ wBool_t wPrefGetFloatBasic( return TRUE; } -void wPrefsLoad(char * name) { +void wPrefsLoad(char * name) +{ readPrefs(name,TRUE); } /** * Save the configuration to a file. The config parameters are held and updated in an array. - * To make the settings persistant, this function has to be called. + * To make the settings persistant, this function has to be called. * */ void wPrefFlush( - char * name ) + char * name ) { prefs_t * p; - char tmp[BUFSIZ]; - const char *workDir; + char tmp[BUFSIZ+32]; FILE * prefFile; - if (!prefInitted) + if (!prefInitted) { return; - - workDir = wGetAppWorkDir(); - if (name && name[0]) - snprintf( tmp, sizeof(tmp), "%s", name ); - else - snprintf( tmp, sizeof(tmp), "%s/%s.rc", workDir, wConfigName ); - prefFile = fopen( tmp, "w" ); - if (prefFile == NULL) + } + + wlibSetProfileFilename(name); + + prefFile = fopen( profileFile, "w" ); + if (prefFile == NULL) { + // Can not write pref file + size_t n = BUFSIZ+32-1-strlen(tmp); + strncat( tmp, ": ", n ); + strncat( tmp, strerror(errno), n-2 ); + wNoticeEx( NT_ERROR, tmp, "Ok", NULL ); return; + } for (p=&prefs(0); p<&prefs(prefs_da.cnt); p++) { if(p->val) { fprintf( prefFile, "%s.%s: %s\n", p->section, p->name, p->val ); - } + } } fclose( prefFile ); } /** * Clear the preferences from memory - * \return + * \return */ void wPrefReset( - void ) + void ) { prefs_t * p; prefInitted = FALSE; for (p=&prefs(0); p<&prefs(prefs_da.cnt); p++) { - if (p->section) + if (p->section) { free( p->section ); - if (p->name) + } + if (p->name) { free( p->name ); - if (p->val) + } + if (p->val) { free( p->val ); + } } prefs_da.cnt = 0; } + +/** + * Split a line from the config file ie. rc ini-file into separate tokens. The + * line is split into sections, name of value and value following. Pointers + * to the respective token are returned. These are zero-terminated. + * If a token is not present, NULL is returned instead. + * The input line is modified. + * + * \param line input line, modified during excution of function + * \param section section if present + * \param name name of config value if present + * \param value name of value if present + */ +void +wPrefTokenize(char* line, char** section, char** name, char** value) +{ + *section = NULL; + *name = NULL; + *value = NULL; + + *section = strtok(line, "."); + *name = strtok(NULL, ":"); + *value = strtok(NULL, "\n"); + if(*value) + g_strstrip(*value); + +} + +/** + * A valid line for a config file is created from the individual elements. + * Values not need for specific statement are ignored. Eg. when section is + * present, name and value are not used. + * The caller has to make sure, that the return buffer is large enough. + * + * \param section section, first token, dellimited with '.' + * \param name name, left side of ':' + * \param value value, right side of ':' + * \param result pointer to buffer for formated line. + */ + +void +wPrefFormatLine(const char* section, const char* name, const char* value, char* result) +{ + if (!value || *value == '\0') { + value = ""; + } + sprintf(result, "%s.%s: %s", section, name, value); +} \ No newline at end of file -- cgit v1.2.3