Category : Recently Uploaded Files
Archive   : INTER48E.ZIP
Filename : INTLIST.E
/* EEL code file for editing the Interrupt List */
/* */
/* Written by Ralf Brown */
/* LastEdit: 29 Oct 95 */
/* */
/* This EEL file adds the following keybindings: */
/* Shf-Alt-B add another BUG: to the current entry */
/* Shf-Alt-D add a Desc: section to the current entry */
/* Sft-Alt-I add an InstallCheck: section to current entry */
/* Shf-Alt-R add a Range: section to the current entry */
/* Shf-Alt-S add a Size: section to the current entry */
/* Alt-I add an Index: section to the current entry */
/* add another Index: line if already on Index: */
/* Alt-N add a new note to current entry or data struct */
/* Alt-P add a Program: section to the current entry */
/* Alt-R insert Return: at start of line */
/* Alt-S insert SeeAlso: at start of line */
/* F11 insert a blank separator line */
/* ^F11 create Format of: header */
/* Shf-F11 create Values for: header */
/* Alt-F11 create Call with: header */
/* Alt-F12 create Bitfield for: header */
/* F12 add the interrupt number to the separator line */
/* preceding the current entry */
/* ^F12 jump to a specified entry */
/* */
/* It adds the following unbound commands: */
/* renumber-tables */
/* make-distribution */
/* */
/* Other: */
/* adds intlist-mode for .LST and .1ST files */
/* switches current buffer into intlist-mode on loading */
/* maintains a table counter which is inserted each time */
/* a table is created in the text */
/****************************************************************/
#include "eel.h"
keytable intlist_tab ; /* key table for IntList mode */
/* on repeated F12, how often to display number of entries processed */
/* for fast 386, every 100; for a Pentium, at least 300 or the message */
/* line will lag way behind the actual progress */
#define NUMBER_INT_PROGRESS_INTERVAL 500
/*=============================================================*/
/* Global Variables */
/*=============================================================*/
char size_section[] = "Size:\t" ;
char return_section[] = "Return: " ;
char install_section[] = " InstallCheck: " ;
char program_section[] = "Program: " ;
char desc_section[] = "Desc:\t" ;
char range_section[] = "Range:\t" ;
char notes_section[] = "Notes*:\t" ;
char bugs_section[] = "BUGS*:\t" ;
char seealso_section[] = "SeeAlso: " ;
char index_section[] = "Index:\t" ;
char table_ID_letters[] = "0123456789CFMP" ;
char *(section_order[11]) ;
char *(list_files[7]) ;
when_loading()
{
/* list the sections of an entry in the order they should appear (if */
/* present at all) */
section_order[0] = size_section ;
section_order[1] = return_section ;
section_order[2] = install_section ;
section_order[3] = program_section ;
section_order[4] = desc_section ;
section_order[5] = range_section ;
section_order[6] = notes_section ;
section_order[7] = bugs_section ;
section_order[8] = seealso_section ;
section_order[9] = index_section ;
section_order[10] = NULL ;
/* list the files comprising the full interrupt list */
list_files[0] = "cmos.lst" ;
list_files[1] = "farcall.lst" ;
list_files[2] = "memory.lst" ;
list_files[3] = "ports.lst" ;
list_files[4] = "interrup.lst" ;
list_files[5] = "tables.lst" ;
list_files[6] = NULL ;
}
/*=============================================================*/
/* Buffer-specific variables */
/*=============================================================*/
buffer spot table_counter ;
/*=============================================================*/
/*=============================================================*/
int empty_line()
{
return (character(point-1) == '\n' && character(point) == '\n') ;
}
/*=============================================================*/
/*=============================================================*/
int is_separator_line()
{
return (empty_line() || parse_string(1,"--------",NULL)) ;
}
/*=============================================================*/
/* search in the specified direction (1 = forward, -1 = back) */
/* for the next entry separator line */
/*=============================================================*/
int to_separator_line(dir)
int dir ;
{
nl_reverse() ;
return search(dir,"\n--------") ;
}
/*=============================================================*/
/* move to the location where the specified section of an */
/* entry begins (if present) or should begin (if not) */
/*=============================================================*/
int to_section_start(section)
char *section ;
{
int i, j, len ;
for (i = 0 ; section_order[i] ; i++)
if (strcmp(section,section_order[i]) == 0)
break ;
if (section_order[i])
{
while (!is_separator_line())
{
for (j = i ; section_order[j] ; j++)
if (parse_string(1,section_order[j],NULL))
{
if ((len = parse_string(1,section,NULL)) != 0)
{
point += len ;
return 1 ; /* section already exists */
}
return 0 ; /* section nonexistent, but found position */
}
if (!nl_forward())
break ;
}
return 0 ; /* section does not yet exist */
}
else
return 0 ; /* section not found */
}
/*=============================================================*/
/*=============================================================*/
int make_section(section,start_entry,name)
char *section, *name ;
int start_entry ;
{
int start = point ;
if (start_entry)
{
if (!to_separator_line(-1)) /* find previous separator line */
{
point = start ;
say("Not in an interrupt entry") ;
return 0 ;
}
}
else
{
to_begin_line() ;
while (!empty_line() && !parse_string(1,"\n--------",NULL))
if (!nl_reverse())
break ;
}
point++ ; /* skip the newline */
nl_forward() ; /* advance to first line of entry */
if (!to_section_start(section))
{
if (name)
stuff(name) ;
else
stuff(section) ;
stuff("\n") ;
point-- ; /* back up over inserted newline */
return 1 ;
}
else
return 0 ;
return 2 ; /* just in case */
}
/*=============================================================*/
/*=============================================================*/
int pluralize_section(plural)
char plural ;
{
point -= 3 ;
if (curchar() != plural) /* already plural ? */
{
point++ ;
insert(plural) ;
}
nl_forward() ;
while (!is_separator_line() && parse_string(1,"[ \t]",NULL))
nl_forward() ;
stuff("\t\n") ;
point-- ;
}
/*=============================================================*/
/* Add "SeeAlso: " to the beginning of the current line unless */
/* it is already present */
/*=============================================================*/
command see_also() on intlist_tab[ALT('s')]
{
to_begin_line() ;
if (parse_string(1,"SeeAlso: ",NULL) == 0)
stuff("SeeAlso: ") ;
else
{
nl_forward() ;
stuff("SeeAlso: \n") ;
point-- ;
}
}
/*=============================================================*/
/* Add a Desc: section if the current entry does not already */
/* have one; if there is already a Desc: section, move to the */
/* start of it */
/*=============================================================*/
command desc() on intlist_tab[ALT('D')]
{
make_section(desc_section,1,NULL) ;
}
/*=============================================================*/
/* Add a InstallCheck: section if the current entry does not */
/* already have one; if there is already a InstallCheck: */
/* section, move to the start of it */
/*=============================================================*/
command instcheck() on intlist_tab[ALT('I')]
{
make_section(install_section,1,NULL) ;
}
/*=============================================================*/
/* Add a Range: section if the current entry does not already */
/* have one; if there is already a Range: section, move to the */
/* start of it */
/*=============================================================*/
command range() on intlist_tab[ALT('R')]
{
make_section(range_section,1,NULL) ;
}
/*=============================================================*/
/* Add a Size: section if the current entry does not already */
/* have one; if there is already a Size: section, move to the */
/* start of it */
/*=============================================================*/
command memsize() on intlist_tab[ALT('S')]
{
make_section(size_section,1,NULL) ;
}
/*=============================================================*/
/* Add a "Program: " section to the current entry if it does */
/* not have one; otherwise, move to the beginning of the */
/* Program: section */
/*=============================================================*/
command program() on intlist_tab[ALT('p')]
{
make_section(program_section,1,NULL) ;
}
/*=============================================================*/
/* Add an "Index: " section to the current entry if it does */
/* not have one; otherwise, move to the beginning of the */
/* Index: section */
/*=============================================================*/
command add_index() on intlist_tab[ALT('i')]
{
to_begin_line() ;
if (parse_string(1,"Index:",NULL))
{
while (parse_string(1,"Index:",NULL))
nl_forward() ;
stuff("Index:\t\n") ;
point-- ;
}
else
make_section(index_section,1,NULL) ;
}
/*=============================================================*/
/*=============================================================*/
command bug() on intlist_tab[ALT('B')]
{
if (!make_section(bugs_section,1,"BUG:\t"))
pluralize_section('S') ;
}
/*=============================================================*/
/* Add "Note: " section to the current entry; change an */
/* existing Note: to Notes: and position at end of Note: */
/* section. */
/*=============================================================*/
command add_note() on intlist_tab[ALT('n')]
{
if (!make_section(notes_section,0,"Note:\t"))
pluralize_section('s') ;
}
/*=============================================================*/
/* Insert "Return: " at the beginning of the current line, if */
/* not already present */
/*=============================================================*/
command returns() on intlist_tab[ALT('r')]
{
int start = point ;
to_begin_line() ;
if (parse_string(1,return_section,NULL) == 0)
stuff(return_section) ;
else
point = start ;
}
/*=============================================================*/
/* insert a line of dashes prior to the current cursor line */
/*=============================================================*/
command separator_line() on intlist_tab[FKEY(11)]
{
int i ;
to_begin_line() ;
for (i = 0 ; i < 45 ; i++)
insert('-') ;
insert('\n') ;
}
/*=============================================================*/
/*=============================================================*/
void insert_table_counter()
{
char counter[6] ;
save_var point = *table_counter + 3 ;
/* increment that table counter */
while (curchar() >= '0')
{
if (curchar() < '9')
{
replace(point,curchar()+1) ;
break ;
}
else
{
replace(point,'0') ;
point-- ;
}
}
restore_vars() ;
/* and now insert the incremented value at point */
stuff("(Table ") ;
grab(*table_counter,*table_counter+4,counter) ;
stuff(counter) ;
stuff(")") ;
}
/*=============================================================*/
/* type the name of a structure, then invoke this function */
/* to create the "Format of X:" and "Offset Size Descr" lines */
/*=============================================================*/
command structure_header() on intlist_tab[FCTRL(11)]
{
int start = point ;
to_begin_line() ;
if (parse_string(1,"Format of ",NULL) == 0)
{
stuff("Format of ") ;
to_end_line() ;
stuff(":\nOffset\tSize\tDescription\t") ;
insert_table_counter() ;
stuff("\n 00h\t") ;
}
else
point = start ;
}
/*=============================================================*/
/* Turn the current line into the header for a "Values of" */
/* section */
/*=============================================================*/
command value_header() on intlist_tab[FSHIFT(11)]
{
int start = point ;
to_begin_line() ;
if (parse_string(1,"Values for ",NULL) == 0)
{
insert_table_counter() ;
stuff("\nValues for ") ;
to_end_line() ;
stuff(":\n ") ;
}
else
point = start ;
}
/*=============================================================*/
/* Turn the current line into the header of a "Call with" */
/* section */
/*=============================================================*/
command call_with_header() on intlist_tab[FALT(11)]
{
int start = point ;
to_begin_line() ;
if (parse_string(1,"Call ",NULL) == 0)
{
insert_table_counter() ;
stuff("\nCall ") ;
to_end_line() ;
if (character(point-1) != ' ')
stuff(" ") ;
stuff("with:\n") ;
}
else
point = start ;
}
/*=============================================================*/
/* Turn the current line into the header of a "Bitfield for" */
/* section */
/*=============================================================*/
command bitfields_for_header() on intlist_tab[FALT(12)]
{
int start = point ;
to_begin_line() ;
if (parse_string(1,"Bitfields for ",NULL) == 0)
{
stuff("Bitfields for ") ;
to_end_line() ;
stuff(":\nBit(s)\tDescription\t") ;
insert_table_counter() ;
stuff("\n ") ;
}
else
point = start ;
}
/*=============================================================*/
/*=============================================================*/
char grab_int_entry_number(func_num)
char *func_num ;
{
int i ;
char c ;
point += 4 ; /* skip the "INT " */
func_num[0] = curchar() ; /* grab the interrupt number */
point++ ;
func_num[1] = curchar() ;
nl_forward() ; /* skip to second line of entry */
if (parse_string(1,"[ \t]*A[LHX][ \t]=[ \t][0-9A-F][0-9A-F]+h",NULL))
{
re_search(1,"[ \t]*A") ;
c = curchar() ;
point += 4 ; /* skip ch and " = " */
if (c != 'L')
{
grab(point,point+((c=='X')?4:2),func_num+2) ;
point += ((c=='X')?4:2) ;
func_num[(c=='H')?4:6] = '-' ; /* grab() stuck a NUL into the string */
}
else /* c == 'L' */
{
func_num[4] = curchar() ;
point++ ;
func_num[5] = curchar() ;
point ++ ;
}
point++ ;
if (parse_string(1,"[ \t]*subfn [0-9A-F][0-9A-F]+h",NULL))
{
re_search(1,"[ \t]*subfn ") ;
func_num[6] = 'S' ;
func_num[7] = 'F' ;
for (i = 0 ; i < 4 ; i++)
{
c = curchar() ;
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
{
func_num[8+i] = c ;
point++ ;
}
else
break ;
}
}
nl_forward() ; /* skip to third line of entry */
}
if (parse_string(1,"[ \t]*[BCDES][HILPSX] = [0-9A-F][0-9A-F]+h",NULL))
{
re_search(1,"[ \t]*") ;
func_num[6] = curchar() ;
point++ ;
func_num[7] = c = curchar() ;
point += 4 ; /* skip curchar and " = " */
if (c == 'H' || c == 'L')
{
grab(point,point+2,func_num+8) ;
func_num[10] = '-' ; /* grab() stuck a NUL into the string */
}
else /* c == 'X' || c == 'I' || c == 'P' || c == 'S' */
grab(point,point+4,func_num+8) ;
}
return 1 ; /* successful and have func number */
}
/*=============================================================*/
char grab_cmos_entry_number(func_num)
char *func_num ;
{
point += 5 ; /* skip the "CMOS " */
func_num[0] = 'R' ; /* mark this as a CMOS RAM entry */
grab(point,point+4,func_num+1) ;
if (func_num[3] == 'h' && func_num[4] == '-')
grab(point+4,point+6,func_num+3) ;
else
{
func_num[3] = '-' ;
func_num[4] = '-' ;
}
func_num[5] = '-' ; /* grab() stuck a NUL into string */
return 1 ;
}
/*=============================================================*/
char grab_farcall_entry_number(func_num)
char *func_num ;
{
point += 5 ; /* skip the "CALL " */
func_num[0] = '@' ; /* mark this as a far call entry */
grab(point,point+4,func_num+1) ; /* get segment of address */
grab(point+6,point+10,func_num+5) ; /* get offset of address */
func_num[9] = '-' ; /* grab() stuck a NUL into string */
return 1 ;
}
/*=============================================================*/
char grab_memory_entry_number(func_num)
char *func_num ;
{
point += 4 ; /* skip the "MEM " */
func_num[0] = 'M' ; /* mark this as a memory loc entry */
grab(point,point+6,func_num+1) ; /* get segment or high word of addr */
if (func_num[5] == 'h' && func_num[6] == ':') /* segmented address? */
grab(point+6,point+10,func_num+5) ; /* get offset of address */
else
{
grab(point+6,point+8,func_num+7) ;/* get low word of the address */
func_num[0] = 'm' ; /* indicate linear address */
}
func_num[9] = '-' ; /* grab() stuck a NUL into string */
return 1 ;
}
/*=============================================================*/
char grab_port_entry_number(func_num)
char *func_num ;
{
point += 5 ; /* skip the "PORT " */
func_num[0] = 'P' ; /* mark this as an I/O port entry */
grab(point,point+4,func_num+1) ; /* get starting port number */
func_num[5] = '-' ; /* grab() stuck a NUL into string */
if (character(point+4) == '-')
{
grab(point+5,point+9,func_num+5) ; /* get ending port number */
func_num[9] = '-' ; /* grab() stuck a NUL into string */
}
return 1 ;
}
/*=============================================================*/
char grab_entry_number(func_num)
char *func_num ;
{
strcpy(func_num,"------------") ; /* 12 dashes */
point++ ; /* go to first char of separator line */
nl_forward() ; /* go to first line of entry */
if (parse_string(1,"INT ",NULL)) /* is it an interrupt entry? */
return grab_int_entry_number(func_num) ;
else if (parse_string(1,"CMOS ",NULL) != 0)
return grab_cmos_entry_number(func_num) ;
else if (parse_string(1,"CALL ",NULL) != 0)
return grab_farcall_entry_number(func_num) ;
else if (parse_string(1,"MEM ",NULL) != 0)
return grab_memory_entry_number(func_num) ;
else if (parse_string(1,"PORT ",NULL) != 0)
return grab_port_entry_number(func_num) ;
else
return 0 ;
}
/*=============================================================*/
/* Put the interrupt and function number into the separator */
/* line just above the intlist entry preceding the cursor pos */
/*=============================================================*/
int number_one_int()
{
char func_num[13] ; /* 2->int, 4->AX, 6->extra reg, NUL */
int oldpoint ;
while (to_separator_line(-1)) /* find previous separator line */
{
oldpoint = point ;
if (grab_entry_number(func_num)) /* does it belong to an intlist entry? */
{ /* if yes, success, else try again */
point = oldpoint + 11 ; /* skip NL and first ten dashes */
delete(point,point+12) ; /* replace 12 dashes by the function */
stuff(func_num) ; /* number and extra register */
point = oldpoint + 9 ; /* back to category letter position */
return 1 ;
}
point = oldpoint ;
}
return 0 ; /* if we get here, we failed */
}
/*=============================================================*/
/* Put the interrupt and function number into the separator */
/* line just above one or more intlist entries preceding the */
/* current cursor position, letting user know of progress */
/*=============================================================*/
command number_int() on intlist_tab[FKEY(12)]
{
int i, hit_top = 0 ;
for (i = 0 ; i < iter ; i++)
{
if (!number_one_int())
{
hit_top = 1 ;
say("No prior entry.") ;
break ;
}
if (((i+1) % NUMBER_INT_PROGRESS_INTERVAL) == 0)
say("%4d...",i+1) ;
}
if (iter > 1 && !hit_top)
say("Done.") ;
iter = 1 ;
}
/*=============================================================*/
/*=============================================================*/
int line_has_see_also()
{
int len ;
to_begin_line() ;
if ((len = parse_string(1,".*%([sS]ee ",NULL)) != 0)
{
point += len ; /* go to start of cross-reference */
point += parse_string(1,"also ",NULL) ;
if (parse_string(1,"INT [0-9A-F]",NULL) ||
parse_string(1,"A[XHL] =",NULL)
)
{
point++ ; /* move into reference */
return 1 ;
}
}
return 0 ;
}
/*=============================================================*/
/*=============================================================*/
int grab_int_reference(ref)
char *ref ;
{
int begin, start = point ;
re_search(-1,"[, \t\n]") ; /* backup to start of reference */
if (curchar() == '\n') /* start of line? */
re_search(1,":[ \t]") ; /* skip the SeeAlso: */
else if (character(point-1) == 'T' && character(point-2) == 'N')
point -= 3 ;
else
point++ ; /* back to start of reference */
begin = point ;
re_search(1,"[,\n\"]") ; /* find end of INT-spec */
point-- ;
if (curchar() == '\"') /* extra string at end of INT-spec? */
{
point++ ;
re_search(1,"[\"\n]") ; /* if yes, run to end of line or string */
}
grab(begin,point,ref) ;
point = start ;
return 0 ;
}
/*=============================================================*/
/*=============================================================*/
int parse_int_name(entry_name,id,extra_string)
char *entry_name, *id, *extra_string ;
{
int start = point ;
int i ;
char c, *last ;
for (i = strlen(entry_name)-1 ; i >= 0 ; i--)
entry_name[i] = toupper(entry_name[i]) ;
strcpy(id,"------------") ;
if (strncmp(entry_name,"INT ",4) == 0)
{
id[0] = entry_name[4] ;
id[1] = entry_name[5] ;
entry_name += 6 ;
if (entry_name[0] == '/')
entry_name++ ;
}
else if (to_separator_line(-1))
{
id[0] = character(point+11) ;
id[1] = character(point+12) ;
}
point = start ;
c = entry_name[1] ;
if (entry_name[0] == 'A' && (c == 'X' || c == 'H' || c == 'L'))
{
entry_name += 2 ;
while (entry_name[0] == ' ' || entry_name[0] == '\t')
entry_name++ ;
if (entry_name[0] == '=')
entry_name++ ;
while (entry_name[0] == ' ' || entry_name[0] == '\t')
entry_name++ ;
if (c != 'L')
{
id[2] = entry_name[0] ;
id[3] = entry_name[1] ;
}
if (c == 'X')
{
id[4] = entry_name[2] ;
id[5] = entry_name[3] ;
entry_name += 4 ;
}
else
{
if (c == 'L')
{
id[2] = entry_name[0] ;
id[3] = entry_name[1] ;
}
entry_name += 2 ;
}
if (entry_name[0] == 'H')
entry_name++ ;
if (entry_name[0] == '/')
entry_name++ ;
}
if (index("ABCDES",entry_name[0]) && index("HILPSXF",entry_name[1]))
{
id[6] = entry_name[0] ;
c = id[7] = entry_name[1] ;
entry_name += 2 ;
while (entry_name[0] == ' ' || entry_name[0] == '\t')
entry_name++ ;
if (entry_name[0] == '=')
entry_name++ ;
while (entry_name[0] == ' ' || entry_name[0] == '\t')
entry_name++ ;
id[8] = entry_name[0] ;
id[9] = entry_name[1] ;
if (c != 'H' && c != 'L' && (c != 'F' || entry_name[2] != 'h'))
{
id[10] = entry_name[2] ;
id[11] = entry_name[3] ;
entry_name += 4 ;
}
else
entry_name += 2 ;
if (entry_name[0] == 'H')
entry_name++ ;
if (entry_name[0] == '/')
entry_name++ ;
}
if (entry_name[0] == '\"')
{
entry_name++ ;
strcpy(extra_string,entry_name) ;
last = index(extra_string,'\"') ;
if (last)
*last = '\0' ;
}
else
extra_string[0] = '\0' ;
return 0 ;
}
/*=============================================================*/
/*=============================================================*/
int hex2_to_int(c1,c2)
char c1, c2 ;
{
if (c1 >= '0' && c1 <= '9')
c1 -= '0' ;
else if (c1 >= 'A' && c1 <= 'F')
c1 = c1 - 'A' + 10 ;
else if (c1 >= 'a' && c1 <= 'f')
c1 = c1 - 'a' + 10 ;
else
return -1 ;
if (c2 >= '0' && c2 <= '9')
c2 -= '0' ;
else if (c2 >= 'A' && c2 <= 'F')
c2 = c2 - 'A' + 10 ;
else if (c2 >= 'a' && c2 <= 'f')
c2 = c2 - 'a' + 10 ;
else
return -1 ;
return 16*c1 + c2 ;
}
/*=============================================================*/
/*=============================================================*/
char hex_digit(val)
int val ;
{
if (val < 0)
return '-' ;
else
return (val > 9) ? ('A' + val - 10) : ('0' + val) ;
}
/*=============================================================*/
/*=============================================================*/
int scan_for_entry(entry,extra_str,first_entry)
char *entry, *extra_str ;
int *first_entry ;
{
int ah, al, t1, t2, match, found ;
char buf[7] ;
if (extra_str) extra_str = 0 ; /* for now, to avoid compiler warning */
*first_entry = 0 ;
ah = hex2_to_int(entry[2],entry[3]) ;
while (1)
{
if (!to_separator_line(1))
return 0 ; /* failed if hit end of file */
if (character(point+1) != entry[0] || character(point+2) != entry[1])
return 0 ; /* failed if no longer on same interrupt */
t1 = hex2_to_int(character(point+3),character(point+4)) ;
if (t1 == ah)
break ;
else if (t1 > ah)
{
to_begin_line() ;
*first_entry = point ;
return 0 ; /* no such entry */
}
}
nl_reverse() ;
*first_entry = point ;
found = 0 ;
al = hex2_to_int(entry[4],entry[5]) ;
while (1)
{
if (!to_separator_line(1))
return 0 ; /* failed if hit end of file */
if (character(point+1) != entry[0] || character(point+2) != entry[1])
return 0 ; /* failed if no longer on same interrupt */
t1 = hex2_to_int(character(point+3),character(point+4)) ;
if (t1 != ah)
return 0 ; /* failed if no longer on same INT/AH combo */
t2 = hex2_to_int(character(point+5),character(point+6)) ;
if (t2 == al)
{
if (!found)
{
found = 1 ;
*first_entry = point ;
}
if (entry[6] != '-')
{
grab(point+7,point+12,buf) ;
match = strncmp(buf,entry+6,6) ;
if (match == 0)
{
*first_entry = point ;
break ;
}
else if (match > 0)
return 0 ; /* no exact match, but return a partial match */
}
else
break ;
}
else if (t2 > al)
{
if (found)
break ;
else
{
to_begin_line() ;
*first_entry = point ;
return 0 ; /* no such entry */
}
}
}
point = *first_entry ; /* back to first matching entry */
return 1 ; /* we were successful */
}
/*=============================================================*/
/*=============================================================*/
int goto_entry(entry_name)
char *entry_name ;
{
char int_id[13], extra_string[60] ;
int start = point, first_entry ;
int int_num, curr_int ;
char search_str[22] ;
parse_int_name(entry_name,int_id,extra_string) ;
int_num = hex2_to_int(int_id[0],int_id[1]) ;
if (to_separator_line(-1))
{
if (character(point+11) == '-')
curr_int = -1 ;
else
curr_int = hex2_to_int(character(point+11),character(point+12)) ;
if (int_num <= 0)
point = 0 ; /* go to top of file */
else
{
if (curr_int < 0)
point = 0 ; /* go to top of file */
strcpy(search_str,"----------") ;
search_str[10] = hex_digit((int_num-1) / 16) ;
search_str[11] = hex_digit((int_num-1) % 16) ;
search_str[12] = '\0' ;
search( (int_num<=curr_int)?-1:1, search_str) ;
to_begin_line() ;
}
}
else
point = 0 ;
if (!scan_for_entry(int_id,extra_string,&first_entry))
{
say("%s not found.",entry_name) ;
if (first_entry)
{
mark = start ;
point = first_entry ;
}
else
point = start ;
}
if (has_arg)
iter = 1 ; /* don't search repeatedly */
return 0 ;
}
/*=============================================================*/
/*=============================================================*/
command goto_int() on intlist_tab[FCTRL(12)]
{
char entry_name[60], def_entry[60] ;
int start = point ;
to_begin_line() ;
if (parse_string(1,"SeeAlso: ",NULL) != 0)
{
point += 9 ; /* skip the SeeAlso: */
if (point < start) /* if we were originally to the right of */
point = start ; /* current position, go back to original pos */
grab_int_reference(def_entry) ;
get_strdef(entry_name,"Goto Interrupt",def_entry) ;
}
else if (line_has_see_also())
{
grab_int_reference(def_entry) ;
get_strdef(entry_name,"Goto Interrupt",def_entry) ;
}
else
get_string(entry_name,"Goto Interrupt: ") ;
point = start ;
goto_entry(entry_name) ;
if (has_arg)
iter = 1 ;
}
/*=============================================================*/
/*=============================================================*/
void maybe_append_table_number()
{
if (parse_string(1,".*\t%(Table ",0) == 0)
{
int matchsize ;
/* if the pattern didn't match, there is no table number, */
/* so add it */
to_end_line() ;
matchsize = parse_string(-1,"[ \t]+",0) ;
if (matchsize)
delete(point-matchsize,point) ;
stuff("\t") ;
insert_table_counter() ;
}
}
/*=============================================================*/
/*=============================================================*/
void fix_unnumbered_tables()
{
spot start = alloc_spot(1) ;
*start = point ;
point = 0 ;
while (search(1,"\n\n"))
{
switch(curchar())
{
case 'C':
if (parse_string(1,"Call ") != 0)
{
/* we got Call..., we know it doesn't have a table number */
insert_table_counter() ;
stuff("\n") ;
}
break ;
case 'V':
if (parse_string(1,"Values ") != 0)
{
/* we know this Values... doesn't have a table number */
insert_table_counter() ;
stuff("\n") ;
}
break ;
case 'B':
if (parse_string(1,"Bitfields ",0) == 0)
break ;
nl_forward() ; /* skip to start of next line */
maybe_append_table_number() ;
break ;
case 'F':
if (parse_string(1,"Format ",0) == 0)
break ;
nl_forward() ; /* skip to start of next line */
maybe_append_table_number() ;
break ;
default:
/* not a table header, so ignore it */
break ;
}
}
point = *start ;
free_spot(start) ;
}
/*=============================================================*/
/*=============================================================*/
short *gather_table_numbers(new_numbers)
short *new_numbers ;
{
int tcount[6] ;
char counter[5] ;
int old_number ;
int table_type ;
spot start = alloc_spot(1) ;
save_var case_fold = 0 ;
tcount[0] = tcount[1] = tcount[2] = tcount[3] = tcount[4] = tcount[5] = 0 ;
*start = point ;
point = 0 ;
while (search(1,"(Table "))
{
char *tbl ;
int table_offset ;
grab(point,point+4,counter) ;
tbl = index(table_ID_letters,counter[0]) ;
if (tbl)
table_offset = (tbl-table_ID_letters) ;
else
table_offset = 0 ;
old_number = strtoi(counter+1,10) + 1000*table_offset ;
table_type = (table_offset > 9) ? (table_offset-9) : 0 ;
new_numbers[old_number] = (short)++(tcount[table_type]) ;
}
point = *start ;
free_spot(start) ;
return new_numbers ;
}
/*=============================================================*/
/*=============================================================*/
int adjust_table_numbers(new_numbers, dangling)
short *new_numbers ;
int dangling ;
{
char counter[5] ;
int old_number ;
int old_type ;
char *tbl ;
int table_offset ;
spot start = alloc_spot(1) ;
*start = point ;
point = 0 ;
while (search(1,"(Table "))
{
grab(point,point+4,counter) ;
tbl = index(table_ID_letters,counter[0]) ;
if (tbl)
table_offset = 1000*(tbl-table_ID_letters) ;
else
table_offset = 0 ;
old_number = strtoi(counter+1,10) + table_offset ;
old_type = (counter[0] >= '0' && counter[0] <= '9') ? 0 : counter[0] ;
if (old_number > 0)
{
delete(point,point+4) ;
if (old_type)
bprintf("%c%03d",old_type,new_numbers[old_number]%1000) ;
else
bprintf("%04d",new_numbers[old_number]) ;
}
}
point = 0 ;
while (re_search(1,"[, \t]%#[0-9CFMP][0-9][0-9][0-9]"))
{
grab(point-4,point,counter) ;
tbl = index(table_ID_letters,counter[0]) ;
if (tbl)
table_offset = 1000*(tbl-table_ID_letters) ;
else
table_offset = 0 ;
old_number = strtoi(counter+1,10) + table_offset ;
old_type = (counter[0] >= '0' && counter[0] <= '9') ? 0 : counter[0] ;
if (old_number > 0)
{
if (new_numbers[old_number])
{
delete(point-4,point) ;
if (old_type)
bprintf("%c%03d",old_type,new_numbers[old_number]) ;
else
bprintf("%04d",new_numbers[old_number]) ;
}
else /* dangling xref */
{
dangling++ ;
point -= 4 ;
stuff("?") ;
point += 4 ;
}
}
}
point = *start ;
free_spot(start) ;
return dangling ;
}
/*=============================================================*/
/*=============================================================*/
int get_list_file(list_file)
char *list_file ;
{
char abs_filename[FNAMELEN] ;
strcpy(abs_filename,list_file) ;
absolute(abs_filename) ;
return find_it(abs_filename,1) ;
}
/*=============================================================*/
/*=============================================================*/
command renumber_tables()
{
short *new_numbers ;
int num_tables ;
int dangling ;
int i ;
for (i = 0 ; list_files[i] ; i++)
{
if (get_list_file(list_files[i]) == 0)
{
say("Renumber Pass 1: numbering unnumbered tables (%s)",
list_files[i]) ;
fix_unnumbered_tables() ;
}
else
say("Renumber Pass 1: forced to skip %s") ;
}
num_tables = 1000*strlen(table_ID_letters) ;
new_numbers = (short*)malloc(num_tables*sizeof(short)) ;
if (!new_numbers)
{
say("Out of memory!") ;
return ;
}
for (i = 0 ; i < num_tables ; i++)
new_numbers[i] = 0 ;
for (i = 0 ; list_files[i] ; i++)
{
if (get_list_file(list_files[i]) == 0)
{
say("Renumber Pass 2: gathering table numbers (%s)",
list_files[i]) ;
gather_table_numbers(new_numbers) ;
}
else
say("Renumber Pass 2: forced to skip %s") ;
}
dangling = 0 ;
for (i = 0 ; list_files[i] ; i++)
{
if (get_list_file(list_files[i]) == 0)
{
say("Renumber Pass 3: adjusting table numbers (%s)",
list_files[i]) ;
dangling = adjust_table_numbers(new_numbers,dangling) ;
}
else
say("Renumber Pass 3: forced to skip %s") ;
}
free(new_numbers) ;
if (dangling)
say("%d dangling cross-references, search for '#?'",dangling) ;
else
say("Done") ;
}
/*=============================================================*/
/*=============================================================*/
command make_distribution()
{
int i ;
for (i = 0 ; list_files[i] ; i++)
{
/* switch to proper buffer, or load if not yet in a buffer */
if (get_list_file(list_files[i]) == 0)
{
say("Setting divider lines (%s)",list_files[i]) ;
point = size() ;
while (point > 0)
if (!number_one_int())
break ;
}
}
renumber_tables() ;
save_all_buffers() ;
say("Ready for distribution") ;
point = 0 ;
/* !!! should also split main list automatically */
}
/*=============================================================*/
/*=============================================================*/
void find_table_counter()
{
save_var point = (size() > 10000) ? size() - 10000 : 0 ;
search(1,"Highest Table Number = ") ;
table_counter = alloc_spot(1) ;
}
/*=============================================================*/
/* Put the current buffer into IntList major mode */
/*=============================================================*/
command intlist_mode()
{
mode_keys = intlist_tab ;
intlist_tab[')'] = intlist_tab[']'] = (short) show_matching_delimiter;
delete_hacking_tabs = 0 ;
major_mode = strsave("IntList") ;
make_mode() ;
auto_indent = 0 ;
margin_right = 79 ;
want_backups = 1 ;
undo_size = 100000 ; /* less than default 500,000 since list is so big */
find_table_counter() ;
}
when_loading()
{
char *curbuf ;
want_backups = want_backups.default = 1 ;
strcpy(backup_name,"%pbak/%b%e") ; /* put backups in BAK subdir */
one_window() ;
intlist_mode() ;
if (exist("interrup.1st"))
{
curbuf = bufname ;
bufname = "interrup.1st" ;
intlist_mode() ;
bufname = curbuf ;
}
/* Epsilon v6.0+ */
strcpy(mode_end," %d%p %S") ;
}
/*=============================================================*/
/* automagically switch into interrupt list mode on .LST and .1ST files */
suffix_lst() { intlist_mode(); }
suffix_1st() { intlist_mode(); }
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/