home *** CD-ROM | disk | FTP | other *** search
/ Amiga Times / AmigaTimes.iso / spiele / FreeCiv / src / freeciv-1.7.0 / server / registry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-06  |  11.5 KB  |  459 lines

  1. /********************************************************************** 
  2.  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2, or (at your option)
  6.    any later version.
  7.  
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12. ***********************************************************************/
  13.  
  14. /**************************************************************************
  15.   the idea with this file is to create something similar to the ms-windows
  16.   .ini files functions.
  17.   it also demonstrates how ugly code using the genlist class looks.
  18.   however the interface is nice. ie:
  19.   section_file_lookup_string(file, "player%d.unit%d.name", plrno, unitno); 
  20. ***************************************************************************/
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <stdarg.h>
  26.  
  27. #include <registry.h>
  28. #include <log.h>
  29. #include <shared.h>
  30.  
  31. /**************************************************************************
  32. ...
  33. **************************************************************************/
  34. void section_file_init(struct section_file *file)
  35. {
  36.   genlist_init(&file->section_list);
  37. }
  38.  
  39.  
  40. /**************************************************************************
  41. ...
  42. **************************************************************************/
  43. void section_file_free(struct section_file *file)
  44. {
  45.   struct genlist_iterator myiter;
  46.  
  47.   genlist_iterator_init(&myiter, &file->section_list, 0);
  48.  
  49.   for(; ITERATOR_PTR(myiter); ) {
  50.     struct genlist_iterator myiter2;
  51.     struct section *psection=(struct section *)ITERATOR_PTR(myiter);
  52.  
  53.     genlist_iterator_init(&myiter2, &psection->entry_list, 0);
  54.     for(; ITERATOR_PTR(myiter2);) {
  55.       struct section_entry *pentry=
  56.     (struct section_entry *)ITERATOR_PTR(myiter2);
  57.       ITERATOR_NEXT(myiter2);
  58.       free(pentry->name);
  59.       free(pentry->svalue);
  60.       genlist_unlink(&psection->entry_list, pentry);
  61.       free(pentry);
  62.     }
  63.  
  64.     ITERATOR_NEXT(myiter);
  65.     free(psection->name);
  66.     genlist_unlink(&file->section_list, psection);
  67.     free(psection);
  68.   }
  69.  
  70. }
  71.  
  72.  
  73.  
  74. /**************************************************************************
  75. ...
  76. **************************************************************************/
  77. int section_file_load(struct section_file *my_section_file, char *filename)
  78. {
  79.   FILE *fs;
  80.   char buffer[512];
  81.   int lineno, ival=0;
  82.   struct section *current_section=0;
  83.  
  84.   if(!(fs=fopen(filename, "r")))
  85.     return 0;
  86.  
  87.  
  88.   genlist_init(&my_section_file->section_list);
  89.  
  90.  
  91.   lineno=0;
  92.  
  93.   while(fgets(buffer, 512, fs)) {
  94.     char *cptr;
  95.  
  96.     lineno++;
  97.  
  98.     for(cptr=buffer; *cptr && isspace(*cptr); cptr++);
  99.  
  100.     if(!*cptr || *cptr==';')
  101.       continue;
  102.  
  103.     else if(*cptr=='[') {
  104.       struct section *psection;
  105.  
  106.       for(++cptr; *cptr && *cptr!=']'; cptr++);
  107.       
  108.       if(!*cptr) {
  109.     log(LOG_FATAL, "missing ] in %s - line %d", filename, lineno);
  110.     exit(1);
  111.       }
  112.  
  113.       *cptr='\0';
  114.  
  115.       psection=(struct section *)malloc(sizeof(struct section));
  116.       psection->name=mystrdup(buffer+1);
  117.       genlist_init(&psection->entry_list);
  118.       genlist_insert(&my_section_file->section_list, psection, -1);
  119.  
  120.       current_section=psection;
  121.  
  122.     }
  123.     else {
  124.       char *pname, *pvalue;
  125.       struct section_entry *pentry;
  126.  
  127.       pvalue=0;
  128.  
  129.       for(; *cptr && isspace(*cptr); cptr++);
  130.  
  131.       if(!*cptr)
  132.     continue;
  133.  
  134.       pname=cptr;
  135.  
  136.       for(; *cptr && *cptr!='='; cptr++);
  137.       
  138.       if(!*cptr) {
  139.     log(LOG_FATAL, "syntax error in %s - line %d", filename, lineno);
  140.     exit(1);
  141.       }
  142.  
  143.       
  144.       *cptr++='\0';
  145.  
  146.       for(; *cptr && isspace(*cptr); cptr++);
  147.  
  148.       if(isdigit(*cptr) || *cptr=='-')
  149.     ival=atoi(cptr);
  150.       else if(*cptr=='\"') {
  151.     pvalue=++cptr;
  152.     for(; *cptr && *cptr!='\"'; cptr++);
  153.     
  154.     if(!*cptr) {
  155.       log(LOG_FATAL, "expected end of string in %s - line %d", filename, lineno);
  156.       exit(1);
  157.     }
  158.  
  159.     *cptr='\0';
  160.  
  161.       }
  162.       else {
  163.     log(LOG_FATAL, "syntax error in %s - line %d", filename, lineno);
  164.     exit(1);
  165.       }
  166.  
  167.  
  168.       if(!current_section) {
  169.     log(LOG_FATAL, "entry defined before first section in %s - line %d", 
  170.         filename, lineno);
  171.     exit(1);
  172.       }
  173.  
  174.       
  175.       pentry=(struct section_entry *)malloc(sizeof(struct section_entry));
  176.       pentry->name=mystrdup(pname);
  177.       
  178.       if(pvalue)
  179.     pentry->svalue=minstrdup(pvalue);
  180.       else {
  181.     pentry->ivalue=ival;
  182.     pentry->svalue=0;
  183.       }
  184.       genlist_insert(¤t_section->entry_list, pentry, -1); 
  185.  
  186.     }
  187.   }
  188.  
  189.   fclose(fs);
  190.   
  191.   return 1;
  192. }
  193.  
  194. /**************************************************************************
  195. ...
  196. **************************************************************************/
  197. int section_file_save(struct section_file *my_section_file, char *filename)
  198. {
  199.   FILE *fs;
  200.  
  201.   struct genlist_iterator myiter;
  202.  
  203.   if(!(fs=fopen(filename, "w")))
  204.     return 0;
  205.  
  206.  
  207.   genlist_iterator_init(&myiter, &my_section_file->section_list, 0);
  208.   
  209.  
  210.   for(; ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter)) {
  211.     struct genlist_iterator myiter2;
  212.     fprintf(fs, "\n[%s]\n",((struct section *)ITERATOR_PTR(myiter))->name);
  213.  
  214.     genlist_iterator_init(&myiter2, &((struct section *)
  215.                    ITERATOR_PTR(myiter))->entry_list, 0);
  216.  
  217.     for(; ITERATOR_PTR(myiter2); ITERATOR_NEXT(myiter2)) {
  218.       if(((struct section_entry *)ITERATOR_PTR(myiter2))->svalue)
  219.     fprintf(fs, "%s=\"%s\"\n", 
  220.         ((struct section_entry *)ITERATOR_PTR(myiter2))->name,
  221.         ((struct section_entry *)ITERATOR_PTR(myiter2))->svalue);
  222.       else
  223.     fprintf(fs, "%s=%d\n", 
  224.         ((struct section_entry *)ITERATOR_PTR(myiter2))->name,
  225.         ((struct section_entry *)ITERATOR_PTR(myiter2))->ivalue);
  226.     }
  227.  
  228.  
  229.   }
  230.  
  231.   if(ferror(fs) || fclose(fs) == EOF)
  232.     return 0;
  233.  
  234.   return 1;
  235. }
  236.  
  237. /**************************************************************************
  238. ...
  239. **************************************************************************/
  240. char *secfile_lookup_str(struct section_file *my_section_file, char *path, ...)
  241. {
  242.   struct section_entry *entry;
  243.   char buf[512];
  244.   va_list ap;
  245.  
  246.   va_start(ap, path);
  247.   vsprintf(buf, path, ap);
  248.   va_end(ap);
  249.  
  250.  
  251.   if(!(entry=section_file_lookup_internal(my_section_file, buf))) {
  252.     log(LOG_FATAL, "sectionfile doesn't contain a '%s' entry", buf);
  253.     exit(1);
  254.   }
  255.  
  256.   if(!entry->svalue) {
  257.     log(LOG_FATAL, "sectionfile entry '%s' doesn't contain a string", buf);
  258.     exit(1);
  259.   }
  260.   
  261.   return entry->svalue;
  262. }
  263.  
  264.       
  265.  
  266. /**************************************************************************
  267. ...
  268. **************************************************************************/
  269. void secfile_insert_int(struct section_file *my_section_file,
  270.             int val, char *path, ...)
  271. {
  272.   struct section_entry *pentry;
  273.   char buf[512];
  274.   va_list ap;
  275.  
  276.   va_start(ap, path);
  277.   vsprintf(buf, path, ap);
  278.   va_end(ap);
  279.  
  280.   pentry=section_file_insert_internal(my_section_file, buf);
  281.  
  282.   pentry->ivalue=val;
  283.   pentry->svalue=0;
  284.   
  285. }
  286.  
  287.  
  288.  
  289. /**************************************************************************
  290. ...
  291. **************************************************************************/
  292. void secfile_insert_str(struct section_file *my_section_file,
  293.             char *sval, char *path, ...)
  294. {
  295.   struct section_entry *pentry;
  296.   char buf[512];
  297.   va_list ap;
  298.  
  299.   va_start(ap, path);
  300.   vsprintf(buf, path, ap);
  301.   va_end(ap);
  302.  
  303.   pentry=section_file_insert_internal(my_section_file, buf);
  304.   pentry->svalue=mystrdup(sval);
  305. }
  306.  
  307.  
  308.  
  309. /**************************************************************************
  310. ...
  311. **************************************************************************/
  312. int secfile_lookup_int(struct section_file *my_section_file, 
  313.                char *path, ...)
  314. {
  315.   struct section_entry *entry;
  316.   char buf[512];
  317.   va_list ap;
  318.  
  319.   va_start(ap, path);
  320.   vsprintf(buf, path, ap);
  321.   va_end(ap);
  322.  
  323.   if(!(entry=section_file_lookup_internal(my_section_file, buf))) {
  324.     log(LOG_FATAL, "sectionfile doesn't contain a '%s' entry", buf);
  325.     exit(1);
  326.   }
  327.  
  328.   if(entry->svalue) {
  329.     log(LOG_FATAL, "sectionfile entry '%s' doesn't contain an integer", buf);
  330.     exit(1);
  331.   }
  332.   
  333.   return entry->ivalue;
  334. }
  335.  
  336.  
  337.  
  338. /**************************************************************************
  339. ...
  340. **************************************************************************/
  341. int section_file_lookup(struct section_file *my_section_file, 
  342.             char *path, ...)
  343. {
  344.   char buf[512];
  345.   va_list ap;
  346.  
  347.   va_start(ap, path);
  348.   vsprintf(buf, path, ap);
  349.   va_end(ap);
  350.  
  351.   return !!section_file_lookup_internal(my_section_file, buf);
  352. }
  353.  
  354.  
  355.  
  356.  
  357.  
  358. /**************************************************************************
  359. ...
  360. **************************************************************************/
  361. struct section_entry *section_file_lookup_internal(struct section_file 
  362.                            *my_section_file,  
  363.                            char *fullpath) 
  364.                            
  365. {
  366.   char *pdelim;
  367.   char sec_name[512];
  368.   char ent_name[512];
  369.   struct genlist_iterator myiter;
  370.  
  371.  
  372.   if(!(pdelim=strchr(fullpath, '.'))) /* i dont like strtok */
  373.     return 0;
  374.   strncpy(sec_name, fullpath, pdelim-fullpath);
  375.   sec_name[pdelim-fullpath]='\0';
  376.   strcpy(ent_name, pdelim+1);
  377.  
  378.   genlist_iterator_init(&myiter, &my_section_file->section_list, 0);
  379.  
  380.   for(; ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter))
  381.     if(!strcmp(((struct section *)ITERATOR_PTR(myiter))->name, sec_name)) {
  382.       struct genlist_iterator myiter2;
  383.       genlist_iterator_init(&myiter2, &((struct section *)
  384.                  ITERATOR_PTR(myiter))->entry_list, 0);
  385.       for(; ITERATOR_PTR(myiter2); ITERATOR_NEXT(myiter2)) {
  386.        if(!strcmp(((struct section_entry *)ITERATOR_PTR(myiter2))->name, 
  387.            ent_name))
  388.       return (struct section_entry *)ITERATOR_PTR(myiter2);
  389.       }
  390.     }
  391.  
  392.   return 0;
  393. }
  394.  
  395.  
  396. /**************************************************************************
  397. ...
  398. **************************************************************************/
  399. struct section_entry *section_file_insert_internal(struct section_file 
  400.                            *my_section_file, 
  401.                            char *fullpath)
  402. {
  403.   char *pdelim;
  404.   char sec_name[512];
  405.   char ent_name[512];
  406.   struct genlist_iterator myiter;
  407.   struct section *psection;
  408.   struct section_entry *pentry;
  409.  
  410.  
  411.   if(!(pdelim=strchr(fullpath, '.'))) /* i dont like strtok */
  412.     return 0;
  413.   strncpy(sec_name, fullpath, pdelim-fullpath);
  414.   sec_name[pdelim-fullpath]='\0';
  415.   strcpy(ent_name, pdelim+1);
  416.  
  417.  
  418.   genlist_iterator_init(&myiter, &my_section_file->section_list, 0);
  419.  
  420.   for(; ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter))
  421.     if(!strcmp(((struct section *)ITERATOR_PTR(myiter))->name, sec_name)) {
  422.  
  423.       struct genlist_iterator myiter2;
  424.       genlist_iterator_init(&myiter2, &((struct section *)
  425.                  ITERATOR_PTR(myiter))->entry_list, 0);
  426.       for(; ITERATOR_PTR(myiter2); ITERATOR_NEXT(myiter2)) {
  427.        if(!strcmp(((struct section_entry *)ITERATOR_PTR(myiter2))->name, 
  428.            ent_name))
  429.       return (struct section_entry *)ITERATOR_PTR(myiter2);
  430.       }
  431.  
  432.       pentry=(struct section_entry *)malloc(sizeof(struct section_entry));
  433.       pentry->name=mystrdup(ent_name);
  434.       genlist_insert(&((struct section *)
  435.                 ITERATOR_PTR(myiter))->entry_list, pentry, -1);
  436.  
  437.       return pentry;
  438.     }
  439.  
  440.  
  441.   psection=(struct section *)malloc(sizeof(struct section));
  442.   psection->name=mystrdup(sec_name);
  443.   genlist_init(&psection->entry_list);
  444.   genlist_insert(&my_section_file->section_list, psection, -1);
  445.   
  446.   pentry=(struct section_entry *)malloc(sizeof(struct section_entry));
  447.   pentry->name=mystrdup(ent_name);
  448.   genlist_insert(&psection->entry_list, pentry, -1);
  449.  
  450.   return pentry;
  451. }
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.