home *** CD-ROM | disk | FTP | other *** search
/ Hot Shareware 32 / hot34.iso / ficheros / DTOOL / INTER57E.ZIP / INTLIST.E < prev    next >
Text File  |  1998-03-22  |  48KB  |  1,665 lines

  1. /****************************************************************/
  2. /*    EEL code file for editing the Interrupt List        */
  3. /*                                */
  4. /*    Written by Ralf Brown                    */
  5. /*    LastEdit:  22 Mar 98                    */
  6. /*                                */
  7. /*  This EEL file adds the following keybindings:        */
  8. /*    Shf-Alt-A add an Access: section to the current entry    */
  9. /*    Shf-Alt-B add another BUG: to the current entry           */
  10. /*    Shf-Alt-D add a Desc: section to the current entry    */
  11. /*    Sft-Alt-I add an InstallCheck: section to current entry    */
  12. /*    Shf-Alt-R add a Range: section to the current entry       */
  13. /*    Shf-Alt-S add a Size: section to the current entry    */
  14. /*    Alt-I    add an Index: section to the current entry;    */
  15. /*         add another Index: line if already on Index:    */
  16. /*      Alt-N   add a new note to current entry or data struct  */
  17. /*      Alt-P   add a Program: section to the current entry     */
  18. /*      Alt-R   insert Return: at start of line                 */
  19. /*    Alt-S    insert SeeAlso: at start of line; add another    */
  20. /*         SeeAlso: line if already on SeeAlso:        */
  21. /*    F11    insert a blank separator line            */
  22. /*    ^F11    create Format of: header            */
  23. /*    Shf-F11    create Values for: header            */
  24. /*    Alt-F11 create Call with: header            */
  25. /*    Alt-F12 create Bitfield for: header            */
  26. /*    F12    add the interrupt number to the separator line    */
  27. /*        preceding the current entry            */
  28. /*    ^F12    jump to a specified entry            */
  29. /*                                */
  30. /*  It adds the following unbound commands:                */
  31. /*      renumber-tables                            */
  32. /*    make-distribution                    */
  33. /*      filter-region                        */
  34. /*        run region through a specified command; by      */
  35. /*               default, the program is given the region on its */
  36. /*         stdin and its stdout is used to replace the    */
  37. /*        region; if one or two "%s" are given, they    */
  38. /*        will be replaced by the input and output (resp) */
  39. /*        file the program should use.            */
  40. /*                                */ 
  41. /*  Other:                            */
  42. /*    adds intlist-mode for .LST and .1ST files        */
  43. /*    switches current buffer into intlist-mode on loading    */
  44. /*      maintains a table counter which is inserted each time   */
  45. /*        a table is created in the text                */
  46. /*      performs syntax highlighting (Epsilon v7+)        */
  47. /****************************************************************/
  48.  
  49. #include "eel.h"
  50. #if EELVERSION >= 70
  51. #include "colcode.h"
  52. #endif /* Epsilon v7.0+ */
  53.  
  54. keytable intlist_tab ;            /* key table for IntList mode */
  55.  
  56. /* on repeated F12, how often to display number of entries processed */
  57. /* for fast 386, every 100; for a Pentium, at least 300 or the message */
  58. /* line will lag way behind the actual progress */
  59. #define NUMBER_INT_PROGRESS_INTERVAL 500
  60.  
  61. /*=============================================================*/
  62. /*    Global Variables                           */
  63. /*=============================================================*/
  64.  
  65. /* table headings */
  66. char str_format_of[] = "Format of " ;
  67. char str_bitfields_for[] = "Bitfields for " ;
  68.  
  69. /* section names within an entry */
  70. char size_section[] = "Size:\t" ;
  71. char access_section[] = "Access:\t" ;
  72. char return_section[] = "Return: " ;
  73. char program_section[] = "Program: " ;
  74. char desc_section[] = "Desc:\t" ;
  75. char install_section[] = "InstallCheck:" ;
  76. char range_section[] = "Range:\t" ;
  77. char notes_section[] = "Notes*:\t" ;
  78. char bugs_section[] = "BUGS*:\t" ;
  79. char example_section[] = "Example: " ;
  80. char seealso_section[] = "SeeAlso: " ;
  81. char index_section[] = "Index:\t" ;
  82.  
  83. #if EELVERSION >= 70
  84. char all_sections[] = "Return:|SeeAlso:|Program:|Desc:|Range:|Notes*:|BUGS*:|Example:|Index:|Access:|InstallCheck:|Size:" ;
  85. char indented_sections[] = "[\t ]*(Return|Notes*):" ;
  86. char table_headers[] = "INT |Format |Values |Bitfields |MEM |CMOS |MSR |CALL |PORT |Call |OPCODE |I2C " ;
  87. #endif /* Epsilon v7.0+ */
  88.  
  89. char table_ID_letters[] = "0123456789CFIMPRS" ;
  90.  
  91. char *(section_order[13]) ;
  92. char *(list_files[13]) ;
  93.  
  94. #if EELVERSION >= 90
  95. // Lugaru renamed the variable on us!
  96. #define strip_returns translation_type
  97. #endif /* EELVERSION >= 90 */
  98.  
  99. when_loading()
  100. {
  101.    /* list the sections of an entry in the order they should appear (if */
  102.    /* present at all) */
  103.    section_order[0] = size_section ;
  104.    section_order[1] = access_section ;
  105.    section_order[2] = return_section ;
  106.    section_order[3] = program_section ;
  107.    section_order[4] = desc_section ;
  108.    section_order[5] = install_section ;
  109.    section_order[6] = range_section ;
  110.    section_order[7] = notes_section ;
  111.    section_order[8] = bugs_section ;
  112.    section_order[9] = example_section ;
  113.    section_order[10] = seealso_section ;
  114.    section_order[11] = index_section ;
  115.    section_order[12] = NULL ;
  116.    /* list the files comprising the full interrupt list */
  117.    list_files[0] = "cmos.lst" ;
  118.    list_files[1] = "farcall.lst" ;
  119.    list_files[2] = "memory.lst" ;
  120.    list_files[3] = "ports.lst" ;
  121.    list_files[4] = "interrup.lst" ;
  122.    list_files[5] = "tables.lst" ;
  123.    list_files[6] = "msr.lst" ;
  124.    list_files[7] = "biblio.lst" ;
  125.    list_files[8] = "glossary.lst" ;
  126.    list_files[9] = "opcodes.lst" ;
  127.    list_files[10] = "smm.lst" ;
  128.    list_files[11] = "i2c.lst" ;
  129.    list_files[12] = NULL ;
  130. }
  131.  
  132. /*=============================================================*/
  133. /*    Buffer-specific variables                       */
  134. /*=============================================================*/
  135.  
  136. buffer spot table_counter ;
  137.  
  138. /*=============================================================*/
  139. /*=============================================================*/
  140.  
  141. int empty_line()
  142. {
  143.    return (character(point-1) == '\n' && character(point) == '\n') ;
  144. }
  145.  
  146. /*=============================================================*/
  147. /*=============================================================*/
  148.  
  149. int is_separator_line()
  150. {
  151.    return (empty_line() || parse_string(1,"--------",NULL)) ;
  152. }
  153.  
  154. /*=============================================================*/
  155. /* search in the specified direction (1 = forward, -1 = back)  */
  156. /* for the next entry separator line                   */
  157. /*=============================================================*/
  158.  
  159. int to_separator_line(dir)
  160. int dir ;
  161. {
  162.    nl_reverse() ;
  163.    return search(dir,"\n--------") ;
  164. }
  165.  
  166. /*=============================================================*/
  167. /* move to the location where the specified section of an      */
  168. /* entry begins (if present) or should begin (if not)           */
  169. /*=============================================================*/
  170.  
  171. int to_section_start(section)
  172. char *section ;
  173. {
  174.    int i, j, len ;
  175.  
  176.    for (i = 0 ; section_order[i] ; i++)
  177.       if (strcmp(section,section_order[i]) == 0)
  178.      break ;
  179.    if (section_order[i])
  180.       {
  181.       while (!is_separator_line())
  182.      {
  183.      for (j = i ; section_order[j] ; j++)
  184.         if (parse_string(1,section_order[j],NULL))
  185.            {
  186.            if ((len = parse_string(1,section,NULL)) != 0)
  187.           {
  188.           point += len ;
  189.           return 1 ;    /* section already exists */
  190.           }
  191.            return 0 ;    /* section nonexistent, but found position */
  192.            }
  193.      if (!nl_forward())
  194.         break ;
  195.      }
  196.       return 0 ;    /* section does not yet exist */
  197.       }
  198.    else
  199.       return 0 ;    /* section not found */
  200. }
  201.  
  202. /*=============================================================*/
  203. /*=============================================================*/
  204.  
  205. int make_section(section,start_entry,name)
  206. char *section, *name ;
  207. int start_entry ;
  208. {
  209.    int start = point ;
  210.  
  211.    if (start_entry)
  212.       {
  213.       if (!to_separator_line(-1))  /* find previous separator line */
  214.      {
  215.      point = start ;
  216.      say("Not in an interrupt entry") ;
  217.      return 0 ;
  218.      }
  219.       }
  220.    else
  221.       {
  222.       to_begin_line() ;
  223.       while (!empty_line() && !parse_string(1,"\n--------",NULL))
  224.      if (!nl_reverse())
  225.         break ;
  226.       }
  227.    point++ ;                 /* skip the newline */
  228.    nl_forward() ;             /* advance to first line of entry */
  229.    if (!to_section_start(section))
  230.       {
  231.       if (name)
  232.      stuff(name) ;
  233.       else
  234.      stuff(section) ;
  235.       stuff("\n") ;
  236.       point-- ;              /* back up over inserted newline */
  237.       return 1 ;
  238.       }
  239.    else
  240.       return 0 ;
  241.    return 2 ;  /* just in case */
  242. }
  243.  
  244. /*=============================================================*/
  245. /*=============================================================*/
  246.  
  247. int pluralize_section(plural)
  248. char plural ;
  249. {
  250.    point -= 3 ;
  251.    if (curchar() != plural)        /* already plural ? */
  252.       {
  253.       point++ ;
  254.       insert(plural) ;
  255.       }
  256.    nl_forward() ;
  257.    while (!is_separator_line() && parse_string(1,"[ \t]",NULL))
  258.       nl_forward() ;
  259.    stuff("\t\n") ;
  260.    point-- ;
  261. }
  262.  
  263. /*=============================================================*/
  264. /* Add "SeeAlso: " to the beginning of the current line unless */
  265. /* it is already present; in that case, insert a fresh line    */
  266. /* containing just a SeeAlso: and position the cursor at the   */
  267. /* end of the new line                           */
  268. /*=============================================================*/
  269.  
  270. command see_also() on intlist_tab[ALT('s')]
  271. {
  272.    to_begin_line() ;
  273.    if (parse_string(1,"SeeAlso: ",NULL) == 0)
  274.       stuff("SeeAlso: ") ;
  275.    else
  276.       {
  277.       nl_forward() ;
  278.       stuff("SeeAlso: \n") ;
  279.       point-- ;
  280.       }
  281. }
  282.  
  283. /*=============================================================*/
  284. /* Add a Desc: section if the current entry does not already   */
  285. /* have one; if there is already a Desc: section, move to the  */
  286. /* start of it                               */
  287. /*=============================================================*/
  288.  
  289. command access() on intlist_tab[ALT('A')]
  290. {
  291.    make_section(access_section,1,NULL) ;
  292. }
  293.  
  294. /*=============================================================*/
  295. /* Add a Desc: section if the current entry does not already   */
  296. /* have one; if there is already a Desc: section, move to the  */
  297. /* start of it                               */
  298. /*=============================================================*/
  299.  
  300. command desc() on intlist_tab[ALT('D')]
  301. {
  302.    make_section(desc_section,1,NULL) ;
  303. }
  304.  
  305. /*=============================================================*/
  306. /* Add a InstallCheck: section if the current entry does not   */
  307. /* already have one; if there is already a InstallCheck:       */
  308. /* section, move to the start of it                   */
  309. /*=============================================================*/
  310.  
  311. command instcheck() on intlist_tab[ALT('I')]
  312. {
  313.    make_section(install_section,1,NULL) ;
  314. }
  315.  
  316. /*=============================================================*/
  317. /* Add a Range: section if the current entry does not already  */
  318. /* have one; if there is already a Range: section, move to the */
  319. /* start of it                               */
  320. /*=============================================================*/
  321.  
  322. command range() on intlist_tab[ALT('R')]
  323. {
  324.    make_section(range_section,1,NULL) ;
  325. }
  326.  
  327. /*=============================================================*/
  328. /* Add a Size: section if the current entry does not already   */
  329. /* have one; if there is already a Size: section, move to the  */
  330. /* start of it                               */
  331. /*=============================================================*/
  332.  
  333. command memsize() on intlist_tab[ALT('S')]
  334. {
  335.    make_section(size_section,1,NULL) ;
  336. }
  337.  
  338. /*=============================================================*/
  339. /* Add a "Program: " section to the current entry if it does   */
  340. /* not have one; otherwise, move to the beginning of the       */
  341. /* Program: section                           */
  342. /*=============================================================*/
  343.  
  344. command program() on intlist_tab[ALT('p')]
  345. {
  346.    make_section(program_section,1,NULL) ;
  347. }
  348.  
  349. /*=============================================================*/
  350. /* Add an "Index: " section to the current entry if it does    */
  351. /* not have one; otherwise, move to the beginning of the       */
  352. /* Index: section                           */
  353. /*=============================================================*/
  354.  
  355. command add_index() on intlist_tab[ALT('i')]
  356. {
  357.    to_begin_line() ;
  358.    if (parse_string(1,"Index:",NULL))
  359.       {
  360.       while (parse_string(1,"Index:",NULL))
  361.      nl_forward() ;
  362.       stuff("Index:\t\n") ;
  363.       point-- ;
  364.       }
  365.    else
  366.       make_section(index_section,1,NULL) ;
  367. }
  368.  
  369. /*=============================================================*/
  370. /*=============================================================*/
  371.  
  372. command bug() on intlist_tab[ALT('B')]
  373. {
  374.    if (!make_section(bugs_section,1,"BUG:\t"))
  375.       pluralize_section('S') ;
  376. }
  377.  
  378. /*=============================================================*/
  379. /* Add "Note: " section to the current entry; change an        */
  380. /* existing Note: to Notes: and position at end of Note:       */
  381. /* section.                               */
  382. /*=============================================================*/
  383.  
  384. command add_note() on intlist_tab[ALT('n')]
  385. {
  386.    if (!make_section(notes_section,0,"Note:\t"))
  387.       pluralize_section('s') ;
  388. }
  389.  
  390. /*=============================================================*/
  391. /* Insert "Return: " at the beginning of the current line, if  */
  392. /* not already present                           */
  393. /*=============================================================*/
  394.  
  395. command returns() on intlist_tab[ALT('r')]
  396. {
  397.    int start = point ;
  398.    
  399.    to_begin_line() ;
  400.    if (parse_string(1,return_section,NULL) == 0)
  401.       stuff(return_section) ;
  402.    else
  403.       point = start ;
  404. }
  405.  
  406. /*=============================================================*/
  407. /* insert a line of dashes prior to the current cursor line    */
  408. /*=============================================================*/
  409.  
  410. command separator_line() on intlist_tab[FKEY(11)]
  411. {
  412.    int i ;
  413.  
  414.    to_begin_line() ;
  415.    for (i = 0 ; i < 45 ; i++)
  416.       insert('-') ;
  417.    insert('\n') ;
  418. }
  419.  
  420. /*=============================================================*/
  421. /*=============================================================*/
  422.  
  423. void insert_table_counter()
  424. {
  425.    char counter[6] ;
  426.    save_var point = *table_counter + 3 ;
  427.  
  428.    /* increment that table counter */
  429.    while (curchar() >= '0')
  430.       {
  431.       if (curchar() < '9')
  432.      {
  433.      replace(point,curchar()+1) ;
  434.      break ;
  435.      }
  436.       else
  437.      {
  438.      replace(point,'0') ;
  439.      point-- ;
  440.      }
  441.       }
  442.    restore_vars() ;
  443.    /* and now insert the incremented value at point */
  444.    stuff("(Table ") ;
  445.    grab(*table_counter,*table_counter+4,counter) ;
  446.    stuff(counter) ;
  447.    stuff(")") ;
  448. }
  449.  
  450. /*=============================================================*/
  451. /* type the name of a structure, then invoke this function     */
  452. /* to create the "Format of X:" and "Offset Size Descr" lines  */
  453. /*=============================================================*/
  454.  
  455. command structure_header() on intlist_tab[FCTRL(11)]
  456. {
  457.    int start = point ;
  458.  
  459.    to_begin_line() ;
  460.    if (parse_string(1,str_format_of,NULL) == 0)
  461.       {
  462.       stuff(str_format_of) ;
  463.       to_end_line() ;
  464.       stuff(":\nOffset\tSize\tDescription\t") ;
  465.       insert_table_counter() ;
  466.       stuff("\n 00h\t") ;
  467.       }
  468.    else
  469.       point = start ;
  470. }
  471.  
  472. /*=============================================================*/
  473. /* Turn the current line into the header for a "Values of"     */
  474. /* section                               */
  475. /*=============================================================*/
  476.  
  477. command value_header() on intlist_tab[FSHIFT(11)]
  478. {
  479.    int start = point ;
  480.    
  481.    to_begin_line() ;
  482.    if (parse_string(1,"Values for ",NULL) == 0)
  483.       {
  484.       insert_table_counter() ;
  485.       stuff("\nValues for ") ;
  486.       to_end_line() ;
  487.       stuff(":\n ") ;
  488.       }
  489.    else
  490.       point = start ;
  491. }
  492.  
  493. /*=============================================================*/
  494. /* Turn the current line into the header of a "Call with"      */
  495. /* section                               */
  496. /*=============================================================*/
  497.  
  498. command call_with_header() on intlist_tab[FALT(11)]
  499. {
  500.    int start = point ;
  501.    
  502.    to_begin_line() ;
  503.    if (parse_string(1,"Call ",NULL) == 0)
  504.       {
  505.       insert_table_counter() ;
  506.       stuff("\nCall ") ;
  507.       to_end_line() ;
  508.       if (character(point-1) != ' ')
  509.      stuff(" ") ;
  510.       stuff("with:\n") ;
  511.       }
  512.    else
  513.       point = start ;
  514. }
  515.  
  516. /*=============================================================*/
  517. /* Turn the current line into the header of a "Bitfield for"   */
  518. /* section                               */
  519. /*=============================================================*/
  520.  
  521. command bitfields_for_header() on intlist_tab[FALT(12)]
  522. {
  523.    int start = point ;
  524.    
  525.    to_begin_line() ;
  526.    if (parse_string(1,str_bitfields_for,NULL) == 0)
  527.       {
  528.       stuff(str_bitfields_for) ;
  529.       to_end_line() ;
  530.       stuff(":\nBit(s)\tDescription\t") ;
  531.       insert_table_counter() ;
  532.       stuff("\n ") ;
  533.       }
  534.    else
  535.       point = start ;
  536. }
  537.  
  538. /*=============================================================*/
  539. /*=============================================================*/
  540.  
  541. char grab_int_entry_number(func_num)
  542. char *func_num ;
  543. {
  544.    int i ;
  545.    char c ;
  546.    
  547.    point += 4 ;                /* skip the "INT " */
  548.    func_num[0] = curchar() ;        /* grab the interrupt number */
  549.    point++ ;
  550.    func_num[1] = curchar() ;
  551.    nl_forward() ;            /* skip to second line of entry */
  552.    if (parse_string(1,"[ \t]*A[LHX][ \t]=[ \t][0-9A-F][0-9A-F]+h",NULL))
  553.       {
  554.       re_search(1,"[ \t]*A") ;
  555.       c = curchar() ;
  556.       point += 4 ;            /* skip ch and " = " */
  557.       if (c != 'L')
  558.      {
  559.      grab(point,point+((c=='X')?4:2),func_num+2) ;
  560.      point += ((c=='X')?4:2) ;
  561.      func_num[(c=='H')?4:6] = '-' ;    /* grab() stuck a NUL into the string */
  562.      }
  563.       else /* c == 'L' */
  564.      {
  565.      func_num[4] = curchar() ;
  566.      point++ ;
  567.      func_num[5] = curchar() ;
  568.      point ++ ;
  569.      }
  570.       point++ ;
  571.       if (parse_string(1,"[ \t]*subfn [0-9A-F][0-9A-F]+h",NULL))
  572.      {
  573.      re_search(1,"[ \t]*subfn ") ;
  574.      func_num[6] = 'S' ;
  575.      func_num[7] = 'F' ;
  576.      for (i = 0 ; i < 4 ; i++)
  577.         {
  578.         c = curchar() ;
  579.         if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
  580.            {
  581.            func_num[8+i] = c ;
  582.            point++ ;
  583.            }
  584.         else
  585.            break ;
  586.         }
  587.      }
  588.       nl_forward() ;            /* skip to third line of entry */
  589.       }
  590.    if (parse_string(1,"[ \t]*([BCDES][HILPSX]|VxD) = [0-9A-F][0-9A-F]+h",NULL))
  591.       {
  592.       re_search(1,"[ \t]*") ;
  593.       func_num[6] = curchar() ;
  594.       point++ ;
  595.       func_num[7] = c = curchar() ;
  596.       point += 4 ;            /* skip curchar and " = " */
  597.       if (func_num[6] == 'V')        /* VxD has three letters not two... */
  598.      point++ ;
  599.       if (c == 'H' || c == 'L')
  600.      {
  601.      grab(point,point+2,func_num+8) ;
  602.      func_num[10] = '-' ;        /* grab() stuck a NUL into the string */
  603.      }
  604.       else /* c == 'X' || c == 'I' || c == 'P' || c == 'S' */
  605.      {
  606.      grab(point,point+4,func_num+8) ;
  607.      func_num[12] = '-' ;
  608.      }
  609.       }
  610.    return 1 ;                /* successful and have func number */
  611. }
  612.  
  613. /*=============================================================*/
  614.  
  615. char grab_cmos_entry_number(func_num)
  616. char *func_num ;
  617. {
  618.    point += 5 ;                    /* skip the "CMOS " */
  619.    func_num[0] = 'R' ;            /* mark this as a CMOS RAM entry */
  620.    grab(point,point+4,func_num+1) ;
  621.    if (func_num[3] == 'h' && func_num[4] == '-')
  622.       grab(point+4,point+6,func_num+3) ;
  623.    else
  624.       {
  625.       func_num[3] = '-' ;
  626.       func_num[4] = '-' ;
  627.       }
  628.    func_num[5] = '-' ;            /* grab() stuck a NUL into string */
  629.    return 1 ;
  630. }
  631.  
  632. /*=============================================================*/
  633.  
  634. char grab_farcall_entry_number(func_num)
  635. char *func_num ;
  636. {
  637.    point += 5 ;                /* skip the "CALL " */
  638.    func_num[0] = '@' ;            /* mark this as a far call entry */
  639.    grab(point,point+4,func_num+1) ;    /* get segment of address */
  640.    grab(point+6,point+10,func_num+5) ;    /* get offset of address */
  641.    func_num[9] = '-' ;            /* grab() stuck a NUL into string */
  642.    return 1 ;
  643. }
  644.  
  645. /*=============================================================*/
  646.  
  647. char grab_msr_entry_number(func_num)
  648. char *func_num ;
  649. {
  650.    point += 4 ;                /* skip the "MSR " */
  651.    func_num[0] = 'S' ;            /* mark this as an MSR entry */
  652.    grab(point,point+8,func_num+1) ;     /* get the MSR number */
  653.    func_num[9] = '-' ;                  /* grab() stuck a NUL into string */
  654.    return 1 ;
  655. }
  656.  
  657. /*=============================================================*/
  658.  
  659. char grab_memory_entry_number(func_num)
  660. char *func_num ;
  661. {
  662.    point += 4 ;                /* skip the "MEM " */
  663.    func_num[0] = 'M' ;                /* mark this as a memory loc entry */
  664.    grab(point,point+6,func_num+1) ;    /* get segment or high word of addr */
  665.    if (func_num[5] == 'h' && func_num[6] == ':') /* segmented address? */
  666.       grab(point+6,point+10,func_num+5) ;    /* get offset of address */
  667.    else
  668.       {
  669.       grab(point+6,point+8,func_num+7) ;/* get low word of the address */
  670.       func_num[0] = 'm' ;        /* indicate linear address */
  671.       }
  672.    func_num[9] = '-' ;            /* grab() stuck a NUL into string */
  673.    return 1 ;
  674. }
  675.  
  676. /*=============================================================*/
  677.  
  678. char grab_opcode_name(func_num)
  679. char *func_num ;
  680. {
  681.    int i ;
  682.    point += 7 ;                /* skip the "OPCODE " */
  683.    func_num[0] = 'O' ;            /* mark this as an opcode entry */
  684.    for (i = 2 ; i < 12 ; i++)        /* grab the opcode name and stuff */
  685.       {                       /*   it into the header line */
  686.       char c = curchar() ;
  687.       if (c == ' ' || c == '\t')
  688.      break ;
  689.       else
  690.      {
  691.      func_num[i] = c ;
  692.      point++ ;
  693.      }
  694.       }
  695.    return 1 ;
  696. }
  697.  
  698. /*=============================================================*/
  699.  
  700. char grab_port_entry_number(func_num)
  701. char *func_num ;
  702. {
  703.    point += 5 ;                /* skip the "PORT " */
  704.    func_num[0] = 'P' ;            /* mark this as an I/O port entry */
  705.    grab(point,point+4,func_num+1) ;    /* get starting port number */
  706.    func_num[5] = '-' ;            /* grab() stuck a NUL into string */
  707.    if (character(point+4) == '-')
  708.       {
  709.       grab(point+5,point+9,func_num+5) ; /* get ending port number */
  710.       func_num[9] = '-' ;        /* grab() stuck a NUL into string */
  711.       }
  712.    return 1 ;
  713. }
  714.  
  715. /*=============================================================*/
  716.  
  717. char grab_i2c_entry_number(func_num)
  718. char *func_num ;
  719. {
  720.    point += 4 ;                /* skip the "I2C " */
  721.    func_num[0] = 'I' ;            /* mark this as an I2C port entry */
  722.    grab(point,point+2,func_num+1) ;    /* get slave address */
  723.    func_num[3] = '-' ;            /* grab() stuck a NUL into string */
  724.    if (character(point+3) == '/')
  725.       {
  726.       grab(point+4,point+6,func_num+3) ; /* get register address */
  727.       func_num[5] = '-' ;        /* grab() stuck a NUL into string */
  728.       if (character(point+6) != 'h' && character(point+6) != '/')
  729.      {
  730.      grab(point+6,point+8,func_num+5) ; /* get second byte of reg. addr */
  731.      func_num[7] = '-' ;        /* grab() stuck a NUL into string */
  732.      point += 2 ;
  733.      }
  734.       if (character(point+7) == '/')
  735.      {
  736.      func_num[7] = 'S' ;
  737.      func_num[8] = 'F' ;
  738.      grab(point+8,point+10,func_num+9) ;
  739.      func_num[11] = '-' ;
  740.      if (character(point+10) != 'h')
  741.         grab(point+10,point+12,func_num+11) ;
  742.      }
  743.       }
  744.    return 1 ;
  745. }
  746.  
  747. /*=============================================================*/
  748.  
  749. char grab_entry_number(func_num)
  750. char *func_num ;
  751. {
  752.    strcpy(func_num,"-------------") ;    /* 13 dashes */
  753.    point++ ;                /* go to first char of separator line */
  754.    nl_forward() ;            /* go to first line of entry */
  755.    if (parse_string(1,"INT ",NULL))    /* is it an interrupt entry? */
  756.       return grab_int_entry_number(func_num) ;
  757.    else if (parse_string(1,"CMOS ",NULL) != 0)
  758.       return grab_cmos_entry_number(func_num) ;
  759.    else if (parse_string(1,"CALL ",NULL) != 0)
  760.       return grab_farcall_entry_number(func_num) ;
  761.    else if (parse_string(1,"MEM ",NULL) != 0)
  762.       return grab_memory_entry_number(func_num) ;
  763.    else if (parse_string(1,"PORT ",NULL) != 0)
  764.       return grab_port_entry_number(func_num) ;
  765.    else if (parse_string(1,"MSR ",NULL) != 0)
  766.       return grab_msr_entry_number(func_num) ;
  767.    else if (parse_string(1,"OPCODE ",NULL) != 0)
  768.       return grab_opcode_name(func_num) ;
  769.    else if (parse_string(1,"I2C ",NULL) != 0)
  770.       return grab_i2c_entry_number(func_num) ;
  771.    else
  772.       return 0 ;
  773. }
  774.  
  775. /*=============================================================*/
  776. /* Put the interrupt and function number into the separator    */
  777. /* line just above the intlist entry preceding the cursor pos  */
  778. /*=============================================================*/
  779.  
  780. int number_one_int()
  781. {
  782.    char func_num[14] ;            /* 2->int, 4->AX, 6->extra reg, NUL */
  783.    int oldpoint ;
  784.    
  785.    while (to_separator_line(-1))    /* find previous separator line */
  786.       {
  787.       oldpoint = point ;
  788.       if (grab_entry_number(func_num))    /* does it belong to an intlist entry? */
  789.      {                /*   if yes, success, else try again */
  790.      point = oldpoint + 11 ;    /* skip NL and first ten dashes */
  791.      delete(point,point+13) ;    /* replace 13 dashes by the function */
  792.      stuff(func_num) ;        /*   number and extra register */
  793.      point = oldpoint + 9 ;        /* back to category letter position */
  794.      return 1 ;
  795.      }
  796.       point = oldpoint ;
  797.       }
  798.    return 0 ;                /* if we get here, we failed */
  799. }
  800.  
  801. /*=============================================================*/
  802. /* Put the interrupt and function number into the separator    */
  803. /* line just above one or more intlist entries preceding the   */
  804. /* current cursor position, letting user know of progress      */
  805. /*=============================================================*/
  806.  
  807. command number_int() on intlist_tab[FKEY(12)]
  808. {
  809.    int i, hit_top = 0 ;
  810.    
  811.    for (i = 0 ; i < iter ; i++)
  812.       {
  813.       if (!number_one_int())
  814.      {
  815.      hit_top = 1 ;
  816.      say("No prior entry.") ;
  817.      break ;
  818.      }
  819.       if (((i+1) % NUMBER_INT_PROGRESS_INTERVAL) == 0)
  820.      say("%4d...",i+1) ;
  821.       }
  822.    if (iter > 1 && !hit_top)
  823.       say("Done.") ;
  824.    iter = 1 ;
  825. }
  826.  
  827. /*=============================================================*/
  828. /*=============================================================*/
  829.  
  830. int line_has_see_also()
  831. {
  832.    int len ;
  833.    
  834.    to_begin_line() ;
  835.    if ((len = parse_string(1,".*%([sS]ee ",NULL)) != 0)
  836.       {
  837.       point += len ;        /* go to start of cross-reference */
  838.       point += parse_string(1,"also ",NULL) ;
  839.       if (parse_string(1,"INT [0-9A-F]",NULL) ||
  840.       parse_string(1,"A[XHL] =",NULL)
  841.      )
  842.      {
  843.      point++ ;        /* move into reference */
  844.      return 1 ;
  845.      }
  846.       }
  847.    return 0 ;
  848. }
  849.  
  850. /*=============================================================*/
  851. /*=============================================================*/
  852.  
  853. int grab_int_reference(ref)
  854. char *ref ;
  855. {
  856.    int begin, start = point ;
  857.    
  858.    re_search(-1,"[, \t\n]") ;    /* backup to start of reference */
  859.    if (curchar() == '\n')    /* start of line? */
  860.       re_search(1,":[ \t]") ;    /* skip the SeeAlso: */
  861.    else if (character(point-1) == 'T' && character(point-2) == 'N')
  862.       point -= 3 ;
  863.    else
  864.       point++ ;            /* back to start of reference */
  865.    begin = point ;
  866.    re_search(1,"[,\n\"]") ;    /* find end of INT-spec */
  867.    point-- ;
  868.    if (curchar() == '\"')    /* extra string at end of INT-spec? */
  869.       {
  870.       point++ ;
  871.       re_search(1,"[\"\n]") ;    /* if yes, run to end of line or string */
  872.       }
  873.    grab(begin,point,ref) ;
  874.    point = start ;
  875.    return 0 ;
  876. }
  877.  
  878. /*=============================================================*/
  879. /*=============================================================*/
  880.  
  881. int parse_int_name(entry_name,id,extra_string)
  882. char *entry_name, *id, *extra_string ;
  883. {
  884.    int start = point ;
  885.    int i ;
  886.    char c, *last ;
  887.  
  888.    for (i = strlen(entry_name)-1 ; i >= 0 ; i--)
  889.       entry_name[i] = toupper(entry_name[i]) ;
  890.    strcpy(id,"------------") ;
  891.    if (strncmp(entry_name,"INT ",4) == 0)
  892.       {
  893.       id[0] = entry_name[4] ;
  894.       id[1] = entry_name[5] ;
  895.       entry_name += 6 ;
  896.       if (entry_name[0] == '/')
  897.      entry_name++ ;
  898.       }
  899.    else if (to_separator_line(-1))
  900.       {
  901.       id[0] = character(point+11) ;
  902.       id[1] = character(point+12) ;
  903.       }
  904.    point = start ;
  905.    c = entry_name[1] ;
  906.    if (entry_name[0] == 'A' && (c == 'X' || c == 'H' || c == 'L'))
  907.       {
  908.       entry_name += 2 ;
  909.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  910.      entry_name++ ;
  911.       if (entry_name[0] == '=')
  912.      entry_name++ ;
  913.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  914.      entry_name++ ;
  915.       if (c != 'L')
  916.      {
  917.          id[2] = entry_name[0] ;
  918.          id[3] = entry_name[1] ;
  919.      }
  920.       if (c == 'X')
  921.      {
  922.      id[4] = entry_name[2] ;
  923.      id[5] = entry_name[3] ;
  924.      entry_name += 4 ;
  925.      }
  926.       else
  927.      {
  928.      if (c == 'L')
  929.         {
  930.         id[2] = entry_name[0] ;
  931.         id[3] = entry_name[1] ;
  932.         }
  933.      entry_name += 2 ;
  934.      }
  935.       if (entry_name[0] == 'H')
  936.      entry_name++ ;
  937.       if (entry_name[0] == '/')
  938.      entry_name++ ;
  939.       }
  940.    if (index("ABCDES",entry_name[0]) && index("HILPSXF",entry_name[1]))
  941.       {
  942.       id[6] = entry_name[0] ;
  943.       c = id[7] = entry_name[1] ;
  944.       entry_name += 2 ;
  945.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  946.      entry_name++ ;
  947.       if (entry_name[0] == '=')
  948.      entry_name++ ;
  949.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  950.      entry_name++ ;
  951.       id[8] = entry_name[0] ;
  952.       id[9] = entry_name[1] ;
  953.       if (c != 'H' && c != 'L' && (c != 'F' || entry_name[2] != 'h'))
  954.      {
  955.      id[10] = entry_name[2] ;
  956.      id[11] = entry_name[3] ;
  957.      entry_name += 4 ;
  958.      }
  959.       else
  960.      entry_name += 2 ;
  961.       if (entry_name[0] == 'H')
  962.      entry_name++ ;
  963.       if (entry_name[0] == '/')
  964.      entry_name++ ;
  965.       }
  966.    if (entry_name[0] == '\"')
  967.       {
  968.       entry_name++ ;
  969.       strcpy(extra_string,entry_name) ;
  970.       last = index(extra_string,'\"') ;
  971.       if (last)
  972.      *last = '\0' ;
  973.       }
  974.    else
  975.       extra_string[0] = '\0' ;
  976.    return 0 ;
  977. }
  978.  
  979. /*=============================================================*/
  980. /*=============================================================*/
  981.  
  982. int hex2_to_int(c1,c2)
  983. char c1, c2 ;
  984. {
  985.    if (c1 >= '0' && c1 <= '9')
  986.       c1 -= '0' ;
  987.    else if (c1 >= 'A' && c1 <= 'F')
  988.       c1 = c1 - 'A' + 10 ;
  989.    else if (c1 >= 'a' && c1 <= 'f')
  990.       c1 = c1 - 'a' + 10 ;
  991.    else
  992.       return -1 ;
  993.    if (c2 >= '0' && c2 <= '9')
  994.       c2 -= '0' ;
  995.    else if (c2 >= 'A' && c2 <= 'F')
  996.       c2 = c2 - 'A' + 10 ;
  997.    else if (c2 >= 'a' && c2 <= 'f')
  998.       c2 = c2 - 'a' + 10 ;
  999.    else
  1000.       return -1 ;
  1001.    return 16*c1 + c2 ;
  1002. }
  1003.  
  1004. /*=============================================================*/
  1005. /*=============================================================*/
  1006.  
  1007. char hex_digit(val)
  1008. int val ;
  1009. {
  1010.    if (val < 0)
  1011.       return '-' ;
  1012.    else
  1013.       return (val > 9) ? ('A' + val - 10) : ('0' + val) ;
  1014. }
  1015.  
  1016. /*=============================================================*/
  1017. /*=============================================================*/
  1018.  
  1019. int scan_for_entry(entry,extra_str,first_entry)
  1020. char *entry, *extra_str ;
  1021. int *first_entry ;
  1022. {
  1023.    int bestcount = 0 ;
  1024.    int bestmatch = -1 ;
  1025.  
  1026.    if (extra_str) extra_str = 0 ;  /* for now, to avoid compiler warning */
  1027.    *first_entry = 0 ;
  1028.    /* scan for the first entry for the desired interrupt number */
  1029.    while (to_separator_line(1))
  1030.       {
  1031.       point += 2 ;
  1032.       if (character(point) == entry[0] && character(point+1) == entry[1])
  1033.      break ;
  1034.       nl_forward() ;
  1035.       }
  1036.    /* now scan through the entries for the given interrupt number */
  1037.    while (to_separator_line(1))
  1038.       {
  1039.       int i ;
  1040.       char buf[14] ;
  1041.       point += 2 ;
  1042.       grab(point,point+12,buf) ;
  1043.       if ((buf[0] != entry[0] || buf[1] != entry[1]) &&
  1044.       (buf[0] != '-' && buf[1] != '-'))
  1045.      break ;            /* ran out of entries... */
  1046.       for (i = 2 ; i <= 12 ; i++)
  1047.      {
  1048.      if (buf[i] != entry[i])
  1049.         break ;
  1050.      }
  1051.       if (i > bestcount)
  1052.      {
  1053.      bestcount = i ;
  1054.      bestmatch = point ;
  1055.      if (i > 12)
  1056.         break ;            /* found an exact match */
  1057.      }
  1058.       nl_forward() ;
  1059.       }
  1060.    if (bestmatch == -1)
  1061.       return 0 ;            /* we failed */
  1062.    else
  1063.       {
  1064.       *first_entry = bestmatch ;
  1065.       point = bestmatch ;        /* back to best-matching entry */
  1066.       nl_forward() ;
  1067.       return 1 ;            /* we were successful */
  1068.       }
  1069. }
  1070.  
  1071. /*=============================================================*/
  1072. /*=============================================================*/
  1073.  
  1074. int goto_entry(entry_name)
  1075. char *entry_name ;
  1076. {
  1077.    char int_id[13], extra_string[60] ;
  1078.    int start = point, first_entry ;
  1079.    int int_num, curr_int ;
  1080.    char search_str[22] ;
  1081.    
  1082.    parse_int_name(entry_name,int_id,extra_string) ;
  1083.    int_num = hex2_to_int(int_id[0],int_id[1]) ;
  1084.    if (to_separator_line(-1))
  1085.       {
  1086.       if (character(point+11) == '-')
  1087.      curr_int = -1 ;
  1088.       else
  1089.      curr_int = hex2_to_int(character(point+11),character(point+12)) ;
  1090.       if (int_num <= 0)
  1091.      point = 0 ;        /* go to top of file */
  1092.       else
  1093.      {
  1094.      if (curr_int <= 0)
  1095.         point = 0 ;        /* go to top of file */
  1096.      strcpy(search_str,"--------.-") ;
  1097.      search_str[10] = hex_digit((int_num-1) / 16) ;
  1098.      search_str[11] = hex_digit((int_num-1) % 16) ;
  1099.      search_str[12] = '\0' ;
  1100.      if (!re_search( (int_num<=curr_int)?-1:1, search_str))
  1101.         {
  1102.         say("%s not found.",entry_name) ;
  1103.         iter = 1 ;
  1104.         return 0 ;
  1105.         }
  1106.      to_begin_line() ;
  1107.      }
  1108.       }
  1109.    else
  1110.       point = 0 ;
  1111.    if (!scan_for_entry(int_id,extra_string,&first_entry))
  1112.       {
  1113.       say("%s not found.",entry_name) ;
  1114.       if (first_entry)
  1115.      {
  1116.      mark = start ;
  1117.      point = first_entry ;
  1118.      }
  1119.       else
  1120.      point = start ;
  1121.       }
  1122.    if (has_arg)
  1123.      iter = 1 ;                /* don't search repeatedly */
  1124.    return 0 ;
  1125. }
  1126.  
  1127. /*=============================================================*/
  1128. /*=============================================================*/
  1129.  
  1130. command goto_int() on intlist_tab[FCTRL(12)]
  1131. {
  1132.    char entry_name[60], def_entry[60] ;
  1133.    int start = point ;
  1134.  
  1135.    to_begin_line() ;
  1136.    if (parse_string(1,"SeeAlso: ",NULL) != 0)
  1137.       {
  1138.       point += 9 ;        /* skip the SeeAlso: */
  1139.       if (point < start)    /* if we were originally to the right of     */
  1140.      point = start ;    /* current position, go back to original pos */
  1141.       grab_int_reference(def_entry) ;
  1142.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  1143.       }
  1144.    else if (line_has_see_also())
  1145.       {
  1146.       grab_int_reference(def_entry) ;
  1147.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  1148.       }
  1149.    else
  1150.       get_string(entry_name,"Goto Interrupt: ") ;
  1151.    point = start ;
  1152.    goto_entry(entry_name) ;
  1153.    if (has_arg)
  1154.       iter = 1 ;
  1155. }
  1156.  
  1157. /*=============================================================*/
  1158. /*=============================================================*/
  1159.  
  1160. void maybe_append_table_number()
  1161. {
  1162.    if (parse_string(1,".*\t%(Table ",0) == 0)
  1163.       {
  1164.       int matchsize ;
  1165.       /* if the pattern didn't match, there is no table number, */
  1166.       /* so add it */
  1167.       to_end_line() ;
  1168.       matchsize = parse_string(-1,"[ \t]+",0) ;
  1169.       if (matchsize)
  1170.      delete(point-matchsize,point) ;
  1171.       stuff("\t") ;
  1172.       insert_table_counter() ;
  1173.       }
  1174. }
  1175.  
  1176. /*=============================================================*/
  1177. /*=============================================================*/
  1178.  
  1179. void fix_unnumbered_tables()
  1180. {
  1181.    spot start = alloc_spot(1) ;
  1182.    
  1183.    *start = point ;
  1184.    point = 0 ;
  1185.    while (search(1,"\n\n"))
  1186.       {
  1187.       switch(curchar())
  1188.      {
  1189.      case 'C':
  1190.         if (parse_string(1,"Call ") != 0)
  1191.            {
  1192.            /* we got Call..., we know it doesn't have a table number */
  1193.            insert_table_counter() ;
  1194.            stuff("\n") ;
  1195.            }
  1196.         break ;
  1197.      case 'V':
  1198.         if (parse_string(1,"Values ") != 0)
  1199.            {
  1200.            /* we know this Values... doesn't have a table number */
  1201.            insert_table_counter() ;
  1202.            stuff("\n") ;
  1203.            }
  1204.         break ;
  1205.      case 'B':
  1206.         if (parse_string(1,"Bitfields ",0) == 0)
  1207.            break ;
  1208.         nl_forward() ;    /* skip to start of next line */
  1209.         maybe_append_table_number() ;
  1210.         break ;
  1211.      case 'F':
  1212.         if (parse_string(1,"Format ",0) == 0)
  1213.            break ;
  1214.         nl_forward() ;    /* skip to start of next line */
  1215.         maybe_append_table_number() ;
  1216.         break ;
  1217.      default:
  1218.         /* not a table header, so ignore it */
  1219.         break ;
  1220.      }
  1221.       }
  1222.    point = *start ;
  1223.    free_spot(start) ;
  1224. }
  1225.  
  1226. /*=============================================================*/
  1227. /*=============================================================*/
  1228.  
  1229. short *gather_table_numbers(new_numbers)
  1230. short *new_numbers ;
  1231. {
  1232.    int tcount[6] ;
  1233.    char counter[5] ;
  1234.    int old_number ;
  1235.    int table_type ;
  1236.    spot start = alloc_spot(1) ;
  1237.    save_var case_fold = 0 ;
  1238.    
  1239.    tcount[0] = tcount[1] = tcount[2] = tcount[3] = tcount[4] = tcount[5] = 0 ;
  1240.    *start = point ;
  1241.    point = 0 ;
  1242.    while (search(1,"(Table "))
  1243.       {
  1244.       char *tbl ;
  1245.       int table_offset ;
  1246.       grab(point,point+4,counter) ;
  1247.       tbl = index(table_ID_letters,counter[0]) ;
  1248.       if (tbl)
  1249.      table_offset = (tbl-table_ID_letters) ;
  1250.       else
  1251.      table_offset = 0 ;
  1252.       old_number = strtoi(counter+1,10) + 1000*table_offset ;
  1253.       table_type = (table_offset > 9) ? (table_offset-9) : 0 ;
  1254.       new_numbers[old_number] = (short)++(tcount[table_type]) ;
  1255.       }
  1256.    point = *start ;
  1257.    free_spot(start) ;
  1258.    return new_numbers ;
  1259. }
  1260.  
  1261. /*=============================================================*/
  1262. /*=============================================================*/
  1263.  
  1264. int adjust_table_numbers(new_numbers, dangling)
  1265. short *new_numbers ;
  1266. int dangling ;
  1267. {
  1268.    char counter[5] ;
  1269.    int old_number ;
  1270.    int old_type ;
  1271.    char *tbl ;
  1272.    int table_offset ;
  1273.    spot start = alloc_spot(1) ;
  1274.    
  1275.    *start = point ;
  1276.    point = 0 ;
  1277.    while (search(1,"(Table "))
  1278.       {
  1279.       grab(point,point+4,counter) ;
  1280.       tbl = index(table_ID_letters,counter[0]) ;
  1281.       if (tbl)
  1282.      table_offset = 1000*(tbl-table_ID_letters) ;
  1283.       else
  1284.      table_offset = 0 ;
  1285.       old_number = strtoi(counter+1,10) + table_offset ;
  1286.       old_type = (counter[0] >= '0' && counter[0] <= '9') ? 0 : counter[0] ;
  1287.       if (old_number > 0)
  1288.      {
  1289.      delete(point,point+4) ;
  1290.      if (old_type)
  1291.         bprintf("%c%03d",old_type,new_numbers[old_number]%1000) ;
  1292.      else
  1293.         bprintf("%04d",new_numbers[old_number]) ;
  1294.      }
  1295.       }
  1296.    point = 0 ;
  1297.    while (re_search(1,"[, \t]%#[0-9CFMPR][0-9][0-9][0-9]"))
  1298.       {
  1299.       grab(point-4,point,counter) ;
  1300.       tbl = index(table_ID_letters,counter[0]) ;
  1301.       if (tbl)
  1302.      table_offset = 1000*(tbl-table_ID_letters) ;
  1303.       else
  1304.      table_offset = 0 ;
  1305.       old_number = strtoi(counter+1,10) + table_offset ;
  1306.       old_type = (counter[0] >= '0' && counter[0] <= '9') ? 0 : counter[0] ;
  1307.       if (old_number > 0)
  1308.      {
  1309.      if (new_numbers[old_number])
  1310.         {
  1311.         delete(point-4,point) ;
  1312.         if (old_type)
  1313.            bprintf("%c%03d",old_type,new_numbers[old_number]) ;
  1314.         else
  1315.            bprintf("%04d",new_numbers[old_number]) ;
  1316.         }
  1317.      else /* dangling xref */
  1318.         {
  1319.         dangling++ ;
  1320.         point -= 4 ;
  1321.         stuff("?") ;
  1322.         point += 4 ;
  1323.         }
  1324.      }
  1325.       }
  1326.    point = *start ;
  1327.    free_spot(start) ;
  1328.    return dangling ;
  1329. }
  1330.  
  1331. /*=============================================================*/
  1332. /*=============================================================*/
  1333.  
  1334. int get_list_file(list_file)
  1335. char *list_file ;
  1336. {
  1337.    char abs_filename[FNAMELEN] ;
  1338.    strcpy(abs_filename,list_file) ;
  1339.    absolute(abs_filename) ;
  1340.    return find_it(abs_filename,1) ;
  1341. }
  1342.  
  1343. /*=============================================================*/
  1344. /*=============================================================*/
  1345.  
  1346. command renumber_tables()
  1347. {
  1348.    short *new_numbers ;
  1349.    int num_tables ;
  1350.    int dangling ;
  1351.    int i ;
  1352.    
  1353.    for (i = 0 ; list_files[i] ; i++)
  1354.       {
  1355.       if (get_list_file(list_files[i]) == 0)
  1356.      {
  1357.      say("Renumber Pass 1: numbering unnumbered tables (%s)",
  1358.          list_files[i]) ;
  1359.      fix_unnumbered_tables() ;
  1360.      }
  1361.       else
  1362.      say("Renumber Pass 1: forced to skip %s") ;
  1363.       }
  1364.    num_tables = 1000*strlen(table_ID_letters) ;
  1365.    new_numbers = (short*)malloc(num_tables*sizeof(short)) ;
  1366.    if (!new_numbers)
  1367.       {
  1368.       say("Out of memory!") ;
  1369.       return ;
  1370.       }
  1371.    for (i = 0 ; i < num_tables ; i++)
  1372.       new_numbers[i] = 0 ;
  1373.    for (i = 0 ; list_files[i] ; i++)
  1374.       {
  1375.       if (get_list_file(list_files[i]) == 0)
  1376.      {
  1377.      say("Renumber Pass 2: gathering table numbers (%s)",
  1378.          list_files[i]) ;
  1379.      gather_table_numbers(new_numbers) ;
  1380.      }
  1381.       else
  1382.      say("Renumber Pass 2: forced to skip %s") ;
  1383.       }
  1384.    dangling = 0 ;
  1385.    for (i = 0 ; list_files[i] ; i++)
  1386.       {
  1387.       if (get_list_file(list_files[i]) == 0)
  1388.      {
  1389.      say("Renumber Pass 3: adjusting table numbers (%s)",
  1390.          list_files[i]) ;
  1391.      dangling = adjust_table_numbers(new_numbers,dangling) ;
  1392.      }
  1393.       else
  1394.      say("Renumber Pass 3: forced to skip %s") ;
  1395.       }
  1396.    free(new_numbers) ;
  1397.    if (dangling)
  1398.       say("%d dangling cross-references, search for '#?'",dangling) ;
  1399.    else
  1400.       say("Done") ;
  1401. }
  1402.  
  1403. /*=============================================================*/
  1404. /*=============================================================*/
  1405.  
  1406. command make_distribution()
  1407. {
  1408.    int i ;
  1409.    
  1410.    for (i = 0 ; list_files[i] ; i++)
  1411.       {
  1412.       /* switch to proper buffer, or load if not yet in a buffer */
  1413.       if (get_list_file(list_files[i]) == 0)
  1414.      {
  1415.      say("Setting divider lines (%s)",list_files[i]) ;
  1416.      point = size() ;
  1417.      while (point > 0)
  1418.         if (!number_one_int())
  1419.            break ;
  1420.      }
  1421.       else
  1422.      say("Forced to skip %s !",list_files[i]) ;
  1423.       }
  1424.    for (i = 0 ; list_files[i] ; i++)
  1425.       {
  1426.       /* switch to proper buffer, or load if not yet in a buffer */
  1427.       if (get_list_file(list_files[i]) == 0)
  1428.      {
  1429.      say("Tabifying file (%s)",list_files[i]) ;
  1430.      mark = 0 ;
  1431.      point = size() ;
  1432.      tabify_region() ;
  1433.      }
  1434.       }
  1435.    renumber_tables() ;
  1436.    save_all_buffers() ;
  1437.    say("Ready for distribution") ;
  1438.    point = 0 ;
  1439.    /* !!! should also split main list automatically */
  1440. }
  1441.  
  1442. /*=============================================================*/
  1443. /*=============================================================*/
  1444.  
  1445. void find_table_counter()
  1446. {
  1447.    save_var point = (size() > 10000) ? size() - 10000 : 0 ;
  1448.  
  1449.    search(1,"Highest Table Number = ") ;
  1450.    table_counter = alloc_spot(1) ;
  1451. }
  1452.  
  1453. /*=============================================================*/
  1454. /*=============================================================*/
  1455.  
  1456. char filter_cmd[128] = "" ;
  1457.  
  1458. command filter_region()
  1459. {
  1460.    char new_filter_cmd[128] ;
  1461.    get_strdef(new_filter_cmd,"Filter region through",filter_cmd) ;
  1462.    strcpy(filter_cmd,new_filter_cmd) ;
  1463.    if (filter_cmd[0] != 0)
  1464.       {
  1465.       int size ;
  1466.       int fd ;
  1467.       char *commandline ;
  1468.       char *argptr ;
  1469.       int numargs = 0 ;
  1470.       char filename[128] ;
  1471.       char outputfile[128] ;
  1472.       int start = point ;
  1473.       int end = mark ;
  1474.       if (end < start)
  1475.      {
  1476.      start = mark ;
  1477.      end = point ;
  1478.      }
  1479.       size = end - start ;
  1480.       make_temp_file(filename,3*size) ;
  1481.       /* Eps7.0 always generates same temp file!  Thus, we have to manually */
  1482.       /* generate a second file name for use as the output file */
  1483.       strcpy(outputfile,filename) ;
  1484.       strcat(outputfile,"_2") ;
  1485.       delete_file(filename) ;
  1486.       if (write_part(filename,strip_returns,start,end) != 0)
  1487.      {
  1488.      delete_file(filename) ;
  1489.      return ;
  1490.      }
  1491.       fd = lowopen(outputfile,3) ;
  1492.       if (fd != -1)
  1493.      lowclose(fd) ;
  1494.       /* execute the command on the temporary file */
  1495.       commandline = malloc(strlen(filter_cmd)+strlen(filename)+strlen(outputfile)+6) ;
  1496.       if (!commandline)
  1497.      {
  1498.      say("out of memory....") ;
  1499.      delete_file(filename) ;
  1500.      return ;
  1501.      }
  1502.       argptr = strstr(filter_cmd,"%s") ;
  1503.       if (argptr)
  1504.      {
  1505.      numargs++ ;
  1506.      argptr = strstr(argptr+1,"%s") ;
  1507.      if (argptr)
  1508.         numargs++ ;
  1509.      }
  1510.       switch (numargs)
  1511.      {
  1512.      case 0:
  1513.         sprintf(commandline,"%s <%s >%s",filter_cmd,filename,outputfile) ;
  1514.         break ;
  1515.      case 1:
  1516.         sprintf(commandline,filter_cmd,filename) ;
  1517.         strcat(commandline," >") ;
  1518.         strcat(commandline,outputfile) ;
  1519.         break ;
  1520.      case 2:
  1521.         sprintf(commandline,filter_cmd,filename,outputfile) ;
  1522.         break ;
  1523.      }
  1524.       shell("",commandline,"") ;
  1525.       free(commandline) ;
  1526.       delete_file(filename) ;
  1527.       /* read back the result of the filtering */
  1528.       kill_region() ;
  1529.       if (do_insert_file(outputfile,strip_returns) != 0)
  1530.      {
  1531.      kill_region() ;     /* remove any partially-read data */
  1532.      yank() ;        /* restore region to pre-filter state */
  1533.      }
  1534.       delete_file(outputfile) ;
  1535.       }
  1536. }
  1537.  
  1538. /*=============================================================*/
  1539. /*  Coloring functions for Epsilon v7.0+               */
  1540. /*=============================================================*/
  1541.  
  1542. #if EELVERSION >= 70
  1543. int int_recolor_range(from, to)
  1544. int from, to ;
  1545. {
  1546.    if (from >= to)
  1547.       return to ;
  1548.    set_character_color(from,to,-1) ;
  1549.    save_var point, matchstart, matchend ;
  1550.    point = from ;
  1551.    if (to > size())
  1552.       to = size() ;
  1553.    while (point < to)
  1554.       {
  1555.       int start = point ;
  1556.       int len ;
  1557.       char c = curchar() ;
  1558.       if (c >= 'A' && c <= 'V')
  1559.      {
  1560.      if (parse_string(1,table_headers,NULL) != 0)
  1561.         {
  1562.         nl_forward() ;
  1563.         point-- ;
  1564.         set_character_color(start,point,color_class c_comment) ;
  1565.         }
  1566.      else if ((len = parse_string(1,all_sections,NULL)) > 0)
  1567.         set_character_color(start,start+len,color_class c_function) ;
  1568.      }
  1569.       else if (c == '\t' &&
  1570.            (len = parse_string(1,indented_sections,NULL)) != 0)
  1571.      {
  1572.      while (curchar() == '\t')
  1573.         {
  1574.         point++ ;
  1575.         len-- ;
  1576.         }
  1577.      set_character_color(point,point+len,color_class c_function) ;
  1578.      }
  1579.       nl_forward() ;
  1580.       }
  1581.    return point ;
  1582. }
  1583. #endif /* Epsilon v7.0+ */
  1584.  
  1585. #if EELVERSION >= 70
  1586. int int_recolor_from_here(safe)
  1587. int safe ;
  1588. {
  1589.    save_var point ;
  1590.    if (safe != point)
  1591.       {
  1592.       to_begin_line() ;            /* start of line is always 'safe' */
  1593.       }
  1594.    return point ;
  1595. }
  1596. #endif /* Epsilon v7.0+ */
  1597.  
  1598. /*=============================================================*/
  1599. /* Put the current buffer into IntList major mode           */
  1600. /*=============================================================*/
  1601.  
  1602. command intlist_mode()
  1603. {
  1604.    mode_keys = intlist_tab ;
  1605.    intlist_tab[')'] = intlist_tab[']'] = (short) show_matching_delimiter;
  1606.    delete_hacking_tabs = 0 ;
  1607.    major_mode = strsave("IntList") ;
  1608.    auto_indent = 0 ;
  1609.    margin_right = 79 ;
  1610.    want_backups = 1 ;
  1611.    undo_size = 200000 ;     /* less than default 500,000 since list is so big */
  1612.    find_table_counter() ;
  1613. #if EELVERSION >= 70
  1614.    recolor_range = int_recolor_range ;
  1615.    recolor_from_here = int_recolor_from_here ;
  1616.    if (want_code_coloring)
  1617.       when_setting_want_code_coloring() ;
  1618. #endif /* Epsilon v7.0+ */
  1619.    make_mode() ;
  1620. }
  1621.  
  1622. when_loading()
  1623. {
  1624.    char *curbuf ;
  1625.    int i ;
  1626.    
  1627.    want_backups = want_backups.default = 1 ;
  1628.    strcpy(backup_name,"%pbak/%b%e") ;        /* put backups in BAK subdir */
  1629.    one_window() ;
  1630.    intlist_mode() ;
  1631.    if (exist("interrup.1st"))
  1632.       {
  1633.       curbuf = bufname ;
  1634.       bufname = "interrup.1st" ;
  1635.       intlist_mode() ;
  1636.       want_code_coloring = 0 ;
  1637.       when_setting_want_code_coloring() ;
  1638.       bufname = curbuf ;
  1639.       }
  1640.    for (i = 0 ; list_files[i] ; i++)
  1641.       {
  1642.       if (exist(list_files[i]))
  1643.      {
  1644.      curbuf = bufname ;
  1645.      bufname = list_files[i] ;
  1646.      intlist_mode() ;
  1647.      bufname = curbuf ;
  1648.      }
  1649.       }
  1650. #if EELVERSION >= 70
  1651.    strcpy(mode_end," %d%p%S%>C%c") ;
  1652. #endif /* Epsilon v7.0+ */
  1653. #if EELVERSION >= 60 && EELVERSION < 70
  1654.    strcpy(mode_end," %d%p%S") ;
  1655. #endif /* Epsilon v6.x */
  1656. }
  1657.  
  1658. /*=============================================================*/
  1659. /* automagically switch into interrupt list mode on .LST and .1ST files */
  1660.  
  1661. suffix_lst()   { intlist_mode(); }
  1662. suffix_1st()   { intlist_mode(); }
  1663.  
  1664. /* end of file intlist.e */
  1665.