Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

idep_alutil.cxx

Go to the documentation of this file.
00001 // idep_alutil.c
00002 #include "idep_aliasutil.h"
00003 #include "idep_aliastable.h"
00004 #include "idep_tokeniter.h"
00005 #include "idep_string.h"
00006 
00007 #include <fstream>   // ifstream
00008 #include <iostream>
00009 #include <cassert> 
00010 
00011                 // -*-*-*- static functions -*-*-*-
00012 
00013 static std::ostream& warning(std::ostream& orr, const char *file, int lineno)
00014 {
00015     return orr << "Warning in " << file << '(' << lineno << "): ";
00016 }
00017  
00018 static std::ostream& err(std::ostream& orr, const char *file, int lineno)
00019 {
00020     return orr << "Error in " << file << '(' << lineno << "): ";
00021 }
00022 
00023 static int tryToAlias(idep_AliasTable *table, std::ostream& orr, 
00024                       const char *inputName, int lineno, 
00025                       const char *componentName, const char *alias)
00026 {
00027     if (table->add(alias, componentName) < 0) {
00028         const char *previousName = table->lookup(alias);
00029         err(orr, inputName, lineno) << "two names for alias \"" 
00030             << alias << "\":" << std::endl << "    \"" << previousName
00031             << "\" and \"" << componentName << "\"" << std::endl;
00032         return 1;
00033     }
00034     return 0;
00035 }
00036 
00037                 // -*-*-*- idep_AliasUtil -*-*-*-
00038 
00039 int idep_AliasUtil::readAliases(idep_AliasTable *table, std::ostream& orr, 
00040                                    std::istream& in, const char *inputName)
00041 {
00042     // The following is a state-machine description of the alias language:
00043 
00044     enum State {
00045         START,          // starting a new alias
00046         CONTINUE_0,     // continue - no previous identifiers
00047         IDENT_0,        //    ident - no previous identifiers
00048         CONTINUE_1,     // continue - one previous identifier
00049         CONTINUE_NL,    // continue - newline terminated
00050         IDENT_NL,       //    ident - newline terminated
00051         NEWLINE_BL,     //  newline - blank line terminated
00052         CONTINUE_BL,    // continue - blank line terminated
00053         IDENT_BL,       //    ident - blank line terminated
00054         NUM_STATES      // must be last entry
00055     } state = START;
00056  
00057     enum Input {
00058         CONTINUE,       // continuation character by it self
00059         NEWLINE,        // end of line
00060         IDENT,          // indentifier (not the previous two)
00061         NUM_INPUTS      // must be last entry
00062     } input;
00063 
00064     enum Action { 
00065         NOP,            // do nothing
00066         BEG_CUR,        // set component name to current token
00067         BEG_PRE,        // set component name to previous token
00068         BEG_PRE_CUR,    // set component name to previous and try current token
00069         TRY_CUR,        // try to alias current token to component name
00070         TRY_PRE,        // try to alias previous token to component name
00071         TRY_PRE_CUR,    // try to alias both tokens to component name
00072         END,            // unset component name
00073         NUM_ACTIONS     // must be last entry
00074     };
00075 
00076     static State nextStateTable[NUM_STATES][NUM_INPUTS] = {
00077         //CONTINUE      NEWLINE         IDENT
00078         { CONTINUE_0,   START,          IDENT_0         }, // START
00079         { CONTINUE_1,   START,          IDENT_NL        }, // CONTINUE_0
00080         { CONTINUE_1,   NEWLINE_BL,     IDENT_NL        }, // IDENT_0
00081         { CONTINUE_NL,  IDENT_0,        IDENT_NL        }, // CONTINUE_1
00082         { CONTINUE_NL,  IDENT_NL,       IDENT_NL        }, // CONTINUE_NL
00083         { CONTINUE_NL,  START,          IDENT_NL        }, // IDENT_NL
00084         { CONTINUE_BL,  START,          IDENT_BL        }, // NEWLINE_BL
00085         { CONTINUE_BL,  IDENT_BL,       IDENT_BL        }, // CONTINUE_BL
00086         { CONTINUE_BL,  NEWLINE_BL,     IDENT_BL        }  // IDENT_BL
00087     };
00088 
00089     static Action actionTable[NUM_STATES][NUM_INPUTS] = {
00090         //CONTINUE      NEWLINE         IDENT
00091         { NOP,          NOP,            BEG_CUR         }, // START
00092         { BEG_PRE,      NOP,            BEG_PRE_CUR     }, // CONTINUE_0
00093         { NOP,          NOP,            TRY_CUR         }, // IDENT_0
00094         { TRY_PRE,      NOP,            TRY_PRE_CUR     }, // CONTINUE_1
00095         { TRY_PRE,      NOP,            TRY_PRE_CUR     }, // CONTINUE_NL
00096         { NOP,          END,            TRY_CUR         }, // IDENT_NL
00097         { NOP,          END,            TRY_CUR         }, // NEWLINE_BL
00098         { TRY_PRE,      NOP,            TRY_PRE_CUR     }, // CONTINUE_BL
00099         { NOP,          NOP,            TRY_CUR         }  // IDENT_BL
00100     };
00101 
00102     const char *const EMPTY_NAME = "";
00103     const char NULL_CHAR = *EMPTY_NAME;
00104     const char COMMENT_CHAR = '#';
00105     const char CONTINUE_CHAR = '\\';
00106     const char NEWLINE_CHAR = '\n';
00107  
00108     int numBadAliases = 0;
00109     int lineno = 1;
00110 
00111     idep_String componentName = EMPTY_NAME;
00112     idep_String lastToken = EMPTY_NAME;
00113     Input lastInput = IDENT;
00114 
00115     for (idep_TokenIter it(in); it; ++it) {
00116         if (*it() == COMMENT_CHAR) {
00117             while (*it() != NEWLINE_CHAR) {
00118                 ++it;                   // ignore all tokens until newline
00119             }
00120         }
00121 
00122         // Determine the input type:
00123 
00124         switch (*it()) {
00125           case CONTINUE_CHAR: {
00126             input = NULL_CHAR == it()[1] ? CONTINUE : IDENT;
00127           } break;
00128           case NEWLINE_CHAR: {
00129             input = NEWLINE;
00130           } break;
00131           default: {
00132             input = IDENT;
00133           } break;
00134         };
00135 
00136         // Perform the selected action:
00137 
00138         switch (actionTable[state][input]) {
00139           case NOP: {
00140           } break;
00141           case BEG_CUR: {
00142             componentName = it();
00143           } break;
00144           case BEG_PRE: {
00145             componentName = lastToken;
00146             warning(orr, inputName, lineno) << '"' << lastToken 
00147                 << "\" << used as component name." << std::endl;
00148           } break;
00149           case BEG_PRE_CUR: {
00150             componentName = lastToken;
00151             numBadAliases += tryToAlias(table, orr, inputName, lineno,
00152                                                         componentName, it());
00153             warning(orr, inputName, lineno) << '"' << lastToken 
00154                 << "\" << used as component name." << std::endl;
00155           } break;
00156           case TRY_CUR: {
00157             numBadAliases += tryToAlias(table, orr, inputName, lineno,
00158                                                         componentName, it());
00159           } break;
00160           case TRY_PRE: {
00161             numBadAliases += tryToAlias(table, orr, inputName, lineno,
00162                                                    componentName, lastToken);
00163             warning(orr, inputName, lineno) << '"' << lastToken 
00164                 << "\" << used as alias name." << std::endl;
00165           } break;
00166           case TRY_PRE_CUR: {
00167             numBadAliases += tryToAlias(table, orr, inputName, lineno,
00168                                                    componentName, lastToken);
00169             numBadAliases += tryToAlias(table, orr, inputName, lineno,
00170                                                         componentName, it());
00171             warning(orr, inputName, lineno) << '"' << lastToken 
00172                 << "\" << used as alias name." << std::endl;
00173           } break;
00174           case END: {
00175             componentName = EMPTY_NAME;
00176           } break;
00177           default: 
00178           case NUM_ACTIONS: {
00179             assert(0);
00180           }
00181         };
00182 
00183         // Advance to the next state:
00184                 
00185         if (NEWLINE == input) {
00186             ++lineno;                           // end of line
00187         }
00188         
00189         lastToken = it();
00190         lastInput = input;
00191 
00192         state = nextStateTable[state][input];
00193     }
00194 
00195     return numBadAliases;                       // 0 on success
00196 }
00197 
00198 
00199 int idep_AliasUtil::readAliases(idep_AliasTable *table, std::ostream& orr, 
00200                                                         const char *fileName)
00201 {
00202     enum { IOERROR = -1 };
00203     std::ifstream in(fileName);
00204     if (!in) {
00205         return IOERROR;
00206     }
00207     return readAliases(table, orr, in, fileName);
00208 }
00209    

Generated on Mon Feb 15 11:06:48 2010 for loon by  doxygen 1.3.9.1