/* Program Name : FILERDIF.C */ /* Original Author : C. K. Hung */ /* Date : 18-MAY-1991 */ /* Program Description : */ /* : */ /* Revision History follows */ #include "global.h" #include "diff.h" #include "dx.h" #include "filer.h" #include "filerdif.h" #include "inquire.h" #include #include /* **** INTERNAL FUNCTION PROTOTYPING *** */ static int filer_diff$2(char *, char *, char *); static int diff_read(TXTINF f[], int *n, char *m, char *dna, char *errmsg); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_diff() { if (DX_CURRENT_DIRECTORY.filemode == multiple) filer_multiple_diff(); else filer_single_diff(); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_multiple_diff() { char errmsg[MAXFILESPEC+1]; strcpy(errmsg, "Error comparing file"); multi_get_userinput_and_exec( filer_diff$1, "Multiple diff", "Compare with: ", "", errmsg); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_single_diff() { char errmsg[MAXFILESPEC+1]; char fn[MAXFILESPEC+1]; if (!strcmp(DX_CURRENT_FILE->fn, "[-]")) { signal_err("Compare 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 comparing file"); get_userinput_and_execute( filer_diff$1, "Compare File", "Compare with: ", "", errmsg, fn); } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_diff$1(to, from, errmsg) char *to; char *from; char *errmsg; { return filer_diff$2(from, to, errmsg); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ static int filer_diff$2(from, old_to, errmsg) char *from; char *old_to; char *errmsg; { TXTINF file1[MAXLINES]; int n1; TXTINF file2[MAXLINES]; int n2; unsigned long int display_id; unsigned short word_terminator_code; char result_string[255]; $DESCRIPTOR (result_string_descrip, result_string); int i; int vm_len; unsigned long old_mask; char to[MAXFILESPEC+1]; /* ** Do not update the user-specified diff TO filespec **/ strcpy(to, old_to); /* ** Read two files to be compared **/ if (diff_read (file1, &n1, from, from, errmsg) == -1 || diff_read (file2, &n2, to, from, errmsg) == -1) { return DX__ERROR; } /* ** Since compare() does not use SMG$ output routines to ** show the differences, need to save the current display ** and restore back after the comparison. **/ check_OK(smg$save_physical_screen ( &cntrl_info_block.pasteboard_id, &display_id, 0, 0)) check_OK(smg$set_physical_cursor ( &cntrl_info_block.pasteboard_id, &cntrl_info_block.pasteboard_rows, &1)) /* ** Set the signal back to system default so that it won't ** interfere with smg$read_keystroke() routine. **/ alarm(0); signal(SIGALRM, SIG_DFL); fprintf (stdout, "DX File Comparison Utility\n"); fprintf (stdout, " %s-\n", from); fprintf (stdout, " %s\n\n\n\n", to); /* ** Start the comparison of the two files. ** No paging mechanism is provided at present. **/ compare (from, file1, n1, to, file2, n2, LNGVAL); /* ** Free up the dynamic memory used by DIFF **/ for (i = 1; i <= n1; i++) { vm_len = file1[i].len+1; check_OK(lib$free_vm ( &vm_len, &(file1[i].content), 0)) } for (i = 1; i <= n2; i++) { vm_len = file2[i].len+1; check_OK(lib$free_vm ( &vm_len, &(file2[i].content), 0)) } /* ** Prompt for user input. ** CTRL/Y cancel multiple DIFF operations. All other key ** puts the user back to DX. **/ sleep(2); fprintf ( stdout, "\n\n\nPress RETURN to continue -or- CTRL/Y to cancel multiple DIFF "); check_OK(lib$disable_ctrl ( &LIB$M_CLI_CTRLY, &old_mask)) smg$read_keystroke ( &cntrl_info_block.keyboard_id, &word_terminator_code, 0, 0, 0, 0, 0); check_OK(lib$enable_ctrl ( &old_mask, 0)) /* ** Cleanup and exit **/ check_OK(smg$restore_physical_screen ( &cntrl_info_block.pasteboard_id, &display_id)) if (word_terminator_code == SMG$K_TRM_CTRLY) { strcpy(errmsg, "DIFF canceled by request"); return DX__DONTCARE; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ static int diff_read(TXTINF f[], int *n, char *m, char *dna, char *errmsg) { struct FAB fab; struct RAB rab; struct NAM nam; unsigned long retcode; long vm_len; char s[MAXCHARS+1]; char *t; char resultant_name[NAM$C_MAXRSS]; /** Initialize File FAB **/ fab = cc$rms_fab; nam = cc$rms_nam; fab.fab$l_fna = m; fab.fab$b_fns = strlen(m); fab.fab$l_dna = dna; fab.fab$b_dns = strcspn(dna, ";")+1; /** Default to highest version **/ fab.fab$l_nam = &nam; nam.nam$l_rsa = &resultant_name; nam.nam$b_rss = NAM$C_MAXRSS; /** Initialize Source File RAB **/ rab = cc$rms_rab; rab.rab$l_fab = &fab; rab.rab$b_rac = RAB$C_SEQ; rab.rab$l_ubf = s; rab.rab$w_usz = MAXCHARS; /** Open and file **/ if ((retcode = sys$open (&fab, 0, 0)) != RMS$_NORMAL || (retcode = sys$connect (&rab, 0, 0)) != RMS$_NORMAL) { sys$close(&fab, 0, 0); sprintf(errmsg, "Error opening %s as input file", m); return DX__ERROR; } resultant_name[nam.nam$b_rsl] = EOS; strcpy(m, resultant_name); *n = 0; while ((retcode = sys$get(&rab, 0, 0)) != RMS$_EOF) { if (*n >= MAXLINES) { sprintf (errmsg, "File %s too big", m); sys$close (&fab, 0, 0); return DX__ERROR; } vm_len = rab.rab$w_rsz + 1; if ((retcode = lib$get_vm ( &vm_len, &t, 0)) != SS$_NORMAL) { strcpy(errmsg, "Error allocating virtual memory - exceeded quota"); sys$close (&fab, 0, 0); return DX__ERROR; } memcpy (t, s, rab.rab$w_rsz); t[rab.rab$w_rsz] = EOS; f[++(*n)].content = t; f[*n].len = rab.rab$w_rsz; } sys$close (&fab, 0, 0); return DX__NORMAL; }