nz@wucs.UUCP (Neal Ziring) (08/12/86)
We got in VMS GNU Emacs version 4 about two weeks ago, and we like it very much (Thanks, Marty!). However, after a few days of using it, I wanted to edit every .com file in my project directory. I typed $ gemacs *.com to DCL. Well, Emacs thoughtfully put me in a buffer named "*.COM". This is Bad! To remedy the situation, I wrote two Elisp-callable C routines, and modified some the the GNU Emacs startup code to use them. Below is my C code, plus the differences between the old modules and my new versions. The differences are the output of the VAX/VMS ``Difference'' utility. To use this stuff, just take the comple file, FILE_GLOB.C, and put it into the emacs source directory, and compile it with CC FILE_GLOB.C. Then, using emacs, make the changes to CONFIG.H and EMACS.C (I'd like to see EVE let you view the differences plus both files, all at the same time!). All the changes are _very_ minor. Then, recompile EMACS.C. Lastly, modify the LINK*.COM file that you use to link in the new module, FILE_GLOB.OBJ. You will now have a new TEMACS.EXE, which you can re-install or test or whatever. Have fun! If you have any questions, mail them to nz@wucs.UUCP soon! Also, would somebody please forward this letter to the vms-gnu mailing list? I don't know how to do that. ================================ EMACS_C.DIFF ************ File DUA0:[EMACS.SRC]EMACS.C;17 144 Vcommand_line_args 145 = Fcons (build_string (argv[i]), Vcommand_line_args); 146 } ****** File DUA0:[EMACS.SRC]EMACS.C;33 144 #ifdef GLOB_VMS 145 146 /* glob our command line file-names, safe for other args, too */ 147 Vcommand_line_args 148 = Fglob_file_safe ( build_string (argv[i] ), Vcommand_line_args); 149 #else 150 Vcommand_line_args 151 = Fcons (build_string (argv[i]), Vcommand_line_args); 152 #endif 153 } ************ ************ File DUA0:[EMACS.SRC]EMACS.C;17 293 #ifdef CLASH_DETECTION ****** File DUA0:[EMACS.SRC]EMACS.C;33 300 #ifdef GLOB_VMS 301 302 syms_of_file_glob (); 303 #endif 304 #ifdef CLASH_DETECTION ************ Number of difference sections found: 2 Number of difference records found: 13 DIFFERENCES /IGNORE=()/MERGED=1/OUTPUT=DUA0:[EMACS.SRC]EMACS_C.DIFF;1- DUA0:[EMACS.SRC]EMACS.C;17- DUA0:[EMACS.SRC]EMACS.C;33 ============================= FILE_GLOB.C /* Simple VMS-Native file-name wild-card expansion for GNU Emacs Copyright (C) 1986 Richard M. Stallman and Neal Ziring? This file is part of GNU Emacs. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the GNU Emacs General Public License for full details. Everyone is granted permission to copy, modify and redistribute GNU Emacs, but only under the conditions described in the GNU Emacs General Public License. A copy of this license is supposed to have been given to you along with GNU Emacs so you can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ /* * most of this code is stolen from the SIFT project, at * Washington University, Summer 1986. For information about * it, write to nz@wucs.UUCP. Written by Neal Ziring with * help from Tom Patterson. * For information about the VMS system service calls, see * VMS Documentation Volume 8B. */ #include "config.h" #include "lisp.h" /* all the code in this file is in between VMS and GLOB_VMS ifdefs */ #ifdef VMS #ifdef GLOB_VMS #include <ssdef.h> #include <file.h> #include <rms.h> #include <descrip.h> #define DSC struct dsc$descriptor /* ************************************************************** * glob_word: given a string, glob it as a file name, return * a name-list with all the results. * * This routine operates in two ways. When compiled under * UNIX, the routine does a directory in a rather cheap way. * When compiled under VMS, the routine does a directory in * a weird VMS-ish way. * * VMS - call the routine find_file repeatedly to * retrieve all the names that match a given spec. * * In all circumstances, the routine passes back a name-list. * If no file matches the spec, Qnil is returned. */ DEFUN ( "glob-file-name", Fglob_file_name, Sglob_file_name, 2, 2, 0, "Return a list of file names matching SPEC.\n\ Return nil if SPEC is not matched by any files. If\n\ SPEC does match file, prepend them to list SLT and return\n\ the new value of the list") (spec, slt) Lisp_Object spec,slt; { int i, e_cnt; unsigned char *s1, *s2, *strbuf; #define FUDGE_LEN 39+39+39+39 char nbuf[5+FUDGE_LEN]; Lisp_Object Vexpansion, Fcons(); DSC d_name, d_res, d_rel, d_def; unsigned long context, stv, uflag; strbuf = XSTRING (spec)->data; /* first initialize the descriptors */ for(s1 = s2 = (char *) &d_name; s2 - s1 < sizeof(DSC); *s2++ = '\0'); d_name.dsc$b_class = DSC$K_CLASS_D; ch$move(sizeof(DSC), &d_name, &d_res); ch$move(sizeof(DSC), &d_name, &d_rel); ch$move(sizeof(DSC), &d_name, &d_def); context = stv = uflag = 0; if (strdesc(&d_name, strbuf) < 0) return(Qnil); /* now search for files, one at a time */ for( Vexpansion = slt, e_cnt=0; ((i = lib$find_file(&d_name,&d_res,&context,&d_def,&d_rel,&stv,&uflag)) == RMS$_NORMAL); e_cnt++) { str$copy_dx(&d_rel, &d_name); for(s1 = d_res.dsc$a_pointer, i = 0; i < d_res.dsc$w_length && i < FUDGE_LEN; nbuf[i++] = *s1++); nbuf[i] = '\0'; Vexpansion = Fcons ( build_string (nbuf), Vexpansion); } /* close down directory-reading operations */ lib$find_file_end( &context); /* this better not crash! */ if ( d_name.dsc$w_length > 0 ) lib$sfree1_dd(&d_name); if ( d_res.dsc$w_length > 0 ) lib$sfree1_dd(&d_res); if ( d_def.dsc$w_length > 0 ) lib$sfree1_dd(&d_def); if ( d_rel.dsc$w_length > 0 ) lib$sfree1_dd(&d_rel); if (e_cnt == 0) return( Qnil ); else return ( Vexpansion ); } /* some utility routines for the VAXC part of glob_word */ int strdesc(d,s) DSC *d; char *s; { unsigned long len; len = strlen(s) + 1; if ( lib$sget1_dd( &len, d) == SS$_NORMAL) strcpy(d->dsc$a_pointer, s); else return(-1); return(0); } int ch$move(size, from, to) int size; unsigned char *from, *to; { while( size-- >= 0) *to++ = *from++; return(0); } DEFUN ( "glob-file-safe", Fglob_file_safe, Sglob_file_safe, 2, 2 , 0, "Return a list of file names matching SPEC.\n\ Return SPEC itself if SPEC is not matched by any files.\n\ The expansion list for spec is prepended to SLT") (spec, slt) Lisp_Object spec, slt; { Lisp_Object Vtmp; Vtmp = Fglob_file_name(spec,slt); if (Vtmp == Qnil) return( Fcons( spec, slt) ); else return(Vtmp); } syms_of_file_glob() { defsubr ( &Sglob_file_name ); defsubr ( &Sglob_file_safe ); } #endif GLOB_VMS #endif VMS ============================ -- ...nz (Neal Ziring at WU ECL - we're here to provide superior computing.) {seismo,ihnp4,cbosgd}!wucs!nz OR nz@wucs.UUCP "You could get an infinite number of wires into this !*$$#!?! junction box, but we usually don't go that far in practice" -- Employee of London Electricity Board, 1959