home *** CD-ROM | disk | FTP | other *** search
/ Power CD-ROM!! 7 / POWERCD7.ISO / prgmming / inter43 / intlist.e < prev    next >
Text File  |  1994-07-23  |  33KB  |  1,151 lines

  1. /****************************************************************/
  2. /*    EEL code file for editing the Interrupt List        */
  3. /*                                */
  4. /*    Written by Ralf Brown                    */
  5. /*    LastEdit: 7 May 94                    */
  6. /*                                */
  7. /*  This EEL file adds the following keybindings:        */
  8. /*    Shf-Alt-B add another BUG: to the current entry           */
  9. /*    Shf-Alt-D add a Desc: section to the current entry    */
  10. /*    Shf-Alt-R add a Range: section to the current entry       */
  11. /*    Alt-I    add an Index: section to the current entry    */
  12. /*        add another Index: line if already on Index:    */
  13. /*      Alt-N   add a new note to current entry or data struct  */
  14. /*      Alt-P   add a Program: section to the current entry     */
  15. /*      Alt-R   insert Return: at start of line                 */
  16. /*    Alt-S    insert SeeAlso: at start of line        */
  17. /*    F11    insert a blank separator line            */
  18. /*    ^F11    create Format of: header            */
  19. /*    Shf-F11    create Values for: header            */
  20. /*    Alt-F11 create Call with: header            */
  21. /*    Alt-F12 create Bitfield for: header            */
  22. /*    F12    add the interrupt number to the separator line    */
  23. /*        preceding the current entry            */
  24. /*    ^F12    jump to a specified entry            */
  25. /*                                */
  26. /*  It adds the following unbound commands:                */
  27. /*      renumber-tables                            */
  28. /*                                */
  29. /*  Other:                            */
  30. /*    adds intlist-mode for .LST and .1ST files        */
  31. /*    switches current buffer into intlist-mode on loading    */
  32. /*      maintains a table counter which is inserted each time   */
  33. /*        a table is created in the text                */
  34. /****************************************************************/
  35.  
  36. #include "eel.h"
  37.  
  38. keytable intlist_tab ;            /* key table for IntList mode */
  39.  
  40. /* on repeated F12, how often to display number of entries processed */
  41. /* for fast 386, every 100; for a Pentium, at least 300 or the message */
  42. /* line will lag way behind the actual progress */
  43. #define NUMBER_INT_PROGRESS_INTERVAL 500
  44.  
  45. /*=============================================================*/
  46. /*    Global Variables                           */
  47. /*=============================================================*/
  48.  
  49. char return_section[] = "Return: " ;
  50. char program_section[] = "Program: " ;
  51. char desc_section[] = "Desc:\t" ;
  52. char range_section[] = "Range:\t" ;
  53. char notes_section[] = "Notes*:\t" ;
  54. char bugs_section[] = "BUGS*:\t" ;
  55. char seealso_section[] = "SeeAlso: " ;
  56. char index_section[] = "Index:\t" ;
  57.  
  58. char *(section_order[9]) ;
  59.  
  60. when_loading()
  61. {
  62.    /* list the sections of an entry in the order they should appear (if */
  63.    /* present at all) */
  64.    section_order[0] = return_section ;
  65.    section_order[1] = program_section ;
  66.    section_order[2] = desc_section ;
  67.    section_order[3] = range_section ;
  68.    section_order[4] = notes_section ;
  69.    section_order[5] = bugs_section ;
  70.    section_order[6] = seealso_section ;
  71.    section_order[7] = index_section ;
  72.    section_order[8] = NULL ;
  73. }
  74.  
  75. /*=============================================================*/
  76. /*    Buffer-specific variables                       */
  77. /*=============================================================*/
  78.  
  79. buffer spot table_counter ;
  80.  
  81. /*=============================================================*/
  82. /*=============================================================*/
  83.  
  84. int empty_line()
  85. {
  86.    return (character(point-1) == '\n' && character(point) == '\n') ;
  87. }
  88.  
  89. /*=============================================================*/
  90. /*=============================================================*/
  91.  
  92. int is_separator_line()
  93. {
  94.    return (empty_line() || parse_string(1,"--------",NULL)) ;
  95. }
  96.  
  97. /*=============================================================*/
  98. /* search in the specified direction (1 = forward, -1 = back)  */
  99. /* for the next entry separator line                   */
  100. /*=============================================================*/
  101.  
  102. int to_separator_line(dir)
  103. int dir ;
  104. {
  105.    nl_reverse() ;
  106.    return search(dir,"\n--------") ;
  107. }
  108.  
  109. /*=============================================================*/
  110. /* move to the location where the specified section of an      */
  111. /* entry begins (if present) or should begin (if not)           */
  112. /*=============================================================*/
  113.  
  114. int to_section_start(section)
  115. char *section ;
  116. {
  117.    int i, j, len ;
  118.  
  119.    for (i = 0 ; section_order[i] ; i++)
  120.       if (strcmp(section,section_order[i]) == 0)
  121.      break ;
  122.    if (section_order[i])
  123.       {
  124.       while (!is_separator_line())
  125.      {
  126.      for (j = i ; section_order[j] ; j++)
  127.         if (parse_string(1,section_order[j],NULL))
  128.            {
  129.            if ((len = parse_string(1,section,NULL)) != 0)
  130.           {
  131.           point += len ;
  132.           return 1 ;    /* section already exists */
  133.           }
  134.            return 0 ;    /* section nonexistent, but found position */
  135.            }
  136.      if (!nl_forward())
  137.         break ;
  138.      }
  139.       return 0 ;    /* section does not yet exist */
  140.       }
  141.    else
  142.       return 0 ;    /* section not found */
  143. }
  144.  
  145. /*=============================================================*/
  146. /*=============================================================*/
  147.  
  148. int make_section(section,start_entry,name)
  149. char *section, *name ;
  150. int start_entry ;
  151. {
  152.    int start = point ;
  153.  
  154.    if (start_entry)
  155.       {
  156.       if (!to_separator_line(-1))  /* find previous separator line */
  157.      {
  158.      point = start ;
  159.      say("Not in an interrupt entry") ;
  160.      return 0 ;
  161.      }
  162.       }
  163.    else
  164.       {
  165.       to_begin_line() ;
  166.       while (!empty_line() && !parse_string(1,"\n--------",NULL))
  167.      if (!nl_reverse())
  168.         break ;
  169.       }
  170.    point++ ;                 /* skip the newline */
  171.    nl_forward() ;             /* advance to first line of entry */
  172.    if (!to_section_start(section))
  173.       {
  174.       if (name)
  175.      stuff(name) ;
  176.       else
  177.      stuff(section) ;
  178.       stuff("\n") ;
  179.       point-- ;              /* back up over inserted newline */
  180.       return 1 ;
  181.       }
  182.    else
  183.       return 0 ;
  184.    return 2 ;  /* just in case */
  185. }
  186.  
  187. /*=============================================================*/
  188. /*=============================================================*/
  189.  
  190. int pluralize_section(plural)
  191. char plural ;
  192. {
  193.    point -= 3 ;
  194.    if (curchar() != plural)        /* already plural ? */
  195.       {
  196.       point++ ;
  197.       insert(plural) ;
  198.       }
  199.    nl_forward() ;
  200.    while (!is_separator_line() && parse_string(1,"[ \t]",NULL))
  201.       nl_forward() ;
  202.    stuff("\t\n") ;
  203.    point-- ;
  204. }
  205.  
  206. /*=============================================================*/
  207. /* Add "SeeAlso: " to the beginning of the current line unless */
  208. /* it is already present                       */
  209. /*=============================================================*/
  210.  
  211. command see_also() on intlist_tab[ALT('s')]
  212. {
  213.    to_begin_line() ;
  214.    if (parse_string(1,"SeeAlso: ",NULL) == 0)
  215.       stuff("SeeAlso: ") ;
  216.    else
  217.       {
  218.       nl_forward() ;
  219.       stuff("SeeAlso: \n") ;
  220.       point-- ;
  221.       }
  222. }
  223.  
  224. /*=============================================================*/
  225. /* Add a Desc: section if the current entry does not already   */
  226. /* have one; if there is already a Desc: section, move to the  */
  227. /* start of it                               */
  228. /*=============================================================*/
  229.  
  230. command desc() on intlist_tab[ALT('D')]
  231. {
  232.    make_section(desc_section,1,NULL) ;
  233. }
  234.  
  235. /*=============================================================*/
  236. /* Add a Range: section if the current entry does not already  */
  237. /* have one; if there is already a Range: section, move to the */
  238. /* start of it                               */
  239. /*=============================================================*/
  240.  
  241. command range() on intlist_tab[ALT('R')]
  242. {
  243.    make_section(range_section,1,NULL) ;
  244. }
  245.  
  246. /*=============================================================*/
  247. /* Add a "Program: " section to the current entry if it does   */
  248. /* not have one; otherwise, move to the beginning of the       */
  249. /* Program: section                           */
  250. /*=============================================================*/
  251.  
  252. command program() on intlist_tab[ALT('p')]
  253. {
  254.    make_section(program_section,1,NULL) ;
  255. }
  256.  
  257. /*=============================================================*/
  258. /* Add an "Index: " section to the current entry if it does    */
  259. /* not have one; otherwise, move to the beginning of the       */
  260. /* Index: section                           */
  261. /*=============================================================*/
  262.  
  263. command add_index() on intlist_tab[ALT('i')]
  264. {
  265.    to_begin_line() ;
  266.    if (parse_string(1,"Index:",NULL))
  267.       {
  268.       while (parse_string(1,"Index:",NULL))
  269.      nl_forward() ;
  270.       stuff("Index:\t\n") ;
  271.       point-- ;
  272.       }
  273.    else
  274.       make_section(index_section,1,NULL) ;
  275. }
  276.  
  277. /*=============================================================*/
  278. /*=============================================================*/
  279.  
  280. command bug() on intlist_tab[ALT('B')]
  281. {
  282.    if (!make_section(bugs_section,1,"BUG:\t"))
  283.       pluralize_section('S') ;
  284. }
  285.  
  286. /*=============================================================*/
  287. /* Add "Note: " section to the current entry; change an        */
  288. /* existing Note: to Notes: and position at end of Note:       */
  289. /* section.                               */
  290. /*=============================================================*/
  291.  
  292. command add_note() on intlist_tab[ALT('n')]
  293. {
  294.    if (!make_section(notes_section,0,"Note:\t"))
  295.       pluralize_section('s') ;
  296. }
  297.  
  298. /*=============================================================*/
  299. /* Insert "Return: " at the beginning of the current line, if  */
  300. /* not already present                           */
  301. /*=============================================================*/
  302.  
  303. command returns() on intlist_tab[ALT('r')]
  304. {
  305.    int start = point ;
  306.    
  307.    to_begin_line() ;
  308.    if (parse_string(1,return_section,NULL) == 0)
  309.       stuff(return_section) ;
  310.    else
  311.       point = start ;
  312. }
  313.  
  314. /*=============================================================*/
  315. /* insert a line of dashes prior to the current cursor line    */
  316. /*=============================================================*/
  317.  
  318. command separator_line() on intlist_tab[FKEY(11)]
  319. {
  320.    int i ;
  321.  
  322.    to_begin_line() ;
  323.    for (i = 0 ; i < 45 ; i++)
  324.       insert('-') ;
  325.    insert('\n') ;
  326. }
  327.  
  328. /*=============================================================*/
  329. /*=============================================================*/
  330.  
  331. void insert_table_counter()
  332. {
  333.    char counter[6] ;
  334.    save_var point = *table_counter + 3 ;
  335.  
  336.    /* increment that table counter */
  337.    while (curchar() >= '0')
  338.       {
  339.       if (curchar() < '9')
  340.      {
  341.      replace(point,curchar()+1) ;
  342.      break ;
  343.      }
  344.       else
  345.      {
  346.      replace(point,'0') ;
  347.      point-- ;
  348.      }
  349.       }
  350.    restore_vars() ;
  351.    /* and now insert the incremented value at point */
  352.    stuff("(Table ") ;
  353.    grab(*table_counter,*table_counter+4,counter) ;
  354.    stuff(counter) ;
  355.    stuff(")") ;
  356. }
  357.  
  358. /*=============================================================*/
  359. /* type the name of a structure, then invoke this function     */
  360. /* to create the "Format of X:" and "Offset Size Descr" lines  */
  361. /*=============================================================*/
  362.  
  363. command structure_header() on intlist_tab[FCTRL(11)]
  364. {
  365.    int start = point ;
  366.  
  367.    to_begin_line() ;
  368.    if (parse_string(1,"Format of ",NULL) == 0)
  369.       {
  370.       stuff("Format of ") ;
  371.       to_end_line() ;
  372.       stuff(":\nOffset\tSize\tDescription\t") ;
  373.       insert_table_counter() ;
  374.       stuff("\n 00h\t") ;
  375.       }
  376.    else
  377.       point = start ;
  378. }
  379.  
  380. /*=============================================================*/
  381. /* Turn the current line into the header for a "Values of"     */
  382. /* section                               */
  383. /*=============================================================*/
  384.  
  385. command value_header() on intlist_tab[FSHIFT(11)]
  386. {
  387.    int start = point ;
  388.    
  389.    to_begin_line() ;
  390.    if (parse_string(1,"Values for ",NULL) == 0)
  391.       {
  392.       insert_table_counter() ;
  393.       stuff("\nValues for ") ;
  394.       to_end_line() ;
  395.       stuff(":\n ") ;
  396.       }
  397.    else
  398.       point = start ;
  399. }
  400.  
  401. /*=============================================================*/
  402. /* Turn the current line into the header of a "Call with"      */
  403. /* section                               */
  404. /*=============================================================*/
  405.  
  406. command call_with_header() on intlist_tab[FALT(11)]
  407. {
  408.    int start = point ;
  409.    
  410.    to_begin_line() ;
  411.    if (parse_string(1,"Call ",NULL) == 0)
  412.       {
  413.       insert_table_counter() ;
  414.       stuff("\nCall ") ;
  415.       to_end_line() ;
  416.       if (character(point-1) != ' ')
  417.      stuff(" ") ;
  418.       stuff("with:\n") ;
  419.       }
  420.    else
  421.       point = start ;
  422. }
  423.  
  424. /*=============================================================*/
  425. /* Turn the current line into the header of a "Bitfield for"   */
  426. /* section                               */
  427. /*=============================================================*/
  428.  
  429. command bitfields_for_header() on intlist_tab[FALT(12)]
  430. {
  431.    int start = point ;
  432.    
  433.    to_begin_line() ;
  434.    if (parse_string(1,"Bitfields for ",NULL) == 0)
  435.       {
  436.       stuff("Bitfields for ") ;
  437.       to_end_line() ;
  438.       stuff(":\nBit(s)\tDescription\t") ;
  439.       insert_table_counter() ;
  440.       stuff("\n ") ;
  441.       }
  442.    else
  443.       point = start ;
  444. }
  445.  
  446. /*=============================================================*/
  447. /*=============================================================*/
  448.  
  449. char grab_entry_number(func_num)
  450. char *func_num ;
  451. {
  452.    char c ;
  453.    int i ;
  454.  
  455.    strcpy(func_num,"------------") ;    /* 12 dashes */
  456.    point++ ;                /* go to first char of separator line */
  457.    nl_forward() ;            /* go to first line of entry */
  458.    if (parse_string(1,"INT ",NULL) == 0)
  459.       return 0 ;            /* not an interrupt entry, so return */
  460.    point += 4 ;                /* skip the "INT " */
  461.    func_num[0] = curchar() ;        /* grab the interrupt number */
  462.    point++ ;
  463.    func_num[1] = curchar() ;
  464.    nl_forward() ;            /* skip to second line of entry */
  465.    if (parse_string(1,"[ \t]*A[LHX][ \t]=[ \t][0-9A-F][0-9A-F]+h",NULL))
  466.       {
  467.       re_search(1,"[ \t]*A") ;
  468.       c = curchar() ;
  469.       point += 4 ;            /* skip ch and " = " */
  470.       if (c != 'L')
  471.      {
  472.      grab(point,point+((c=='X')?4:2),func_num+2) ;
  473.      point += ((c=='X')?4:2) ;
  474.      func_num[(c=='H')?4:6] = '-' ;    /* grab() stuck a NUL into the string */
  475.      }
  476.       else /* c == 'L' */
  477.      {
  478.      func_num[4] = curchar() ;
  479.      point++ ;
  480.      func_num[5] = curchar() ;
  481.      point ++ ;
  482.      }
  483.       point++ ;
  484.       if (parse_string(1,"[ \t]*subfn [0-9A-F][0-9A-F]+h",NULL))
  485.      {
  486.      re_search(1,"[ \t]*subfn ") ;
  487.      func_num[6] = 'S' ;
  488.      func_num[7] = 'F' ;
  489.      for (i = 0 ; i < 4 ; i++)
  490.         {
  491.         c = curchar() ;
  492.         if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
  493.            {
  494.            func_num[8+i] = c ;
  495.            point++ ;
  496.            }
  497.         else
  498.            break ;
  499.         }
  500.      }
  501.       nl_forward() ;            /* skip to third line of entry */
  502.       }
  503.    if (parse_string(1,"[ \t]*[BCDES][HILPSX] = [0-9A-F][0-9A-F]+h",NULL))
  504.       {
  505.       re_search(1,"[ \t]*") ;
  506.       func_num[6] = curchar() ;
  507.       point++ ;
  508.       func_num[7] = c = curchar() ;
  509.       point += 4 ;            /* skip curchar and " = " */
  510.       if (c == 'H' || c == 'L')
  511.      {
  512.      grab(point,point+2,func_num+8) ;
  513.      func_num[10] = '-' ;        /* grab() stuck a NUL into the string */
  514.      }
  515.       else /* c == 'X' || c == 'I' || c == 'P' || c == 'S' */
  516.      grab(point,point+4,func_num+8) ;
  517.       }
  518.    return 1 ;                /* successful and have func number */
  519. }
  520.  
  521. /*=============================================================*/
  522. /* Put the interrupt and function number into the separator    */
  523. /* line just above the intlist entry preceding the cursor pos  */
  524. /*=============================================================*/
  525.  
  526. int number_one_int()
  527. {
  528.    char func_num[13] ;            /* 2->int, 4->AX, 6->extra reg, NUL */
  529.    int oldpoint ;
  530.    
  531.    while (to_separator_line(-1))    /* find previous separator line */
  532.       {
  533.       oldpoint = point ;
  534.       if (grab_entry_number(func_num))    /* does it belong to an intlist entry? */
  535.      {                /*   if yes, success, else try again */
  536.      point = oldpoint + 11 ;    /* skip NL and first ten dashes */
  537.      delete(point,point+12) ;    /* replace 12 dashes by the function */
  538.      stuff(func_num) ;        /*   number and extra register */
  539.      point = oldpoint + 9 ;        /* back to category letter position */
  540.      return 1 ;
  541.      }
  542.       point = oldpoint ;
  543.       }
  544.    return 0 ;                /* if we get here, we failed */
  545. }
  546.  
  547. /*=============================================================*/
  548. /* Put the interrupt and function number into the separator    */
  549. /* line just above one or more intlist entries preceding the   */
  550. /* current cursor position, letting user know of progress      */
  551. /*=============================================================*/
  552.  
  553. command number_int() on intlist_tab[FKEY(12)]
  554. {
  555.    int i, hit_top = 0 ;
  556.    
  557.    for (i = 0 ; i < iter ; i++)
  558.       {
  559.       if (!number_one_int())
  560.      {
  561.      hit_top = 1 ;
  562.      say("No prior entry.") ;
  563.      break ;
  564.      }
  565.       if (((i+1) % NUMBER_INT_PROGRESS_INTERVAL) == 0)
  566.      say("%4d...",i+1) ;
  567.       }
  568.    if (iter > 1 && !hit_top)
  569.       say("Done.") ;
  570.    iter = 1 ;
  571. }
  572.  
  573. /*=============================================================*/
  574. /*=============================================================*/
  575.  
  576. int line_has_see_also()
  577. {
  578.    int len ;
  579.    
  580.    to_begin_line() ;
  581.    if ((len = parse_string(1,".*%([sS]ee ",NULL)) != 0)
  582.       {
  583.       point += len ;        /* go to start of cross-reference */
  584.       point += parse_string(1,"also ",NULL) ;
  585.       if (parse_string(1,"INT [0-9A-F]",NULL) ||
  586.       parse_string(1,"A[XHL] =",NULL)
  587.      )
  588.      {
  589.      point++ ;        /* move into reference */
  590.      return 1 ;
  591.      }
  592.       }
  593.    return 0 ;
  594. }
  595.  
  596. /*=============================================================*/
  597. /*=============================================================*/
  598.  
  599. int grab_int_reference(ref)
  600. char *ref ;
  601. {
  602.    int begin, start = point ;
  603.    
  604.    re_search(-1,"[, \t\n]") ;    /* backup to start of reference */
  605.    if (curchar() == '\n')    /* start of line? */
  606.       re_search(1,":[ \t]") ;    /* skip the SeeAlso: */
  607.    else if (character(point-1) == 'T' && character(point-2) == 'N')
  608.       point -= 3 ;
  609.    else
  610.       point++ ;            /* back to start of reference */
  611.    begin = point ;
  612.    re_search(1,"[,\n\"]") ;    /* find end of INT-spec */
  613.    point-- ;
  614.    if (curchar() == '\"')    /* extra string at end of INT-spec? */
  615.       {
  616.       point++ ;
  617.       re_search(1,"[\"\n]") ;    /* if yes, run to end of line or string */
  618.       }
  619.    grab(begin,point,ref) ;
  620.    point = start ;
  621.    return 0 ;
  622. }
  623.  
  624. /*=============================================================*/
  625. /*=============================================================*/
  626.  
  627. int parse_int_name(entry_name,id,extra_string)
  628. char *entry_name, *id, *extra_string ;
  629. {
  630.    int start = point ;
  631.    int i ;
  632.    char c, *last ;
  633.  
  634.    for (i = strlen(entry_name)-1 ; i >= 0 ; i--)
  635.       entry_name[i] = toupper(entry_name[i]) ;
  636.    strcpy(id,"------------") ;
  637.    if (strncmp(entry_name,"INT ",4) == 0)
  638.       {
  639.       id[0] = entry_name[4] ;
  640.       id[1] = entry_name[5] ;
  641.       entry_name += 6 ;
  642.       if (entry_name[0] == '/')
  643.      entry_name++ ;
  644.       }
  645.    else if (to_separator_line(-1))
  646.       {
  647.       id[0] = character(point+11) ;
  648.       id[1] = character(point+12) ;
  649.       }
  650.    point = start ;
  651.    c = entry_name[1] ;
  652.    if (entry_name[0] == 'A' && (c == 'X' || c == 'H' || c == 'L'))
  653.       {
  654.       entry_name += 2 ;
  655.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  656.      entry_name++ ;
  657.       if (entry_name[0] == '=')
  658.      entry_name++ ;
  659.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  660.      entry_name++ ;
  661.       if (c != 'L')
  662.      {
  663.          id[2] = entry_name[0] ;
  664.          id[3] = entry_name[1] ;
  665.      }
  666.       if (c == 'X')
  667.      {
  668.      id[4] = entry_name[2] ;
  669.      id[5] = entry_name[3] ;
  670.      entry_name += 4 ;
  671.      }
  672.       else
  673.      {
  674.      if (c == 'L')
  675.         {
  676.         id[2] = entry_name[0] ;
  677.         id[3] = entry_name[1] ;
  678.         }
  679.      entry_name += 2 ;
  680.      }
  681.       if (entry_name[0] == 'H')
  682.      entry_name++ ;
  683.       if (entry_name[0] == '/')
  684.      entry_name++ ;
  685.       }
  686.    if (index("ABCDES",entry_name[0]) && index("HILPSXF",entry_name[1]))
  687.       {
  688.       id[6] = entry_name[0] ;
  689.       c = id[7] = entry_name[1] ;
  690.       entry_name += 2 ;
  691.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  692.      entry_name++ ;
  693.       if (entry_name[0] == '=')
  694.      entry_name++ ;
  695.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  696.      entry_name++ ;
  697.       id[8] = entry_name[0] ;
  698.       id[9] = entry_name[1] ;
  699.       if (c != 'H' && c != 'L' && (c != 'F' || entry_name[2] != 'h'))
  700.      {
  701.      id[10] = entry_name[2] ;
  702.      id[11] = entry_name[3] ;
  703.      entry_name += 4 ;
  704.      }
  705.       else
  706.      entry_name += 2 ;
  707.       if (entry_name[0] == 'H')
  708.      entry_name++ ;
  709.       if (entry_name[0] == '/')
  710.      entry_name++ ;
  711.       }
  712.    if (entry_name[0] == '\"')
  713.       {
  714.       entry_name++ ;
  715.       strcpy(extra_string,entry_name) ;
  716.       last = index(extra_string,'\"') ;
  717.       if (last)
  718.      *last = '\0' ;
  719.       }
  720.    else
  721.       extra_string[0] = '\0' ;
  722.    return 0 ;
  723. }
  724.  
  725. /*=============================================================*/
  726. /*=============================================================*/
  727.  
  728. int hex2_to_int(c1,c2)
  729. char c1, c2 ;
  730. {
  731.    if (c1 >= '0' && c1 <= '9')
  732.       c1 -= '0' ;
  733.    else if (c1 >= 'A' && c1 <= 'F')
  734.       c1 = c1 - 'A' + 10 ;
  735.    else if (c1 >= 'a' && c1 <= 'f')
  736.       c1 = c1 - 'a' + 10 ;
  737.    else
  738.       return -1 ;
  739.    if (c2 >= '0' && c2 <= '9')
  740.       c2 -= '0' ;
  741.    else if (c2 >= 'A' && c2 <= 'F')
  742.       c2 = c2 - 'A' + 10 ;
  743.    else if (c2 >= 'a' && c2 <= 'f')
  744.       c2 = c2 - 'a' + 10 ;
  745.    else
  746.       return -1 ;
  747.    return 16*c1 + c2 ;
  748. }
  749.  
  750. /*=============================================================*/
  751. /*=============================================================*/
  752.  
  753. char hex_digit(val)
  754. int val ;
  755. {
  756.    if (val < 0)
  757.       return '-' ;
  758.    else
  759.       return (val > 9) ? ('A' + val - 10) : ('0' + val) ;
  760. }
  761.  
  762. /*=============================================================*/
  763. /*=============================================================*/
  764.  
  765. int scan_for_entry(entry,extra_str,first_entry)
  766. char *entry, *extra_str ;
  767. int *first_entry ;
  768. {
  769.    int ah, al, t1, t2, match, found ;
  770.    char buf[7] ;
  771.  
  772.    if (extra_str) extra_str = 0 ;  /* for now, to avoid compiler warning */
  773.    *first_entry = 0 ;
  774.    ah = hex2_to_int(entry[2],entry[3]) ;
  775.    while (1)
  776.       {
  777.       if (!to_separator_line(1))
  778.      return 0 ;    /* failed if hit end of file */
  779.       if (character(point+1) != entry[0] || character(point+2) != entry[1])
  780.      return 0 ;    /* failed if no longer on same interrupt */
  781.       t1 = hex2_to_int(character(point+3),character(point+4)) ;
  782.       if (t1 == ah)
  783.      break ;
  784.       else if (t1 > ah)
  785.      {
  786.      to_begin_line() ;
  787.      *first_entry = point ;
  788.      return 0 ;    /* no such entry */
  789.      }
  790.       }
  791.    nl_reverse() ;
  792.    *first_entry = point ;
  793.    found = 0 ;
  794.    al = hex2_to_int(entry[4],entry[5]) ;
  795.    while (1)
  796.       {
  797.       if (!to_separator_line(1))
  798.      return 0 ;    /* failed if hit end of file */
  799.       if (character(point+1) != entry[0] || character(point+2) != entry[1])
  800.      return 0 ;    /* failed if no longer on same interrupt */
  801.       t1 = hex2_to_int(character(point+3),character(point+4)) ;
  802.       if (t1 != ah)
  803.      return 0 ;    /* failed if no longer on same INT/AH combo */
  804.       t2 = hex2_to_int(character(point+5),character(point+6)) ;
  805.       if (t2 == al)
  806.      {
  807.      if (!found)
  808.         {
  809.         found = 1 ;
  810.         *first_entry = point ;
  811.         }
  812.      if (entry[6] != '-')
  813.         {
  814.         grab(point+7,point+12,buf) ;
  815.         match = strncmp(buf,entry+6,6) ;
  816.         if (match == 0)
  817.            {
  818.            *first_entry = point ;
  819.            break ;
  820.            }
  821.         else if (match > 0)
  822.            return 0 ;    /* no exact match, but return a partial match */
  823.         }
  824.      else
  825.         break ;
  826.      }
  827.       else if (t2 > al)
  828.      {
  829.      if (found)
  830.         break ;
  831.      else
  832.         {
  833.         to_begin_line() ;
  834.         *first_entry = point ;
  835.         return 0 ;    /* no such entry */
  836.         }
  837.      }
  838.       }
  839.    point = *first_entry ;    /* back to first matching entry */
  840.    
  841.    
  842.    return 1 ;            /* we were successful */
  843. }
  844.  
  845. /*=============================================================*/
  846. /*=============================================================*/
  847.  
  848. int goto_entry(entry_name)
  849. char *entry_name ;
  850. {
  851.    char int_id[13], extra_string[60] ;
  852.    int start = point, first_entry ;
  853.    int int_num, curr_int ;
  854.    char search_str[22] ;
  855.    
  856.    parse_int_name(entry_name,int_id,extra_string) ;
  857.    int_num = hex2_to_int(int_id[0],int_id[1]) ;
  858.    if (to_separator_line(-1))
  859.       {
  860.       if (character(point+11) == '-')
  861.      curr_int = -1 ;
  862.       else
  863.      curr_int = hex2_to_int(character(point+11),character(point+12)) ;
  864.       if (int_num <= 0)
  865.      point = 0 ;        /* go to top of file */
  866.       else
  867.      {
  868.      if (curr_int < 0)
  869.         point = 0 ;        /* go to top of file */
  870.      strcpy(search_str,"----------") ;
  871.      search_str[10] = hex_digit((int_num-1) / 16) ;
  872.      search_str[11] = hex_digit((int_num-1) % 16) ;
  873.      search_str[12] = '\0' ;
  874.      search( (int_num<=curr_int)?-1:1, search_str) ;
  875.      to_begin_line() ;
  876.      }
  877.       }
  878.    else
  879.       point = 0 ;
  880.    if (!scan_for_entry(int_id,extra_string,&first_entry))
  881.       {
  882.       say("%s not found.",entry_name) ;
  883.       if (first_entry)
  884.      {
  885.      mark = start ;
  886.      point = first_entry ;
  887.      }
  888.       else
  889.      point = start ;
  890.       }
  891.    if (has_arg)
  892.      iter = 1 ;                /* don't search repeatedly */
  893.    return 0 ;
  894. }
  895.  
  896. /*=============================================================*/
  897. /*=============================================================*/
  898.  
  899. command goto_int() on intlist_tab[FCTRL(12)]
  900. {
  901.    char entry_name[60], def_entry[60] ;
  902.    int start = point ;
  903.  
  904.    to_begin_line() ;
  905.    if (parse_string(1,"SeeAlso: ",NULL) != 0)
  906.       {
  907.       point += 9 ;        /* skip the SeeAlso: */
  908.       if (point < start)    /* if we were originally to the right of     */
  909.      point = start ;    /* current position, go back to original pos */
  910.       grab_int_reference(def_entry) ;
  911.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  912.       }
  913.    else if (line_has_see_also())
  914.       {
  915.       grab_int_reference(def_entry) ;
  916.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  917.       }
  918.    else
  919.       get_string(entry_name,"Goto Interrupt: ") ;
  920.    point = start ;
  921.    goto_entry(entry_name) ;
  922.    if (has_arg)
  923.       iter = 1 ;
  924. }
  925.  
  926. /*=============================================================*/
  927. /*=============================================================*/
  928.  
  929. void fix_unnumbered_tables()
  930. {
  931.    int matchsize ;
  932.    
  933.    point = 0 ;
  934.    while (search(1,"\n\n"))
  935.       {
  936.       switch(curchar())
  937.      {
  938.      case 'C':
  939.         if (parse_string(1,"Call ") != 0)
  940.            {
  941.            /* we got Call..., we know it doesn't have a table number */
  942.            insert_table_counter() ;
  943.            stuff("\n") ;
  944.            }
  945.         break ;
  946.      case 'V':
  947.         if (parse_string(1,"Values ") != 0)
  948.            {
  949.            /* we know this Values... doesn't have a table number */
  950.            insert_table_counter() ;
  951.            stuff("\n") ;
  952.            }
  953.         break ;
  954.      case 'B':
  955.         if (parse_string(1,"Bitfields ",0) == 0)
  956.            break ;
  957.         nl_forward() ;    /* skip to start of next line */
  958.         if (parse_string(1,".*\t%(Table ",0) == 0)
  959.            {
  960.            /* if the pattern didn't match, there is no table number, */
  961.            /* so add it */
  962.            to_end_line() ;
  963.            matchsize = parse_string(-1,"[ \t]+",0) ;
  964.            if (matchsize)
  965.           delete(point-matchsize,point) ;
  966.            stuff("\t") ;
  967.            insert_table_counter() ;
  968.            }
  969.         break ;
  970.      case 'F':
  971.         if (parse_string(1,"Format ",0) == 0)
  972.            break ;
  973.         nl_forward() ;    /* skip to start of next line */
  974.         if (parse_string(1,".*\t%(Table ",0) == 0)
  975.            {
  976.            /* if the pattern didn't match, there is no table number, */
  977.            /* so add it */
  978.            to_end_line() ;
  979.            matchsize = parse_string(-1,"[ \t]+",0) ;
  980.            if (matchsize)
  981.           delete(point-matchsize,point) ;
  982.            stuff("\t") ;
  983.            insert_table_counter() ;
  984.            }
  985.         break ;
  986.      default:
  987.         /* not a table header, so ignore it */
  988.         break ;
  989.      }
  990.       }
  991. }
  992.  
  993. /*=============================================================*/
  994. /*=============================================================*/
  995.  
  996. int *gather_table_numbers(number_of_tables)
  997. int *number_of_tables ;
  998. {
  999.    int i, num_tables ;
  1000.    int tcount = 0 ;
  1001.    char counter[5] ;
  1002.    int *new_numbers ;
  1003.    int old_number ;
  1004.    save_var case_fold = 0 ;
  1005.    
  1006.    grab(*table_counter,*table_counter+4,counter) ;
  1007.    num_tables = strtoi(counter,10) ;
  1008.    new_numbers = (int *)malloc((num_tables+2)*sizeof(int)) ;
  1009.    for (i = 0 ; i <= num_tables ; i++)
  1010.       new_numbers[i] = 0 ;
  1011.    point = 0 ;
  1012.    while (search(1,"(Table "))
  1013.       {
  1014.       grab(point,point+4,counter) ;
  1015.       old_number = strtoi(counter,10) ;
  1016.       if (old_number > 0 && old_number <= num_tables)
  1017.      new_numbers[old_number] = ++tcount ;
  1018.       }
  1019.    if (number_of_tables)
  1020.       *number_of_tables = num_tables ;
  1021.    return new_numbers ;
  1022. }
  1023.  
  1024. /*=============================================================*/
  1025. /*=============================================================*/
  1026.  
  1027. int adjust_table_numbers(num_tables,new_numbers)
  1028. int num_tables ;
  1029. int *new_numbers ;
  1030. {
  1031.    char counter[5] ;
  1032.    int old_number ;
  1033.    int dangling = 0 ;
  1034.    
  1035.    point = 0 ;
  1036.    while (search(1,"(Table "))
  1037.       {
  1038.       grab(point,point+4,counter) ;
  1039.       old_number = strtoi(counter,10) ;
  1040.       if (old_number > 0 && old_number <= num_tables)
  1041.      {
  1042.      delete(point,point+4) ;
  1043.      bprintf("%04d",new_numbers[old_number]) ;
  1044.      }
  1045.       }
  1046.    point = 0 ;
  1047.    while (re_search(1,"[, \t]%#[0-9][0-9][0-9][0-9]"))
  1048.       {
  1049.       grab(point-4,point,counter) ;
  1050.       old_number = strtoi(counter,10) ;
  1051.       if (old_number > 0 && old_number <= num_tables)
  1052.      {
  1053.      if (new_numbers[old_number])
  1054.         {
  1055.         delete(point-4,point) ;
  1056.         bprintf("%04d",new_numbers[old_number]) ;
  1057.         }
  1058.      else /* dangling xref */
  1059.         {
  1060.         dangling++ ;
  1061.         point -= 4 ;
  1062.         stuff("?") ;
  1063.         point += 4 ;
  1064.         }
  1065.      }
  1066.       }
  1067.    return dangling ;
  1068. }
  1069.  
  1070. /*=============================================================*/
  1071. /*=============================================================*/
  1072.  
  1073. command renumber_tables()
  1074. {
  1075.    int number_of_tables ;
  1076.    int *new_numbers ;
  1077.    spot start = alloc_spot(1) ;
  1078.    int dangling ;
  1079.    
  1080.    *start = point ;
  1081.    say("Pass 1: numbering unnumbered tables") ;
  1082.    fix_unnumbered_tables() ;
  1083.    say("Pass 2: gathering table numbers") ;
  1084.    new_numbers = gather_table_numbers(&number_of_tables) ;
  1085.    say("Pass 3: adjusting table numbers") ;
  1086.    dangling = adjust_table_numbers(number_of_tables,new_numbers) ;
  1087.    free(new_numbers) ;
  1088.    if (dangling)
  1089.       say("%d dangling cross-references, search for '#?'",dangling) ;
  1090.    else
  1091.       say("Done") ;
  1092.    point = *start ;
  1093.    free_spot(start) ;
  1094. }
  1095.  
  1096. /*=============================================================*/
  1097. /*=============================================================*/
  1098.  
  1099. void find_table_counter()
  1100. {
  1101.    save_var point = (size() > 10000) ? size() - 10000 : 0 ;
  1102.  
  1103.    search(1,"Highest Table Number = ") ;
  1104.    table_counter = alloc_spot(1) ;
  1105. }
  1106.  
  1107. /*=============================================================*/
  1108. /* Put the current buffer into IntList major mode           */
  1109. /*=============================================================*/
  1110.  
  1111. command intlist_mode()
  1112. {
  1113.    mode_keys = intlist_tab ;
  1114.    intlist_tab[')'] = intlist_tab[']'] = (short) show_matching_delimiter;
  1115.    delete_hacking_tabs = 0 ;
  1116.    major_mode = strsave("IntList") ;
  1117.    make_mode() ;
  1118.    auto_indent = 0 ;
  1119.    margin_right = 79 ;
  1120.    want_backups = 1 ;
  1121.    undo_size = 100000 ;     /* less than default 500,000 since list is so big */
  1122.    find_table_counter() ;
  1123. }
  1124.  
  1125. when_loading()
  1126. {
  1127.    char *curbuf ;
  1128.  
  1129.    want_backups = want_backups.default = 1 ;
  1130.    strcpy(backup_name,"%pbak/%b%e") ;        /* put backups in BAK subdir */
  1131.    one_window() ;
  1132.    intlist_mode() ;
  1133.    if (exist("interrup.1st"))
  1134.       {
  1135.       curbuf = bufname ;
  1136.       bufname = "interrup.1st" ;
  1137.       intlist_mode() ;
  1138.       bufname = curbuf ;
  1139.       }
  1140. /* Epsilon v6.0+ */
  1141.    strcpy(mode_end," %d%p %S") ;
  1142. }
  1143.  
  1144. /*=============================================================*/
  1145. /* automagically switch into interrupt list mode on .LST and .1ST files */
  1146.  
  1147. suffix_lst()   { intlist_mode(); }
  1148. suffix_1st()   { intlist_mode(); }
  1149.  
  1150.  
  1151.