Search
lxdream.org :: lxdream/src/lxpaths.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/lxpaths.c
changeset 1286:8376a612a79d
prev1283:2cbafe321d6f
next1296:30ecee61f811
author nkeynes
date Sun Jul 01 13:19:27 2012 +1000 (9 years ago)
permissions -rw-r--r--
last change Add glib/gfileutils.h includes, as some required defines were moved there in recent versions of glib
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * GUI helper functions that aren't specific to any particular implementation.
     5  *
     6  * Copyright (c) 2009 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <ctype.h>
    20 #include <unistd.h>
    21 #include <stdlib.h>
    22 #include <glib/gfileutils.h>
    23 #include <glib/gstrfuncs.h>
    24 #include <glib/gutils.h>
    26 #include "gui.h"
    27 #include "config.h"
    29 static gchar *gui_paths[CONFIG_KEY_MAX];
    31 /**
    32  * Test if we need to escape a path to prevent substitution mangling. 
    33  * @return TRUE if the input value contains any character that doesn't
    34  * match [a-zA-Z0-9._@%/] (this will escape slightly more than it needs to,
    35  * but is safe)
    36  */
    37 static gboolean path_needs_escaping( const gchar *value )
    38 {
    39    const gchar *p = value;
    40    while( *p ) {
    41        if( !isalnum(*p) && *p != '.' && *p != '_' &&
    42                *p != '@' && *p != '%' && *p != '/' ) {
    43            return TRUE;
    44        }
    45        p++;
    46    }
    47    return FALSE;
    48 }
    50 gchar *get_escaped_path( const gchar *value )
    51 {
    52     if( value != NULL && path_needs_escaping(value) ) {
    53         /* Escape with "", and backslash the remaining characters:
    54          *   \ " $ `
    55          */
    56         char buf[strlen(value)*2+3];  
    57         const char *s = value;
    58         char *p = buf;
    59         *p++ = '\"';
    60         while( *s ) {
    61             if( *s == '\\' || *s == '"' || *s == '$' || *s == '`' ) {
    62                 *p++ = '\\';
    63             }
    64             *p++ = *s++;
    65         }
    66         *p++ = '\"';
    67         *p = '\0';
    68         return g_strdup(buf);
    69     } else {
    70         return g_strdup(value);
    71     }
    72 }
    74 gchar *get_expanded_path( const gchar *input )
    75 {
    76     char result[PATH_MAX];
    78     char *d, *e;
    79     const char *s;
    80     d = result;
    81     e = result+sizeof(result)-1;
    82     s = input;
    83     gboolean inDQstring = FALSE;
    85     if( input == NULL )
    86         return NULL;
    88     while( *s ) {
    89         if( d == e ) {
    90             return g_strdup(input); /* expansion too long */
    91         }
    92         char c = *s++;
    93         if( c == '$' ) {
    94             if( *s == '{' ) {
    95                 s++;
    96                 const char *q = s;
    97                 while( *q != '}' ) {
    98                     if( ! *q ) {
    99                         return g_strdup(input); /* unterminated variable */
   100                     }
   101                     q++;
   102                 }
   103                 char *tmp = g_strndup(s, (q-s));
   104                 s = q+1;
   105                 char *value = getenv(tmp);
   106                 g_free(tmp);
   107                 if( value != NULL ) {
   108                     int len = strlen(value);
   109                     if( d + len > e )
   110                         return g_strdup(input);
   111                     strcpy(d, value);
   112                     d+=len;
   113                 } /* Else, empty string */
   114             } else {
   115                 const char *q = s;
   116                 while( isalnum(*q) || *q == '_' ) {
   117                     q++;
   118                 }
   119                 if( q == s ) {
   120                     *d++ = '$';
   121                 } else {
   122                     char *tmp = g_strndup(s,q-s);
   123                     s = q;
   124                     char *value = getenv(tmp);
   125                     g_free(tmp);
   126                     if( value != NULL ) {
   127                         int len = strlen(value);
   128                         if( d + len > e )
   129                             return g_strdup(input);
   130                         strcpy(d, value);
   131                         d += len;
   132                     }
   133                 }
   134             }
   135         } else if( c == '\\' ) {
   136             c = *s++;
   137             if( c ) {
   138                 *d++ = c;
   139             } else {
   140                 *d++ = '\\';
   141             }
   142         } else if( c == '\"' ) {
   143             /* Unescaped double-quotes start a DQ string. Although we treat the
   144              * string as if it were double-quoted for most purposes anyway, so
   145              * this has little effect.
   146              */
   147             inDQstring = !inDQstring;
   148         } else {
   149             *d++ = c;
   150         }
   151     }
   152     *d = '\0';
   153     if( inDQstring ) {
   154         WARN( "Unterminated double-quoted string '%s'", input );
   155     }
   156     return g_strdup(result);
   157 }
   158 gchar *get_absolute_path( const gchar *in_path )
   159 {
   160     char tmp[PATH_MAX];
   161     if( in_path == NULL ) {
   162         return NULL;
   163     }
   164     if( in_path[0] == '/' || in_path[0] == 0 ) {
   165         return g_strdup(in_path);
   166     } else {
   167         getcwd(tmp, sizeof(tmp));
   168         return g_strdup_printf("%s%c%s", tmp, G_DIR_SEPARATOR, in_path);
   169     }
   170 }
   172 gchar *get_filename_at( const gchar *at, const gchar *filename )
   173 {
   174     char tmp[PATH_MAX];
   175     char *p = strrchr( at, '/' );
   176     if( p == NULL ) {
   177         /* No path at all, so just return filename */
   178         return g_strdup(filename);
   179     } else {
   180         int off = p-at;
   181         return g_strdup_printf("%.*s%c%s", off, at, G_DIR_SEPARATOR, filename );
   182     }
   183 }
   185 const gchar *get_gui_path( int key )
   186 {
   187     if( gui_paths[key] == NULL ) {
   188         gui_paths[key] = lxdream_get_global_config_path_value(key);
   189         /* If no path defined, go with the current working directory */
   190         if( gui_paths[key] == NULL ) {
   191             gui_paths[key] = get_absolute_path(".");
   192         }
   193     }
   194     return gui_paths[key];
   195 }
   197 void set_gui_path( int key, const gchar *path )
   198 {
   199     g_free(gui_paths[key]);
   200     gui_paths[key] = g_strdup(path);
   201 }
   203 void reset_gui_paths()
   204 {
   205     int i;
   206     for( i=0; i < CONFIG_KEY_MAX; i++ ) {
   207         g_free(gui_paths[i]);
   208         gui_paths[i] = NULL;
   209     }
   210 }
.