1 /* A little program to help create the en_GB.po file. */
2 
3 #include <stdio.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <time.h>
7 
8 #define true 1
9 #define false 0
10 
11 struct {
12     char *us, *gb;
13 } words[] = {
14     { "color", "colour" },
15 /*    { "program", "programme" }, */		/* programme except for computer programs */
16     { "CCW", "ACW" },	/* Counter/Anti Clockwise */
17     { "neighbor", "neighbour" },
18     { "Adobe now considers", "Adobe now consider" },
19     { "behavior", "behaviour" },
20     { "centered", "centred" },
21     { "center", "centre" },
22     { "dialog", "dialogue" },
23     { "license", "licence" },
24     { "argument", "arguement" },
25     { "delimiter", "delimiter" },	/* Otherwise the miter transform would lead to misspellings */
26     { "miter", "mitre" },
27     { "recognize", "recognise" },
28     { "realize", "realise" },
29 /* careful about meter/metre because parameter does not become parametre */
30     NULL
31 };
32 
33 /* If we were to call the following function strcasestr(), on some
34  * systems (PC-BSD 9.0 in particular) the confusion with the native
35  * strcasestr() causes compilation problems. */
my_strcasestr(const char * haystack,const char * needle)36 static char *my_strcasestr(const char *haystack, const char *needle) {
37     const char *npt, *hpt;
38     int hch, nch;
39 
40     for ( ; *haystack!='\0' ; ++haystack ) {
41 	for ( hpt = haystack, npt = needle; *npt!='\0'; ++hpt, ++npt ) {
42 	    hch = *hpt; nch = *npt;
43 	    if ( isupper(hch)) hch = tolower(hch);
44 	    if ( isupper(nch)) nch = tolower(nch);
45 	    if ( nch!=hch )
46 	break;
47 	}
48 	if ( *npt=='\0' )
49 return( (char *) haystack );
50     }
51 return( NULL );
52 }
53 
caserpl(char * to,int flen,char * rpl)54 static void caserpl(char *to,int flen, char *rpl) {
55     int i, ch=0, och;
56 
57     for ( i=0 ; i<flen; ++i ) {
58 	ch = *rpl++;
59 	if ( ch=='\0' )
60 return;
61 	if ( isupper(to[i]) && islower(ch) )
62 	    ch = toupper(ch);
63 	else if ( isupper(ch) && islower(to[i]) )
64 	    ch = tolower(ch);
65 	to[i] = ch;
66     }
67     och = ch;
68     while ( *rpl!='\0' ) {
69 	ch = *rpl++;
70 	if ( isupper(och) && islower(ch) )
71 	    ch = toupper(ch);
72 	else if ( isupper(ch) && islower(och) )
73 	    ch = tolower(ch);
74 	to[i++] = ch;
75     }
76 }
77 
replace(char * line,char * find,char * rpl)78 static void replace(char *line, char *find, char *rpl) {
79     char *pt=line, *mpt;
80     int flen = strlen(find), rlen = strlen(rpl);
81     int len = rlen - flen;
82 
83     while ( (pt = my_strcasestr(pt,find))!=NULL ) {
84 	if ( len>0 ) {
85 	    for ( mpt = line+strlen(line); mpt>=pt+flen; --mpt )
86 		mpt[len] = *mpt;
87 	    caserpl(pt,flen,rpl);
88 	} else if ( len<0 ) {
89 	    caserpl(pt,flen,rpl);
90 	    for ( mpt=pt+flen; *mpt; ++mpt )
91 		mpt[len] = *mpt;
92 	    mpt[len] = 0;
93 	} else
94 	    caserpl(pt,flen,rpl);
95 	pt += rlen;
96     }
97 }
98 
99 #define LINE_MAX	40
100 static char linebuffers[LINE_MAX][200];
101 
anyneedles(int start,int end)102 static int anyneedles(int start, int end) {
103     int l,i;
104 
105     for ( l=start; l<end; ++l ) {
106 	char *lpt = linebuffers[l], *pt;
107 	if ( l==start && (pt=strchr(lpt,'|'))!=NULL )
108 	    lpt = pt+1;
109 	for ( i=0; words[i].us!=NULL; ++i ) {
110 	    if ( my_strcasestr(lpt,words[i].us)!=NULL ) {
111 		if ( strcmp(words[i].us,words[i].gb)==0 )		/* The word delimiter is the same, but miter isn't. So we include delimiter first to make sure miter isn't found */
112 return( false );
113 		else
114 return( true );
115 	    }
116 	}
117     }
118 return( false );
119 }
120 
rplall(int l)121 static void rplall(int l) {
122     int i;
123 
124     for ( i=0; words[i].us!=NULL; ++i )
125 	replace( linebuffers[l], words[i].us, words[i].gb);
126 }
127 
main(int argc,char ** argv)128 int main(int argc, char **argv) {
129     time_t now;
130     struct tm *tm;
131     FILE *input, *output;
132     int i,l, start, end;
133     char *pt;
134 
135     input = fopen("FontForge.pot", "r");
136     if ( input==NULL ) {
137 	fprintf( stderr, "No pot file\n" );
138 return( 1 );
139     }
140     output = fopen("en_GB.po", "w");
141     if ( output==NULL ) {
142 	fprintf( stderr, "Can't create en_GB.po\n" );
143 	fclose( input );
144 return( 1 );
145     }
146 
147     time(&now);
148     tm = gmtime(&now);
149 
150     fprintf( output, "# (British) English User Interface strings for FontForge.\n" );
151     fprintf( output, "# Copyright (C) 2000-2006 by George Williams\n" );
152     fprintf( output, "# This file is distributed under the same license as the FontForge package.\n" );
153     fprintf( output, "# George Williams, <pfaedit@users.sourceforge.net>, %d.\n", tm->tm_year+1900 );
154     fprintf( output, "#\n" );
155     fprintf( output, "#, fuzzy\n" );
156     fprintf( output, "msgid \"\"\n" );
157     fprintf( output, "msgstr \"\"\n" );
158     fprintf( output, "\"Project-Id-Version: %4d%02d%02d\\n\"\n", tm->tm_year+1990, tm->tm_mon+1, tm->tm_mday );
159     fprintf( output, "\"POT-Creation-Date: 2006-05-07 20:02-0700\\n\"\n" );
160     fprintf( output, "\"PO-Revision-Date: %4d-%02d-%02d %02d:%02d-0800\\n\"\n",
161 	    tm->tm_year+1990, tm->tm_mon+1, tm->tm_mday,
162 	    tm->tm_hour, tm->tm_min );
163     fprintf( output, "\"Last-Translator: George Williams, <pfaedit@users.sourceforge.net>\\n\"\n" );
164     fprintf( output, "\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n" );
165     fprintf( output, "\"MIME-Version: 1.0\\n\"\n" );
166     fprintf( output, "\"Content-Type: text/plain; charset=UTF-8\\n\"\n" );
167     fprintf( output, "\"Content-Transfer-Encoding: 8bit\\n\"\n" );
168     fprintf( output, "\"Plural-Forms: nplurals=2; plural=n!=1\\n\"\n" );
169 
170     while ( fgets(linebuffers[0],sizeof(linebuffers[0]),input)!=NULL ) {
171 	if ( linebuffers[0][0]=='\n' )
172     break;
173     }
174 
175     while ( !feof(input)) {
176 	l=0;
177 	while ( l<LINE_MAX && fgets(linebuffers[l],sizeof(linebuffers[0]),input)!=NULL ) {
178 	    if ( linebuffers[l][0]=='\n' )
179 	break;
180 	    ++l;
181 	}
182 	if ( l==0 )
183     continue;
184 	if ( l==LINE_MAX ) {
185 	    fprintf( stderr, "Increase LINE_MAX. MSG:\n%s\n", linebuffers[0] );
186 	    fclose( output );
187 	    fclose( input );
188 return( 1 );
189 	}
190 	for ( i=0; i<l; ++i )
191 	    if ( strncmp(linebuffers[i],"msgid",5)==0 )
192 	break;
193 	if ( i==l ) {
194 	    for ( i=0; i<l; ++i )
195 		if ( linebuffers[l-1][0]!='#' )
196 	    break;
197 	    if ( i!=l )
198 		fprintf( stderr, "Didn't understand: %s\n", linebuffers[0] );
199 		/* But comments are ok */
200     continue;
201 	}
202 	start = i;
203 	for (    ; i<l; ++i )
204 	    if ( strncmp(linebuffers[i],"msgstr",6)==0 )
205 	break;
206 	if ( i==l ) {
207 	    fprintf( stderr, "Didn't understand (2): %s\n", linebuffers[0] );
208     continue;
209 	}
210 	end = i;
211 	if ( !anyneedles(start,end))
212     continue;
213 	fprintf( output, "\n" );
214 	for ( i=0; i<end; ++i )
215 	    fprintf( output, "%s", linebuffers[i] );
216 	replace(linebuffers[start],"msgid","msgstr");
217 	pt = strchr(linebuffers[start],'|');
218 	if ( pt!=NULL ) {
219 	    char *qpt = strchr(linebuffers[start],'"');
220 	    int j;
221 	    if ( qpt!=NULL ) {
222 		j=1;
223 		do {
224 		    qpt[j] = pt[j];
225 		    ++j;
226 		} while ( pt[j]!='\0' );
227 		qpt[j] = '\0';
228 	    }
229 	}
230 	for ( i=start; i<end; ++i ) {
231 	    rplall(i);
232 	    fprintf( output, "%s", linebuffers[i] );
233 	}
234     }
235 
236     fclose( output );
237     fclose( input );
238 return( 0 );
239 }
240