meissner@osf.org (03/21/91)
| I'm using Gnu Emacs 18.55 on a machine with VERY little spare | disk space. I've managed to persuade info to read compressed | info files, but am at a loss as to how to get emacs to read | /load compressed *.el or *.elc files. Has anyone managed to do | this? Sure, you have to modify Fload, and then add a new function to create a filter on a file descriptor: First replace the Fload function in lread.c with the following: DEFUN ("load", Fload, Sload, 1, 4, 0, "Execute a file of Lisp code named FILE.\n\ First tries FILE with .elc appended, then tries with .elc.Z,\n\ then tries with .el, then tries with .el.Z,\n\ then tries FILE unmodified. Searches directories in load-path.\n\ If a .elc.Z or .el.Z file is found, it is uncompressed.\n\ If optional second arg MISSING-OK is non-nil,\n\ report no error if FILE doesn't exist.\n\ Print messages at start and end of loading unless\n\ optional third arg NOMESSAGE is non-nil.\n\ If optional fourth arg NOSUFFIX is non-nil, don't try adding\n\ suffixes .elc, .elc.Z, .el or .el.Z to the specified name FILE.\n\ Return t if file exists.") (str, missing_ok, nomessage, nosuffix) Lisp_Object str, missing_ok, nomessage, nosuffix; { register FILE *stream; register int fd = -1; register Lisp_Object lispstream; register FILE **ptr; int count = specpdl_ptr - specpdl; struct gcpro gcpro1, gcpro2; Lisp_Object name = Qnil; register int len; register char *msg = "Loading %s..."; CHECK_STRING (str, 0); str = Fsubstitute_in_file_name (str); /* Avoid weird lossage with null string as arg, since it would try to load a directory as a Lisp file */ if (XSTRING (str)->size > 0) { fd = openp (Vload_path, str, !NULL (nosuffix) ? "" : ".elc:.elc.Z:.el:.el.Z:", &name, 0); } if (fd < 0) if (NULL (missing_ok)) while (1) Fsignal (Qfile_error, Fcons (build_string ("Cannot open load file"), Fcons (str, Qnil))); else return Qnil; #ifndef standalone if (XTYPE (name) == Lisp_String && (len = XSTRING (name)->size) > 2 && strcmp ((char *)&XSTRING (name)->data[len-2], ".Z") == 0) { char *new_argv[3]; msg = "Decompressing and loading %s..."; new_argv[0] = "zcat"; new_argv[1] = (char *)XSTRING (name)->data; new_argv[2] = (char *)0; fd = create_filter (fd, new_argv); } #endif /* standalone */ stream = fdopen (fd, "r"); if (stream == 0) { close (fd); error ("Failure to create stdio stream for %s", XSTRING (str)->data); } if (NULL (nomessage)) message (msg, XSTRING (name)->data); GCPRO2 (str, name); ptr = (FILE **) xmalloc (sizeof (FILE *)); *ptr = stream; XSET (lispstream, Lisp_Internal_Stream, (int) ptr); record_unwind_protect (load_unwind, lispstream); load_in_progress++; readevalloop (Qget_file_char, stream, Feval, 0); unbind_to (count); UNGCPRO; if (!noninteractive && NULL (nomessage)) message ("Loading %s...done", XSTRING (name)->data); return Qt; } And then add the following function somewhere in process.c: /* Internal function to create a filter process, that given an input file descriptor and an argument list, invokes the process with the output directed to a pipe, and return the file descriptor of the read end of the pipe. */ int create_filter (infd, new_argv) int infd; /* input file descriptor */ char *new_argv[]; /* argument list */ { int pipe_fd[2]; int pid; char **env; /* child_setup must clobber environ on systems with true vfork. Protect it from permanent change. */ extern char **environ; char **save_environ = environ; #ifdef MAINTAIN_ENVIRONMENT env = (char **) alloca (size_of_current_environ ()); get_current_environ (env); #else env = environ; #endif /* MAINTAIN_ENVIRONMENT */ if (pipe (pipe_fd) < 0) { error ("Failure to create pipe for %s command", new_argv[0]); return -1; } /* Delay interrupts until we have a chance to store the new fork's pid in its process structure */ #ifdef SIGCHLD #ifdef BSD4_1 sighold (SIGCHLD); #else /* not BSD4_1 */ #ifdef HPUX sigsetmask (1 << (SIGCHLD - 1)); #endif /* HPUX */ #if defined (BSD) || defined (UNIPLUS) sigsetmask (1 << (SIGCHLD - 1)); #else /* ordinary USG */ sigchld = (int (*)()) signal (SIGCHLD, SIG_DFL); #endif /* ordinary USG */ #endif /* not BSD4_1 */ #endif /* SIGCHLD */ pid = vfork (); if (pid == 0) /* don't do controlling terminal stuff, since we are using pipes. */ child_setup (infd, pipe_fd[1], pipe_fd[1], new_argv, env); environ = save_environ; close (pipe_fd[1]); close (infd); if (pid < 0) { close (pipe_fd[0]); pipe_fd[0] = -1; report_file_error ("Doing vfork", Qnil); } #ifdef SIGCHLD #ifdef BSD4_1 sigrelse (SIGCHLD); #else /* not BSD4_1 */ #ifdef HPUX sigsetmask (0); #endif /* HPUX */ #if defined (BSD) || defined (UNIPLUS) sigsetmask (0); #else /* ordinary USG */ signal (SIGCHLD, sigchld); #endif /* ordinary USG */ #endif /* not BSD4_1 */ #endif /* SIGCHLD */ return pipe_fd[0]; } -- Michael Meissner email: meissner@osf.org phone: 617-621-8861 Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142 Considering the flames and intolerance, shouldn't USENET be spelled ABUSENET?
rms@GNU.AI.MIT.EDU (Richard Stallman) (03/21/91)
It's not a good idea for people to introduce further use of compress, because it's patented, and Unisys wants us to pay for the privilege. True, they won't come after an individual to demand money. They won't even know about you. However, the more we get in the habit of using compress, the harder it will be for larger organizations to drop it when forced otherwise to pay. We are working on alternative data-compression programs, and so are other people, but there's no telling when one will be available and suitable.
mjh@kernel.co.uk (Mark J Hewitt) (03/21/91)
I'd be interested to know just how much time penalty vs. space saving this trend for loading compressed .el[c]'s is. After all, by not using the byte compiled versions, or by off-line storing the .el sources and loading only .elc's, there will be a considerable saving. Using .el's rather than .elc's must imply a load-time time penalty - which is what compression must do in any case. So the best saving is to off-line the .el's and compress the .elc's. What are the time and space tradeoffs for all these options? Mark J. Hewitt bangpath: ...!ukc!kernel!mjh JANET: mjh@uk.co.kernel voice: (+44) 532 444566 other: mjh@kernel.co.uk fax: (+44) 532 425456 old style: mjh%uk.co.kernel@uk.ac.ukc paper: Kernel Technology Ltd, Development Centre, 46 The Calls, Leeds, LS2 7EY, West Yorkshire, UK