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