home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / OCT_MAC.PAK / MACROGEN.CPP next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  9.9 KB  |  410 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
  4. //
  5. //----------------------------------------------------------------------------
  6. #include <services/defs.h>
  7. #include <iostream.h>
  8. #include <strstrea.h>
  9. #include <cstring.h>
  10. #include <stdlib.h>
  11.  
  12. //
  13. // AutomationMacro
  14. //  Abstract base class
  15. //
  16. class AutomationMacro {
  17.   public:
  18.     AutomationMacro() {}
  19.     virtual ~AutomationMacro() {}
  20.  
  21.     virtual void Generate(strstream &stream, const bool voidReturnType, const int numArgs) = 0;
  22.     virtual const char* GetMacroName() const = 0;
  23.     virtual const int   GetRequiredArgs() const = 0;
  24. };
  25.  
  26. void
  27. GenerateDefArgsMacro(strstream& stream, const int numArgs)
  28. {
  29.   int i;
  30.  
  31.   stream << "#define DEFARGS" << numArgs << "(";
  32.   for (i=1; i<=numArgs; i++) {
  33.     stream << "t" << i;
  34.     if (i != numArgs)
  35.       stream << ",";
  36.   }
  37.   stream << ") ";
  38.  
  39.   for (i=1; i<=numArgs; i++)
  40.     stream << "t" << i << " Arg" << i << ";";
  41.  
  42.   stream << endl;
  43. }
  44.  
  45. void
  46. GenerateBldArgsMacro(strstream& stream, const int numArgs)
  47. {
  48.   int i;
  49.  
  50.   stream << "#define BLDARGS" << numArgs << "(";
  51.   for (i=1; i<=numArgs; i++) {
  52.     stream << "t" << i;
  53.     if (i != numArgs)
  54.       stream << ",";
  55.   }
  56.   stream << ") ";
  57.  
  58.   for (i=1; i<=numArgs; i++)
  59.     stream << ",(t" << i << ")args[" << (i-1) << "]";
  60.  
  61.   stream << endl;
  62. }
  63.  
  64. void
  65. GenerateCtrArgsMacro(strstream& stream, const int numArgs)
  66. {
  67.   int i;
  68.  
  69.   stream << "#define CTRARGS" << numArgs << "(";
  70.   for (i=1; i<=numArgs; i++) {
  71.     stream << "t" << i;
  72.     if (i != numArgs)
  73.       stream << ",";
  74.   }
  75.   stream << ") ";
  76.  
  77.   for (i=1; i<=numArgs; i++)
  78.     stream << ",t" << i << " arg" << i;
  79.  
  80.   stream << endl;
  81. }
  82.  
  83. void
  84. GenerateSetArgsMacro(strstream& stream, const int numArgs)
  85. {
  86.   int i;
  87.  
  88.   stream << "#define SETARGS" << numArgs << " ";
  89.  
  90.   for (i=1; i<=numArgs; i++)
  91.     stream << ",Arg" << i << "(arg" << i << ")";
  92.  
  93.   stream << endl;
  94. }
  95.  
  96. void
  97. GenerateMacrosUsage(strstream& stream, const char* macroName, const int numArgs)
  98. {
  99.   int i;
  100.  
  101.   stream << macroName << numArgs << "(";
  102.   for (i=1; i<=numArgs; i++) {
  103.     stream << "t" << i;
  104.     if (i != numArgs)
  105.       stream << ",";
  106.   }
  107.   stream << ")";
  108. }
  109.  
  110.  
  111. //
  112. // AutoFunc
  113. //
  114. class AutoFunc : public AutomationMacro {
  115.   public:
  116.     void Generate(strstream& stream, const bool voidReturnType, const int numArgs);
  117.     const char* GetMacroName() const      { return "AutoFunc"; }
  118.     const int   GetRequiredArgs() const   { return 4; }
  119. };
  120.  
  121. void
  122. AutoFunc::Generate(strstream& stream, const bool voidReturnType, const int numArgs)
  123. {
  124.   int i;
  125.   string returnTypeString;
  126.  
  127.   if (voidReturnType == true) {
  128.     returnTypeString = "V";
  129.   } else {
  130.     returnTypeString = "";
  131.   }
  132.  
  133.   GenerateDefArgsMacro(stream, numArgs);
  134.   GenerateBldArgsMacro(stream, numArgs);
  135.   GenerateCtrArgsMacro(stream, numArgs);
  136.   GenerateSetArgsMacro(stream, numArgs);
  137.  
  138.   stream << "#define AUTOFUNC" << numArgs << returnTypeString << "(name, func";
  139.   if (voidReturnType != true)
  140.     stream << ", ret";
  141.   for (i=1; i<=numArgs; i++)
  142.     stream << ", t" << i;
  143.   stream << ", defs) \\" << endl;
  144.  
  145.   stream << "  AUTOFUNC_(name, ";
  146.   if (voidReturnType != true)
  147.     stream << "Val=";
  148.   stream << "This->func(";
  149.   for (i=1; i<=numArgs; i++) {
  150.     stream << "Arg" << i;
  151.     if (i!=numArgs)
  152.       stream << ", ";
  153.   }
  154.   stream << ");, defs, \\" << endl;
  155.  
  156.   stream << "  ";
  157.   if (voidReturnType != true)
  158.     stream << "RETARG(ret) ";
  159.   GenerateMacrosUsage(stream, "DEFARGS", numArgs);
  160.   stream << ", \\" << endl;
  161.   GenerateMacrosUsage(stream, "  BLDARGS", numArgs);
  162.   stream << ", \\" << endl;
  163.   GenerateMacrosUsage(stream, "  CTRARGS", numArgs);
  164.   stream << ", \\" << endl;
  165.   stream << "  SETARGS" << numArgs << ")" << endl;
  166. }
  167.  
  168. //
  169. // AutoStat
  170. //
  171. class AutoStat : public AutomationMacro {
  172.   public:
  173.     void Generate(strstream& stream, const bool voidReturnType, const int numArgs);
  174.     const char* GetMacroName() const      { return "AutoStat"; }
  175.     const int   GetRequiredArgs() const   { return 4; }
  176. };
  177.  
  178. void
  179. AutoStat::Generate(strstream& stream, const bool voidReturnType, const int numArgs)
  180. {
  181.   int i;
  182.   string returnTypeString;
  183.  
  184.   if (voidReturnType == true) {
  185.     returnTypeString = "V";
  186.   } else {
  187.     returnTypeString = "";
  188.   }
  189.  
  190.   GenerateDefArgsMacro(stream, numArgs);
  191.   GenerateBldArgsMacro(stream, numArgs);
  192.   GenerateCtrArgsMacro(stream, numArgs);
  193.   GenerateSetArgsMacro(stream, numArgs);
  194.  
  195.   stream << "#define AUTOSTAT" << numArgs << returnTypeString << "(name, func";
  196.   if (voidReturnType != true)
  197.     stream << ", ret";
  198.   for (i=1; i<=numArgs; i++)
  199.     stream << ", t" << i;
  200.   stream << ", defs) \\" << endl;
  201.  
  202.   stream << "  AUTOFUNC_(name, ";
  203.   if (voidReturnType != true)
  204.     stream << "Val=";
  205.   stream << "func(";
  206.  
  207.   for (i=1; i<=numArgs; i++) {
  208.     stream << "Arg" << i;
  209.     if (i!=numArgs)
  210.       stream << ", ";
  211.   }
  212.   stream << ");, defs, \\" << endl;
  213.  
  214.   stream << "  ";
  215.   if (voidReturnType != true)
  216.     stream << "RETARG(ret) ";
  217.   GenerateMacrosUsage(stream, "DEFARGS", numArgs);
  218.   stream << ", \\" << endl;
  219.   GenerateMacrosUsage(stream, "  BLDARGS", numArgs);
  220.   stream << ", \\" << endl;
  221.   GenerateMacrosUsage(stream, "  CTRARGS", numArgs);
  222.   stream << ", \\" << endl;
  223.   stream << "  SETARGS" << numArgs << ")" << endl;
  224. }
  225.  
  226.  
  227. //
  228. // AutoBuild
  229. //
  230. class AutoBuild : public AutomationMacro {
  231.   public:
  232.     void Generate(strstream& stream, const bool voidReturnType, const int numArgs);
  233.     const char* GetMacroName() const      { return "AutoBuild"; }
  234.     const int   GetRequiredArgs() const   { return 4; }
  235. };
  236.  
  237. void
  238. AutoBuild::Generate(strstream& stream, const bool /*voidReturnType*/, const int numArgs)
  239. {
  240.   int i;
  241.  
  242.   GenerateDefArgsMacro(stream, numArgs);
  243.   GenerateBldArgsMacro(stream, numArgs);
  244.   GenerateCtrArgsMacro(stream, numArgs);
  245.   GenerateSetArgsMacro(stream, numArgs);
  246.  
  247.   stream << "#define AUTOBUILD" << numArgs << "(name, func";
  248.   for (i=1; i<=numArgs; i++)
  249.     stream << ", t" << i;
  250.   stream << ", defs) \\" << endl;
  251.  
  252.   stream << "  AUTOBUILD_(name, Val=new ThisClass(";
  253.   for (i=1; i<=numArgs; i++) {
  254.     stream << "Arg" << i;
  255.     if (i!=numArgs)
  256.       stream << ", ";
  257.   }
  258.  
  259.   stream << ");, defs, \\" << endl;
  260.  
  261.   GenerateMacrosUsage(stream, "  DEFARGS", numArgs);
  262.   stream << ", \\" << endl;
  263.   GenerateMacrosUsage(stream, "  BLDARGS", numArgs);
  264.   stream << ", \\" << endl;
  265.   GenerateMacrosUsage(stream, "  CTRARGS", numArgs);
  266.   stream << ", \\" << endl;
  267.   stream << "  SETARGS" << numArgs << ")" << endl;
  268. }
  269.  
  270.  
  271. //
  272. // AutoNames
  273. //
  274. class AutoNames : public AutomationMacro {
  275.   public:
  276.     void Generate(strstream& stream, const bool voidReturnType, const int numArgs);
  277.     const char* GetMacroName() const      { return "AutoNames"; }
  278.     const int   GetRequiredArgs() const   { return 6; }
  279. };
  280.  
  281. void
  282. AutoNames::Generate(strstream& stream, const bool /*voidReturnType*/, const int numArgs)
  283. {
  284.   int i;
  285.   stream << "#define AUTONAMES" << numArgs << "(id";
  286.  
  287.   for (i=1; i<=numArgs; i++) {
  288.     stream << ",n" << i;
  289.   }
  290.   stream << ") static TAutoDispIds<" << numArgs << "> i_(this, id, ";
  291.   for (i=numArgs; i>=1; i--) {
  292.     stream << "_A(n" << i << ")";
  293.   }
  294.   stream << ");" << endl;
  295. }
  296.  
  297.  
  298. //
  299. // AutoArgs
  300. //
  301. class AutoArgs : public AutomationMacro {
  302.   public:
  303.     void Generate(strstream& stream, const bool voidReturnType,
  304.       const int numArgs);
  305.     const char* GetMacroName() const      { return "AutoArgs"; }
  306.     const int   GetRequiredArgs() const   { return 6; }
  307. };
  308.  
  309. void
  310. AutoArgs::Generate(strstream& stream, const bool /*voidReturnType*/, const int numArgs)
  311. {
  312.   int i;
  313.   stream << "#define AUTOARGS" << numArgs << "(";
  314.  
  315.   for (i=1; i<=numArgs; i++) {
  316.     stream << "a" << i;
  317.     if (i != numArgs)
  318.       stream << ",";
  319.   }
  320.   stream << ") TAutoArgs<" << numArgs << ">a_; ";
  321.   for (i=1; i<=numArgs; i++) {
  322.     stream << "a_[" << i << "]=a" << i << "; ";
  323.   }
  324.   stream << endl;
  325. }
  326.  
  327.  
  328. //
  329. // Global variables
  330. //
  331. AutoFunc    GlobalAutoFunc;
  332. AutoStat    GlobalAutoStat;
  333. AutoBuild   GlobalAutoBuild;
  334. AutoNames   GlobalAutoNames;
  335. AutoArgs    GlobalAutoArgs;
  336.  
  337. AutomationMacro *Macros[] = {
  338.   &GlobalAutoFunc,    &GlobalAutoStat,  &GlobalAutoBuild,
  339.   &GlobalAutoNames, &GlobalAutoArgs
  340. };
  341.  
  342. const int NumMacros = sizeof(Macros) / sizeof(Macros[0]);
  343.  
  344. void
  345. PrintUsage()
  346. {
  347.   cerr << "MacroGen Utility v1.0" << endl;
  348.   cerr << "Copyright (c) 1994, 1996 Borland International Inc" << endl;
  349.   cerr << "All Rights Reserved" << endl;
  350.   cerr << endl;
  351.   cerr << "  MacroGen AutomationMacro [void] numArgs" << endl;
  352.   cerr << endl;
  353.   cerr << "where AutomationMacro is one of the following:" << endl;
  354.   cerr << endl;
  355.   for (int i=0; i<NumMacros; i++)
  356.     cerr << "\t" << Macros[i]->GetMacroName() << endl;
  357. }
  358.  
  359. void
  360. ErrorMsg(const char* msg, const int exitCode)
  361. {
  362.   cerr << "Error: " << msg << endl;
  363.   cerr << endl;
  364.   PrintUsage();
  365.   exit(exitCode);
  366. }
  367.  
  368. //
  369. // starting point
  370. //
  371. int
  372. main(int argc, char *argv[])
  373. {
  374.   bool voidReturnType = false;
  375.   bool macroMatch = false;
  376.   int numArgs = 0;
  377.  
  378.   if (argc <= 2 || 4 < argc)
  379.     ErrorMsg("Wrong number of arguments", 1);
  380.  
  381.   if (strcmpi(argv[2], "void") == 0) {
  382.     if (argc == 3)
  383.       ErrorMsg("Missing 'numArgs' argument", 1);
  384.     voidReturnType = true;
  385.     numArgs = atoi(argv[3]);
  386.   } else {
  387.     if (argc == 4)
  388.       ErrorMsg("Extra argument", 1);
  389.     numArgs = atoi(argv[2]);
  390.   }
  391.  
  392.   strstream outStream;
  393.  
  394.   for (int i=0; i<NumMacros; i++) {
  395.     if (strcmpi(argv[1], Macros[i]->GetMacroName()) == 0) {
  396.       macroMatch = true;
  397.       if (numArgs <= Macros[i]->GetRequiredArgs())
  398.         ErrorMsg("Number of arguments specified for macro is already defined in automacr.h", 1);
  399.       Macros[i]->Generate(outStream, voidReturnType, numArgs);
  400. //      OutStream << ends;
  401.       cout << outStream.rdbuf();
  402.     }
  403.   }
  404.  
  405.   if (macroMatch == false)
  406.     ErrorMsg("Macro not found", 1);
  407.  
  408.   return 0;
  409. }
  410.