Created
April 13, 2010 16:51
-
-
Save pclouds/364823 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <gettext-po.h> | |
#include <unistd.h> | |
static void | |
err(int severity, | |
po_message_t msg, const char *filename, size_t lineno, | |
size_t column, int multiline_p, const char *msgstr) | |
{ | |
} | |
static void | |
err2(int severity, | |
po_message_t msg1, const char *filename1, size_t lineno1, | |
size_t column1, int multiline_p1, const char *msgstr1, | |
po_message_t msg2, const char *filename2, size_t lineno2, | |
size_t column2, int multiline_p2, const char *msgstr2) | |
{ | |
} | |
struct msg_pair { | |
struct msg_pair *next; | |
char *id; | |
char *str; | |
}; | |
#define SIZE 251 | |
struct msg_pair *tab[SIZE]; | |
static int | |
idx(const char *id) | |
{ | |
int i, len = strlen(id); | |
unsigned int c = 0; | |
for (i = 0; i < len; i++) | |
c += (unsigned char)id[i]; | |
return c % SIZE; | |
} | |
static int is_html; | |
static const char * | |
quote(const char *s, | |
const char *color_start, | |
const char *color_stop, | |
const char *color_start2, | |
const char *color_stop2) | |
{ | |
#define WRAP 100 | |
static int next = 0; | |
static char *buf[5]; | |
int c = 0, i, len = strlen(s), wrap; | |
char *sss; | |
int color_start_len = strlen(color_start); | |
int color_start2_len = strlen(color_start2); | |
int color_stop_len = strlen(color_stop); | |
int color_stop2_len = strlen(color_stop2); | |
if (buf[next]) | |
free(buf[next]); | |
c += color_start_len; | |
for (wrap = i = 0; i < len; i++) { | |
if (s[i] == '\n' || s[i] == '\t') { | |
c += color_stop_len + color_start2_len + color_stop2_len + color_start_len; | |
c++; | |
} | |
if (strchr("<>", s[i])) | |
c += 4+4+5; | |
if (is_html) | |
continue; | |
if (i && (i % WRAP) == 0) | |
wrap = 1; | |
if (wrap && s[i] == ' ') { /* safe point */ | |
c += 9 + color_start_len + color_stop_len; | |
wrap = 0; | |
} | |
} | |
c+= color_stop_len; | |
buf[next] = sss = malloc(len+c+1); | |
strcpy(sss, color_start); | |
sss += color_start_len; | |
for (i = wrap = 0; i < len; i++) { | |
if (s[i] == '\n' || s[i] == '\t') { | |
sprintf(sss, "%s%s", color_stop, color_start2); | |
sss += color_start2_len + color_stop_len; | |
*sss++ = '\\'; | |
*sss++ = s[i] == '\n' ? 'n' : 't'; | |
sprintf(sss, "%s%s", color_stop2, color_start); | |
sss += color_start_len + color_stop2_len; | |
} | |
else if (strchr("<>", s[i])) { | |
strcpy(sss, s[i] == '<' ? "<tt><</tt>" : "<tt>></tt>"); | |
sss += 4+4+5; | |
} | |
else | |
*sss++ = s[i]; | |
if (is_html) | |
continue; | |
if (i && (i % WRAP) == 0) | |
wrap = 1; | |
if (wrap && s[i] == ' ') { | |
sprintf(sss, "%s\n %s", color_stop, color_start); | |
sss += 9 + color_start_len + color_stop_len; | |
wrap = 0; | |
} | |
} | |
strcpy(sss, color_stop); | |
sss = buf[next]; | |
next = (next+1) % 5; | |
return sss; | |
} | |
int main(int argc, char **argv) | |
{ | |
struct po_xerror_handler h; | |
po_file_t base, new; | |
po_message_iterator_t iter; | |
po_message_t msg; | |
int is_tty = isatty(1); | |
int nr; | |
argv++; | |
if (!strcmp(*argv, "-c")) { | |
is_tty = 1; | |
argv++; | |
} | |
if (!strcmp(*argv, "-h")) { | |
is_tty = 0; | |
is_html = 1; | |
argv++; | |
} | |
h.xerror = err; | |
h.xerror2 = err2; | |
base = po_file_read(*argv++, &h); | |
new = po_file_read(*argv++, &h); | |
iter = po_message_iterator(base, NULL); | |
while ((msg = po_next_message(iter)) != NULL) { | |
struct msg_pair *mp; | |
int i; | |
mp = malloc(sizeof(*mp)); | |
mp->id = strdup(po_message_msgid(msg)); | |
mp->str = strdup(po_message_msgstr(msg)); | |
i = idx(mp->id); | |
mp->next = tab[i]; | |
tab[i] = mp; | |
} | |
iter = po_message_iterator(new, NULL); | |
nr = 0; | |
if (is_html) | |
printf("<html>" | |
"<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/></head>" | |
"<body style=\"font: 12px/1.5 verdana, arial, helvetica, sans-serif;\"><table>\n"); | |
while ((msg = po_next_message(iter)) != NULL) { | |
const char *id = po_message_msgid(msg); | |
const char *str = po_message_msgstr(msg); | |
int i = idx(id); | |
struct msg_pair *mp = tab[i]; | |
nr++; | |
if (!*id) | |
continue; | |
while (mp && strcmp(mp->id, id)) | |
mp = mp->next; | |
if (mp && !strcmp(mp->str, str)) | |
continue; | |
if (is_html) { | |
static int colored = 0; | |
printf("<tr%s>" | |
"<td valign=\"top\">%5d </td>" | |
"<td>%s</td>" | |
"<td>%s</td>" | |
"</tr>\n", | |
colored ? " style=\"background: #e0e0e0\"" : "", | |
nr, | |
quote(id, "", "", "<tt>", "</tt>"), | |
!strcmp(id, str) ? | |
quote(str, "", "", "<tt>", "</tt>") : | |
quote(str, "", "", "<tt>", "</tt>")); | |
colored = !colored; | |
continue; | |
} | |
#define COLOR(x) (is_tty ? (x) : "") | |
printf("%5d < %s\n", nr, | |
quote(id, "", "", | |
COLOR("\033[31m"), COLOR("\033[m"))); | |
printf("%5d > %s\n\n", nr, | |
quote(str, | |
!strcmp(id, str) ? COLOR("\033[32m") : "", | |
!strcmp(id, str) ? COLOR("\033[m") : "", | |
COLOR("\033[31m"), COLOR("\033[m"))); | |
} | |
if (is_html) | |
printf("</table></body></html>\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment