diff options
Diffstat (limited to 'app/wlib/gtklib/wpref.c')
-rw-r--r-- | app/wlib/gtklib/wpref.c | 360 |
1 files changed, 254 insertions, 106 deletions
diff --git a/app/wlib/gtklib/wpref.c b/app/wlib/gtklib/wpref.c index 124305a..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 <stdio.h> @@ -26,6 +26,7 @@ #include <ctype.h> #include <dirent.h> #include <sys/stat.h> +#include <errno.h> #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/lib/xtrkcad - * 4. /usr/local/lib/xtrkcad - * + * 3. /usr/share/xtrkcad + * 4. /usr/local/share/xtrkcad + * * \return pointer to directory name */ @@ -79,46 +82,66 @@ 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; } } - strcpy(appLibDir, XTRKCAD_INSTALL_PREFIX); - strcat(appLibDir, "/share/"); + strcpy(appLibDir, "../share/"); strcat(appLibDir, wlibGetAppName()); - if ((stat( appLibDir, &buf) == 0 ) && S_ISDIR( buf.st_mode)) { + //printf( "wAppLbDir=%s\n", appLibDir ); return appLibDir; } - strcpy( appLibDir, "/usr/lib/" ); + 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; } - strcpy( appLibDir, "/usr/local/lib/" ); + strcpy( appLibDir, dir2 ); strcat( appLibDir, wlibGetAppName() ); if ((stat( appLibDir, &buf) == 0 ) && S_ISDIR( buf.st_mode)) { + //printf( "wAppLbDir=%s\n", appLibDir ); return appLibDir; } 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" - " %s/share/xtrkcad or\n" - " /usr/lib/%s or\n" - " /usr/local/lib/%s\n" - "If this is not possible, the environment variable %s must contain " - "the name of the correct directory."), - XTRKCAD_INSTALL_PREFIX, 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); @@ -135,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 { @@ -157,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 ); } } } @@ -185,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; } @@ -209,63 +239,116 @@ 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( void ) +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(); - 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'; - DYNARR_APPEND( prefs_t, prefs_da, 10 ); - p = &prefs(prefs_da.cnt-1); - p->name = strdup(np); - p->section = strdup(sp); - p->dirty = FALSE; - p->val = strdup(vp); + if (update) { + for (int i=0; i<prefs_da.cnt; i++) { + p = &DYNARR_N(prefs_t,prefs_da,i); + if (strcmp(p->name,np)==0 && strcmp(p->section,sp)==0) { + p->val = strdup(vp); + p->dirty = TRUE; + break; + } + } + } else { + DYNARR_APPEND( prefs_t, prefs_da, 10 ); + p = &prefs(prefs_da.cnt-1); + p->name = strdup(np); + p->section = strdup(sp); + p->dirty = FALSE; + p->val = strdup(vp); + } } fclose( prefFile ); } @@ -279,19 +362,21 @@ static void readPrefs( void ) */ 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) - readPrefs(); - + 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; @@ -313,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) - readPrefs(); - + 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; @@ -337,14 +423,14 @@ 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]; - sprintf(tmp, "%ld", lval ); + snprintf(tmp, sizeof(tmp), "%ld", lval ); wPrefSetString( section, name, tmp ); } @@ -359,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) { @@ -381,21 +467,21 @@ 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]; - sprintf(tmp, "%0.6f", lval ); + snprintf(tmp, sizeof(tmp), "%0.6f", lval ); wPrefSetString( section, name, tmp ); } @@ -411,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) { @@ -432,55 +518,117 @@ wBool_t wPrefGetFloatBasic( return TRUE; } +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( - void ) + char * name ) { prefs_t * p; - char tmp[BUFSIZ]; - const char *workDir; + char tmp[BUFSIZ+32]; FILE * prefFile; - if (!prefInitted) + if (!prefInitted) { return; - - workDir = wGetAppWorkDir(); - sprintf( 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 |