summaryrefslogtreecommitdiff
path: root/app/wlib/gtklib/wpref.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/wlib/gtklib/wpref.c')
-rw-r--r--app/wlib/gtklib/wpref.c310
1 files changed, 214 insertions, 96 deletions
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 <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/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;i<prefs_da.cnt;i++) {
+ 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);
@@ -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