1 /*
2 * $Id: arjdata.c,v 1.6 2004/04/17 11:44:46 andrew_belov Exp $
3 * ---------------------------------------------------------------------------
4 * User-modifyable resource information. It must be kept binding-independent.
5 *
6 */
7
8 #include <time.h>
9
10 #include "arj.h"
11
12 /* Tags */
13
14 #define TAG_CHAR '@'
15 #define TAG_SPECIAL_BEGIN '{'
16 #define TAG_SPECIAL_END '}'
17
18 /* Alignments */
19
20 #define ALIGN_NONE 0
21 #define ALIGN_RIGHT 1
22 #define ALIGN_CENTER 2
23
24 /* Resource list hash array. The syntax is: <tag> <substitution> */
25
26 static char *resources[][2]=
27 {
28 /* Version */
29 {
30 "VERSION",
31 #ifdef TILED
32 "2.78"
33 #else
34 "3.10"
35 #endif
36 },
37 /* ARJ Software, Inc. counterparts (note: always 4 chars, spaces allowed!) */
38 {
39 "COUNTERPARTS", "2.7x" /* The docs mention DOS */
40 },
41 /* Short product description */
42 {
43 "PRODUCT",
44 "ARJ"
45 #if TARGET==OS2
46 "/2"
47 #endif
48 #ifndef TILED
49 #if TARGET==OS2
50 "-"
51 #endif
52 "32"
53 #endif
54 },
55 /* Platform */
56 {
57 "PLATFORM",
58 #if TARGET==DOS
59 "DOS"
60 #elif TARGET==OS2
61 "OS/2"
62 #elif TARGET==WIN32
63 "Win32"
64 #elif TARGET==UNIX
65 #if defined(linux)
66 "Linux"
67 #elif defined(__FreeBSD__)
68 "FreeBSD"
69 #elif defined(SUNOS)
70 "SunOS"
71 #elif defined(__QNXNTO__)
72 "QNX"
73 #else
74 "UNIX"
75 #endif
76 #endif
77 },
78 /* Platform -- legal filename format */
79 {
80 "PLATFORM_FN",
81 #if TARGET==OS2
82 "OS2",
83 #elif TARGET==UNIX
84 "UNIX",
85 #else
86 "@PLATFORM",
87 #endif
88 },
89 /* Platform specification for FILE_ID.DIZ (appended to description) */
90 {
91 "PLATFORM_APPENDIX",
92 #if defined(linux)
93 "/Linux",
94 #elif defined(__FreeBSD__)
95 "/FreeBSD",
96 #elif defined(SUNOS)
97 "/SunOS",
98 #elif defined(__QNXNTO__)
99 "/QNX",
100 #elif TARGET==WIN32
101 "/Win32",
102 #else
103 "",
104 #endif
105 },
106 /* Long product description */
107 {
108 "PRODUCT_LONG",
109 #if TARGET==DOS
110 #if LOCALE==LANG_en
111 "ARJ version @VERSION Open-Source"
112 #elif LOCALE==LANG_ru
113 "ARJ, ����� @VERSION"
114 #endif
115 #else
116 #if LOCALE==LANG_en
117 "ARJ for @PLATFORM, version @VERSION"
118 #elif LOCALE==LANG_ru
119 "ARJ ��� @PLATFORM, ����� @VERSION"
120 #endif
121 #endif
122 },
123 /* Registration token */
124 {
125 "REGTYPE",
126 #ifdef TILED
127 "A2"
128 #else
129 "A3"
130 #endif
131 },
132 /* Extension of executables (for resources) */
133 {"EXE_EXT", EXE_EXTENSION},
134 /* Archive extension */
135 {"ARJ_EXT",
136 #if TARGET==DOS
137 ".ARJ" /* ASR 27/10/2000 -- for packaging
138 under OS/2 MDOS */
139 #else
140 ".arj"
141 #endif
142 },
143 /* Ending marker */
144 {NULL, NULL}
145 };
146
147 /* Returns year (for Q&D copyright formatting) */
148
cur_year()149 static int cur_year()
150 {
151 struct tm *stm;
152 time_t cur_unixtime;
153
154 cur_unixtime=time(NULL);
155 stm=localtime(&cur_unixtime);
156 return(stm->tm_year+1900);
157 }
158
159 /* Date formatter */
160
date_fmt(char * dest)161 void date_fmt(char *dest)
162 {
163 #if LOCALE==LANG_en
164 static char *mon[]={"January", "February", "March", "April", "May", "June",
165 "July", "August", "September", "October", "November",
166 "December"};
167 #elif LOCALE==LANG_fr
168 static char *mon[]={"janvier", "fevrier", "mars", "avril", "mai", "juin",
169 "juillet", "aout", "septembre", "octobre", "novembre",
170 "decembre"};
171 #elif LOCALE==LANG_de
172 static char *mon[]={"Januar", "Februar", "Maerz", "April", "Mai", "Juni",
173 "Juli", "August", "September", "Oktober", "November",
174 "Dezember"};
175 #elif LOCALE==LANG_ru
176 static char *mon[]={"ﭢ���", "䥢ࠫ�", "����", "��५�", "���", "���",
177 "���", "������", "ᥭ����", "������", "�����",
178 "�������"};
179 #endif
180 time_t cur_unixtime;
181 struct tm *stm;
182 #if LOCALE==LANG_en
183 char *enstr; /* -rd, -th, ... */
184 #endif
185
186 cur_unixtime=time(NULL);
187 stm=localtime(&cur_unixtime);
188 #if LOCALE==LANG_en
189 if(stm->tm_mday==1||stm->tm_mday==21||stm->tm_mday==31)
190 enstr="st";
191 else if(stm->tm_mday==2||stm->tm_mday==22)
192 enstr="nd";
193 else if(stm->tm_mday==3||stm->tm_mday==23)
194 enstr="rd";
195 else
196 enstr="th";
197 sprintf(dest, "%s %d%s, %d", mon[stm->tm_mon], stm->tm_mday, enstr, cur_year());
198 #elif LOCALE==LANG_fr
199 sprintf(dest, "%d %s %d", stm->tm_mday, mon[stm->tm_mon], cur_year());
200 #elif LOCALE==LANG_de
201 sprintf(dest, "%d %s %d", stm->tm_mday, mon[stm->tm_mon], cur_year());
202 #elif LOCALE==LANG_ru
203 sprintf(dest, "%d %s %d �.", stm->tm_mday, mon[stm->tm_mon], cur_year());
204 #endif
205 }
206
207 /* Context substitution routine */
208
expand_tags(char * str,int limit)209 char *expand_tags(char *str, int limit)
210 {
211 int i, j, sl;
212 int l, rl; /* Tag/substitution length */
213 int align_lmargin=0, align_rmargin=0;
214 int align_type=ALIGN_NONE;
215 char *p, *et;
216 int shift;
217 char date_stg[128];
218 int repl_len, repl_j;
219
220 sl=strlen(str);
221 p=str;
222 while(*p!='\0')
223 {
224 if(*p==TAG_CHAR)
225 {
226 if(*(p+1)==TAG_CHAR)
227 {
228 safe_strcpy(p, p+1);
229 p++;
230 }
231 else if(*(p+1)==TAG_SPECIAL_BEGIN&&(et=strchr(p+3, TAG_SPECIAL_END))!=NULL)
232 {
233 switch(*(p+2))
234 {
235 case 'd':
236 case 'y':
237 if(*(p+2)=='y')
238 sprintf(date_stg, "%u", cur_year());
239 else
240 date_fmt(date_stg);
241 rl=strlen(date_stg);
242 if(sl+rl<limit)
243 {
244 safe_strcpy(p+rl, p);
245 memcpy(p, date_stg, rl);
246 limit+=rl;
247 p+=rl;
248 et+=rl;
249 }
250 break;
251 case 'r':
252 align_type=ALIGN_RIGHT;
253 align_lmargin=p-str;
254 align_rmargin=atoi(p+3);
255 break;
256 case 'c':
257 align_type=ALIGN_CENTER;
258 align_lmargin=p-str;
259 align_rmargin=atoi(p+3);
260 break;
261 case '_':
262 i=p-str;
263 if(align_type==ALIGN_RIGHT)
264 shift=align_rmargin-i; /* The margin is 1-relative! */
265 else if(align_type==ALIGN_CENTER)
266 shift=align_rmargin-(i+align_lmargin)/2-1;
267 if(align_type!=ALIGN_NONE&&shift>0&&sl+shift<limit)
268 {
269 sl+=shift;
270 safe_strcpy(str+align_lmargin+shift, str+align_lmargin);
271 memset(str+align_lmargin, 32, shift);
272 p+=shift;
273 et+=shift;
274 }
275 align_type=ALIGN_NONE;
276 align_rmargin=0;
277 break;
278 }
279 sl-=(et-p);
280 safe_strcpy(p, et+1);
281 }
282 else
283 {
284 repl_len=0;
285 for(j=0; resources[j][0]!=NULL; j++)
286 {
287 l=strlen(resources[j][0]);
288 if(!memcmp(p+1, resources[j][0], l))
289 {
290 /* Try to find the longest possible match */
291 if(l>repl_len)
292 {
293 repl_j=j;
294 repl_len=l;
295 }
296 }
297 }
298 if(repl_len==0)
299 {
300 printf("ARJDATA: unknown tag <%s>\n", p);
301 p++;
302 }
303 else
304 {
305 rl=strlen(resources[repl_j][1]);
306 /* Is it OK to stick the substitution in? */
307 if((sl+=rl)>=limit)
308 return(NULL);
309 safe_strcpy(p+rl, p+repl_len+1);
310 memcpy(p, resources[repl_j][1], rl);
311 }
312 }
313 }
314 else
315 p++;
316 }
317 return(str);
318 }
319