% mkdoc.sl % % Extract documentation from .sl and .c files % For this to work, a strict format must be followed. % In .c files, add_intrinsic and add_variable statements are checked. The % syntax prototype is: % % MAKE_INTRINSIC("name", function, TYPE, n)% % /* This is a function called name which returns TYPE % and takes n arguments. */ % % Note that it is assummed that comments cannot be nested. % For .sl files, the syntax follows: % % %!% This function pops an integer n off the stack and an object s. % %!% It returns n copies of s on the stack. % define dupn (n, s) % { % loop (n) { s; } % } % % Here I search for '%!%' in column 1 which make indicate a doc string and % then search for 'define' preceed by only whitespace. The '%!%' must start in % column 1. % % There is no ambiguity as long as the doc strings are placed BEFORE the % object they describe. %!% Extracts do string from FILE and appends it to BUFFER. %!% Returns 0 upon failure. . ( . [file doc_buf cbuf] =doc_buf =file . [doc_ind] "%!%" =doc_ind . [chars] "a-zA-Z0-9_$!" =chars . [c] . [name ctrlm] 1 char =ctrlm . . file read_file {0 return} !if . whatbuf =cbuf . . bob . . { doc_ind bol_fsearch } . { . doc_buf setbuf . eob . bolp {newline} !if . push_spot . cbuf setbuf . . 3 right pop push_mark . {1 down bol doc_ind looking_at and}{} while . doc_buf copy_region . . . % now look for what this documents . { . bol " \t\n" skip_chars what_char =c . "variable" looking_at . { . "variable" strlen go_right . skip_white push_mark . chars skip_chars "V" bufsubstr strcat " " strcat =name . break . } if . . "define" looking_at . { . "define" strlen go_right . skip_white . push_mark . chars skip_chars . ")" ffind { 1 go_right } if . "F" bufsubstr strcat =name . break . } if . . 1 down {"Error parsing " file strcat error} !if . } forever . . %% now we have the name with the appropriate prefix. Insert it and . %% replace newlines with ctrl-M . doc_buf setbuf . pop_spot name insert . ctrlm insert . {eol eobp not}{del ctrlm insert} while . newline . . cbuf setbuf . } while . 1 . ) mkdoc_process_sl_file . . %% same routine for C files. Looks for MAKE_INTRINSIC and MAKE_VARIABLE . %% macros. . ( . [file doc_buf cbuf] =doc_buf =file . [f v name ctrlm c] 1 char =ctrlm . . file read_file {0 return} !if . whatbuf =cbuf . . bob . . { . 0 =f 0 =v . "MAKE_" fsearch . { . "MAKE_INTRINSIC" looking_at =f . "MAKE_VARIABLE" looking_at =v . }{break} else . . POINT bol skip_white . POINT - {eol continue} if %%continue if in middle of line . %% found . . doc_buf setbuf . eob . bolp {newline} !if . cbuf setbuf . . %% formats are MAKE_INTRINSIC(".fun", cfun, TYPE, n) . %% and MAKE_VARIABLE(".var", &c_var, TYPE, flag) . %% where the & may not be present for string variables . . "\"." ffind {"Corrupt file." error} !if . 2 right pop push_mark . "\"" ffind {"Corrupt file." error} !if . bufsubstr " " strcat =name . 1 right pop . . %% if it is a function, get the c function info as well . f { . "F" name strcat ":" strcat =name %%Ffun: . ",\t " skip_chars . push_mark "$_A-Za-z0-9" skip_chars . name bufsubstr strcat ":" strcat %%Ffun:cfun: . ",\t " skip_chars . what_char char strcat ":" strcat %%Ffun:cfun:T: . "," ffind pop %% assume ok . ", \t" skip_chars push_mark "0-9" skip_chars . bufsubstr strcat =name %%Whew!! %%Ffun:cfun:T:0 . }{ . "V" name strcat =name . } . else . . doc_buf setbuf name insert push_spot . cbuf setbuf . . %% look for documentation . {1 down} . { . bol skip_white eolp {continue} if . "/*" looking_at {break} !if . 2 right pop . what_column =c . push_mark . "*/" fsearch pop %% I assume it compiled . . doc_buf copy_region . doc_buf setbuf . pop_spot . push_spot . {1 down} . { . bol skip_white . "*" looking_at {del skip_white} if . what_column bol trim c - {" " insert} loop . } . while . pop_spot . ctrlm insert . {eol eobp not} . {del ctrlm insert} while . newline . cbuf setbuf . break . } while . } forever . 1 . ) mkdoc_process_c_file . . . %%% Make documentation for set of files. Function takes as top argument . %%% the name of docfile to be produced followed by number n of files . %%% then followed by the n filenames. . ( . [docfile] =docfile . [argc argv] =argc . [docbuf cbuf] whatbuf =cbuf . [type] . . docfile setbuf erase_buffer . whatbuf =docbuf . cbuf setbuf . . argc . { . =argv . argv file_type =type . "processing " argv strcat flush . type . {"c" strcmp not type "C" strcmp not or . type "ci" strcmp not or : . argv docbuf mkdoc_process_c_file . { argv " could not be processed!" strcat error } !if . } . {"sl" strcmp not type "SL" strcmp not or : . argv docbuf mkdoc_process_sl_file . { argv " could not be processed!" strcat error } !if . } . {" File type not supported!" strcat error} . switch . whatbuf docbuf strcmp {whatbuf delbuf} if . } . loop . . . docbuf setbuf . docfile write_buffer {"Unable to write doc file!" error} !if . 0 set_buffer_modified_flag docbuf delbuf . cbuf setbuf . ) mkdoc . . _stkdepth =$1 . "site.sl" "buf.sl" "help.sl" "util.sl" "dired.sl" "most.sl" "fortran.sl" . "../src/intrin.c" "../src/xterm.c" . "../../slang/src/slang.c" "../../slang/src/slstd.c" . "../../slang/src/slmath.c" #ifdef UNIX . "../../slang/src/slunix.c" #endif . _stkdepth $1 - . % number of files listed above . . "jed_funs.hlp" mkdoc . exit_jed