fltk  1.3.5-source
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X.
  Fossies Dox: fltk-1.3.5-source.tar.bz2  ("inofficial" and yet experimental doxygen-generated source code documentation)  

filename_absolute.cxx
Go to the documentation of this file.
1 //
2 // "$Id$"
3 //
4 // Filename expansion routines for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 by Bill Spitzak and others.
7 //
8 // This library is free software. Distribution and use rights are outlined in
9 // the file "COPYING" which should have been included with this file. If this
10 // file is missing or damaged, see the license at:
11 //
12 // http://www.fltk.org/COPYING.php
13 //
14 // Please report all bugs and problems on the following page:
15 //
16 // http://www.fltk.org/str.php
17 //
18 
19 /* expand a file name by prepending current directory, deleting . and
20  .. (not really correct for symbolic links) between the prepended
21  current directory. Use $PWD if it exists.
22  Returns true if any changes were made.
23 */
24 
25 #include <FL/filename.H>
26 #include <FL/fl_utf8.h>
27 #include <stdlib.h>
28 #include "flstring.h"
29 #include <ctype.h>
30 #if defined(WIN32) && !defined(__CYGWIN__)
31 # include <direct.h>
32 #else
33 # include <unistd.h>
34 #endif
35 
36 #if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
37 inline int isdirsep(char c) {return c=='/' || c=='\\';}
38 #else
39 #define isdirsep(c) ((c)=='/')
40 #endif
41 
56 int fl_filename_absolute(char *to, int tolen, const char *from) {
57  if (isdirsep(*from) || *from == '|'
58 #if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
59  || from[1]==':'
60 #endif
61  ) {
62  strlcpy(to, from, tolen);
63  return 0;
64  }
65 
66  char *a;
67  char *temp = new char[tolen];
68  const char *start = from;
69 
70  a = fl_getcwd(temp, tolen);
71  if (!a) {
72  strlcpy(to, from, tolen);
73  delete[] temp;
74  return 0;
75  }
76 #if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)
77  for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha
78 #else
79  a = temp+strlen(temp);
80 #endif
81  if (isdirsep(*(a-1))) a--;
82  /* remove intermediate . and .. names: */
83  while (*start == '.') {
84  if (start[1]=='.' && isdirsep(start[2])) {
85  char *b;
86  for (b = a-1; b >= temp && !isdirsep(*b); b--) {/*empty*/}
87  if (b < temp) break;
88  a = b;
89  start += 3;
90  } else if (isdirsep(start[1])) {
91  start += 2;
92  } else if (!start[1]) {
93  start ++; // Skip lone "."
94  break;
95  } else
96  break;
97  }
98 
99  *a++ = '/';
100  strlcpy(a,start,tolen - (a - temp));
101 
102  strlcpy(to, temp, tolen);
103 
104  delete[] temp;
105 
106  return 1;
107 }
108 
127 int // O - 0 if no change, 1 if changed
128 fl_filename_relative(char *to, // O - Relative filename
129  int tolen, // I - Size of "to" buffer
130  const char *from) // I - Absolute filename
131 {
132  char cwd_buf[FL_PATH_MAX]; // Current directory
133  // get the current directory and return if we can't
134  if (!fl_getcwd(cwd_buf, sizeof(cwd_buf))) {
135  strlcpy(to, from, tolen);
136  return 0;
137  }
138  return fl_filename_relative(to, tolen, from, cwd_buf);
139 }
140 
141 
149 int // O - 0 if no change, 1 if changed
150 fl_filename_relative(char *to, // O - Relative filename
151  int tolen, // I - Size of "to" buffer
152  const char *from, // I - Absolute filename
153  const char *base) { // I - Find path relative to this path
154 
155  char *newslash; // Directory separator
156  const char *slash; // Directory separator
157  char *cwd = 0L, *cwd_buf = 0L;
158  if (base) cwd = cwd_buf = strdup(base);
159 
160  // return if "from" is not an absolute path
161 #if defined(WIN32) || defined(__EMX__)
162  if (from[0] == '\0' ||
163  (!isdirsep(*from) && !isalpha(*from) && from[1] != ':' &&
164  !isdirsep(from[2]))) {
165 #else
166  if (from[0] == '\0' || !isdirsep(*from)) {
167 #endif // WIN32 || __EMX__
168  strlcpy(to, from, tolen);
169  if (cwd_buf) free(cwd_buf);
170  return 0;
171  }
172 
173  // return if "cwd" is not an absolute path
174 #if defined(WIN32) || defined(__EMX__)
175  if (!cwd || cwd[0] == '\0' ||
176  (!isdirsep(*cwd) && !isalpha(*cwd) && cwd[1] != ':' &&
177  !isdirsep(cwd[2]))) {
178 #else
179  if (!cwd || cwd[0] == '\0' || !isdirsep(*cwd)) {
180 #endif // WIN32 || __EMX__
181  strlcpy(to, from, tolen);
182  if (cwd_buf) free(cwd_buf);
183  return 0;
184  }
185 
186 #if defined(WIN32) || defined(__EMX__)
187  // convert all backslashes into forward slashes
188  for (newslash = strchr(cwd, '\\'); newslash; newslash = strchr(newslash + 1, '\\'))
189  *newslash = '/';
190 
191  // test for the exact same string and return "." if so
192  if (!strcasecmp(from, cwd)) {
193  strlcpy(to, ".", tolen);
194  free(cwd_buf);
195  return (1);
196  }
197 
198  // test for the same drive. Return the absolute path if not
199  if (tolower(*from & 255) != tolower(*cwd & 255)) {
200  // Not the same drive...
201  strlcpy(to, from, tolen);
202  free(cwd_buf);
203  return 0;
204  }
205 
206  // compare the path name without the drive prefix
207  from += 2; cwd += 2;
208 #else
209  // test for the exact same string and return "." if so
210  if (!strcmp(from, cwd)) {
211  strlcpy(to, ".", tolen);
212  free(cwd_buf);
213  return (1);
214  }
215 #endif // WIN32 || __EMX__
216 
217  // compare both path names until we find a difference
218  for (slash = from, newslash = cwd;
219  *slash != '\0' && *newslash != '\0';
220  slash ++, newslash ++)
221  if (isdirsep(*slash) && isdirsep(*newslash)) continue;
222 #if defined(WIN32) || defined(__EMX__) || defined(__APPLE__)
223  else if (tolower(*slash & 255) != tolower(*newslash & 255)) break;
224 #else
225  else if (*slash != *newslash) break;
226 #endif // WIN32 || __EMX__ || __APPLE__
227 
228  // skip over trailing slashes
229  if ( *newslash == '\0' && *slash != '\0' && !isdirsep(*slash)
230  &&(newslash==cwd || !isdirsep(newslash[-1])) )
231  newslash--;
232 
233  // now go back to the first character of the first differing paths segment
234  while (!isdirsep(*slash) && slash > from) slash --;
235  if (isdirsep(*slash)) slash ++;
236 
237  // do the same for the current dir
238  if (isdirsep(*newslash)) newslash --;
239  if (*newslash != '\0')
240  while (!isdirsep(*newslash) && newslash > cwd) newslash --;
241 
242  // prepare the destination buffer
243  to[0] = '\0';
244  to[tolen - 1] = '\0';
245 
246  // now add a "previous dir" sequence for every following slash in the cwd
247  while (*newslash != '\0') {
248  if (isdirsep(*newslash)) strlcat(to, "../", tolen);
249 
250  newslash ++;
251  }
252 
253  // finally add the differing path from "from"
254  strlcat(to, slash, tolen);
255 
256  free(cwd_buf);
257  return 1;
258 }
259 
260 
261 //
262 // End of "$Id$".
263 //
fl_filename_relative
int fl_filename_relative(char *to, int tolen, const char *from)
Definition: filename_absolute.cxx:128
fl_getcwd
char * fl_getcwd(char *buf, int maxlen)
Definition: fl_utf8.cxx:699
isdirsep
#define isdirsep(c)
Definition: filename_absolute.cxx:39
filename.H
free
void free()
b
long b
Definition: jpegint.h:397
fl_utf8.h
header for Unicode and UTF-8 character handling
FL_PATH_MAX
#define FL_PATH_MAX
Definition: filename.H:38
strlcpy
#define strlcpy
Definition: flstring.h:84
fl_filename_absolute
int fl_filename_absolute(char *to, int tolen, const char *from)
Definition: filename_absolute.cxx:56
flstring.h
strlcat
#define strlcat
Definition: flstring.h:79
start
static int start(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy, int &X, int &Y, int &W, int &H)
Definition: Fl_Image.cxx:655