parser.c

Go to the documentation of this file.
00001 #include "parser.h"
00002 #include "structs.h"
00003 #include "constants.h"
00004 #include "FilterSpec.h"
00005 #include "StreamSpec.h"
00006 #include "Layout.h"
00007 #include "FilterData/Policies.h"
00008 #include "Hosts.h"
00009 
00010 // global: parser state
00011 static State state = start, lastState = start;
00012 static char errorMsg[200];
00013 
00014 static char *stateNames[] = {
00015                 "start", "prehost", "hostdec","preplace", 
00016                 "placement", "prelay", "layout", 
00017                 "preend", "end", "resources", "filter", 
00018                 "stream", "fromto", "tostream", 
00019                 "error", "parseerror" 
00020 };
00021 
00022 static int currentHostIndex; //the host index we are reading resources
00023 static FilterSpec *currentFilter = NULL; // the filter we are reading
00024 static StreamSpec *currentStream = NULL; //the stream we are reading
00025 static int remainingInstances, instances; //each filter runs on X hosts, we use this variable to control this
00026 
00027 
00028 /*! \file parser.c This file parses the conf.xml, using the expat lib  */
00029 
00030 /// this functions is called whenever a tag is open. 
00031 void abreTag(void *userData, const XML_Char *name, const XML_Char **atts){
00032         Layout *systemLayout = (Layout*)userData;
00033 
00034         lastState = state;
00035         switch (state){
00036                 case start:
00037                         //we expect config tag here
00038                         if (strcasecmp("config", name) ==  0)
00039                                 state = prehost;
00040                         else {
00041                                 strcpy(errorMsg, "Expecting <config>\n");
00042                                 state = error;
00043                         }
00044                 break;
00045                 case prehost:
00046                         //we expect hostdec tag here
00047                         if (strcasecmp("hostdec", name) ==  0){
00048                                 state = hostdec;
00049                         }
00050                         else {
00051                                 strcpy(errorMsg, "Expecting <hostdec>\n");
00052                                 state = error;
00053                                 return;
00054                         }
00055                 break;
00056                 case hostdec:
00057                         //we expect host tag here
00058                         if (strcasecmp("host", name) !=  0){
00059                                 strcpy(errorMsg, "Expecting <host name=\"\" [weight=\"\"]/>\n");
00060                                 state = error;
00061                                 return;
00062                         }
00063 
00064 
00065                         int wi = -1, ni = -1, mi = -1, weight, mem = -1;
00066                         int i=0;
00067                         char *hname;
00068 
00069                         while (atts[i] != NULL){
00070                                 if (strcasecmp(atts[i], "name") == 0){
00071                                         ni= i+1;        
00072                                 }
00073                                 else if (strcasecmp(atts[i], "weight") == 0){
00074                                         wi = i+1;
00075                                 }
00076                                 else if (strcasecmp(atts[i], "mem") == 0){
00077                                         mi = i+1;
00078                                 }
00079                                 else {
00080                                         strcpy(errorMsg, "Expecting name or weight attribute\n");
00081                                         state = error;
00082                                         return;
00083                                 }
00084                                 i += 2;
00085                         }
00086 
00087                         if (ni == -1){
00088                                 strcpy(errorMsg, "Expecting <host name=\"\" [weight="" mem=""]/>\n");
00089                                 state = error;
00090                                 return;
00091                         }
00092                         else {
00093                                 hname = strdup(atts[ni]);
00094                         }
00095 
00096                         if (wi == -1){
00097                                 weight = 1;
00098                         }
00099                         else {
00100                                 weight = atoi(atts[wi]);
00101                         }
00102 
00103                         //memory: if mem == -1, filter must autodetect memory
00104                         //reading /proc/meminfo
00105                         if (!((mi == -1) || (strcasecmp(atts[mi], "auto") == 0 ))){
00106                                 int len = strlen(atts[mi]);
00107                                 int unitType = 0; // 0 = MB(default), 1 = GB
00108 
00109                                 //skip trailing B if exists
00110                                 if ((atts[mi][len-1] == 'B') || (atts[mi][len-1] == 'b')){
00111                                         len--;
00112                                 }
00113                                 
00114                                 //find the unit of memory
00115                                 if ((atts[mi][len-1] == 'G') || (atts[mi][len-1] == 'g')){
00116                                         unitType = 1;
00117                                         len --;
00118                                 }
00119                                 else if ((atts[mi][len-1] == 'M') || (atts[mi][len-1] == 'm')){
00120                                         unitType = 0;
00121                                         len --;
00122                                 }
00123                                 else if ((atts[mi][len-1] == 'T') || (atts[mi][len-1] == 't')){
00124                                         unitType = 2;
00125                                         len --;
00126                                 }
00127                                 mem = atoi(atts[mi]) * pow((double)1024, (double)unitType);
00128                         }
00129 
00130 
00131                         //add the host, but no duplicates
00132                         int hindex = hostsAdd(systemLayout->hostsStruct);
00133                         if (hostsSetName(systemLayout->hostsStruct, hindex, hname) == -1 ) {
00134                                 state = error;
00135                                 sprintf(errorMsg, "Could not add host %s", hname);
00136                                 return;
00137                         }
00138                         hostsSetWeight(systemLayout->hostsStruct, hindex, weight);
00139                         hostsSetMemory(systemLayout->hostsStruct, hindex, mem);
00140                         printf("\tparser.c: host %s added to the Void enviroment, weight %d\n", hname, weight);
00141                         free(hname);
00142                         state = resources; //we go reading resources
00143                         currentHostIndex = hindex;
00144                 break;
00145                 case resources:
00146                 {
00147                         //here we read resources for a given host
00148                         if (strcasecmp(name, "resource") != 0){
00149                                 sprintf(errorMsg, "Error, expecting <resource tag>");
00150                                 state = error;
00151                                 return;
00152                         }
00153 
00154                         int rni = -1, i=0; //resource name index
00155                         char resourceName[MAX_RNAME_LENGTH+1];
00156                         //read resource name
00157                         while (atts[i] != NULL) {
00158                                 if (strcasecmp("name", atts[i]) == 0){
00159                                         rni = i+1;
00160                                 }
00161                                 else {
00162                                         sprintf(errorMsg, "Error, expecting <resource name=\"\">");
00163                                         state = error;
00164                                         return;
00165                                 }
00166                                 i+=2;
00167                         }
00168 
00169                         if (rni == -1){
00170                                 sprintf(errorMsg, "Resource name is mandatory");
00171                                 state=error;
00172                                 return;
00173                         }
00174                         else {
00175                                 strncpy(resourceName, atts[rni], MAX_RNAME_LENGTH);
00176                         }
00177 
00178                         HostsStruct *hs = systemLayout->hostsStruct;
00179                         if (hostsAddResource(hs, currentHostIndex, resourceName) < 0){
00180                                 sprintf(errorMsg, "Error adding resource %s: too many resources for host %s", 
00181                                                 resourceName, hostsGetName(hs, currentHostIndex));
00182                                 state = error;
00183                                 return;
00184                         }
00185                         printf("\t\tparser.c: resource %s added to host %s\n", resourceName, hostsGetName(hs, currentHostIndex));
00186                         //no state change
00187                 }
00188                 break;
00189                 case preplace:
00190                         //expect placement tag
00191                         if (strcasecmp("placement", name) == 0)
00192                                 state = placement;
00193                         else {
00194                                 strcpy(errorMsg, "Expecting <placement>");
00195                                 state = error;
00196                         }
00197                 break;
00198                 case placement:
00199                 {
00200                         char filterName[MAX_FNAME_LENGTH+1], libname[MAX_LNAME_LENGTH+1];
00201                         int nameInd = -1, libInd = -1, instInd=-1, i=0;
00202                         instances=-1;
00203 
00204                         // we read the filter entry here
00205                         if ( (strcasecmp("filter", name) != 0) ){
00206                                 state = error;
00207                                 strcpy(errorMsg, "Expecting <filter name=\"filtername\" [instances=\"N\" libname=\"library.so\"] >");
00208                                 return;
00209                         }
00210 
00211                         //filter attributes
00212                         while (atts[i] != NULL){
00213                                 if ( strcasecmp(atts[i], "name") == 0 ){
00214                                         nameInd = i+1;
00215                                         //mandatory
00216                                 }
00217                                 else if ( strcasecmp(atts[i], "libname") == 0 ){
00218                                         libInd = i+1;
00219                                         //optional: default is to use libNAME.so
00220                                 }
00221                                 else if ( strcasecmp(atts[i], "instances") == 0 ){
00222                                         instInd = i+1;
00223                                         //optional: defaults to 1
00224                                 }
00225                                 else {
00226                                         state = error;
00227                                         strcpy(errorMsg, "Expecting <filter name=\"filtername\" [instances=\"N\" libname=\"library.so\"] >");
00228                                         break;
00229                                 }
00230                                 i+=2;
00231                         }
00232 
00233                         //name is mandatory
00234                         if (nameInd == -1){
00235                                 state = error;
00236                                 strcpy(errorMsg, "Name attribute is mandatory, expecting <filter name=\"filtername\" [instances=\"N\" libname=\"library.so\"] >");
00237                                 return;
00238                         }
00239                         else { //get the name
00240                                 strncpy(filterName, atts[nameInd], MAX_FNAME_LENGTH);
00241                                 filterName[MAX_FNAME_LENGTH] = '\0';
00242                         }
00243 
00244                         // if we did not receive the library name, we add lib and .so to filtername
00245                         if (libInd == -1){ 
00246                                 sprintf(libname, "lib%s.so", filterName);
00247                         }
00248                         else { //else we use library from user
00249                                 strncpy(libname, atts[libInd], MAX_LNAME_LENGTH);
00250                                 libname[MAX_LNAME_LENGTH] = '\0';
00251                         }
00252 
00253                         //get optional number of instances
00254                         if (instInd == -1){
00255                                 instances = -1; //default value, auto detect
00256                                 remainingInstances = 1; //we spawn at least 1 instances
00257                         }
00258                         else {
00259                                 instances = atoi(atts[instInd]);
00260                                 remainingInstances = instances; //we'll spawn this number of instances
00261                         }
00262 
00263                         //create the filter!
00264                         currentFilter = createFilterSpec(filterName, libname);
00265                         if (instances == -1){
00266                                 printf("\tparser.c: reading filter %s, library %s, auto number of instances\n", filterName, libname);
00267                         }
00268                         else {
00269                                 printf("\tparser.c: reading filter %s, library %s, %d instances\n", filterName, libname, instances);
00270                         }
00271 
00272                         //update state
00273                         state = filter;
00274                 }
00275                 break;
00276                 case filter:
00277                 {
00278                         //read the hosts of each filter
00279                         if (strcasecmp("instance", name) != 0){
00280                                 //error, did not receive host
00281                                 state = error;
00282                                 strcpy(errorMsg, "Expecting <instance demands=\"hostname or resource\" [qty=\"n\"]/>, n >");
00283                                 return;
00284                         }
00285 
00286                         int demandInd = -1, numInstInd = -1; //attribute index
00287                         int i = 0;
00288                         
00289                         while (atts[i] != NULL){
00290                                 // even indexes are attribute names
00291                                 // odd indexes are values
00292                                 //ex: <host name="bla"/>
00293                                 //atts[0]=name, atts[1]=bla, atts[2]=NULL
00294                                 if (strcasecmp(atts[i], "demands") == 0){
00295                                         demandInd = i+1;
00296                                 }
00297                                 else if (strcasecmp(atts[i], "numinstances") == 0){
00298                                         numInstInd = i+1;
00299                                 } 
00300                                 else {
00301                                         state = error;
00302                                         strcpy(errorMsg, "Expecting <host name=\"hostname\" [numinstances=\"n\"]/>, n > 0");
00303                                         return;
00304                                 }
00305                                 i+=2;
00306                         }
00307 
00308                         if (demandInd == -1){
00309                                 state = error;
00310                                 strcpy(errorMsg, "Instance must demand something, either a hostname or a resource");
00311                                 return;
00312                         }
00313 
00314                         //we declared N instances, and are trying to spawn more
00315                         if ((instances != -1) && (remainingInstances <= 0)){
00316                                 printf("\t\tparser.c: WARNING: ignoring instance, %d declared\n", instances);
00317                                 return;
00318                         }
00319 
00320                         int numInstances = 1;
00321                         //how many instances, default value is 1
00322                         if (numInstInd != -1){
00323                                 numInstances = atoi(atts[numInstInd]);
00324                         }
00325                         
00326                         for (i=0;i<numInstances;i++){
00327                                 HostsStruct *hs = systemLayout->hostsStruct;
00328                                 //resource name
00329                                 char resourceName[MAX_RNAME_LENGTH+1];
00330                                 strncpy(resourceName, atts[demandInd], MAX_RNAME_LENGTH);
00331 
00332                                 //here we add the host to the filter
00333                                 //first we try to get a host with the resource. If not found, we try to get the host with the given name
00334                                 int hostIndex = hostsGetIndexByResource(hs, resourceName);
00335                                 if (hostIndex == -1){
00336                                         //try to get host by name
00337                                         hostIndex = hostsGetIndexByName(hs, resourceName);
00338                                         if (hostIndex == -1){
00339                                                 sprintf(errorMsg, "Error, resource %s invalid or host not found", resourceName);
00340                                                 state = error;
00341                                                 return;
00342                                         }
00343                                 }
00344 
00345                                 char hostname[MAX_HNAME_LENGTH+1];
00346                                 strcpy(hostname, hostsGetName(hs, hostIndex));
00347                                 printf("\t\tparser.c: host %s running this filter\n", hostname);
00348 
00349                                 addHostToFilter(currentFilter, hs->hosts[hostIndex].name);
00350                                 remainingInstances--;
00351                         }
00352                         break;
00353                 }
00354                 case prelay:
00355                         //reads <layout>
00356                         if (strcasecmp("layout", name) == 0)
00357                                 state = layout;
00358                         else {
00359                                 state = error;
00360                                 strcpy(errorMsg, "Expecting <layout>");
00361                                 return;
00362                         }
00363                 break;
00364                 case layout:
00365                         //reads stream
00366                         if (strcasecmp("stream", name) == 0){
00367                                 state = stream;
00368 
00369                                 //creates the stream
00370                                 currentStream = createEmptyStreamSpec();
00371                         }
00372                         else {
00373                                 state = error;
00374                                 strcpy(errorMsg, "Expecting <stream>");
00375                                 return;
00376                         }
00377 
00378                 break;
00379                 case stream:
00380                         //reads <from />
00381                         if (strcasecmp(name, "from") == 0){
00382                                 int filInd = -1, portInd = -1, polInd = -1, polibInd = -1;
00383 #ifdef VOID_TERM
00384                                 int breakLoop = 0;
00385 #endif
00386                                 char filterName[MAX_FNAME_LENGTH+1], portName[MAX_PTNAME_LENGTH+1], 
00387                                         policyName[MAX_PLNAME_LENGTH+1], polibName[MAX_PLNAME_LENGTH+1];
00388                                 int i=0;
00389                                 //dont want to read junk
00390                                 policyName[0] = '\0';
00391                                 polibName[0] = '\0';
00392                                 filterName[0] = '\0';
00393                                 portName[0] = '\0';
00394 
00395                                 while (atts[i] != NULL){
00396                                         if ( strcasecmp(atts[i], "filter") == 0 ){
00397                                                 filInd = i+1;
00398                                                 strncpy(filterName, atts[i+1], MAX_FNAME_LENGTH);
00399                                                 filterName[MAX_FNAME_LENGTH] = '\0';
00400                                         }
00401                                         else if ( strcasecmp(atts[i], "port") == 0 ){
00402                                                 portInd = i+1;
00403                                                 strncpy(portName, atts[i+1], MAX_PTNAME_LENGTH);
00404                                                 portName[MAX_PTNAME_LENGTH] = '\0';
00405                                         }
00406                                         else if ( strcasecmp(atts[i], "policy") == 0 ){
00407                                                 polInd = i+1;
00408                                                 strncpy(policyName, atts[i+1], MAX_PLNAME_LENGTH);
00409                                                 policyName[MAX_PLNAME_LENGTH] = '\0';
00410                                         }
00411                                         else if ( strcasecmp(atts[i], "policyLib") == 0 ){
00412                                                 polibInd = i+1;
00413                                                 strncpy(polibName, atts[i+1], MAX_PLNAME_LENGTH);
00414                                                 polibName[MAX_PLNAME_LENGTH] = '\0';
00415                                         }
00416 #ifdef VOID_TERM
00417                                         else if ( strcasecmp(atts[i], "breakLoop") == 0){
00418                                                 if ( strcasecmp(atts[i+1], "yes") == 0){
00419                                                         breakLoop = 1;  
00420                                                 }else if ( strcasecmp(atts[i+1], "no") != 0){
00421                                                         state = error; // exist break loop but its not true or false
00422                                                 }
00423                                         }
00424 #endif
00425                                         else {
00426                                                 //invalid attribute
00427                                                 state = error;
00428                                         }
00429 
00430                                         i+=2;
00431                                 }
00432 
00433                                 if ( (filInd == -1) || (portInd == -1) || (state == error) ) {
00434                                         state = error;
00435                                         strcpy(errorMsg, "Expecting <from filter=\"filter_name\" port=\"port_name\" [policy=\"policy_name\" policyLib=\"\"] />");
00436                                 }
00437                                 else {
00438                                         //default policy
00439                                         if (strlen(policyName) == 0)
00440                                                 strcpy(policyName, "rr");
00441                                         
00442                                         //lets set stream origin
00443                                         // fills stream FROM part
00444                                         if (!setFrom(currentStream,
00445                                                 getFilterSpecByName(systemLayout, filterName),
00446                                                 portName, policyName, polibName
00447 #ifdef VOID_TERM
00448                                                 , breakLoop
00449 #endif
00450                                                 )){
00451                                                 state = error;
00452                                                 strcpy(errorMsg, "Invalid Policy or labeled stream requires a policy lib name");
00453                                                 return;
00454                                         }
00455                                         if (polInd != -1)
00456                                                 printf("\tparser.c: filter %s:%s(%s) writes to ", filterName, portName, policyName);
00457                                         else
00458                                                 printf("\tparser.c: filter %s:%s(default policy) writes to ", filterName, portName);
00459 
00460                                 }
00461                         }
00462                         else {
00463                                 state = error;
00464                                 strcpy(errorMsg, "Expecting <from filter=\"filter_name\" port=\"port_name\" [policy=\"policy_name\"] />");
00465                         }
00466 
00467                 break;
00468                 case fromto:
00469                         //reads stream <to />
00470                         if (strcasecmp(name, "to") == 0){
00471                                 int filInd = -1, portInd = -1, polInd = -1;
00472                                 int i=0;
00473                                 char filterName[MAX_FNAME_LENGTH+1], portName[MAX_PTNAME_LENGTH+1], 
00474                                         policyName[MAX_PLNAME_LENGTH+1];
00475 
00476                                 while (atts[i] != NULL){
00477                                         if ( strcasecmp(atts[i], "filter") == 0 ){
00478                                                 filInd = i+1;
00479                                                 strncpy(filterName, atts[i+1], MAX_FNAME_LENGTH);
00480                                                 filterName[MAX_FNAME_LENGTH] = '\0';
00481                                         }
00482                                         else if ( strcasecmp(atts[i], "port") == 0 ){
00483                                                 portInd = i+1;
00484                                                 strncpy(portName, atts[i+1], MAX_PTNAME_LENGTH);
00485                                                 portName[MAX_PTNAME_LENGTH] = '\0';
00486                                         }
00487                                         else if ( strcasecmp(atts[i], "policy") == 0 ){
00488                                                 polInd = i+1;
00489                                                 strncpy(policyName, atts[i+1], MAX_PLNAME_LENGTH);
00490                                                 policyName[MAX_PLNAME_LENGTH] = '\0';
00491                                         }
00492                                         else {
00493                                                 //invalid attribute
00494                                                 state = error;
00495                                         }
00496                                         i+=2;
00497                                 }
00498 
00499                                 if ( (filInd == -1) || (portInd == -1) || (state == error) ){
00500                                         state = error;
00501                                         strcpy(errorMsg, "Expecting <to filter=\"filter_name\" port=\"port_name\" [policy=\"policy_name\"] />");
00502                                 }
00503                                 else {
00504 
00505                                         // fills stream TO part
00506                                         if (!setTo(currentStream, 
00507                                                 getFilterSpecByName(systemLayout, filterName), 
00508                                                 portName, policyName)){
00509                                                 state = error;
00510                                                 strcpy(errorMsg, "Error setting stream destination");
00511                                                 return;
00512                                         }
00513                                         if (polInd != -1)
00514                                                 printf("filter %s:%s\n", filterName, portName);
00515                                         else
00516                                                 printf("filter %s:%s\n", filterName, portName);
00517                                 }
00518                         }
00519                         else {
00520                                 state = error;
00521                                 strcpy(errorMsg, "Expecting <to filter=\"filter_name\" port=\"port_name\" [policy=\"policy_name\"] />");
00522                         }
00523                 break;
00524                 case tostream:
00525                         // we cant open tag in this state
00526                         state = error;
00527                         strcpy(errorMsg, "Expecting </stream>");
00528                 break;
00529                 case preend:
00530                         // same
00531                         state = error;
00532                         strcpy(errorMsg, "Expecting </config>");
00533                 break;
00534                 case end:
00535                         //junk after </config>
00536                         strcpy(errorMsg, "Expecting eof after </config>");
00537                         state = error;
00538                 break;
00539                 default:
00540                 break;
00541         }
00542 
00543 }
00544 
00545 /// this function is called whenever a tag is closed
00546 void fechaTag(void *userData, const XML_Char *name){
00547         Layout *systemLayout = (Layout*)userData;
00548 
00549         lastState = state;
00550         
00551         switch (state){
00552                 case hostdec:
00553                         //close hostdec
00554                         if ( strcasecmp("hostdec", name) == 0){
00555                                 state = preplace;
00556                                 printf("\tparser.c: ...\n");
00557                         }
00558                         else {
00559                                 state = error;
00560                                 strcpy(errorMsg, "Expecting </hostdec>");
00561                         }
00562                 break;
00563                 case resources:
00564                 {
00565                         if (strcasecmp("resource", name) == 0){
00566                                 //do nothing
00567                         }
00568                         else if ( strcasecmp("host", name) == 0){
00569                                 state = hostdec; //go back to hostdec
00570                         }
00571                 }
00572                 break;
00573                 case prelay:
00574                 break;
00575                 case filter:
00576                 {
00577                         // host empty tag, no state change
00578                         // or filter close tag, change state
00579                         if ( strcasecmp("filter", name) == 0){
00580                                 while (remainingInstances > 0){
00581                                         //spawn the remaing hosts
00582                                         HostsStruct *hs = systemLayout->hostsStruct;
00583                                         int hid = hostsGetIndex(hs);
00584                                         if (hid == -1){
00585                                                 state = error;
00586                                                 sprintf(errorMsg, "Error filling remaining hosts");
00587                                                 return;
00588                                         }
00589                                         
00590                                         
00591                                         if (addHostToFilter(currentFilter, hostsGetName(hs, hid)) == -1){
00592                                                 state = error;
00593                                                 sprintf(errorMsg, "Error adding host %s to filter %s", hostsGetName(hs, hid), currentFilter->name);
00594                                                 return;
00595                                         }
00596 
00597                                         printf("\t\tparser.c: instance %s(chosen randomly)\n", systemLayout->hostsStruct->hosts[hid].name);
00598                                         remainingInstances--;
00599                                 }
00600                                 
00601                                 state = placement;
00602                                 addFilterSpec(systemLayout, currentFilter);
00603                         }
00604                         else if ( strcasecmp("instance", name) == 0 ){
00605                                 //do nothing
00606                                 
00607                         }
00608                         else {
00609                                 state = error;
00610                                 strcpy(errorMsg, "Expecting </filter> or <instance />");
00611                         }
00612                 }
00613                 break;
00614                 case placement:
00615                         if (strcasecmp("placement", name) == 0){
00616                                 state = prelay;
00617                                 printf("\tparser.c: ...\n");    
00618                         }
00619                         else {
00620                                 strcpy(errorMsg, "Expecting </placement>");
00621                                 state = error;
00622                         }
00623                 break;
00624                 case stream:
00625                         if ( strcasecmp("from", name) == 0 ){
00626                                 state = fromto;
00627                         }
00628                         else {
00629                                 strcpy(errorMsg, "Expecting <from />");
00630                                 state = error;
00631                         }
00632                 break;
00633                 case fromto:
00634                         if ( strcasecmp("to", name) == 0 ){
00635                                 state = tostream;
00636                         }
00637                         else {
00638                                 strcpy(errorMsg, "Expecting <to />");
00639                                 state = error;
00640                         }
00641                 break;
00642                 case tostream:
00643                         if ( strcasecmp("stream", name) == 0 ){
00644                                 state = layout;
00645                                 addStreamSpec(systemLayout, currentStream);
00646                         }
00647                         else {
00648                                 strcpy(errorMsg, "Expecting </stream>");
00649                                 state = error;
00650                         }
00651 
00652                 break;
00653                 case layout:
00654                         if ( strcasecmp("layout", name) == 0){
00655                                 state = preend;
00656                         }
00657                         else {
00658                                 strcpy(errorMsg, "Expecting </layout>");
00659                                 state = error;
00660                         }
00661                 break;
00662                 case preend:
00663                         if (strcasecmp(name, "config") == 0)
00664                                 state = end;
00665                 break;
00666                 case end:
00667                         //junk after </config>
00668                         state = error;
00669                 break;
00670                 default:
00671                 break;
00672         }
00673 }
00674 
00675 int readConfig(char *fileName, Layout *l) {
00676         FILE *arq;
00677         char buffer[1]; //read char by char
00678         XML_Parser parser = XML_ParserCreate(NULL);
00679         
00680         arq = fopen(fileName, "ro");
00681         if (arq == NULL){
00682                 char erro[200];
00683                 sprintf(erro, "Error opening configuration file: %s", fileName);
00684                 perror(erro);
00685                 exit(1);
00686         }
00687 
00688         //handlers and user data
00689         XML_SetElementHandler(parser, abreTag, fechaTag);
00690         XML_SetUserData(parser, (void*)l);
00691 
00692         //loop till the end
00693         while ( (state != end) && (state != error) && (state != parseerror) && (!feof(arq)) ){
00694                 fread(buffer, sizeof(char), 1, arq);
00695 
00696                 if (XML_Parse(parser, buffer, 1, 0)== 0)
00697                         state = parseerror;
00698         }
00699 
00700         // possible errors: 
00701         // parseerror- XML parse error
00702         // error: parse error too, a tag Void does not recognize
00703 
00704         // last one: unexpected eof
00705         if (state == parseerror){
00706                 //XML parse error
00707                 printf("\tparser.c: parse error!!!\n");
00708                 printf("\tparser.c: %s line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser) );
00709                 printf("\tparser.c: state = %s\n", stateNames[lastState]);
00710                 return (-1);
00711         }
00712         else if (state == error){
00713                 //DS parse error
00714                 printf("\tparser.c: Parse error!!!\n");
00715                 printf("\tparser.c: Wrong file format, line: %d\n", XML_GetCurrentLineNumber(parser));
00716                 printf("\tparser.c: %s\n", errorMsg);
00717                 printf("\tparser.c: State = %s\n", stateNames[lastState]);      
00718                 return (-1);
00719         }
00720         else if (state != end){
00721                 //eof b4 </config>
00722                 printf("\tparser.c: Unexpected end of file!!!\n");
00723                 printf("\tparser.c: State = %s\n", stateNames[lastState]);      
00724                 return (-1);
00725         }
00726 
00727         // got here, ok!
00728         fclose(arq);
00729 
00730         //free the parser
00731         XML_ParserFree(parser);
00732         return 1;
00733 }
00734 

Generated on Tue Jan 17 19:18:38 2006 for Void by  doxygen 1.4.6