Laxkit
0.0.7.1
|
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. | |
char * | QuotedAttribute (const char *v, char **endptr) |
Grab the first chunk of str, return as new char[]. | |
char * | WholeQuotedAttribute (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. | |
char * | removeescapes (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. | |
Attribute * | NameValueToAttribute (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. | |
char * | AttributeToXML (Attribute *att, char *&appendtothis, char **error_ret) |
Convert the attribute to a character array. | |
Attribute * | 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. | |
Attribute * | XMLChunkToAttribute (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. | |
Attribute * | 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. | |
int | AttributeToCSSFile (FILE *f, Attribute *att, int indent) |
Write out a specially formatted Attribute to a CSS file. | |
char * | AttributeToCSS (Attribute *att, char **appendtothis, char **error_ret) |
Attribute * | CSSFileToAttribute (const char *cssfile, Attribute *att) |
Create a specially formatted Attribute with data from a CSS file. | |
Attribute * | CSSToAttribute (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). | |
char * | sanitize_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. | |
char * | simplify_path (char *origfile, int modorig) |
Collapses any excess stuff like '/a/../b' which becomes '/b'. | |
char * | file_to_uri (const char *file) |
For "~/blah", will return "file:///home/whoever/blah" for instance. | |
char * | expand_home (const char *file) |
Return a new char[] with the expansion performed. | |
char * | expand_home_inplace (char *&file) |
Replace an initial "~/" with the $HOME environment variable. | |
char * | full_path_for_file (const char *file, const char *path) |
Convert "blah" to "/full/path/to/blah". Works with (const char *), rather than (char *). | |
char * | convert_to_full_path (char *&file, const char *path) |
Basically convert 'blah' to '/full/path/to/blah', changing contents of file. | |
char * | relative_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. | |
char * | make_filename_base (const char *f) |
Turns "blah###.eps" into "blah%03d.eps". | |
char * | 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. | |
char * | get_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) |
Attribute * | recently_used_att (const char *file) |
Return an Attribute created from XML. | |
char * | recently_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. | |
char * | freedesktop_thumbnail (const char *file, char which) |
Return the freedesktop thumbnail name corresponding to file. |
Variables | |
const char * | legalfilechars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+=-_.%/ " |
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.
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().
Write out a specially formatted Attribute to a CSS file.
Return 0 for success, or nonzero error.
References AttributeToCSSFile(), and isblank().
Referenced by AttributeToCSSFile().
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:".
References AttributeToXML().
Referenced by AttributeToXML().
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.
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().
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().
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().
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.
*** 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().
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().
Create a specially formatted Attribute with data from a CSS file.
Cascading style sheet files have this kind of syntax:
References CSSFileToAttribute().
Referenced by CSSFileToAttribute().
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.
*** 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().
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().
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().
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.
*** 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().
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().
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.
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().
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().
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().
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().
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().
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().
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().
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
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().
Read in an rgb value such as "af3" or "ff00ff".
Return 1 if successful, or 0 if unable to parse.
References HexColorAttributeRGB().
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().
Turn v into an int, put in i if successful, return 1. Else don't change i and return 0.
References IntAttribute().
Referenced by Laxkit::Palette::dump_in(), LaxInterfaces::FillStyle::dump_in_atts(), LaxInterfaces::ImagePatchData::dump_in_atts(), LaxInterfaces::ColorPatchData::dump_in_atts(), LaxInterfaces::LineStyle::dump_in_atts(), Laxkit::Palette::dump_in_atts(), LaxInterfaces::PointWarpData::dump_in_atts(), LaxInterfaces::SomeData::dump_in_atts(), Laxkit::RulerWindow::dump_in_atts(), LaxInterfaces::PatchData::dump_in_atts(), Laxkit::anXWindow::dump_in_atts(), Laxkit::anXApp::dump_in_rc(), and IntAttribute().
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().
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.
References IntListAttribute().
Basic filename sanitizer checker. sanitize_filename() does actual sanitizing.
Allows [a-zA-Z0-9+=-_.%/ ]
.
Wrapper around stat().
Return 0 for success, or whatever stat sets errno to when it fails.
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().
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[].
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().
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.
****** 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().
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().
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.
does not currently check sanity of file when opening.
add a return error string
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 "'gimp-2.6 %u'" modified "2010-02-21T05:35:45Z" count "32"
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().
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().
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().
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().
Strip out characters not in: [a-zA-Z0-9+=-_.% ]
.
If the filename is nothing but illegal characters, then return NULL.
References newstr().
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().
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().
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.
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().
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.
References DoubleListAttribute(), Laxkit::transform_copy(), Laxkit::transform_identity(), Laxkit::transform_mult(), Laxkit::transform_set(), and TransformAttribute().
Referenced by TransformAttribute().
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.
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.
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
n | Buffer with the xml |
C | Length of buf |
until | Current 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.
References XMLChunkToAttribute(), and XMLFileToAttribute().
Referenced by XMLFileToAttribute().