include include # Default maximum number of characters in the output line define LINE_CHARS 80 # Maximum number of characters in the task name define NAME_CHARS 13 # Offset in characters, between the end of the task name # and the beginning of the description define DESC_OFFSET 3 # Offset, in characters, between the end of the description # and the package name define PACK_OFFSET 1 # Apropos environment variable name for apropos database specification define APROPOSDB "aproposdb" # Max length of the apropos database contents define SZ_APROPOSDB 512 # T_APROPOS -- Read a list of apropos database files (generated by mkapropos) # and search for the subject string in them. Print every line where the subject # string is found. procedure t_apropos () bool ignore # ignore case ? bool verbose # verbose output ? char subject[SZ_LINE] # subject string char aproposdb[SZ_APROPOSDB] # apropos database char name[SZ_FNAME] # database file name int list # database file list int fd # file descriptor bool clgetb() bool streq() int open() int fntopnb(), fntgfnb() int envgets() begin # Get task parameters call clgstr ("subject", subject, SZ_LINE) call clgstr ("aproposdb", aproposdb, SZ_APROPOSDB) ignore = clgetb ("ignore_case") verbose = clgetb ("verbose") # Open list if (streq (aproposdb, APROPOSDB)) { if (envgets (APROPOSDB, aproposdb, SZ_APROPOSDB) <= 0) call error (0, "apropos environment variable not found") } # Open list of apropos databases, and traverse it list = fntopnb (aproposdb, NO) while (fntgfnb (list, name, SZ_FNAME) != EOF) { # Try to open input file iferr (fd = open (name, READ_ONLY, TEXT_FILE)) { call erract (EA_WARN) next } # Print database file name if (verbose) { call printf ("-- %s\n") call pargstr (name) } # Process input file call apropos (fd, subject, ignore) # Flush STDOUT call flush (STDOUT) # Close file call close (fd) } # Close list call fntclsb (list) end # APROPOS - Read all lines of the apropos database file and print the lines # where the subject string is present. The output lines are formated to align # columns and to avoid line wrap around. procedure apropos (fd, subject, ignore) int fd # database file descriptor char subject[ARB] # subject string bool ignore # ignore subject case ? char line[SZ_LINE] # input line char task_name[SZ_LINE] # task name char description[SZ_LINE] # task description char package[SZ_LINE] # task package name char aux[SZ_LINE] int ncols # output line columns int len_name # name length int len_desc # description length int len_pack # package name length int ip, n int fscan() int strmatch(), ctowrd(), strlen() int envgeti() begin # Get terminal number of columns iferr (ncols = envgeti ("ttyncols")) ncols = LINE_CHARS # Loop over list file while (fscan (fd) != EOF) { # Read line call gargstr (line, SZ_LINE) # Test is case sensivity is required if (ignore) { aux[1] = CH_IGNORECASE aux[2] = EOS call strcat (subject, aux, SZ_LINE) } else call strcpy (subject, aux, SZ_LINE) # Test if the subject string is in the input line if (strmatch (line, aux) != 0) { # Break the line into task name, description # and package path. ip = 1 n = ctowrd (line, ip, task_name, SZ_LINE) n = ctowrd (line, ip, description, SZ_LINE) n = ctowrd (line, ip, package, SZ_LINE) # Compute string lengths len_name = strlen (task_name) len_desc = strlen (description) len_pack = strlen (package) # Build format string for task name and description # and print them call sprintf (aux, SZ_LINE, "%%%s%d%s%ds - %%%s%ds") call pargstr ("-") call pargi (NAME_CHARS) call pargstr (".") call pargi (NAME_CHARS) call pargstr (".") call pargi (ncols - NAME_CHARS - DESC_OFFSET) call printf (aux) call pargstr (task_name) call pargstr (description) # Print package name if (NAME_CHARS + len_desc + len_pack + DESC_OFFSET + PACK_OFFSET > ncols) { call sprintf (aux, SZ_LINE, "%s%%%d%ss%%s%s") call pargstr ("\n") call pargi (NAME_CHARS + DESC_OFFSET) call pargstr (".") call pargstr ("\n") call printf (aux) call pargstr (" ") call pargstr (package) } else { call printf (" %s\n") call pargstr (package) } } } end