Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

protomake.y

Go to the documentation of this file.
00001 %{
00009 #include <map>
00010 #include <vector>
00011 #include <typeinfo>
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <ctype.h>
00016 using namespace std;
00017 
00018 #include "nodes/protomake.h"
00019 
00021 int yylex(void);
00022 
00027 extern int lines;
00028 
00032 Program *root;
00033 
00034 int yyerror(char *msg);
00035 
00036 typedef struct FieldTypeInfo
00037 {
00038         FieldType::FType fType;
00039 
00040         union {
00041                 int numChars;
00042                 char *cteStr;
00043                 char *terminator;
00044                 char *blanks;
00045         } info;
00046 } FieldTypeInfo;
00047 
00049 /*
00050 static void generateEtherealPlugin(map<string, vector<FieldInfo> > *fiMap,
00051                                    multimap<EtherType, EtherInfoType> *eit);
00052 
00053 static void writeHeader(FILE *plugin, char *fileName,
00054                         multimap<EtherType, EtherInfoType> *eit); 
00055 
00056 static void writeDissector(FILE *plugin, map<string, vector<FieldInfo> > *fiMap,
00057                            multimap<EtherType, EtherInfoType> *eit);
00058 
00059 static void writeRest(FILE *plugin, char *trans, char *port, char *abbrev);
00060 */
00061 %}
00062 
00064 %union {
00065         long number;
00066         char *string;
00067         SimpleImport *simpImp;
00068         Import *import;
00069         IdentifierList *idLst;
00070         Behavior *behavior;
00071         SimpleBehavior *simpBhv;
00072         Message *message;
00073         SimpleMessage *simpMsg;
00074         FieldType::FType fType;
00075         FieldTypeInfo fTypeInfo;
00076         FieldType *fieldType
00077         Expression *exp;
00078         FieldDeclaration *fieldDcl;
00079         SimpleFieldDeclaration *simpFld;
00080         StringLiteral *strLit;
00081         Process *proc;
00082         SimpleProcess *simpProc;
00083         Declaration *decl;
00084         SimpleDeclaration *simpDecl;    
00085         Action *action;
00086         SimpleAction *simpAct;
00087         Type *type;
00088         Guard *guard;
00089         Statement *stmt;
00090         SimpleStatement *simpStmt;
00091         ArrayReference *arrayRef;
00092         LeftSideList *leftSideLst;
00093         LeftSide *leftSide;
00094         GuardedStatement *guardStmt;
00095         SimpleGuardedStatement *simpGuardStmt;
00096         FieldReference *fieldRef;
00097         ExpressionList *expLst;
00098 }
00099 
00104 %token<string>  tBEHAVIOR
00105 %token<string>  tID
00106 %token<string>  tSTRING
00107 %token<string>  tTERMSTRING
00108 %token<number>  tNUMBER
00109 %token<string>  tMESSAGE
00110 %token<string>  tIMPORT
00111 %token<string>  tEXTERNAL
00112 %token<string>  tBEGIN
00113 %token<string>  tEND
00114 %token<string>  tBITS
00115 %token<string>  tBYTES
00116 %token<string>  tSTRTYPE
00117 %token<string>  tBLANKS
00118 %token<string>  tPROCESS
00119 %token<string>  tGLOBAL
00120 %token<string>  tCONST
00121 %token<string>  tVAR
00122 %token<string>  tINTEGER
00123 %token<string>  tADDRESS
00124 %token<string>  tCLIENTADDRESS
00125 %token<string>  tSERVERADDRESS
00126 %token<string>  tARRAY
00127 %token<string>  tOF
00128 %token<string>  tRCV
00129 %token<string>  tFROM
00130 %token<string>  tTIMEOUT
00131 %token<string>  tSKIP
00132 %token<string>  tSEND
00133 %token<string>  tTO
00134 %token<string>  tIF
00135 %token<string>  tFI
00136 %token<string>  tDO
00137 %token<string>  tOD
00138 %token<string>  tACT
00139 %token<string>  tIN
00140 %token<string>  tPLUS
00141 %token<string>  tMINUS
00142 %token<string>  tTIMES
00143 %token<string>  tDIVIDE
00144 %token<string>  tBAND
00145 %token<string>  tBOR
00146 %token<string>  tNEG
00147 %token<string>  tDIFFERENT
00148 %token<string>  tLTE
00149 %token<string>  tGTE
00150 %token<string>  tEQUAL
00151 %token<string>  tLT
00152 %token<string>  tGT
00153 %token<number>  tGUARD
00154 %token<number>  tLBRACKET
00155 %token<number>  tRBRACKET
00156 %token<number>  tLPAR
00157 %token<number>  tRPAR
00158 %token<number>  tCOMMA
00159 %token<number>  tCOLON
00160 %token<number>  tSCOLON
00161 %token<number>  tACTION
00162 %token<number>  tDOT
00163 %token<number>  tRANGE
00164 %token<number>  tASSIGN
00165 %token<number>  tDQUOTE
00166 %token<string>  tSTART
00167 %token<string>  tSTOP
00168 
00170 %type<string>   Program
00171 %type<import>   Imports
00172 %type<import>   ReallyImport
00173 %type<simpImp>  Import
00174 %type<behavior> Behaviors
00175 %type<behavior> RealBehavior
00176 %type<simpBhv>  Behavior
00177 %type<message>  Messages
00178 %type<proc>             Processes
00179 %type<simpProc> RealProcess
00180 %type<simpMsg>  Message
00181 %type<number>   External
00182 %type<fieldDcl> MessageBody
00183 %type<fieldDcl> Fields
00184 %type<simpFld>  Field
00185 %type<fieldTyp> FieldType
00186 %type<exp>              Init
00187 %type<fType>    BitByte
00188 %type<fTypeInfo>StrType
00189 %type<simpDecl> DeclarationTypes
00190 %type<decl>             Declarations
00191 %type<number>   Global
00192 %type<idLst>    IDs
00193 %type<type>             Type
00194 %type<action>   Actions
00195 %type<simpAct>  Action
00196 %type<guard>    GuardedAction
00197 %type<exp>              Expression
00198 %type<fieldRef>         FieldReference
00199 %type<arrayRef>         ArrayReference
00200 %type<exp>              ArrayPosition
00201 %type<stmt>             Statements
00202 %type<simpStmt> Statement
00203 %type<leftSideLst>      LeftSides
00204 %type<leftSide> LeftSide
00205 %type<expLst>   Expressions
00206 %type<guardStmt>        GuardedStatements
00207 %type<simpGuardStmt>    GuardedStatement
00208 
00210 %nonassoc tBOR, tBAND
00211 %nonassoc tNEG
00212 %nonassoc tLT, tLTE, tGT, tGTE, tEQUAL, tDIFFERENT
00213 %left tASSIGN
00214 %left tPLUS, tMINUS
00215 %left tTIMES, tDIVIDE
00216 %left UMINUS
00217 
00218 %%
00219 
00222 Program : Imports Behaviors Messages Processes
00223                         {
00224                                 root = new Program(new SrcPosition(1),  $1, $2, $3, $4);
00225                 } 
00226                 ;
00227                         
00230 Imports : ReallyImport { $$ = $1; }
00231                 | { $$ = NULL; }
00232                 ;
00233 
00235 ReallyImport    : Import
00236                                         {
00238                                                 $$ = $1;
00239                                         }
00240                                 | ReallyImport Import
00241                                         {
00242                                                 $$ = new SequentialImport($2->getPosition(), $1, $2);
00243                                         }
00244                                 ;
00245 
00247 Import  : tIMPORT tSTRING
00248                         {
00250                                 SrcPosition *srcPos = new SrcPosition(lines);
00251                                 StringLiteral *str = new StringLiteral(srcPos, $2);
00252                                 $$ = new SimpleImport(srcPos,  str);
00253                         }
00254                 | error { yyerror("Import sintax error!"); }
00255                 ;
00256 
00259 Behaviors       : RealBehavior { $$ = $1; }
00260                         | { $$ = NULL}
00261                         ;
00262 
00264 RealBehavior    : Behavior
00265                                         {
00266                                                 $$ = $1; 
00267                                         }
00268                                 | RealBehavior Behavior
00269                                         {
00270                                                 $$ = new SequentialBehavior($2->getPosition(), $1, $2);
00271                                         }
00272                                 ;
00273 
00275 Behavior        : tBEHAVIOR IDs
00276                                 {
00277                                         $$ = new SimpleBehavior($2->getPosition(), $2);
00278                                 }
00279                         ;
00280 
00283 Messages        : Message { $$ = $1; }
00284                         | Messages Message { $$ = new SequentialMessage($2->getPosition(), $1, $2); }
00285                         ;
00286 
00289 Message : External tMESSAGE tID tLPAR tID tCOMMA tID tRPAR MessageBody
00290                         {
00291                                 $$ = new SimpleMessage($9->getPosition(), new Identifier($9->getPosition(), $3),
00292                                                                            $9, new Identifier($9->getPosition(), $5),
00293                                                                            new Identifier($9->getPosition(), $7), $1);
00294                         }
00295                 | External tMESSAGE tID MessageBody
00296                         {
00297                                 $$ = new SimpleMessage($4->getPosition(), new Identifier($4->getPosition(), $3),
00298                                                                            $4, NULL, NULL, $1);
00299             }
00300                 ;
00301 
00304 External        : tEXTERNAL { $$ = 1; }
00305                         | { $$ = 0 }
00306                         ;
00307 
00310 MessageBody     : tBEGIN Fields tEND { $$ = $2; }
00311                         | error { yyerror("Message body sintax error!"); }
00312                         ;
00313 
00316 Fields  : Field { $$ = $1; }
00317                 | Fields tCOMMA Field { $$ = new SequentialFieldDeclaration($3->getPosition(), $1, $3); }
00318                 ;
00319 
00322 Field   : tID tCOLON FieldType Init
00323                         {
00324                                 Identifier *id = new Identifier($1->getPosition(), $1);
00325                                 $$ = new SimpleFieldDeclaration($1->getPosition(), id, $2, $3, $4);
00326                         }
00327 
00328                 | tID tGUARD tCOLON tSTRTYPE tLPAR tTERMSTRING tRPAR tSTOP tLPAR tTERMSTRING tRPAR
00329                         {
00330                                 // Falta terminar!!!!!
00331                                 $$ = NULL
00332                         }
00333                 | error { yyerror("Field declaration sintax error!"); }
00334                 ;
00335 
00338 Init    : tEQUAL Expression { $$ = $2; }
00339                 | { $$ = NULL; }
00340                 ;
00341 
00344 FieldType       : Expression BitByte
00345                                 {
00346                                         $$ = new FieldType($1->getPosition(), $1, $2);
00347                                 }
00348 
00349                         | StrType
00350                                 {
00351                                         // Falta terminar!!!
00352                                         $$ = NULL;
00353                                 }
00354                                 
00355                         | error { yyerror("Field type sintaxe error!"); }
00356                         ;
00357 
00360 BitByte : tBITS { $$ = FieldType::BIT; }
00361                 | tBYTES { $$ = FieldType::BYTE; }
00362                 | error { yyerror("Undefined field type!"); }
00363                 ;
00364                         
00365 StrType : tSTRTYPE tLPAR tNUMBER tRPAR 
00366                         {
00367                                 $$.fType = FieldType::STRN;
00368                                 $$.info.number = $3;
00369                         }
00370                                 
00371                 | tSTRTYPE tLPAR tSTRING tRPAR
00372                         {
00373                                 $$.fType = FieldType::STRCTE;
00374                                 $$.info.cteStr = $3;
00375                         }
00376                 | tSTRTYPE tLPAR tTERMSTRING tRPAR
00377                         {
00378                                 $$.fType = FieldType::STRTERM;
00379                                 $$.info.terminator = $3;
00380                         }
00381                 | tBLANKS tLPAR tTERMSTRING tRPAR
00382                         {
00383                                 $$.fType = FieldType::BLANKS;
00384                                 $$.info.blanks = $3;
00385                         }
00386                                 
00387                 | error { yyerror("Undefined field type!"); }
00388                 ;
00389 
00392 Processes       : RealProcess
00393                           {
00394                                         $$ = $1;
00395                           }
00396                         | Processes RealProcess
00397                           {
00398                                         $$ = new SequentialProcess($2->getPosition(), $1, $2);
00399                           }
00400                         ;
00401 
00403 RealProcess     : tPROCESS tID Declarations tBEGIN Actions tEND
00404                             {
00405                                         // Falta ajeitar!
00406                                         $$ = new SimpleProcess($4->getPosition(), 
00407                                                      new Identifier($4->getPosition(), $3), $4, $6, 0);
00408                                 }
00409                         | error { yyerror("Process defenition sintax error!"); }
00410                         ;
00411 
00414 DeclarationTypes        : tCONST IDs tCOLON Type Init 
00415                                                 { 
00416                                                         $$ = new SimpleDeclaration(new SrcPosition(lines), $2, $4, $5, true); 
00417                                                 }
00418                                         | Global tVAR IDs tCOLON Type Init 
00419                                                 {
00420                                                         $$ = new SimpleDeclaration(new SrcPosition(lines), $3, $5, $6, false, $1);
00421                                                 } 
00422                                                 
00423                                         | { $$ = NULL; }
00424                                         | error { yyerror("DeclarationType syntax error!"); }
00425                                         ;
00426 
00427 Global  : tGLOBAL { $$ = 1;}
00428                 | { $$ = 0;}
00429                 ;
00430 
00433 Declarations    : DeclarationTypes 
00434                                         {
00435                                                 $$ = $1;
00436                                         }
00437                                 | Declarations tSCOLON DeclarationTypes 
00438                                         { 
00439                                                 $$ = new SequentialDeclaration($3->getPosition(), $1, $3);
00440                                         }
00441                                 ;
00442 
00443 
00446 IDs     : tID
00447                 {
00448                         Identifier *identifier = new Identifier(new SrcPosition(lines), $1);
00449                         $$ = new SimpleIdentifierList(identifier->getPosition(), identifier);
00450                 }
00451                 
00452         | IDs tCOMMA tID
00453                 {
00454                         Identifier *identifier = new Identifier(new SrcPosition(lines), $3);
00455                         SimpleIdentifierList *simpIdList = new SimpleIdentifierList(identifier->getPosition(), identifier);
00456                         $$ = new SequentialIdentifierList(identifier->getPosition(), $1, simpIdList);                                    
00457                 }
00458                 
00459         | error { yyerror("Identifier list sintax error!"); }
00460         ;
00461 
00464 Type    : tINTEGER {$$ = new Type(new SrcPosition(lines), Type::INTEGER);}
00465                 | tNUMBER tRANGE tNUMBER { $$ = new RangeType(new SrcPosition(lines), Type::RANGE, $1, $3); }
00466                 | tADDRESS { $$ = new Type(new SrcPosition(lines), Type::ADDRESS); }
00467                 | tCLIENTADDRESS { $$ = new Type(new SrcPostion(lines), Type::CLIENTADDRESS); }
00468                 | tSERVERADDRESS { $$ = new Type(new SrcPostion(lines), Type::SERVERADDRESS); }
00469                 | tARRAY tLBRACKET tNUMBER tRBRACKET tOF Type {$$ = new ArrayType(new SrcPosition(lines), Type::ARRAY, $6, $3);}
00470                 | error {yyerror("Undefined type!");}
00471                 ;
00472 
00475 Actions : Action {$$ = $1;}
00476                 | Actions tGUARD Action {$$ = new SequentialAction($3->getPosition(), $1, $3);}
00477                 ;
00478 
00484 Action  : GuardedAction tACTION Statements {$$ = new SimpleAction($1->getPosition(), $1, $3);}
00485             | error {yyerror("Action syntax error!");}
00486                 ;
00487 
00490 GuardedAction   : Expression { $$ = new GuardExpression($1->getPosition(), $1); }
00491                                 | tRCV tID tFROM tID
00492                                         {
00493                                                 // Falta ajeitar!!
00494                                                 SrcPosition *pos = new SrcPosition(lines);
00495                                                 
00496                                                 ReceiveStatement *rs = new ReceiveStatement(pos, new Identifier(pos, $2),
00497                                                                                                                                         new Identifier(pos, $4), NULL);
00498                                                 $$ = new GuardReceive(pos, rs);
00499                                         }
00500                                 | tTIMEOUT tID
00501                                         {
00502                                                 SrcPosition *pos = new SrcPosition(lines);
00503                                         
00504                                                 $$ = new GuardTimeout(pos, new Identifier(pos, $2));
00505                                         }
00506                                 | error { yyerror("Invalid guard!"); }
00507                                 ;
00508 
00511 Expression      : tLPAR Expression tRPAR { $$ = $2; }
00512                    
00513                         | Expression tEQUAL Expression
00514                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00515                                 
00516                         | Expression tGT Expression
00517                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00518                                 
00519                         | Expression tLT Expression
00520                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00521                                 
00522                         | Expression tGTE Expression
00523                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00524                                 
00525                         | Expression tLTE Expression
00526                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00527                                 
00528                         | Expression tDIFFERENT Expression
00529                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00530                                 
00531                         | Expression tBOR Expression
00532                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00533                                 
00534                         | Expression tBAND Expression
00535                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00536                                 
00537                         | Expression tPLUS Expression
00538                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00539                                 
00540                         | Expression tMINUS Expression
00541                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00542                                 
00543                         | Expression tTIMES Expression
00544                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00545                                 
00546                         | Expression tDIVIDE Expression
00547                                 { $$ = new BinaryExpression(new SrcPosition(lines), $1, $3, $2); }
00548                                 
00549                         | tNEG Expression { $$ = new UnaryExpression(new SrcPosition(lines), $2, $1); }
00550                         
00551                         | tMINUS Expression %prec UMINUS { $$ = new UnaryExpression(new SrcPosition(lines), $2, $1); }
00552 
00553                         | FieldReference { $$ = $1; }
00554                         | ArrayReference { $$ = $1; }
00555                         | tID { $$ = new Identifier(new SrcPosition(lines), $1); }
00556                         | tNUMBER { $$ = new IntegerLiteral(new SrcPosition(lines), $1); }
00557                         | tSTRING { $$ = new StringLiteral(new SrcPosition(lines), $1); }
00558                         ;
00559 
00562 FieldReference  : tID tDOT tID 
00563                                         { 
00564                                                 SrcPosition *pos = new SrcPosition(lines);
00565                                                 $$ = new FieldReference(pos, new Identifier(pos, $1), new Identifier(pos, $3)); 
00566                                         }
00567                                 ;
00568 
00571 ArrayReference  : tID ArrayPosition  { $$ = new SimpleArrayReference($2->getPosition(), new Identifier($2->getPosition(), $1), $2); }
00572                                 | ArrayReference ArrayPosition {$$ = new MultipleArrayReference($1->getPosition(), $1, $2);}
00573                                 ;
00574 
00577 ArrayPosition   : tLBRACKET Expression tRBRACKET { $$ = $2; }
00578                                 ;
00579 
00582 Statements      : Statement {$$ = $1;}
00583                         | Statements tSCOLON Statement {$$ = new SequentialStatement($3->getPosition(), $1, $3);}
00584                         ;
00585 
00588 Statement       : tSKIP {$$ = new SkipStatement(new SrcPosition(lines));}
00589                         | LeftSides tASSIGN Expressions {$$ = new AssignStatement($1->getPosition(), $1, $3);}
00590                         | tRCV tID tFROM tID
00591                                 {
00592                                         // Falta ajeitar!!
00593                                         SrcPosition *pos = new SrcPosition(lines);
00594                                         $$ = new ReceiveStatement(pos, new Identifier(pos, $2), new Identifier(pos, $4), NULL);
00595                                 }
00596                         | tSEND tID tTO tID
00597                                 {
00598                                         // Falta Ajeitar
00599                                         SrcPosition *pos = new SrcPosition(lines);
00600                                         $$ = new SendStatement(pos, new Identifier(pos, $2), new Identifier(pos, $4), NULL);
00601                                 }
00602                         | tIF GuardedStatements tFI { $$ = new IfStatement($2->getPosition(), $2); }
00603                         | tDO GuardedStatement tOD { $$ = new DoStatement($2->getPosition(), $2); }
00604                         | tACT tID tIN Expression { $$ = new ActStatement($4->getPosition(), new Identifier($4->getPosition(), $2) ,$4); }
00605                         | tSTART tID 
00606                                 {
00607                                         SrcPosition *pos = new SrcPosition(lines);
00608                                         $$ = new StartStatement(pos, new Identifier(pos, $2));
00609                                 }
00610                         | tSTOP { $$ = new StopStatement(new SrcPosition(lines)); }
00611 
00612                         | tID tDOT tID tLPAR Expressions tRPAR
00613                                 {
00614                                         $$ = new BehaviorStatement($5->getPosition(),
00615                                                                                            new Identifier($5->getPosition(), $1),
00616                                                                                            new Identifier($5->getPosition(), $3),
00617                                                                                            $5);
00618                                 }
00619                         ;
00620 
00623 LeftSides       : LeftSide { $$ = new SimpleLeftSideList($1->getPosition(), $1); }
00624                         | LeftSides tCOMMA LeftSide
00625                                 {
00626                                         $$ = new SequentialLeftSideList($3->getPosition(), $1,
00627                                                                                                         new SimpleLeftSideList($3->getPosition(), $3));
00628                                 }
00629                         ;
00630 
00633 LeftSide        : tID { $$ = new Identifier(new SrcPosition(lines), $1); }
00634                         | FieldReference { $$ = $1; }
00635                         | ArrayReference { $$ = $1; }
00636                         ;
00637 
00640 Expressions     : Expression { $$ = new SimpleExpressionList($1->getPosition(), $1); }
00641                         | Expressions tCOMMA Expression
00642                                 {
00643                                         $$ = new SequentialExpressionList($1->getPosition(), $1,
00644                                                                                                           new SimpleExpressionList($1->getPosition(), $3));
00645                                 }
00646                         ;
00647 
00650 GuardedStatements       : GuardedStatement { $$ = $1; }
00651                                         | GuardedStatements tGUARD GuardedStatement
00652                                                 {
00653                                                         $$ = new SequentialGuardedStatement($1->getPosition(), $1, $3);
00654                                                 }
00655                                         ;
00656 
00659 GuardedStatement        : Expression tACTION Statements
00660                                                 {
00661                                                         $$ = new SimpleGuardedStatement($1->getPosition(), $1, $3);
00662                                                 }
00663                                         ;
00664 
00665 %%
00666 
00667 int main(int argc, char **argv)
00668 {
00669         extern FILE *yyin;
00670 
00671         if (argc != 2)
00672         {
00673                 fprintf(stderr, "Uso: protomake <arquivo-entrada>\n");
00674                 exit(1);
00675         }
00676 
00677         if ((yyin = fopen(argv[1], "r")) == NULL)
00678         {
00679                 fprintf(stderr, "Erro ao tentar abrir o arquivo %s!\n", argv[1]);
00680                 exit(1);
00681         }
00682 
00683         if (yyparse())
00684         {
00685                 fprintf(stderr, "Não foi possível compilar %s!\n", argv[1]);
00686                 exit(1);
00687         }
00688 
00689         TypeCheckerVisitor typeChecker;
00690         root->visit(typeChecker);
00691         
00692         CCodeGeneratorVisitor ccodeGenerator;
00693         root->visit(ccodeGenerator);
00694 
00695         JavaCodeGeneratorVisitor java("./code/teste.java");
00696         root->visit(java);
00697 
00698         fprintf(stderr, "Sintaxe de %s correta!\n", argv[1]);
00699         fclose(yyin);
00700 
00701     if (etherInfo != NULL)
00702     {
00703         fprintf(stderr, "Gerando o plugin do ethereal para o protocolo...\n");
00704         generateEtherealPlugin(&fiMap, etherInfo);
00705         fprintf(stderr, "Plugin gerado!\n");
00706     }
00707 
00708         return 0;
00709 }
00710                                                                                                                                                            
00711 int yyerror(char *msg)
00712 {
00713         fprintf(stderr, "Line %d: %s\n", lines+1, msg);
00714     exit(1);
00715         
00716         return 0;
00717 }
00718 
00720 static void generateEtherealPlugin(map<string, vector<FieldInfo> > *fiMap,
00721                                    multimap<EtherType, EtherInfoType> *eit)
00722 {
00723     multimap<EtherType, EtherInfoType>::iterator itr;
00724 
00726     if (eit->count(NAME) > 1)
00727     {
00728         itr = eit->find(NAME);
00729         itr++;
00730         fprintf(stderr, "Line %d: More than one name was defined for the protocol!\n",
00731                 (*itr).second.lines + 1);
00732         exit(1);
00733     }
00734     else if (eit->count(NAME) == 0)
00735     {
00736         fprintf(stderr, "No name was defined for the protocol!\n");
00737         exit(1);
00738     }
00739     if (eit->count(ABBREV) > 1)
00740     {
00741         itr = eit->find(ABBREV);
00742         itr++;
00743         fprintf(stderr, "Line %d: More than one short name was defined for the protocol!\n",
00744                 (*itr).second.lines + 1);
00745         exit(1);
00746     }
00747     else if (eit->count(ABBREV) == 0)
00748     {
00749         fprintf(stderr, "No short name was defined for the protocol!\n");
00750         exit(1);
00751     }
00752     else if (eit->count(PORT) > 1)
00753     {
00754         itr = eit->find(PORT);
00755         itr++;
00756         fprintf(stderr, "Line %d: More than one port was defined for the protocol!\n",
00757                 (*itr).second.lines + 1);
00758         exit(1);
00759     }
00760     else if (eit->count(PORT) == 0)
00761     {
00762         fprintf(stderr, "No port was defined for the protocol!\n");
00763         exit(1);
00764     }
00765     else if (eit->count(TRANSPORT) > 1)
00766     {
00767         itr = eit->find(TRANSPORT);
00768         itr++;
00769         fprintf(stderr, "Line %d: More than one transport protocol was defined for the protocol!\n",
00770                 (*itr).second.lines + 1);
00771         exit(1);
00772     }
00773     else if (eit->count(TRANSPORT) == 0)
00774     {
00775         fprintf(stderr, "No transport protocol was defined for the protocol!\n");
00776         exit(1);
00777     }
00778 
00780     itr = eit->find(ABBREV);
00781     FILE *plugin;
00782     char fileName[256];
00783     char *abbrev = ++((*itr).second.string);
00784     unsigned i;
00785 
00789     abbrev[strlen(abbrev)-1] = '\0';
00790     for (i = 0; abbrev[i]; i++)
00791         abbrev[i] = tolower(abbrev[i]);
00792     
00793 
00794     sprintf(fileName, "./plugin/packet-%s.c", (*itr).second.string);
00795     if ((plugin = fopen(fileName, "w")) == NULL)
00796     {
00797         fprintf(stderr, "Unable to create %s!\n", fileName);
00798         exit(1);
00799     }
00800 
00802     writeHeader(plugin, fileName, eit);
00803 
00805     // Gambiarra para adicionar
00806     int j;
00807     FieldInfo fi;
00808     fi.identifier = "code";
00809     fi.bitByte = FieldType::BIT;
00810     fi.size = NULL;
00811     
00812     j = 1;
00813     fprintf(plugin, "/** Message  structures. Inicialize the protocol and registered fields */\n");
00814     for (map<string, vector<FieldInfo> >::iterator itr = fiMap->begin();
00815          itr != fiMap->end();
00816          itr++, j++)
00817     {
00818         fi.init = new IntegerLiteral(NULL, j);
00819         ((*itr).second).push_back(fi);
00820 
00821         fprintf(plugin, "typedef struct {\n");
00822         for (i = 0; i < (*itr).second.size(); i++)
00823             fprintf(plugin, "\tint %s_%s;\n", abbrev, ((*itr).second)[i].identifier);
00824         fprintf(plugin, "} hf_%s_fields;\n", (*itr).first.c_str());
00825         fprintf(plugin, "static hf_%s_fields hf_%s = { ", (*itr).first.c_str(), (*itr).first.c_str());
00826         for (i = 0; i < (*itr).second.size(); i++)
00827         {
00828             if (!i) fprintf(plugin, "-1");
00829             else fprintf(plugin, ", -1");
00830         }
00831         fprintf(plugin, " };\n\n");
00832     } 
00833     fprintf(plugin, "static int proto_%s = -1;\n\n", abbrev);
00834     fprintf(plugin, "/* Initialize the subtree pointers */\n");
00835     fprintf(plugin, "static gint ett_%s = -1;\n\n", abbrev);
00836 
00838     writeDissector(plugin, fiMap, eit);
00839 
00841     fprintf(plugin, "void proto_register_%s(void)\n{\n", abbrev);
00842     fprintf(plugin, "/** Setup list of header fields */\n");
00843     fprintf(plugin, "\t static hf_register_info hf[] = {\n");
00844     
00846     for (map<string, vector<FieldInfo> >::iterator itr = fiMap->begin();
00847          itr != fiMap->end();
00848          itr++)
00849     {
00850         if (itr != fiMap->begin())
00851             fprintf(plugin, ",\n");
00852 
00853         for (i = 0; i < (*itr).second.size(); i++)
00854         {
00855             if (i)
00856                 fprintf(plugin, ",\n");
00857             fprintf(plugin, "\t\t{ &(hf_%s.%s_%s),\n", (*itr).first.c_str(), abbrev,
00858                                                        ((*itr).second)[i].identifier);
00859             fprintf(plugin, "\t\t\t{ \"%s\", \"%s.%s_%s\",\n", ((*itr).second)[i].identifier,
00860                                                                abbrev,
00861                                                                (*itr).first.c_str(),
00862                                                                ((*itr).second)[i].identifier);
00863 
00864             if ((*itr).second[i].bitByte == FieldType::BIT)
00865                 fprintf(plugin, "\t\t\tFT_INT32, BASE_DEC, NULL, 0x0,\n\t\t\t\"%s\" }\n", ((*itr).second)[i].identifier);
00866             else
00867                 fprintf(plugin, "\t\t\tFT_STRING, BASE_NONE, NULL, 0x0,\n\t\t\t\"%s\" }\n", ((*itr).second)[i].identifier);
00868             fprintf(plugin, "\t\t}");
00869         }
00870     }
00871     fprintf(plugin, "\n\t};\n\n");
00872 
00873     fprintf(plugin, "/** Setup protocol subtree array */\n");
00874     fprintf(plugin, "\tstatic gint *ett[] = { &ett_%s };\n\n", abbrev);
00875    
00876     fprintf(plugin, "/** Register the protocol name and description */\n");
00877     char *ABBREV = strdup(abbrev);
00878     for (i = 0; ABBREV[i]; i++)
00879         ABBREV[i] = toupper(ABBREV[i]);
00880 
00881     char *name = (*(eit->find(NAME))).second.string;
00882     fprintf(plugin, "\tproto_%s = proto_register_protocol(\"%s\",\n"
00883                     "\t                                      \"%s\",\n"
00884                     "\t                                      \"%s\");\n\n",
00885                     abbrev, name, ABBREV, abbrev);
00886 
00887     fprintf(plugin, "/** Required function calls to register the header fields and subtrees used */\n");
00888     fprintf(plugin, "\tproto_register_field_array(proto_%s, hf, array_length(hf));\n", abbrev);
00889     fprintf(plugin, "\tproto_register_subtree_array(ett, array_length(ett));\n}");
00890 
00892     writeRest(plugin, (*(eit->find(TRANSPORT))).second.string, (*(eit->find(PORT))).second.string, abbrev);
00893     fclose(plugin);
00894 
00895         FILE *makefile = fopen("./plugin/Makefile.am", "w");
00896         if (makefile)
00897         {
00898                 fprintf(makefile, "INCLUDES = -I$(top_src_dir)\n\n");
00899 
00900                 fprintf(makefile, "plugindir = @plugindir@\n\n");
00901 
00902                 fprintf(makefile, "plugin_LTLIBRARIES = %s.la\n", abbrev);
00903                 fprintf(makefile, "%s_la_SOURCES = packet-%s.c\n", abbrev, abbrev);
00904                 fprintf(makefile, "%s_la_LDFLAGS = -module -avoid-version\n\n", abbrev);
00905 
00906                 fprintf(makefile, "LIB = \n\n");
00907 
00908                 fprintf(makefile, "%s_la_DEPENDENCIES = packet-%s-static.o\n\n", abbrev, abbrev);
00909 
00910                 fprintf(makefile, "packet-%s-static.o: packet-%s.c\n", abbrev, abbrev);
00911                 fprintf(makefile, "\t$(LTCOMPILE) -c -o packet-%s-static.o -D__ETHEREAL_STATIC__ $(srcdir)/packet-%s.c\n",
00912                                                   abbrev, abbrev);
00913                                                   
00914                 fprintf(makefile, "CLEANFILES = %s \n", abbrev);
00915                 fprintf(makefile, "EXTRA_DIST = Makefile.nmake\n");
00916         }
00917         else fprintf(stderr, "Unable to create Makfile.am!\n");
00918         fclose(makefile);
00919 
00920         makefile = fopen("./plugin/Makefile.nmake", "w");
00921         if (makefile)
00922         {
00923                 fprintf(makefile, "include ..\\..\\config.nmake\n\n");
00924 
00925                 fprintf(makefile, "CFLAGS=/DHAVE_CONFIG_H /I../.. /I../../wiretap \\\n");
00926                 fprintf(makefile, "\t/I$(GLIB_DIR) /I$(GTK_DIR) /I$(GLIB_DIR)/gmodule \\\n");
00927                 fprintf(makefile, "/I$(PCAP_DIR)\\include $(LOCAL_CFLAGS)\n\n");
00928                 
00929                 fprintf(makefile, "OBJECTS=packet-%s.obj\n\n", abbrev);
00930                 fprintf(makefile, "%s.dll %s.exp %s.lib : packet-%s.obj ..\\plugin_api.obj\n",
00931                                                   abbrev, abbrev, abbrev, abbrev);
00932                 fprintf(makefile, "\tlink -dll /out:%s.dll packet-%s.obj ..\\plugin_api.obj \\\n",
00933                                                   abbrev, abbrev);
00934                 fprintf(makefile, "$(GLIB_DIR)\\glib-$(GLIB_VERSION).lib\n\n");
00935                 fprintf(makefile, "clean:\n\trm -f $(OBJECTS) %s.dll %s.exp %s.lib\n",
00936                                                   abbrev, abbrev, abbrev);
00937         }
00938         else fprintf(stderr, "Unable to create Makefile.nmake!\n");
00939         fclose(makefile);
00940 }
00941 
00942 static void writeHeader(FILE *plugin, char *fileName,
00943                         multimap<EtherType, EtherInfoType> *eit)
00944 {
00945     int total;
00946     char *author, *email;
00947     char *name = ++((*(eit->find(NAME))).second.string);
00948     multimap<EtherType, EtherInfoType>::iterator itr;
00949 
00950     name[strlen(name)-1] = '\0';
00951     fprintf(plugin, "/* %s\n", &fileName[2]);
00952     fprintf(plugin, " * Routines for %s dissection\n", name);
00953 
00954     fprintf(plugin, " * Copyright 2003");
00955     for (total = eit->count(AUTHOR), itr = eit->find(AUTHOR);
00956          total > 0;
00957          itr++, total--)
00958     {
00959         author = ++((*itr).second.string);
00960 
00961         author[strlen(author) - 1] = '\0';
00962         fprintf(plugin, ", %s", author);
00963     }
00964 
00965     fprintf(plugin, " <");
00966     for (total = eit->count(EMAIL), itr = eit->find(EMAIL);
00967          total > 0;
00968          itr++, total--)
00969     {
00970         email = ++((*itr).second.string);
00971 
00972         email[strlen(email) - 1] =  '\0';
00973         fprintf(plugin, "%s, ", email);
00974     }
00975     fprintf(plugin, ">\n");
00976 
00977     char *header = " * \n\
00978  * Ethereal - Network traffic analyzer\n\
00979  * By Gerald Combs <gerald@ethereal.com>\n\
00980  * Copyright 1998 Gerald Combs\n\
00981  * \n\
00982  * Generated from ProtoMake by Igor Cananéa, Fábio Guerra, Rodrigo Araújo &\n\
00983  * Thiago Souto Maior, Copyright 2003.\n\
00984  *\n\
00985  * This program is free software; you can redistribute it and/or\n\
00986  * modify it under the terms of the GNU General Public License\n\
00987  * as published by the Free Software Foundation; either version 2\n\
00988  * of the License, or (at your option) any later version.\n\
00989  *\n\
00990  * This program is distributed in the hope that it will be useful,\n\
00991  * but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
00992  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
00993  * GNU General Public License for more details.\n\
00994  *\n\
00995  * You should have received a copy of the GNU General Public License\n\
00996  * along with this program; if not, write to the Free Software\n\
00997  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n\
00998  */\n\
00999 \n\
01000 #ifdef HAVE_CONFIG_H\n\
01001 # include \"config.h\"\n\
01002 #endif\n\
01003 \n\
01004 #include <stdio.h>\n\
01005 #include <stdlib.h>\n\
01006 #include <string.h>\n\
01007 \n\
01008 /* Includes glib.h! */\n\
01009 #include <gmodule.h>\n\
01010 \n\
01011 #ifdef NEED_SNPRINTF_H\n\
01012 # include \"snprintf.h\"\n\
01013 #endif\n\
01014 \n\
01015 #include <epan/packet.h>\n\
01016 #include \"plugins/plugin_api.h\"\n\
01017 #include \"plugins/plugin_api_defs.h\"\n\
01018 \n\
01019 #ifndef __ETHEREAL_STATIC__\n\
01020 G_MODULE_EXPORT const gchar version[] = \"1.0\";\n\
01021 #endif\n\n";
01022 
01023     fprintf(plugin, "%s", header);
01024 }
01025 
01026 
01027 static void writeDissector(FILE *plugin, map<string, vector<FieldInfo> > *fiMap,
01028                            multimap<EtherType, EtherInfoType> *eit)
01029 {
01030     char *abbrev = (*(eit->find(ABBREV))).second.string;
01031     char *ABBREV = strdup(abbrev);
01032     unsigned i;
01033 
01034     for (i = 0; ABBREV[i]; i++)
01035         ABBREV[i] = toupper(ABBREV[i]);
01036 
01037     fprintf(plugin, "/** Dissector main code! */\n");
01038     fprintf(plugin, "void dissect_%s(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)\n{\n", abbrev);
01039 
01040     fprintf(plugin, "/** Set up structures needed to add the protocol subtree and manage it */\n");
01041     fprintf(plugin, "\tproto_item *tree_item;\n\tproto_tree *%s_tree;\n\tguint16 code;\n", abbrev);
01042 
01043     for (map<string, vector<FieldInfo> >::iterator itr = fiMap->begin();
01044          itr != fiMap->end();
01045          itr++)
01046     {
01047         fprintf(plugin, "\tstatic struct {\n");
01048         for (i = 0; i < (*itr).second.size(); i++)
01049         {
01050             if (((*itr).second)[i].bitByte == FieldType::BIT)
01051                 fprintf(plugin, "\t\tguint32 ");
01052             else
01053                 fprintf(plugin, "\t\tguint8 *");
01054             fprintf(plugin, "%s_%s;\n", abbrev, ((*itr).second)[i].identifier);            
01055         }
01056         fprintf(plugin, "\t} msg_%s;\n\n", (*itr).first.c_str());
01057     }
01058 
01059     fprintf(plugin, "/** Make entries in Protocol column and Info column on summary display */\n");
01060     fprintf(plugin, "\tif (check_col(pinfo->cinfo, COL_PROTOCOL))\n");
01061     fprintf(plugin, "\t\tcol_set_str(pinfo->cinfo, COL_PROTOCOL, \"%s\");\n\n", ABBREV);
01062 
01063     fprintf(plugin, "/** Verify the message sent and dissect it properly */\n");
01064     fprintf(plugin, "\tif (tree) {\n");
01065     fprintf(plugin, "\t\tcode = tvb_get_ntohs(tvb, 0);\n\n");
01066 
01067     fprintf(plugin, "\t\ttree_item = proto_tree_add_item(tree, proto_%s, tvb, 0, -1, FALSE);\n", abbrev);
01068     fprintf(plugin, "\t\t%s_tree = proto_item_add_subtree(tree_item, ett_%s);\n\n", abbrev, abbrev);
01069 
01070     fprintf(plugin, "\t\tif (");
01071 
01072     for (map<string, vector<FieldInfo> >::iterator itr = fiMap->begin();
01073          itr != fiMap->end();
01074          itr++)
01075     {
01076         if (itr != fiMap->begin())
01077             fprintf(plugin, "\t\telse if (");
01078         vector <FieldInfo> temp = ((*itr).second);
01079         IntegerLiteral *msgCode = dynamic_cast<IntegerLiteral*> (temp[temp.size() - 1].init);
01080         fprintf(plugin, "code == %d)\n\t\t{\n", msgCode->getValue());
01081         fprintf(plugin, "\t\t\tint offset = 2; //sizeof(code) == 2 since code is a guint16 :)\n\n");
01082 
01084         for (i = 0; i < (*itr).second.size() - 1; i++)
01085         {
01086             FieldInfo fi = (*itr).second[i];
01087 
01088             if (fi.bitByte == FieldType::BIT)
01089             {
01090                 int value = (dynamic_cast<IntegerLiteral*> (fi.size))->getValue();
01091                 
01092                 if (value <= 8)
01093                 {
01094                     fprintf(plugin, "\t\t\tmsg_%s.%s_%s = tvb_get_guint8(tvb, offset);\n",
01095                             (*itr).first.c_str(), abbrev, fi.identifier);
01096                                         fprintf(plugin, "\t\t\tproto_tree_add_item(%s_tree, hf_%s.%s_%s, tvb, offset, 1, FALSE);\n",
01097                                                         abbrev, (*itr).first.c_str(), abbrev, fi.identifier);
01098                     fprintf(plugin, "\t\t\toffset++;\n\n");
01099                 }
01100                 else if (value <= 16)
01101                 {
01102                     fprintf(plugin, "\t\t\tmsg_%s.%s_%s = tvb_get_ntohs(tvb, offset);\n",
01103                             (*itr).first.c_str(), abbrev, fi.identifier);
01104                                         fprintf(plugin, "\t\t\tproto_tree_add_item(%s_tree, hf_%s.%s_%s, tvb, offset, 2, FALSE);\n",
01105                                                         abbrev, (*itr).first.c_str(), abbrev, fi.identifier);
01106                     fprintf(plugin, "\t\t\toffset += 2;\n\n"); 
01107                 } 
01108                 else if (value <= 32 || value > 16) // This might be a problem for > 32 bits!
01109                 {
01110                     fprintf(plugin, "\t\t\tmsg_%s.%s_%s = tvb_get_ntohl(tvb, offset);\n",
01111                             (*itr).first.c_str(), abbrev, fi.identifier);
01112                                         fprintf(plugin, "\t\t\tproto_tree_add_item(%s_tree, hf_%s.%s_%s, tvb, offset, 4, FALSE);\n",
01113                                                         abbrev, (*itr).first.c_str(), abbrev, fi.identifier);
01114                     fprintf(plugin, "\t\t\toffset += 4;\n\n");
01115                 }
01116             }
01117             else if (fi.bitByte == FieldType::BYTE &&
01118                      typeid(*(fi.size)) == typeid(IntegerLiteral))
01119             {
01120                 int value = (dynamic_cast<IntegerLiteral*> (fi.size))->getValue();
01121 
01122                 fprintf(plugin, "\t\t\tmsg_%s.%s_%s = tvb_memdup(tvb, offset, %d);\n",
01123                         (*itr).first.c_str(), abbrev, fi.identifier, value);
01124                                 fprintf(plugin, "\t\t\tproto_tree_add_string(%s_tree, hf_%s.%s_%s, tvb, offset, %d, msg_%s.%s_%s);\n",
01125                                                 abbrev, (*itr).first.c_str(), abbrev, fi.identifier, value, (*itr).first.c_str(), abbrev, fi.identifier);
01126                                 fprintf(plugin, "\t\t\toffset += %d;\n\n", value);
01127             }
01128             else if (fi.bitByte == FieldType::BYTE &&
01129                      typeid(*(fi.size)) == typeid(Identifier))
01130             {
01131                 const char *name = (dynamic_cast<Identifier*>(fi.size))->getName().c_str();
01132 
01133                 fprintf(plugin, "\t\t\tmsg_%s.%s_%s = tvb_memdup(tvb, offset, msg_%s.%s_%s);\n",
01134                         (*itr).first.c_str(), abbrev, fi.identifier, (*itr).first.c_str(),
01135                         abbrev, name);
01136                                 fprintf(plugin, "\t\t\tproto_tree_add_string(%s_tree, hf_%s.%s_%s, tvb, offset, msg_%s.%s_%s, msg_%s.%s_%s);\n",
01137                                                 abbrev, (*itr).first.c_str(), abbrev, fi.identifier, (*itr).first.c_str(), abbrev, name,
01138                                                 (*itr).first.c_str(), abbrev, fi.identifier);
01139                 fprintf(plugin, "\t\t\toffset += msg_%s.%s_%s;\n\n", (*itr).first.c_str(), abbrev, name);
01140             }
01141         }
01142 
01143         fprintf(plugin, "\t\t}\n");
01144     }    
01145     fprintf(plugin, "\t}\n");
01146     fprintf(plugin, "}\n\n");
01147 }
01148 
01149 
01150 static void writeRest(FILE *plugin, char *trans, char *port, char *abbrev)
01151 {
01152     char *rest = "\n\n/* If this dissector uses sub-dissector registration add a registration routine.\n\
01153    This format is required because a script is used to find these routines and\n\
01154    create the code that calls these routines.\n\
01155 */\n";
01156 
01157     fprintf(plugin, "%s", rest);
01158     fprintf(plugin, "void proto_reg_handoff_%s(void)\n{\n", abbrev);
01159         fprintf(plugin, "\tdissector_handle_t %s_handle;\n\n", abbrev);
01160         
01161     fprintf(plugin, "\t%s_handle = create_dissector_handle(dissect_%s,\n\t\tproto_%s);\n", abbrev, abbrev, abbrev);
01162     fprintf(plugin, "   dissector_add(\"%s.port\", %s, %s_handle);\n", trans, port, abbrev);
01163 
01164     rest = "}\n\
01165 \n\
01166 #ifndef __ETHEREAL_STATIC__\n\
01167 G_MODULE_EXPORT void plugin_init(plugin_address_table_t *pat)\n\
01168 {\n\
01169         /* initialise the table of pointers needed in Win32 DLLs */\n\
01170         plugin_address_table_init(pat);\n\
01171 \n\
01172         /* register the new protocol, protocol fields, and subtrees */\n";
01173     fprintf(plugin, "%s", rest);
01174         fprintf(plugin, "\tif (proto_%s == -1) /* execute protocol initialization only once */\n", abbrev);
01175         fprintf(plugin, "\t\tproto_register_%s();\n}\n", abbrev);
01176     rest = "#endif\n\
01177 \n\
01178 #ifndef __ETHEREAL_STATIC__\n\
01179 G_MODULE_EXPORT void plugin_reg_handoff(void)\n\
01180 {\n\
01181         proto_reg_handoff_";
01182     fprintf(plugin, "%s%s();\n}\n#endif\n", rest, abbrev);
01183 }

Generated on Mon Dec 1 17:36:18 2003 for Protomake by doxygen1.3