home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ctb_291.zip / source / ctb.cpp next >
C/C++ Source or Header  |  1996-08-14  |  11KB  |  433 lines

  1. /*
  2. ** Module   :CTB.CPP
  3. ** Abstract :Main file of CLASS TREE BUILDER
  4. **
  5. ** Copyright (C) Sergey I. Yevtushenko
  6. ** Log:
  7. ** Update : Sat  11-05-96
  8. ** Update : Tue  10-26-93
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <dlc.h>
  14. #include <dos.h>
  15.  
  16. char label[] = "Class Tree Builder  Version 2.91  Copyright (C) 1992-96 Sergey I. Yevtushenko.\n\n";
  17. char sintax[] = "Usage: CTB [options] file[s]\n"
  18. "\t-Ixxx  Include search path\n"
  19. "\t-Sxxx  Set output base class\n"
  20. "\t-oxxx  Output filename\n"
  21. "\t-i     Ignore all includes\n"
  22. "\t-w     Supress warnings messages\n"
  23. "\t-s     Print pair (file,line) of class declaration\n"
  24. "\t-c     Treat 'struct' and 'union' as 'class'\n"
  25. "\t-a     Show all classes\n"
  26. "\t-m     Show methods of classes\n"
  27. "\t-n     Supress drawing tree, show only class names\n"
  28. ;
  29.  
  30. int error_count = 0;
  31. TokenStream *IN;
  32. char *INCLUDEpath;
  33.  
  34. char show_all          = 0;
  35. char treat_struct      = 0;
  36. char ignore_includes   = 0;
  37. char skip_warnings     = 0;
  38. char print_declarators = 0;
  39. char print_methods     = 0;
  40. char draw_tree         = 1;
  41.  
  42. char UnableToOpenFile[] = "Unable to open file";
  43.  
  44. int fatal(char *str)
  45. {
  46.     printf("FATAL::%s\nProgram aborted.\n", str);
  47.     abort();
  48.     return 0;
  49. }
  50.  
  51. void *operator new(size_t size)
  52. {
  53.     void *ptr = malloc(size);
  54.     if(!ptr)
  55.         fatal("Not enough memory");
  56.     return ptr;
  57. }
  58.  
  59. int error2(char *str, char *str2 = "")
  60. {
  61.     printf("Error :%s %s.\n", str, str2);
  62.     return 0;
  63. }
  64. int error(char *str, char *str2 = "")
  65. {
  66.     int ln = IN->line();
  67.     printf("Error %s %d::%s %s.\n", IN->name(), ln, str, str2);
  68.     error_count++;
  69.     return 0;
  70. }
  71. int warning(char *str, char *str2 = "")
  72. {
  73.     if (skip_warnings)
  74.         return 0;
  75.     int ln = IN->line();
  76.     printf("Warning %s %d::%s %s.\n", IN->name(), ln, str, str2);
  77.     return 0;
  78. }
  79. inline token_rec & next()
  80. {
  81.     return IN->next();
  82. }
  83. inline token_rec & current()
  84. {
  85.     return IN->current();
  86. }
  87. inline is(char *str)
  88. {
  89.     return !strcmp(IN->current(), str);
  90. }
  91. inline is(char chr)
  92. {
  93.     return (IN->current().type == _other && IN->current().str[0] == chr) ? 1 : 0;
  94. }
  95. inline is_name(char *str)
  96. {
  97.     return (isalnum(*str) || (*str == '_'));
  98. }
  99. tree(char *nm, char *ext)
  100. {
  101.     IN = new TokenStream;
  102.     IN->open(nm, ext);
  103.     if (!IN->ok())
  104.     {
  105.         if (!*ext)
  106.         {
  107.             char path[_MAX_PATH];
  108.             char *ptr = INCLUDEpath;
  109.             char *sptr;
  110.             do
  111.             {
  112.                 sptr = ptr;
  113.                 ptr = strchr(ptr, ';');
  114.                 if (ptr)
  115.                     *ptr = 0;
  116.                 strcpy(path, sptr);
  117.                 if (ptr)
  118.                     *ptr = ';';
  119.                 if (path[strlen(path)] != '\\')
  120.                 {
  121.                     int i = strlen(path);
  122.                     path[i] = '\\';
  123.                     path[i + 1] = 0;
  124.                 }
  125.                 strcat(path, nm);
  126.                 IN->open(path, ext);
  127.                 if (IN->ok())
  128.                     break;
  129.                 if(ptr)
  130.                     ptr++;
  131.             }
  132.             while (ptr);
  133.  
  134.             if (!IN->ok())
  135.             {
  136.                 delete IN;
  137.                 return 1;
  138.             }
  139.         }
  140.         else
  141.         {
  142.             delete IN;
  143.             return 1;
  144.         }
  145.     }
  146.     strlwr(IN->name());
  147.     char short_name[_MAX_FNAME];
  148.  
  149.     if(strrchr(IN->name(),'\\'))
  150.         strncpy(short_name, strrchr(IN->name(), '\\')+1, 14);
  151.     else
  152.         strncpy(short_name, IN->name() , 14);
  153.  
  154.     if (INCLUDES.look(short_name))
  155.     {
  156.         delete IN;
  157.         return 0;
  158.     }
  159.     else
  160.         INCLUDES.insert(short_name);
  161.     printf("%s%s:\n", ((*ext) ? "":"  "), short_name);
  162.     for (next(); current().type != _eof;)
  163.     {
  164.         if (is('#'))
  165.         {
  166.             next();
  167.             if (is("include"))
  168.             {
  169.                 next();
  170.                 char include_name[_MAX_PATH];
  171.                 if (is('<'))
  172.                 {
  173.                     include_name[0]=0;
  174.                     for(;;)
  175.                     {
  176.                         next();
  177.                         if(!is('>'))
  178.                             strcat(include_name, current());
  179.                         else
  180.                             break;
  181.                     }
  182.                 }
  183.                 else
  184.                     strcpy(include_name, current());
  185.                 if (ignore_includes)
  186.                 {
  187.                     next();
  188.                     continue;
  189.                 }
  190.                 TokenStream *SAVE = IN;
  191.                 int rc = tree(include_name, "");
  192.                 IN = SAVE;
  193.                 if (rc)
  194.                     error2(UnableToOpenFile, include_name);
  195.             }
  196.             if (is("define"))
  197.             {
  198.                 long ln = IN->line();
  199.                 next();
  200.                 DEFS.insert(current());
  201.                 while(ln == IN->line() && IN->current().type != _eof)
  202.                     next();
  203.                 continue;
  204.             }
  205.         }
  206.         if (is("class") || is("struct") || is("union"))
  207.         {
  208.             if(!treat_struct && is("struct") || is("union"))
  209.             {
  210.                 next();
  211.                 continue;
  212.             }
  213.             next();
  214.             while (DEFS.look(current()))
  215.                 next();
  216.             while (is("far") || is("near"))
  217.                 next();
  218.             if (is(';'))
  219.                 continue;
  220.             if(current().type != _ident)
  221.                 continue;
  222.  
  223.             Name *tmp = NT.insert(current());
  224.  
  225.             strupr(short_name);
  226.             strcpy(tmp->declaration_file,short_name);
  227.             tmp->declaration_line = IN->line();
  228.  
  229.             next();
  230.             if (is(';'))
  231.                 continue;
  232.             if (is(':'))
  233.             {
  234.                 for (;;)
  235.                 {
  236.                     next();
  237.                     while (is("public") || is("protected") || is("private") || is("virtual"))
  238.                         next();
  239.                     Name *tmp2 = NT.look(current());
  240.                     if (!tmp2)
  241.                         warning("Undefined class name", current());
  242.                     else
  243.                         tmp->base = new link(tmp2, tmp->base);
  244.                     next();
  245.                     if (!is(','))
  246.                         break;
  247.                 }
  248.             }
  249. //-----------------------------------
  250.             while (!is('{') && current().type != _eof)
  251.                 next();
  252.             char method_name[128];
  253.             int flags = 0;
  254.             int level = 0;
  255.             method_name[0] = 0;
  256.             char single = 0;
  257.             do
  258.             {
  259.                 if(is('{'))
  260.                     level++;
  261.                 if(is('}'))
  262.                     level--;
  263.                 if(current().type == _ident)
  264.                 {
  265.                     //printf("-%s-\n", CPtr(current()));
  266.                     if(is("static"))
  267.                         flags |= 1;
  268.                     if(is("virtual"))
  269.                         flags |= 2;
  270.                     if(single == '~' && level == 1)
  271.                     {
  272.                         flags |= 4;
  273.                         method_name[0] = '~';
  274.                         strcpy(&method_name[1], current());
  275.                     }
  276.                     else
  277.                         strcpy(method_name, current());
  278.                     next();
  279.                     if(is('(') && level == 1)
  280.                     {
  281.                         if(!strcmp(tmp->str, method_name))
  282.                             flags |= 8;
  283.                         tmp->funcs = new method(method_name, tmp->funcs);
  284.                         tmp->funcs->flags = flags;
  285.                         flags = 0;
  286.                     }
  287.                     continue;
  288.                 }
  289.                 else
  290.                     single = *CPtr(current());
  291.                 next();
  292.             }
  293.             while(level && current().type != _eof);
  294. //-----------------------------------            
  295.         }
  296.         next();
  297.     }
  298.     delete IN;
  299.     return 0;
  300. }
  301.  
  302. // ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
  303. // █▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒█
  304. // ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  305.  
  306. int main(int count, char **args)
  307. {
  308.     int cnt;
  309.     char *outname = 0;
  310.     char *obj = 0;
  311.  
  312.     if (1 == count)
  313.     {
  314.         printf(label);
  315.         printf(sintax);
  316.         return -2;
  317.     }
  318.     cnt = 1;
  319.     while ('-' == args[cnt][0])
  320.     {
  321.         switch (args[cnt][1])
  322.         {
  323.             case 'S':
  324.                 obj = &args[cnt][2];
  325.                 break;
  326.             case 'o':
  327.                 outname = &args[cnt][2];
  328.                 break;
  329.             case 'I':
  330.                 INCLUDEpath = &args[cnt][2];
  331.                 break;
  332.             case 'i':
  333.                 ignore_includes = 1;
  334.                 break;
  335.             case 'a':
  336.                 show_all = 1;
  337.                 break;
  338.             case 'c':
  339.                 treat_struct = 1;
  340.                 break;
  341.             case 'w':
  342.                 skip_warnings = 1;
  343.                 break;
  344.             case 'm':
  345.                 print_methods = 1;
  346.                 break;
  347.             case 'n':
  348.                 draw_tree = 0;
  349.                 break;
  350.             case 's':
  351.                 print_declarators = 1;
  352.                 break;
  353.             default:
  354.                 error2("Bad option :", args[cnt]);
  355.                 return -4;
  356.         }
  357.         cnt++;
  358.     }
  359.     printf(label);
  360.     if (count == cnt)
  361.     {
  362.         error2("No file names given");
  363.         return -3;
  364.     }
  365.     char *env  = getenv("INCLUDE");
  366.     if(INCLUDEpath)
  367.     {
  368.         char *temp = new char[strlen(INCLUDEpath) + ((env) ? strlen(env) : 0) + 5];
  369.         strcpy(temp, INCLUDEpath);
  370.         if(env)
  371.         {
  372.             strcat(temp, ";");
  373.             strcat(temp, env);
  374.         }
  375.         INCLUDEpath = temp;
  376.     }
  377.     else
  378.         INCLUDEpath = env;
  379.     for (; cnt < count; cnt++)
  380.     {
  381.         if(strchr(args[cnt],'*') || strchr(args[cnt],'?'))
  382.         {
  383.             char wildarg[_MAX_PATH];
  384.             char *tmp  = args[cnt];
  385.             char *tmp2 = wildarg;
  386.             char *name_pos = wildarg;
  387.             int ext_found = 0;
  388.  
  389.             while(*tmp)
  390.             {
  391.                 if(*tmp == '\\')
  392.                 {
  393.                     ext_found = 0;
  394.                     name_pos = tmp2+1;
  395.                 }
  396.                 if(*tmp == '.')
  397.                     ext_found = 1;
  398.                 *tmp2++ = *tmp++;
  399.             }
  400.             if(!ext_found)
  401.             {
  402.                 *tmp2++ = '.';
  403.                 *tmp2++ = 'h';
  404.             }
  405.             *tmp2 = 0;
  406.             struct find_t one_file;
  407.             for(int done = _dos_findfirst(wildarg, 0x21, &one_file); !done; done = _dos_findnext(&one_file))
  408.             {
  409.                 strcpy(name_pos,one_file.name);
  410.                 if( tree(wildarg, ".h"))
  411.                 {
  412.                     error2(UnableToOpenFile, wildarg);
  413.                     error_count++;
  414.                 }
  415.             }
  416.         }
  417.         else
  418.         {
  419.             if (tree(args[cnt], ".h"))
  420.             {
  421.                 error2(UnableToOpenFile, args[cnt]);
  422.                 error_count++;
  423.             }
  424.         }
  425.     }
  426.     if (error_count)
  427.         printf("\n*** Total %d error(s).\n", error_count);
  428.     else
  429.         NT.show_tree(obj, outname);
  430.  
  431.     return error_count;
  432. }
  433.