📄 textsw_file.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)textsw_file.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. *//* * File load/save/store utilities for text subwindows. */ #include <suntool/primal.h>#include <suntool/textsw_impl.h>#include <sys/dir.h>#include <sys/stat.h>#include <sys/vfs.h>#include <sys/param.h>#include <suntool/alert.h>#include <suntool/frame.h>#include <errno.h>#include <suntool/expand_name.h>extern char *strcat();extern char *strncat();extern char *getwd();extern int errno, sys_nerr;extern char *sys_errlist[];static int textsw_menu_style_already_gotten;static Textsw_enum textsw_menu_style;static int textsw_change_directory();pkg_private void textsw_display(), textsw_display_view_margins();pkg_private void textsw_input_before();pkg_private void textsw_init_undo(), textsw_replace_esh();pkg_private Es_index textsw_input_after();extern Es_status es_copy();extern Textsw_enum textsw_get_menu_style_internal();unsigned tmtn_counter;statictextsw_make_temp_name(in_here) char *in_here;/* *in_here must be at least MAXNAMLEN characters long */{ /* BUG ALERT! Should be able to specify directory other than * /tmp. However, if that directory is not /tmp it should * be a local (not NFS) directory and will make finding files * that need to be replayed after crash harder - assuming we * ever implement replay. */ in_here[0] = '\0'; (void) sprintf(in_here, "%s/Text%d.%d", "/tmp", getpid(), tmtn_counter++);}#define ES_BACKUP_FAILED ES_CLIENT_STATUS(0)#define ES_BACKUP_OUT_OF_SPACE ES_CLIENT_STATUS(1)#define ES_CANNOT_GET_NAME ES_CLIENT_STATUS(2)#define ES_CANNOT_OPEN_OUTPUT ES_CLIENT_STATUS(3)#define ES_CANNOT_OVERWRITE ES_CLIENT_STATUS(4)#define ES_DID_NOT_CHECKPOINT ES_CLIENT_STATUS(5)#define ES_PIECE_FAIL ES_CLIENT_STATUS(6)#define ES_SHORT_READ ES_CLIENT_STATUS(7)#define ES_UNKNOWN_ERROR ES_CLIENT_STATUS(8)#define ES_USE_SAVE ES_CLIENT_STATUS(9)#define TXTSW_LRSS_MASK 0x00000007pkg_private Es_handletextsw_create_ps(folio, original, scratch, status) Textsw_folio folio; register Es_handle original, scratch; Es_status *status;{ register Es_handle result; result = folio->es_create(folio->client_data, original, scratch); if (result) { *status = ES_SUCCESS; } else { es_destroy(original); es_destroy(scratch); *status = ES_PIECE_FAIL; } return(result);}pkg_private Es_handletextsw_create_file_ps(folio, name, scratch_name, status) Textsw_folio folio; char *name, *scratch_name; Es_status *status;/* *scratch_name must be at least MAXNAMLEN characters long, and is modified */{ extern Es_handle es_file_create(); register Es_handle original_esh, scratch_esh, piece_esh; original_esh = es_file_create(name, 0, status); if (!original_esh) return(ES_NULL); textsw_make_temp_name(scratch_name); scratch_esh = es_file_create(scratch_name, ES_OPT_APPEND|ES_OPT_OVERWRITE, status); if (!scratch_esh) { es_destroy(original_esh); return(ES_NULL); } (void) es_set(scratch_esh, ES_FILE_MODE, 0600, 0); piece_esh = textsw_create_ps(folio, original_esh, scratch_esh, status); return(piece_esh);}#define TXTSW_LFI_CLEAR_SELECTIONS 0x1pkg_private Es_statustextsw_load_file_internal( textsw, name, scratch_name, piece_esh, start_at, flags) register Textsw_folio textsw; char *name, *scratch_name; Es_handle *piece_esh; Es_index start_at; int flags;/* *scratch_name must be at least MAXNAMLEN characters long, and is modified */{ Es_status status; *piece_esh = textsw_create_file_ps(textsw, name, scratch_name, &status); if (status == ES_SUCCESS) { if (flags & TXTSW_LFI_CLEAR_SELECTIONS) { Textsw abstract = VIEW_REP_TO_ABS(textsw->first_view); textsw_set_selection(abstract, ES_INFINITY, ES_INFINITY, EV_SEL_PRIMARY); textsw_set_selection(abstract, ES_INFINITY, ES_INFINITY, EV_SEL_SECONDARY); } textsw_replace_esh(textsw, *piece_esh); if (start_at != ES_CANNOT_SET) { (void) ev_set(textsw->views->first_view, EV_FOR_ALL_VIEWS, EV_DISPLAY_LEVEL, EV_DISPLAY_NONE, EV_DISPLAY_START, start_at, EV_DISPLAY_LEVEL, EV_DISPLAY, 0); textsw_notify(textsw->first_view, TEXTSW_ACTION_LOADED_FILE, name, 0); textsw_update_scrollbars(textsw, TEXTSW_VIEW_NULL); } } return(status);}pkg_private voidtextsw_destroy_esh(folio, esh) register Textsw_folio folio; register Es_handle esh;{ Es_handle original_esh, scratch_esh; if (folio->views->esh == esh) folio->views->esh = ES_NULL; if (original_esh = (Es_handle)LINT_CAST(es_get(esh, ES_PS_ORIGINAL))) { textsw_give_shelf_to_svc(folio); scratch_esh = (Es_handle)LINT_CAST(es_get(esh, ES_PS_SCRATCH)); es_destroy(original_esh); if (scratch_esh) es_destroy(scratch_esh); } es_destroy(esh);}pkg_private voidtextsw_replace_esh(textsw, new_esh) register Textsw_folio textsw; Es_handle new_esh;/* Caller is repsonsible for actually repainting the views. */{ Es_handle save_esh = textsw->views->esh; int undo_count = textsw->undo_count; (void) ev_set(textsw->views->first_view, EV_DISPLAY_LEVEL, EV_DISPLAY_NONE, EV_CHAIN_ESH, new_esh, 0); textsw->state &= ~TXTSW_EDITED; textsw_destroy_esh(textsw, save_esh); /* Following two calls are inefficient textsw_re-init_undo. */ textsw_init_undo(textsw, 0); textsw_init_undo(textsw, undo_count); textsw->state &= ~TXTSW_READ_ONLY_ESH; if (textsw->notify_level & TEXTSW_NOTIFY_SCROLL) { register Textsw_view view; FORALL_TEXT_VIEWS(textsw, view) { textsw_display_view_margins(view, RECT_NULL); } }}pkg_private Es_handletextsw_create_mem_ps(folio, original) Textsw_folio folio; register Es_handle original;{ Es_handle es_mem_create(); register Es_handle scratch; Es_status status; Es_handle ps_esh = ES_NULL; if (original == ES_NULL) goto Return; scratch = es_mem_create(folio->es_mem_maximum, ""); if (scratch == ES_NULL) { es_destroy(original); goto Return; } ps_esh = textsw_create_ps(folio, original, scratch, &status);Return: return(ps_esh);}/* Returns 0 iff load succeeded (can do cd instead of load). */pkg_private inttextsw_load_selection(folio, locx, locy, no_cd) register Textsw_folio folio; register int locx, locy; int no_cd;{ char filename[MAXNAMLEN]; register int result; if (textsw_get_selection_as_filename( folio, filename, sizeof(filename), locx, locy)) { return(-10); } result = no_cd ? -2 : textsw_change_directory(folio, filename, TRUE, locx, locy); if (result == -2) { result = textsw_load_file(VIEW_REP_TO_ABS(folio->first_view), filename, TRUE, locx, locy); if (result == 0) { (void) textsw_set_insert(folio, 0L); } } return(result);}pkg_private char *textsw_full_pathname(name) register char *name;{ char pathname[MAXPATHLEN]; register char *full_pathname; if (name == 0) return(name); if (*name == '/') { if ((full_pathname = malloc((unsigned)(1+strlen(name)))) == 0) return (0); (void) strcpy(full_pathname, name); return(full_pathname); } if (getwd(pathname) == 0) return (0); if ((full_pathname = malloc((unsigned)(2+strlen(pathname)+strlen(name)))) == 0) return(0); (void) strcpy(full_pathname, pathname); (void) strcat(full_pathname, "/"); (void) strcat(full_pathname, name); return(full_pathname);}/* ARGSUSED */pkg_private inttextsw_format_load_error(msg, status, filename, scratch_name) char *msg; Es_status status; char *filename; char *scratch_name; /* Currently unused */{ char *full_pathname; switch (status) { case ES_PIECE_FAIL: (void) sprintf(msg, "Cannot create piece stream."); break; case ES_SUCCESS: /* Caller is being lazy! */ break; default: full_pathname = textsw_full_pathname(filename); (void) sprintf(msg, "Cannot load; "); es_file_append_error(msg, "file", status); es_file_append_error(msg, full_pathname, status); free(full_pathname); break; }}pkg_private inttextsw_format_load_error_quietly(msg, status, filename, scratch_name) char *msg; Es_status status; char *filename; char *scratch_name; /* Currently unused */{ char *full_pathname; switch (status) { case ES_PIECE_FAIL: (void) sprintf(msg, "INTERNAL ERROR: Cannot create piece stream."); break; case ES_SUCCESS: /* Caller is being lazy! */ break; default: full_pathname = textsw_full_pathname(filename); (void) sprintf(msg, "Unable to load file:"); es_file_append_error(msg, full_pathname, status); free(full_pathname); break; }}/* Returns 0 iff load succeeded. */extern inttextsw_load_file(abstract, filename, reset_views, locx, locy) Textsw abstract; char *filename; int reset_views; int locx, locy;{ char msg_buf[MAXNAMLEN+100]; char alert_msg_buf[MAXNAMLEN+100]; char scratch_name[MAXNAMLEN]; int result; Es_status status; Es_handle new_esh; Es_index start_at; Textsw_view view = VIEW_ABS_TO_REP(abstract); Textsw_folio textsw = FOLIO_FOR_VIEW(view); Event event; start_at = (reset_views) ? 0 : ES_CANNOT_SET; status = textsw_load_file_internal( textsw, filename, scratch_name, &new_esh, start_at, TXTSW_LFI_CLEAR_SELECTIONS); if (status == ES_SUCCESS) { if (start_at == ES_CANNOT_SET) textsw_notify((Textsw_view)textsw, /* Cast for lint */ TEXTSW_ACTION_LOADED_FILE, filename, 0); } else { textsw_format_load_error_quietly( alert_msg_buf, status, filename, scratch_name); result = alert_prompt( (Frame)window_get(VIEW_FROM_FOLIO_OR_VIEW(textsw), WIN_OWNER), &event, ALERT_BUTTON_YES, "Continue", ALERT_TRIGGER, ACTION_STOP, /* yes or no */ ALERT_MESSAGE_STRINGS, alert_msg_buf, 0, 0); } return(status);}/* Returns 0 iff load succeeded. */extern inttextsw_load_file_quietly(abstract, filename, feedback, reset_views, locx, locy) Textsw abstract; char *filename, *feedback; int reset_views; int locx, locy;{ char msg_buf[MAXNAMLEN+100]; char scratch_name[MAXNAMLEN]; Es_status status; Es_handle new_esh; Es_index start_at; Textsw_view view = VIEW_ABS_TO_REP(abstract); Textsw_folio textsw = FOLIO_FOR_VIEW(view); start_at = (reset_views) ? 0 : ES_CANNOT_SET; status = textsw_load_file_internal( textsw, filename, scratch_name, &new_esh, start_at, TXTSW_LFI_CLEAR_SELECTIONS); if (status == ES_SUCCESS) { if (start_at == ES_CANNOT_SET) textsw_notify((Textsw_view)textsw, /* Cast for lint */ TEXTSW_ACTION_LOADED_FILE, filename, 0); } else { textsw_format_load_error_quietly( feedback, status, filename, scratch_name); } return(status);}#define RELOAD 1#define NO_RELOAD 0static Es_statustextsw_save_store_common(folio, output_name, reload) register Textsw_folio folio; char *output_name; int reload;{ char scratch_name[MAXNAMLEN]; Es_handle new_esh; register Es_handle output; Es_status result; Es_index length; struct statfs fs; struct stat stat_buf; char *full_path; register char *char_ind; extern char *rindex(); length = es_get_length(folio->views->esh); if (stat(output_name, &stat_buf) < 0 && errno != ENOENT) return (ES_UNKNOWN_ERROR); if (errno == ENOENT) { stat_buf.st_size = 0; if ((full_path = textsw_full_pathname (output_name)) != 0) if ((char_ind = rindex (full_path, '/')) != NULL) { *char_ind = '\0'; if (statfs(full_path, &fs) < 0) return (ES_UNKNOWN_ERROR); } } else if (statfs(output_name, &fs) < 0) return (ES_UNKNOWN_ERROR); /* subtract file on disk length from file in memory length = number of bytes needed on disk to write entire file successfully */ if (length - stat_buf.st_size > fs.f_bavail * DEV_BSIZE) return (ES_SHORT_WRITE); output = es_file_create(output_name, ES_OPT_APPEND, &result); if (!output) /* BUG ALERT! For now, don't look at result. */ return(ES_CANNOT_OPEN_OUTPUT); result = es_copy(folio->views->esh, output, TRUE); if (result == ES_SUCCESS) { es_destroy(output); if (folio->checkpoint_name) { if (unlink(folio->checkpoint_name) == -1) { perror("removing checkpoint file:"); } free(folio->checkpoint_name); folio->checkpoint_name = NULL; } if (reload) { result = textsw_load_file_internal( folio, output_name, scratch_name, &new_esh, ES_CANNOT_SET, 0); if ((result == ES_SUCCESS) && (length != es_get_length(new_esh))) { /* Added a newline - repaint to fix line tables */ textsw_display((Textsw)folio->first_view); } } } return(result);}extern Es_statustextsw_process_save_error(abstract, error_buf, status, locx, locy)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -