file.c (most-5.1.0) | : | file.c (most-5.2.0) | ||
---|---|---|---|---|
/* | /* | |||
This file is part of MOST. | This file is part of MOST. | |||
Copyright (c) 1991, 1999, 2002, 2005-2018, 2019 John E. Davis | Copyright (c) 1991, 1999, 2002, 2005-2021, 2022 John E. Davis | |||
This program is free software; you can redistribute it and/or modify it | This program is free software; you can redistribute it and/or modify it | |||
under the terms of the GNU General Public License as published by the Free | under the terms of the GNU General Public License as published by the Free | |||
Software Foundation; either version 2 of the License, or (at your option) | Software Foundation; either version 2 of the License, or (at your option) | |||
any later version. | any later version. | |||
This program is distributed in the hope that it will be useful, but WITHOUT | This program is distributed in the hope that it will be useful, but WITHOUT | |||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |||
more details. | more details. | |||
skipping to change at line 77 | skipping to change at line 77 | |||
char *efile; | char *efile; | |||
if (NULL == (efile = most_escape_filename (file, '"'))) | if (NULL == (efile = most_escape_filename (file, '"'))) | |||
return -1; | return -1; | |||
(void) _pSLsnprintf (buf, sizeof_buf, cmd, efile); | (void) _pSLsnprintf (buf, sizeof_buf, cmd, efile); | |||
SLfree (efile); | SLfree (efile); | |||
return 0; | return 0; | |||
} | } | |||
static int open_compressed_file(char *file, int mode, int *size) | static int open_compressed_file(char *file, int mode, size_t *sizep) | |||
{ | { | |||
int fd; | int fd; | |||
char buf[4], cmdbuf[2*MAX_PATHLEN]; | char buf[4], cmdbuf[2*MAX_PATHLEN]; | |||
struct stat st; | struct stat st; | |||
# ifdef O_BINARY | # ifdef O_BINARY | |||
mode |= O_BINARY; | mode |= O_BINARY; | |||
# endif | # endif | |||
# ifdef IBMPC_SYSTEM | # ifdef IBMPC_SYSTEM | |||
Most_Z_Opt = 1; | Most_Z_Opt = 1; | |||
# endif | # endif | |||
if (Most_Z_Opt) | if (Most_Z_Opt) | |||
{ | { | |||
if (stat(file, &st)) return(-1); | if (stat(file, &st)) return(-1); | |||
*size = st.st_size; | *sizep = st.st_size; | |||
return (open(file,mode)); | return (open(file,mode)); | |||
} | } | |||
fd = open(file, O_RDONLY); | fd = open(file, O_RDONLY); | |||
if (fd < 0) return fd; | if (fd < 0) return fd; | |||
if (4 == read(fd, buf, 4)) | if (4 == read(fd, buf, 4)) | |||
{ | { | |||
char *cmd = NULL; | char *cmd = NULL; | |||
skipping to change at line 129 | skipping to change at line 129 | |||
FILE *fp; | FILE *fp; | |||
close (fd); | close (fd); | |||
most_flush_message ("Uncompressing file..."); | most_flush_message ("Uncompressing file..."); | |||
if (-1 == create_gunzip_cmd (cmd, file, cmdbuf, sizeof(cmdbuf))) | if (-1 == create_gunzip_cmd (cmd, file, cmdbuf, sizeof(cmdbuf))) | |||
return -1; | return -1; | |||
fp = popen (cmdbuf, "r"); /* GLIBC doe not support "rb" */ | fp = popen (cmdbuf, "r"); /* GLIBC doe not support "rb" */ | |||
if (fp == NULL) | if (fp == NULL) | |||
return -1; | return -1; | |||
*size = 0; | *sizep = 0; | |||
fd = fileno (fp); | fd = fileno (fp); | |||
Most_Buf->fp = fp; | Most_Buf->fp = fp; | |||
/* pclose (fp); */ | /* pclose (fp); */ | |||
return fd; | return fd; | |||
} | } | |||
} | } | |||
close (fd); | close (fd); | |||
if (stat(file, &st)) return(-1); | if (stat(file, &st)) return(-1); | |||
*size = st.st_size; | *sizep = st.st_size; | |||
return (open(file,mode)); | return (open(file,mode)); | |||
} | } | |||
#endif /* VMS */ | #endif /* VMS */ | |||
#if MOST_HAS_MMAP | #if MOST_HAS_MMAP | |||
#ifdef HAVE_SYS_MMAN_H | #ifdef HAVE_SYS_MMAN_H | |||
# include <sys/mman.h> | # include <sys/mman.h> | |||
#endif | #endif | |||
#ifndef MAP_FAILED | #ifndef MAP_FAILED | |||
skipping to change at line 171 | skipping to change at line 171 | |||
if (-1 == fstat (fd, &st)) | if (-1 == fstat (fd, &st)) | |||
return -1; | return -1; | |||
addr = (unsigned char *)mmap (NULL,st.st_size,PROT_READ,MAP_SHARED,fd,0); | addr = (unsigned char *)mmap (NULL,st.st_size,PROT_READ,MAP_SHARED,fd,0); | |||
if (addr == (unsigned char *)MAP_FAILED) | if (addr == (unsigned char *)MAP_FAILED) | |||
return -1; | return -1; | |||
Most_Buf->fd = fd; | Most_Buf->fd = fd; | |||
Most_Eob = Most_Beg = Most_Buf->end = Most_Buf->beg = addr; | Most_Eob = Most_Beg = Most_Buf->end = Most_Buf->beg = addr; | |||
Most_Buf->size = 0; | Most_Buf->bufsize = 0; | |||
Most_Buf->mmap_size = st.st_size; | Most_Buf->mmap_file_size = st.st_size; | |||
Most_Buf->is_mmaped = 1; | Most_Buf->is_mmaped = 1; | |||
return 0; | return 0; | |||
} | } | |||
static int unmmap_buffer (Most_Buffer_Type *b) | static int unmmap_buffer (Most_Buffer_Type *b) | |||
{ | { | |||
if (b->is_mmaped == 0) | if (b->is_mmaped == 0) | |||
return 0; | return 0; | |||
if (b->beg != NULL) | if (b->beg != NULL) | |||
munmap ((char *)b->beg, b->size); | munmap ((char *)b->beg, b->bufsize); | |||
b->end = b->beg = NULL; | b->end = b->beg = NULL; | |||
if (b == Most_Buf) | if (b == Most_Buf) | |||
{ | { | |||
Most_Beg = Most_Eob = NULL; | Most_Beg = Most_Eob = NULL; | |||
Most_C_Line = 0; | Most_C_Line = 0; | |||
Most_Num_Lines = Most_C_Line = 0; | Most_Num_Lines = Most_C_Line = 0; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
skipping to change at line 206 | skipping to change at line 206 | |||
static int resync_mmap (void) | static int resync_mmap (void) | |||
{ | { | |||
struct stat st; | struct stat st; | |||
int line = Most_C_Line; | int line = Most_C_Line; | |||
if (Most_Buf->fd == -1) | if (Most_Buf->fd == -1) | |||
return 0; | return 0; | |||
if (-1 == fstat (Most_Buf->fd, &st)) | if (-1 == fstat (Most_Buf->fd, &st)) | |||
return -1; | return -1; | |||
if ((unsigned int) st.st_size == Most_Buf->mmap_size) | if (st.st_size == Most_Buf->mmap_file_size) | |||
return 0; | return 0; | |||
(void) unmmap_buffer (Most_Buf); | (void) unmmap_buffer (Most_Buf); | |||
if (-1 == try_mmap_buffer (Most_Buf->fd)) | if (-1 == try_mmap_buffer (Most_Buf->fd)) | |||
return -1; | return -1; | |||
most_goto_line (line); | most_goto_line (line); | |||
return 0; | return 0; | |||
} | } | |||
skipping to change at line 240 | skipping to change at line 240 | |||
unmmap_buffer (b); | unmmap_buffer (b); | |||
#endif | #endif | |||
if (b->beg != NULL) | if (b->beg != NULL) | |||
SLFREE(b->beg); | SLFREE(b->beg); | |||
b->beg = NULL; | b->beg = NULL; | |||
b->fd = -1; | b->fd = -1; | |||
return 0; | return 0; | |||
} | } | |||
/* If file[0] == 0, the file represents stdin */ | /* If file is NULL, the file represents stdin */ | |||
static int insert_file(char *file) | static int insert_file(char *file) | |||
{ | { | |||
int size = 0, fd; | size_t size = 0; | |||
/* int mode; */ | /* int mode; */ | |||
#ifdef VMS | #ifdef VMS | |||
struct stat st; | struct stat st; | |||
unsigned recsz = 512; | unsigned recsz = 512; | |||
/* extern int stat(char *, struct stat *); */ | /* extern int stat(char *, struct stat *); */ | |||
#endif | #endif | |||
int fd; | ||||
if (file[0] == '\0') /* assume stdin */ | if (file == NULL) /* assume stdin */ | |||
{ | { | |||
fd = 0; | fd = fileno (stdin); | |||
strcpy (Most_Buf->file, "*stdin*"); | strcpy (Most_Buf->file, "*stdin*"); | |||
} | } | |||
else | else | |||
{ | { | |||
#ifdef VMS | #ifdef VMS | |||
if (stat(file, &st)) return(-1); | if (stat(file, &st)) return(-1); | |||
/* mode = st.st_mode & S_IFMT; */ | /* mode = st.st_mode & S_IFMT; */ | |||
size = st.st_size; | size = st.st_size; | |||
recsz = st.st_fab_mrs; | recsz = st.st_fab_mrs; | |||
if (recsz <= 255) recsz = 255; | if (recsz <= 255) recsz = 255; | |||
skipping to change at line 287 | skipping to change at line 288 | |||
if (fd < 0) return(-1); | if (fd < 0) return(-1); | |||
if (!fd || (size <= 0)) size = 0x7FFF; | if (!fd || (size <= 0)) size = 0x7FFF; | |||
#ifdef VMS | #ifdef VMS | |||
Most_Buf->rec = recsz; | Most_Buf->rec = recsz; | |||
#endif | #endif | |||
Most_Buf->fd = fd; | Most_Buf->fd = fd; | |||
/* This will fail on really large files. */ | /* This will fail on really large files. */ | |||
Most_Eob = Most_Beg = Most_Buf->beg = (unsigned char *) MOSTMALLOC(size); | Most_Eob = Most_Beg = Most_Buf->beg = (unsigned char *) MOSTMALLOC(size); | |||
Most_Buf->size = size; | Most_Buf->bufsize = size; | |||
return most_read_file_dsc (1, 1); | return most_read_file_dsc (1, 1); | |||
} | } | |||
static void update_buffer_windows (Most_Buffer_Type *b) | static void update_buffer_windows (Most_Buffer_Type *b) | |||
{ | { | |||
Most_Window_Type *w; | Most_Window_Type *w; | |||
if (NULL == (w = Most_Win)) | if (NULL == (w = Most_Win)) | |||
return; | return; | |||
skipping to change at line 347 | skipping to change at line 348 | |||
Most_W_Opt = 1; | Most_W_Opt = 1; | |||
} | } | |||
} | } | |||
} | } | |||
static int First_Time_Hack = 0; /* true if reading file for first time */ | static int First_Time_Hack = 0; /* true if reading file for first time */ | |||
#if MOST_HAS_MMAP | #if MOST_HAS_MMAP | |||
static int read_mmap_file_dsc (int many, int count_lines) | static int read_mmap_file_dsc (int many, int count_lines) | |||
{ | { | |||
unsigned int size; | MOST_INT size; | |||
size = Most_Buf->size; | size = Most_Buf->bufsize; | |||
if (many == -1) | if (many == -1) | |||
{ | { | |||
if (-1 == resync_mmap ()) | if (-1 == resync_mmap ()) | |||
return -1; | return -1; | |||
} | } | |||
if (size == Most_Buf->mmap_size) | if (size == Most_Buf->mmap_file_size) | |||
return 0; | return 0; | |||
if (many < 0) | if (many < 0) | |||
size = Most_Buf->mmap_size; | size = Most_Buf->mmap_file_size; | |||
else | else | |||
{ | { | |||
size += many * 0xFFFF; | size += many * (size_t) 0xFFFF; | |||
if (size > Most_Buf->mmap_size) | if (size > Most_Buf->mmap_file_size) | |||
size = Most_Buf->mmap_size; | size = Most_Buf->mmap_file_size; | |||
} | } | |||
Most_Eob = Most_Buf->end = Most_Buf->beg + size; | Most_Eob = Most_Buf->end = Most_Buf->beg + size; | |||
Most_Buf->size = size; | Most_Buf->bufsize = size; | |||
most_flush_message ("Mapping file..."); | most_flush_message ("Mapping file..."); | |||
if (First_Time_Hack) | if (First_Time_Hack) | |||
examine_file_contents (); | examine_file_contents (); | |||
if (count_lines) | if (count_lines) | |||
Most_Num_Lines = most_count_lines (Most_Beg, Most_Eob); | Most_Num_Lines = most_count_lines (Most_Beg, Most_Eob); | |||
most_message(Most_Global_Msg, 0); | most_message(Most_Global_Msg, 0); | |||
return 1; | return 1; | |||
} | } | |||
#endif | #endif | |||
/* if read something, return non zero (1) */ | /* if read something, return non zero (1) */ | |||
int most_read_file_dsc (int many, int count_lines) | MOST_INT most_read_file_dsc (MOST_INT many, int count_lines) | |||
{ | { | |||
int fd = Most_Buf->fd, n = 0, i; | MOST_INT dsize, size, n = 0; | |||
int dsize, size, passes = 0; | int fd = Most_Buf->fd; | |||
int passes = 0; | ||||
unsigned char *pos; | unsigned char *pos; | |||
#ifdef VMS | #ifdef VMS | |||
int recsz = Most_Buf->rec; | int recsz = Most_Buf->rec; | |||
#endif | #endif | |||
if (fd < 0) return 0; | if (fd < 0) return 0; | |||
#if MOST_HAS_MMAP | #if MOST_HAS_MMAP | |||
if (Most_Buf->is_mmaped) | if (Most_Buf->is_mmaped) | |||
{ | { | |||
skipping to change at line 415 | skipping to change at line 417 | |||
if (Most_Buf->is_mmaped) | if (Most_Buf->is_mmaped) | |||
return -1; | return -1; | |||
/* No longer mapped..... */ | /* No longer mapped..... */ | |||
} | } | |||
#endif | #endif | |||
dsize = 0x3FFF; | dsize = 0x3FFF; | |||
while (many--) | while (many--) | |||
{ | { | |||
ssize_t i; | ||||
passes++; | passes++; | |||
most_flush_message ("Reading..."); | most_flush_message ("Reading..."); | |||
size = (Most_Eob - Most_Beg) + dsize; | size = (Most_Eob - Most_Beg) + dsize; | |||
if (Most_Buf->size > size) pos = Most_Beg; | if (Most_Buf->bufsize > size) pos = Most_Beg; | |||
else | else | |||
{ | { | |||
size = Most_Buf->size + 0xFFFF; | size = Most_Buf->bufsize + 0xFFFF; | |||
pos = (unsigned char *) MOSTREALLOC(Most_Beg, (unsigned) size); | pos = (unsigned char *) MOSTREALLOC(Most_Beg, (unsigned) size); | |||
Most_Buf->size = size; | Most_Buf->bufsize = size; | |||
} | } | |||
Most_Eob = pos + (unsigned int) (Most_Eob - Most_Beg); | Most_Eob = pos + (Most_Eob - Most_Beg); | |||
Most_Beg = pos; | Most_Beg = pos; | |||
pos = Most_Eob; | pos = Most_Eob; | |||
n = 0; | n = 0; | |||
while (1) | while (1) | |||
{ | { | |||
#ifdef VMS | #ifdef VMS | |||
i = read (fd, (char *) pos, recsz); | i = read (fd, (char *) pos, recsz); | |||
#else | #else | |||
skipping to change at line 497 | skipping to change at line 501 | |||
update_buffer_windows (Most_Buf); | update_buffer_windows (Most_Buf); | |||
most_message("reading...done", 0); | most_message("reading...done", 0); | |||
most_put_message(); | most_put_message(); | |||
most_message(Most_Global_Msg, 0); | most_message(Most_Global_Msg, 0); | |||
return n; | return n; | |||
} | } | |||
/* This routines makes sure line n is read in. */ | /* This routines makes sure line n is read in. */ | |||
void most_read_to_line(int n) | void most_read_to_line(MOST_INT n) | |||
{ | { | |||
int dn; | MOST_INT dn, nbytes; | |||
long nbytes; | ||||
if (Most_Buf->fd == -1) return; | if (Most_Buf->fd == -1) return; | |||
n += 2 * SLtt_Screen_Rows; | n += 2 * SLtt_Screen_Rows; | |||
dn = n - Most_Num_Lines; | dn = n - Most_Num_Lines; | |||
if (dn < 0) return; | if (dn < 0) return; | |||
nbytes = 0; | nbytes = 0; | |||
if (Most_Num_Lines) | if (Most_Num_Lines) | |||
nbytes = dn * ((Most_Eob - Most_Beg) / Most_Num_Lines); | nbytes = dn * ((Most_Eob - Most_Beg) / Most_Num_Lines); | |||
skipping to change at line 525 | skipping to change at line 528 | |||
&& (0 != most_read_file_dsc (nbytes / 0x3FFF, 1)) | && (0 != most_read_file_dsc (nbytes / 0x3FFF, 1)) | |||
&& (SLKeyBoard_Quit == 0)) | && (SLKeyBoard_Quit == 0)) | |||
{ | { | |||
nbytes = 0; | nbytes = 0; | |||
if (Most_Num_Lines) | if (Most_Num_Lines) | |||
nbytes = dn * ((Most_Eob - Most_Beg) / Most_Num_Lines); | nbytes = dn * ((Most_Eob - Most_Beg) / Most_Num_Lines); | |||
if (nbytes < 0x3FFF) nbytes = 0x3FFF; | if (nbytes < 0x3FFF) nbytes = 0x3FFF; | |||
} | } | |||
} | } | |||
/* file may be NULL, which implies *stdin* */ | ||||
int most_find_file(char *file) | int most_find_file(char *file) | |||
{ | { | |||
Most_Buffer_Type *new_buf; | Most_Buffer_Type *new_buf; | |||
int n; | ||||
char msg[MAX_PATHLEN+20], *msgp; | char msg[MAX_PATHLEN+20], *msgp; | |||
int ret = 0; | int ret = 0; | |||
new_buf = most_create_buffer(file); | new_buf = most_create_buffer(file); | |||
(void) most_switch_to_buffer(new_buf); | (void) most_switch_to_buffer(new_buf); | |||
First_Time_Hack = 1; | First_Time_Hack = 1; | |||
if (insert_file(file) < 0) | if (insert_file(file) < 0) | |||
{ | { | |||
size_t n; | ||||
if (file == NULL) file = "*stdin*"; | ||||
sprintf (msg, "%s failed to open.", file); | sprintf (msg, "%s failed to open.", file); | |||
n = strlen (msg); | n = strlen (msg); | |||
msgp = (char *) MOSTMALLOC((unsigned int) (n + 1)); | msgp = (char *) MOSTMALLOC(n + 1); | |||
strcpy (msgp, msg); | strcpy (msgp, msg); | |||
Most_Buf->beg = (unsigned char *) msgp; | Most_Buf->beg = (unsigned char *) msgp; | |||
Most_Buf->end = Most_Buf->beg + n; | Most_Buf->end = Most_Buf->beg + n; | |||
Most_Buf->fd = -1; | Most_Buf->fd = -1; | |||
Most_Num_Lines = 1; | Most_Num_Lines = 1; | |||
ret = -1; | ret = -1; | |||
} | } | |||
First_Time_Hack = 0; | First_Time_Hack = 0; | |||
Most_Beg = Most_Buf->beg; | Most_Beg = Most_Buf->beg; | |||
End of changes. 33 change blocks. | ||||
34 lines changed or deleted | 40 lines changed or added |