|
rllib
1
|
00001 /*************************************************************************** 00002 rlinifile.cpp - description 00003 ------------------- 00004 begin : Tue Jan 02 2001 00005 copyright : (C) 2001 by Rainer Lehrig 00006 email : lehrig@t-online.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as * 00013 * published by the Free Software Foundation * 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; // first section holds names with section name = null_string 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 //while(line[i] > ' ' && line[i] != '=') 00087 while(line[i] != '\0' && line[i] != '=') 00088 { 00089 *buf++ = line[i++]; 00090 } 00091 *buf = '\0'; 00092 i--; // eventually delete spaces 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 // delete old content 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 // read the file 00133 fname.setText(filename); 00134 _firstSection = new rlSection; // first section holds names with section name = null_string 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] == '[') // section identifier 00149 { 00150 copyIdentifier(name_section,line); 00151 setText(name_section, NULL, NULL); 00152 } 00153 else if(line[0] > ' ' && line[0] != '\t' && line[0] != '#') // name identifier 00154 { 00155 copyName(name_name,line); 00156 copyParam(name_param,line); 00157 setText(name_section, name_name, name_param); 00158 } 00159 else // it must be a comment line 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]; // should be big enough 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 00492 const char *rlIniFile::tr(const char *txt) 00493 { 00494 if(txt == NULL) return "ERROR:txt=NULL"; 00495 char default_text[1024]; 00496 if(strlen(txt) < (sizeof(default_text) - 40)) sprintf(default_text,"tr_error:%s", txt); 00497 else strcpy(default_text,"tr_error:text too long"); 00498 return i18n(txt,default_text); 00499 }
1.7.5.1