Skip to content

Instantly share code, notes, and snippets.

@pclouds
Created April 13, 2010 16:51
Show Gist options
  • Save pclouds/364823 to your computer and use it in GitHub Desktop.
Save pclouds/364823 to your computer and use it in GitHub Desktop.
#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>&lt;</tt>" : "<tt>&gt;</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&nbsp;</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