diff --git a/lib/mu-script.cc b/lib/mu-script.cc index aa35db9c..02e3830f 100644 --- a/lib/mu-script.cc +++ b/lib/mu-script.cc @@ -34,7 +34,6 @@ #include #include -#include "utils/mu-str.h" #include "mu-script.hh" #include "utils/mu-util.h" @@ -116,9 +115,9 @@ mu_script_info_matches_regex(MuScriptInfo* msi, const char* rxstr, GError** err) g_return_val_if_fail(rxstr, FALSE); rx = g_regex_new(rxstr, - (GRegexCompileFlags)(G_REGEX_CASELESS | G_REGEX_OPTIMIZE), - (GRegexMatchFlags)0, - err); + (GRegexCompileFlags)(G_REGEX_CASELESS | G_REGEX_OPTIMIZE), + (GRegexMatchFlags)0, + err); if (!rx) return FALSE; @@ -148,8 +147,8 @@ open_channel(const char* path) io_chan = g_io_channel_new_file(path, "r", &err); if (!io_chan) { g_warning("failed to open '%s': %s", - path, - err ? err->message : "something went wrong"); + path, + err ? err->message : "something went wrong"); g_clear_error(&err); return NULL; } @@ -167,7 +166,7 @@ end_channel(GIOChannel* io_chan) status = g_io_channel_shutdown(io_chan, FALSE, &err); if (status != G_IO_STATUS_NORMAL) { g_warning("failed to shutdown io-channel: %s", - err ? err->message : "something went wrong"); + err ? err->message : "something went wrong"); g_clear_error(&err); } @@ -214,8 +213,8 @@ get_descriptions(MuScriptInfo* msi, const char* prefix) if (io_status != G_IO_STATUS_EOF) { g_warning("error reading %s: %s", - msi->_path, - err ? err->message : "something went wrong"); + msi->_path, + err ? err->message : "something went wrong"); g_clear_error(&err); } @@ -228,9 +227,9 @@ get_descriptions(MuScriptInfo* msi, const char* prefix) GSList* mu_script_get_script_info_list(const char* path, - const char* ext, - const char* descprefix, - GError** err) + const char* ext, + const char* descprefix, + GError** err) { DIR* dir; GSList* lst; @@ -241,10 +240,10 @@ mu_script_get_script_info_list(const char* path, dir = opendir(path); if (!dir) { mu_util_g_set_error(err, - MU_ERROR_FILE_CANNOT_OPEN, - "failed to open '%s': %s", - path, - g_strerror(errno)); + MU_ERROR_FILE_CANNOT_OPEN, + "failed to open '%s': %s", + path, + g_strerror(errno)); return NULL; } @@ -289,6 +288,34 @@ mu_script_find_script_with_name(GSList* lst, const char* name) return NULL; } +static char* +quoted_from_strv (const gchar **params) +{ + GString *str; + int i; + + g_return_val_if_fail (params, NULL); + + if (!params[0]) + return g_strdup (""); + + str = g_string_sized_new (64); /* just a guess */ + + for (i = 0; params[i]; ++i) { + + if (i > 0) + g_string_append_c (str, ' '); + + g_string_append_c (str, '"'); + g_string_append (str, params[i]); + g_string_append_c (str, '"'); + } + + return g_string_free (str, FALSE); +} + + + #ifdef BUILD_GUILE static void guile_shell(void* closure, int argc, char** argv) @@ -308,9 +335,9 @@ mu_script_guile_run(MuScriptInfo* msi, const char* muhome, const char** args, GE if (access(mu_script_info_path(msi), R_OK) != 0) { mu_util_g_set_error(err, - MU_ERROR_FILE_CANNOT_READ, - "failed to read script: %s", - g_strerror(errno)); + MU_ERROR_FILE_CANNOT_READ, + "failed to read script: %s", + g_strerror(errno)); return FALSE; } @@ -321,11 +348,11 @@ mu_script_guile_run(MuScriptInfo* msi, const char* muhome, const char** args, GE s = mu_script_info_path(msi); argv[2] = g_strdup(s ? s : ""); - mainargs = mu_str_quoted_from_strv(args); + mainargs = quoted_from_strv(args); expr = g_strdup_printf("(main '(\"%s\" \"--muhome=%s\" %s))", - mu_script_info_name(msi), - muhome, - mainargs ? mainargs : ""); + mu_script_info_name(msi), + muhome, + mainargs ? mainargs : ""); g_free(mainargs); argv[3] = g_strdup("-c"); diff --git a/lib/mu-server.cc b/lib/mu-server.cc index d33c13e7..c6b2807c 100644 --- a/lib/mu-server.cc +++ b/lib/mu-server.cc @@ -40,7 +40,6 @@ #include "index/mu-indexer.hh" #include "mu-store.hh" -#include "utils/mu-str.h" #include "utils/mu-utils.hh" #include "utils/mu-option.hh" #include "utils/mu-command-parser.hh" diff --git a/lib/mu-store.cc b/lib/mu-store.cc index 0d368567..6454d1b2 100644 --- a/lib/mu-store.cc +++ b/lib/mu-store.cc @@ -38,7 +38,6 @@ #include "mu-maildir.hh" #include "mu-store.hh" #include "mu-query.hh" -#include "utils/mu-str.h" #include "utils/mu-error.hh" #include "utils/mu-utils.hh" diff --git a/lib/tests/test-mu-msg.cc b/lib/tests/test-mu-msg.cc index 3c4513dc..ae7a665c 100644 --- a/lib/tests/test-mu-msg.cc +++ b/lib/tests/test-mu-msg.cc @@ -30,7 +30,6 @@ #include "test-mu-common.hh" #include "utils/mu-result.hh" -#include "utils/mu-str.h" #include "utils/mu-utils.hh" #include diff --git a/lib/utils/Makefile.am b/lib/utils/Makefile.am index f6855d5e..aaab66af 100644 --- a/lib/utils/Makefile.am +++ b/lib/utils/Makefile.am @@ -1,4 +1,4 @@ -## Copyright (C) 2020 Dirk-Jan C. Binnema +## Copyright (C) 2022 Dirk-Jan C. Binnema ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -45,11 +45,6 @@ AM_LDFLAGS= \ noinst_LTLIBRARIES= \ libmu-utils.la - -third_party= \ - optional.hpp \ - expected.hpp - libmu_utils_la_SOURCES= \ mu-async-queue.hh \ mu-command-parser.cc \ @@ -64,14 +59,11 @@ libmu_utils_la_SOURCES= \ mu-result.hh \ mu-sexp.cc \ mu-sexp.hh \ - mu-str.c \ - mu-str.h \ mu-util.c \ mu-util.h \ mu-utils.cc \ mu-utils.hh \ - mu-xapian-utils.hh \ - ${third_party} + mu-xapian-utils.h libmu_utils_la_LIBADD= \ $(GLIB_LIBS) \ diff --git a/lib/utils/meson.build b/lib/utils/meson.build index 3ef68a48..d28459de 100644 --- a/lib/utils/meson.build +++ b/lib/utils/meson.build @@ -21,8 +21,6 @@ lib_mu_utils=static_library('mu-utils', [ 'mu-option.cc', 'mu-readline.cc', 'mu-sexp.cc', - 'mu-str.c', - 'mu-str.h', 'mu-util.c', 'mu-util.h', 'mu-utils.cc'], diff --git a/lib/utils/mu-str.c b/lib/utils/mu-str.c deleted file mode 100644 index 4d290b78..00000000 --- a/lib/utils/mu-str.c +++ /dev/null @@ -1,316 +0,0 @@ -/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/ -/* -** Copyright (C) 2008-2013 Dirk-Jan C. Binnema -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, -** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -** -*/ - -#if HAVE_CONFIG_H -#include "config.h" -#endif /*HAVE_CONFIG_H*/ - -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE (500) -#endif /*_XOPEN_SOURCE*/ - -#include -#include -#include -#include -#include - -#include "mu-util.h" /* PATH_MAX */ -#include "mu-str.h" - -const char* -mu_str_size_s (size_t s) -{ - static char buf[32]; - char *tmp; - - tmp = g_format_size((goffset)s); - strncpy (buf, tmp, sizeof(buf)); - buf[sizeof(buf) -1] = '\0'; /* just in case */ - g_free (tmp); - - return buf; -} - -char* -mu_str_summarize (const char* str, size_t max_lines) -{ - char *summary; - size_t nl_seen; - unsigned i,j; - gboolean last_was_blank; - - g_return_val_if_fail (str, NULL); - g_return_val_if_fail (max_lines > 0, NULL); - - /* len for summary <= original len */ - summary = g_new (gchar, strlen(str) + 1); - - /* copy the string up to max_lines lines, replace CR/LF/tab with - * single space */ - for (i = j = 0, nl_seen = 0, last_was_blank = TRUE; - nl_seen < max_lines && str[i] != '\0'; ++i) { - - if (str[i] == '\n' || str[i] == '\r' || - str[i] == '\t' || str[i] == ' ' ) { - - if (str[i] == '\n') - ++nl_seen; - - /* no double-blanks or blank at end of str */ - if (!last_was_blank && str[i+1] != '\0') - summary[j++] = ' '; - - last_was_blank = TRUE; - } else { - - summary[j++] = str[i]; - last_was_blank = FALSE; - } - } - - summary[j] = '\0'; - return summary; -} - -char* -mu_str_from_list (const GSList *lst, char sepa) -{ - const GSList *cur; - char *str; - - g_return_val_if_fail (sepa, NULL); - - for (cur = lst, str = NULL; cur; cur = g_slist_next(cur)) { - - char *tmp; - /* two extra dummy '\0' so -Wstack-protector won't complain */ - char sep[4] = { '\0', '\0', '\0', '\0' }; - sep[0] = cur->next ? sepa : '\0'; - - tmp = g_strdup_printf ("%s%s%s", - str ? str : "", - (gchar*)cur->data, - sep); - g_free (str); - str = tmp; - } - - return str; -} - -GSList* -mu_str_to_list (const char *str, char sepa, gboolean strip) -{ - GSList *lst; - gchar **strs, **cur; - /* two extra dummy '\0' so -Wstack-protector won't complain */ - char sep[4] = { '\0', '\0', '\0', '\0' }; - - g_return_val_if_fail (sepa, NULL); - - if (!str) - return NULL; - - sep[0] = sepa; - strs = g_strsplit (str, sep, -1); - - for (cur = strs, lst = NULL; cur && *cur; ++cur) { - char *elm; - elm = g_strdup(*cur); - if (strip) - elm = g_strstrip (elm); - - lst = g_slist_prepend (lst, elm); - } - - lst = g_slist_reverse (lst); - g_strfreev (strs); - - return lst; -} - - -/* this function is critical for sorting performance; therefore, no - * regexps, but just some good old c pointer magic */ -const gchar* -mu_str_subject_normalize (const gchar* str) -{ - const char* cur; - - g_return_val_if_fail (str, NULL); - - cur = str; - while (isspace(*cur)) ++cur; /* skip space */ - - /* starts with Re:? */ - if (tolower(cur[0]) == 'r' && tolower(cur[1]) == 'e') - cur += 2; - /* starts with Fwd:? */ - else if (tolower(cur[0]) == 'f' && tolower(cur[1]) == 'w' && - tolower(cur[2]) == 'd') - cur += 3; - else /* nope, different string */ - return str; - - /* we're now past either 'Re' or 'Fwd'. Maybe there's a [] now? - * ie., the Re[3]: foo case */ - if (cur[0] == '[') { /* handle the Re[3]: case */ - if (isdigit(cur[1])) { - do { ++cur; } while (isdigit(*cur)); - if ( cur[0] != ']') { - return str; /* nope: no ending ']' */ - } else /* skip ']' and space */ - do { ++cur; } while (isspace(*cur)); - } else /* nope: no number after '[' */ - return str; - } - - /* now, cur points past either 're' or 'fwd', possibly with - * []; check if it's really a prefix -- after re or fwd - * there should either a ':' and possibly some space */ - if (cur[0] == ':') { - do { ++cur; } while (isspace(*cur)); - /* note: there may still be another prefix, such as - * Re[2]: Fwd: foo */ - return mu_str_subject_normalize (cur); - } else - return str; /* nope, it was not a prefix */ -} - - - -/* turn \0-terminated buf into ascii (which is a utf8 subset); convert - * any non-ascii into '.' - */ -char* -mu_str_asciify_in_place (char *buf) -{ - char *c; - - g_return_val_if_fail (buf, NULL); - - for (c = buf; c && *c; ++c) { - if ((!isprint(*c) && !isspace (*c)) || !isascii(*c)) - *c = '.'; - } - - return buf; -} - -char* -mu_str_utf8ify (const char *buf) -{ - char *utf8; - - g_return_val_if_fail (buf, NULL); - - utf8 = g_strdup (buf); - - if (!g_utf8_validate (buf, -1, NULL)) - mu_str_asciify_in_place (utf8); - - return utf8; -} - - - -gchar* -mu_str_convert_to_utf8 (const char* buffer, const char *charset) -{ - GError *err; - gchar * utf8; - - g_return_val_if_fail (buffer, NULL); - g_return_val_if_fail (charset, NULL ); - - err = NULL; - utf8 = g_convert_with_fallback (buffer, -1, "UTF-8", - charset, NULL, - NULL, NULL, &err); - if (!utf8) /* maybe the charset lied; try 8859-15 */ - utf8 = g_convert_with_fallback (buffer, -1, "UTF-8", - "ISO8859-15", NULL, - NULL, NULL, &err); - /* final attempt, maybe it was utf-8 already */ - if (!utf8 && g_utf8_validate (buffer, -1, NULL)) - utf8 = g_strdup (buffer); - - if (!utf8) { - g_warning ("%s: conversion failed from %s: %s", - __func__, charset, err ? err->message : ""); - } - - g_clear_error (&err); - - return utf8; -} - - -gchar* -mu_str_quoted_from_strv (const gchar **params) -{ - GString *str; - int i; - - g_return_val_if_fail (params, NULL); - - if (!params[0]) - return g_strdup (""); - - str = g_string_sized_new (64); /* just a guess */ - - for (i = 0; params[i]; ++i) { - - if (i > 0) - g_string_append_c (str, ' '); - - g_string_append_c (str, '"'); - g_string_append (str, params[i]); - g_string_append_c (str, '"'); - } - - return g_string_free (str, FALSE); -} - - -char* -mu_str_remove_ctrl_in_place (char *str) -{ - char *orig, *cur; - - g_return_val_if_fail (str, NULL); - - orig = str; - - for (cur = orig; *cur; ++cur) { - if (isspace(*cur)) { - /* squash special white space into a simple space */ - *orig++ = ' '; - } else if (iscntrl(*cur)) { - /* eat it */ - } else - *orig++ = *cur; - } - - *orig = '\0'; /* ensure the updated string has a NULL */ - - return str; -} diff --git a/lib/utils/mu-str.h b/lib/utils/mu-str.h deleted file mode 100644 index cfb292fd..00000000 --- a/lib/utils/mu-str.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/ - -/* -** Copyright (C) 2008-2017 Dirk-Jan C. Binnema -** -** This program is free software; you can redistribute it and/or modify -** it under the terms of the GNU General Public License as published by -** the Free Software Foundation; either version 3 of the License, or -** (at your option) any later version. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -** -** You should have received a copy of the GNU General Public License -** along with this program; if not, write to the Free Software Foundation, -** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -** -*/ - -#ifndef __MU_STR_H__ -#define __MU_STR_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -/** - * @addtogroup MuStr - * Various string utilities - * @{ - */ - -/** - * get a display size for a given size_t; uses M for sizes > - * 1000*1000, k for smaller sizes. Note: this function use the - * 10-based SI units, _not_ the powers-of-2 based ones. - * - * mu_str_size_s returns a ptr to a static buffer, - * - * @param t the size as an size_t - * - * @return a string representation of the size; see above - * for what to do with it - */ -const char* mu_str_size_s (size_t s); - -/** - * get a 'summary' of the string, ie. the first /n/ lines of the - * strings, with all newlines removed, replaced by single spaces - * - * @param str the source string - * @param max_lines the maximum number of lines to include in the summary - * - * @return a newly allocated string with the summary. use g_free to free it. - */ -char* mu_str_summarize (const char* str, size_t max_lines) - G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; - -/** - * create a full path from a path + a filename. function is _not_ - * reentrant. - * - * @param path a path (!= NULL) - * @param name a name (may be NULL) - * - * @return the path as a statically allocated buffer. don't free. - */ -const char* mu_str_fullpath_s (const char* path, const char* name); - -/** - * turn a string into plain ascii by replacing each non-ascii - * character with a dot ('.'). Replacement is done in-place. - * - * @param buf a buffer to asciify - * - * @return the buf ptr (as to allow for function composition) - */ -char* mu_str_asciify_in_place (char *buf); - -/** - * turn string in buf into valid utf8. If this string is not valid - * utf8 already, the function massages the offending characters. - * - * @param buf a buffer to utf8ify - * - * @return a newly allocated utf8 string - */ -char* mu_str_utf8ify (const char *buf); - -/** - * convert a string in a certain charset into utf8 - * - * @param buffer a buffer to convert - * @param charset source character set. - * - * @return a UTF8 string (which you need to g_free when done with it), - * or NULL in case of error - */ -gchar* mu_str_convert_to_utf8 (const char* buffer, const char *charset); - - -/** - * macro to check whether the string is empty, ie. if it's NULL or - * it's length is 0 - * - * @param S a string - * - * @return TRUE if the string is empty, FALSE otherwise - */ -#define mu_str_is_empty(S) ((!(S)||!(*S))?TRUE:FALSE) - -/** - * convert a GSList of strings to a #sepa-separated list - * - * @param lst a GSList - * @param the separator character - * - * @return a newly allocated string - */ -char* mu_str_from_list (const GSList *lst, char sepa); - -/** - * convert a #sepa-separated list of strings in to a GSList - * - * @param str a #sepa-separated list of strings - * @param the separator character - * @param remove leading/trailing whitespace from the string - * - * @return a newly allocated GSList (free with mu_str_free_list) - */ -GSList* mu_str_to_list (const char *str, char sepa, gboolean strip); - -/** - * free a GSList consisting of allocated strings - * - * @param lst a GSList - */ -#define mu_str_free_list(lst) g_slist_free_full(lst, g_free) - -/** - * strip the subject of Re:, Fwd: etc. - * - * @param str a subject string - * - * @return a new string -- this is pointing somewhere inside the @str; - * no copy is made, don't free - */ -const gchar* mu_str_subject_normalize (const gchar* str); - - -/** - * take a list of strings, and return the concatenation of their - * quoted forms - * - * @param params NULL-terminated array of strings - * - * @return the quoted concatenation of the strings - */ -gchar* mu_str_quoted_from_strv (const gchar **params); - - - -/** - * Remove control characters from a string - * - * @param str a string - * - * @return the str with control characters removed - */ -char* mu_str_remove_ctrl_in_place (char *str); - - -/** @} */ - -G_END_DECLS - -#endif /*__MU_STR_H__*/ diff --git a/lib/utils/mu-util.c b/lib/utils/mu-util.c index d7301a20..ab38e719 100644 --- a/lib/utils/mu-util.c +++ b/lib/utils/mu-util.c @@ -106,7 +106,7 @@ mu_util_dir_expand (const char *path) /* now resolve any symlinks, .. etc. */ if (realpath (dir, resolved) == NULL) { /* g_debug ("%s: could not get realpath for '%s': %s", */ - /* __func__, dir, g_strerror(errno)); */ + /* __func__, dir, g_strerror(errno)); */ g_free (dir); return NULL; } else @@ -127,20 +127,6 @@ mu_util_error_quark (void) return error_domain; } - -const char* -mu_util_cache_dir (void) -{ - static char cachedir [PATH_MAX]; - - g_snprintf (cachedir, sizeof(cachedir), "%s%cmu-%u", - g_get_tmp_dir(), G_DIR_SEPARATOR, - getuid()); - - return cachedir; -} - - gboolean mu_util_check_dir (const gchar* path, gboolean readable, gboolean writeable) { @@ -220,21 +206,6 @@ mu_util_create_dir_maybe (const gchar *path, mode_t mode, gboolean nowarn) return TRUE; } - -int -mu_util_create_writeable_fd (const char* path, mode_t mode, - gboolean overwrite) -{ - errno = 0; /* clear! */ - g_return_val_if_fail (path, -1); - - if (overwrite) - return open (path, O_WRONLY|O_CREAT|O_TRUNC, mode); - else - return open (path, O_WRONLY|O_CREAT|O_EXCL, mode); -} - - gboolean mu_util_is_local_file (const char* path) { @@ -375,7 +346,7 @@ mu_util_locale_is_utf8 (void) static int is_utf8 = -1; if (G_UNLIKELY(is_utf8 == -1)) - is_utf8 = g_get_charset(&dummy) ? 1 : 0; + is_utf8 = g_get_charset(&dummy) ? 1 : 0; return is_utf8 ? TRUE : FALSE; } @@ -498,3 +469,45 @@ mu_util_read_password (const char *prompt) return g_strdup(pass); } + + +char* +mu_str_summarize (const char* str, size_t max_lines) +{ + char *summary; + size_t nl_seen; + unsigned i,j; + gboolean last_was_blank; + + g_return_val_if_fail (str, NULL); + g_return_val_if_fail (max_lines > 0, NULL); + + /* len for summary <= original len */ + summary = g_new (gchar, strlen(str) + 1); + + /* copy the string up to max_lines lines, replace CR/LF/tab with + * single space */ + for (i = j = 0, nl_seen = 0, last_was_blank = TRUE; + nl_seen < max_lines && str[i] != '\0'; ++i) { + + if (str[i] == '\n' || str[i] == '\r' || + str[i] == '\t' || str[i] == ' ' ) { + + if (str[i] == '\n') + ++nl_seen; + + /* no double-blanks or blank at end of str */ + if (!last_was_blank && str[i+1] != '\0') + summary[j++] = ' '; + + last_was_blank = TRUE; + } else { + + summary[j++] = str[i]; + last_was_blank = FALSE; + } + } + + summary[j] = '\0'; + return summary; +} diff --git a/lib/utils/mu-util.h b/lib/utils/mu-util.h index 82c13c92..86423efe 100644 --- a/lib/utils/mu-util.h +++ b/lib/utils/mu-util.h @@ -1,5 +1,5 @@ /* -** Copyright (C) 2008-2013 Dirk-Jan C. Binnema +** Copyright (C) 2008-2022 Dirk-Jan C. Binnema ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by @@ -85,31 +85,6 @@ gboolean mu_util_check_dir (const gchar* path, gboolean readable, gboolean writeable) G_GNUC_WARN_UNUSED_RESULT; - -/** - * get our the cache directory, typically, /tmp/mu-/ - * - * @return the cache directory; don't free - */ -const char* mu_util_cache_dir (void) G_GNUC_CONST; - -/** - * create a writeable file and return its file descriptor (which - * you'll need to close(2) when done with it.) - * - * @param path the full path of the file to create - * @param the mode to open (ie. 0644 or 0600 etc., see chmod(3) - * @param overwrite should we allow for overwriting existing files? - * - * @return a file descriptor, or -1 in case of error. If it's a file - * system error, 'errno' may contain more info. use 'close()' when done - * with the file descriptor - */ -int mu_util_create_writeable_fd (const char* path, mode_t mode, - gboolean overwrite) - G_GNUC_WARN_UNUSED_RESULT; - - /** * check if file is local, ie. on the local file system. this means * that it's either having a file URI, *or* that it's an existing file @@ -128,6 +103,21 @@ gboolean mu_util_is_local_file (const char* path); */ gboolean mu_util_locale_is_utf8 (void) G_GNUC_CONST; + + +/** + * get a 'summary' of the string, ie. the first /n/ lines of the + * strings, with all newlines removed, replaced by single spaces + * + * @param str the source string + * @param max_lines the maximum number of lines to include in the summary + * + * @return a newly allocated string with the summary. use g_free to free it. + */ +char* mu_str_summarize (const char* str, size_t max_lines) + G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; + + /** * write a string (assumed to be in utf8-format) to a stream, * converted to the current locale @@ -319,18 +309,18 @@ enum _MuError { MU_ERROR_XAPIAN_MISSING_DATA = 17, /* can't get write lock */ MU_ERROR_XAPIAN_CANNOT_GET_WRITELOCK = 19, - /* could not write */ + /* could not write */ MU_ERROR_XAPIAN_STORE_FAILED = 21, /* could not remove */ MU_ERROR_XAPIAN_REMOVE_FAILED = 22, /* database was modified; reload */ MU_ERROR_XAPIAN_MODIFIED = 23, - /* database was modified; reload */ + /* database was modified; reload */ MU_ERROR_XAPIAN_NEEDS_REINDEX = 24, - /* database schema version doesn't match */ - MU_ERROR_XAPIAN_SCHEMA_MISMATCH = 25, - /* failed to open the database */ - MU_ERROR_XAPIAN_CANNOT_OPEN = 26, + /* database schema version doesn't match */ + MU_ERROR_XAPIAN_SCHEMA_MISMATCH = 25, + /* failed to open the database */ + MU_ERROR_XAPIAN_CANNOT_OPEN = 26, /* GMime related errors */ @@ -342,7 +332,7 @@ enum _MuError { MU_ERROR_CONTACTS_CANNOT_RETRIEVE = 51, /* crypto related errors */ - MU_ERROR_CRYPTO = 60, + MU_ERROR_CRYPTO = 60, /* File errors */ diff --git a/lib/utils/mu-utils.cc b/lib/utils/mu-utils.cc index 962cbca9..ee22fe4f 100644 --- a/lib/utils/mu-utils.cc +++ b/lib/utils/mu-utils.cc @@ -46,7 +46,6 @@ #include "mu-utils.hh" #include "mu-utils-format.hh" #include "mu-util.h" -#include "mu-str.h" #include "mu-error.hh" #include "mu-option.hh" @@ -140,11 +139,49 @@ Mu::utf8_flatten(const char* str) return s; } + + + +/* turn \0-terminated buf into ascii (which is a utf8 subset); convert + * any non-ascii into '.' + */ +static char* +asciify_in_place (char *buf) +{ + char *c; + + g_return_val_if_fail (buf, NULL); + + for (c = buf; c && *c; ++c) { + if ((!isprint(*c) && !isspace (*c)) || !isascii(*c)) + *c = '.'; + } + + return buf; +} + + +static char* +utf8ify (const char *buf) +{ + char *utf8; + + g_return_val_if_fail (buf, NULL); + + utf8 = g_strdup (buf); + + if (!g_utf8_validate (buf, -1, NULL)) + asciify_in_place (utf8); + + return utf8; +} + + std::string Mu::utf8_clean(const std::string& dirty) { g_autoptr(GString) gstr = g_string_sized_new(dirty.length()); - g_autofree char *cstr = mu_str_utf8ify(dirty.c_str()); + g_autofree char *cstr = utf8ify(dirty.c_str()); for (auto cur = cstr; cur && *cur; cur = g_utf8_next_char(cur)) { const gunichar uc = g_utf8_get_char(cur); diff --git a/lib/utils/tests/meson.build b/lib/utils/tests/meson.build index 34ae47ec..85dc3c5b 100644 --- a/lib/utils/tests/meson.build +++ b/lib/utils/tests/meson.build @@ -23,11 +23,6 @@ test('test-command-parser', 'test-command-parser.cc', install: false, dependencies: [glib_dep, lib_mu_utils_dep])) -test('test-mu-str', - executable('test-mu-str', - 'test-mu-str.c', - install: false, - dependencies: [glib_dep, config_h_dep,lib_mu_utils_dep])) test('test-mu-util', executable('test-mu-util', 'test-mu-util.c', diff --git a/mu/mu-cmd-cfind.cc b/mu/mu-cmd-cfind.cc index a6385b63..893ce84f 100644 --- a/mu/mu-cmd-cfind.cc +++ b/mu/mu-cmd-cfind.cc @@ -32,10 +32,20 @@ #include "utils/mu-util.h" #include "utils/mu-utils.hh" #include "utils/mu-error.hh" -#include "utils/mu-str.h" using namespace Mu; +/** + * macro to check whether the string is empty, ie. if it's NULL or + * it's length is 0 + * + * @param S a string + * + * @return TRUE if the string is empty, FALSE otherwise + */ +#define mu_str_is_empty(S) ((!(S)||!(*S))?TRUE:FALSE) + + /** * guess the last name for the given name; clearly, * this is just a rough guess for setting an initial value. diff --git a/mu/mu-cmd-extract.cc b/mu/mu-cmd-extract.cc index 1a97e9df..97adb353 100644 --- a/mu/mu-cmd-extract.cc +++ b/mu/mu-cmd-extract.cc @@ -21,7 +21,6 @@ #include "mu-cmd.hh" #include "mu-config.hh" #include "utils/mu-util.h" -#include "utils/mu-str.h" #include "utils/mu-utils.hh" #include #include diff --git a/mu/mu-cmd-find.cc b/mu/mu-cmd-find.cc index 49ea7366..cd7517fa 100644 --- a/mu/mu-cmd-find.cc +++ b/mu/mu-cmd-find.cc @@ -38,7 +38,6 @@ #include "utils/mu-option.hh" #include "utils/mu-util.h" -#include "utils/mu-str.h" #include "mu-cmd.hh" #include "utils/mu-utils.hh" diff --git a/mu/mu-cmd-script.cc b/mu/mu-cmd-script.cc index 187b6b4d..62ef9c12 100644 --- a/mu/mu-cmd-script.cc +++ b/mu/mu-cmd-script.cc @@ -32,7 +32,6 @@ #include "mu-runtime.hh" #include "utils/mu-util.h" -#include "utils/mu-str.h" #define MU_GUILE_EXT ".scm" #define MU_GUILE_DESCR_PREFIX ";; INFO: " diff --git a/mu/mu-cmd.cc b/mu/mu-cmd.cc index a04b4174..07656bce 100644 --- a/mu/mu-cmd.cc +++ b/mu/mu-cmd.cc @@ -37,7 +37,6 @@ #include "message/mu-mime-object.hh" #include "utils/mu-util.h" -#include "utils/mu-str.h" #include "utils/mu-error.hh" #include "utils/mu-utils.hh" diff --git a/mu/tests/test-mu-query.cc b/mu/tests/test-mu-query.cc index 6eed6f7f..26d0000d 100644 --- a/mu/tests/test-mu-query.cc +++ b/mu/tests/test-mu-query.cc @@ -33,7 +33,6 @@ #include "test-mu-common.hh" #include "mu-query.hh" #include "utils/mu-result.hh" -#include "utils/mu-str.h" #include "utils/mu-utils.hh" #include "mu-store.hh"