Laxkit  0.0.7.1
Classes | Functions | Variables
LaxFiles Namespace Reference

Namespace for various file utilities. More...

Classes

class  Attribute
 Basic building block of entries. More...
class  DumpUtility
 Class to provide do nothing place holders for dump_out, dump_in_atts, and a standard dump_in. More...

Functions

int ByteSizeAttribute (const char *s, long *ll, char towhat)
 Convert strings like "24kb" and "3M" to a number.
int DoubleAttribute (const char *v, double *d, char **endptr)
 Turn v into a double, put in d if successful, return 1. Else don't change d and return 0.
int DoubleListAttribute (const char *v, double *d, int maxn, char **endptr)
 Turn v into a double[] of maximum size n. d must already exist. Returns number of items parsed.
int DoubleListAttribute (const char *v, double **d, int *n_ret)
 Turn v into a new double[], and put it in d. Put the number of values in n_ret.
int FloatAttribute (const char *v, float *f, char **endptr)
 Turn v into a float, put in f if successful, return 1. Else don't change f and return 0.
int UIntAttribute (const char *v, unsigned int *i, char **endptr)
 Turn v into an unsigned int, put in i if successful, return 1. Else don't change i and return 0.
int IntAttribute (const char *v, int *i, char **endptr)
 Turn v into an int, put in i if successful, return 1. Else don't change i and return 0.
int BooleanAttribute (const char *v)
 Figure out if value is yes==true==1 or no==false==0. Return the boolean value.
int SimpleColorAttribute (const char *v, unsigned long *color_ret)
 Find an ARGB color packed into an unsigned long.
int HexColorAttributeRGB (const char *v, Laxkit::ScreenColor *color, char **endptr)
 Read in an rgb value such as "af3" or "ff00ff".
int HexColorAttributeRGB (const char *v, unsigned long *l, char **endptr)
 Read in an rgb value such as "af3" or "ff00ff".
int FlatvectorAttribute (const char *v, flatvector *vec, char **endptr)
 Return from something like "1 2", "1,2", "(1,2)", or "(1 2)".
int ULongAttribute (const char *v, unsigned long *l, char **endptr)
 Turn v into an unsigned long, put in l if successful, return 1. Else don't change l and return 0.
int LongAttribute (const char *v, long *l, char **endptr)
 Turn v into a long, put in l if successful.
int IntListAttribute (const char *v, int *i, int maxn, char **endptr)
 Turn v into an int[] of maximum size n. Return the number of integers parsed.
int IntListAttribute (const char *v, int **i, int *n_ret, char **endptr)
 Turn v into a new int[], and put it in i. Put the number of values in n_ret.
double * TransformAttribute (const char *v, double *m, char **endptr)
 Return a double[6] transform derived from v.
charQuotedAttribute (const char *v, char **endptr)
 Grab the first chunk of str, return as new char[].
charWholeQuotedAttribute (const char *v)
 Like QuotedAttribute(), but assumes that the whole thing is meant as only one chunk.
void dump_out_value (FILE *f, int indent, const char *value, int noquotes)
 Used to dump out the value part of an attribute.
void dump_out_escaped (FILE *f, const char *str, int n)
 Dump out n characters of string, escaping quote characters if necessary.
void dump_out_indented (FILE *f, int indent, const char *str)
 Just dump out string at constant indent.
void skip_to_next_attribute (FILE *f, int indent)
 Skip until the first nonblank, non-comment line that has indentation less or equal to indent.
charremoveescapes (char *&str)
 Remove backslashes. Double backslash becomes single backslash.
int NameValueAttribute (const char *str, char **name, char **value, char **end_ptr, char assign, char delim, const char *stopat)
 Extract a single "name=value" string. The value can be quoted.
AttributeNameValueToAttribute (Attribute *att, const char *str, char assign, char delim)
 Transform something like "name=value name2=value2" into an Attribute.
int AttributeToXMLFile (FILE *f, Attribute *att, int indent)
int SubAttributesToXMLFile (FILE *f, Attribute *att, int indent)
 Output any Attribute to some generic XML.
charAttributeToXML (Attribute *att, char *&appendtothis, char **error_ret)
 Convert the attribute to a character array.
AttributeXMLFileToAttribute (Attribute *att, const char *file, const char **stand_alone_tag_list)
 Read in an XML file, and rather simply make an Attribute out of it.
AttributeXMLChunkToAttribute (Attribute *att, FILE *f, const char **stand_alone_tag_list)
 Read in a part of an XML stream.
static void skipws (const char *buf, long n, long *c)
 Skip starting at c. Update c to point to the first non whitespace, non comment.
int one_of_them (const char *str, const char **list)
 Return 1 for str in list, or 0. list is NULL terminated list.
AttributeXMLChunkToAttribute (Attribute *att, const char *buf, long n, long *C, const char *until, const char **stand_alone_tag_list)
 Read in XML to an Attribute from a memory buffer.
int AttributeToCSSFile (FILE *f, Attribute *att, int indent)
 Write out a specially formatted Attribute to a CSS file.
charAttributeToCSS (Attribute *att, char **appendtothis, char **error_ret)
AttributeCSSFileToAttribute (const char *cssfile, Attribute *att)
 Create a specially formatted Attribute with data from a CSS file.
AttributeCSSToAttribute (const char *css, Attribute *att)
int how_indented (char *str, char **strt)
 Return the number of whitespace characters at the beginning of str.
int getline_indent_nonblank (char **line, size_t *n, FILE *f, int indent, const char *comment, char quote, char skiplines, int *lineindent)
 Read the line if indented>=indent, skipping blank lines and comments.
int cut_comment (char *str, const char *cm, char quote)
 Remove single line comments. Return number of characters removed.
int is_good_filename (const char *filename)
 Basic filename sanitizer checker. sanitize_filename() does actual sanitizing.
int check_dirs (const char *dirs, char make_too)
 Check directory components for existence, and make them if (make_too).
charsanitize_filename (char *filename, int makedup)
 Strip out characters not in: [a-zA-Z0-9+=-_.% ].
int lax_stat (const char *file, int followlink, struct stat *buf)
 Wrapper around stat().
long file_size (const char *filename, int followlink, int *error)
 Return the size in bytes of the file, or -1 for error.
int file_exists (const char *filename, int followlink, int *error)
 Return statbuf.st_mode&S_IFMT if exists. Else return 0.
int readable_file (const char *filename, FILE **ff)
 Return if filename is a regular readable file.
charsimplify_path (char *origfile, int modorig)
 Collapses any excess stuff like '/a/../b' which becomes '/b'.
charfile_to_uri (const char *file)
 For "~/blah", will return "file:///home/whoever/blah" for instance.
charexpand_home (const char *file)
 Return a new char[] with the expansion performed.
charexpand_home_inplace (char *&file)
 Replace an initial "~/" with the $HOME environment variable.
charfull_path_for_file (const char *file, const char *path)
 Convert "blah" to "/full/path/to/blah". Works with (const char *), rather than (char *).
charconvert_to_full_path (char *&file, const char *path)
 Basically convert 'blah' to '/full/path/to/blah', changing contents of file.
charrelative_file (const char *file, const char *relativeto, char isdir)
 Return a new char[] containing the path to file, relative to relativeto.
int is_in_subdir (const char *file, const char *dir)
 Return whether file has dir as its initial path.
charmake_filename_base (const char *f)
 Turns "blah###.eps" into "blah%03d.eps".
charread_in_whole_file (const char *file, int *chars_ret, int maxchars)
 Return a new, null terminated char[] containing the contents of file, or NULL on error.
charget_bookmarks (const char *file, const char *filetype)
 Read in file bookmarks.
int touch_recently_used (const char *file, const char *mime, const char *group, const char *timestamp)
Attributerecently_used_att (const char *file)
 Return an Attribute created from XML.
charrecently_used (const char *mimetype, const char *group, int includewhat)
 Return a newline separated list of recent files.
int add_bookmark (const char *directory, int where)
 Add a directory bookmark in some standard way.
charfreedesktop_thumbnail (const char *file, char which)
 Return the freedesktop thumbnail name corresponding to file.

Variables

const charlegalfilechars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+=-_.%/ "

Detailed Description

Namespace for various file utilities.

Contains functions to check file read/write ability, filename sanitizing, plus a couple of parsing routines to extend the standard getline() to skip comments and blank lines.

Also the Attribute class, which is kind of a much simplified xml sort of thing, such that data in files is arranged by indenting, rather than <tags>. It provides reading and writing facilities for such files.

Plus, there are a number of convenient conversion routines to convert char[]s to integers, longs, doubles, integer arrays, etc.


Function Documentation

int LaxFiles::add_bookmark ( const char directory,
int  where 
)

Add a directory bookmark in some standard way.

Currently, where is ignored. This will always default to adding the directory to ~/.gtk-bookmarks.

Return 0 for added. Return -1 for already there. Return 1 for directory was not a directory. Return other positive number for other error, not added.

References add_bookmark(), expand_home(), file_exists(), and file_to_uri().

Referenced by add_bookmark(), and Laxkit::FileDialog::newBookmark().

int LaxFiles::AttributeToCSSFile ( FILE *  f,
Attribute *  att,
int  indent 
)

Write out a specially formatted Attribute to a CSS file.

Return 0 for success, or nonzero error.

References AttributeToCSSFile(), and isblank().

Referenced by AttributeToCSSFile().

char * LaxFiles::AttributeToXML ( Attribute *  att,
char *&  appendtothis,
char **  error_ret 
)

Convert the attribute to a character array.

If appendtothis!=NULL, then append to it. Otherwise return a new char[].

Comments are derived from attributes with name "!--". A <?xml ... ?> tag is derived from an attribute with name ?xml. Any value is mapped to content. Subattributes are mapped to xml attributes of a tag with name as the element name. Further content sections, if any, are mapped from attributes named "content:".

Todo:
implement me!

References AttributeToXML().

Referenced by AttributeToXML().

int LaxFiles::AttributeToXMLFile ( FILE *  f,
Attribute *  att,
int  indent 
)

Warning: completely overwrites the file.

Returns 0 for success. Non-zero for error.

The attribute passed in must be particularly formatted. For each main tag, any subtag that is not named "content:" is written as an XML attribute of that tag, not as an element. Those must have only a name and value. Any sub-attributes they may have are ignored. There should be only one "content:" sub-attribute for a tag. This will contain all the elements in the tag. That "content:" sub-attribute might contain several "cdata:" elements, which are character data in between other tagged elements. "cdata:" attributes must have a value, but not have any subattributes.

Todo:

perhaps have a niceness parameter, so to lay out XML attributes inside a tag on separate lines: <blah first="1" second="2">

*** this needs a lot of work for escaped quoted stuff....

References AttributeToXMLFile(), Laxkit::PtrStack< T >::e, and Laxkit::PtrStack< T >::n.

Referenced by AttributeToXMLFile(), and touch_recently_used().

int LaxFiles::BooleanAttribute ( const char v)

Figure out if value is yes==true==1 or no==false==0. Return the boolean value.

If value==NULL or value=="" then assume true. This is usually what is wanted since it would be something like name="someflag" and no value means that the flag simply exists.

If v is "true" or "yes" (regarless of case), return 1. If "false" or "no", returns 0. Otherwise, If atol(v) returns nonzero, return 1, else 0.

References BooleanAttribute().

Referenced by BooleanAttribute(), and LaxInterfaces::GradientData::dump_in_atts().

int LaxFiles::ByteSizeAttribute ( const char s,
long *  ll,
char  towhat 
)

Convert strings like "24kb" and "3M" to a number.

"never" gets translated to INT_MAX. "34" becomes 34 kilobytes

Return 0 for success or nonzero for error in parsing. If there is an error, ll gets 0.

Really this is pretty simple check. Looks for "number order" where order is some text that begins with 'm' for megabytes, 'g' for gigabytes or 'k' for kilobytes

If towhat=='k' or 'K' returns in kilobytes, 'm' or 'M' megabytes, and 'g' or 'G' in gigabytes.

References ByteSizeAttribute(), newstr(), and stripws().

Referenced by ByteSizeAttribute().

int LaxFiles::check_dirs ( const char dirs,
char  make_too 
)

Check directory components for existence, and make them if (make_too).

If everything checks out, then -1 is returned.

Expects something like "aaaa/bbbbb/cccc/ddd". Each component must be a directory.

If make_too, this is like the command 'install -d 1/2/3', else return first dir (counting from 0) that isn't there. If making too, and a component exists already but is not a directory is encountered, then abruptly stop, and return the index of the problem component (counting from 0). Note that this may leave newly created directories lying around.

Todo:

*** on failure, should remove newly created directories... when doing that, should check that those new dirs are still empty?

*** always follows links, maybe should have some sanity check for that..

References file_exists(), and newstr().

char * LaxFiles::convert_to_full_path ( char *&  file,
const char path 
)

Basically convert 'blah' to '/full/path/to/blah', changing contents of file.

This changes what file points to.

If the file is not an absolute pathname, assumes that file is relative to the path, or if path==NULL, then the current directory. In other words, if file[0]!='/', then prepend the directory. In any case, then collapse any excess stuff like '/a/../b' which will become '/b'. Note that this does not check the file system for existence of the file after collapsing any ".." and ".".

Note that this does NOT currently expand "~/".

Returns whatever file points to now after conversion (after having deleted the old contents). A NULL file returns NULL.

References makestr(), newstr(), prependstr(), and simplify_path().

Referenced by full_path_for_file().

Attribute * LaxFiles::CSSFileToAttribute ( const char cssfile,
Attribute *  att 
)

Create a specially formatted Attribute with data from a CSS file.

Cascading style sheet files have this kind of syntax:

selector [, selector2, ...][:pseudo-class] {
property: value;
[property2: value2;
...]
}
\/\* comment *\/
Todo:
*** implement me!!

References CSSFileToAttribute().

Referenced by CSSFileToAttribute().

int LaxFiles::cut_comment ( char str,
const char cm,
char  quote 
)

Remove single line comments. Return number of characters removed.

Usually removes trailing whitespace. Does not remove whitespace at the front if there is non-whitespace stuff following. Thus if there is only whitespace followed by a comment, the comment is removed, but not the initial whitespace. Does not reallocate str, but it does change the contents of str. A comment starts with the first non escaped or quoted occurrence of cm, and continues until the end of the line. Escaped characters are preceded by a '\'. You can specify the quote and comment delimiter.

Any trailing whitespace after cutting out the comment is removed.

Todo:

*** this could go in strmanip

there appears to be a snag when using dos files, the '\r' does not appear to be recognized as whitespace by isspace()....

Referenced by getline_indent_nonblank().

int LaxFiles::DoubleListAttribute ( const char v,
double *  d,
int  maxn,
char **  endptr 
)

Turn v into a double[] of maximum size n. d must already exist. Returns number of items parsed.

Put in d[] if successful, return number of items parsed. Else don't change d's elements and return 0.

The numbers must be separated by whitespace or a comma.

References DoubleListAttribute().

Referenced by LaxInterfaces::Path::appendBezFromStr(), DoubleListAttribute(), LaxInterfaces::ImageData::dump_in_atts(), LaxInterfaces::ColorPatchData::dump_in_atts(), LaxInterfaces::CaptionData::dump_in_atts(), LaxInterfaces::SomeData::dump_in_atts(), FlatvectorAttribute(), SimpleColorAttribute(), LaxInterfaces::SvgToCoordinate(), and TransformAttribute().

int LaxFiles::DoubleListAttribute ( const char v,
double **  d,
int n_ret 
)

Turn v into a new double[], and put it in d. Put the number of values in n_ret.

Put in d if successful, return number of items parsed. Else don't change d and return 0. The numbers must be separated by whitespace.

The first part unparsable into an int breaks the reading. The rest of the string is ignored.

Returns the number of doubles successfully parsed. Please note that if there is an error, 0 is returned, but n_ret is not changed.

References DoubleListAttribute(), newstr(), and splitonspace().

void LaxFiles::dump_out_escaped ( FILE *  f,
const char str,
int  n 
)

Dump out n characters of string, escaping quote characters if necessary.

If n<0 then dump all characters of str.

If str==NULL, then nothing is written out.

If str has trailing or leading whitespace or it starts with a quote, or it contains a '#' character, then the whole string gets quoted. Otherwise, it is written as is.

So say str='  he said, "blah"', then what gets dumped is:
" he said, \"blah""

A final newline after str is never written.

Todo:

*** quote on escaped, quote on any ws, quote on initial or trailing ws, never quote, quote on escaped or ws, always quote

*** Currently assumes no newlines... could substitute '\n' for them...

References dump_out_escaped().

Referenced by LaxFiles::Attribute::dump_out(), dump_out_escaped(), LaxFiles::Attribute::dump_out_full(), dump_out_value(), and SubAttributesToXMLFile().

void LaxFiles::dump_out_indented ( FILE *  f,
int  indent,
const char str 
)

Just dump out string at constant indent.

If there are newlines it the string, they are inserted in the stream as newlines. Blank lines are written '.'. So, "abc\n\ndef\nghi" (with actual newlines) gets written as:

   abc
   .
   def
   ghi

It always writes out a final newline.

It is assumed that the file pointer points to the beginning of the line to output, so that first line will contain the indent then the first part of str.

See also Attribute::dump_in_indented().

References dump_out_indented().

Referenced by dump_out_indented(), and dump_out_value().

void LaxFiles::dump_out_value ( FILE *  f,
int  indent,
const char value,
int  noquotes 
)

Used to dump out the value part of an attribute.

This is assumed to already point to the spot in the file right after the name part, assumed to already have been written to file. If the value has no newlines, it is put on the same line, potentially with quotes escaped, and after writing out a space. If there are newlines, " \\\n" is output and value is written on subsequent lines at indent.

A newline is always the last thing written to the file. If value==NULL, a single newline is written to f.

Todo:
note that this will almost always quote value, and it probably shouldn't for simple values

References dump_out_escaped(), dump_out_indented(), and dump_out_value().

Referenced by LaxInterfaces::ImageData::dump_out(), LaxFiles::Attribute::dump_out(), LaxFiles::Attribute::dump_out_full(), and dump_out_value().

char * LaxFiles::expand_home_inplace ( char *&  file)

Replace an initial "~/" with the $HOME environment variable.

If file does not begin like that, then if modrig==0, then a new char[] copy of the original is returned. If modorig!=0, then return file without reallocating.

If expansion does occurs, file is delete[]'d and set to a new char[], and the new value of file is returned.

References newstr(), and prependstr().

Referenced by expand_home(), file_to_uri(), freedesktop_thumbnail(), Laxkit::FileDialog::fullFilePath(), and get_bookmarks().

int LaxFiles::file_exists ( const char filename,
int  followlink,
int error 
)

Return statbuf.st_mode&S_IFMT if exists. Else return 0.

This return value can be S_IFSOCK, S_IFREG, S_IFLNK, S_IFBLK, S_IFDIR, S_IFCHR, or S_IFIFO. These are defined in sys/stat.h, which also defines macros that you can use to check if it is various things: S_ISREG(file_exists("blah.png",1,NULL)), S_ISDIR(...), etc.

If stat fails on the file, then error is set to whatever errno was if error is non-null, and 0 is returned.

Referenced by add_bookmark(), check_dirs(), Laxkit::FileDialog::Event(), Laxkit::FileDialog::FileDialog(), get_bookmarks(), Laxkit::FileDialog::getDirectory(), Laxkit::ImageDialog::init(), Laxkit::LineEdit::Modified(), Laxkit::FileDialog::newBookmark(), Laxkit::PaletteWindow::PaletteDir(), Laxkit::FilePreviewer::Preview(), read_in_whole_file(), Laxkit::ImageDialog::RegeneratePreview(), and Laxkit::FileDialog::send().

long LaxFiles::file_size ( const char filename,
int  followlink,
int error 
)

Return the size in bytes of the file, or -1 for error.

This uses stat(), and error gets whatever stat sets errno to when it fails.

Referenced by read_in_whole_file().

char * LaxFiles::file_to_uri ( const char file)

For "~/blah", will return "file:///home/whoever/blah" for instance.

If file already begins "file://" then nothing further is done, and a copy of file is returned.

Relative pathnames such as "blah", "../blah", and "./blah" will cause NULL to be returned.

Returns a new char[].

References expand_home_inplace(), newstr(), and prependstr().

Referenced by add_bookmark(), and freedesktop_thumbnail().

int LaxFiles::FlatvectorAttribute ( const char v,
flatvector vec,
char **  endptr 
)

Return from something like "1 2", "1,2", "(1,2)", or "(1 2)".

Return 1 if successful, else 0.

References DoubleListAttribute(), and FlatvectorAttribute().

Referenced by LaxInterfaces::EngraverFillData::dump_in_atts(), and FlatvectorAttribute().

char * LaxFiles::freedesktop_thumbnail ( const char file,
char  which 
)

Return the freedesktop thumbnail name corresponding to file.

If which=='n' (default), then use the "normal" thumbnail, else use the "large" thumbnail.

Returns a new'd char[] with the path to the presumed preview. Does no existence check or actual thumbnail generation.

References expand_home_inplace(), file_to_uri(), freedesktop_thumbnail(), full_path_for_file(), and newstr().

Referenced by freedesktop_thumbnail().

char * LaxFiles::full_path_for_file ( const char file,
const char path 
)

Convert "blah" to "/full/path/to/blah". Works with (const char *), rather than (char *).

Creates a new string and returns convert_to_full_path(f,path).

References convert_to_full_path(), and newstr().

Referenced by LaxInterfaces::ImagePatchData::dump_in_atts(), LaxInterfaces::ImageData::dump_in_atts(), and freedesktop_thumbnail().

char * LaxFiles::get_bookmarks ( const char file,
const char filetype 
)

Read in file bookmarks.

filetype will be "gtk", "kde", "rox", "lax". If file==NULL and filetype==NULL, then each of the previous filetypes is used. If file!=NULL and filetype==NULL, then NULL is returned. Otherwise, a new char[] with the file or directories separated by a newline is returned.

If file==NULL, then read in the default locations for filetype, which are:

gtk: ~/.gtk-bookmarks
kde: ~/.kde/share/apps/konqueror/bookmarks.xml
rox: ~/.config/rox.sourceforge.net/ROX-Filer/Bookmarks.xml
lax: (no default file at this time)
possibly fd desktop bookmark spec says folder bookmarks in ~/.shortcuts.xbel

Todo:
need to lock files on opening

References appendstr(), expand_home_inplace(), file_exists(), get_bookmarks(), isblank(), and newstr().

Referenced by Laxkit::FileDialog::BuildBookmarks(), and get_bookmarks().

int LaxFiles::getline_indent_nonblank ( char **  line,
size_t *  n,
FILE *  f,
int  indent,
const char comment,
char  quote,
char  skiplines,
int lineindent 
)

Read the line if indented>=indent, skipping blank lines and comments.

comment is comment marker. It might be "#" or "//", etc. Any trailing whitespace is ignored.

If line is not indented enough, then reset file position to the start of the non-blank line. If there is only ws and comments following, then the file marker is advanced to eof.

If line!=NULL, then it is assumed to have been malloc'd, not new'd.

If lineindent!=NULL, then return how indented the current line actually is.

Returns the number of character bytes in the current line.

References cut_comment(), and how_indented().

Referenced by LaxFiles::Attribute::dump_in(), LaxFiles::Attribute::dump_in_indented(), and skip_to_next_attribute().

int LaxFiles::HexColorAttributeRGB ( const char v,
Laxkit::ScreenColor color,
char **  endptr 
)

Read in an rgb value such as "af3" or "ff00ff".

Return 1 if successful, or 0 if unable to parse.

References HexColorAttributeRGB().

Referenced by HexColorAttributeRGB().

int LaxFiles::HexColorAttributeRGB ( const char v,
unsigned long *  l,
char **  endptr 
)

Read in an rgb value such as "af3" or "ff00ff".

Return 1 if successful, or 0 if unable to parse.

References HexColorAttributeRGB().

int LaxFiles::how_indented ( char str,
char **  strt 
)

Return the number of whitespace characters at the beginning of str.

! Skip lines filled with space, tab, and comments. Assumes already positioned at beginning of line. !

If strt!=NULL, then make strt point to the first non-whitespace character.

Referenced by LaxFiles::Attribute::dump_in_indented(), LaxFiles::Attribute::dump_in_until(), and getline_indent_nonblank().

int LaxFiles::IntAttribute ( const char v,
int i,
char **  endptr 
)
int LaxFiles::IntListAttribute ( const char v,
int i,
int  maxn,
char **  endptr 
)

Turn v into an int[] of maximum size n. Return the number of integers parsed.

Put in d[] if successful, return number of items parsed. Else don't change d's elements and return 0. The numbers must be separated by whitespace.

References IntListAttribute().

Referenced by Laxkit::Palette::dump_in(), LaxInterfaces::GradientDataSpot::dump_in_atts(), LaxInterfaces::FillStyle::dump_in_atts(), LaxInterfaces::LineStyle::dump_in_atts(), Laxkit::Palette::dump_in_atts(), IntListAttribute(), and SimpleColorAttribute().

int LaxFiles::IntListAttribute ( const char v,
int **  i,
int n_ret,
char **  endptr 
)

Turn v into a new int[], and put it in i. Put the number of values in n_ret.

Put in i if successful, return number of items parsed. Else point i to NULL and return 0. The numbers must be separated by whitespace.

The first part unparsable into an int breaks the reading. The rest of the string is ignored.

Returns the number of ints successfully parsed. This is the same number put in n_ret, if n_ret!=NULL.

Todo:
*** need to do some testing on this

References IntListAttribute().

int LaxFiles::is_good_filename ( const char filename)

Basic filename sanitizer checker. sanitize_filename() does actual sanitizing.

Allows [a-zA-Z0-9+=-_.%/ ].

Todo:
this could be broken down into is_good_path() and is_good_basename();
int LaxFiles::lax_stat ( const char file,
int  followlink,
struct stat *  buf 
)

Wrapper around stat().

Return 0 for success, or whatever stat sets errno to when it fails.

int LaxFiles::LongAttribute ( const char v,
long *  l,
char **  endptr 
)

Turn v into a long, put in l if successful.

Return 1 if successful. Else don't change l and return 0. endptr will point to either the first invalid char, or to v.

References LongAttribute().

Referenced by Laxkit::Scroller::dump_in_atts(), LaxInterfaces::PathsData::dump_in_atts(), and LongAttribute().

char * LaxFiles::make_filename_base ( const char f)

Turns "blah###.eps" into "blah%03d.eps".

Any '' chars that existed already are turned into "%%".

Also "blah.eps" into "blah%d.eps", "blah" into "blah%d", "blah/blah###.eps" to "blah/blah%03d.eps" and NULL into "%d".

Returns a new'd char[].

Todo:
have something like "blah##-##.ext" -> "blah%02d-%02d.ext" and maybe "blah##\###" -> "blah%02d%03d"? pass in option to say how many fields there should be, and how many there ended up being

References newstr().

int LaxFiles::NameValueAttribute ( const char str,
char **  name,
char **  value,
char **  end_ptr,
char  assign,
char  delim,
const char stopat 
)

Extract a single "name=value" string. The value can be quoted.

On error or no name value found, end_ptr gets set to str, and nonzero is returned. name and value are not modified in this case. Otherwise, 0 is returned and name and value are set.

So if str=="a=5 b=10 c=2", then returned values are name="5", value="10", and end_ptr is "b=10 c=2" (without the whitespace before b). The value here is parsed from the '=' until whitespace.

If you have something like a="1 2 3" with the quotes in str itself, then name="a" and value is "1 2 3" without the quotes.

assign is the single character delimiter, default is '='. In CSS for instance, it might be ':'.

stopat is a '\0' terminated list of characters, any of which will terminate the parsing if unquoted. So, you can properly parse an xml tag ".... color=red/>" or "... color=red>".

delim is an optional end of line marker, such as ';', which is ignored.

end_ptr will be set to the character just after what's been parsed. If delim is encountered, end_ptr will point to the following character.

References NameValueAttribute(), newnstr(), and QuotedAttribute().

Referenced by NameValueAttribute(), NameValueToAttribute(), and XMLChunkToAttribute().

Attribute * LaxFiles::NameValueToAttribute ( Attribute *  att,
const char str,
char  assign,
char  delim 
)

Transform something like "name=value name2=value2" into an Attribute.

If att!=NULL, then append subattributes to it and also return att. Otherwise, return a new Attribute.

References NameValueAttribute(), NameValueToAttribute(), and LaxFiles::Attribute::push().

Referenced by NameValueToAttribute().

char * LaxFiles::QuotedAttribute ( const char v,
char **  endptr 
)

Grab the first chunk of str, return as new char[].

For instance, a string: ' "1\"2"3" "4" 5 ' would return s='1"2"3', and endptr would point to the quote character before the 4. If there are no initial quotes, then the first whitespace delimited chunk is returned.

If there are quotes, then '\n' becomes a newline and '\t' becomes a tab, '\' becomes a backslash, and '"' becomes one doublequote. In fact any other character following the backslash just inserts that character.

On error or no first chunk, NULL is returned.

Please note that it is assumed that there is no trailing comment in v. That is, there is no final chunk of text beginning with a '#' character.

Todo:

****** on error, what happens to endptr?

**** all of v is copied right at the beginning, wasting much memory, should just crawl along v, copying chars to a smaller buf, reallocating that if necessary?

References QuotedAttribute().

Referenced by Laxkit::Tagged::InsertTags(), NameValueAttribute(), and QuotedAttribute().

char * LaxFiles::read_in_whole_file ( const char file,
int chars_ret,
int  maxchars 
)

Return a new, null terminated char[] containing the contents of file, or NULL on error.

If chars_ret!=NULL, then return the number of characters actually read, (not including the final '\0'.

Please note that there is no binary checking done, so the array may contain '\0' characters not at the end.

If maxchars>0, then read at most this many characters.

References file_exists(), file_size(), and isblank().

int LaxFiles::readable_file ( const char filename,
FILE **  ff 
)

Return if filename is a regular readable file.

This attempts to open the file for reading to see if it is readable. If ff==NULL, then close the file. Otherwise return the opened file in ff.

Todo:

does not currently check sanity of file when opening.

add a return error string

char * LaxFiles::recently_used ( const char mimetype,
const char group,
int  includewhat 
)

Return a newline separated list of recent files.

If mimetype!=NULL, then return only items of that type. If group!=NULL, then return items in only that group. If there are private items in the raw list, then return them only if its group matches the group you are looking for.

If includewhat==0, then only return the file name. If it is 1, then each line contains the mime type and file, separated by a tab. If it is 2, then each line is timestamp, then file. If it is 3, then each line is mime-tab-timestamp-tab-file.

By default, this reads in from ~/.recently-used. See the Recently Used Specification at Freedesktop.org: http://www.freedesktop.org/wiki/Specifications/recent-file-spec

Please note that many programs are not using this spec, but are instead using the Freedesktop bookmark spec: http://www.freedesktop.org/wiki/Specifications/desktop-bookmark-spec, which puts info into ~/.recently-used.xbel instead. Apparently, this one will supercede the Recently Used spec.

If you choose to read from ~/.recently-used, then it expects that file to return at Attribute structured basically like this: *

  ?xml
    version "1.0"
  RecentFiles
    content:
      RecentItem
        content:
          URI "file:///blah/blah"
          Mime-Type "text/plain"
          Timestamp "1192504650"
          Groups
            content:
              Group "gedit"
      RecentItem
        content:
          URI "file:///blah/blah2"
          Mime-Type "image/jpeg"
          Timestamp "1192420896"
          Groups
            content:
              Group "gimp"
 

If you instead to read from ~/.recently-used.xbel, then an attribute of the following form is expected.

  ?xml
    version "1.0"
    encoding "UTF-8"
  xbel
    version "1.0"
    xmlns:bookmark "http://www.freedesktop.org/standards/desktop-bookmarks"
    xmlns:mime "http://www.freedesktop.org/standards/shared-mime-info"
    content:
      bookmark
        href "file:///home/tom/images/strobist/pdxstrobist/2010-01-10-BlueMonk/arms/arms.xcf"
        added "2010-01-22T14:35:40Z"
        modified "2010-02-21T05:35:45Z"
        visited "2010-01-22T14:35:40Z"
        content:
          info
            content:
              metadata
                owner "http://freedesktop.org"
                content:
                  mime:mime-type
                    type "image/xcf"
                  bookmark:groups
                    content:
                      bookmark:group "Graphics"
                  bookmark:applications
                    content:
                      bookmark:application
                        name "GNU Image Manipulation Program"
                        exec "&apos;gimp-2.6 %u&apos;"
                        modified "2010-02-21T05:35:45Z"
                        count "32"
 
Todo:

support the other commonly used recent file: ~/.recently-used.xbel

not a whole lot of error checking in here yet.

References appendstr(), Laxkit::PtrStack< T >::e, LaxFiles::Attribute::find(), Laxkit::PtrStack< T >::n, recently_used(), and recently_used_att().

Referenced by Laxkit::FileDialog::init(), and recently_used().

Attribute * LaxFiles::recently_used_att ( const char file)

Return an Attribute created from XML.

Default is to read from ~/.recently-used. See the Recently Used Specification at Freedesktop.org: http://www.freedesktop.org/wiki/Specifications/recent-file-spec

This locks the file, reads it in to an Attribute with XMLChunkToAttribute(), then unlocks the file.

Please note that many programs are not using ~/.recently-used, but are instead using ~/.recently-used.xbel.

References expand_home(), isblank(), recently_used_att(), and XMLChunkToAttribute().

Referenced by recently_used(), recently_used_att(), and touch_recently_used().

char * LaxFiles::relative_file ( const char file,
const char relativeto,
char  isdir 
)

Return a new char[] containing the path to file, relative to relativeto.

Both file and relativeto must be absolute paths.

Say file="/home/blah/2/3.jpg" and relativeto="/home/blah/bleah/ack", then the string returned is "../2/3.jpg" if isdir==0, and "../../2/3.jpg" if isdir!=0. This does not actually consult the filesystem, so relativeto and file need not currently exist to get a relative path. Plus, this means that "~/" is not expanded.

References newstr().

Referenced by LaxInterfaces::ImagePatchData::dump_out(), and LaxInterfaces::ImageData::dump_out().

char* LaxFiles::removeescapes ( char *&  str)

Remove backslashes. Double backslash becomes single backslash.

Note this does not substite characters. Thus "\\t" converts to 't'.

References removeescapes().

Referenced by LaxFiles::Attribute::dump_in(), and removeescapes().

char * LaxFiles::sanitize_filename ( char filename,
int  makedup 
)

Strip out characters not in: [a-zA-Z0-9+=-_.% ].

If the filename is nothing but illegal characters, then return NULL.

References newstr().

int LaxFiles::SimpleColorAttribute ( const char v,
unsigned long *  color_ret 
)

Find an ARGB color packed into an unsigned long.

A, R, G, B are found from color_ret by masking with respectively 0xff000000, 0xff0000, 0xff00, and 0xff.

The value can be something like "black", "white", "red", "green", "blue", "yellow", "orange", "purple".

Also, it can be something like any of the following:

  rgba16(65535,65535,65535,65535)
  rgb(255,255,255)
  rgbf(1.0, .5, .5)
  gray(.5)
  cmyk(.8, .9, .1, .2)
  255 255 255 255     #<– simple list like this is assumed to be 8 bit rgba.
 

These forms follow a pattern. They have to start with rgb, rgba, gray, graya, cmyk, cmyka, ignoring case. The gray ones will return an rgb with each color field equal to the gray value. The cmyk will be converted to rgb with a simple reciprocal function (not ICC based).

Following the letters should be "f" or a number for the bit depth. If missing, 8 bit is assumed. "f" means use floating point values in range [0..1]. 8 means values are [0..255]. 16 means values are [0..65535]. If there are '.' characters anywhere in the string, then it assumed floating point values are used, and 'f' is not necessary.

Returns 0 for successful parsing, and color is returned in color_ret. Returns 1 for unsuccessful for failure, and color_ret not changed.

References DoubleListAttribute(), IntListAttribute(), Laxkit::simple_cmyk_to_rgb(), and SimpleColorAttribute().

Referenced by LaxInterfaces::EngraverFillData::dump_in_atts(), Laxkit::anXApp::dump_in_colors(), and SimpleColorAttribute().

char * LaxFiles::simplify_path ( char origfile,
int  modorig 
)

Collapses any excess stuff like '/a/../b' which becomes '/b'.

Returns a new'd char[] if modorig==0. Otherwise, the content of origfile is modified to be the simplified path (which is always smaller or of equal length as the original), and origfile is returned. Also in this case, note that origfile is not reallocated, the string is merely takes up less of the space allocated to origfile.

Uses the standard that "/../" (one up from root dir) is the same as "/" (root dir itself).

Also makes '//' be '/' and '/./x' is '/x'.

This does not consult the file system, so if you have some convoluted path with a billion symbolic links, then you're on your own. Also please note that "~/" is NOT expanded here. Use expand_home() for that.

Returns the new path os success or NULL for invalid path.

  "../a/../"  ->  "../"
  "a/../"     ->  "."
  "//////"    ->  "/"
  "a/b/.."    ->  "a/"
  ""          ->  "." (if !modorig)
  ""          ->  ""  (if  modorig)
  "~/../a"    ->  "a" (WARNING! Does not expand '~')
 

References newstr().

Referenced by convert_to_full_path(), Laxkit::FileDialog::Event(), and Laxkit::FileDialog::fullFilePath().

void LaxFiles::skip_to_next_attribute ( FILE *  f,
int  indent 
)

Skip until the first nonblank, non-comment line that has indentation less or equal to indent.

If that is the current line, then don't move.

References getline_indent_nonblank(), and skip_to_next_attribute().

Referenced by skip_to_next_attribute().

int LaxFiles::SubAttributesToXMLFile ( FILE *  f,
Attribute *  att,
int  indent 
)

Output any Attribute to some generic XML.

Normal attributes make no distinction between elements and attributes. They are all subattributes. This function does nothing special for "!--" or "?thing" attributes.

The xml output will be a set of nested elements. If there are no subattributes and no value, then the output is "<tag/>". If there are no subattributes and a non-null value, then it'll be "<tag>value</tag>". If there are subattributes and a non-null value, then the tag will be: "<tag value=\""whatever the value was\"> ...(subattributes)...</tag>". If thera are subattributes, but no value, it will be the same, only without the value attribute of tag.

To output data inputted from XMLFileToAttribute(), you should use AttributeToXMLFile().

References dump_out_escaped(), Laxkit::PtrStack< T >::e, Laxkit::PtrStack< T >::n, and SubAttributesToXMLFile().

Referenced by SubAttributesToXMLFile().

int LaxFiles::touch_recently_used ( const char file,
const char mime,
const char group,
const char timestamp 
)

If timestamp==NULL, then use the current time. Otherwise it must be a string representing the number of seconds since the epoch, which is the beginning of Jan 1, 1970 UTC. time gettimeofday

file must be an absolute path.

Todo:

there could be more error checking in here. If recent file spec changes, could well break this.

support the other commonly used recent file: ~/.recently-used.xbel

References AttributeToXMLFile(), Laxkit::PtrStack< T >::e, expand_home(), LaxFiles::Attribute::find(), makestr(), Laxkit::PtrStack< T >::n, newstr(), prependstr(), LaxFiles::Attribute::push(), recently_used_att(), Laxkit::PtrStack< T >::remove(), and touch_recently_used().

Referenced by touch_recently_used().

double * LaxFiles::TransformAttribute ( const char v,
double *  m,
char **  endptr 
)

Return a double[6] transform derived from v.

If m!=NULL, then put the result there. Otherwise, return a new double[6].

The transform can be a simple list of 6 real numbers or an SVG style transform. In the first case, less than 6 numbers will return NULL. Parsing stops after those 6 numbers.

The SVG style transform is composed of a list of chunks of: "translate(3 5)", "scale(3,2)", "rotate(3.1415, 5,6)", "matrix(1 0 0 1 0 0)", "skewX(4)", "skewy(4)". The numbers inside the parentheses can be separated by whitespace or by a comma, and for translate, rotate, and scale, all the numbers after the 1st are optional. Parsing will stop at the first chunk not recognized as a further transform element.

If there is an error, NULL is returned, else m is returned. If m is NULL, then a new double[6] is returned.

Todo:
*** implement me!

References DoubleListAttribute(), Laxkit::transform_copy(), Laxkit::transform_identity(), Laxkit::transform_mult(), Laxkit::transform_set(), and TransformAttribute().

Referenced by TransformAttribute().

char * LaxFiles::WholeQuotedAttribute ( const char v)

Like QuotedAttribute(), but assumes that the whole thing is meant as only one chunk.

Leading and trailing whitespace is stripped.

QuotedAttribute() will decompose something like '"1" "2"' into '1' and the rest is '"2"', but this will return the whole '"1" "2"', without stripping the quotes. But, if you only have '"1 2"', then the quotes are stripped, and '1 2' is returned.

Please note that it is assumed that there is no trailing comment in v. That is, there is no final chunk of text beginning with a '#' character.

References newnstr(), and WholeQuotedAttribute().

Referenced by WholeQuotedAttribute().

Attribute * LaxFiles::XMLChunkToAttribute ( Attribute *  att,
FILE *  f,
const char **  stand_alone_tag_list 
)

Read in a part of an XML stream.

This assumes that the next thing in f is an xml tag beginning with a less than sign. This function parses in everything until the close of the tag. It is a very simplistic conversion. If you need more, you should probably use the actual libxml.

If att==NULL, then return a new Attribute. Otherwise, append the new things to att.

stand_alone_tag_list is a list of element names that are self contained, that is, they have no closing tag, and do not explicitly end in /<.

See XMLChunkToAttribute(Attribute*,const char *,long,long*,const char *,const char **) for details about the conversion.

Todo:

this just reads in the whole file to memory then parses it, which might be rather inefficient, but it is easy to code..

must interpret !DOCTYPE and ?xml...? correctly...

References XMLChunkToAttribute().

Referenced by recently_used_att(), XMLChunkToAttribute(), and XMLFileToAttribute().

Attribute * LaxFiles::XMLChunkToAttribute ( Attribute *  att,
const char buf,
long  n,
long *  C,
const char until,
const char **  stand_alone_tag_list 
)

Read in XML to an Attribute from a memory buffer.

Say you have something like this Passepartout file:

 *   <?xml version="1.0"?>
 *   <!-- this is a comment -->
 *   <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 *   <document paper_name="Letter" doublesided="true" landscape="false" first_page_num="1">
 *    <title>single thing to value</title>
 *    <page>
 *        <frame name="Raster beetile-501x538.jpg" 
 *               matrix="0.812233 0 0 0.884649 98.6048 243.107" 
 *               lock="false"
 *               flowaround="false"
 *               obstaclemargin="
 *               0" type="raster" file="beetile-501x538.jpg"/>
 *     </page>
 *     <extra thing="2">text<b>bold</b>more text</extra>
 *   </document>
 * 

The Attribute that is created will look something like this:

   ?xml
     version 1.0
   !– "this is a comment"
   !DOCTYPE
     svg
     PUBLIC
     "-//W3C//DTD SVG 1.1//EN"
     "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"
   document
     paper_name Letter
     doublesided true
     landscape false
     first_page_num 1
     content:
       title "single thing to value"  <—TODO!!!
       page
         content:
           frame 
             name Raster beetile-501x538.jpg
             matrix 0.812233 0 0 0.884649 98.6048 243.107
             lock false
             flowaround false
             obstaclemargin 0
             type raster
             file beetile-501x538.jpg 
       extra
         thing 2
         content:
           cdata: text
           b bold
           cdata: more text
 

You'll notice that the 'content:' field of the Attribute contains the XML elements that are not xml attributes in the opening <...> tag.

Todo:

UNLESS there are only non-tagged characters between the tags. In that case, the text becomes the value of the given tag.

WARNING!! something like in html where img, br, hr, etc do not have closing tags are not dealt with properly... need to flesh out stand_alone_tag_list

this should be thoroughly gone over by someone who actually knows something about XML in current state is rather sloppy, and is just barely enough to be useful in most cases I've dealt with recently...

Something like:

 *  111 <b>22 2 2</b> 333
 * 

Will become:

   cdata: 111
   b
     cdata: 22 2 2  #TODO<–test this
   cdata: 333
 
Todo:
should have case sensitive switch
Parameters:
nBuffer with the xml
CLength of buf
untilCurrent position in buf which gets updated

References Laxkit::PtrStack< T >::e, Laxkit::PtrStack< T >::flush(), makenstr(), makestr(), Laxkit::PtrStack< T >::n, NameValueAttribute(), newnstr(), one_of_them(), LaxFiles::Attribute::push(), skipws(), and XMLChunkToAttribute().

Attribute * LaxFiles::XMLFileToAttribute ( Attribute *  att,
const char file,
const char **  stand_alone_tag_list 
)

Read in an XML file, and rather simply make an Attribute out of it.

This merely opens the file and returns XMLChunkToAttribute(NULL,f,stand_alone_tag_list).

Puts in att if att!=NULL, otherwist returns a new Attribute. See XMLChunkToAttribute(Attribute*,const char *,long,long*,const char *,const char **) for details about the conversion.

Todo:
WARNING!! something like in html where img, br, hr, etc do not have closing tags are not dealt with properly... need to implement stand_alone_tag_list.. it would be really clever to be able to figure out that list from a dtd..

References XMLChunkToAttribute(), and XMLFileToAttribute().

Referenced by XMLFileToAttribute().


Mon Feb 17 2014 11:52:58, Laxkit