00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package xhelp;
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 int BEGIN ( ) {
00176
00177 $_file_list = "_file_list";
00178 $in_file = "";
00179 $root_path = "./";
00180 $scope_pm = "";
00181 $no_scope_file = 0;
00182 $xscope::sapi = 0;
00183
00184 push (@INC, `pwd`);
00185 push (@INC, '../perl');
00186 if (0){
00187
00188 }
00189
00190
00191 if (@ARGV > 0) {
00192 $scope_pm = @ARGV[0];
00193
00194 unless (open ( IN_LIST, $scope_pm)) {
00195 push (@file_errors, "Cannot open file \"$scope_pm\"\n");
00196 $no_scope_file++;
00197 }
00198
00199 push (@INC, $scope_pm);
00200
00201 if (!@file_errors) {
00202
00203
00204
00205 require $scope_pm;
00206
00207 if (&xscope::declare_variables()) {
00208
00209 } else {
00210 push (@file_errors, "Could not initialize variables from $scope_pm.\n");
00211 }
00212 }
00213 } else {
00214 push (@file_errors, "Need to provide a scope file as first argument.\n");
00215 }
00216
00217
00218 if (@ARGV > 1) {
00219 $root_path = @ARGV[1];
00220 if ($root_path =~ /\/$/) {
00221
00222 } else {
00223 push (@file_errors, "The input argument \"$root_path\" requires a forward slash (\/) at the end.\n");
00224 }
00225 }
00226
00227 if (@ARGV > 2) {
00228 $gen_proto = @ARGV[2];
00229 if ($gen_proto !~ /\
00230
00231
00232 if (1) {
00233 @chunk = split (/\./, $gen_proto);
00234 $last = pop (@chunk);
00235 $all = join ("\.", @chunk);
00236 $gen_list = join ("", $root_path, $all, "_list.", $last);
00237 $gen_class = join ("", $root_path, $all, "_class.", $last);
00238 $gen_template = join ("", $root_path, $all, "_dox_template.", $last);
00239 $gen_proto = "$root_path$gen_proto";
00240 }
00241 } else {
00242 if (1) {
00243 @chunk = split (/\./, $gen_proto);
00244 $last = pop (@chunk);
00245 $all = join ("\.", @chunk);
00246 $gen_list = join ("", $all, "_list.", $last);
00247 $gen_class = join ("", $all, "_class.", $last);
00248 $gen_template = join ("", $all, "_dox_template.", $last);
00249 }
00250 }
00251
00252
00253
00254
00255
00256 } else {
00257 push (@file_errors, "Need to have the output prototype file.\n");
00258 }
00259
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 {
00284
00285
00286
00287 if (@file_errors) {
00288
00289
00290 for ($i=0; $i<@file_errors; $i++){
00291
00292 }
00293 &xhelp::using_xhelp();
00294
00295 }
00296
00297 $_file_list = $root_path . "_eraseme";
00298 if (1){
00299 if (&create_xhelp_grep_results($_file_list) == 0) {
00300 &create_xhelp_hash($_file_list);
00301 } else {
00302
00303
00304 }
00305 }
00306
00307 $_file_list = $root_path . "_eraseme2";
00308 if (1){
00309 if (&create_ingroup_grep_results($_file_list) == 0) {
00310 &create_ingroup_hash($_file_list);
00311 } else {
00312
00313
00314 }
00315 }
00316
00317 if (1) {
00318 &process_ingroup_hash();
00319 }
00320
00321 &process_file_hash();
00322 if (1) {
00323 &write_output_list("$gen_list");
00324 }
00325 if (1) {
00326 if ($xscope::sapi) {
00327
00328
00329 &write_output_class("$gen_template");
00330 } else {
00331
00332
00333 &write_output_class("$gen_class");
00334 }
00335 }
00336 if (1) {
00337 if ($xscope::sapi) {
00338
00339
00340 } else {
00341 &write_output_file($gen_proto);
00342 }
00343
00344 }
00345
00346
00347
00348
00349 if (@file_errors) {
00350
00351 for ($i=0; $i<@file_errors; $i++){
00352
00353 }
00354 }
00355
00356
00357
00358
00359
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 int create_xhelp_grep_results ( ) {
00381 #define $in_file_list $_[0]
00382
00383 system ("echo \"\n\" > $in_file_list");
00384
00385 if ((1) && (@xscope::x_names)) {
00386
00387
00388 foreach $xword (@xscope::x_names){
00389 foreach $f_type (@xscope::include_f_type) {
00390 if (0) {
00391
00392 }
00393
00394
00395 }
00396 }
00397 }
00398 if ((1) && (@xscope::needed_in)) {
00399
00400
00401 foreach $xword (@xscope::needed_in){
00402 foreach $f_type (@xscope::include_f_type) {
00403 if (0) {
00404
00405 }
00406
00407
00408 }
00409 }
00410 }
00411
00412 return (0);
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 int create_xhelp_hash ( ) {
00448 #define $in_file_list $_[0]
00449
00450
00451 unless (open ( IN_LIST, $in_file_list)) {
00452
00453 push (@file_errors, "Cannot open file \"$in_file_list\"\n");
00454
00455 }
00456
00457 $_cnt=0;
00458 $_xcnt=0;
00459 X_INCOMING: while (<IN_LIST>){
00460 if ((/^\n/) || (!/\S+/)){
00461
00462 next X_INCOMING;
00463 }
00464 if ($_cnt > 4) {
00465
00466 }
00467 @line_chunk = split (/\:/, $_, 2);
00468 if (0) {
00469
00470
00471 $_cnt++;
00472
00473 }
00474
00475
00476
00477 if (($line_chunk[1] =~ /^\/\
00478
00479 if (0) {
00480
00481 }
00482 next X_INCOMING;
00483 }
00484
00485
00486
00487
00488
00489 if (($line_chunk[1] =~ /switch/)
00490
00491 || ($line_chunk[1] =~ /\;[\s]*$/)
00492 || ($line_chunk[1] =~ /[\s]*\=[\s]*/)
00493 || ($line_chunk[1] =~ /[\s]+if[\s]*\(/)
00494 || ($line_chunk[1] =~ /^[\s]*return/)
00495 || ($line_chunk[1] =~ /[\s]*\)[\s]*\:/)
00496 || ($line_chunk[1] =~ /^\
00497
00498 if (0) {
00499
00500 }
00501 next X_INCOMING;
00502 }
00503 @code_chunk = split (/\(/, $line_chunk[1], 2);
00504 if ($
00505 foreach $exclude (@xscope::needed_out) {
00506 if (0) {
00507
00508 }
00509
00510 if ($code_chunk[0] =~ /$exclude/) {
00511 if (0) {
00512
00513 }
00514 next X_INCOMING;
00515 }
00516 }
00517 if (0) {
00518
00519
00520
00521 }
00522 if ($code_chunk[0] =~ /[\S+]/){
00523 @ode_name = split (/\s/, $code_chunk[0]);
00524 $_name = $ode_name[$
00525 if (0){
00526
00527 }
00528 } else {
00529 if (0){
00530
00531 }
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 $file_hash{$line_chunk[0]}{$_name}{r}{$code_chunk[0]} = $_xcnt;
00547
00548 $_xcnt++;
00549 }
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559 if (0){
00560 foreach $src_file (sort keys %file_hash){
00561 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
00562 foreach $return_type (sort keys %{$file_hash{$src_file}{$code_item}{r}} ) {
00563
00564
00565 }
00566 }
00567 }
00568 if (0){
00569
00570 }
00571 }
00572 return (1);
00573
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 ** into comment blocks. Also, straight comment lines beginning
00607 ** with // are outright ignored.
00608 **
00609 ** @ingroup tp_xhelp
00610 **/
00611 // #############################################################################
00612 int process_file_hash ( ) {
00613 #define $src_content ""
00614
00615 if (0){ //
00616 foreach $src_file (sort keys %file_hash){
00617 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
00618 foreach $return_type (sort keys %{$file_hash{$src_file}{$code_item}{r}} ) {
00619 // print "ppp $file_hash{$src_file}{$code_item}{r}{$return_type} :: $src_file + $code_item\n";
00620 }
00621 }
00622 }
00623 if (0){
00624 // exit(1);
00625 }
00626 } // if test
00627
00628
00629 SRC_IN: foreach $src_file (sort keys %file_hash){
00630 // for each file that has a code item of interest
00631 unless (open ( IN_SRC, $src_file)) {
00632 // print "Cannot open file \"$src_file\"\n";
00633 push (@file_errors, "Cannot open file \"$src_file\"\n");
00634 next SRC_IN;
00635 }
00636 if (0) {
00637 // print "Source file is: $src_file\n";
00638 }
00639
00640 // undef ($src_content); // start fresh
00641 // read file into memory
00642 while (<IN_SRC>) {
00643 // ########
00644 // Read in the source file, but change Doxygen comment syntax
00645 // so that it is consistent throughout whole file.
00646 // Begin replacement of
00647 // ########
00648 if (/^\/\/\!/) {
00649 if ($comment_count == 0){
00650 // first line of a comment block
00651 $comment_count++;
00652 $_ =~ s/\/\/\!/\/\*\*/;
00653 } else {
00654 // Some line in the middle of a comment block.
00655 $comment_count++;
00656 // ##
00657 // Changed to have middle stuff with no asterix.
00658 // $_ =~ s/\/\/\!/ \*\*/;
00659 // ##
00660 $_ =~ s/\/\/\!//;
00661 }
00662 } elsif ($comment_count > 0){
00663 // We were in a comment block; need to terminate it.
00664 $comment_count = 0;
00665 $_ = " \*\*\/\n" . $_ ;
00666 }
00667 // ######## End Comment style change.
00668
00669 // ########
00670 // Trash all lines beginning with a comment.
00671 // ########
00672 if (/^\/\//) {
00673 // Don't mess with comment lines.
00674 } elsif ((/^\/\*/) && (/\*\/$/)) {
00675 // Don't mess with lines that begin and end as a coment
00676 } else {
00677 // Remember everything else
00678 $src_content .= $_;
00679 }
00680
00681 } // reading in source file
00682
00683 // for each code item of interest within the file
00684 CODE_ITEM: foreach $code_item (sort keys %{$file_hash{$src_file}}) {
00685 OVERLOAD_ITEM: foreach $return_type (sort keys %{$file_hash{$src_file}{$code_item}{r}}) {
00686 // for each overloaded return code item
00687
00688 $split_string = $return_type;
00689
00690 if (0) { // 06/10/2002 attempt to filter split_string
00691 // Attempt to get rid of bogus characters that will screw with pattern
00692 // matching.
00693 if ($split_string =~ /\)/) {
00694 // if it has a closing ), then it has to
00695 // have an opening (, otherwise it is of no
00696 // interest and will mess with us later.
00697 if ($split_string !~ /\(/) {
00698 next OVERLOAD_ITEM;
00699 }
00700 }
00701 } // attempt to filter split_string
00702
00703 $search_chunk = $src_content;
00704 $prototype = "NEXT_ONE";
00705 $prot_cnt = 0;
00706
00707 // Handle overloaded or multiple occurrences.
00708 SOME_ITEM: while ($search_chunk =~ /$split_string/) {
00709 @file_piece = split (/$split_string/, $search_chunk, 2);
00710
00711 $prototype = &inside_parenthesis ($file_piece[1]);
00712 $search_chunk = $file_piece[1];
00713 if ($prototype =~ /NEXT_ONE/) {
00714 // what we have is the prototype and not
00715 // the desired definition
00716 } else {
00717 // #####
00718 // this is the desired definition
00719 // #####
00720
00721 $prototype = "$split_string$prototype";
00722
00723 // ####
00724 // 4/23/2002 Noticed that excluded items were creeping back in.
00725 // This tests for them again and removes them.
00726 // ####
00727 foreach $exclude (@xscope::needed_out) {
00728 // Jump over any commands that we are told to specifically exclude.
00729 if ($prototype =~ $exclude) {
00730 if (0) {
00731 // print "==============\nExclude key \"$exclude\" of $prototype\n+++++++\n";
00732 }
00733 next SOME_ITEM;
00734 }
00735 }
00736
00737 $prototype .= "\n\{\n \/\/ Generated prototypes.\n\}\n";
00738 if (0) {
00739 // print "The definition:\n$prototype=====\n";
00740 }
00741
00742 // #####
00743 // Find the doxygen comments immediately prior to definition
00744 // Note that file_piece[0] is not necessarily the first half of
00745 // the file; it is from either the beginning of the file or
00746 // the first prototype.
00747 // #####
00748 $doxygen = &find_doxygen ($file_piece[0]);
00749 if ($doxygen =~ /NO_DOX_COMMENT/) {
00750 $doxygen = "\/\/ $doxygen\n";
00751 }
00752 $file_hash{$src_file}{$code_item}{p}{$prototype} = $doxygen;
00753
00754 } // NEXT_ONE
00755
00756 } // while $search_chunk; there is still something that looks interesting
00757
00758 if (0) {
00759 // // print "split=$split_string\n";
00760 // print "prototype=\n$prototype\n";
00761 // print "doxygen=\n$doxygen\n";
00762 }
00763 } // foreach OVERLOAD_ITEM
00764 } // foreach CODE_ITEM
00765 // close (SRC_IN);
00766 } // foreach SRC_IN
00767 } // process_file_hash
00768
00769 //#############################################################################
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786 // #############################################################################
00787 int create_ingroup_grep_results ( ) {
00788 #define $in_file_list $_[0]
00789
00790 system ("echo \"\n\" > $in_file_list");
00791
00792 if ((1) && (@xscope::ingroup)) {
00793 // Greps for the prefix names over the supported file types.
00794 // print "Grepping for prefix names in code...\n";
00795 foreach $xword (@xscope::ingroup){
00796 foreach $f_type (@xscope::include_f_type) {
00797 if (0) {
00798 // print "xword=$xword $f_type in $root_path\n";
00799 }
00800 // print ("grep \"$xword\" \`find $root_path -name \"\*\.$f_type\" -print\` >> $in_file_list\n");
00801 // system ("grep \"$xword\" \`find $root_path -name \"\*\.$f_type\" -print\` >> $in_file_list");
00802 } // foreach $f_type
00803 } // foreach $xword
00804 } // if (0)
00805 return (0);
00806 } // create_ingroup_grep_results
00807
00808
00809 //#############################################################################
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 // #############################################################################
00841 int create_ingroup_hash ( ) {
00842 #define $in_file_list $_[0]
00843 // print "Creating command hash from grep results...\n";
00844
00845 unless (open ( IN_LIST, $in_file_list)) {
00846 // print "Cannot open file \"$in_file_list\"\n";
00847 push (@file_errors, "Cannot open file \"$in_file_list\"\n");
00848 // exit(1);
00849 }
00850
00851 $_cnt=0;
00852 $_xcnt=0;
00853 X_INCOMING: while (<IN_LIST>){ // read a line from file into $_
00854 if ((/^\n/) || (!/\S+/)){
00855 // get rid of blank lines
00856 next X_INCOMING;
00857 }
00858 if ($_cnt > 4) {
00859 // exit(1);
00860 }
00861 @line_chunk = split (/\:/, $_, 2);
00862 if (0) {
00863 // print "[0]==$line_chunk[0]\n";
00864 // print "[1]==$line_chunk[1]\n";
00865 $_cnt++;
00866 // // exit(1);
00867 }
00868 // ####
00869 // Get rid of all non-comment lines so they don't give us a spurious hit.
00870 // ###
00871 if (($line_chunk[1] =~ /^\/\//) || ($line_chunk[1] =~ /\*\*/)) {
00872 // These are the ones we want.
00873 if (0) {
00874 // print "keep1==$line_chunk[1]";
00875 }
00876 } else {
00877 // get rid of non-comment lines
00878 if (0) {
00879 // print "trashing1==$line_chunk[1]";
00880 }
00881 next X_INCOMING;
00882 }
00883 // ####
00884 // Get rid of things known to be code specific and not comments
00885 // containing the @ingroup designation
00886 // ###
00887 if ($line_chunk[1] =~ /\@ingroup/) {
00888 // These are the ones we want.
00889 if (0) {
00890 // print "keep2==$line_chunk[1]";
00891 }
00892 } else {
00893 // get rid of program lines
00894 if (0) {
00895 // print "trashing2==$line_chunk[1]";
00896 }
00897 next X_INCOMING;
00898 }
00899 // Remove things from the line of no interest
00900 $line_chunk[1] =~ s/\/\/\![\s+]\@ingroup[\s+]//;
00901 if (0) {
00902 // print "keep3==$line_chunk[1]";
00903 }
00904
00905 // Get the groups
00906
00907 @group_chunk = split (/\s/, $line_chunk[1]);
00908 foreach $group (@group_chunk){
00909 // ####
00910 // If we made it this far without doing a "next X_INCOMING" then
00911 // [1] $line_chunk[0] contains the file of interest;
00912 // Let's put the code items into the file hash to speed up our process.
00913 //
00914 //
00915 // $ingroup_hash {$files} {$group}
00916 // ####
00917 if ($group =~ /\*/) {
00918 //
00919
00920 /g;
00921 }
00922 if (0) {
00923 // print "$_xcnt group==$group\n";
00924 }
00925 foreach $desired_group (@xscope::ingroup){
00926 if (0) {
00927 // print "$_xcnt desired group==$desired_group\n";
00928 }
00929 if (($desired_group =~ /$group/i) && ($group =~ /$desired_group/i)){
00930 // double testing assures that I'm not triggering on part of the
00931 // group name.
00932 if (0) {
00933 // print "found==$group ;desired == $desired_group\n";
00934 }
00935 if (exists ($group_hash{$line_chunk[0]}{$group})) {
00936 $group_hash{$line_chunk[0]}{$group} .= "\; $_xcnt";
00937 } else {
00938 $group_hash{$line_chunk[0]}{$group} = "\; $_xcnt";
00939 }
00940 $_xcnt++;
00941 }
00942 }
00943 } // $group
00944 } // while X_INCOMING
00945
00946 // #####
00947 // What is or will be in group hash
00948 // $group_hash{$src_file}{$group} = number
00949 // #####
00950
00951 if (0){ //
00952 foreach $src_file (sort keys %group_hash){
00953 foreach $group_item (sort keys %{$group_hash{$src_file}} ){
00954 // print "$group_item :: $src_file :: $group_hash{$src_file}{$group_item}\n";
00955 }
00956 }
00957 if (0){
00958 // exit(1);
00959 }
00960 } // if test
00961 return (1);
00962
00963 } // create_ingroup_hash
00964
00965
00966
00967 //#############################################################################
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 ** into comment blocks. Also, straight comment lines beginning
00989 ** with // are outright ignored.
00990 **
00991 ** @ingroup tp_xhelp
00992 **/
00993 // #############################################################################
00994 int process_ingroup_hash ( ) {
00995 #define $src_content ""
00996
00997 if (0){ //
00998 foreach $src_file (sort keys %group_hash){
00999 foreach $group_item (sort keys %{$group_hash{$src_file}} ){
01000 // print "$group_item :: $src_file :: $group_hash{$src_file}{$group_item}\n";
01001 }
01002 }
01003 if (0){
01004 // exit(1);
01005 }
01006 } // if test
01007
01008
01009 SRC_IN: foreach $src_file (sort keys %group_hash){
01010 // for each file that has a code item of interest
01011 unless (open ( IN_SRC, $src_file)) {
01012 // print "Cannot open file \"$src_file\"\n";
01013 push (@file_errors, "Cannot open file \"$src_file\"\n");
01014 next SRC_IN;
01015 }
01016 if (0) {
01017 // print "Source file is: $src_file\n";
01018 }
01019 // undef ($src_content); // start fresh
01020 // read file into memory
01021 while (<IN_SRC>) {
01022 // ########
01023 // Read in the source file, but change Doxygen comment syntax
01024 // so that it is consistent throughout whole file.
01025 // Begin replacement of
01026 // ########
01027 if (/^\/\/\!/) {
01028 if ($comment_count == 0){
01029 // first line of a comment block
01030 $comment_count++;
01031 $_ =~ s/\/\/\!/\/\*\*/;
01032 } else {
01033 // Some line in the middle of a comment block.
01034 $comment_count++;
01035 // ##
01036 // Changed to have middle stuff with no asterix.
01037 // $_ =~ s/\/\/\!/ \*\*/;
01038 // ##
01039 $_ =~ s/\/\/\!//;
01040 }
01041 } elsif ($comment_count > 0){
01042 // We were in a comment block; need to terminate it.
01043 $comment_count = 0;
01044 if (/^\/\//) {
01045 // Don't mess with comment lines.
01046 $_ = " \*\*\/\n" ;
01047 } else {
01048 // Not a comment lines.
01049 $_ = " \*\*\/\n" . $_ ;
01050 }
01051 }
01052 // ######## End Comment style change.
01053
01054 // ########
01055 // Trash all lines beginning with a comment.
01056 // ########
01057 if (/^\/\//) {
01058 // Don't mess with comment lines.
01059 } elsif ((/^\/\*/) && (/\*\/$/)) {
01060 // Don't mess with lines that begin and end as a comment
01061 } else {
01062 // Remember everything else
01063 $src_content .= $_;
01064 }
01065
01066 } // reading in source file
01067 if (0){
01068 // print $src_content;
01069 // exit(1);
01070 }
01071
01072 // for each @ingroup within the file, find the return value.
01073
01074 if ($src_content =~ /\@ingroup/){
01075 @dox_ingroup1 = split (/\@ingroup/, $src_content);
01076 DOX_INCOMING: foreach ($i = 1; $i <= $// dox_ingroup1; $i++) {
01077 // purposely don't look at the first chunk, because it'll be
01078 // uninteresting. Hopefully there's not an off-by-one error.
01079 // Split out the rest of the comments.
01080 @dox_ingroup2 = split (/\*\//, $dox_ingroup1[$i], 2);
01081 // dox_ingroup2[0] is remainder of comment
01082 // dox_ingroup2[1] is code stuff
01083 $process_g_flag = 0;
01084 foreach $desired_group (@xscope::ingroup){
01085 if ($dox_ingroup2[0] =~ /$desired_group/) {
01086 // This dox_group needs to be parsed for its return value
01087 $process_g_flag = 1;
01088 }
01089 } // $desired_group
01090
01091 if ($process_g_flag) {
01092 // Get the return value and code item name from the
01093 // code chunk and build up the file_hash.
01094 // dox_ingroup2[1] is code stuff
01095 @code_chunk1 = split (/\{/, $dox_ingroup2[1], 2);
01096 // $code_chunk1[0] is without implementation
01097 @code_chunk2 = split (/\(/, $code_chunk1[0], 2);
01098 if ($// code_chunk2 > 0) {
01099 if (1) {
01100 // ####
01101 // 4/23/2002 Notice that the excluded elements were creeping back
01102 // in when the actual source code file was processed.
01103 // Seeing if we have to exclude them later,
01104 // figured might as well not test here to save some time.
01105 // ####
01106 foreach $exclude (@xscope::needed_out) {
01107 // Jump over any commands that we are told to specifically exclude.
01108 if ($code_chunk2[0] =~ $exclude) {
01109 next DOX_INCOMING;
01110 }
01111 }
01112 }
01113 // Get rid of any leading carriage returns and slashes
01114 $code_chunk2[0] =~ s/^\s*\n+//;
01115 if (0) {
01116 // print "nnn $code_chunk2[0]\n";
01117 }
01118 if ($code_chunk2[0] =~ /[\S+]/){
01119 @ode_name = split (/\s/, $code_chunk2[0]);
01120 $_name = $ode_name[$// ode_name];
01121 $_name =~ s/^\*//;
01122 if (0){
01123 // print "ooo $_xcnt\:\:$code_chunk2[0]>>> $_name\n";
01124 }
01125 } else {
01126 if (0){
01127 // print "ooo2 $_xcnt\:\:$code_chunk2[0]\n";
01128 }
01129 }
01130 // ####
01131 // If we made it this far without doing a "next D_INCOMING" then
01132 // [1] $src_file contains the file of interest;
01133 // [2] $code_chunk2[0] contains the return type and item name.
01134 // [3] $_name is the item name.
01135 // Let's put the code items into the file hash to speed up our process.
01136 //
01137 // Need to handle function overloading, so
01138 //
01139 // $file_hash {files} {code items} {r} {return types}
01140 //
01141 // We don't care about what it points to.
01142 // ####
01143 if (exists ($file_hash{$src_file}{$_name}{r}{$code_chunk2[0]})) {
01144 $file_hash{$src_file}{$_name}{r}{$code_chunk2[0]} .= "; gp $_xcnt";
01145 } else {
01146 $file_hash{$src_file}{$_name}{r}{$code_chunk2[0]} = "gp $_xcnt";
01147 }
01148
01149 $_xcnt++;
01150 } // ($#code_chunk2 > 0)
01151 } // DOX_INCOMING
01152 } // $dox_chunk
01153 } // ($src_content =~ /\@ingroup/)
01154
01155 // close (SRC_IN);
01156 } // foreach SRC_IN
01157
01158 // #####
01159 // What is or will be in file hash
01160 // $file_hash{$src_file}{$code_item}{r}{$return_type} = number
01161 // #####
01162
01163 if (0){ //
01164 $j=0;
01165 foreach $src_file (sort keys %file_hash){
01166 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01167 foreach $return_type (sort keys %{$file_hash{$src_file}{$code_item}{r}} ) {
01168 $j++;
01169 // // print "$j $code_item :: $return_type :: $src_file\n";
01170 // print "$j $code_item :: $return_type\n";
01171 }
01172 }
01173 }
01174 if (1){
01175 // print "stopping here...";
01176 // exit(1);
01177 }
01178 } // if test
01179 if (0){
01180 // print "stopping here...";
01181 // exit(1);
01182 }
01183
01184 } // process_ingroup_hash
01185
01186
01187 //#############################################################################
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 // #############################################################################
01209 int inside_parenthesis ( ) {
01210 #define $in_text $_[0]
01211 // undef (@in_array);
01212 // undef (@out_array);
01213 #define $nest_cnt 0
01214 #define $have_it 0
01215
01216
01217 @in_array = split (//, $in_text);
01218 if (0) {
01219 // // print "GCMin:$#in_array:$in_text\n";
01220 // print "begin:$begin\n";
01221 // print "end:$end\n======\n";
01222 for ($i=0; $i<200; $i++){
01223 // print "$in_array[$i]";
01224 }
01225 // print "\nhey======\n";
01226 // // exit(1);
01227 }
01228 NEXT_CHAR: foreach $cchar (@in_array) {
01229 // put together an array that contains the prototype
01230 // and handles nested parenthesis with the prototype.
01231 if ($have_it) {
01232 // If this is set, we have the parenthesis,
01233 // but keep checking it until we have either a semicolon (;)
01234 // or an opening curly brace ({);
01235 if ($cchar =~ /\;/) {
01236 // If a semicolon follows what was in parenthesis,
01237 // then we've snagged the prototype which is not of interest.
01238 // get out of here
01239 if (0) {
01240 // print "Z1no$nest_cnt:$cchar\n";
01241 }
01242 return ("NEXT_ONE");
01243 } elsif ($cchar =~ /\{/) {
01244 // If an open curly brace follows what was in parenthesis,
01245 // then we've snagged the real code item that is of interest.
01246 if (0) {
01247 // print "Z2yes$nest_cnt:$cchar\n";
01248 }
01249 goto REALLY_HAVE;
01250 } else {
01251 if (0) {
01252 // print "Z3notyet$nest_cnt:$cchar\n";
01253 }
01254 next NEXT_CHAR;
01255 }
01256 } elsif (($nest_cnt == 0) && ($cchar =~ /\(/)) {
01257 if (0) {
01258 // print "A$nest_cnt:$cchar\n";
01259 }
01260 push (@out_array, $cchar);
01261 $nest_cnt++;
01262 next NEXT_CHAR;
01263 } elsif (($nest_cnt != 0) && ($cchar =~ /\(/)) {
01264 if (0) {
01265 // print "B$nest_cnt:$cchar\n";
01266 }
01267 push (@out_array, $cchar);
01268 $nest_cnt++;
01269 next NEXT_CHAR;
01270 } elsif (($nest_cnt != 0) && ($cchar =~ /\)/)) {
01271 push (@out_array, $cchar);
01272 $nest_cnt--;
01273 if (0) {
01274 // print "C$nest_cnt:$cchar\n";
01275 }
01276 if ($nest_cnt == 0){
01277 // Mark that we really have it;
01278 $have_it = 1;
01279 }
01280 next NEXT_CHAR;
01281
01282 } elsif (($nest_cnt == 0) && ($cchar !~ /\(/)) {
01283 if (0) {
01284 // print "D$nest_cnt:$cchar\n";
01285 }
01286 push (@out_array, $cchar);
01287 next NEXT_CHAR;
01288 } elsif ($nest_cnt != 0) {
01289 if (0) {
01290 // print "E$nest_cnt:$cchar\n";
01291 }
01292 push (@out_array, $cchar);
01293 next NEXT_CHAR;
01294 } // nest_cnt loop
01295 } // foreach $cchar
01296
01297 REALLY_HAVE:
01298 $out = join ("", @out_array);
01299 // undef (@in_array);
01300 // undef (@out_array);
01301 if (0) {
01302 // print "what's coming out=\n$out\n======\n";
01303 // // exit(1);
01304 }
01305 return ($out);
01306 } // inside_parenthesis
01307
01308
01309 //#############################################################################
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 // #############################################################################
01332 int find_doxygen ( ) {
01333 #define $piece_to_search $_[0]
01334 #define $dox_flag_b "\/\*\*"
01335 #define $dox_flag_e "\*\/"
01336 #define $out ""
01337
01338 if ($piece_to_search =~ /\/\*\*/) {
01339 // Doxygen in piece that could potentially be processed
01340 @dox_pieces = split ( /\/\*\*/, $piece_to_search);
01341 if (0) {
01342 // print "Maybe there is some doxygen (\/\*\*) ($// dox_pieces) to process.\n";
01343 // print "\/\*\*$dox_pieces[$// dox_pieces]";
01344 }
01345 // reduce to just doxygen stuff
01346 @dox_pieces2 = split (/\*\//, $dox_pieces[$// dox_pieces], 2);
01347
01348 // ERROR CHECKING
01349 // The leftover piece $dox_pieces2[1] is between the doxygen comment
01350 // and the code definition.
01351 // If there are parenthesis "(" or curly braces in the left over piece,
01352 // then the doxygen comment does not belong with this code item.
01353 if (($dox_pieces2[1] =~ /\(/) || ($dox_pieces2[1] =~ /\{/) || ($dox_pieces2[1] =~ /\;/)) {
01354 $out = "NO_DOX_COMMENT";
01355 } else {
01356 $out = "\/\*\*";
01357 $out .= $dox_pieces2[0];
01358 $out .= "\*\/";
01359 }
01360 } else {
01361 if (0) {
01362 // print "No doxygen to process.\n";
01363 }
01364 $out = "NO_DOX_COMMENT";
01365 }
01366 return ($out);
01367
01368 } // find_doxygen
01369
01370
01371 //#############################################################################
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395 // #############################################################################
01396 int write_output_file ( ) {
01397 $file_out = $_[0];
01398 // undef (%s_code_item); // sorted hash for code item
01399 // print "Writing the $file_out output file.\n";
01400
01401 unless (open ( OUT_FILE, ">$file_out")) {
01402 push (@file_errors, "Cannot open file \"$file_out\"\n");
01403 // print "Cannot open file \"$file_out\"\n";
01404 }
01405 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01406 if (1) {
01407 // Non-doxygen disclaimer at top of file.
01408 // print (OUT_FILE "\/\/ Generated file with the appropriate commands.\n");
01409 // print (OUT_FILE "\/\/ \n\/\/ Contains blank function declaration that\n");
01410 // print (OUT_FILE "\/\/ are preceded by their appropriate Doxygen comments\n");
01411 // print (OUT_FILE "\/\/ if they exist.\n");
01412 // print (OUT_FILE "\/\/ \n\/\/ Its purpose is to reduce what Doxygen looks at\n");
01413 // print (OUT_FILE "\/\/ to get rid of the noise in the output.\n");
01414 // print (OUT_FILE "\/\/ \n\/\/ THIS FILE IS GENERATED!!!\n");
01415 } else {
01416 // print (OUT_FILE "\/\/\! \@file\n");
01417 // print (OUT_FILE "\/\/\! \@brief Generated file with the appropriate commands.\n");
01418 // print (OUT_FILE "\/\/\! \n\/\/\! Contains blank function declaration that\n");
01419 // print (OUT_FILE "\/\/\! are preceded by their appropriate Doxygen comments\n");
01420 // print (OUT_FILE "\/\/\! if they exist.\n");
01421 // print (OUT_FILE "\/\/\! \n\/\/\! Its purpose is to reduce what Doxygen looks at\n");
01422 // print (OUT_FILE "\/\/\! to get rid of the noise in the output.\n");
01423 // print (OUT_FILE "\/\/\! \n\/\/\! THIS FILE IS GENERATED!!!\n");
01424 // // print (OUT_FILE "\/\/\! \n\/\/\! \@ingroup xhelp\n");
01425 }
01426 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01427 // print (OUT_FILE "\n\n\n");
01428
01429
01430 if (1) { // new way of doing it so that it gets sorted
01431 foreach $src_file (sort keys %file_hash){
01432 if (0) {
01433 // print "$src_file is source file\n";
01434 }
01435 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01436 if (0) {
01437 // print "$code_item is code item\n";
01438 }
01439 PPROTO: foreach $prototype (sort keys %{$file_hash{$src_file}{$code_item}{p}} ){
01440 if (0) {
01441 // print "$prototype\n";
01442 }
01443 $process_g_flag = 1;
01444 // ####
01445 // Exclude certain doxygen comment blocks;
01446 // In particular, if the block is the file header, it may
01447 // be of no interest.
01448 // ####
01449 foreach $undesired_tag (@xscope::dox_exclude){
01450 if ($file_hash{$src_file}{$code_item}{p}{$prototype} =~ /$undesired_tag/) {
01451 // This item does not belong in the output
01452 if (1) {
01453 // print"\"$code_item\" not in output because of \"$undesired_tag\"\n";
01454 }
01455 $process_g_flag = 0;
01456 }
01457 } // $undesired_tag
01458
01459 if ($process_g_flag) {
01460 if ($xscope::sapi) { // This is set in the generated sapi.pm
01461 $command_name = &get_sapi_name ($file_hash{$src_file}{$code_item}{p}{$prototype});
01462 if (0) {
01463 // print "debug:> $code_item\n";
01464 // // print "before the call with $src_file, $code_item, $prototype\n";
01465 // // print "$file_hash{$src_file}{$code_item}{p}{$prototype}\n";
01466 // print "c_name:> $command_name\n";
01467 }
01468 if ($command_name =~ /_NONE_/) {
01469 // if we don't have a command name, no sense putting anything out.
01470 next PPROTO;
01471 }
01472 } else { // for non-SAPI commands, like xhelp
01473 $command_name = $code_item;
01474 }
01475 if (0) {
01476 // print "debug:> $code_item\n";
01477 // print "c_name:> $command_name\n";
01478 }
01479 if (exists ($s_code_item{$code_item})) {
01480 $temp_string = "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n";
01481 $temp_string .= "$file_hash{$src_file}{$code_item}{p}{$prototype}\n";
01482 $temp_string .= "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n";
01483 $temp_string .= "$prototype\n\n";
01484 // if it exists, append this information to it.
01485 $s_code_item{$command_name} .= $temp_string;
01486 } else {
01487 $temp_string = "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n";
01488 $temp_string .= "$file_hash{$src_file}{$code_item}{p}{$prototype}\n";
01489 $temp_string .= "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n";
01490 $temp_string .= "$prototype\n\n";
01491 // if it doesn't exists, write this information to it.
01492 $s_code_item{$command_name} = $temp_string;
01493 }
01494 } // $process_g_flag
01495 }
01496 }
01497 }
01498 if (0) {
01499 // print "\n\nHi Glenn\n=====\n";
01500 foreach $command_name (sort keys %s_code_item){
01501 // print "$command_name\n";
01502 // // print "$s_code_item{$command_name}";
01503 }
01504 }
01505
01506 foreach $command_name (sort keys %s_code_item){
01507 // print (OUT_FILE "$s_code_item{$command_name}");
01508 }
01509
01510 // undef (%s_code_item);
01511 } // if (1) # new way of doing it so that it gets sorted
01512
01513
01514
01515
01516 if (0) { // old way of doing it
01517 foreach $src_file (sort keys %file_hash){
01518 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01519 foreach $prototype (sort keys %{$file_hash{$src_file}{$code_item}{p}} ){
01520 $process_g_flag = 1;
01521 // ####
01522 // Exclude certain doxygen comment blocks;
01523 // In particular, if the block is the file header, it may
01524 // be of no interest.
01525 // ####
01526 foreach $undesired_tag (@xscope::dox_exclude){
01527 if ($file_hash{$src_file}{$code_item}{p}{$prototype} =~ /$undesired_tag/) {
01528 // This item does not belong in the output
01529 $process_g_flag = 0;
01530 }
01531 } // $undesired_tag
01532
01533 if ($process_g_flag) {
01534 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01535 // print (OUT_FILE "$file_hash{$src_file}{$code_item}{p}{$prototype}\n");
01536 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01537 // print (OUT_FILE "$prototype\n\n");
01538 }
01539 }
01540 }
01541 }
01542 } // if (0) { # old way of doing it, no sorting done
01543 // close (OUT_FILE);
01544 } // write_output_file
01545
01546 //#############################################################################
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557 // #############################################################################
01558 int get_sapi_name ( ) {
01559 #define $all_doc $_[0]
01560 #define @all_line
01561 if (0) {
01562 // print "you are here with:) \n$all_doc\n";
01563 }
01564
01565 @all_line = split (/\n/, $all_doc);
01566
01567 DOCLINE: foreach $line (@all_line) {
01568 if ($line =~ /\@fn/){
01569 @fn_chunk = split (/\@fn[\s]*/, $line, 2);
01570 @rtn_chunk = split (/[\s]+/, $fn_chunk[1]);
01571 if (0) {
01572 // print "returning with \"$rtn_chunk[1]\"\n";
01573 }
01574 return ($rtn_chunk[1]); // this contains the sapi function name
01575 break;
01576 }
01577 } // foreach $line
01578 if (0) {
01579 // print "returning with \"_NONE_\"\n";
01580 }
01581 return ("_NONE_");
01582
01583 } // get_sapi_name
01584
01585 //#############################################################################
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609 // #############################################################################
01610 int write_output_list ( ) {
01611 $file_out = $_[0];
01612 // print "Writing the $file_out output file.\n";
01613
01614 unless (open ( OUT_FILE, ">$file_out")) {
01615 push (@file_errors, "Cannot open file \"$file_out\"\n");
01616 // print "Cannot open file \"$file_out\"\n";
01617 }
01618 // print (OUT_FILE "This file contains a list of the commands\n");
01619 // print (OUT_FILE "and their location.\n");
01620 // print (OUT_FILE "The letter in parenthesis refers to existing Doxygen comments.\n");
01621 // print (OUT_FILE "(n) has no comment block.\n");
01622 // print (OUT_FILE "(y) has a comment block filled in.\n");
01623 // print (OUT_FILE "(_TBD_) has a comment block still needing information.\n");
01624 // print (OUT_FILE "==============================================================\n\n");
01625
01626 foreach $src_file (sort keys %file_hash){
01627 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01628 foreach $prototype (sort keys %{$file_hash{$src_file}{$code_item}{p}} ){
01629 if ($file_hash{$src_file}{$code_item}{p}{$prototype} =~ /NO_DOX_COMMENT/) {
01630 // print (OUT_FILE "\(n\) $code_item :: $src_file\n");
01631 } elsif ($file_hash{$src_file}{$code_item}{p}{$prototype} =~ /_TBD_/) {
01632 // print (OUT_FILE "\(_TBD_\) $code_item :: $src_file\n");
01633 } else {
01634 // print (OUT_FILE "\(y\) $code_item :: $src_file\n");
01635 }
01636 }
01637 }
01638 }
01639 // close (OUT_FILE);
01640
01641 if (0) {
01642 foreach $src_file (sort keys %file_hash){
01643 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01644 // print "$code_item\n";
01645 }
01646 }
01647 // print "hola glenn\n";
01648 // exit(1);
01649 }
01650 if (0) {
01651 foreach $src_file (sort keys %file_hash){
01652 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01653 foreach $prototype (sort keys %{$file_hash{$src_file}{$code_item}{p}} ){
01654 // print "$prototype";
01655 }
01656 }
01657 }
01658 // print "hola glenn\n";
01659 // exit(1);
01660 }
01661 } // write_output_list
01662
01663 //#############################################################################
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675 // #############################################################################
01676 int write_output_class ( ) {
01677 $file_out = $_[0];
01678 // print "Writing the $file_out output file.\n";
01679
01680 unless (open ( OUT_FILE, ">$file_out")) {
01681 push (@file_errors, "Cannot open file \"$file_out\"\n");
01682 // print "Cannot open file \"$file_out\"\n";
01683 }
01684
01685 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01686 if (1) {
01687 // print (OUT_FILE "\/\/ brief Generated file with the appropriate commands.\n");
01688 // print (OUT_FILE "\/\/ \n\/\/ Contains blank function declaration that\n");
01689 // print (OUT_FILE "\/\/ are preceded by their appropriate Doxygen comments\n");
01690 // print (OUT_FILE "\/\/ if they exist.\n");
01691 // print (OUT_FILE "\/\/ \n\/\/ Its purpose is to reduce what Doxygen looks at\n");
01692 // print (OUT_FILE "\/\/ to get rid of the noise in the output.\n");
01693 // print (OUT_FILE "\/\/ \n\/\/ THIS FILE IS GENERATED!!!\n");
01694 } else {
01695 // print (OUT_FILE "\/\/\! \@file\n");
01696 // print (OUT_FILE "\/\/\! \@brief Generated file with the appropriate commands.\n");
01697 // print (OUT_FILE "\/\/\! \n\/\/\! Contains blank function declaration that\n");
01698 // print (OUT_FILE "\/\/\! are preceded by their appropriate Doxygen comments\n");
01699 // print (OUT_FILE "\/\/\! if they exist.\n");
01700 // print (OUT_FILE "\/\/\! \n\/\/\! Its purpose is to reduce what Doxygen looks at\n");
01701 // print (OUT_FILE "\/\/\! to get rid of the noise in the output.\n");
01702 // print (OUT_FILE "\/\/\! \n\/\/\! THIS FILE IS GENERATED!!!\n");
01703 // // print (OUT_FILE "\/\/\! \n\/\/\! \@ingroup xhelp\n");
01704 }
01705 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01706 // print (OUT_FILE "\n\n\n");
01707
01708 // ####
01709 // Sort the output by actual code item
01710 // We just need keys into the other structure; we don't need all of the data
01711 // of the other structure.
01712 // ####
01713 // undef (%list_of_items);
01714 if ($xscope::sapi) { // This is set in the generated sapi.pm
01715 // Then the list of $xscope::sapi_names is available
01716 // We still need to step through and match things up from the doxygen comment
01717 foreach $src_file (sort keys %file_hash){
01718 S_CODE: foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01719 S_PROTO: foreach $prototype (sort keys %{$file_hash{$src_file}{$code_item}{p}} ){
01720 @sm_dox = split (/\n/, $file_hash{$src_file}{$code_item}{p}{$prototype});
01721 for ($i=0; $i <= $// sm_dox; $i++) {
01722 if ($sm_dox[$i] =~ /\@fn/) {
01723 $match_line = $sm_dox[$i];
01724 if (0) {
01725 // print "match:$match_line\n";
01726 }
01727 break; // get out of this inner most loop
01728 }
01729 }
01730 S_NAME: foreach $names (@xscope::sapi_names){
01731 // ###
01732 // This is intended to match our sapi.pm generated list of names
01733 // with prototypes that are near the beginning of the doxygen comment.
01734 // ###
01735 // if ($file_hash{$src_file}{$code_item}{p}{$prototype} =~ /$names[\s]*\(/ ) {
01736 if ($match_line =~ /$names[\s]*\(/ ) {
01737 // something like "@fn int bogus_name ( blah, blah)"
01738 push ( @{$list_of_items{$names}{src}}, $src_file);
01739 push ( @{$list_of_items{$names}{code}}, $code_item);
01740 push ( @{$list_of_items{$names}{proto}}, $prototype);
01741 next S_PROTO;
01742 }
01743 }
01744 }
01745 }
01746 }
01747
01748 } else { // if ($xscope::sapi)
01749 // Then the $file_hash{$src_file}{$code_items} are the names we need
01750 foreach $src_file (sort keys %file_hash){
01751 foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01752 foreach $prototype (sort keys %{$file_hash{$src_file}{$code_item}{p}} ){
01753 push ( @{$list_of_items{$code_item}{src}}, $src_file);
01754 // duplicates it, but allows for a parallel structure as above
01755 // which gives us the needed keys into the original structure
01756 push ( @{$list_of_items{$code_item}{code}}, $code_item);
01757 push ( @{$list_of_items{$code_item}{proto}}, $prototype);
01758 }
01759 }
01760 }
01761 } // if ($xscope::sapi)
01762
01763 if (0) { // Debug
01764 foreach $item (sort keys %list_of_items) {
01765 for ($i=0; $i <= $// {$list_of_items{$item}{src}}; $i++) {
01766 // // print "$i\=\=$item\t\=\=$list_of_items{$item}{src}[$i]\n";
01767 // print "$i\=\=$item\t\=\=$list_of_items{$item}{code}[$i]\n";
01768 }
01769 }
01770 if (0) {
01771 // print "hola glenn\n";
01772 // exit(1);
01773 }
01774 }
01775
01776
01777 // ####
01778 // The problem this solves is that doxygen's output is organized
01779 // in the order that it receives it.
01780 // I end up sorting all temporary files before running
01781 // them through doxygen. Then my HTML will be organized.
01782 // ####
01783
01784 // ####
01785 // We remove the following, which is the old access method and unsorted.
01786 // It is replaced with what is sorted.
01787 // We need to match braces.
01788 // ####
01789 // foreach $src_file (sort keys %file_hash){
01790 // foreach $code_item (sort keys %{$file_hash{$src_file}} ){
01791 // foreach $prototype (sort keys %{$file_hash{$src_file}{$code_item}{p}} ){
01792 // ####
01793 foreach $item (sort keys %list_of_items) {
01794 for ($i=0; $i <= $// {$list_of_items{$item}{src}}; $i++) {
01795 $src_file = $list_of_items{$item}{src}[$i];
01796 $code_item = $list_of_items{$item}{code}[$i];
01797 $prototype = $list_of_items{$item}{proto}[$i];
01798
01799 { // $prototype matching parenthesis
01800 // ####
01801 // Replacement loop above
01802 // ####
01803
01804 $process_g_flag = 1;
01805 // ####
01806 // Exclude certain doxygen comment blocks;
01807 // In particular, if the block is the file header, it may
01808 // be of no interest.
01809 // ####
01810 foreach $undesired_tag (@xscope::dox_exclude) {
01811 if ($file_hash{$src_file}{$code_item}{p}{$prototype} =~ /$undesired_tag/) {
01812 // This item does not belong in the output
01813 $process_g_flag = 0;
01814 }
01815 } // $undesired_tag
01816
01817 if ($process_g_flag) {
01818 // if ($prototype =~ /\"\)\;\}/){
01819 if ($prototype =~ /\"/){
01820 // The construct above is giving us problems in the output,
01821 // so let's not put it in the output.
01822 delete ($file_hash{$src_file}{$code_item}{p}{$prototype});
01823 } elsif ($prototype =~ /\:\:/){
01824 @sm_proto = split (/\{/, $prototype);
01825 $sm_proto[0] =~ s/\n//g;
01826
01827 @class_ch1 = split (/\:\:/, $prototype);
01828 @class_ch2 = split (/[\s+]/, @class_ch1[0]);
01829 if (exists ($class_hash{$class_ch2[$// class_ch2]})) {
01830 // $class_hash{$class_ch2[$#class_ch2]} .= " virtual $sm_proto[0]\;\n";
01831 // $class_hash{$class_ch2[$#class_ch2]} .= " $sm_proto[0]\;\n";
01832 } else {
01833 // $class_hash{$class_ch2[$#class_ch2]} = " virtual $sm_proto[0]\;\n";
01834 // $class_hash{$class_ch2[$#class_ch2]} = " $sm_proto[0]\;\n";
01835 $class_hash{$class_ch2[$// class_ch2]} = " \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n";
01836 }
01837 // ####
01838 // code prototype is $prototype while
01839 // doxygen template is in $file_hash{$src_file}{$code_item}{p}{$prototype}
01840 // ####
01841 if (!($xscope::sapi)) { // This is set in the generated sapi.pm
01842 // Means we're working on something that wants to have
01843 // the class definitions come through.
01844 // We need the class definition.
01845 $class_hash{$class_ch2[$// class_ch2]} .= " \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n";
01846 $class_hash{$class_ch2[$// class_ch2]} .= "$file_hash{$src_file}{$code_item}{p}{$prototype}\n";
01847 $class_hash{$class_ch2[$// class_ch2]} .= " \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n";
01848 $class_hash{$class_ch2[$// class_ch2]} .= " $sm_proto[0]\;\n";
01849 } else { // $xscope::sapi
01850 // when working on sapi, we don't need to be so anal about
01851 // creating class stuff;
01852 // we just need the doxygen comment output so that
01853 // the @fn can map to the sapi_gen prototypes later.
01854 if ($file_hash{$src_file}{$code_item}{p}{$prototype} =~ /\@fn/) {
01855 // only output a sapi @fn doxygen template;
01856 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01857 // print (OUT_FILE "$file_hash{$src_file}{$code_item}{p}{$prototype}\n");
01858 }
01859 } // $xscope::sapi
01860 }
01861 } // if process flag
01862 } // $prototype matching parenthesis
01863 } // $i
01864 } // $item
01865
01866 if (!($xscope::sapi)) { // This is set in the generated sapi.pm
01867 // Means we're working on something that wants to have
01868 // the class definitions come through.
01869 // We need the class definition.
01870 foreach $class (sort keys %class_hash){
01871 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01872 // print (OUT_FILE "\/\/ begin $class\n");
01873 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01874 // print (OUT_FILE "class $class\n");
01875 // print (OUT_FILE "{\n");
01876 // print (OUT_FILE " public\:\n");
01877 // print (OUT_FILE "$class_hash{$class}\n");
01878 // print (OUT_FILE "}\;\n");
01879 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01880 // print (OUT_FILE "\/\/ end $class\n");
01881 // print (OUT_FILE "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n");
01882 // print (OUT_FILE "\n\n\n\n");
01883 }
01884 }
01885 // close (OUT_FILE);
01886 } // write_output_class
01887
01888
01889 //#############################################################################
01890
01891
01892
01893
01894
01895
01896
01897
01898 // #############################################################################
01899 int using_xhelp ( ) {
01900 // print "============ Syntax ==================================\n";
01901 // print "xhelp_gen.pl <input scope package> <root path to files> <output file path \& name> \n\n";
01902 // print "- <input scope package> is file path and name to a perl package that ";
01903 // print "has lists of functions to be included and to be excluded.\n\n";
01904 // print "- <root path to files> is the code location to start looking ";
01905 // print "and must be terminated with a forward (\/) slash. ";
01906 // print "If output file does not have a forward slash (\/) -- an indication ";
01907 // print "of a path --, then the <root path to files> is assumed.\n\n";
01908 // print "- <output file path \& name> plus another file ";
01909 // print "with a leading underscore are generated. ";
01910 // print "The file without the underscore is intended as the input to Doxygen.\n\n";
01911 // print "============ Terminate ==================================\n";
01912 // print "Terminating xhelp_gen.pl without doing anything.\n";
01913 return(1);
01914 }
01915
01916
01917 //#############################################################################
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928 // #############################################################################
01929 int END ( ) {
01930 // undef ($_file_list); // "_file_list";
01931 // undef ($in_file ); // "";
01932 // undef ($root_path ); // "./";
01933 // undef (%file_hash);
01934
01935
01936 // #############################################################################
01937 // # Memory clean-up.
01938 // # Perform this if it was defined.
01939 // #############################################################################
01940 if ($no_scope_file > 0){
01941 &xscope::memory_clean_up();
01942 }
01943
01944 // print "\n============ Finished xhelp_gen.pl ==================================\n";
01945 } // END
01946