00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "rldefine.h"
00017 #include <stdio.h>
00018 #include <stdlib.h>
00019 #include <stdarg.h>
00020 #include <string.h>
00021 #ifdef RLWIN32
00022 #include <windows.h>
00023 #endif
00024 #include "rlinifile.h"
00025 #include "rlcutil.h"
00026
00027 static const char null_string[] = "";
00028
00029 rlIniFile::rlIniFile()
00030 {
00031 _firstSection = new rlSection;
00032 _firstSection->nextSection = NULL;
00033 _firstSection->firstName = NULL;
00034 _firstSection->name = new char[1];
00035 _firstSection->name[0] = '\0';
00036 currentSection = currentName = -1;
00037 }
00038
00039 rlIniFile::~rlIniFile()
00040 {
00041 rlSection *section, *last_section;
00042
00043 section = _firstSection;
00044 while(section != NULL)
00045 {
00046 deleteSectionNames(section);
00047 last_section = section;
00048 section = section->nextSection;
00049 delete last_section;
00050 }
00051 }
00052
00053 void rlIniFile::deleteSectionNames(rlSection *section)
00054 {
00055 rlSectionName *name, *last_name;
00056
00057 if(section == NULL) return;
00058 name = section->firstName;
00059 while(name != NULL)
00060 {
00061 if(name->name != NULL) delete [] name->name;
00062 if(name->param != NULL) delete [] name->param;
00063 last_name = name;
00064 name = name->nextName;
00065 delete [] last_name;
00066 }
00067 if(section->name != NULL) delete [] section->name;
00068 }
00069
00070 void rlIniFile::copyIdentifier(char *buf, const char *line)
00071 {
00072 int i = 1;
00073 buf[0] = '\0';
00074 if(line[0] != '[') return;
00075 while(line[i] != ']' && line[i] != '\0')
00076 {
00077 *buf++ = line[i++];
00078 }
00079 *buf = '\0';
00080 }
00081
00082 void rlIniFile::copyName(char *buf, const char *line)
00083 {
00084 int i = 0;
00085 buf[0] = '\0';
00086
00087 while(line[i] != '\0' && line[i] != '=')
00088 {
00089 *buf++ = line[i++];
00090 }
00091 *buf = '\0';
00092 i--;
00093 while(i>=0 && (buf[i] == ' ' || buf[i] == '\t'))
00094 {
00095 buf[i--] = '\0';
00096 }
00097 }
00098
00099 void rlIniFile::copyParam(char *buf, const char *line)
00100 {
00101 const char *cptr;
00102 buf[0] = '\0';
00103 cptr = strchr(line,'=');
00104 if(cptr == NULL) return;
00105 cptr++;
00106 while((*cptr == ' ' || *cptr == '\t') && *cptr != '\0') cptr++;
00107 if(*cptr == '\0') return;
00108 while(*cptr != '\0' && *cptr != '\n') *buf++ = *cptr++;
00109 *buf = '\0';
00110 }
00111
00112 int rlIniFile::read(const char *filename)
00113 {
00114 FILE *fp;
00115 char line[rl_PRINTF_LENGTH],
00116 name_section[rl_PRINTF_LENGTH],
00117 name_name[rl_PRINTF_LENGTH],
00118 name_param[rl_PRINTF_LENGTH],
00119 *cptr;
00120 rlSection *s, *s_old;
00121
00122
00123 s = _firstSection;
00124 while(s != NULL)
00125 {
00126 deleteSectionNames(s);
00127 s_old = s;
00128 s = s->nextSection;
00129 delete s_old;
00130 }
00131
00132
00133 fname.setText(filename);
00134 _firstSection = new rlSection;
00135 _firstSection->nextSection = NULL;
00136 _firstSection->firstName = NULL;
00137 _firstSection->name = new char[1];
00138 _firstSection->name[0] = '\0';
00139 fp = fopen(filename,"r");
00140 if(fp == NULL) return -1;
00141 name_section[0] = name_name[0] = name_param[0] = '\0';
00142 while(fgets(line,sizeof(line)-1,fp) != NULL)
00143 {
00144 cptr = strchr(line,0x0d);
00145 if(cptr != NULL) *cptr = '\0';
00146 cptr = strchr(line,0x0a);
00147 if(cptr != NULL) *cptr = '\0';
00148 if(line[0] == '[')
00149 {
00150 copyIdentifier(name_section,line);
00151 setText(name_section, NULL, NULL);
00152 }
00153 else if(line[0] > ' ' && line[0] != '\t' && line[0] != '#')
00154 {
00155 copyName(name_name,line);
00156 copyParam(name_param,line);
00157 setText(name_section, name_name, name_param);
00158 }
00159 else
00160 {
00161 setText(name_section, line, NULL);
00162 }
00163 }
00164 fclose(fp);
00165 return 0;
00166 }
00167
00168 int rlIniFile::write(const char *filename)
00169 {
00170 FILE *fp;
00171 rlSection *s;
00172 rlSectionName *n;
00173
00174 fp = fopen(filename,"w");
00175 if(fp == NULL) return -1;
00176
00177 s = _firstSection;
00178 while(s != NULL)
00179 {
00180 if (s->name[0] == '#') fprintf(fp,"%s\n",s->name);
00181 else if(s->name[0] == '\0') ;
00182 else fprintf(fp,"[%s]\n",s->name);
00183 n = s->firstName;
00184 while(n != NULL)
00185 {
00186 if (n->name[0] == '#') fprintf(fp,"%s\n",n->name);
00187 else if(n->name[0] == '\0') fprintf(fp,"\n");
00188 else if(n->param[0] == '\0') fprintf(fp,"\n");
00189 else fprintf(fp,"%s=%s\n",n->name,n->param);
00190 n = n->nextName;
00191 }
00192 s = s->nextSection;
00193 }
00194
00195 fclose(fp);
00196 return 0;
00197 }
00198
00199 const char *rlIniFile::filename()
00200 {
00201 return fname.text();
00202 }
00203
00204 const char *rlIniFile::text(const char *section, const char *name)
00205 {
00206 rlSection *s;
00207 rlSectionName *n;
00208
00209 s = _firstSection;
00210 while(s != NULL)
00211 {
00212 if(strcmp(section,s->name) == 0)
00213 {
00214 n = s->firstName;
00215 while(n != NULL)
00216 {
00217 if(n->name != NULL && strcmp(name,n->name) == 0)
00218 {
00219 return n->param;
00220 }
00221 n = n->nextName;
00222 }
00223 return null_string;
00224 }
00225 s = s->nextSection;
00226 }
00227 return null_string;
00228 }
00229
00230 void rlIniFile::setText(const char *section, const char *name, const char *text)
00231 {
00232 rlSection *s, *last_section;
00233 rlSectionName *n, *last_name;
00234
00235 if(section == NULL) return;
00236 last_section = NULL;
00237 last_name = NULL;
00238 s = _firstSection;
00239 while(s != NULL)
00240 {
00241 if(strcmp(section,s->name) == 0)
00242 {
00243 last_name = NULL;
00244 n = s->firstName;
00245 while(n != NULL)
00246 {
00247 if(name != NULL && name[0] != '#' && name[0] != '\0' && strcmp(name,n->name) == 0)
00248 {
00249 if(n->param != NULL) delete [] n->param;
00250 if(text == NULL)
00251 {
00252 n->param = new char[1];
00253 n->param[0] = '\0';
00254 }
00255 else
00256 {
00257 n->param = new char[strlen(text)+1];
00258 strcpy(n->param,text);
00259 }
00260 return;
00261 }
00262 last_name = n;
00263 n = n->nextName;
00264 }
00265 if(last_name == NULL)
00266 {
00267 s->firstName = new rlSectionName;
00268 n = s->firstName;
00269 }
00270 else
00271 {
00272 last_name->nextName = new rlSectionName;
00273 n = last_name->nextName;
00274 }
00275 if(name == NULL)
00276 {
00277 n->name = new char[1];
00278 n->name[0] = '\0';
00279 }
00280 else
00281 {
00282 n->name = new char[strlen(name)+1];
00283 strcpy(n->name,name);
00284 }
00285 if(text == NULL)
00286 {
00287 n->param = new char[1];
00288 n->param[0] = '\0';
00289 }
00290 else
00291 {
00292 n->param = new char[strlen(text)+1];
00293 strcpy(n->param,text);
00294 }
00295 n->nextName = NULL;
00296 return;
00297 }
00298 last_section = s;
00299 s = s->nextSection;
00300 }
00301 if(last_section == NULL)
00302 {
00303 _firstSection = new rlSection;
00304 last_section = _firstSection;
00305 }
00306 else
00307 {
00308 last_section->nextSection = new rlSection;
00309 last_section = last_section->nextSection;
00310 }
00311 last_section->name = new char[strlen(section)+1];
00312 strcpy(last_section->name,section);
00313 last_section->nextSection = NULL;
00314 if(name == NULL)
00315 {
00316 last_section->firstName = NULL;
00317 }
00318 else
00319 {
00320 last_section->firstName = new rlSectionName;
00321 n = last_section->firstName;
00322 n->name = new char[strlen(name)+1];
00323 strcpy(n->name,name);
00324 if(text == NULL)
00325 {
00326 n->param = new char[1];
00327 n->param[0] = '\0';
00328 }
00329 else
00330 {
00331 n->param = new char[strlen(text)+1];
00332 strcpy(n->param,text);
00333 }
00334 n->nextName = NULL;
00335 }
00336 return;
00337 }
00338
00339 int rlIniFile::printf(const char *section, const char *name, const char *format, ...)
00340 {
00341 int ret;
00342 char buf[rl_PRINTF_LENGTH];
00343
00344 va_list ap;
00345 va_start(ap,format);
00346 ret = rlvsnprintf(buf, rl_PRINTF_LENGTH - 1, format, ap);
00347 va_end(ap);
00348 if(ret > 0) setText(section, name, buf);
00349 return ret;
00350 }
00351
00352 void rlIniFile::remove(const char *section)
00353 {
00354 rlSection *s, *last;
00355
00356 last = NULL;
00357 s = _firstSection;
00358 while(s != NULL)
00359 {
00360 if(strcmp(section,s->name) == 0)
00361 {
00362 deleteSectionNames(s);
00363 if(last != NULL) last->nextSection = s->nextSection;
00364 delete s;
00365 return;
00366 }
00367 last = s;
00368 s = s->nextSection;
00369 }
00370 }
00371
00372 void rlIniFile::remove(const char *section, const char *name)
00373 {
00374 rlSection *s;
00375 rlSectionName *n, *last;
00376
00377 s = _firstSection;
00378 while(s != NULL)
00379 {
00380 if(strcmp(section,s->name) == 0)
00381 {
00382 last = NULL;
00383 n = s->firstName;
00384 while(n != NULL)
00385 {
00386 if(strcmp(name,n->name) == 0)
00387 {
00388 if(n->name != NULL) delete [] n->name;
00389 if(n->param != NULL) delete [] n->param;
00390 if(last != NULL) last->nextName = n->nextName;
00391 delete n;
00392 return;
00393 }
00394 last = n;
00395 n = n->nextName;
00396 }
00397 return;
00398 }
00399 s = s->nextSection;
00400 }
00401 }
00402
00403 const char *rlIniFile::firstSection()
00404 {
00405 currentSection = 0;
00406 return _firstSection->name;
00407 }
00408
00409 const char *rlIniFile::nextSection()
00410 {
00411 rlSection *s;
00412 int i;
00413
00414 if(currentSection < 0) return NULL;
00415 currentSection++;
00416 i = 0;
00417 s = _firstSection;
00418 while(s != NULL)
00419 {
00420 if(i == currentSection) return s->name;
00421 s = s->nextSection;
00422 i++;
00423 }
00424 currentSection = -1;
00425 return NULL;
00426 }
00427
00428 const char *rlIniFile::firstName(const char *section)
00429 {
00430 rlSection *s;
00431 rlSectionName *n;
00432
00433 s = _firstSection;
00434 while(s != NULL)
00435 {
00436 if(strcmp(section,s->name) == 0)
00437 {
00438 n = s->firstName;
00439 currentName = 0;
00440 return n->name;
00441 }
00442 s = s->nextSection;
00443 }
00444 return NULL;
00445 }
00446
00447 const char *rlIniFile::nextName(const char *section)
00448 {
00449 rlSection *s;
00450 rlSectionName *n;
00451 int i;
00452
00453 if(currentName < 0) return NULL;
00454 currentName++;
00455 i = 0;
00456 s = _firstSection;
00457 while(s != NULL)
00458 {
00459 if(strcmp(section,s->name) == 0)
00460 {
00461 n = s->firstName;
00462 while(n != NULL)
00463 {
00464 if(i == currentName) return n->name;
00465 i++;
00466 n = n->nextName;
00467 }
00468 return NULL;
00469 }
00470 s = s->nextSection;
00471 }
00472 return NULL;
00473 }
00474
00475 void rlIniFile::setDefaultSection(const char *section)
00476 {
00477 default_section.setText(section);
00478 }
00479
00480 const char *rlIniFile::defaultSection()
00481 {
00482 return default_section.text();
00483 }
00484
00485 const char *rlIniFile::i18n(const char *tag, const char *default_text)
00486 {
00487 const char *cptr = text(default_section.text(), tag);
00488 if(strcmp(cptr,null_string) == 0) return default_text;
00489 else return cptr;
00490 }
00491