diff options
author | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
---|---|---|
committer | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
commit | 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch) | |
tree | 4464880c571602d54f6ae114729bf62a89518057 /pkg/ecl/edcap.c | |
download | iraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz |
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'pkg/ecl/edcap.c')
-rw-r--r-- | pkg/ecl/edcap.c | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/pkg/ecl/edcap.c b/pkg/ecl/edcap.c new file mode 100644 index 00000000..b06536af --- /dev/null +++ b/pkg/ecl/edcap.c @@ -0,0 +1,390 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#define import_stdio +#define import_libc +#define import_ctype +#define import_fset +#define import_spp +#include <iraf.h> + +#include "config.h" +#include "operand.h" +#include "param.h" +#include "task.h" +#include "eparam.h" +#include "proto.h" + + +#define COLWIDTH 40 /* column width for showhelp */ + + +/*------------------------------------------------------------------------- + * EDCAP.C -- Tools to support the edcap utility, used to define the input + * language of screen editors. + * + * External procedures: + * edtinit initialize the editor database and terminal + * edtexit terminate edit mode (may send output to terminal) + * host_editor return host command used to call the named editor + * what_cmd convert escape sequence into editor command + * show_editorhelp print a list of editor keystrokes + * + * Internal procedures: + * get_editor open and scan the EDCAP file + * cmd_match search the editor command list for an escape sequence + * map_escapes map encoded escape sequence from EDCAP file + * + *------------------------------------------------------------------------- + */ + +static char ed_editorcmd[SZ_LINE+1]; +static void map_escapes(); + + +/* EDTINIT -- Initialize the editor. + */ +void +edtinit (void) +{ + register int i; + char editor[SZ_FNAME]; /* the name of the editor */ + + /* See if the current editor is the one to use. If not, get the + * editor.ed definitions. + */ + if (c_envgets ("editor", editor, SZ_FNAME) > 0) + if (strcmp (editor, command[EDITOR_ID].keystroke) != 0) + get_editor (editor); + + /* Count the number of editor commands. + */ + numcommands = FIRST_CMD; + for (i=FIRST_CMD; command[i].cmd < NOMORE_COMMANDS; i++) + numcommands++; + + /* Send the initial edit sequence (to enable keypad, if any). + */ + if (*(command[EDIT_INIT].escape) != '\0') + printf ("%s",command[EDIT_INIT].escape); + + /* Enable transmission of the screen repaint sequence, to be returned + * by the terminal driver if the process is suspended and later + * resumed while in raw mode. + */ + for (i=FIRST_CMD; command[i].cmd < NOMORE_COMMANDS; i++) + if (command[i].cmd == REPAINT && strlen(command[i].escape)==1) + c_fseti ((XINT)STDOUT, F_SETREDRAW, command[i].escape[0]); +} + + +/* EDTEXIT -- Terminate the editor. Send an escape sequence to the terminal + * if necessary. + */ +void +edtexit (void) +{ + c_fseti ((XINT)STDOUT, F_SETREDRAW, 0); + if (*(command[EDIT_TERM].escape) != '\0') + printf ("%s",command[EDIT_TERM].escape); +} + + +/* HOST_EDITOR -- Return a pointer to the command string to be sent to the + * host system to run an editor, given the user name for the editor. + */ +char * +host_editor (char *editor) +{ + get_editor (editor); + return (ed_editorcmd); +} + + +/* GET_EDITOR -- Redefine the editor keystrokes from the editor.ed file. + * Search for that file first in the users home directory. If not found + * there, look in the standard device directory. + */ +void +get_editor ( + char *editor /* the name of the editor */ +) +{ + FILE *fp; /* pointer to the editor.ed file */ + char string[SZ_LINE];/* an edcap string from the .ed file */ + char label[SZ_LINE]; /* the key-sequence label (keyword) */ + char escape[SZ_LINE];/* the escape sequence in c octal */ + char name[SZ_LINE]; /* the keystroke name, for HELP */ + char fname[SZ_PATHNAME]; + int i, num, n; + + /* Search the directories for the edcap file editor.ed. + */ + sprintf (fname, "home$%s.ed", editor); + fp = fopen (fname, "r"); + + if (fp == NULL) { + sprintf (fname, "dev$%s.ed", editor); + fp = fopen (fname, "r"); + + if (fp == NULL) { + eprintf ("cannot find edcap file for `%s'\n", editor); + eprintf ("editor language defaults to `%s'\n", + command[EDITOR_ID].keystroke); + return; + } + } + + /* Parse the edcap file and initialize the command list and the host + * editor command string (default `irafvi', `irafemacs', etc.). + */ + sprintf (ed_editorcmd, "iraf%s", editor); + num = 0; + + while (fgets (string, SZ_LINE, fp) != NULL) { + /* Check for the EDITOR_CMD field, the command to be sent to the + * host system to run the editor. This is a special case since + * the edcap format does not support anything but keystrokes. + * A termcap format file should have been used for this + * database, rather than defining a new format file, then this + * would not have been necessary. + */ + if (strncmp (string, "EDITOR_CMD", 10) == 0) { + char *ip, *op; + char delim; + int isformat; + + /* Extract the optionally quoted host command format string. + * This is either the editor command name (prefix), e.g., + * "irafemacs", or an SPRINTF format string containing a %s + * where the filename(s) are to go. + */ + for (ip=string+10; isspace(*ip); ip++) + ; + delim = (*ip == '"' || *ip == '\'') ? *ip++ : 0; + for (op=ed_editorcmd, isformat=NO; (*op = *ip++); op++) { + if ((delim && *op == delim) || (!delim && isspace(*op))) + break; + else if (*op == '%' && *ip == 's') + isformat++; + } + + /* If the command string did not contain an embedded %s to + * indicate where the file names(s) are to go, add one at + * the end, i.e., "... %s". + */ + if (!isformat) { + *op++ = ' '; + *op++ = '%'; + *op++ = 's'; + } + + *op = EOS; + continue; + } + + /* Process a normal editor command into the command table. + * Each line must contain three tokens, the internal command + * name, the terminal escape sequence, and the keystroke name. + */ + n = sscanf (string, "%s %s %s", label, escape, name); + + if (n == 3) { + /* Determine which legitimate editor command this is. + */ + for (i=0; i < NUM_COMMANDS; i++) + if (strcmp (label, cmdnames[i]) == 0) + break; + + /* Stuff the command into the static command buffer. + */ + if (i < NUM_COMMANDS) { + command[num].cmd = i; + map_escapes (escape, label); + strncpy (command[num].escape, label, SZ_ESCAPE); + strncpy (command[num].keystroke, name, SZ_KEYSTROKE); + num++; + } + } + } + + /* Make sure the command buffer terminates here. + */ + command[num].cmd = NOMORE_COMMANDS; + strcpy (command[num].escape, ""); + strcpy (command[num].keystroke, " "); + + strncpy (command[EDITOR_ID].keystroke, editor, SZ_KEYSTROKE); + fclose (fp); +} + + +/* MAP_ESCAPES -- Take an ASCII string which may have escape sequences + * encoded as octal (\nnn). Copy the string to the output, replacing + * the encoded values with the binary character value. The output + * string may be the same as the input string. + * + * Control codes may be represented in the input in any of the following ways: + * + * ^X control-X + * \[befnrt] backspace, escape, formfeed, newline, return, tab + * \nnn octal constant + * \^ the character ^ + * \\ the character \ + * + * Ordinary characters are copied to the output. + */ +static void +map_escapes ( + char *input, /* pointer into input string */ + char *output /* pointer into output string */ +) +{ + static char *echars = "befnrt"; + static char *ecodes = "\b\033\f\n\r\t"; + register char *ip = input; + register char *op = output; + register int n; + char *index(); + + while (*ip != '\0') { + if (*ip == '\\') { + switch (*++ip) { + case 'b': case 'e': case 'f': + case 'n': case 'r': case 't': + *op++ = ecodes[index(echars,*ip++)-echars]; + break; + default: + if (isdigit (*ip)) { + for (n=0; isdigit(*ip) != 0; ip++) + n = n * 8 + (*ip - '0'); + *op++ = n; + } else + *op++ = *ip++; + } + } else if (*ip == '^') { + ip++; + *op++ = (*ip++ % 040); + } else + *op++ = *ip++; + } + + *op = '\0'; +} + + +/* WHAT_CMD -- Determine which editing command has been sent. Such commands + * must begin with a non-printable character. Return the command number or + * zero if unrecognized. We are called with the first character of the + * command (some control code). Additional keystrokes are read from the + * standard input until an editor command is recognized. + */ +int +what_cmd ( + int first_char /* the first unprintable character */ +) +{ + register int nchars, k; + char cmd_string[9]; + char *cmd; + + cmd = cmd_string; + *cmd = first_char; + + /* Loop until we get an exact match or until we get no match. + * A character is read from the standard input in each pass + * through the loop. + */ + for (nchars=1; nchars < 9; nchars++) + if ((k = cmd_match (cmd_string, nchars)) < 0) + return (0); + else if (nchars == strlen (command[k].escape)) + return (command[k].cmd); + else + *(++cmd) = fgetc(stdin); + + return (0); +} + + +/* CMD_MATCH -- Scan the first nchars of the available commands to see if + * any match the command string. Return -1 if the command string does not + * match any editor escape sequence, else return the index of the first + * command code matched. + */ +int +cmd_match ( + char *cstring, /* command string */ + int nchars /* nchars to compare */ +) +{ + int k; + + for (k=FIRST_CMD; k <= numcommands; k++) + if (strncmp (cstring, command[k].escape, nchars) == 0) + return (k); + + return (-1); +} + + +/* SHOW_EDITORHELP -- Display the edit commands and their keystroke + * equivalences. + */ +void +show_editorhelp (void) +{ + char sbuf[MAX_COMMANDS*COLWIDTH]; + char *strp[MAX_COMMANDS]; + int center, maxcols, firstcol, lastcol, nstrs, i; + int save_raw; + + maxcols = c_envgeti ("ttyncols"); + center = maxcols / 2; + + /* Disable raw mode output so that output processing will be enabled, + * e.g., to map newlines into crlfs. + */ + save_raw = c_fstati ((XINT)STDOUT, F_RAW); + c_fseti ((XINT)STDOUT, F_RAW, NO); + + /* Format the help strings for the individual keystrokes. + */ + for (i=FIRST_CMD, nstrs=0; i <= numcommands; i++) + if (*(command[i].escape) != '\0') { + strp[nstrs] = &sbuf[nstrs*COLWIDTH]; + sprintf (strp[nstrs], "%8w%-10.10s = %-11.11s%2w", + cmdnames[command[i].cmd], command[i].keystroke); + nstrs++; + } + + e_clear(); + e_goto (center - 7, 1); + e_putline ("EDIT COMMANDS ("); + e_putline (command[EDITOR_ID].keystroke); + e_putline (")\n\n"); + + /* Sort and output the string table. + */ + if (nstrs) { + strsort (strp, nstrs); + i = strlen (strp[0]); + firstcol = center - i - 2; + lastcol = center + i + 2; + strtable (stdout, strp, nstrs, firstcol, lastcol, COLWIDTH, 2); + } + + e_putline ("\n"); + e_ctrl ("so"); + e_putline ("[hit any key to continue]"); + e_ctrl ("se"); + + /* Restore raw mode. + */ + c_fseti ((XINT)STDOUT, F_RAW, save_raw); + + fflush (stdout); + + /* Pause. */ + fgetc (stdin); +} |