home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / OCT_MAC.PAK / MACROGEN.CPP next >
C/C++ Source or Header  |  1995-08-29  |  10KB  |  413 lines

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