1#!/usr/bin/perl -w
2
3use strict;
4use File::Basename;
5
6my @locales;
7my $func_prefix = "hebcal_lookup_";
8
9foreach my $pofile (@ARGV) {
10    my $locale = basename($pofile, ".po");
11    my $outfile = "strings_$locale.gperf";
12
13    print STDERR "$pofile => $outfile\n";
14    open(IN, $pofile) || die "$pofile: $!";
15    open(OUT, ">$outfile") || die "$outfile: $!";
16    binmode(IN, ":utf8");
17    binmode(OUT, ":utf8");
18
19    print OUT '%delimiters=|', "\n";
20    print OUT '%define lookup-function-name ', $func_prefix, $locale, "\n";
21    print OUT '%struct-type
22%{
23#include <string.h>
24%}
25struct event_title { char *name; char *dest; };
26%%
27';
28
29    my $msgid;
30    while(<IN>) {
31        if (/^msgid\s+"(.*)"\s*$/) {
32            $msgid = $1;
33        } elsif (/^msgstr\s+"(.+)"\s*$/) {
34            my $msgstr = $1;
35            print OUT qq{$msgid|"$msgstr"\n};
36        }
37    }
38    close(IN);
39    close(OUT);
40
41    my $dest = "strings_$locale.c";
42    my $cmd = "gperf $outfile > $dest";
43    print STDERR "$cmd\n";
44    system($cmd);
45    push(@locales, $locale);
46}
47
48my $outfile = "translations.h";
49print STDERR "$outfile\n";
50open(OUT, ">$outfile") || die "$outfile: $!";
51print OUT <<EOF;
52/*
53 * DO NOT EDIT THIS FILE!
54 * Generated by $0
55 */
56#ifndef __HEBCAL_TRANSLATIONS__
57#define __HEBCAL_TRANSLATIONS__
58
59struct event_title { char *name; char *dest; };
60
61const char * lookup_translation(const char *s);
62
63typedef enum hebcal_lang_e {
64    HEBCAL_LANG_DEFAULT,
65EOF
66;
67
68foreach my $locale (@locales) {
69    print OUT "    HEBCAL_LANG_", uc($locale), ",\n";
70}
71
72print OUT <<EOF;
73    HEBCAL_LANG_UNDEFINED
74} hebcal_lang;
75
76void hebcal_set_language(hebcal_lang lang);
77
78hebcal_lang hebcal_get_language(const char *locale);
79
80#endif /* __HEBCAL_TRANSLATIONS__ */
81EOF
82;
83close(OUT);
84
85$outfile = "translations.c";
86print STDERR "$outfile\n";
87open(OUT, ">$outfile") || die "$outfile: $!";
88print OUT <<EOF;
89/*
90 * DO NOT EDIT THIS FILE!
91 * Generated by $0
92 */
93#include "translations.h"
94#include <string.h>
95
96EOF
97;
98
99foreach my $locale (@locales) {
100    print OUT "struct event_title * ", $func_prefix, $locale, "(const char *str, unsigned int len);\n";
101}
102
103print OUT <<EOF;
104
105hebcal_lang g_lang = HEBCAL_LANG_DEFAULT;
106
107void hebcal_set_language(hebcal_lang lang) {
108    g_lang = lang;
109}
110
111hebcal_lang hebcal_get_language(const char *locale) {
112    if (!locale || !locale[0]) {
113        return HEBCAL_LANG_DEFAULT;
114EOF
115;
116foreach my $locale (@locales) {
117    print OUT "    } else if (0 == strcmp(locale, \"", $locale, "\")) {\n";
118    print OUT "        return HEBCAL_LANG_", uc($locale), ";\n";
119}
120
121print OUT <<EOF;
122    } else {
123        return HEBCAL_LANG_UNDEFINED;
124    }
125}
126
127const char * lookup_translation(const char *src) {
128    struct event_title *et;
129    if (!src || !src[0]) {
130        return src;
131    }
132    switch (g_lang) {
133        case HEBCAL_LANG_DEFAULT:
134            return src;
135EOF
136;
137
138foreach my $locale (@locales) {
139    print OUT "        case HEBCAL_LANG_", uc($locale), ":\n";
140    print OUT "            et = ", $func_prefix, $locale, "(src, strlen(src));\n";
141    print OUT "            break;\n";
142}
143
144print OUT <<EOF;
145        case HEBCAL_LANG_UNDEFINED:
146        default:
147            return src;
148    }
149    if (et && et->dest && et->dest[0]) {
150        return et->dest;
151    }
152    return src;
153}
154EOF
155;
156
157close(OUT);
158exit(0);
159