23 #include <system_helper.h>
27 #include <sys/types.h>
28 #if defined(__UNIX__) || defined(__GNU_WINDOWS__)
35 #define LOG(to_print) printf("%s::%s: %s\n", static_class_name(), func, astring(to_print).s())
37 using namespace basis;
40 class status_info :
public stat
74 _had_directory =
false;
78 bool add_slash =
false;
82 *
this += name_of_file;
88 _had_directory(to_copy._had_directory)
105 _had_directory =
true;
123 if (
this == &to_copy)
return *
this;
125 _had_directory = to_copy._had_directory;
131 _had_directory =
true;
132 if (
this == &to_copy)
return *
this;
161 bool found_sep =
false;
162 for (
int j = 0; j <
length(); j++) {
172 if (!found_sep) _had_directory =
false;
177 bool saw_sep =
false;
178 for (
int i = 1; i <
length(); i++) {
187 }
else saw_sep =
false;
195 const astring CYGDRIVE_SENTINEL =
"cygdrive";
203 &&
compare(CYGDRIVE_SENTINEL, 1,
204 0, CYGDRIVE_SENTINEL.
length(),
true) ) {
240 bool inject_root =
false;
263 insert(0, FEISTY_MEOW_VIRTUAL_UNIX_ROOT);
272 const int last =
end();
274 }
else if ( (
length() == 2) && (
get(1) ==
':') ) {
289 if (!interact_with_fs)
294 if (!get_info(&fill))
296 return char(
'A' + fill.st_dev);
302 int posn = base.
find(
'.', base.
end(),
true);
311 int posn = base.
find(
'.', base.
end(),
true);
317 bool filename::get_info(status_info *to_fill)
const
328 if (!get_info(&fill))
330 return !!(fill.st_mode &
S_IFDIR);
336 if (!get_info(&fill))
344 if (!get_info(&fill))
346 return !!(fill.st_mode &
S_IREAD);
352 if (!get_info(&fill))
354 return !!(fill.st_mode &
S_IEXEC);
360 if (!get_info(&fill))
362 #if defined(__WIN32__) || defined(__VMS__)
366 bool weird = S_ISCHR(fill.st_mode)
367 || S_ISBLK(fill.st_mode)
368 || S_ISFIFO(fill.st_mode)
369 || S_ISSOCK(fill.st_mode);
374 int filename::find_last_separator(
const astring &look_at)
const
380 if (sep >= 0) last_sep = sep;
388 int last_sep = find_last_separator(
basename);
396 int last_sep = find_last_separator(
dirname);
441 case '*':
case '?':
case '$':
case '&':
case '|':
442 case '\'':
case '"':
case '`':
448 default:
return true;
454 for (
int i = 0; i < to_clean.
length(); i++) {
456 to_clean[i] = replacement;
467 attach(packed_form,
int(_had_directory));
474 if (!
detach(packed_form, temp))
476 _had_directory = temp;
488 for (
int i = 0; i < raw_form.
length(); i++) {
492 if (i && accumulator.
length()) pieces += accumulator;
494 accumulator = astring::empty_string();
497 accumulator += raw_form[i];
500 if (accumulator.
length()) pieces += accumulator;
507 for (
int i = 0; i < pieces.
length(); i++) {
508 constructed_name += pieces[i];
509 if (!i || (i != pieces.
length() - 1))
512 *
this = constructed_name;
515 bool filename::base_compare_prefix(
const filename &to_compare,
521 to_compare.
separate(second_rooted, second);
522 if (first_rooted != second_rooted) {
531 for (
int i = 0; i < first.
length(); i++) {
532 #if defined(__WIN32__) || defined(__VMS__)
534 if (!first[i].
iequals(second[i]))
538 if (first[i] != second[i])
547 sequel = astring::empty_string();
550 if (!base_compare_prefix(to_compare, first, second))
555 for (
int i = second.
length() - extra_strings; i < second.
length(); i++) {
567 return base_compare_prefix(to_compare, first, second);
570 bool filename::base_compare_suffix(
const filename &to_compare,
576 to_compare.
separate(second_rooted, second);
583 for (
int i = first.
length() - 1; i >= 0; i--) {
585 int distance_from_end = first.
length() - 1 - i;
586 int j = second.
length() - 1 - distance_from_end;
587 #if defined(__WIN32__) || defined(__VMS__)
589 if (!first[i].
iequals(second[j]))
593 if (first[i] != second[j])
602 prequel = astring::empty_string();
605 if (!base_compare_suffix(to_compare, first, second))
610 for (
int i = 0; i < extra_strings; i++) {
611 prequel += second[i];
621 return base_compare_suffix(to_compare, first, second);
629 if (owner_mode &
USER_RIGHTS) chmod_value |= S_IRUSR;
634 if (owner_mode &
USER_RIGHTS) chmod_value |= S_IWUSR;
639 #elif defined(__WIN32__)
641 chmod_value |= _S_IREAD;
644 chmod_value |= _S_IWRITE;
647 #error unsupported OS type currently.
649 int chmod_result =
::chmod(
raw().
s(), chmod_value);
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
int length() const
Returns the current reported length of the allocated C array.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
virtual char get(int index) const
a constant peek at the string's internals at the specified index.
virtual void zap(int start, int end)
Deletes the characters between "start" and "end" inclusively.
astring()
constructs an empty string.
bool substring(astring &target, int start, int end) const
a version that stores the substring in an existing "target" string.
bool iequals(const astring &that) const
returns true if this is case-insensitively equal to "that".
void insert(int position, const astring &to_insert)
Copies "to_insert" into "this" at the "position".
void reset()
clears out the contents string.
bool equal_to(const char *that) const
returns true if "that" is equal to this.
int end() const
returns the index of the last (non-null) character in the string.
virtual void put(int position, char to_put)
stores the character "to_put" at index "position" in the string.
int length() const
Returns the current length of the string.
bool compare(const astring &to_compare, int start_first, int start_second, int count, bool case_sensitive) const
Compares "this" string with "to_compare".
int find(char to_find, int position=0, bool reverse=false) const
Locates "to_find" in "this".
virtual const char * observe() const
observes the underlying pointer to the zero-terminated string.
A very common template for a dynamic array of bytes.
Implements a scanner that finds all filenames in the directory specified.
Provides operations commonly needed on file names.
bool exists() const
returns true if the file exists.
static bool separator(char is_it)
returns true if the character "is_it" in question is a separator.
void canonicalize()
cleans up the filename as needed for the current operating system.
void join(bool rooted, const structures::string_array &pieces)
undoes a separate() operation to get the filename back.
bool good() const
returns true if the filename seems to be valid.
virtual bool unpack(basis::byte_array &packed_form)
Restores the packable from the "packed_form".
void separate(bool &rooted, structures::string_array &pieces) const
breaks the filename into its component parts.
bool compare_prefix(const filename &to_compare, basis::astring &sequel)
examines "this" filename to see if it's a prefix of "to_compare".
static basis::astring default_separator()
returns the default separator character for this OS.
basis::astring extension() const
returns the extension for the file, if one is present.
filename parent() const
returns the parent filename for this one.
virtual void pack(basis::byte_array &packed_form) const
Creates a packed form of the packable object in "packed_form".
char drive(bool interact_with_fs=false) const
returns the drive letter for the file, without the colon.
basis::astring rootname() const
returns the root part of the basename without an extension.
bool compare_suffix(const filename &to_compare, basis::astring &prequel)
compares the back end of a filename to this.
static basis::astring null_device()
returns the name for the black hole device that consumes all input, i.e. /dev/null.
bool chmod(int write_mode, int owner_mode) const
changes the access rights on the file.
bool is_directory() const
void push(const basis::astring &to_push)
pushes a new filename onto the current pathname.
const basis::astring & raw() const
returns the astring that we're holding onto for the path.
filename dirname() const
returns the directory for the filename.
bool is_executable() const
bool unlink() const
actually removes the file, if possible.
static void detooth_filename(basis::astring &to_clean, char replacement='_')
takes any known illegal file system characters out of "to_clean".
filename basename() const
returns the base of the filename; no directory.
basis::astring pop()
removes the deepest component of the pathname.
filename & operator=(const filename &to_copy)
provides assignment for this object, plus a simple string.
static bool legal_character(char to_check)
returns true if "to_check" is a valid character in a filename.
virtual int packed_size() const
Estimates the space needed for the packed structure.
filename()
blank constructor.
An array of strings with some additional helpful methods.
static bool is_alpha(char look_at)
returns true if "look_at" is one of the alphabetical characters.
static bool is_alphanumeric(char look_at)
returns true if "look_at" is one of the alphanumeric characters.
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
The guards collection helps in testing preconditions and reporting errors.
void attach(byte_array &packed_form, const char *to_attach)
Packs a character string "to_attach" into "packed_form".
bool detach(byte_array &packed_form, astring &to_detach)
Unpacks a character string "to_attach" from "packed_form".
bool negative(const type &a)
negative returns true if "a" is less than zero.
A platform independent way to obtain the timestamp of a file.
const char DEFAULT_SEPARATOR
const char * NO_PARENT_DEFAULT
A dynamic container class that holds any kind of object via pointers.
bool unpack(basis::byte_array &packed_form, set< contents > &to_unpack)
provides a way to unpack any set that stores packable objects.
void pack(basis::byte_array &packed_form, const set< contents > &to_pack)
provides a way to pack any set that stores packable objects.
const int PACKED_SIZE_INT32
int packed_size(const byte_array &packed_form)
Reports the size required to pack a byte array into a byte array.