home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / doc / intlist / int2hlp.bat < prev    next >
DOS Batch File  |  1991-11-15  |  14KB  |  556 lines

  1. @REM=("
  2. @perl -w %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
  3. @end ") if 0 ;
  4. #
  5. # Create an RTF file from the PC interrupt list.
  6. # The RTF file will be compiled into quickhelp format.
  7. # By Diomidis Spinellis <dds@doc.ic.ac.uk>.
  8. #
  9. # You will need the Microsoft helpmake utility, a sort that takes the -f (fold)
  10. # and -d (dictionary order) options, around 12:40 time of 20MHz 386 CPU 
  11. # time and around 6 MB of disk space.
  12. # Put all the interrupt list distribution files in one directory create the
  13. # interrupt.lst file by merging interrupt.? and run the  program.  The 
  14. # interrupt.lst file will be deleted during the process to save disk space.
  15. #
  16. # (C) Copyright 1991 Diomidis Spinellis.  All rights reserved.
  17. # Permission to use and distribute this file without modification is given.
  18. #
  19.  
  20. $labelnum = 0;
  21. # int.byf - Interrupts by Function (Tree Internal Nodes)
  22. &maketop_by_function();
  23. &makecont(0, "Interrupts by Function", "int.byfunc", "int.hlp");
  24. &merge_out('int.byf');
  25. # int.byv - Interrupts by Value (Tree Internal Nodes)
  26. &maketop_by_value();
  27. &makecont(0, "Interrupts by Value", "int.byval", "int.hlp");
  28. &merge_out('int.byv');
  29. # int.bot - Interrupt List Interrupts (Tree Terminal Nodes)
  30. &summary('int.byv', 'sum.byv');
  31. &summary('int.byf', 'sum.byf');
  32. &makebottom();
  33. &unlink_intermediate();
  34. unlink('interrup.lst');    # To make room
  35. # int.idx - Interrupt List Index
  36. &makeindex();
  37. # int.fil - Interrupt List Auxiliary Files
  38. unlink('int.fil');
  39. &incfile('int.mem', 'Memory List', 'memory.lst');
  40. &incfile('int.pri', 'Interrupt Primer', 'interrup.pri');
  41. &make1st();
  42. #&incfile('int.1st', 'Distribution, Abbreviations and Acknowledgements', 'interrup.1st');
  43. # int.toc - Interupt List Table of Contents
  44. &maketoc();
  45. exec('helpmake', '/T', '/e', '/W100', '/oint.hlp', '/V', 'int.toc', 'int.byv', 'int.byf', 'int.bot', 'int.idx', 'int.fil');
  46.  
  47. # Create a contents file.  Level is the recursive level, topic the
  48. # header to use, context the unique identifier for this topic and
  49. # up the identifier of the parent topic.
  50. # Works by scanning the input of the current level line by line and
  51. # identifying topics.  If the topic is unique it is output on a list
  52. # else the topic is output on the list with a pointer to another list
  53. # and the function is called recursively.
  54. sub makecont
  55. {
  56.     local($level, $topic, $context, $up) = @_;
  57.     local($IN, $OUT);
  58.     local($l, $prev, $part, $ref, $tmp);
  59.  
  60.     $IN = "IN$level";
  61.     $OUT = "OUT$level";
  62.     open($IN, "sort in$level|") || die;
  63.     open($OUT, ">>out$level") || die;
  64.  
  65.     print "makecont($level, [$topic], [$context], [$up])\n";
  66.     $dummy = &makehead($context, 3, $topic, $up);
  67.     print $OUT $dummy;
  68.     while (<$IN>) {
  69.         chop;
  70.         print "$level: Read [$_]\n";
  71.         $part = (split(/ \- /))[0];
  72.         if ($part =~ /^`/) {
  73.             $part =~ s/`//;
  74.         } else {
  75.             $part =~ s/`.*//;
  76.         }
  77.         next if ($part eq $prev);
  78.         $ref = (split(/`/))[1];
  79.         print "part = [$part]\n";
  80.         if (&count($part, "in$level") <= 1) {
  81.             if ($ref eq '') {
  82.                 print $OUT "\t\\a$part\\v$part\\v\n";
  83.             } else {
  84.                 print $OUT "\t\\a$part\\v$ref\\v\n";
  85.             }
  86.         } else {
  87.             $u = &newlabel();
  88.             print $OUT "\t\\a$part\\v$u\\v\n";
  89.             $l = $level + 1;
  90.             ©match($part, "in$level", "in$l");
  91.             $tmp = $context;
  92.             &makecont($l, $part, $u, $tmp);
  93.         }
  94.         $prev = $part;
  95.     }
  96.     print $OUT ' ' x 35 . "-\04-\n";
  97.     close($IN);
  98.     close($OUT);
  99. }
  100.  
  101. # Return number of lines matching string
  102. sub count
  103. {
  104.     local($string, $file) = @_;
  105.  
  106.     $string =~ s/(\W)/\\$1/g;
  107.     open (CIN, $file) || die;
  108.     $count = 0;
  109.     while (<CIN>) {
  110.         $count++ if (/^$string(( - )|`)/);
  111.     }
  112.     print "count($string) = $count\n";
  113.     close(CIN);
  114.     return $count;
  115. }
  116.  
  117. # Copy lines that match string from $in to $out removing string
  118. sub copymatch
  119. {
  120.     local($string, $in, $out) = @_;
  121.  
  122.     $string =~ s/(\W)/\\$1/g;
  123.     open(CIN, $in) || die;
  124.     open(COUT, ">$out") || die;
  125.     while (<CIN>) {
  126.         if (/^$string(( - )|`)/) {
  127.             s/^$string[-\s`]*//;
  128.             print COUT;
  129.         }
  130.     }
  131.     close(CIN);
  132.     close(COUT);
  133. }
  134.  
  135. # Open the interrupt list and create a file with one line for each
  136. # interrupt.  The line consists of the interrupt description followed
  137. # by a backtick and the interrupt number.
  138. sub maketop_by_function
  139. {
  140.     &unlink_out();
  141.     open(IN, "interrup.lst") || die;
  142.     open(OUT, ">in0") || die;
  143.     while (<IN>) {
  144.         if (/^--------/) {
  145.             chop;
  146.             $int = $_;
  147.             $int =~ s/-+//g;
  148.             if ($last eq $int) {
  149.                 $int .= $letter++;
  150.             } else {
  151.                 $letter = 'a';
  152.                 $last = $int;
  153.             }
  154.         }
  155.         if (/^INT /) {
  156.             chop;
  157.             $line = $_;
  158.             $line =~ s/^INT [^-]*- //;
  159.             $line =~ s/\\/\\\\/g;
  160.             print OUT "$line\`$int\n";
  161.         }
  162.     }
  163.     close(IN);
  164.     close(OUT);
  165. }
  166.  
  167. # Return a unique new label
  168. sub newlabel
  169. {
  170.     return "\@IL" . $labelnum++;
  171. }
  172.  
  173. # Unlink all output files
  174. sub unlink_out
  175. {
  176.     for ($i = 0; $i < 10; $i++) {
  177.         unlink("out$i");
  178.     }
  179. }
  180.  
  181. # Unlink all intermediate files
  182. sub unlink_intermediate
  183. {
  184.     for ($i = 0; $i < 10; $i++) {
  185.         unlink("out$i");
  186.         unlink("in$i");
  187.     }
  188.     unlink('sum.byf');
  189.     unlink('sum.byv');
  190. }
  191.  
  192. # Merge the output files into int.byf
  193. sub merge_out
  194. {
  195.     local($outname) = @_;
  196.  
  197.     open(OUT, ">$outname");
  198.     for ($i = 0; $i < 10; $i++) {
  199.         if (open(IN, "out$i")) {
  200.             while (<IN>) {
  201.                 print OUT;
  202.             }
  203.             close(IN);
  204.         }
  205.     }
  206.     close(OUT);
  207.     &unlink_out();
  208. }
  209.  
  210. # Open the interrupt list and create a file with one line for each
  211. # interrupt.  The line consists of the interrupt identifications
  212. # (number and register values) followed by the unique interrupt identifier
  213. sub maketop_by_value
  214. {
  215.     &unlink_out();
  216.     open(IN, "interrup.lst") || die;
  217.     open(OUT, ">in0") || die;
  218.     while (<IN>) {
  219.         if (/^----------[0-9A-F]/) {
  220.             chop;
  221.             $int = $_;
  222.             $int =~ s/-+//g;
  223.             if ($last eq $int) {
  224.                 $int .= $letter++;
  225.             } else {
  226.                 $letter = 'a';
  227.                 $last = $int;
  228.             }
  229.             $_ =~ /^----------(..)(..)(..)(..)(....)/;
  230.             $num = $1;    # Interrupt number
  231.             $ah = $2;    # Register AH
  232.             $al = $3;    # Register AL
  233.             $rn = $4;    # Other register name
  234.             $rv = $5;    # Other register value (8 or 16 bit)
  235.             $rv =~ s/-//g;
  236.             print OUT "INT $num";
  237.             print OUT " - AH = $ah" if ($ah ne '--');
  238.             print OUT " - AL = $al" if ($al ne '--');
  239.             print OUT " - $rn = $rv" if ($rn ne '--');
  240.             print OUT "`$int\n";
  241.         }
  242.     }
  243.     close(IN);
  244.     close(OUT);
  245. }
  246.  
  247. # Create the bottom nodes of the file
  248. # Each node contains a navigation line for going upwards by value or function
  249. # Try to create seens for the SeeAlso lines
  250. sub makebottom
  251. {
  252.     open(IN, "interrup.lst") || die;
  253.     open(OUT, ">int.bot") || die;
  254.     print OUT &makehead('int.intro', 3, 'Interrupt List', 'int.hlp');
  255.     while (<IN>) {
  256.         chop;
  257.         s/\\/\\\\/g;
  258.         if (/^----------[0-9A-F]/) {
  259.             $int = $_;
  260.             $int =~ s/-+//g;
  261.             if ($last eq $int) {
  262.                 $int .= $letter++;
  263.             } else {
  264.                 $letter = 'a';
  265.                 $last = $int;
  266.             }
  267.             $_ =~ /^----------(..)(..)(..)(..)(....)/;
  268.             $num = $1;    # Interrupt number
  269.         } elsif (/^INT /) {
  270.             $line = $_;
  271.             print "$line\n";
  272.             print OUT ' ' x 35 . "-\04-\n";
  273.             print OUT ".context $int\n";
  274.             print OUT ".freeze 4\n";
  275.             print OUT ".topic $line\n";
  276.             $upf = &parent('sum.byf', $int);
  277.             $upv = &parent('sum.byv', $int);
  278.             print OUT "                         \\i\021\\p\\aUp Function\\v${upf}\\v\\i\020\\p \\i\021\\p\\aUp Value\\v${upv}\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  279.             print OUT "\304" x 75 . "\n";
  280.             print OUT "\\b$line\\p\n\n";
  281.         } elsif (/^SeeAlso: (.*)$/) {
  282.             print OUT '\bSeeAlso:\p ';
  283.             @back = @list = split(/, */, $1);
  284.             for ($i = 0; $i <= $#list; $i++) {
  285.                 $list[$i] =~ s/"[^"]*"//g;
  286.                 $list[$i] =~ s/A[HX]//g;
  287.                 $list[$i] =~ s/[\/h=]//g;
  288.                 if ($list[$i] =~ /^INT (..)/) {
  289.                     $num = $1;
  290.                     $list[$i] =~ s/^INT //;
  291.                 } else {
  292.                     $list[$i] =~ s/^/$num/;
  293.                 }
  294.                 if ($cont = &intcontext($list[$i])) {
  295.                     print OUT "\\i\021\\p\\a$back[$i]\\i\020\\p\\v$cont\\v";
  296.                 } elsif (&exists($list[$i])) {
  297.                     print OUT "\\i\021\\p\\a$back[$i]\\i\020\\p\\v$list[$i]\\v";
  298.                 } else {
  299.                     print OUT "$back[$i]";
  300.                 }
  301.                 print OUT ', ' if ($i < $#list);
  302.             }
  303.             print OUT "\n";
  304.         } elsif (/^(\w+:)(.*)$/) {
  305.             print OUT "\\b$1\\p$2\n";
  306.         } else {
  307.             print OUT;
  308.             print OUT "\n";
  309.         }
  310.     }
  311.     print OUT ' ' x 35 . "-\04-\n";
  312.     close(IN);
  313.     close(OUT);
  314. }
  315.  
  316. # Reding $in create a $out file containing each context and its parent
  317. # context.
  318. sub summary
  319. {
  320.     local($in, $out) = @_;
  321.  
  322.     open(IN, $in) || die;
  323.     open(OUT, ">$out") || die;
  324.     while (<IN>) {
  325.         chop;
  326.         next if (/\\i\021\\p/);
  327.         if (/^\.context (.*)$/) {
  328.             $context = $1;
  329.         }
  330.         if (/\\v([^I][^\\]+)/) {
  331.             print OUT "$1`$context\n";
  332.         }
  333.     }
  334. }
  335.  
  336. # Return the parent of node $val in file $in
  337. sub parent
  338. {
  339.     local ($in, $val) = @_;
  340.  
  341.     open (SUM, $in) || die;
  342.     while (<SUM>) {
  343.         chop;
  344.         if (/^$val`(.*)$/) {
  345.             close(SUM);
  346.             return $1;
  347.         }
  348.     }
  349.     print STDERR "\a*** $val has not parent node!\n";
  350.     close(SUM);
  351.     return 'int.hlp';
  352. }
  353.  
  354. # Return true if a bottom node $val exists as a context
  355. sub exists
  356. {
  357.     local ($val) = @_;
  358.  
  359.     open (EX, 'sum.byf') || die;
  360.     while (<EX>) {
  361.         chop;
  362.         if (/^$val`/) {
  363.             close(SUM);
  364.             return 1;
  365.         }
  366.     }
  367.     print STDERR "\a*** $val does not exist!\n";
  368.     close(SUM);
  369.     return 0;
  370. }
  371.  
  372. # Given a two digit interrupt number return the correct context
  373. # Works by searching the first 300 lines of int.byv.  Do not change
  374. # its format without checking this function.
  375. sub intcontext
  376. {
  377.     local($int) = @_;
  378.  
  379.     if ($int !~ /^[0-9][A-F][0-9][A-F]$/) {
  380.         return undef;
  381.     }
  382.     open(INC, 'int.byv') || die;
  383.     $i = 0;
  384.     while (<INC> && $i < 300) {
  385.         if (/\\aINT $int\\v([^\\]+)\\v$/) {
  386.             close(INC);
  387.             return $1;
  388.         }
  389.         $i++;
  390.     }
  391.     close(INC);
  392.     print STDERR "\a*** Unable to locate interrupt $int\n";
  393.     return undef;
  394. }
  395.  
  396. # Make a simple index by concatenating all the int.byf lines and sorting them
  397. # by character.
  398. sub makeindex
  399. {
  400.     # Construct the index line
  401.     $all='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';        # Dict chars
  402.     $index = "\332";
  403.     for ($i = 0; $i < length($all) - 1; $i++) {
  404.         $index .= "\304\302";
  405.     }
  406.     $index .= "\304\277\n";
  407.     $index .= "\263";
  408.     for ($i = 0; $i < length($all); $i++) {
  409.         $l = substr($all, $i, 1);
  410.         $index .= "\\a$l\\v\@IL.$l\\v\263";
  411.     }
  412.     $index .= "\n";
  413.     $index .= "\300";
  414.     for ($i = 0; $i < length($all) - 1; $i++) {
  415.         $index .= "\304\301";
  416.     }
  417.     $index .= "\304\331\n\n";
  418.     # Now create the index, character by character
  419.     open(IN, 'sort -d -f int.byf|');    # Fold case, dict order
  420.     open(OUT, '>int.idx');
  421.     undef $prev;
  422.     while (<IN>) {
  423.         if (/^\t\\a[^A-Za-z0-9]*(.)/) {
  424.             $letter = $1;
  425.             next if ($letter eq '?');        # Ignore \v on V
  426.             $letter =~ tr/[a-z]/[A-Z]/;
  427.             if ($letter ne $prev) {
  428.                 print OUT ' ' x 35 . "-\04-\n" if ($prev);
  429.                 print OUT &makehead("\@IL.$letter", 7, "Index $letter", 'int.idx');
  430.                 $idxline = $index;
  431.                 $idxline =~ s/\\a$letter\\v/\\a\\b$letter\\p\\v/;
  432.                 print OUT $idxline;
  433.                 $prev = $letter;
  434.             }
  435.             print OUT;
  436.         }
  437.     }
  438.     close(IN);
  439.     print OUT ' ' x 35 . "-\04-\n";
  440.     print OUT ".context h.idx\n";
  441.     print OUT &makehead('int.idx', 3, 'Index', 'int.hlp');
  442.     print OUT "\n\n\n";
  443.     print OUT $index;
  444.     print OUT ' ' x 35 . "-\04-\n";
  445.     close(OUT);
  446. }
  447.  
  448. # Include a file with given context, topic and filename to the file int.fil
  449. sub incfile
  450. {
  451.     local($context, $topic, $name) = @_;
  452.  
  453.     open(OUT, '>>int.fil');
  454.     open(IN, "$name") || die;
  455.     print OUT &makehead($context, 3, $topic, 'int.hlp');
  456.     while (<IN>) {
  457.         s/\\/\\\\/g;
  458.         print OUT;
  459.     }
  460.     print OUT ' ' x 35 . "-\04-\n";
  461.     close(OUT);
  462. }
  463.  
  464. # Create the table of contents file
  465. sub maketoc
  466. {
  467.     open(OUT, '>int.toc') || die;
  468.     print OUT 
  469. ".context Interrupt List
  470. .context int.hlp
  471. .context int
  472. .context interrupt list
  473. .context h.contents
  474. .context h.pg1
  475. ";
  476.     print OUT &makehead('contents', 3, 'The Interrupt List', 'int.hlp');
  477.     print OUT "\t\t\t\\bThe PC Interrupt List\\p
  478.  
  479.  
  480. \t\\a\\i\021\\p1. General Information\\vint.1st\\v\\i\020\\p
  481. \t\\a\\i\021\\p2. File Header\\vint.intro\\v\\i\020\\p
  482. \t\\a\\i\021\\p3. Interrupts by Value\\vint.byval\\v\\i\020\\p
  483. \t\\a\\i\021\\p4. Interrupts by Function\\vint.byfunc\\v\\i\020\\p
  484. \t\\a\\i\021\\p5. Memory List\\vint.mem\\v\\i\020\\p
  485. \t\\a\\i\021\\p6. Interrupt Primer\\vint.pri\\v\\i\020\\p
  486. \t\\a\\i\021\\p7. Index\\vint.idx\\v\\i\020\\p
  487.  
  488.  
  489.  
  490.  
  491.  
  492. Compilation Copyright (c) 1989, 1990, 1991 Ralf Brown
  493. Helpmake conversion Copyright (c) 1991 Diomidis Spinellis
  494.  
  495.                                    -\04-
  496. .context List Categories
  497. Interrupt List
  498. ";
  499.     close(OUT);
  500. }
  501.  
  502. #
  503. # Split up the interrup.1st file into sections as section.1st
  504. #
  505. sub make1st
  506. {
  507.     open(IN, 'interrup.1st') || die;
  508.     open(OUT, '>>int.fil') || die;
  509.     @sections = (
  510.         'Version', &newlabel,
  511.         'Copyright Notice', &newlabel,
  512.         'Additional Copyright', &newlabel,
  513.         'Disclaimer', &newlabel,
  514.         'Updates and Distribution', &newlabel,
  515.         'System Abbreviations', &newlabel,
  516.         'Contributors', &newlabel,
  517.         'Sources', &newlabel,
  518.         'API Reference Providers', &newlabel,
  519.         'Other Addresses', &newlabel,
  520.         'Trademarks and Copyrights', &newlabel,
  521.         'Reviews', &newlabel,
  522.         'Author Contact', &newlabel
  523.     );
  524.     for ($i = 0; $i <= $#sections; $i += 2) {
  525.         print OUT &makehead($sections[$i + 1], 3, $sections[$i], 'int.1st');
  526.         while (<IN>) {
  527.             last if (/^----------------------------------/);
  528.             s/\\/\\\\/g;
  529.             print OUT;
  530.         }
  531.         print OUT ' ' x 35 . "-\04-\n";
  532.     }
  533.     print OUT &makehead('int.1st', 3, 'General Information', 'int.hlp');
  534.     print OUT "\t\t\t\t\\bGeneral Information\\p\n\n\n";
  535.     for ($i = 0, $num = 1; $i <= $#sections; $i += 2, $num++) {
  536.         printf(OUT "\t\\a\\i\021\\p%2d. $sections[$i]\\v" . $sections[$i + 1] . "\\v\\i\020\\p\n", $num);
  537.     }
  538.     print OUT "\n\n";
  539.     print OUT ' ' x 35 . "-\04-\n";
  540.     close(OUT);
  541. }
  542.  
  543. #
  544. # Return a navigation head for an entry
  545. #
  546. sub makehead
  547. {
  548.     local($context, $freeze, $topic, $up) = @_;
  549.     $head = ".context $context\n";
  550.     $head .= ".freeze $freeze\n";
  551.     $head .= ".topic $topic\n";
  552.     $head .= "                                             \\i\021\\p\\aUp\\v${up}\\v\\i\020\\p \\i\021\\p\\aContents\\vint.hlp\\v\\i\020\\p \\i\021\\p\\aIndex\\vint.idx\\v\\i\020\\p \\i\021\\p\\aBack\\v!B\\v\\i\020\\p\n";
  553.     $head .= "\304" x 75 . "\n\n";
  554.     return $head;
  555. }
  556.