home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / INTER34C.ZIP / INTLIST.E < prev    next >
Encoding:
Text File  |  1993-02-24  |  24.8 KB  |  896 lines

  1. /****************************************************************/
  2. /*    EEL code file for editing the Interrupt List        */
  3. /*                                */
  4. /*    Written by Ralf Brown                    */
  5. /*    LastEdit: 24 Feb 93                    */
  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. /*    Alt-I    add an Index: section to the current entry    */
  11. /*        add another Index: line if already on Index:    */
  12. /*      Alt-N   add a new note to current entry or data struct  */
  13. /*      Alt-P   add a Program: section to the current entry     */
  14. /*      Alt-R   insert Return: at start of line                 */
  15. /*    Alt-S    insert SeeAlso: at start of line        */
  16. /*    F11    insert a blank separator line            */
  17. /*    ^F11    create Format of: header            */
  18. /*    Shf-F11    create Values for: header            */
  19. /*    Alt-F11 create Call with: header            */
  20. /*    Alt-F12 create Bitfield for: header            */
  21. /*    F12    add the interrupt number to the separator line    */
  22. /*        preceding the current entry            */
  23. /*    ^F12    jump to a specified entry            */
  24. /*                                */
  25. /*  Other:                            */
  26. /*    adds intlist-mode for .LST and .1ST files        */
  27. /*    switches current buffer into intlist-mode on loading    */
  28. /****************************************************************/
  29.  
  30. #include "eel.h"
  31.  
  32. keytable intlist_tab ;            /* key table for IntList mode */
  33.  
  34. /*=============================================================*/
  35. /*=============================================================*/
  36.  
  37. char return_section[] = "Return: " ;
  38. char program_section[] = "Program: " ;
  39. char desc_section[] = "Desc:\t" ;
  40. char notes_section[] = "Notes*:\t" ;
  41. char bugs_section[] = "BUGS*:\t" ;
  42. char seealso_section[] = "SeeAlso: " ;
  43. char index_section[] = "Index:\t" ;
  44.  
  45. /*=============================================================*/
  46. /*=============================================================*/
  47.  
  48. int empty_line()
  49. {
  50.    return (character(point-1) == '\n' && character(point) == '\n') ;
  51. }
  52.  
  53. /*=============================================================*/
  54. /*=============================================================*/
  55.  
  56. int is_separator_line()
  57. {
  58.    return (empty_line() || parse_string(1,"--------",NULL)) ;
  59. }
  60.  
  61. /*=============================================================*/
  62. /* search in the specified direction (1 = forward, -1 = back)  */
  63. /* for the next entry separator line                   */
  64. /*=============================================================*/
  65.  
  66. int to_separator_line(dir)
  67. int dir ;
  68. {
  69.    return search(dir,"\n--------") ;
  70. }
  71.  
  72. /*=============================================================*/
  73. /* move to the location where the specified section of an      */
  74. /* entry begins (if present) or should begin (if not)           */
  75. /*=============================================================*/
  76.  
  77. int to_section_start(section)
  78. char *section ;
  79. {
  80.    int i, j, len ;
  81.    char *s ;
  82.    char *(sections[8]) ;
  83.  
  84.    /* list the sections of an entry in the order they should appear (if */
  85.    /* present at all) */
  86.    sections[0] = return_section ;
  87.    sections[1] = program_section ;
  88.    sections[2] = desc_section ;
  89.    sections[3] = notes_section ;
  90.    sections[4] = bugs_section ;
  91.    sections[5] = seealso_section ;
  92.    sections[6] = index_section ;
  93.    sections[7] = NULL ;
  94.    for (i = 0 ; sections[i] ; i++)
  95.       if (strcmp(section,sections[i]) == 0)
  96.      break ;
  97.    if (sections[i])
  98.       {
  99.       while (!is_separator_line() && !empty_line())
  100.      {
  101.      for (j = i ; sections[j] ; j++)
  102.         if (parse_string(1,sections[j],NULL))
  103.            {
  104.            if ((len = parse_string(1,section,NULL)) != 0)
  105.           {
  106.           point += len ;
  107.           return 1 ;    /* section already exists */
  108.           }
  109.            return 0 ;    /* section nonexistent, but found position */
  110.            }
  111.      if (!nl_forward())
  112.         break ;
  113.      }
  114.       return 0 ;    /* section does not yet exist */
  115.       }
  116.    else
  117.       return 0 ;    /* section not found */
  118. }
  119.  
  120. /*=============================================================*/
  121. /*=============================================================*/
  122.  
  123. int make_section(section,start_entry,name)
  124. char *section, *name ;
  125. int start_entry ;
  126. {
  127.    int start = point ;
  128.  
  129.    if (start_entry)
  130.       {
  131.       if (!to_separator_line(-1))  /* find previous separator line */
  132.      {
  133.      point = start ;
  134.      say("Not in an interrupt entry") ;
  135.      return 0 ;
  136.      }
  137.       }
  138.    else
  139.       {
  140.       to_begin_line() ;
  141.       while (!empty_line() && !parse_string(1,"\n--------",NULL))
  142.      if (!nl_reverse())
  143.         break ;
  144.       }
  145.    point++ ;                 /* skip the newline */
  146.    nl_forward() ;             /* advance to first line of entry */
  147.    if (!to_section_start(section))
  148.       {
  149.       if (name)
  150.      stuff(name) ;
  151.       else
  152.      stuff(section) ;
  153.       stuff("\n") ;
  154.       point-- ;              /* back up over inserted newline */
  155.       return 1 ;
  156.       }
  157.    else
  158.       return 0 ;
  159.    return 2 ;  /* just in case */
  160. }
  161.  
  162. /*=============================================================*/
  163. /*=============================================================*/
  164.  
  165. int pluralize_section(plural)
  166. char plural ;
  167. {
  168.    point -= 3 ;
  169.    if (curchar() != plural)        /* already plural ? */
  170.       {
  171.       point++ ;
  172.       insert(plural) ;
  173.       }
  174.    nl_forward() ;
  175.    while (!is_separator_line() && parse_string(1,"[ \t]",NULL))
  176.       nl_forward() ;
  177.    stuff("\t\n") ;
  178.    point-- ;
  179. }
  180.  
  181. /*=============================================================*/
  182. /* Add "SeeAlso: " to the beginning of the current line unless */
  183. /* it is already present                       */
  184. /*=============================================================*/
  185.  
  186. command see_also() on intlist_tab[ALT('s')]
  187. {
  188.    to_begin_line() ;
  189.    if (parse_string(1,"SeeAlso: ",NULL) == 0)
  190.       stuff("SeeAlso: ") ;
  191.    else
  192.       {
  193.       nl_forward() ;
  194.       stuff("SeeAlso: \n") ;
  195.       point-- ;
  196.       }
  197. }
  198.  
  199. /*=============================================================*/
  200. /* Add a Desc: section if the current entry does not already   */
  201. /* have one; if there is already a Desc: section, move to the  */
  202. /* start of it                               */
  203. /*=============================================================*/
  204.  
  205. command desc() on intlist_tab[ALT('D')]
  206. {
  207.    make_section(desc_section,1,NULL) ;
  208. }
  209.  
  210. /*=============================================================*/
  211. /* Add a "Program: " section to the current entry if it does   */
  212. /* not have one; otherwise, move to the beginning of the       */
  213. /* Program: section                           */
  214. /*=============================================================*/
  215.  
  216. command program() on intlist_tab[ALT('p')]
  217. {
  218.    make_section(program_section,1,NULL) ;
  219. }
  220.  
  221. /*=============================================================*/
  222. /* Add an "Index: " section to the current entry if it does    */
  223. /* not have one; otherwise, move to the beginning of the       */
  224. /* Index: section                           */
  225. /*=============================================================*/
  226.  
  227. command add_index() on intlist_tab[ALT('i')]
  228. {
  229.    to_begin_line() ;
  230.    if (parse_string(1,"Index:",NULL))
  231.       {
  232.       while (parse_string(1,"Index:",NULL))
  233.      nl_forward() ;
  234.       stuff("Index:\t\n") ;
  235.       point-- ;
  236.       }
  237.    else
  238.       make_section(index_section,1,NULL) ;
  239. }
  240.  
  241. /*=============================================================*/
  242. /*=============================================================*/
  243.  
  244. command bug() on intlist_tab[ALT('B')]
  245. {
  246.    if (!make_section(bugs_section,1,"BUG:\t"))
  247.       pluralize_section('S') ;
  248. }
  249.  
  250. /*=============================================================*/
  251. /* Add "Note: " section to the current entry; change an           */
  252. /* existing Note: to Notes: and position at end of Note:       */
  253. /* section.                               */
  254. /*=============================================================*/
  255.  
  256. command note() on intlist_tab[ALT('n')]
  257. {
  258.    if (!make_section(notes_section,0,"Note:\t"))
  259.       pluralize_section('s') ;
  260. }
  261.  
  262. /*=============================================================*/
  263. /* Insert "Return: " at the beginning of the current line, if  */
  264. /* not already present                           */
  265. /*=============================================================*/
  266.  
  267. command returns() on intlist_tab[ALT('r')]
  268. {
  269.    int len ;
  270.    int start = point ;
  271.    
  272.    to_begin_line() ;
  273.    if (parse_string(1,return_section,NULL) == 0)
  274.       stuff(return_section) ;
  275.    else
  276.       point = start ;
  277. }
  278.  
  279. /*=============================================================*/
  280. /* insert a line of dashes prior to the current cursor line    */
  281. /*=============================================================*/
  282.  
  283. command separator_line() on intlist_tab[FKEY(11)]
  284. {
  285.    int i ;
  286.  
  287.    to_begin_line() ;
  288.    for (i = 0 ; i < 45 ; i++)
  289.       insert('-') ;
  290.    insert('\n') ;
  291. }
  292.  
  293. /*=============================================================*/
  294. /* type the name of a structure, then invoke this function     */
  295. /* to create the "Format of X:" and "Offset Size Descr" lines  */
  296. /*=============================================================*/
  297.  
  298. command structure_header() on intlist_tab[FCTRL(11)]
  299. {
  300.    int start = point ;
  301.  
  302.    to_begin_line() ;
  303.    if (parse_string(1,"Format of ",NULL) == 0)
  304.       {
  305.       stuff("Format of ") ;
  306.       to_end_line() ;
  307.       stuff(":\nOffset\tSize\tDescription\n 00h\t") ;
  308.       }
  309.    else
  310.       point = start ;
  311. }
  312.  
  313. /*=============================================================*/
  314. /* Turn the current line into the header for a "Values of"     */
  315. /* section                               */
  316. /*=============================================================*/
  317.  
  318. command value_header() on intlist_tab[FSHIFT(11)]
  319. {
  320.    int start = point ;
  321.    
  322.    to_begin_line() ;
  323.    if (parse_string(1,"Values for ",NULL) == 0)
  324.       {
  325.       stuff("Values for ") ;
  326.       to_end_line() ;
  327.       stuff(":\n ") ;
  328.       }
  329.    else
  330.       point = start ;
  331. }
  332.  
  333. /*=============================================================*/
  334. /* Turn the current line into the header of a "Call with"      */
  335. /* section                               */
  336. /*=============================================================*/
  337.  
  338. command call_with_header() on intlist_tab[FALT(11)]
  339. {
  340.    int start = point ;
  341.    
  342.    to_begin_line() ;
  343.    if (parse_string(1,"Call ",NULL) == 0)
  344.       {
  345.       stuff("Call ") ;
  346.       to_end_line() ;
  347.       stuff("with:\n") ;
  348.       }
  349.    else
  350.       point = start ;
  351. }
  352.  
  353. /*=============================================================*/
  354. /* Turn the current line into the header of a "Bitfield for"   */
  355. /* section                               */
  356. /*=============================================================*/
  357.  
  358. command bitfields_for_header() on intlist_tab[FALT(12)]
  359. {
  360.    int start = point ;
  361.    
  362.    to_begin_line() ;
  363.    if (parse_string(1,"Bitfields for ",NULL) == 0)
  364.       {
  365.       stuff("Bitfields for ") ;
  366.       to_end_line() ;
  367.       stuff(":\n") ;
  368.       }
  369.    else
  370.       point = start ;
  371. }
  372.  
  373. /*=============================================================*/
  374. /*=============================================================*/
  375.  
  376. char grab_entry_number(func_num)
  377. char *func_num ;
  378. {
  379.    char c ;
  380.    int i ;
  381.  
  382.    strcpy(func_num,"------------") ;    /* 12 dashes */
  383.    point++ ;                /* go to first char of separator line */
  384.    nl_forward() ;            /* go to first line of entry */
  385.    if (parse_string(1,"INT ",NULL) == 0)
  386.       return 0 ;            /* not an interrupt entry, so return */
  387.    point += 4 ;                /* skip the "INT " */
  388.    func_num[0] = curchar() ;        /* grab the interrupt number */
  389.    point++ ;
  390.    func_num[1] = curchar() ;
  391.    nl_forward() ;            /* skip to second line of entry */
  392.    if (parse_string(1,"[ \t]*A[LHX][ \t]=[ \t][0-9A-F][0-9A-F]+h",NULL))
  393.       {
  394.       re_search(1,"[ \t]*A") ;
  395.       c = curchar() ;
  396.       point += 4 ;            /* skip ch and " = " */
  397.       if (c != 'L')
  398.      {
  399.      grab(point,point+((c=='X')?4:2),func_num+2) ;
  400.      point += ((c=='X')?4:2) ;
  401.      func_num[(c=='H')?4:6] = '-' ;    /* grab() stuck a NUL into the string */
  402.      }
  403.       else /* c == 'L' */
  404.      {
  405.      func_num[4] = curchar() ;
  406.      point++ ;
  407.      func_num[5] = curchar() ;
  408.      point ++ ;
  409.      }
  410.       point++ ;
  411.       if (parse_string(1,"[ \t]*subfn [0-9A-F][0-9A-F]+h",NULL))
  412.      {
  413.      re_search(1,"[ \t]*subfn ") ;
  414.      func_num[6] = 'S' ;
  415.      func_num[7] = 'F' ;
  416.      for (i = 0 ; i < 4 ; i++)
  417.         {
  418.         c = curchar() ;
  419.         if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
  420.            {
  421.            func_num[8+i] = c ;
  422.            point++ ;
  423.            }
  424.         else
  425.            break ;
  426.         }
  427.      }
  428.       nl_forward() ;            /* skip to third line of entry */
  429.       }
  430.    if (parse_string(1,"[ \t]*[BCDES][HILPSX] = [0-9A-F][0-9A-F]+h",NULL))
  431.       {
  432.       re_search(1,"[ \t]*") ;
  433.       func_num[6] = curchar() ;
  434.       point++ ;
  435.       func_num[7] = c = curchar() ;
  436.       point += 4 ;            /* skip curchar and " = " */
  437.       if (c == 'H' || c == 'L')
  438.      {
  439.      grab(point,point+2,func_num+8) ;
  440.      func_num[10] = '-' ;        /* grab() stuck a NUL into the string */
  441.      }
  442.       else /* c == 'X' || c == 'I' || c == 'P' || c == 'S' */
  443.      grab(point,point+4,func_num+8) ;
  444.       }
  445.    return 1 ;                /* successful and have func number */
  446. }
  447.  
  448. /*=============================================================*/
  449. /* Put the interrupt and function number into the separator    */
  450. /* line just above the intlist entry preceding the cursor pos  */
  451. /*=============================================================*/
  452.  
  453. int number_one_int()
  454. {
  455.    char func_num[13] ;            /* 2->int, 4->AX, 6->extra reg, NUL */
  456.    int oldpoint ;
  457.    
  458.    while (to_separator_line(-1))    /* find previous separator line */
  459.       {
  460.       oldpoint = point ;
  461.       if (grab_entry_number(func_num))    /* does it belong to an intlist entry? */
  462.      {                /*   if yes, success, else try again */
  463.      point = oldpoint + 11 ;    /* skip NL and first ten dashes */
  464.      delete(point,point+12) ;    /* replace 12 dashes by the function */
  465.      stuff(func_num) ;        /*   number and extra register */
  466.      point = oldpoint ;        /* back to start of line, allowing repeat */
  467.      return 1 ;
  468.      }
  469.       point = oldpoint ;
  470.       }
  471.    return 0 ;                /* if we get here, we failed */
  472. }
  473.  
  474. /*=============================================================*/
  475. /* Put the interrupt and function number into the separator    */
  476. /* line just above one or more intlist entries preceding the   */
  477. /* current cursor position, letting user know of progress      */
  478. /*=============================================================*/
  479.  
  480. command number_int() on intlist_tab[FKEY(12)]
  481. {
  482.    int i, hit_top = 0 ;
  483.    
  484.    for (i = 0 ; i < iter ; i++)
  485.       {
  486.       if (!number_one_int())
  487.      {
  488.      hit_top = 1 ;
  489.      say("No prior entry.") ;
  490.      break ;
  491.      }
  492.       if (((i+1) % 100) == 0)
  493.      say("%d...",i+1) ;
  494.       }
  495.    if (iter > 1 && !hit_top)
  496.       say("Done.") ;
  497.    iter = 1 ;
  498. }
  499.  
  500. /*=============================================================*/
  501. /*=============================================================*/
  502.  
  503. int line_has_see_also()
  504. {
  505.    int start = point ;
  506.    int len ;
  507.    
  508.    to_begin_line() ;
  509.    if ((len = parse_string(1,".*%([sS]ee ",NULL)) != 0)
  510.       {
  511.       point += len ;        /* go to start of cross-reference */
  512.       point += parse_string(1,"also ",NULL) ;
  513.       if (parse_string(1,"INT [0-9A-F]",NULL) ||
  514.       parse_string(1,"A[XHL] =",NULL)
  515.      )
  516.      {
  517.      point++ ;        /* move into reference */
  518.      return 1 ;
  519.      }
  520.       }
  521.    return 0 ;
  522. }
  523.  
  524. /*=============================================================*/
  525. /*=============================================================*/
  526.  
  527. int grab_int_reference(ref)
  528. char *ref ;
  529. {
  530.    int begin, start = point ;
  531.    
  532.    re_search(-1,"[, \t\n]") ;    /* backup to start of reference */
  533.    if (curchar() == '\n')    /* start of line? */
  534.       re_search(1,":[ \t]") ;    /* skip the SeeAlso: */
  535.    else if (character(point-1) == 'T' && character(point-2) == 'N')
  536.       point -= 3 ;
  537.    else
  538.       point++ ;            /* back to start of reference */
  539.    begin = point ;
  540.    re_search(1,"[,\n\"]") ;    /* find end of INT-spec */
  541.    point-- ;
  542.    if (curchar() == '\"')    /* extra string at end of INT-spec? */
  543.       {
  544.       point++ ;
  545.       re_search(1,"[\"\n]") ;    /* if yes, run to end of line or string */
  546.       }
  547.    grab(begin,point,ref) ;
  548.    point = start ;
  549.    return 0 ;
  550. }
  551.  
  552. /*=============================================================*/
  553. /*=============================================================*/
  554.  
  555. int parse_int_name(entry_name,id,extra_string)
  556. char *entry_name, *id, *extra_string ;
  557. {
  558.    int start = point ;
  559.    int i ;
  560.    char def_int[3] ;
  561.    char c, *last ;
  562.  
  563.    for (i = strlen(entry_name)-1 ; i >= 0 ; i--)
  564.       entry_name[i] = toupper(entry_name[i]) ;
  565.    strcpy(id,"------------") ;
  566.    if (strncmp(entry_name,"INT ",4) == 0)
  567.       {
  568.       id[0] = entry_name[4] ;
  569.       id[1] = entry_name[5] ;
  570.       entry_name += 6 ;
  571.       if (entry_name[0] == '/')
  572.      entry_name++ ;
  573.       }
  574.    else if (to_separator_line(-1))
  575.       {
  576.       id[0] = character(point+11) ;
  577.       id[1] = character(point+12) ;
  578.       }
  579.    point = start ;
  580.    c = entry_name[1] ;
  581.    if (entry_name[0] == 'A' && (c == 'X' || c == 'H' || c == 'L'))
  582.       {
  583.       entry_name += 2 ;
  584.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  585.      entry_name++ ;
  586.       if (entry_name[0] == '=')
  587.      entry_name++ ;
  588.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  589.      entry_name++ ;
  590.       if (c != 'L')
  591.      {
  592.          id[2] = entry_name[0] ;
  593.          id[3] = entry_name[1] ;
  594.      }
  595.       if (c == 'X')
  596.      {
  597.      id[4] = entry_name[2] ;
  598.      id[5] = entry_name[3] ;
  599.      entry_name += 4 ;
  600.      }
  601.       else
  602.      {
  603.      if (c == 'L')
  604.         {
  605.         id[2] = entry_name[0] ;
  606.         id[3] = entry_name[1] ;
  607.         }
  608.      entry_name += 2 ;
  609.      }
  610.       if (entry_name[0] == 'H')
  611.      entry_name++ ;
  612.       if (entry_name[0] == '/')
  613.      entry_name++ ;
  614.       }
  615.    if (index("ABCDES",entry_name[0]) && index("HILPSXF",entry_name[1]))
  616.       {
  617.       id[6] = entry_name[0] ;
  618.       c = id[7] = entry_name[1] ;
  619.       entry_name += 2 ;
  620.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  621.      entry_name++ ;
  622.       if (entry_name[0] == '=')
  623.      entry_name++ ;
  624.       while (entry_name[0] == ' ' || entry_name[0] == '\t')
  625.      entry_name++ ;
  626.       id[8] = entry_name[0] ;
  627.       id[9] = entry_name[1] ;
  628.       if (c != 'H' && c != 'L' && (c != 'F' || entry_name[2] != 'h'))
  629.      {
  630.      id[10] = entry_name[2] ;
  631.      id[11] = entry_name[3] ;
  632.      entry_name += 4 ;
  633.      }
  634.       else
  635.      entry_name += 2 ;
  636.       if (entry_name[0] == 'H')
  637.      entry_name++ ;
  638.       if (entry_name[0] == '/')
  639.      entry_name++ ;
  640.       }
  641.    if (entry_name[0] == '\"')
  642.       {
  643.       entry_name++ ;
  644.       strcpy(extra_string,entry_name) ;
  645.       last = index(extra_string,'\"') ;
  646.       if (last)
  647.      *last = '\0' ;
  648.       }
  649.    else
  650.       extra_string[0] = '\0' ;
  651.    return 0 ;
  652. }
  653.  
  654. /*=============================================================*/
  655. /*=============================================================*/
  656.  
  657. int hex2_to_int(c1,c2)
  658. char c1, c2 ;
  659. {
  660.    if (c1 >= '0' && c1 <= '9')
  661.       c1 -= '0' ;
  662.    else if (c1 >= 'A' && c1 <= 'F')
  663.       c1 = c1 - 'A' + 10 ;
  664.    else if (c1 >= 'a' && c1 <= 'f')
  665.       c1 = c1 - 'a' + 10 ;
  666.    else
  667.       return -1 ;
  668.    if (c2 >= '0' && c2 <= '9')
  669.       c2 -= '0' ;
  670.    else if (c2 >= 'A' && c2 <= 'F')
  671.       c2 = c2 - 'A' + 10 ;
  672.    else if (c2 >= 'a' && c2 <= 'f')
  673.       c2 = c2 - 'a' + 10 ;
  674.    else
  675.       return -1 ;
  676.    return 16*c1 + c2 ;
  677. }
  678.  
  679. /*=============================================================*/
  680. /*=============================================================*/
  681.  
  682. char hex_digit(val)
  683. int val ;
  684. {
  685.    if (val < 0)
  686.       return '-' ;
  687.    else if (val > 9)
  688.       return 'A' + val - 10 ;
  689.    else
  690.       return '0' + val ;
  691. }
  692.  
  693. /*=============================================================*/
  694. /*=============================================================*/
  695.  
  696. int scan_for_entry(entry,extra_str,first_entry)
  697. char *entry, *extra_str ;
  698. int *first_entry ;
  699. {
  700.    int ah, al, t1, t2, match, found ;
  701.    char buf[7] ;
  702.    
  703.    *first_entry = 0 ;
  704.    ah = hex2_to_int(entry[2],entry[3]) ;
  705.    while (1)
  706.       {
  707.       if (!to_separator_line(1))
  708.      return 0 ;    /* failed if hit end of file */
  709.       if (character(point+1) != entry[0] || character(point+2) != entry[1])
  710.      return 0 ;    /* failed if no longer on same interrupt */
  711.       t1 = hex2_to_int(character(point+3),character(point+4)) ;
  712.       if (t1 == ah)
  713.      break ;
  714.       else if (t1 > ah)
  715.      {
  716.      to_begin_line() ;
  717.      *first_entry = point ;
  718.      return 0 ;    /* no such entry */
  719.      }
  720.       }
  721.    nl_reverse() ;
  722.    *first_entry = point ;
  723.    found = 0 ;
  724.    al = hex2_to_int(entry[4],entry[5]) ;
  725.    while (1)
  726.       {
  727.       if (!to_separator_line(1))
  728.      return 0 ;    /* failed if hit end of file */
  729.       if (character(point+1) != entry[0] || character(point+2) != entry[1])
  730.      return 0 ;    /* failed if no longer on same interrupt */
  731.       t1 = hex2_to_int(character(point+3),character(point+4)) ;
  732.       if (t1 != ah)
  733.      return 0 ;    /* failed if no longer on same INT/AH combo */
  734.       t2 = hex2_to_int(character(point+5),character(point+6)) ;
  735.       if (t2 == al)
  736.      {
  737.      if (!found)
  738.         {
  739.         found = 1 ;
  740.         *first_entry = point ;
  741.         }
  742.      if (entry[6] != '-')
  743.         {
  744.         grab(point+7,point+12,buf) ;
  745.         match = strncmp(buf,entry+6,6) ;
  746.         if (match == 0)
  747.            {
  748.            *first_entry = point ;
  749.            break ;
  750.            }
  751.         else if (match > 0)
  752.            return 0 ;    /* no exact match, but return a partial match */
  753.         }
  754.      else
  755.         break ;
  756.      }
  757.       else if (t2 > al)
  758.      {
  759.      if (found)
  760.         break ;
  761.      else
  762.         {
  763.         to_begin_line() ;
  764.         *first_entry = point ;
  765.         return 0 ;    /* no such entry */
  766.         }
  767.      }
  768.       }
  769.    point = *first_entry ;    /* back to first matching entry */
  770.    
  771.    
  772.    return 1 ;            /* we were successful */
  773. }
  774.  
  775. /*=============================================================*/
  776. /*=============================================================*/
  777.  
  778. int goto_entry(entry_name)
  779. char *entry_name ;
  780. {
  781.    char int_id[13], extra_string[60] ;
  782.    int start = point, first_entry ;
  783.    int int_num, curr_int ;
  784.    char search_str[22] ;
  785.    char line_buf[90] ;
  786.    
  787.    parse_int_name(entry_name,int_id,extra_string) ;
  788.    int_num = hex2_to_int(int_id[0],int_id[1]) ;
  789.    if (to_separator_line(-1))
  790.       {
  791.       if (character(point+11) == '-')
  792.      curr_int = -1 ;
  793.       else
  794.      curr_int = hex2_to_int(character(point+11),character(point+12)) ;
  795.       if (int_num <= 0)
  796.      point = 0 ;        /* go to top of file */
  797.       else
  798.      {
  799.      if (curr_int < 0)
  800.         point = 0 ;        /* go to top of file */
  801.      strcpy(search_str,"----------") ;
  802.      search_str[10] = hex_digit((int_num-1) / 16) ;
  803.      search_str[11] = hex_digit((int_num-1) % 16) ;
  804.      search_str[12] = '\0' ;
  805.      search( (int_num<=curr_int)?-1:1, search_str) ;
  806.      to_begin_line() ;
  807.      }
  808.       }
  809.    else
  810.       point = 0 ;
  811.    if (!scan_for_entry(int_id,extra_string,&first_entry))
  812.       {
  813.       say("%s not found.",entry_name) ;
  814.       if (first_entry)
  815.      {
  816.      mark = start ;
  817.      point = first_entry ;
  818.      }
  819.       else
  820.      point = start ;
  821.       }
  822.    if (has_arg)
  823.      iter = 1 ;                /* don't search repeatedly */
  824.    return 0 ;
  825. }
  826.  
  827. /*=============================================================*/
  828. /*=============================================================*/
  829.  
  830. command goto_int() on intlist_tab[FCTRL(12)]
  831. {
  832.    char entry_name[60], def_entry[60] ;
  833.    int start = point ;
  834.  
  835.    to_begin_line() ;
  836.    if (parse_string(1,"SeeAlso: ",NULL) != 0)
  837.       {
  838.       point += 9 ;        /* skip the SeeAlso: */
  839.       if (point < start)    /* if we were originally to the right of     */
  840.      point = start ;    /* current position, go back to original pos */
  841.       grab_int_reference(def_entry) ;
  842.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  843.       }
  844.    else if (line_has_see_also())
  845.       {
  846.       grab_int_reference(def_entry) ;
  847.       get_strdef(entry_name,"Goto Interrupt",def_entry) ;
  848.       }
  849.    else
  850.       get_string(entry_name,"Goto Interrupt: ") ;
  851.    point = start ;
  852.    goto_entry(entry_name) ;
  853.    if (has_arg)
  854.       iter = 1 ;
  855. }
  856.  
  857. /*=============================================================*/
  858. /* Put the current buffer into IntList major mode           */
  859. /*=============================================================*/
  860.  
  861. command intlist_mode()
  862. {
  863.    mode_keys = intlist_tab ;
  864.    intlist_tab[')'] = intlist_tab[']'] = (short) show_matching_delimiter;
  865.    delete_hacking_tabs = 0 ;
  866.    major_mode = strsave("IntList") ;
  867.    make_mode() ;
  868.    auto_indent = 0 ;
  869.    margin_right = 79 ;
  870.    want_backups = 1 ;
  871.    undo_size = 100000 ;     /* less than default 500,000 since list is so big */
  872. }
  873.  
  874. when_loading()
  875. {
  876.    char *curbuf ;
  877.  
  878.    want_backups = want_backups.default = 1 ;
  879.    strcpy(backup_name,"%pbak/%b%e") ;        /* put backups in BAK subdir */
  880.    one_window() ;
  881.    intlist_mode() ;
  882.    if (exist("interrup.1st"))
  883.       {
  884.       curbuf = bufname ;
  885.       bufname = "interrup.1st" ;
  886.       intlist_mode() ;
  887.       bufname = curbuf ;
  888.       }
  889. }
  890.  
  891. /*=============================================================*/
  892. /* automagically switch into interrupt list mode on .LST and .1ST files */
  893.  
  894. suffix_lst()   { intlist_mode(); }
  895. suffix_1st()   { intlist_mode(); }
  896.