Subversion Repositories SvarDOS

Rev

Rev 588 | Rev 592 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 588 Rev 591
1
/*
1
/*
2
 * Locales configuration for SvarDOS
2
 * Locales configuration for SvarDOS
3
 *
3
 *
4
 * Copyright (C) Mateusz Viste 2015-2022
4
 * Copyright (C) Mateusz Viste 2015-2022
5
 *
5
 *
6
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are met:
7
 * modification, are permitted provided that the following conditions are met:
8
 *
8
 *
9
 * 1. Redistributions of source code must retain the above copyright notice,
9
 * 1. Redistributions of source code must retain the above copyright notice,
10
 *    this list of conditions and the following disclaimer.
10
 *    this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
13
 *    documentation and/or other materials provided with the distribution.
14
 */
14
 */
15
 
15
 
16
#include <stdio.h>
16
#include <stdio.h>
17
#include <stdlib.h> /* atoi() */
17
#include <stdlib.h> /* atoi() */
18
#include <string.h> /* strchr */
18
#include <string.h> /* strchr */
19
 
19
 
20
#include "country.h"
20
#include "country.h"
21
 
21
 
22
#define PVER "0.90"
22
#define PVER "20220202"
23
#define PDATE "2015-2022"
23
#define PDATE "2015-2022"
24
 
24
 
25
 
25
 
26
static void about(void) {
26
static void about(void) {
27
  puts("localcfg v" PVER " - locales configuration for DOS\n"
27
  puts("localcfg ver " PVER " - locales configuration for DOS\n"
28
       "Copyright (C) Mateusz Viste 2015 / http://localcfg.sourceforge.net\n"
28
       "Copyright (C) Mateusz Viste " PDATE "\n"
29
       "\n"
29
       "\n"
30
       "localcfg creates a custom COUNTRY.SYS-like file matching your preferences.\n"
30
       "localcfg creates a custom COUNTRY.SYS-like file matching your preferences.\n"
31
       "\n"
31
       "\n"
32
       "usage: localcfg myprefs.sys [options]\n"
32
       "usage: localcfg myprefs.sys [options]\n"
33
       "\n"
33
       "\n"
34
       "options allow to configure country locales to your likening, as follows:\n"
34
       "options allow to configure country locales to your likening, as follows:\n"
35
       "  /country:XX indicates your country code is XX (1 for USA, 33 for France, etc)\n"
35
       "  /country:XX indicates your country code is XX (1 for USA, 33 for France, etc)\n"
36
       "  /cp:XXX     adapts country data for codepage XXX (example: '437')\n"
36
       "  /cp:XXX     adapts country data for codepage XXX (example: '437')\n"
37
       "  /decim:X    reconfigures the decimal symbol to be 'X'");
37
       "  /decim:X    reconfigures the decimal symbol to be 'X'");
38
  puts("  /thous:X    reconfigures the thousands symbol to be 'X'\n"
38
  puts("  /thous:X    reconfigures the thousands symbol to be 'X'\n"
39
       "  /datesep:X  sets the date separator to 'X' (for example '/')\n"
39
       "  /datesep:X  sets the date separator to 'X' (for example '/')\n"
40
       "  /datefmt:X  sets the date format, can be: MDY, DMY or YMD\n"
40
       "  /datefmt:X  sets the date format, can be: MDY, DMY or YMD\n"
41
       "  /timesep:X  sets the time separator to 'X' (for example ':')\n"
41
       "  /timesep:X  sets the time separator to 'X' (for example ':')\n"
42
       "  /timefmt:X  sets the time format: 0=12h with AM/PM or 1=24h\n"
42
       "  /timefmt:X  sets the time format: 0=12h with AM/PM or 1=24h\n"
43
       "  /curr:XXX   sets the currency to XXX (a string of 1 to 4 characters)\n"
43
       "  /curr:XXX   sets the currency to XXX (a string of 1 to 4 characters)\n"
44
       "  /currpos:X  sets the currency symbol position to X, where X is either");
44
       "  /currpos:X  sets the currency symbol position to X, where X is either");
45
  puts("              0=currency precedes the value, 1=currency follows the value and\n"
45
  puts("              0=currency precedes the value, 1=currency follows the value and\n"
46
       "              2=currency replaces the decimal sign\n"
46
       "              2=currency replaces the decimal sign\n"
47
       "  /currspc:X  space between the currency and the value (0=no, 1=yes)\n"
47
       "  /currspc:X  space between the currency and the value (0=no, 1=yes)\n"
48
       "  /currprec:X currency's precision (number of decimal digits, 0..9)\n"
48
       "  /currprec:X currency's precision (number of decimal digits, 0..9)\n"
49
       "  /yesno:XY   sets the 'Yes/No' letter to XY (default: YN)\n"
49
       "  /yesno:XY   sets the 'Yes/No' letter to XY (default: YN)\n"
50
      );
50
      );
51
}
51
}
52
 
52
 
53
 
53
 
54
static char *datestring(struct country *c) {
54
static char *datestring(struct country *c) {
55
  static char result[16];
55
  static char result[16];
56
  switch (c->datefmt) {
56
  switch (c->CTYINFO.datefmt) {
57
    case COUNTRY_DATE_MDY:
57
    case COUNTRY_DATE_MDY:
58
      sprintf(result, "12%c31%c1990", c->datesep, c->datesep);
58
      sprintf(result, "12%c31%c1990", c->CTYINFO.datesep[0], c->CTYINFO.datesep[0]);
59
      break;
59
      break;
60
    case COUNTRY_DATE_DMY:
60
    case COUNTRY_DATE_DMY:
61
      sprintf(result, "31%c12%c1990", c->datesep, c->datesep);
61
      sprintf(result, "31%c12%c1990", c->CTYINFO.datesep[0], c->CTYINFO.datesep[0]);
62
      break;
62
      break;
63
    case COUNTRY_DATE_YMD:
63
    case COUNTRY_DATE_YMD:
64
    default:
64
    default:
65
      sprintf(result, "1990%c12%c31", c->datesep, c->datesep);
65
      sprintf(result, "1990%c12%c31", c->CTYINFO.datesep[0], c->CTYINFO.datesep[0]);
66
      break;
66
      break;
67
  }
67
  }
68
  return(result);
68
  return(result);
69
}
69
}
70
 
70
 
71
 
71
 
72
static char *timestring(struct country *c) {
72
static char *timestring(struct country *c) {
73
  static char result[16];
73
  static char result[16];
74
  if (c->timefmt == COUNTRY_TIME12) {
74
  if (c->CTYINFO.timefmt == COUNTRY_TIME12) {
75
    sprintf(result, "11%c59%c59 PM", c->timesep, c->timesep);
75
    sprintf(result, "11%c59%c59 PM", c->CTYINFO.timesep[0], c->CTYINFO.timesep[0]);
76
  } else {
76
  } else {
77
    sprintf(result, "23%c59%c59", c->timesep, c->timesep);
77
    sprintf(result, "23%c59%c59", c->CTYINFO.timesep[0], c->CTYINFO.timesep[0]);
78
  }
78
  }
79
  return(result);
79
  return(result);
80
}
80
}
81
 
81
 
82
 
82
 
83
static char *currencystring(struct country *c) {
83
static char *currencystring(struct country *c) {
84
  static char result[16];
84
  static char result[16];
85
  char decimalpart[16];
85
  char decimalpart[16];
86
  char space[2] = {0, 0};
86
  char space[2] = {0, 0};
87
  char decsym[8];
87
  char decsym[8];
88
  char cursym[8];
88
  char cursym[8];
89
  decimalpart[0] = '1';
89
  decimalpart[0] = '1';
90
  decimalpart[1] = '2';
90
  decimalpart[1] = '2';
91
  decimalpart[2] = '3';
91
  decimalpart[2] = '3';
92
  decimalpart[3] = '4';
92
  decimalpart[3] = '4';
93
  decimalpart[4] = '5';
93
  decimalpart[4] = '5';
94
  decimalpart[5] = '6';
94
  decimalpart[5] = '6';
95
  decimalpart[6] = '7';
95
  decimalpart[6] = '7';
96
  decimalpart[7] = '8';
96
  decimalpart[7] = '8';
97
  decimalpart[8] = '9';
97
  decimalpart[8] = '9';
98
  decimalpart[9] = 0;
98
  decimalpart[9] = 0;
99
  /* prepare the decimal string first */
99
  /* prepare the decimal string first */
100
  if (c->currencyprec < 9) {
100
  if (c->CTYINFO.currprec < 9) {
101
    decimalpart[c->currencyprec] = 0;
101
    decimalpart[c->CTYINFO.currprec] = 0;
102
  }
102
  }
103
  /* prepare the currency space string */
103
  /* prepare the currency space string */
104
  if (c->currencyspace != 0) {
104
  if (c->CTYINFO.currspace != 0) {
105
    space[0] = ' ';
105
    space[0] = ' ';
106
  }
106
  }
107
  /* prepare the currency and decimal symbols */
107
  /* prepare the currency and decimal symbols */
108
  if (c->currencydecsym != 0) { /* currency replaces the decimal point */
108
  if (c->CTYINFO.currdecsym != 0) { /* currency replaces the decimal point */
109
    sprintf(decsym, "%s", c->currency);
109
    sprintf(decsym, "%s", c->CTYINFO.currsym);
110
    cursym[0] = 0;
110
    cursym[0] = 0;
111
  } else {
111
  } else {
112
    sprintf(decsym, "%c", c->decimal);
112
    sprintf(decsym, "%c", c->CTYINFO.decimal[0]);
113
    sprintf(cursym, "%s", c->currency);
113
    sprintf(cursym, "%s", c->CTYINFO.currsym);
114
  }
114
  }
115
  if (c->currencyprec == 0) decsym[0] = 0;
115
  if (c->CTYINFO.currprec == 0) decsym[0] = 0;
116
  /* compute the final string */
116
  /* compute the final string */
117
  if (c->currencypos == 0) { /* currency precedes value */
117
  if (c->CTYINFO.currpos == 0) { /* currency precedes value */
118
    sprintf(result, "%s%s99%s%s", cursym, space, decsym, decimalpart);
118
    sprintf(result, "%s%s99%s%s", cursym, space, decsym, decimalpart);
119
  } else { /* currency follows value or replaces decimal symbol */
119
  } else { /* currency follows value or replaces decimal symbol */
120
    sprintf(result, "99%s%s%s%s", decsym, decimalpart, space, cursym);
120
    sprintf(result, "99%s%s%s%s", decsym, decimalpart, space, cursym);
121
  }
121
  }
122
  return(result);
122
  return(result);
123
}
123
}
124
 
124
 
125
 
125
 
126
/* checks if str starts with prefix. returns 0 if so, non-zero otherwise. */
126
/* checks if str starts with prefix. returns 0 if so, non-zero otherwise. */
127
static int stringstartswith(char *str, char *prefix) {
127
static int stringstartswith(char *str, char *prefix) {
128
  for (;;) {
128
  for (;;) {
129
    /* end of prefix means success */
129
    /* end of prefix means success */
130
    if (*prefix == 0) return(0);
130
    if (*prefix == 0) return(0);
131
    /* otherwise there is no match */
131
    /* otherwise there is no match */
132
    if (*str != *prefix) return(-1);
132
    if (*str != *prefix) return(-1);
133
    /* if match good so far, look at next char */
133
    /* if match good so far, look at next char */
134
    str += 1;
134
    str += 1;
135
    prefix += 1;
135
    prefix += 1;
136
  }
136
  }
137
}
137
}
138
 
138
 
139
 
139
 
140
/* processes an argument. returns 0 on success, non-zero otherwise. */
140
/* processes an argument. returns 0 on success, non-zero otherwise. */
141
static int processarg(char *arg, struct country *c) {
141
static int processarg(char *arg, struct country *c) {
142
  char *value;
142
  char *value;
143
  int intvalue;
143
  int intvalue;
144
  /* an option must start with a '/' */
144
  /* an option must start with a '/' */
145
  if (arg[0] != '/') return(-1);
145
  if (arg[0] != '/') return(-1);
146
  arg += 1; /* skip the slash */
146
  arg += 1; /* skip the slash */
147
  /* find where the value starts */
147
  /* find where the value starts */
148
  value = strchr(arg, ':');
148
  value = strchr(arg, ':');
149
  /* if no value present, fail */
149
  /* if no value present, fail */
150
  if (value == NULL) return(-2);
150
  if (value == NULL) return(-2);
151
  value += 1;
151
  value += 1;
152
  if (*value == 0) return(-3);
152
  if (*value == 0) return(-3);
153
  /* interpret the option now */
153
  /* interpret the option now */
154
  if (stringstartswith(arg, "country:") == 0) {
154
  if (stringstartswith(arg, "country:") == 0) {
155
    intvalue = atoi(value);
155
    intvalue = atoi(value);
156
    if ((intvalue > 0) && (intvalue < 1000)) {
156
    if ((intvalue > 0) && (intvalue < 1000)) {
157
      c->id = intvalue;
157
      c->CTYINFO.id = intvalue;
158
      return(0);
158
      return(0);
159
    }
159
    }
160
  } else if (stringstartswith(arg, "cp:") == 0) {
160
  } else if (stringstartswith(arg, "cp:") == 0) {
161
    intvalue = atoi(value);
161
    intvalue = atoi(value);
162
    if ((intvalue > 0) && (intvalue < 1000)) {
162
    if ((intvalue > 0) && (intvalue < 1000)) {
163
      c->codepage = intvalue;
163
      c->CTYINFO.codepage = intvalue;
164
      return(0);
164
      return(0);
165
    }
165
    }
166
  } else if (stringstartswith(arg, "decim:") == 0) {
166
  } else if (stringstartswith(arg, "decim:") == 0) {
167
    if (value[1] == 0) { /* value must be exactly one character */
167
    if (value[1] == 0) { /* value must be exactly one character */
168
      c->decimal = *value;
168
      c->CTYINFO.decimal[0] = *value;
169
      return(0);
169
      return(0);
170
    }
170
    }
171
  } else if (stringstartswith(arg, "thous:") == 0) {
171
  } else if (stringstartswith(arg, "thous:") == 0) {
172
    if (value[1] == 0) { /* value must be exactly one character */
172
    if (value[1] == 0) { /* value must be exactly one character */
173
      c->thousands = *value;
173
      c->CTYINFO.thousands[0] = *value;
174
      return(0);
174
      return(0);
175
    }
175
    }
176
  } else if (stringstartswith(arg, "datesep:") == 0) {
176
  } else if (stringstartswith(arg, "datesep:") == 0) {
177
    if (value[1] == 0) { /* value must be exactly one character */
177
    if (value[1] == 0) { /* value must be exactly one character */
178
      c->datesep = *value;
178
      c->CTYINFO.datesep[0] = *value;
179
      return(0);
179
      return(0);
180
    }
180
    }
181
  } else if (stringstartswith(arg, "timesep:") == 0) {
181
  } else if (stringstartswith(arg, "timesep:") == 0) {
182
    if (value[1] == 0) { /* value must be exactly one character */
182
    if (value[1] == 0) { /* value must be exactly one character */
183
      c->timesep = *value;
183
      c->CTYINFO.timesep[0] = *value;
184
      return(0);
184
      return(0);
185
    }
185
    }
186
  } else if (stringstartswith(arg, "datefmt:") == 0) {
186
  } else if (stringstartswith(arg, "datefmt:") == 0) {
187
    if (strcmp(value, "MDY") == 0) {
187
    if (strcmp(value, "MDY") == 0) {
188
      c->datefmt = COUNTRY_DATE_MDY;
188
      c->CTYINFO.datefmt = COUNTRY_DATE_MDY;
189
      return(0);
189
      return(0);
190
    } else if (strcmp(value, "DMY") == 0) {
190
    } else if (strcmp(value, "DMY") == 0) {
191
      c->datefmt = COUNTRY_DATE_DMY;
191
      c->CTYINFO.datefmt = COUNTRY_DATE_DMY;
192
      return(0);
192
      return(0);
193
    } else if (strcmp(value, "YMD") == 0) {
193
    } else if (strcmp(value, "YMD") == 0) {
194
      c->datefmt = COUNTRY_DATE_YMD;
194
      c->CTYINFO.datefmt = COUNTRY_DATE_YMD;
195
      return(0);
195
      return(0);
196
    }
196
    }
197
  } else if (stringstartswith(arg, "timefmt:") == 0) {
197
  } else if (stringstartswith(arg, "timefmt:") == 0) {
198
    if (value[1] == 0) {
198
    if (value[1] == 0) {
199
      if ((value[0] >= '0') && (value[0] <= '1')) {
199
      if ((value[0] >= '0') && (value[0] <= '1')) {
200
        c->timefmt = value[0] - '0';
200
        c->CTYINFO.timefmt = value[0] - '0';
201
        return(0);
201
        return(0);
202
      }
202
      }
203
    }
203
    }
204
  } else if (stringstartswith(arg, "curr:") == 0) {
204
  } else if (stringstartswith(arg, "curr:") == 0) {
205
    if (strlen(value) <= 4) {
205
    if (strlen(value) <= 4) {
206
      strcpy(c->currency, value);
206
      strcpy(c->CTYINFO.currsym, value);
207
      return(0);
207
      return(0);
208
    }
208
    }
209
  } else if (stringstartswith(arg, "currpos:") == 0) {
209
  } else if (stringstartswith(arg, "currpos:") == 0) {
210
    if (value[1] == 0) {
210
    if (value[1] == 0) {
211
      if (value[0] == '0') {
211
      if (value[0] == '0') {
212
        c->currencypos = 0;
212
        c->CTYINFO.currpos = 0;
213
        return(0);
213
        return(0);
214
      } else if (value[0] == '1') {
214
      } else if (value[0] == '1') {
215
        c->currencypos = 1;
215
        c->CTYINFO.currpos = 1;
216
        return(0);
216
        return(0);
217
      } else if (value[0] == '2') {
217
      } else if (value[0] == '2') {
218
        c->currencypos = 0;
218
        c->CTYINFO.currpos = 0;
219
        c->currencydecsym = 1;
219
        c->CTYINFO.currdecsym = 1;
220
        return(0);
220
        return(0);
221
      }
221
      }
222
    }
222
    }
223
  } else if (stringstartswith(arg, "currspc:") == 0) {
223
  } else if (stringstartswith(arg, "currspc:") == 0) {
224
    if (value[1] == 0) {
224
    if (value[1] == 0) {
225
      if ((value[0] >= '0') && (value[0] <= '1')) {
225
      if ((value[0] >= '0') && (value[0] <= '1')) {
226
        c->currencyspace = value[0] - '0';
226
        c->CTYINFO.currspace = value[0] - '0';
227
        return(0);
227
        return(0);
228
      }
228
      }
229
    }
229
    }
230
  } else if (stringstartswith(arg, "currprec:") == 0) {
230
  } else if (stringstartswith(arg, "currprec:") == 0) {
231
    if (value[1] == 0) {
231
    if (value[1] == 0) {
232
      if ((value[0] >= '0') && (value[0] <= '9')) {
232
      if ((value[0] >= '0') && (value[0] <= '9')) {
233
        c->currencyprec = value[0] - '0';
233
        c->CTYINFO.currprec = value[0] - '0';
234
        return(0);
234
        return(0);
235
      }
235
      }
236
    }
236
    }
237
  } else if (stringstartswith(arg, "yesno:") == 0) {
237
  } else if (stringstartswith(arg, "yesno:") == 0) {
238
    /* string must be exactly 2 characters long */
238
    /* string must be exactly 2 characters long */
239
    if ((value[0] != 0) && (value[1] != 0) && (value[2] == 0)) {
239
    if ((value[0] != 0) && (value[1] != 0) && (value[2] == 0)) {
240
      c->yes = value[0];
240
      c->YESNO.yes[0] = value[0];
241
      c->no = value[1];
241
      c->YESNO.no[0] = value[1];
242
      return(0);
242
      return(0);
243
    }
243
    }
244
  }
244
  }
245
  /* if I'm here, something went wrong */
245
  /* if I'm here, something went wrong */
246
  return(-4);
246
  return(-4);
247
}
247
}
248
 
248
 
249
 
249
 
250
/* converts a path to its canonic representation, returns 0 on success
250
/* converts a path to its canonic representation, returns 0 on success
251
 * or DOS err on failure (invalid drive) */
251
 * or DOS err on failure (invalid drive) */
252
static unsigned short file_truename(const char *dst, char *src) {
252
static unsigned short file_truename(const char *dst, char *src) {
253
  unsigned short res = 0;
253
  unsigned short res = 0;
254
  _asm {
254
  _asm {
255
    push es
255
    push es
256
    mov ah, 0x60  /* query truename, DS:SI=src, ES:DI=dst */
256
    mov ah, 0x60  /* query truename, DS:SI=src, ES:DI=dst */
257
    push ds
257
    push ds
258
    pop es
258
    pop es
259
    mov si, src
259
    mov si, src
260
    mov di, dst
260
    mov di, dst
261
    int 0x21
261
    int 0x21
262
    jnc DONE
262
    jnc DONE
263
    mov [res], ax
263
    mov [res], ax
264
    DONE:
264
    DONE:
265
    pop es
265
    pop es
266
  }
266
  }
267
  return(res);
267
  return(res);
268
}
268
}
269
 
269
 
270
 
270
 
271
int main(int argc, char **argv) {
271
int main(int argc, char **argv) {
272
  struct country cntdata;
272
  struct country cntdata;
273
  int changedflag;
273
  int changedflag;
274
  int x;
274
  int x;
275
  static char fname[130];
275
  static char fname[130];
276
 
276
 
277
  if ((argc < 2) || (argv[1][0] == '/')) {
277
  if ((argc < 2) || (argv[1][0] == '/')) {
278
    about();
278
    about();
279
    return(1);
279
    return(1);
280
  }
280
  }
281
 
281
 
282
  if (file_truename(fname, argv[1]) != 0) {
282
  if (file_truename(fname, argv[1]) != 0) {
283
    puts("ERROR: bad file path");
283
    puts("ERROR: bad file path");
284
    return(1);
284
    return(1);
285
  }
285
  }
286
 
286
 
287
  x = country_read(&cntdata, fname);
287
  x = country_read(&cntdata, fname);
288
  if (x != 0) {
288
  if (x != 0) {
289
    printf("ERROR: failed to read the preference file [%d]\n", x);
289
    printf("ERROR: failed to read the preference file [%d]\n", x);
290
    return(2);
290
    return(2);
291
  }
291
  }
292
 
292
 
293
  changedflag = argc - 2;
293
  changedflag = argc - 2;
294
 
294
 
295
  /* process command line arguments */
295
  /* process command line arguments */
296
  while (--argc > 1) {
296
  while (--argc > 1) {
297
    if (processarg(argv[argc], &cntdata) != 0) {
297
    if (processarg(argv[argc], &cntdata) != 0) {
298
      about();
298
      about();
299
      return(3);
299
      return(3);
300
    }
300
    }
301
  }
301
  }
302
 
302
 
303
  printf("Country intl code.....: %03d\n", cntdata.id);
303
  printf("Country intl code.....: %03d\n", cntdata.CTYINFO.id);
304
  printf("Codepage..............: %d\n", cntdata.codepage);
304
  printf("Codepage..............: %d\n", cntdata.CTYINFO.codepage);
305
  printf("Decimal separator.....: %c\n", cntdata.decimal);
305
  printf("Decimal separator.....: %c\n", cntdata.CTYINFO.decimal[0]);
306
  printf("Thousands separator...: %c\n", cntdata.thousands);
306
  printf("Thousands separator...: %c\n", cntdata.CTYINFO.thousands[0]);
307
  printf("Date format...........: %s\n", datestring(&cntdata));
307
  printf("Date format...........: %s\n", datestring(&cntdata));
308
  printf("Time format...........: %s\n", timestring(&cntdata));
308
  printf("Time format...........: %s\n", timestring(&cntdata));
309
  printf("Yes/No letters........: %c/%c\n", cntdata.yes, cntdata.no);
309
  printf("Yes/No letters........: %c/%c\n", cntdata.YESNO.yes[0], cntdata.YESNO.no[0]);
310
  printf("Currency example......: %s\n", currencystring(&cntdata));
310
  printf("Currency example......: %s\n", currencystring(&cntdata));
311
 
311
 
312
  printf("\n"
312
  printf("\n"
313
         "Please make sure your CONFIG.SYS contains a COUNTRY directive that points to\n"
313
         "Please make sure your CONFIG.SYS contains a COUNTRY directive that points to\n"
314
         "your custom preferences file:\n"
314
         "your custom preferences file:\n"
315
         "COUNTRY=%03d,%03d,%s\n\n", cntdata.id, cntdata.codepage, fname);
315
         "COUNTRY=%03d,%03d,%s\n\n", cntdata.CTYINFO.id, cntdata.CTYINFO.codepage, fname);
316
 
316
 
317
  /* if anything changed, write the new file */
317
  /* if anything changed, write the new file */
318
  if (changedflag != 0) country_write(fname, &cntdata);
318
  if (changedflag != 0) country_write(fname, &cntdata);
319
 
319
 
320
  return(0);
320
  return(0);
321
}
321
}
322
 
322