158 lines · 3.9 KB · C
RawDownload
#include <math.h>#include "prelude.h"#include "storage.h"#include "connect.h"#include "errors.h"#include "opts.h"#include "strutil.h"#include "machdep.h" Bool startEdit(line,nm)    /* Start editor on file name at    */Int    line;               /* given line.  Both name and line */String nm; {               /* or just line may be zero        */    String editorCmd;    String fullNm;    Bool   expandedName = FALSE;    Bool   syncEdit     = TRUE;    Bool   useShell     = FALSE;    String he;    String ec;    unsigned int roomReqd = 0;    unsigned int nmLen, lineLen, fullNmLen;        /* First off, check whether we have actually got a plausible editor     * available. On a Mac, files have creator information, telling which     * program to launch to, so an editor named to the empty string ""     * is often desirable.     */    if (!hugsEdit #if !(defined(macintosh))        || *hugsEdit == '\0'#endif	             ) {	ERRMSG(0) "Hugs is not configured to use an editor"	EEND;    }           /* More sanity checks */    if (nm == NULL) {      return FALSE;    }        fullNm = RealPath(nm);    fullNmLen = strlen(fullNm);    nmLen = strlen(nm);    lineLen = 1 + (line == 0 ? 0 : (unsigned int)log10((double)line));        he = hugsEdit;     /* Compute the length of the expanded 'hugsEdit' string */    while (*he) {      if (*he++ == '%') {	if (*he == 's') {	  /* assume quotes are always put around the filename. */	  roomReqd += nmLen + 2;	  expandedName = TRUE;	} else if (*he == 'f') {	  /* assume quotes are always put around the filename. */	  roomReqd += fullNmLen + 2;	  expandedName = TRUE;	} else if ( *he == 'd' ) {	  roomReqd += lineLen;	} else if ( *he == '%' ) {	  /* %% is contracted to % in the expanded string */	  roomReqd++;	} else {	  roomReqd += 2;	}	he++;      } else {	roomReqd++;      }    }        if (!expandedName) {      /* include room for quotes and an extra space */      roomReqd += nmLen + 3;    }        editorCmd = (String)malloc(sizeof(char) * (roomReqd + 1));    if (editorCmd == NULL) {      Printf("Warning: Unable to start editor\n");      return FALSE;    }        /* Given a properly sized output buffer, perform the expansion */    expandedName = FALSE;    ec = editorCmd;    he = hugsEdit;        /* If the editor command is prefixed with '&', the editor is     * started up asynchronously (the default is for Hugs to block     * and wait for the editor to exit).     *     * If the editor command is prefixed with '!', then the editor is     * invoked by going via the shell.     */    while (1) {      if (*he == '&') {	syncEdit = FALSE;	he++;      } else if (*he == '!') {	useShell = TRUE;	he++;      } else {	break;      }    }        while (*he) {      if (*he=='%') {	if (*++he=='d') {	  sprintf(ec,"%d",(line ? line : 1));	  ec += lineLen;	  he++;	} else if (*he == 's' || *he == 'f') {	  /* Put quotes around it if the %s occurrence surrounded by wspace only. */	  Bool useQuotes = isspace(he[-2]) && (he[1] == '\0' || isspace(he[1]));	  if (useQuotes) *ec++='\"';	  if (*he == 's') {	    strcpy(ec,nm);	    ec += nmLen;	  } else {	    strcpy(ec,fullNm);	    ec += fullNmLen;	  }	  if (useQuotes) *ec++='\"';	  *ec='\0';	  expandedName = TRUE;	  he++;	} else if (*he == '%') { /* Unescape % */	  *ec++ = '%';	  he++;	} else {	  *ec++ = '%'; 	  *ec++ = *he++;	}      } else {	*ec++ = *he++;      }    }     if (!expandedName) {  /* If file name was not included, add it. */      *ec++=' ';      /* Protect the filename by putting quotes around it */      *ec++='\"'; strcpy(ec,nm); ec += nmLen; *ec++='\"';    }        /* Terminate the string and go! */    *ec = '\0';       if (shellEsc(editorCmd,syncEdit/*sync*/, useShell/*sep console*/)) {      Printf("Warning: Editor terminated abnormally\n");      free(editorCmd);      return FALSE;    }    free(editorCmd);    return syncEdit;}