/* Program Name : FILERFND.C */ /* Original Author : C. K. Hung */ /* Date : 18-MAY-1991 */ /* Program Description : */ /* : */ /* Revision History follows */ #include "global.h" #include "dx.h" #include "filer.h" #include "filerfnd.h" #include "filertyp.h" #include "inquire.h" #include #include /* **** MACROS *** */ #define MAXLINES 65535 /* **** INTERNAL FUNCTION PROTOTYPING *** */ static int filer_find_by_page(struct FAB, unsigned long, unsigned long, unsigned short int *, char *, char *); static int filer_find_no_page(struct FAB, unsigned long, unsigned long, unsigned short int *, char *, char *); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_find() { if (DX_CURRENT_DIRECTORY.filemode == multiple) filer_multiple_find(); else filer_single_find(); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_multiple_find() { char dummy[] = ""; char errmsg[MAXFILESPEC+1]; strcpy(errmsg, "Error searching string"); multi_get_userinput_and_exec( filer_find$1, "Multiple Find", "Find what? ", "", errmsg); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_single_find() { char dummy[] = ""; char errmsg[MAXFILESPEC+1]; char fn[MAXFILESPEC+1]; if (!strcmp(DX_CURRENT_FILE->fn, "[-]")) { signal_err("Search a parent directory file not allowed", bell); } else { find_full_path_name(DX_CURRENT_FILE->fn, fn, cntrl_info_block.cur_win); strcpy(errmsg, "Error searching string"); get_userinput_and_execute( filer_find$1, "Search String", "Find what? ", "", errmsg, fn); } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_find$1(pattern, from, errmsg) char *pattern; char *from; char *errmsg; { return filer_type$2 ( from, errmsg, pattern, (cntrl_info_block.user_pref.type_by_page? filer_find_by_page : filer_find_no_page)); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ static int filer_find_by_page(from_fab, filer_find1_display_id, filer_find2_display_id, word_terminator_code, errmsg, pattern) struct FAB from_fab; unsigned long filer_find1_display_id, filer_find2_display_id; unsigned short int *word_terminator_code; char *errmsg; char *pattern; { char linebuf[BUFSIZ+1]; $DESCRIPTOR (linebuf_descrip, linebuf); char rendition_set[BUFSIZ+1]; $DESCRIPTOR (rendition_set_descrip, rendition_set); struct RAB from_rab; int filer_find1_bottom = cntrl_info_block.pasteboard_rows-2; unsigned long old_mask; int lastline, linepos; char errmsg1[MAXFILESPEC+1]; $DESCRIPTOR (errmsg1_descrip, errmsg1); unsigned short int len; unsigned long retcode; char *base_address; char *lines[MAXLINES], *attrs[MAXLINES]; int allocate_size; int count; int total_found; char upcase_string[BUFSIZ+1]; $DESCRIPTOR (upcase_string_descrip, upcase_string); char *start, *cp; int eof_flag = 0; int file_lines; int filer_find2_pasteboard_row = cntrl_info_block.pasteboard_rows-1; /* ** Trap broadcast messages **/ check_OK(smg$set_broadcast_trapping ( &cntrl_info_block.pasteboard_id, broadcast_routine, 0)) /* ** Initialize Source File RAB **/ from_rab = cc$rms_rab; from_rab.rab$l_fab = &from_fab; from_rab.rab$b_rac = RAB$C_SEQ; from_rab.rab$l_ubf = linebuf; from_rab.rab$w_usz = BUFSIZ; if ((retcode = sys$connect ( &from_rab, 0, 0)) != RMS$_NORMAL) { lib$sys_getmsg ( &retcode, &len, &errmsg1_descrip, 0, 0); errmsg1[len] = EOS; strcpy(errmsg, errmsg1); return DX__ERROR; } len = strlen(pattern); /* ** Set the signal back to system default so that it won't ** interfere with smg$read_keystroke() routine. ** Reset display attributes to avoid SMG$PUT_LINE_MULTI bugs. **/ alarm(0); signal(SIGALRM, SIG_DFL); check_OK(smg$change_virtual_display ( &filer_find1_display_id, 0, 0, &0, 0, 0)) file_lines = total_found = lastline = 0; /* ** Display the first page and wait for user response **/ retcode = sys$get ( &from_rab, 0, 0); count = 1; while (count <= filer_find1_bottom) { if (retcode == RMS$_EOF && total_found > 0) { eof_flag++; LENGTH(rendition_set_descrip) = 0; check_OK(smg$put_line_multi ( &filer_find1_display_id, $DESCR (""), &rendition_set_descrip, 0, 0, 0, 0, 0)) check_OK(lib$get_vm ( &1, &base_address, 0)) base_address[0] = EOS; lines[lastline] = base_address; check_OK(lib$get_vm ( &1, &base_address, 0)) base_address[0] = SMG$M_NORMAL; attrs[lastline] = base_address; lastline++; sprintf(linebuf, "%s - %d line%s, %d match%s", from_fab.fab$l_fna, file_lines, (file_lines > 1? "s" : ""), total_found, (total_found > 1? "s" : "")); LENGTH(linebuf_descrip) = strlen(linebuf); memset(rendition_set, SMG$M_NORMAL, strlen(linebuf)); LENGTH(rendition_set_descrip) = strlen(linebuf); check_OK(smg$put_line_multi ( &filer_find1_display_id, &linebuf_descrip, &rendition_set_descrip, 0, 0, 0, 0, 0)) allocate_size = strlen(linebuf)+1; check_OK(lib$get_vm ( &allocate_size, &base_address, 0)) memcpy(base_address, linebuf, allocate_size-1); base_address[allocate_size-1] = EOS; lines[lastline] = base_address; check_OK(lib$get_vm ( &allocate_size, &base_address, 0)) memset(base_address, SMG$M_NORMAL, allocate_size-1); base_address[allocate_size-1] = EOS; attrs[lastline] = base_address; lastline++; break; } else if (retcode != RMS$_NORMAL) { lib$sys_getmsg ( &retcode, &len, &errmsg1_descrip, 0, 0); errmsg1[len] = EOS; strcpy(errmsg, errmsg1); goto free_vm; } file_lines++; linebuf[from_rab.rab$w_rsz] = EOS; LENGTH(linebuf_descrip) = from_rab.rab$w_rsz; memset(rendition_set, SMG$M_NORMAL, (size_t) from_rab.rab$w_rsz); LENGTH(rendition_set_descrip) = from_rab.rab$w_rsz; str$upcase ( &upcase_string_descrip, &linebuf_descrip); upcase_string[from_rab.rab$w_rsz] = EOS; for (start = upcase_string; cp = strstr(start, pattern); start = cp+1) { total_found++; memset(rendition_set+(cp-upcase_string), SMG$M_BOLD, (size_t) len); } if (start != upcase_string) { if (lastline == 0) { check_OK(smg$paste_virtual_display ( &filer_find1_display_id, &cntrl_info_block.pasteboard_id, &FILER_TYPE1_PBD_ROW, &FILER_TYPE1_PBD_COLUMN, 0)) check_OK(smg$paste_virtual_display ( &filer_find2_display_id, &cntrl_info_block.pasteboard_id, &filer_find2_pasteboard_row, &FILER_TYPE2_PBD_COLUMN, 0)) } smg$put_line_multi ( &filer_find1_display_id, &linebuf_descrip, &rendition_set_descrip, 0, 0, 0, 0, 0); allocate_size = (int) from_rab.rab$w_rsz+1; check_OK(lib$get_vm ( &allocate_size, &base_address, 0)) memcpy(base_address, linebuf, from_rab.rab$w_rsz); base_address[allocate_size-1] = EOS; lines[lastline] = base_address; check_OK(lib$get_vm ( &allocate_size, &base_address, 0)) memcpy(base_address, rendition_set, from_rab.rab$w_rsz); base_address[allocate_size-1] = EOS; attrs[lastline] = base_address; lastline++; count++; } retcode = sys$get ( &from_rab, 0, 0); } /* ** Return to caller immediately if none found **/ if (total_found == 0) { return DX__NORMAL; } smg$put_chars ( &filer_find2_display_id, $DESCR ( "Press ARROW KEYS for prev or next -or- keypad 0 and CTRL/Y to cancel"), &FILER_TYPE2_BOTTOM, &1, 0, &SMG$M_REVERSE, 0, 0); smg$read_keystroke ( &cntrl_info_block.keyboard_id, word_terminator_code, 0, 0, &filer_find2_display_id, 0, 0); check_OK(smg$erase_line ( &filer_find2_display_id, &FILER_TYPE2_BOTTOM, &1)) linepos = 1; /* ** Keep typing until exit by the user **/ while (*word_terminator_code != SMG$K_TRM_CTRLY && *word_terminator_code != SMG$K_TRM_CTRLC && *word_terminator_code != SMG$K_TRM_KP0 && *word_terminator_code != SMG$K_TRM_CTRLZ) { switch (*word_terminator_code) { case SMG$K_TRM_UP : if (linepos == 1) { check_OK(smg$ring_bell ( &filer_find1_display_id, 0)) } else { for (count = filer_find1_bottom; count > 1 && linepos > 1; count--) { linepos--; strcpy(linebuf, lines[linepos-1]); LENGTH(linebuf_descrip) = strlen(linebuf); memcpy(rendition_set, attrs[linepos-1], strlen(linebuf)); LENGTH(rendition_set_descrip) = strlen(linebuf); smg$scroll_display_area ( &filer_find1_display_id, 0, 0, 0, 0, &SMG$M_DOWN, 0); smg$put_chars_multi ( &filer_find1_display_id, &linebuf_descrip, &1, &1, &SMG$M_ERASE_TO_EOL, &rendition_set_descrip, 0, 0); } } break; case SMG$K_TRM_DOWN: case SMG$K_TRM_CR : if (linepos+filer_find1_bottom-1 >= lastline && retcode == RMS$_EOF) { check_OK(smg$ring_bell ( &filer_find1_display_id, 0)) } else { count = filer_find1_bottom; while (count > 1) { if (linepos+filer_find1_bottom-1 < lastline) { linepos++; strcpy( linebuf, lines[linepos+filer_find1_bottom-2]); LENGTH(linebuf_descrip) = strlen(linebuf); memcpy( rendition_set, attrs[linepos+filer_find1_bottom-2], strlen(linebuf)); LENGTH(rendition_set_descrip) = strlen(linebuf); smg$scroll_display_area ( &filer_find1_display_id, 0, 0, 0, 0, &SMG$M_UP, 0); smg$put_chars_multi ( &filer_find1_display_id, &linebuf_descrip, &filer_find1_bottom, &1, &SMG$M_ERASE_TO_EOL, &rendition_set_descrip, 0, 0); count--; } else if (retcode == RMS$_EOF) { if (!eof_flag) { eof_flag++; LENGTH(rendition_set_descrip) = 0; smg$scroll_display_area ( &filer_find1_display_id, 0, 0, 0, 0, &SMG$M_UP, 0); smg$put_chars_multi ( &filer_find1_display_id, $DESCR (""), &filer_find1_bottom, &1, &SMG$M_ERASE_TO_EOL, &rendition_set_descrip, 0, 0); check_OK(lib$get_vm ( &1, &base_address, 0)) base_address[0] = EOS; lines[lastline] = base_address; check_OK(lib$get_vm ( &1, &base_address, 0)) base_address[0] = SMG$M_NORMAL; attrs[lastline] = base_address; linepos++; lastline++; sprintf(linebuf, "%s - %d line%s, %d match%s", from_fab.fab$l_fna, file_lines, (file_lines > 1? "s" : ""), total_found, (total_found > 1? "s" : "")); LENGTH(linebuf_descrip) = strlen(linebuf); memset(rendition_set, SMG$M_NORMAL, strlen(linebuf)); LENGTH(rendition_set_descrip) = strlen(linebuf); smg$scroll_display_area ( &filer_find1_display_id, 0, 0, 0, 0, &SMG$M_UP, 0); smg$put_chars_multi ( &filer_find1_display_id, &linebuf_descrip, &filer_find1_bottom, &1, &SMG$M_ERASE_TO_EOL, &rendition_set_descrip, 0, 0); allocate_size = strlen(linebuf)+1; check_OK(lib$get_vm ( &allocate_size, &base_address, 0)) memcpy(base_address, linebuf, allocate_size-1); base_address[allocate_size-1] = EOS; lines[lastline] = base_address; check_OK(lib$get_vm ( &allocate_size, &base_address, 0)) memset(base_address, SMG$M_NORMAL, allocate_size-1); base_address[allocate_size-1] = EOS; attrs[lastline] = base_address; linepos++; lastline++; } break; } else if (retcode != RMS$_NORMAL) { lib$sys_getmsg ( &retcode, &len, &errmsg1_descrip, 0, 0); errmsg1[len] = EOS; strcpy(errmsg, errmsg1); goto free_vm; } else { file_lines++; linebuf[from_rab.rab$w_rsz] = EOS; LENGTH(linebuf_descrip) = from_rab.rab$w_rsz; memset(rendition_set, SMG$M_NORMAL, (size_t) from_rab.rab$w_rsz); LENGTH(rendition_set_descrip) = from_rab.rab$w_rsz; str$upcase ( &upcase_string_descrip, &linebuf_descrip); upcase_string[from_rab.rab$w_rsz] = EOS; for (start = upcase_string; cp = strstr(start, pattern); start = cp+1) { total_found++; memset(rendition_set+(cp-upcase_string), SMG$M_BOLD, (size_t) len); } if (start != upcase_string) { smg$scroll_display_area ( &filer_find1_display_id, 0, 0, 0, 0, &SMG$M_UP, 0); smg$put_chars_multi ( &filer_find1_display_id, &linebuf_descrip, &filer_find1_bottom, &1, &SMG$M_ERASE_TO_EOL, &rendition_set_descrip, 0, 0); allocate_size = (int) from_rab.rab$w_rsz+1; check_OK(lib$get_vm ( &allocate_size, &base_address, 0)) memcpy(base_address, linebuf, from_rab.rab$w_rsz); base_address[allocate_size-1] = EOS; lines[lastline] = base_address; check_OK(lib$get_vm ( &allocate_size, &base_address, 0)) memcpy(base_address, rendition_set, from_rab.rab$w_rsz); base_address[allocate_size-1] = EOS; attrs[lastline] = base_address; count--; lastline++; linepos++; } retcode = sys$get ( &from_rab, 0, 0); } } } break; case SMG$K_TRM_CTRLW: check_OK(smg$repaint_screen ( &cntrl_info_block.pasteboard_id)) break; default: if (*word_terminator_code != SMG$K_TRM_CANCELLED) { /** Returned from broadcast message trapping **/ check_OK(smg$ring_bell ( &filer_find1_display_id, 0)) } break; } check_OK(smg$put_chars ( &filer_find2_display_id, $DESCR ( "Press ARROW KEYS for prev or next -or- keypad 0 and CTRL/Y to cancel"), &FILER_TYPE2_BOTTOM, &1, 0, &SMG$M_REVERSE, 0, 0)) smg$read_keystroke ( &cntrl_info_block.keyboard_id, word_terminator_code, 0, 0, &filer_find2_display_id, 0, 0); check_OK(smg$erase_line ( &filer_find2_display_id, &FILER_TYPE2_BOTTOM, &1)) } free_vm: for (count = 0; count < lastline; count++) { allocate_size = strlen(lines[count])+1; check_OK(lib$free_vm ( &allocate_size, &lines[count], 0)) check_OK(lib$free_vm ( &allocate_size, &attrs[count], 0)) } return (retcode == RMS$_NORMAL || retcode == RMS$_EOF? DX__NORMAL : DX__ERROR); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ static int filer_find_no_page(from_fab, filer_find1_display_id, filer_find2_display_id, word_terminator_code, errmsg, pattern) struct FAB from_fab; unsigned long filer_find1_display_id, filer_find2_display_id; unsigned short int *word_terminator_code; char *errmsg; char *pattern; { char linebuf[BUFSIZ+1]; $DESCRIPTOR (linebuf_descrip, linebuf); char rendition_set[BUFSIZ+1]; $DESCRIPTOR (rendition_set_descrip, rendition_set); struct RAB from_rab; char errmsg1[MAXFILESPEC+1]; $DESCRIPTOR (errmsg1_descrip, errmsg1); unsigned short int len; unsigned long retcode; int total_found; int lines; char upcase_string[BUFSIZ+1]; $DESCRIPTOR (upcase_string_descrip, upcase_string); char *start, *cp; int filer_find2_pasteboard_row = cntrl_info_block.pasteboard_rows-1; /* ** Initialize Source File RAB **/ from_rab = cc$rms_rab; from_rab.rab$l_fab = &from_fab; from_rab.rab$b_rac = RAB$C_SEQ; from_rab.rab$l_ubf = linebuf; from_rab.rab$w_usz = BUFSIZ; if ((retcode = sys$connect ( &from_rab, 0, 0)) != RMS$_NORMAL) { lib$sys_getmsg ( &retcode, &len, &errmsg1_descrip, 0, 0); errmsg1[len] = EOS; strcpy(errmsg, errmsg1); return DX__ERROR; } len = strlen(pattern); /* ** Set the signal back to system default so that it won't ** interfere with smg$read_keystroke() routine. ** Reset display attributes to avoid SMG$PUT_LINE_MULTI bugs. **/ alarm(0); signal(SIGALRM, SIG_DFL); check_OK(smg$change_virtual_display ( &filer_find1_display_id, 0, 0, &0, 0, 0)) check_OK(smg$paste_virtual_display ( &filer_find1_display_id, &cntrl_info_block.pasteboard_id, &FILER_TYPE1_PBD_ROW, &FILER_TYPE1_PBD_COLUMN, 0)) check_OK(smg$paste_virtual_display ( &filer_find2_display_id, &cntrl_info_block.pasteboard_id, &filer_find2_pasteboard_row, &FILER_TYPE2_PBD_COLUMN, 0)) total_found = lines = 0; while ((retcode = sys$get( &from_rab, 0, 0)) != RMS$_EOF) { if (retcode != RMS$_NORMAL) { lib$sys_getmsg ( &retcode, &len, &errmsg1_descrip, 0, 0); errmsg1[len] = EOS; strcpy(errmsg, errmsg1); return DX__ERROR; } lines++; linebuf[from_rab.rab$w_rsz] = EOS; LENGTH(linebuf_descrip) = from_rab.rab$w_rsz; memset(rendition_set, SMG$M_NORMAL, (size_t) from_rab.rab$w_rsz); rendition_set[from_rab.rab$w_rsz] = EOS; LENGTH(rendition_set_descrip) = from_rab.rab$w_rsz; str$upcase ( &upcase_string_descrip, &linebuf_descrip); upcase_string[from_rab.rab$w_rsz] = EOS; for (start = upcase_string; cp = strstr(start, pattern); start = cp+1) { total_found++; memset(rendition_set+(cp-upcase_string), SMG$M_BOLD, (size_t) len); } if (start != upcase_string) { smg$put_line_multi ( &filer_find1_display_id, &linebuf_descrip, &rendition_set_descrip, 0, 0, 0, 0, 0); } } /* ** Return to caller immediately if none found **/ if (total_found == 0) { return DX__NORMAL; } smg$put_line ( &filer_find1_display_id, $DESCR (""), 0, 0, 0, 0, 0, 0); sprintf(linebuf, "%s - %d line%s, %d match%s", from_fab.fab$l_fna, lines, (lines > 1? "s" : ""), total_found, (total_found > 1? "s" : "")); POINTER(linebuf_descrip) = linebuf; LENGTH(linebuf_descrip) = strlen(linebuf); smg$put_line ( &filer_find1_display_id, &linebuf_descrip, 0, 0, 0, 0, 0, 0); smg$put_chars ( &filer_find2_display_id, $DESCR ("Press RETURN to continue -or- keypad 0 and CTRL/Y to cancel"), &FILER_TYPE2_BOTTOM, &1, 0, &SMG$M_REVERSE, 0, 0); smg$read_keystroke ( &cntrl_info_block.keyboard_id, word_terminator_code, 0, 0, &filer_find2_display_id, 0, 0); smg$erase_line ( &filer_find2_display_id, &FILER_TYPE2_BOTTOM, &1); return DX__NORMAL; }