diff options
Diffstat (limited to 'riscos/gui.c')
-rw-r--r-- | riscos/gui.c | 188 |
1 files changed, 143 insertions, 45 deletions
diff --git a/riscos/gui.c b/riscos/gui.c index db57ff68a..6447e4d90 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -67,6 +67,7 @@ #include "desktop/save_complete.h" #include "desktop/treeview.h" #include "render/font.h" +#include "utils/file.h" #include "riscos/content-handlers/artworks.h" #include "riscos/bitmap.h" @@ -2285,77 +2286,173 @@ void PDF_Password(char **owner_pass, char **user_pass, char *path) *owner_pass = NULL; } + +#define DIR_SEP ('.') + /** - * Return the filename part of a full path + * Generate a riscos path from one or more component elemnts. + * + * Constructs a complete path element from passed components. The + * second (and subsequent) components have a slash substituted for all + * riscos directory separators. * - * \param path full path and filename - * \return filename (will be freed with free()) + * If a string is allocated it must be freed by the caller. + * + * @param[in,out] str pointer to string pointer if this is NULL enough + * storage will be allocated for the complete path. + * @param[in,out] size The size of the space available if \a str not + * NULL on input and if not NULL set to the total + * output length on output. + * @param[in] nemb The number of elements. + * @param[in] ap The elements of the path as string pointers. + * @return NSERROR_OK and the complete path is written to str + * or error code on faliure. */ - -static char *filename_from_path(char *path) +static nserror riscos_mkpath(char **str, size_t *size, size_t nelm, va_list ap) { - char *leafname; - char *temp; - int leaflen; + const char *elm[16]; + size_t elm_len[16]; + size_t elm_idx; + char *fname; + size_t fname_len = 0; + char *curp; + size_t idx; + + /* check the parameters are all sensible */ + if ((nelm == 0) || (nelm > 16)) { + return NSERROR_BAD_PARAMETER; + } + if ((*str != NULL) && (size == NULL)) { + /* if the caller is providing the buffer they must say + * how much space is available. + */ + return NSERROR_BAD_PARAMETER; + } - temp = strrchr(path, '.'); - if (!temp) - temp = path; /* already leafname */ - else - temp += 1; + /* calculate how much storage we need for the complete path + * with all the elements. + */ + for (elm_idx = 0; elm_idx < nelm; elm_idx++) { + elm[elm_idx] = va_arg(ap, const char *); + elm_len[elm_idx] = strlen(elm[elm_idx]); + fname_len += elm_len[elm_idx]; + } + fname_len += nelm; /* allow for separators and terminator */ + + /* ensure there is enough space */ + fname = *str; + if (fname != NULL) { + if (fname_len > *size) { + return NSERROR_NOSPACE; + } + } else { + fname = malloc(fname_len); + if (fname == NULL) { + return NSERROR_NOMEM; + } + } - leaflen = strlen(temp); + /* copy the elements in with directory separator */ + curp = fname; - leafname = malloc(leaflen + 1); - if (!leafname) { - LOG(("malloc failed")); - return NULL; + /* first element is not altered */ + memmove(curp, elm[elm_idx], elm_len[elm_idx]); + curp += elm_len[elm_idx]; + /* ensure there is a delimiter */ + if (curp[-1] != DIR_SEP) { + *curp = DIR_SEP; + curp++; } - memcpy(leafname, temp, leaflen + 1); - /* and s/\//\./g */ - for (temp = leafname; *temp; temp++) - if (*temp == '/') - *temp = '.'; + /* subsequent elemnts have slashes substituted with directory + * separators. + */ + for (elm_idx = 1; elm_idx < nelm; elm_idx++) { + for (idx = 0; idx < elm_len[elm_idx]; idx++) { + if (elm[elm_idx][idx] == DIR_SEP) { + *curp = '/'; + } else { + *curp = elm[elm_idx][idx]; + } + curp++; + } + *curp = DIR_SEP; + curp++; + } + curp[-1] = 0; /* NULL terminate */ + + assert((curp - fname) <= (int)fname_len); + + *str = fname; + if (size != NULL) { + *size = fname_len; + } + + return NSERROR_OK; - return leafname; } + /** - * Add a path component/filename to an existing path + * Get the basename of a file using posix path handling. + * + * This gets the last element of a path and returns it. The returned + * element has all forward slashes translated into riscos directory + * separators. * - * \param path buffer containing platform-native format path + free space - * \param length length of buffer "path" - * \param newpart string containing unix-format path component to add to path - * \return true on success + * @param[in] path The path to extract the name from. + * @param[in,out] str Pointer to string pointer if this is NULL enough + * storage will be allocated for the path element. + * @param[in,out] size The size of the space available if \a + * str not NULL on input and set to the total + * output length on output. + * @return NSERROR_OK and the complete path is written to str + * or error code on faliure. */ - -static bool path_add_part(char *path, int length, const char *newpart) +static nserror riscos_basename(const char *path, char **str, size_t *size) { - size_t path_len = strlen(path); + const char *leafname; + char *fname; + char *temp; - /* Append directory separator, if there isn't one */ - if (path[path_len - 1] != '.') { - strncat(path, ".", length); - path_len += 1; + if (path == NULL) { + return NSERROR_BAD_PARAMETER; } - strncat(path, newpart, length); + leafname = strrchr(path, DIR_SEP); + if (!leafname) { + leafname = path; + } else { + leafname += 1; + } - /* Newpart is either a directory name, or a file leafname - * Either way, we must replace all dots with forward slashes */ - for (path = path + path_len; *path; path++) { - if (*path == '.') - *path = '/'; + fname = strdup(leafname); + if (fname == NULL) { + return NSERROR_NOMEM; } - return true; + /** @todo check this leafname translation is actually required */ + /* and s/\//\./g */ + for (temp = fname; *temp != 0; temp++) { + if (*temp == '/') { + *temp = DIR_SEP; + } + } + + *str = fname; + if (size != NULL) { + *size = strlen(fname); + } + return NSERROR_OK; } +static struct gui_file_table riscos_file_table = { + .mkpath = riscos_mkpath, + .basename = riscos_basename, +}; + static struct gui_fetch_table riscos_fetch_table = { - .filename_from_path = filename_from_path, - .path_add_part = path_add_part, .filetype = fetch_filetype, .path_to_url = path_to_url, .url_to_path = url_to_path, @@ -2392,6 +2489,7 @@ int main(int argc, char** argv) .clipboard = riscos_clipboard_table, .download = riscos_download_table, .fetch = &riscos_fetch_table, + .file = &riscos_file_table, .utf8 = riscos_utf8_table, .search = riscos_search_table, }; |