diff options
Diffstat (limited to 'src/common/text.c')
-rw-r--r-- | src/common/text.c | 582 |
1 files changed, 227 insertions, 355 deletions
diff --git a/src/common/text.c b/src/common/text.c index 329ef37b..cd9ea26e 100644 --- a/src/common/text.c +++ b/src/common/text.c @@ -51,6 +51,9 @@ #include <canberra.h> #endif +const gchar* unicode_fallback_string = "\357\277\275"; /* The Unicode replacement character 0xFFFD */ +const gchar* arbitrary_encoding_fallback_string = "?"; + struct pevt_stage1 { int len; @@ -83,7 +86,7 @@ scrollback_get_filename (session *sess) buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "scrollback" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.txt", get_xdir (), net, chan); else buf = NULL; - free (chan); + g_free (chan); return buf; } @@ -173,11 +176,11 @@ scrollback_shrink (session *sess) p++; } - fh = g_open (file, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY, 0644); + fh = g_open (file, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY | OFLAGS, 0644); g_free (file); if (fh == -1) { - free (buf); + g_free (buf); return; } @@ -200,14 +203,13 @@ scrollback_shrink (session *sess) } close (fh); - free (buf); + g_free (buf); } static void -scrollback_save (session *sess, char *text) +scrollback_save (session *sess, char *text, time_t stamp) { char *buf; - time_t stamp; int len; if (sess->type == SESS_SERVER && prefs.hex_gui_tab_server == 1) @@ -229,13 +231,14 @@ scrollback_save (session *sess, char *text) if ((buf = scrollback_get_filename (sess)) == NULL) return; - sess->scrollfd = g_open (buf, O_CREAT | O_APPEND | O_WRONLY, 0644); + sess->scrollfd = g_open (buf, O_CREAT | O_APPEND | O_WRONLY | OFLAGS, 0644); g_free (buf); if (sess->scrollfd == -1) return; } - stamp = time (0); + if (!stamp) + stamp = time(0); if (sizeof (stamp) == 4) /* gcc will optimize one of these out */ buf = g_strdup_printf ("T %d ", (int) stamp); else @@ -298,13 +301,6 @@ scrollback_load (session *sess) { char *buf_tmp; - /* If nothing but funny trailing matter e.g. 0x0d or 0x0d0a, toss it */ - if (n_bytes >= 1 && buf[0] == 0x0d) - { - g_free (buf); - continue; - } - n_bytes--; buf_tmp = buf; buf = g_strndup (buf_tmp, n_bytes); @@ -319,9 +315,9 @@ scrollback_load (session *sess) if (buf[0] == 'T') { if (sizeof (time_t) == 4) - stamp = strtoul (buf + 2, NULL, 10); + stamp = g_ascii_strtoull (buf + 2, NULL, 10); else - stamp = strtoull (buf + 2, NULL, 10); /* in case time_t is 64 bits */ + stamp = g_ascii_strtoull (buf + 2, NULL, 10); /* in case time_t is 64 bits */ text = strchr (buf + 3, ' '); if (text && text[1]) { @@ -383,7 +379,7 @@ log_close (session *sess) { currenttime = time (NULL); write (sess->logfd, obuf, - snprintf (obuf, sizeof (obuf) - 1, _("**** ENDING LOGGING AT %s\n"), + g_snprintf (obuf, sizeof (obuf) - 1, _("**** ENDING LOGGING AT %s\n"), ctime (¤ttime))); close (sess->logfd); sess->logfd = -1; @@ -393,9 +389,7 @@ log_close (session *sess) static void mkdir_p (char *filename) { - char *dirname; - - dirname = g_path_get_dirname (filename); + char *dirname = g_path_get_dirname (filename); g_mkdir_with_parents (dirname, 0700); @@ -408,7 +402,7 @@ log_create_filename (char *channame) char *tmp, *ret; int mbl; - ret = tmp = strdup (channame); + ret = tmp = g_strdup (channame); while (*tmp) { mbl = g_utf8_skip[((unsigned char *)tmp)[0]]; @@ -507,34 +501,6 @@ log_insert_vars (char *buf, int bufsize, char *fmt, char *c, char *n, char *s) } } -static int -logmask_is_fullpath () -{ - /* Check if final path/filename is absolute or relative. - * If one uses log mask variables, such as "%c/...", %c will be empty upon - * connecting since there's no channel name yet, so we have to make sure - * we won't try to write to the FS root. On Windows we can be sure it's - * full path if the 2nd character is a colon since Windows doesn't allow - * colons in filenames. - */ -#ifdef WIN32 - /* Treat it as full path if it - * - starts with '\' which denotes the root directory of the current drive letter - * - starts with a drive letter and followed by ':' - */ - if (prefs.hex_irc_logmask[0] == '\\' || (((prefs.hex_irc_logmask[0] >= 'A' && prefs.hex_irc_logmask[0] <= 'Z') || (prefs.hex_irc_logmask[0] >= 'a' && prefs.hex_irc_logmask[0] <= 'z')) && prefs.hex_irc_logmask[1] == ':')) -#else - if (prefs.hex_irc_logmask[0] == '/') -#endif - { - return 1; - } - else - { - return 0; - } -} - static char * log_create_pathname (char *servname, char *channame, char *netname) { @@ -544,7 +510,7 @@ log_create_pathname (char *servname, char *channame, char *netname) if (!netname) { - netname = strdup ("NETWORK"); + netname = g_strdup ("NETWORK"); } else { @@ -554,7 +520,7 @@ log_create_pathname (char *servname, char *channame, char *netname) /* first, everything is in UTF-8 */ if (!rfc_casecmp (channame, servname)) { - channame = strdup ("server"); + channame = g_strdup ("server"); } else { @@ -562,27 +528,29 @@ log_create_pathname (char *servname, char *channame, char *netname) } log_insert_vars (fname, sizeof (fname), prefs.hex_irc_logmask, channame, netname, servname); - free (channame); - free (netname); + g_free (channame); + g_free (netname); /* insert time/date */ now = time (NULL); strftime_utf8 (fnametime, sizeof (fnametime), fname, now); - /* create final path/filename */ - if (logmask_is_fullpath ()) + /* If one uses log mask variables, such as "%c/...", %c will be empty upon + * connecting since there's no channel name yet, so we have to make sure + * we won't try to write to the FS root. */ + if (g_path_is_absolute (prefs.hex_irc_logmask)) { - snprintf (fname, sizeof (fname), "%s", fnametime); + g_snprintf (fname, sizeof (fname), "%s", fnametime); } else /* relative path */ { - snprintf (fname, sizeof (fname), "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", get_xdir (), fnametime); + g_snprintf (fname, sizeof (fname), "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", get_xdir (), fnametime); } /* create all the subdirectories */ mkdir_p (fname); - return g_strdup(fname); + return g_strdup (fname); } static int @@ -597,18 +565,14 @@ log_open_file (char *servname, char *channame, char *netname) if (!file) return -1; -#ifdef WIN32 - fd = g_open (file, O_CREAT | O_APPEND | O_WRONLY, S_IREAD|S_IWRITE); -#else - fd = g_open (file, O_CREAT | O_APPEND | O_WRONLY, 0644); -#endif + fd = g_open (file, O_CREAT | O_APPEND | O_WRONLY | OFLAGS, 0644); g_free (file); if (fd == -1) return -1; currenttime = time (NULL); write (fd, buf, - snprintf (buf, sizeof (buf), _("**** BEGIN LOGGING AT %s\n"), + g_snprintf (buf, sizeof (buf), _("**** BEGIN LOGGING AT %s\n"), ctime (¤ttime))); return fd; @@ -625,14 +589,15 @@ log_open (session *sess) if (!log_error && sess->logfd == -1) { - char *message; + char *filename = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE)); + char *message = g_strdup_printf (_("* Can't open log file(s) for writing. Check the\npermissions on %s"), filename); - message = g_strdup_printf (_("* Can't open log file(s) for writing. Check the\npermissions on %s"), - log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE))); + g_free (filename); fe_message (message, FE_MSG_WAIT | FE_MSG_ERROR); g_free (message); + log_error = TRUE; } } @@ -659,34 +624,29 @@ log_open_or_close (session *sess) int get_stamp_str (char *fmt, time_t tim, char **ret) { - char *loc = NULL; char dest[128]; - gsize len; + gsize len_locale; + gsize len_utf8; - /* strftime wants the format string in LOCALE! */ - if (!prefs.utf8_locale) - { - const gchar *charset; + /* strftime requires the format string to be in locale encoding. */ + fmt = g_locale_from_utf8 (fmt, -1, NULL, NULL, NULL); - g_get_charset (&charset); - loc = g_convert_with_fallback (fmt, -1, charset, "UTF-8", "?", 0, 0, 0); - if (loc) - fmt = loc; - } + len_locale = strftime_validated (dest, sizeof (dest), fmt, localtime (&tim)); - len = strftime_validated (dest, sizeof (dest), fmt, localtime (&tim)); - if (len) + g_free (fmt); + + if (len_locale == 0) { - if (prefs.utf8_locale) - *ret = g_strdup (dest); - else - *ret = g_locale_to_utf8 (dest, len, 0, &len, 0); + return 0; } - if (loc) - g_free (loc); + *ret = g_locale_to_utf8 (dest, len_locale, NULL, &len_utf8, NULL); + if (*ret == NULL) + { + return 0; + } - return len; + return len_utf8; } static void @@ -709,22 +669,32 @@ log_write (session *sess, char *text, time_t ts) } if (sess->logfd == -1) + { log_open (sess); + } /* change to a different log file? */ - file = log_create_pathname (sess->server->servername, sess->channel, - server_get_network (sess->server, FALSE)); + file = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE)); if (file) { if (g_access (file, F_OK) != 0) { - close (sess->logfd); - sess->logfd = log_open_file (sess->server->servername, sess->channel, - server_get_network (sess->server, FALSE)); + if (sess->logfd != -1) + { + close (sess->logfd); + } + + sess->logfd = log_open_file (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE)); } + g_free (file); } + if (sess->logfd == -1) + { + return; + } + if (prefs.hex_stamp_log) { if (!ts) ts = time(0); @@ -735,6 +705,7 @@ log_write (session *sess, char *text, time_t ts) g_free (stamp); } } + temp = strip_color (text, -1, STRIP_ALL); len = strlen (temp); write (sess->logfd, temp, len); @@ -744,156 +715,104 @@ log_write (session *sess, char *text, time_t ts) g_free (temp); } -/* converts a CP1252/ISO-8859-1(5) hybrid to UTF-8 */ -/* Features: 1. It never fails, all 00-FF chars are converted to valid UTF-8 */ -/* 2. Uses CP1252 in the range 80-9f because ISO doesn't have any- */ -/* thing useful in this range and it helps us receive from mIRC */ -/* 3. The five undefined chars in CP1252 80-9f are replaced with */ -/* ISO-8859-15 control codes. */ -/* 4. Handles 0xa4 as a Euro symbol ala ISO-8859-15. */ -/* 5. Uses ISO-8859-1 (which matches CP1252) for everything else. */ -/* 6. This routine measured 3x faster than g_convert :) */ - -static unsigned char * -iso_8859_1_to_utf8 (unsigned char *text, int len, gsize *bytes_written) +/** + * Converts a given string using the given iconv converter. This is similar to g_convert_with_fallback, except that it is tolerant of sequences in + * the original input that are invalid even in from_encoding. g_convert_with_fallback fails for such text, whereas this function replaces such a + * sequence with the fallback string. + * + * If len is -1, strlen(text) is used to calculate the length. Do not pass -1 if text is supposed to contain \0 bytes, such as if from_encoding is a + * multi-byte encoding like UTF-16. + */ +gchar * +text_convert_invalid (const gchar* text, gssize len, GIConv converter, const gchar *fallback, gsize *len_out) { - unsigned int idx; - unsigned char *res, *output; - static const unsigned short lowtable[] = /* 74 byte table for 80-a4 */ - { - /* compressed utf-8 table: if the first byte's 0x20 bit is set, it - indicates a 2-byte utf-8 sequence, otherwise prepend a 0xe2. */ - 0x82ac, /* 80 Euro. CP1252 from here on... */ - 0xe281, /* 81 NA */ - 0x809a, /* 82 */ - 0xe692, /* 83 */ - 0x809e, /* 84 */ - 0x80a6, /* 85 */ - 0x80a0, /* 86 */ - 0x80a1, /* 87 */ - 0xeb86, /* 88 */ - 0x80b0, /* 89 */ - 0xe5a0, /* 8a */ - 0x80b9, /* 8b */ - 0xe592, /* 8c */ - 0xe28d, /* 8d NA */ - 0xe5bd, /* 8e */ - 0xe28f, /* 8f NA */ - 0xe290, /* 90 NA */ - 0x8098, /* 91 */ - 0x8099, /* 92 */ - 0x809c, /* 93 */ - 0x809d, /* 94 */ - 0x80a2, /* 95 */ - 0x8093, /* 96 */ - 0x8094, /* 97 */ - 0xeb9c, /* 98 */ - 0x84a2, /* 99 */ - 0xe5a1, /* 9a */ - 0x80ba, /* 9b */ - 0xe593, /* 9c */ - 0xe29d, /* 9d NA */ - 0xe5be, /* 9e */ - 0xe5b8, /* 9f */ - 0xe2a0, /* a0 */ - 0xe2a1, /* a1 */ - 0xe2a2, /* a2 */ - 0xe2a3, /* a3 */ - 0x82ac /* a4 ISO-8859-15 Euro. */ - }; + gchar *result_part; + gsize result_part_len; + const gchar *end; + gsize invalid_start_pos; + GString *result; + const gchar *current_start; if (len == -1) + { len = strlen (text); + } - /* worst case scenario: every byte turns into 3 bytes */ - res = output = g_malloc ((len * 3) + 1); - if (!output) - return NULL; + end = text + len; - while (len) + /* Find the first position of an invalid sequence. */ + result_part = g_convert_with_iconv (text, len, converter, &invalid_start_pos, &result_part_len, NULL); + if (result_part != NULL) { - if (G_LIKELY (*text < 0x80)) + /* All text converted successfully on the first try. Return it. */ + + if (len_out != NULL) { - *output = *text; /* ascii maps directly */ + *len_out = result_part_len; } - else if (*text <= 0xa4) /* 80-a4 use a lookup table */ + + return result_part; + } + + /* One or more invalid sequences exist that need to be replaced with the fallback. */ + + result = g_string_sized_new (len); + current_start = text; + + for (;;) + { + g_assert (current_start + invalid_start_pos < end); + + /* Convert everything before the position of the invalid sequence. It should be successful. */ + result_part = g_convert_with_iconv (current_start, invalid_start_pos, converter, &invalid_start_pos, &result_part_len, NULL); + g_assert (result_part != NULL); + g_string_append_len (result, result_part, result_part_len); + g_free (result_part); + + /* Append the fallback */ + g_string_append (result, fallback); + + /* Now try converting everything after the invalid sequence. */ + current_start += invalid_start_pos + 1; + + result_part = g_convert_with_iconv (current_start, end - current_start, converter, &invalid_start_pos, &result_part_len, NULL); + if (result_part != NULL) { - idx = *text - 0x80; - if (lowtable[idx] & 0x2000) - { - *output++ = (lowtable[idx] >> 8) & 0xdf; /* 2 byte utf-8 */ - *output = lowtable[idx] & 0xff; - } - else + /* The rest of the text converted successfully. Append it and return the whole converted text. */ + + g_string_append_len (result, result_part, result_part_len); + g_free (result_part); + + if (len_out != NULL) { - *output++ = 0xe2; /* 3 byte utf-8 */ - *output++ = (lowtable[idx] >> 8) & 0xff; - *output = lowtable[idx] & 0xff; + *len_out = result->len; } + + return g_string_free (result, FALSE); } - else if (*text < 0xc0) - { - *output++ = 0xc2; - *output = *text; - } - else - { - *output++ = 0xc3; - *output = *text - 0x40; - } - output++; - text++; - len--; - } - *output = 0; /* terminate */ - *bytes_written = output - res; - return res; + /* The rest of the text didn't convert successfully. invalid_start_pos has the position of the next invalid sequence. */ + } } -char * -text_validate (char **text, int *len) +/** + * Replaces any invalid UTF-8 in the given text with the unicode replacement character. + */ +gchar * +text_fixup_invalid_utf8 (const gchar* text, gssize len, gsize *len_out) { - char *utf; - gsize utf_len; - - /* valid utf8? */ - if (g_utf8_validate (*text, *len, 0)) - return NULL; - -#ifdef WIN32 - if (GetACP () == 1252) /* our routine is better than iconv's 1252 */ -#else - if (prefs.utf8_locale) -#endif - /* fallback to iso-8859-1 */ - utf = iso_8859_1_to_utf8 (*text, *len, &utf_len); - else + static GIConv utf8_fixup_converter = NULL; + if (utf8_fixup_converter == NULL) { - /* fallback to locale */ - utf = g_locale_to_utf8 (*text, *len, 0, &utf_len, NULL); - if (!utf) - utf = iso_8859_1_to_utf8 (*text, *len, &utf_len); + utf8_fixup_converter = g_iconv_open ("UTF-8", "UTF-8"); } - if (!utf) - { - *text = g_strdup ("%INVALID%"); - *len = 9; - } else - { - *text = utf; - *len = utf_len; - } - - return utf; + return text_convert_invalid (text, len, utf8_fixup_converter, unicode_fallback_string, len_out); } void PrintTextTimeStamp (session *sess, char *text, time_t timestamp) { - char *conv; - if (!sess) { if (!sess_list) @@ -902,22 +821,19 @@ PrintTextTimeStamp (session *sess, char *text, time_t timestamp) } /* make sure it's valid utf8 */ - if (text[0] == 0) + if (text[0] == '\0') { - text = "\n"; - conv = NULL; - } else + text = g_strdup ("\n"); + } + else { - int len = -1; - conv = text_validate ((char **)&text, &len); + text = text_fixup_invalid_utf8 (text, -1, NULL); } log_write (sess, text, timestamp); - scrollback_save (sess, text); + scrollback_save (sess, text, timestamp); fe_print_text (sess, text, timestamp, FALSE); - - if (conv) - g_free (conv); + g_free (text); } void @@ -1004,7 +920,7 @@ PrintTextTimeStampf (session *sess, time_t timestamp, const char *format, ...) Each XP_TE_* signal is hard coded to call text_emit which calls display_event which decodes the data - This means that this system *should be faster* than snprintf because + This means that this system *should be faster* than g_snprintf because it always 'knows' that format of the string (basically is preparses much of the work) @@ -1211,26 +1127,26 @@ static char * const pevt_chanrmlimit_help[] = { }; static char * const pevt_chandeop_help[] = { - N_("The nick of the person of did the deop'ing"), + N_("The nick of the person who did the deop'ing"), N_("The nick of the person who has been deop'ed"), }; static char * const pevt_chandehop_help[] = { - N_("The nick of the person of did the dehalfop'ing"), + N_("The nick of the person who did the dehalfop'ing"), N_("The nick of the person who has been dehalfop'ed"), }; static char * const pevt_chandevoice_help[] = { - N_("The nick of the person of did the devoice'ing"), + N_("The nick of the person who did the devoice'ing"), N_("The nick of the person who has been devoice'ed"), }; static char * const pevt_chanunban_help[] = { - N_("The nick of the person of did the unban'ing"), + N_("The nick of the person who did the unban'ing"), N_("The ban mask"), }; static char * const pevt_chanunquiet_help[] = { - N_("The nick of the person of did the unquiet'ing"), + N_("The nick of the person who did the unquiet'ing"), N_("The quiet mask"), }; @@ -1569,14 +1485,13 @@ pevent_load_defaults () for (i = 0; i < NUM_XP; i++) { - if (pntevts_text[i]) - free (pntevts_text[i]); + g_free (pntevts_text[i]); /* make-te.c sets this 128 flag (DON'T call gettext() flag) */ if (te[i].num_args & 128) - pntevts_text[i] = strdup (te[i].def); + pntevts_text[i] = g_strdup (te[i].def); else - pntevts_text[i] = strdup (_(te[i].def)); + pntevts_text[i] = g_strdup (_(te[i].def)); } } @@ -1588,19 +1503,18 @@ pevent_make_pntevts () for (i = 0; i < NUM_XP; i++) { - if (pntevts[i] != NULL) - free (pntevts[i]); + g_free (pntevts[i]); if (pevt_build_string (pntevts_text[i], &(pntevts[i]), &m) != 0) { - snprintf (out, sizeof (out), + g_snprintf (out, sizeof (out), _("Error parsing event %s.\nLoading default."), te[i].name); fe_message (out, FE_MSG_WARN); - free (pntevts_text[i]); + g_free (pntevts_text[i]); /* make-te.c sets this 128 flag (DON'T call gettext() flag) */ if (te[i].num_args & 128) - pntevts_text[i] = strdup (te[i].def); + pntevts_text[i] = g_strdup (te[i].def); else - pntevts_text[i] = strdup (_(te[i].def)); + pntevts_text[i] = g_strdup (_(te[i].def)); if (pevt_build_string (pntevts_text[i], &(pntevts[i]), &m) != 0) { fprintf (stderr, @@ -1622,22 +1536,17 @@ pevent_make_pntevts () static void pevent_trigger_load (int *i_penum, char **i_text, char **i_snd) { - int penum = *i_penum, len; + int penum = *i_penum; char *text = *i_text, *snd = *i_snd; if (penum != -1 && text != NULL) { - len = strlen (text) + 1; - if (pntevts_text[penum]) - free (pntevts_text[penum]); - pntevts_text[penum] = malloc (len); - memcpy (pntevts_text[penum], text, len); + g_free (pntevts_text[penum]); + pntevts_text[penum] = g_strdup (text); } - if (text) - free (text); - if (snd) - free (snd); + g_free (text); + g_free (snd); *i_text = NULL; *i_snd = NULL; *i_penum = 0; @@ -1690,7 +1599,7 @@ pevent_load (char *filename) close (fd); return 1; } - ibuf = malloc (st.st_size); + ibuf = g_malloc (st.st_size); read (fd, ibuf, st.st_size); close (fd); @@ -1706,8 +1615,6 @@ pevent_load (char *filename) continue; *ofs = 0; ofs++; - /*if (*ofs == 0) - continue;*/ if (strcmp (buf, "event_name") == 0) { @@ -1717,53 +1624,16 @@ pevent_load (char *filename) continue; } else if (strcmp (buf, "event_text") == 0) { - if (text) - free (text); - -#if 0 - /* This allows updating of old strings. We don't use new defaults - if the user has customized the strings (.e.g a text theme). - Hash of the old default is enough to identify and replace it. - This only works in English. */ - - switch (g_str_hash (ofs)) - { - case 0x526743a4: - /* %C08,02 Hostmask PRIV NOTI CHAN CTCP INVI UNIG %O */ - text = strdup (te[XP_TE_IGNOREHEADER].def); - break; - - case 0xe91bc9c2: - /* %C08,02 %O */ - text = strdup (te[XP_TE_IGNOREFOOTER].def); - break; - - case 0x1fbfdf22: - /* -%C10-%C11-%O$tDCC RECV: Cannot open $1 for writing - aborting. */ - text = strdup (te[XP_TE_DCCFILEERR].def); - break; - - default: - text = strdup (ofs); - } -#else - text = strdup (ofs); -#endif - - continue; - }/* else if (strcmp (buf, "event_sound") == 0) - { - if (snd) - free (snd); - snd = strdup (ofs); + g_free (text); + text = g_strdup (ofs); continue; - }*/ + } continue; } pevent_trigger_load (&penum, &text, &snd); - free (ibuf); + g_free (ibuf); return 0; } @@ -1777,13 +1647,13 @@ pevent_check_all_loaded () if (pntevts_text[i] == NULL) { /*printf ("%s\n", te[i].name); - snprintf(out, sizeof(out), "The data for event %s failed to load. Reverting to defaults.\nThis may be because a new version of HexChat is loading an old config file.\n\nCheck all print event texts are correct", evtnames[i]); + g_snprintf(out, sizeof(out), "The data for event %s failed to load. Reverting to defaults.\nThis may be because a new version of HexChat is loading an old config file.\n\nCheck all print event texts are correct", evtnames[i]); gtkutil_simpledialog(out); */ /* make-te.c sets this 128 flag (DON'T call gettext() flag) */ if (te[i].num_args & 128) - pntevts_text[i] = strdup (te[i].def); + pntevts_text[i] = g_strdup (te[i].def); else - pntevts_text[i] = strdup (_(te[i].def)); + pntevts_text[i] = g_strdup (_(te[i].def)); } } } @@ -1808,9 +1678,10 @@ load_text_events () #define ARG_FLAG(argn) (1 << (argn)) void -format_event (session *sess, int index, char **args, char *o, int sizeofo, unsigned int stripcolor_args) +format_event (session *sess, int index, char **args, char *o, gsize sizeofo, unsigned int stripcolor_args) { - int len, oi, ii, numargs; + int len, ii, numargs; + gsize oi; char *i, *ar, d, a, done_all = FALSE; i = pntevts[index]; @@ -1868,19 +1739,10 @@ format_event (session *sess, int index, char **args, char *o, int sizeofo, unsig done_all = TRUE; continue; case 3: -/* if (sess->type == SESS_DIALOG) - { - if (prefs.dialog_indent_nicks) - o[oi++] = '\t'; - else - o[oi++] = ' '; - } else - {*/ - if (prefs.hex_text_indent) - o[oi++] = '\t'; - else - o[oi++] = ' '; - /*}*/ + if (prefs.hex_text_indent) + o[oi++] = '\t'; + else + o[oi++] = ' '; break; } } @@ -1908,7 +1770,7 @@ pevt_build_string (const char *input, char **output, int *max_arg) int oi, ii, max = -1, len, x; len = strlen (input); - i = malloc (len + 1); + i = g_malloc (len + 1); memcpy (i, input, len + 1); check_special_chars (i, TRUE); @@ -1933,14 +1795,14 @@ pevt_build_string (const char *input, char **output, int *max_arg) } if (oi > 0) { - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; - s->data = malloc (oi + sizeof (int) + 1); + s->data = g_malloc (oi + sizeof (int) + 1); s->len = oi + sizeof (int) + 1; clen += oi + sizeof (int) + 1; s->data[0] = 0; @@ -1951,12 +1813,12 @@ pevt_build_string (const char *input, char **output, int *max_arg) if (ii == len) { fe_message ("String ends with a $", FE_MSG_WARN); - return 1; + goto err; } d = i[ii++]; if (d == 'a') - { /* Hex value */ - x = 0; + { + /* Hex value */ if (ii == len) goto a_len_error; d = i[ii++]; @@ -1977,24 +1839,24 @@ pevt_build_string (const char *input, char **output, int *max_arg) o[oi++] = x; continue; - a_len_error: + a_len_error: fe_message ("String ends in $a", FE_MSG_WARN); - return 1; - a_range_error: + goto err; + a_range_error: fe_message ("$a value is greater than 255", FE_MSG_WARN); - return 1; + goto err; } if (d == 't') { /* Tab - if tabnicks is set then write '\t' else ' ' */ - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; - s->data = malloc (1); + s->data = g_malloc (1); s->len = 1; clen += 1; s->data[0] = 3; @@ -2003,21 +1865,21 @@ pevt_build_string (const char *input, char **output, int *max_arg) } if (d < '1' || d > '9') { - snprintf (o, sizeof (o), "Error, invalid argument $%c\n", d); + g_snprintf (o, sizeof (o), "Error, invalid argument $%c\n", d); fe_message (o, FE_MSG_WARN); - return 1; + goto err; } d -= '0'; if (max < d) max = d; - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; - s->data = malloc (2); + s->data = g_malloc (2); s->len = 2; clen += 2; s->data[0] = 1; @@ -2025,14 +1887,14 @@ pevt_build_string (const char *input, char **output, int *max_arg) } if (oi > 0) { - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; - s->data = malloc (oi + sizeof (int) + 1); + s->data = g_malloc (oi + sizeof (int) + 1); s->len = oi + sizeof (int) + 1; clen += oi + sizeof (int) + 1; s->data[0] = 0; @@ -2040,39 +1902,54 @@ pevt_build_string (const char *input, char **output, int *max_arg) memcpy (&(s->data[1 + sizeof (int)]), o, oi); oi = 0; } - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; - last = s; s->next = NULL; - s->data = malloc (1); + s->data = g_malloc (1); s->len = 1; clen += 1; s->data[0] = 2; oi = 0; s = base; - obuf = malloc (clen); + obuf = g_malloc (clen); + while (s) { next = s->next; memcpy (&obuf[oi], s->data, s->len); oi += s->len; - free (s->data); - free (s); + g_free (s->data); + g_free (s); s = next; } - free (i); + g_free (i); if (max_arg) *max_arg = max; if (output) *output = obuf; + else + g_free (obuf); return 0; + +err: + while (s) + { + next = s->next; + g_free (s->data); + g_free (s); + s = next; + } + + g_free(i); + + return 1; } @@ -2107,7 +1984,7 @@ text_emit (int index, session *sess, char *a, char *b, char *c, char *d, if (prefs.hex_text_color_nicks && (index == XP_TE_CHANACTION || index == XP_TE_CHANMSG)) { - snprintf (tbuf, sizeof (tbuf), "\003%d%s", text_color_of (a), a); + g_snprintf (tbuf, sizeof (tbuf), "\003%d%s", text_color_of (a), a); a = tbuf; stripcolor_args &= ~ARG_FLAG(1); /* don't strip color from this argument */ } @@ -2239,9 +2116,9 @@ pevent_save (char *fn) for (i = 0; i < NUM_XP; i++) { - write (fd, buf, snprintf (buf, sizeof (buf), + write (fd, buf, g_snprintf (buf, sizeof (buf), "event_name=%s\n", te[i].name)); - write (fd, buf, snprintf (buf, sizeof (buf), + write (fd, buf, g_snprintf (buf, sizeof (buf), "event_text=%s\n\n", pntevts_text[i])); } @@ -2257,7 +2134,7 @@ char *sound_files[NUM_XP]; void sound_beep (session *sess) { - if (!prefs.hex_gui_focus_omitalerts || !fe_gui_info (sess, 0) == 1) + if (!prefs.hex_gui_focus_omitalerts || fe_gui_info (sess, 0) != 1) { if (sound_files[XP_TE_BEEP] && sound_files[XP_TE_BEEP][0]) /* user defined beep _file_ */ @@ -2283,12 +2160,8 @@ sound_play (const char *file, gboolean quiet) return; } -#ifdef WIN32 /* check for fullpath */ - if (file[0] == '\\' || (((file[0] >= 'A' && file[0] <= 'Z') || (file[0] >= 'a' && file[0] <= 'z')) && file[1] == ':')) -#else - if (file[0] == '/') -#endif + if (g_path_is_absolute (file)) { wavfile = g_strdup (file); } @@ -2363,9 +2236,8 @@ sound_load_event (char *evt, char *file) if (file[0] && pevent_find (evt, &i) != -1) { - if (sound_files[i]) - free (sound_files[i]); - sound_files[i] = strdup (file); + g_free (sound_files[i]); + sound_files[i] = g_strdup (file); } } @@ -2417,9 +2289,9 @@ sound_save () { if (sound_files[i] && sound_files[i][0]) { - write (fd, buf, snprintf (buf, sizeof (buf), + write (fd, buf, g_snprintf (buf, sizeof (buf), "event=%s\n", te[i].name)); - write (fd, buf, snprintf (buf, sizeof (buf), + write (fd, buf, g_snprintf (buf, sizeof (buf), "sound=%s\n\n", sound_files[i])); } } |