2 // "$Id: filename_expand.cxx 7903 2010-11-28 21:06:39Z matt $"
4 // Filename expansion routines for the Fast Light Tool Kit (FLTK).
6 // Copyright 1998-2010 by Bill Spitzak and others.
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library 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 GNU
16 // Library General Public License for more details.
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 // Please report all bugs and problems on the following page:
25 // http://www.fltk.org/str.php
28 /* expand a file name by substuting environment variables and
29 home directories. Returns true if any changes were made.
30 to & from may be the same buffer.
33 #include <FL/filename.H>
34 #include <FL/fl_utf8.h>
37 #if defined(WIN32) && !defined(__CYGWIN__)
44 #if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
45 static inline int isdirsep(char c
) {return c
=='/' || c
=='\\';}
47 #define isdirsep(c) ((c)=='/')
50 /** Expands a filename containing shell variables and tilde (~).
51 Currently handles these variants:
53 "~username" // if 'username' does not exist, result will be unchanged
55 "$VARNAME" // does NOT handle ${VARNAME}
60 #include <FL/filename.H>
62 putenv("TMPDIR=/var/tmp");
63 fl_filename_expand(out, sizeof(out), "~fred/.cshrc"); // out="/usr/fred/.cshrc"
64 fl_filename_expand(out, sizeof(out), "~/.cshrc"); // out="/usr/<yourname>/.cshrc"
65 fl_filename_expand(out, sizeof(out), "$TMPDIR/foo.txt"); // out="/var/tmp/foo.txt"
67 \param[out] to resulting expanded filename
68 \param[in] tolen size of the expanded filename buffer
69 \param[in] from filename containing shell variables
70 \return 0 if no change, non zero otherwise
72 int fl_filename_expand(char *to
,int tolen
, const char *from
) {
74 char *temp
= new char[tolen
];
75 strlcpy(temp
,from
, tolen
);
77 char *end
= temp
+strlen(temp
);
81 for (char *a
=temp
; a
<end
; ) { // for each slash component
82 char *e
; for (e
=a
; e
<end
&& !isdirsep(*e
); e
++); // find next slash
83 const char *value
= 0; // this will point at substitute value
85 case '~': // a home directory name
86 if (e
<= a
+1) { // current user's directory
87 value
= fl_getenv("HOME");
89 } else { // another user's directory
91 char t
= *e
; *(char *)e
= 0;
94 if (pwd
) value
= pwd
->pw_dir
;
98 case '$': /* an environment variable */
99 {char t
= *e
; *(char *)e
= 0; value
= fl_getenv(a
+1); *(char *)e
= t
;}
103 // substitutions that start with slash delete everything before them:
104 if (isdirsep(value
[0])) start
= a
;
105 #if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
106 // also if it starts with "A:"
107 if (value
[0] && value
[1]==':') start
= a
;
109 int t
= strlen(value
); if (isdirsep(value
[t
-1])) t
--;
110 if ((end
+1-e
+t
) >= tolen
) end
+= tolen
- (end
+1-e
+t
);
111 memmove(a
+t
, e
, end
+1-e
);
118 #if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
119 if (*e
== '\\') {*e
= '/'; ret
++;} // ha ha!
124 strlcpy(to
, start
, tolen
);
133 // End of "$Id: filename_expand.cxx 7903 2010-11-28 21:06:39Z matt $".