X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fcommon%2Futils.c;h=ab112f240f8049d5401a8b9eba92b8582d9bc808;hp=cfd5309c6cf3187a8f54807a257a82ced2e3b9a9;hb=99a7382d8fc0b91c98475ec8c92c9a86975accc7;hpb=0c50c0a40aac3638f7492e635b9232c748633b2f diff --git a/src/common/utils.c b/src/common/utils.c index cfd5309c6..ab112f240 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2002 Hiroyuki Yamamoto + * Copyright (C) 1999-2003 Hiroyuki Yamamoto * * 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 @@ -470,52 +470,29 @@ wchar_t *wcscasestr(const wchar_t *haystack, const wchar_t *needle) } /* Examine if next block is non-ASCII string */ -gboolean is_next_nonascii(const wchar_t *s) +gboolean is_next_nonascii(const guchar *s) { - const wchar_t *wp; + const guchar *p; /* skip head space */ - for (wp = s; *wp != (wchar_t)0 && iswspace(*wp); wp++) + for (p = s; *p != '\0' && isspace(*p); p++) ; - for (; *wp != (wchar_t)0 && !iswspace(*wp); wp++) { - if (*wp > 127) + for (; *p != '\0' && !isspace(*p); p++) { + if (*p > 127 || *p < 32) return TRUE; } return FALSE; } -/* Examine if next block is multi-byte string */ -gboolean is_next_mbs(const wchar_t *s) +gint get_next_word_len(const gchar *s) { - gint mbl; - const wchar_t *wp; - gchar tmp[MB_LEN_MAX]; + gint len = 0; - /* skip head space */ - for (wp = s; *wp != (wchar_t)0 && iswspace(*wp); wp++) + for (; *s != '\0' && !isspace(*s); s++, len++) ; - for (; *wp != (wchar_t)0 && !iswspace(*wp); wp++) { - mbl = wctomb(tmp, *wp); - if (mbl > 1) - return TRUE; - } - - return FALSE; -} - -wchar_t *find_wspace(const wchar_t *s) -{ - const wchar_t *wp; - for (wp = s; *wp != (wchar_t)0 && iswspace(*wp); wp++) - ; - for (; *wp != (wchar_t)0; wp++) { - if (iswspace(*wp)) - return (wchar_t *)wp; - } - - return NULL; + return len; } /* compare subjects */ @@ -1270,22 +1247,21 @@ gchar *get_abbrev_newsgroup_name(const gchar *group, gint len) gchar *abbrev_group; gchar *ap; const gchar *p = group; - gint count = 0; + const gchar *last; + last = group + strlen(group); abbrev_group = ap = g_malloc(strlen(group) + 1); while (*p) { while (*p == '.') *ap++ = *p++; - - if ((strlen( p) + count) > len && strchr(p, '.')) { + if ((ap - abbrev_group) + (last - p) > len && strchr(p, '.')) { *ap++ = *p++; while (*p != '.') p++; } else { - strcpy( ap, p); + strcpy(ap, p); return abbrev_group; } - count = count + 2; } *ap = '\0'; @@ -2086,7 +2062,7 @@ gint copy_file(const gchar *src, const gchar *dest) while (len > 0) { n_write = write(dest_fd, bufp, len); if (n_write <= 0) { - g_warning(_("writing to %s failed.\n"), dest); + g_warning("writing to %s failed.\n", dest); close(dest_fd); close(src_fd); unlink(dest); @@ -2106,7 +2082,7 @@ gint copy_file(const gchar *src, const gchar *dest) close(dest_fd); if (n_read < 0 || get_file_size(src) != get_file_size(dest)) { - g_warning(_("File copy from %s to %s failed.\n"), src, dest); + g_warning("File copy from %s to %s failed.\n", src, dest); unlink(dest); if (dest_bak) { if (rename(dest_bak, dest) < 0) @@ -2147,14 +2123,14 @@ gint append_file(const gchar *src, const gchar *dest, gboolean keep_backup) if (change_file_mode_rw(dest_fp, dest) < 0) { FILE_OP_ERROR(dest, "chmod"); - g_warning(_("can't change file mode\n")); + g_warning("can't change file mode\n"); } while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), src_fp)) > 0) { if (n_read < sizeof(buf) && ferror(src_fp)) break; if (fwrite(buf, n_read, 1, dest_fp) < 1) { - g_warning(_("writing to %s failed.\n"), dest); + g_warning("writing to %s failed.\n", dest); fclose(dest_fp); fclose(src_fp); unlink(dest); @@ -2215,14 +2191,14 @@ gint copy_file(const gchar *src, const gchar *dest, gboolean keep_backup) if (change_file_mode_rw(dest_fp, dest) < 0) { FILE_OP_ERROR(dest, "chmod"); - g_warning(_("can't change file mode\n")); + g_warning("can't change file mode\n"); } while ((n_read = fread(buf, sizeof(gchar), sizeof(buf), src_fp)) > 0) { if (n_read < sizeof(buf) && ferror(src_fp)) break; if (fwrite(buf, n_read, 1, dest_fp) < 1) { - g_warning(_("writing to %s failed.\n"), dest); + g_warning("writing to %s failed.\n", dest); fclose(dest_fp); fclose(src_fp); unlink(dest); @@ -2314,7 +2290,7 @@ gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest) if (n_read < to_read && ferror(fp)) break; if (fwrite(buf, n_read, 1, dest_fp) < 1) { - g_warning(_("writing to %s failed.\n"), dest); + g_warning("writing to %s failed.\n", dest); fclose(dest_fp); unlink(dest); return -1; @@ -2345,6 +2321,39 @@ gint copy_file_part(FILE *fp, off_t offset, size_t length, const gchar *dest) /* convert line endings into CRLF. If the last line doesn't end with * linebreak, add it. */ +gchar *canonicalize_str(const gchar *str) +{ + const gchar *p; + guint new_len = 0; + gchar *out, *outp; + + for (p = str; *p != '\0'; ++p) { + if (*p != '\r') { + ++new_len; + if (*p == '\n') + ++new_len; + } + } + if (p == str || *(p - 1) != '\n') + new_len += 2; + + out = outp = g_malloc(new_len + 1); + for (p = str; *p != '\0'; ++p) { + if (*p != '\r') { + if (*p == '\n') + *outp++ = '\r'; + *outp++ = *p; + } + } + if (p == str || *(p - 1) != '\n') { + *outp++ = '\r'; + *outp++ = '\n'; + } + *outp = '\0'; + + return out; +} + gint canonicalize_file(const gchar *src, const gchar *dest) { FILE *src_fp, *dest_fp; @@ -2406,7 +2415,7 @@ gint canonicalize_file(const gchar *src, const gchar *dest) } if (ferror(src_fp)) { - FILE_OP_ERROR(src, "fread"); + FILE_OP_ERROR(src, "fgets"); err = TRUE; } fclose(src_fp); @@ -2445,6 +2454,79 @@ gint canonicalize_file_replace(const gchar *file) return 0; } +gint uncanonicalize_file(const gchar *src, const gchar *dest) +{ + FILE *src_fp, *dest_fp; + gchar buf[BUFFSIZE]; + gboolean err = FALSE; + + if ((src_fp = fopen(src, "rb")) == NULL) { + FILE_OP_ERROR(src, "fopen"); + return -1; + } + + if ((dest_fp = fopen(dest, "wb")) == NULL) { + FILE_OP_ERROR(dest, "fopen"); + fclose(src_fp); + return -1; + } + + if (change_file_mode_rw(dest_fp, dest) < 0) { + FILE_OP_ERROR(dest, "chmod"); + g_warning("can't change file mode\n"); + } + + while (fgets(buf, sizeof(buf), src_fp) != NULL) { + strcrchomp(buf); + if (fputs(buf, dest_fp) == EOF) { + g_warning("writing to %s failed.\n", dest); + fclose(dest_fp); + fclose(src_fp); + unlink(dest); + return -1; + } + } + + if (ferror(src_fp)) { + FILE_OP_ERROR(src, "fgets"); + err = TRUE; + } + fclose(src_fp); + if (fclose(dest_fp) == EOF) { + FILE_OP_ERROR(dest, "fclose"); + err = TRUE; + } + + if (err) { + unlink(dest); + return -1; + } + + return 0; +} + +gint uncanonicalize_file_replace(const gchar *file) +{ + gchar *tmp_file; + + tmp_file = get_tmp_file(); + + if (uncanonicalize_file(file, tmp_file) < 0) { + g_free(tmp_file); + return -1; + } + + if (move_file(tmp_file, file, TRUE) < 0) { + g_warning("can't replace %s .\n", file); + unlink(tmp_file); + g_free(tmp_file); + return -1; + } + + g_free(tmp_file); + return 0; +} + gint change_file_mode_rw(FILE *fp, const gchar *file) { #if HAVE_FCHMOD @@ -2774,7 +2856,6 @@ void decode_uri(gchar *decoded_uri, const gchar *encoded_uri) gint open_uri(const gchar *uri, const gchar *cmdline) { - static gchar *default_cmdline = "netscape -remote openURL(%s,raise)"; gchar buf[BUFFSIZE]; gchar *p; gchar encoded_uri[BUFFSIZE]; @@ -2790,9 +2871,9 @@ gint open_uri(const gchar *uri, const gchar *cmdline) g_snprintf(buf, sizeof(buf), cmdline, encoded_uri); else { if (cmdline) - g_warning(_("Open URI command line is invalid: `%s'"), + g_warning("Open URI command line is invalid: `%s'", cmdline); - g_snprintf(buf, sizeof(buf), default_cmdline, encoded_uri); + g_snprintf(buf, sizeof(buf), DEFAULT_BROWSER_CMD, encoded_uri); } execute_command_line(buf, TRUE); @@ -3030,10 +3111,11 @@ FILE *get_tmpfile_in_dir(const gchar *dir, gchar **filename) /* allow Mutt-like patterns in quick search */ gchar *expand_search_string(const gchar *search_string) { - int i, len, new_len = 0; + int i = 0; gchar term_char, save_char; gchar *cmd_start, *cmd_end; - gchar *new_str = NULL; + GString *matcherstr; + gchar *returnstr = NULL; gchar *copy_str; gboolean casesens, dontmatch; /* list of allowed pattern abbreviations */ @@ -3060,6 +3142,7 @@ gchar *expand_search_string(const gchar *search_string) { "h", "headers_part", 1, TRUE, TRUE }, { "i", "header \"Message-Id\"", 1, TRUE, TRUE }, { "I", "inreplyto", 1, TRUE, TRUE }, + { "L", "locked", 0, FALSE, FALSE }, { "n", "newsgroups", 1, TRUE, TRUE }, { "N", "new", 0, FALSE, FALSE }, { "O", "~new", 0, FALSE, FALSE }, @@ -3090,16 +3173,18 @@ gchar *expand_search_string(const gchar *search_string) /* if it's a full command don't process it so users can still do something like from regexpcase "foo" */ for (i = 0; cmds[i].command; i++) { + const gchar *tmp_search_string = search_string; cmd_start = cmds[i].command; /* allow logical NOT */ - if (*cmd_start == '~') - cmd_start++; - if (!strncmp(copy_str, cmd_start, strlen(cmd_start))) + if (*tmp_search_string == '~') + tmp_search_string++; + if (!strncmp(tmp_search_string, cmd_start, strlen(cmd_start))) break; } if (cmds[i].command) return copy_str; + matcherstr = g_string_sized_new(16); cmd_start = cmd_end = copy_str; while (cmd_end && *cmd_end) { /* skip all white spaces */ @@ -3135,26 +3220,15 @@ gchar *expand_search_string(const gchar *search_string) if (!strcmp(cmd_start, cmds[i].abbreviated)) { /* restore character */ *cmd_end = save_char; - len = strlen(cmds[i].command) + 1; - if (dontmatch) - len++; - if (casesens) - len++; /* copy command */ - if (new_str) { - new_len += 1; - new_str = g_realloc(new_str, new_len); - strcat(new_str, " "); + if (matcherstr->len > 0) { + g_string_append(matcherstr, " "); } - new_len += (len + 1); - new_str = g_realloc(new_str, new_len); - if (new_len == len + 1) - *new_str = '\0'; if (dontmatch) - strcat(new_str, "~"); - strcat(new_str, cmds[i].command); - strcat(new_str, " "); + g_string_append(matcherstr, "~"); + g_string_append(matcherstr, cmds[i].command); + g_string_append(matcherstr, " "); /* stop if no params required */ if (cmds[i].numparams == 0) @@ -3183,33 +3257,23 @@ gchar *expand_search_string(const gchar *search_string) save_char = *cmd_end; *cmd_end = '\0'; - new_len += strlen(cmd_start); - - /* do we need to add regexpcase ? */ - if (cmds[i].qualifier) - new_len += 10; /* "regexpcase " */ - - if (term_char != '"') - new_len += 2; - new_str = g_realloc(new_str, new_len); - if (cmds[i].qualifier) { if (casesens) - strcat(new_str, "regexp "); + g_string_append(matcherstr, "regexp "); else - strcat(new_str, "regexpcase "); + g_string_append(matcherstr, "regexpcase "); } /* do we need to add quotes ? */ if (cmds[i].quotes && term_char != '"') - strcat(new_str, "\""); + g_string_append(matcherstr, "\""); /* copy actual parameter */ - strcat(new_str, cmd_start); + g_string_append(matcherstr, cmd_start); /* do we need to add quotes ? */ if (cmds[i].quotes && term_char != '"') - strcat(new_str, "\""); + g_string_append(matcherstr, "\""); /* restore original character */ *cmd_end = save_char; @@ -3225,6 +3289,29 @@ gchar *expand_search_string(const gchar *search_string) } g_free(copy_str); - return new_str; + returnstr = matcherstr->str; + g_string_free(matcherstr, FALSE); + return returnstr; +} + +guint g_stricase_hash(gconstpointer gptr) +{ + guint hash_result = 0; + const char *str; + + for (str = gptr; str && *str; str++) { + if (isupper(*str)) hash_result += (*str + ' '); + else hash_result += *str; + } + + return hash_result; +} + +gint g_stricase_equal(gconstpointer gptr1, gconstpointer gptr2) +{ + const char *str1 = gptr1; + const char *str2 = gptr2; + + return !strcasecmp(str1, str2); }