#include #include "xconf.h" #include "section.h" PUBLIC XCONFIG::XCONFIG() :SECTION("","") { //#nbsection = 0; parsing.section = NULL; parsing.subopt = NULL; parsing.subdisp = NULL; } /* #Specification: Xconfig / format The Xconfig file has a format "mostly" like this Section "name" option [ value ] . EndSection ... Sometime, this is just a keyword with or without a value Sometime, there is no option. So the way we parsed this is that we only understand the keyword for section, and option are seen as subsection themselves. */ /* Read a complete Xconfig */ PUBLIC int XCONFIG::read(const char *fname) { FILE *fin = xconf_fopen (fname,"r"); int ret = -1; if (fin != NULL){ char buf[500]; int noline = 0; // parsing.section = NULL; // parsing.subopt = NULL; // parsing.subdisp = NULL; ret = 0; while (fgets_strip(buf,sizeof(buf)-1,fin,'\0','\0',&noline)!=NULL){ char *pt = str_skip (buf); int err = 1; if (pt[0] == '#'){ err = 0; }else if (strnicmp("section",pt,7)==0 && isspace(pt[7])){ pt = str_skip(pt+7); if (*pt == '"'){ pt++; char *start = str_skip(pt); while (*pt != '\0' && *pt > ' ') pt++; if (*pt == '"'){ *pt = '\0'; SECTION *sect = NULL; if (stricmp(start,"monitor")==0){ sect = new MONITOR; }else if (stricmp(start,"device")==0){ sect = new DEVICE; }else if (stricmp(start,"files")==0){ sect = new FILES; }else if (stricmp(start,"keyboard")==0){ sect = new KEYBOARD; }else if (stricmp(start,"screen")==0){ sect = new SCREEN; }else if (stricmp(start,"pointer")==0){ sect = new POINTER; }else if (stricmp(start,"serverflags")==0){ sect = new SERVERFLAGS; } if (sect != NULL){ err = 0; sect->read (fin,fname,noline); tbsect.add(sect); } } } } if (err){ xconf_error ("Invalid line %d in file %s\n%s\n" ,noline,fname,buf); ret = -1; } } fclose (fin); } return ret; } /* Sort all section of an XCONFIG. THe section are not sorted, only their content. */ PUBLIC void XCONFIG::sort() { for (int i=0; isort (); } } PUBLIC int XCONFIG::print(FILE *fout, int indent) { int ret = 0; OPTION *last = NULL; for (int i=0; ikeyw,last->keyw)!=0){ fprintf (fout,"\n\n"); } ret |= cur->print (fout,indent); last = cur; } return ret; } PUBLIC COMMENTS::COMMENTS() : SECTION("","") { } PUBLIC void COMMENTS::print (FILE *fout) { for (int i=0; ikeyw,opt->arg); } } /* Write an Xconfig to a file Return -1 if any error. */ PUBLIC int XCONFIG::write(const char *fname) { int ret = -1; FILE *fout = xconf_fopen (fname,"w"); if (fout != NULL){ fprintf (fout,"%s",DONT_TOUCH); ret = 0; comments.print (fout); fprintf (fout,"\n"); print (fout,0); fclose (fout); } return ret; } /* Add/merge an XCONFIG into another Section and their content are added to the destination */ PUBLIC void XCONFIG::merge (const XCONFIG *src) { if (src != NULL){ SECTION::merge (src); comments.merge (&src->comments); } } /* Add a comment to the XCONFIG. It will appear at the beginning of the Xconfig file with a #-# prefix. */ PUBLIC void XCONFIG::addcomment( const char *keyw, const char *manuf_id, const char *model_id) { char buf[100]; sprintf (buf,"%s %s",manuf_id,model_id); OPTION *tmpopt = new OPTION (keyw,buf); COMMENTS tmpsec; tmpsec.addoption (tmpopt); comments.merge (&tmpsec); } /* Return the value of the comment identify with keyw */ PUBLIC const char *XCONFIG::getcomment (const char *keyw) { return comments.findarg (keyw); } #ifdef TEST int main (int argc, char *argv[]) { XCONFIG x; x.read (ETC_XF86CONFIG); x.sort(); x.write ("/tmp/XF86Config"); XCONFIG x2; x2.merge (&x); x.write ("/tmp/XF86Config2"); return 0; } #endif