static void gotoCB(Widget widget, WindowInfo *window, Atom *sel, Atom *type, char *value, int *length, int *format) { /* two integers and some space in between */ char lineText[(TYPE_INT_STR_SIZE(int) * 2) + 5]; int rc, lineNum, column, position, curCol; /* skip if we can't get the selection data, or it's obviously not a number */ if (*type == XT_CONVERT_FAIL || value == NULL) { XBell(TheDisplay, 0); return; } if (((size_t) *length) > sizeof(lineText) - 1) { XBell(TheDisplay, 0); XtFree(value); return; } /* should be of type text??? */ if (*format != 8) { fprintf(stderr, "NEdit: Can't handle non 8-bit text\n"); XBell(TheDisplay, 0); XtFree(value); return; } strncpy(lineText, value, sizeof(lineText)); lineText[sizeof(lineText) - 1] = '\0'; rc = StringToLineAndCol(lineText, &lineNum, &column); XtFree(value); if (rc == -1) { XBell(TheDisplay, 0); return; } /* User specified column, but not line number */ if ( lineNum == -1 ) { position = TextGetCursorPos(widget); if (TextPosToLineAndCol(widget, position, &lineNum, &curCol) == False) { XBell(TheDisplay, 0); return; } } /* User didn't specify a column */ else if ( column == -1 ) { SelectNumberedLine(window, lineNum); return; } position = TextLineAndColToPos(widget, lineNum, column ); if ( position == -1 ) { XBell(TheDisplay, 0); return; } TextSetCursorPos(widget, position); }
/* ** Execute the line of text where the the insertion cursor is positioned ** as a shell command. */ void ExecCursorLine(WindowInfo *window, int fromMacro) { char *cmdText; int left, right, insertPos; char *subsCommand, fullName[MAXPATHLEN]; int pos, line, column; char lineNumber[11]; /* Can't do two shell commands at once in the same window */ if (window->shellCmdData != NULL) { XBell(TheDisplay, 0); return; } /* get all of the text on the line with the insert position */ pos = TextGetCursorPos(window->lastFocus); if (!GetSimpleSelection(window->buffer, &left, &right)) { left = right = pos; left = BufStartOfLine(window->buffer, left); right = BufEndOfLine(window->buffer, right); insertPos = right; } else insertPos = BufEndOfLine(window->buffer, right); cmdText = BufGetRange(window->buffer, left, right); BufUnsubstituteNullChars(cmdText, window->buffer); /* insert a newline after the entire line */ BufInsert(window->buffer, insertPos, "\n"); /* Substitute the current file name for % and the current line number for # in the shell command */ strcpy(fullName, window->path); strcat(fullName, window->filename); TextPosToLineAndCol(window->lastFocus, pos, &line, &column); sprintf(lineNumber, "%d", line); subsCommand = shellCommandSubstitutes(cmdText, fullName, lineNumber); if (subsCommand == NULL) { DialogF(DF_ERR, window->shell, 1, "Shell Command", "Shell command is too long due to\n" "filename substitutions with '%%' or\n" "line number substitutions with '#'", "OK"); return; } /* issue the command */ issueCommand(window, subsCommand, NULL, 0, 0, window->lastFocus, insertPos+1, insertPos+1, fromMacro); free(subsCommand); XtFree(cmdText); }
/* ** Execute shell command "command", depositing the result at the current ** insert position or in the current selection if the window has a ** selection. */ void ExecShellCommand(WindowInfo *window, const char *command, int fromMacro) { int left, right, flags = 0; char *subsCommand, fullName[MAXPATHLEN]; int pos, line, column; char lineNumber[11]; /* Can't do two shell commands at once in the same window */ if (window->shellCmdData != NULL) { XBell(TheDisplay, 0); return; } /* get the selection or the insert position */ pos = TextGetCursorPos(window->lastFocus); if (GetSimpleSelection(window->buffer, &left, &right)) flags = ACCUMULATE | REPLACE_SELECTION; else left = right = pos; /* Substitute the current file name for % and the current line number for # in the shell command */ strcpy(fullName, window->path); strcat(fullName, window->filename); TextPosToLineAndCol(window->lastFocus, pos, &line, &column); sprintf(lineNumber, "%d", line); subsCommand = shellCommandSubstitutes(command, fullName, lineNumber); if (subsCommand == NULL) { DialogF(DF_ERR, window->shell, 1, "Shell Command", "Shell command is too long due to\n" "filename substitutions with '%%' or\n" "line number substitutions with '#'", "OK"); return; } /* issue the command */ issueCommand(window, subsCommand, NULL, 0, flags, window->lastFocus, left, right, fromMacro); free(subsCommand); }
/* ** Do a shell command, with the options allowed to users (input source, ** output destination, save first and load after) in the shell commands ** menu. */ void DoShellMenuCmd(WindowInfo *window, const char *command, int input, int output, int outputReplacesInput, int saveFirst, int loadAfter, int fromMacro) { int flags = 0; char *text; char *subsCommand, fullName[MAXPATHLEN]; int left, right, textLen; int pos, line, column; char lineNumber[11]; WindowInfo *inWindow = window; Widget outWidget; /* Can't do two shell commands at once in the same window */ if (window->shellCmdData != NULL) { XBell(TheDisplay, 0); return; } /* Substitute the current file name for % and the current line number for # in the shell command */ strcpy(fullName, window->path); strcat(fullName, window->filename); pos = TextGetCursorPos(window->lastFocus); TextPosToLineAndCol(window->lastFocus, pos, &line, &column); sprintf(lineNumber, "%d", line); subsCommand = shellCommandSubstitutes(command, fullName, lineNumber); if (subsCommand == NULL) { DialogF(DF_ERR, window->shell, 1, "Shell Command", "Shell command is too long due to\n" "filename substitutions with '%%' or\n" "line number substitutions with '#'", "OK"); return; } /* Get the command input as a text string. If there is input, errors shouldn't be mixed in with output, so set flags to ERROR_DIALOGS */ if (input == FROM_SELECTION) { text = BufGetSelectionText(window->buffer); if (*text == '\0') { XtFree(text); free(subsCommand); XBell(TheDisplay, 0); return; } flags |= ACCUMULATE | ERROR_DIALOGS; } else if (input == FROM_WINDOW) { text = BufGetAll(window->buffer); flags |= ACCUMULATE | ERROR_DIALOGS; } else if (input == FROM_EITHER) { text = BufGetSelectionText(window->buffer); if (*text == '\0') { XtFree(text); text = BufGetAll(window->buffer); } flags |= ACCUMULATE | ERROR_DIALOGS; } else /* FROM_NONE */ text = NULL; /* If the buffer was substituting another character for ascii-nuls, put the nuls back in before exporting the text */ if (text != NULL) { textLen = strlen(text); BufUnsubstituteNullChars(text, window->buffer); } else textLen = 0; /* Assign the output destination. If output is to a new window, create it, and run the command from it instead of the current one, to free the current one from waiting for lengthy execution */ if (output == TO_DIALOG) { outWidget = NULL; flags |= OUTPUT_TO_DIALOG; left = right = 0; } else if (output == TO_NEW_WINDOW) { EditNewFile(GetPrefOpenInTab()?inWindow:NULL, NULL, False, NULL, window->path); outWidget = WindowList->textArea; inWindow = WindowList; left = right = 0; CheckCloseDim(); } else { /* TO_SAME_WINDOW */ outWidget = window->lastFocus; if (outputReplacesInput && input != FROM_NONE) { if (input == FROM_WINDOW) { left = 0; right = window->buffer->length; } else if (input == FROM_SELECTION) { GetSimpleSelection(window->buffer, &left, &right); flags |= ACCUMULATE | REPLACE_SELECTION; } else if (input == FROM_EITHER) { if (GetSimpleSelection(window->buffer, &left, &right)) flags |= ACCUMULATE | REPLACE_SELECTION; else { left = 0; right = window->buffer->length; } } } else { if (GetSimpleSelection(window->buffer, &left, &right)) flags |= ACCUMULATE | REPLACE_SELECTION; else left = right = TextGetCursorPos(window->lastFocus); } } /* If the command requires the file be saved first, save it */ if (saveFirst) { if (!SaveWindow(window)) { if (input != FROM_NONE) XtFree(text); free(subsCommand); return; } } /* If the command requires the file to be reloaded after execution, set a flag for issueCommand to deal with it when execution is complete */ if (loadAfter) flags |= RELOAD_FILE_AFTER; /* issue the command */ issueCommand(inWindow, subsCommand, text, textLen, flags, outWidget, left, right, fromMacro); free(subsCommand); }