[comp.sources.x] v10i011: exedit, Part01/01

gustav@arp.anu.oz.au (Zdzislaw Meglicki) (10/24/90)

Submitted-by: gustav@arp.anu.oz.au (Zdzislaw Meglicki)
Posting-number: Volume 10, Issue 11
Archive-name: exedit/part01

[ moderator's note:
    This was originally posted as Volume 9, Issue 65, but just about
    every news site doesn't have it, so I'm reposting it.  I'm not
    posting it as a "REPOST" because the autho sent me an updated
    version.  So, archive sites should scrap issue 65 from vol 9
    and leave a hole :-)  --dan
]

               Program  exedit is  based  on  the  MIT  X11R4  program
          xedit.   Exedit  adds  some  new  functionality  to  xedit -
          mainly in the area of communicating with other processes. If
          you have ever worked with Apple's  MPW shell you will recog-
          nize some similarity.  Exedit, like  MPW  shell,  allows  to
          execute shell commands and selected programs from within the
          editing environment of xedit. When you  start  exedit,  your
          shell  of  choice,  as  defined by the evironmental variable
          SHELL, is invoked in the background.  If  you  have  a  file
          called   .exeditrc in your HOME directory, this file will be
          sourced into your shell. Whenever you type Shift-Return, the
          whole  line  on which the cursor resides will be sent to the
          shell. If that line begins with a prompt string, you can ask
          exedit  to  skip that string by making an appropriate selec-
          tion from the  prompts menu. If you have made a text  selec-
          tion  in  the editing window and you press  Shift-Return the
          whole selection will be sent to the shell. But  prompt  will
          not  be  skipped in this case. You can send a complex multi-
          line commands to the shell this way. You can even paste such
          multiline  commands  by selecting various parts from various
          places in your input file.

============================== cut here =================================
# This is a shell archive.  Remove anything before this line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# This archive contains the following files:
#	./exedit.0.91/exedit.c
#	./exedit.0.91/EXedit.ad
#	./exedit.0.91/Imakefile
#	./exedit.0.91/Makefile
#	./exedit.0.91/README
#	./exedit.0.91/exedit.man
#	./exedit.0.91/patchlevel.h
#
if `test ! -d ./exedit.0.91`
then
  mkdir ./exedit.0.91
  echo "mkdir ./exedit.0.91"
fi
if `test ! -s ./exedit.0.91/exedit.c`
then
echo "writing ./exedit.0.91/exedit.c"
cat > ./exedit.0.91/exedit.c << '\Rogue\Monster\'

#if(0)
FTANGLE         v1 .13 a, tangled with SunOS / UNIX on "Tuesday, August 7, 1990 at 23:52."
                COMMAND LINE:"ftangle exedit"
                RUN TIME:"Tuesday, October 23, 1990 at 15:50."
                WEB FILE NAME:"exedit.web"
                CHANGE FILE NAME:"/dev/null"
#endif

/* 1: */
#line 148 "exedit.web"


#ifndef lint
static char     src_id[] =
"$ANU: exedit.c, v 0.91, 3 Oct 90, 23:36:48 UTC, gustav@arp.anu.oz.au$";

#endif

/*
 * \ COPYRIGHT 1987, \ DIGITAL EQUIPMENT CORPORATION, \ MAYNARD,
 * MASSACHUSETTS, \ ALL RIGHTS RESERVED. \ \ THE INFORMATION IN THIS SOFTWARE
 * IS SUBJECT TO CHANGE WITHOUT NOTICE AND \ SHOULD NOT BE CONSTRUED AS A
 * COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. \ DIGITAL MAKES NO
 * REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR \ ANY PURPOSE.
 * IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. \ \ IF THE
 * SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, \
 * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO
 * THAT \ SET FORTH ABOVE. \ \ \ Permission to use, copy, modify, and
 * distribute this software and its \ documentation for any purpose and
 * without fee is hereby granted, provided \ that the above copyright notice
 * appear in all copies and that both that \ copyright notice and this
 * permission notice appear in supporting \ documentation, and that the name
 * of Digital Equipment Corporation not be \ used in advertising or publicity
 * pertaining to distribution of the software \ without specific, written
 * prior permission. \ \
 */

/* :1 *//* 2: */
#line 184 "exedit.web"


/*
 * \ COPYRIGHT 1990, \ THE AUSTRALIAN NATIONAL UNIVERSITY, \ CANBERRA,
 * AUSTRALIAN CAPITAL TERRITORY, \ AUSTRALIA, \ ALL RIGHTS RESERVED. \ \ THE
 * INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND \
 * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY THE AUSTRALIAN NATIONAL
 * UNIVERSITY. \ THE AUSTRALIAN NATIONAL UNIVERSITY MAKES NO REPRESENTATIONS
 * ABOUT THE \ SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  IT IS SUPPLIED
 * "AS IS" WITHOUT \ EXPRESS OR IMPLIED WARRANTY. \ \ IF THE SOFTWARE IS
 * MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, \ APPROPRIATE
 * LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT \ SET
 * FORTH ABOVE. \ \ \ Permission to use, copy, modify, and distribute this
 * software and its \ documentation for any purpose and without fee is hereby
 * granted, provided \ that the above copyright notice appear in all copies
 * and that both that \ copyright notice and this permission notice appear in
 * supporting \ documentation, and that the name of the Australian National
 * University not be \ used in advertising or publicity pertaining to
 * distribution of the software \ without specific, written prior permission.
 * \ \
 */


/* :2 *//* 3: */
#line 228 "exedit.web"


/* 6: */
#line 335 "exedit.web"


#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/cursorfont.h>
#include <X11/Xatom.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/Cardinals.h>

/* :6 */
#line 230 "exedit.web"


/* 5: */
#line 327 "exedit.web"


Widget          top;

/* :5 *//* 7: */
#line 393 "exedit.web"


#define EXedit

Display        *CurDpy;

struct _app_resources
{
   Boolean         enableBackups;
   char           *backupNamePrefix;
   char           *backupNameSuffix;

#ifdef EXedit
   char           *prompt1;
   char           *prompt2;
   char           *prompt3;
   char           *prompt4;
   char           *prompt5;
   char           *prompt6;
   char           *prompt7;
   char           *prompt8;
   char           *prompt9;
#endif
}               app_resources;

#define offset(field) XtOffset(struct _app_resources*, field)
XtResource      resources[] = {
   {"enableBackups", "EnableBackups", XtRBoolean, sizeof(Boolean),
   offset(enableBackups), XtRImmediate, FALSE},
   {"backupNamePrefix", "BackupNamePrefix", XtRString, sizeof(char *),
   offset(backupNamePrefix), XtRString, ""},
   {"backupNameSuffix", "BackupNameSuffix", XtRString, sizeof(char *),
   offset(backupNameSuffix), XtRString, ".BAK"},

#ifdef EXedit
   {"prompt1", "Prompt1", XtRString, sizeof(char *),
   offset(prompt1), XtRString, "none"},
   {"prompt2", "Prompt2", XtRString, sizeof(char *),
   offset(prompt2), XtRString, "$"},
   {"prompt3", "Prompt3", XtRString, sizeof(char *),
   offset(prompt3), XtRString, "%"},
   {"prompt4", "Prompt4", XtRString, sizeof(char *),
   offset(prompt4), XtRString, "#"},
   {"prompt5", "Prompt5", XtRString, sizeof(char *),
   offset(prompt5), XtRString, ">"},
   {"prompt6", "Prompt6", XtRString, sizeof(char *),
   offset(prompt6), XtRString, ":"},
   {"prompt7", "Prompt7", XtRString, sizeof(char *),
   offset(prompt7), XtRString, "-"},
   {"prompt8", "Prompt8", XtRString, sizeof(char *),
   offset(prompt8), XtRString, "?"},
   {"prompt9", "Prompt9", XtRString, sizeof(char *),
   offset(prompt9), XtRString, "]"},
#endif
};

#undef offset

/* :7 *//* 10: */
#line 528 "exedit.web"


typedef enum
{
   NO_READ, READ_OK, WRITE_OK
}               FileAccess;

/* :10 *//* 17: */
#line 817 "exedit.web"


void            DoQuit();
void            DoSave();
void            DoLoad();
Widget          filenamewindow;

/* :17 *//* 19: */
#line 866 "exedit.web"


Widget          messwidget;
Widget          labelwindow;

/* :19 *//* 21: */
#line 895 "exedit.web"


Widget          textwindow;
void            ResetSourceChanged();

/* :21 *//* 25: */
#line 1024 "exedit.web"


Boolean         source_changed = FALSE;

/* :25 *//* 27: */
#line 1086 "exedit.web"


Boolean         double_click = FALSE;

/* :27 *//* 40: */
#line 1571 "exedit.web"


typedef enum
{
   IN_PLACE, APPEND
}               PrintMode;

/* :40 *//* 49: */
#line 2010 "exedit.web"


#include <signal.h>

int             master, child;
extern int      errno;

/* :49 *//* 64: */
#line 2621 "exedit.web"


#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/SmeLine.h>

#define NUM_MENU_ITEMS 3

String          menu_entry_names[NUM_MENU_ITEMS] = {
   "append",
   "verbose",
   "debug",
};

#define P_NUM_MENU_ITEMS 9

String          p_menu_entry_names[P_NUM_MENU_ITEMS] = {
   "long_prompt",
   "long_prompt",
   "long_prompt",
   "long_prompt",
   "long_prompt",
   "long_prompt",
   "long_prompt",
   "long_prompt",
   "long_prompt",
};

Widget          p_entry[P_NUM_MENU_ITEMS];
char            prompt[BUFSIZ] = "long_prompt";

Boolean         status[NUM_MENU_ITEMS] = {FALSE, FALSE, FALSE,};
Boolean         p_status[P_NUM_MENU_ITEMS] = {TRUE, FALSE, FALSE, FALSE,
   FALSE, FALSE, FALSE, FALSE,
FALSE};

#define checkmark_width 10
#define checkmark_height 10
static char     checkmark_bits[] = {
   0x00, 0x02, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0xc6, 0x00, 0xcc, 0x00,
0x78, 0x00, 0x78, 0x00, 0x30, 0x00, 0x30, 0x00};
static Pixmap   mark;

/* :64 */
#line 232 "exedit.web"


void 
main(argc, argv)
   int             argc;
   char          **argv;

{

   /* 8: */
#line 469 "exedit.web"


   String          filename = NULL;
   extern void     makeButtonsAndBoxes();
   extern FileAccess CheckFilePermissions();

   /* :8 *//* 43: */
#line 1637 "exedit.web"


   extern void     WriteToShell();

   static XtActionsRec the_actions[] = {
   {"shell", WriteToShell},};

   /* :43 *//* 50: */
#line 2019 "exedit.web"


   extern int      GetMaster();

   /* :50 *//* 58: */
#line 2387 "exedit.web"


   extern void     SendDirect();

   static XtActionsRec more_actions[] = {{"direct", SendDirect},};

   /* :58 */
#line 240 "exedit.web"


   /* 48: */
#line 1986 "exedit.web"


   if ((master = GetMaster()) <= 0)
   {
      perror("exedit: cannot open a pseudo-terminal");
      exit(errno);
   }
   if ((child = fork()) < 0)
   {
      perror("exedit: cannot fork");
      exit(errno);
   }
   if (child == 0)
   {
      /* This is the child process */

      /* 52: */
#line 2115 "exedit.web"


      int             grandchild;
      extern void     DoShell(), WakeUp();

      signal(SIGALRM, WakeUp);

#if(0)
      alarm(10);
#endif

      pause();

      DoShell();

      /* :52 */
#line 2001 "exedit.web"


      exit;
   }
   /* The rest is the parent. The child must exit before it gets here. */

   /* :48 */
#line 242 "exedit.web"


   /* 4: */
#line 309 "exedit.web"


   top = XtInitialize("exedit", "EXedit", NULL, 0, &argc, argv);
   XtGetApplicationResources(top, &app_resources, resources,
			     XtNumber(resources), NULL, 0);
   CurDpy = XtDisplay(top);

   /* :4 *//* 42: */
#line 1607 "exedit.web"


   XtAddActions(the_actions, XtNumber(the_actions));

   /* :42 *//* 59: */
#line 2403 "exedit.web"


   XtAddActions(more_actions, XtNumber(more_actions));

   /* :59 */
#line 244 "exedit.web"


   /* 9: */
#line 495 "exedit.web"


   if (argc > 1)
   {
      Boolean         exists;

      filename = argv[1];

      switch (CheckFilePermissions(filename, &exists))
      {
      case NO_READ:
	 if (exists)
	    fprintf(stderr,
		    "File %s exists, and could not opened for reading.\n",
		    filename);
	 else
	    fprintf(stderr, "File %s %s %s", filename, "does not exist,",
		    "and the directory could not be opened for writing.\n");
	 exit(1);
      case READ_OK:
      case WRITE_OK:
	 makeButtonsAndBoxes(top, filename);
	 break;
      default:
	 fprintf(stderr, "%s %s", "Internal function MaybeCreateFile()",
		 "returned unexpected value.\n");
	 exit(1);
      }
   } else
      makeButtonsAndBoxes(top, NULL);

   /* :9 */
#line 246 "exedit.web"


   /* 11: */
#line 571 "exedit.web"


   XtRealizeWidget(top);
   XDefineCursor(CurDpy, XtWindow(top),
		 XCreateFontCursor(CurDpy, XC_left_ptr));

   /* 54: */
#line 2172 "exedit.web"


   {

      extern XtInputCallbackProc ReadPipe();
      char            message[BUFSIZ];
      extern void     XeditPrintf();

      sprintf(message, "shell pid = %d\n", (int) child);
      XeditPrintf(messwidget, message, APPEND);

      XtAddInput(master, XtInputReadMask, ReadPipe, NULL);

      kill(child, SIGALRM);

   }


   /* :54 */
#line 577 "exedit.web"


   XtMainLoop();

   /* :11 */
#line 248 "exedit.web"


}

/* :3 *//* 12: */
#line 608 "exedit.web"


#include <X11/Xos.h>

FileAccess 
CheckFilePermissions(file, exists)

   char           *file;
   Boolean        *exists;

{

   char            temp[BUFSIZ], *ptr;

   /* 13: */
#line 632 "exedit.web"


   if (access(file, F_OK) == 0)
   {
      *exists = TRUE;

      if (access(file, R_OK) != 0)
	 return (NO_READ);

      if (access(file, R_OK | W_OK) == 0)
	 return (WRITE_OK);

      return (READ_OK);
   }
   /* :13 */
#line 621 "exedit.web"


   /* 14: */
#line 660 "exedit.web"


   *exists = FALSE;

   strcpy(temp, file);
   if ((ptr = rindex(temp, '/')) == NULL)
      strcpy(temp, ".");
   else
      *ptr = '\0';

   if (access(temp, R_OK | W_OK | X_OK) == 0)
      return (WRITE_OK);
   return (NO_READ);


   /* :14 */
#line 623 "exedit.web"


}

/* :12 *//* 15: */
#line 715 "exedit.web"


void 
makeButtonsAndBoxes(parent, filename)
   Widget          parent;
   char           *filename;

{

   Widget          outer, b_row;
   Arg             arglist[10];
   Cardinal        num_args;
   extern Widget   MakeCommandButton();
   extern Widget   MakeStringBox();

#ifdef EXedit
   Widget          m_row;

#endif


   outer = XtCreateManagedWidget("paned", panedWidgetClass,
				 parent, NULL, ZERO);

   /* 16: */
#line 789 "exedit.web"


   b_row = XtCreateManagedWidget("buttons", panedWidgetClass, outer, NULL, ZERO);
   {
      MakeCommandButton(b_row, "quit", DoQuit);
      MakeCommandButton(b_row, "save", DoSave);
      MakeCommandButton(b_row, "load", DoLoad);
      filenamewindow = MakeStringBox(b_row, "filename", filename);
   }

#ifndef EXedit
   XtCreateManagedWidget("bc_label", labelWidgetClass, outer, NULL, ZERO);

#else

   m_row = XtCreateManagedWidget("menus", panedWidgetClass, outer, NULL, ZERO);
   {
      /* 61: */
#line 2487 "exedit.web"


      Widget          m_button, menu, entry, p_button, p_menu;
      extern void     MenuSelect(), PMenuSelect();
      extern Widget   p_entry[P_NUM_MENU_ITEMS];
      Arg             arg_list[1];
      Cardinal        i;

      mark = XCreateBitmapFromData(CurDpy, RootWindowOfScreen(XtScreen(top)),
			 checkmark_bits, checkmark_width, checkmark_height);

      /* 62: */
#line 2530 "exedit.web"


      i = 0;
      XtSetArg(arg_list[i], XtNmenuName, "menu");
      i++;

#if(0)
      m_button = XtCreateManagedWidget("settings", menuButtonWidgetClass,
				       m_row, arg_list, i);
#endif

      m_button = XtCreateManagedWidget("settings", menuButtonWidgetClass,
				       b_row, arg_list, i);
      menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, m_button,
				NULL, NULL);

      for (i = 0; i < NUM_MENU_ITEMS; i++)
      {
	 String          item = menu_entry_names[i];

	 entry = XtCreateManagedWidget(item, smeBSBObjectClass,
				       menu, NULL, NULL);
	 XtAddCallback(entry, XtNcallback, MenuSelect, (caddr_t) i);
      }


      /* :62 */
#line 2498 "exedit.web"


      /* 63: */
#line 2563 "exedit.web"


      i = 0;
      XtSetArg(arg_list[i], XtNmenuName, "p_menu");
      i++;

#if(0)
      p_button = XtCreateManagedWidget("prompts", menuButtonWidgetClass,
				       m_row, arg_list, i);
#endif

      p_button = XtCreateManagedWidget("prompts", menuButtonWidgetClass,
				       b_row, arg_list, i);
      p_menu = XtCreatePopupShell("p_menu", simpleMenuWidgetClass, p_button,
				  NULL, NULL);

      strcpy(p_menu_entry_names[0], app_resources.prompt1);
      strcpy(p_menu_entry_names[1], app_resources.prompt2);
      strcpy(p_menu_entry_names[2], app_resources.prompt3);
      strcpy(p_menu_entry_names[3], app_resources.prompt4);
      strcpy(p_menu_entry_names[4], app_resources.prompt5);
      strcpy(p_menu_entry_names[5], app_resources.prompt6);
      strcpy(p_menu_entry_names[6], app_resources.prompt7);
      strcpy(p_menu_entry_names[7], app_resources.prompt8);
      strcpy(p_menu_entry_names[8], app_resources.prompt9);
      strcpy(prompt, app_resources.prompt1);

      for (i = 0; i < P_NUM_MENU_ITEMS; i++)
      {

	 String          item = p_menu_entry_names[i];

	 p_entry[i] = XtCreateManagedWidget(item, smeBSBObjectClass,
					    p_menu, NULL, NULL);
	 XtAddCallback(p_entry[i], XtNcallback, PMenuSelect, (caddr_t) i);
      }

      i = 0;
      XtSetArg(arg_list[i], XtNleftBitmap, mark);
      i++;
      XtSetValues(p_entry[0], arg_list, i);

      /* :63 */
#line 2500 "exedit.web"



      /* :61 */
#line 807 "exedit.web"


      XtCreateManagedWidget("bc_label", labelWidgetClass, m_row, NULL, ZERO);
   }
#endif

   /* :16 */
#line 739 "exedit.web"


   /* 18: */
#line 849 "exedit.web"


   num_args = 0;
   XtSetArg(arglist[num_args], XtNeditType, XawtextEdit);
   num_args++;
   messwidget = XtCreateManagedWidget("messageWindow", asciiTextWidgetClass,
				      outer, arglist, num_args);

   num_args = 0;
   if (filename != NULL)
      XtSetArg(arglist[num_args], XtNlabel, filename);
   num_args++;

   labelwindow = XtCreateManagedWidget("labelWindow", labelWidgetClass,
				       outer, arglist, num_args);

   /* :18 */
#line 741 "exedit.web"


   /* 20: */
#line 879 "exedit.web"


   num_args = 0;
   XtSetArg(arglist[num_args], XtNtype, XawAsciiFile);
   num_args++;
   XtSetArg(arglist[num_args], XtNeditType, XawtextEdit);
   num_args++;
   textwindow = XtCreateManagedWidget("editWindow", asciiTextWidgetClass,
				      outer, arglist, num_args);

   if (filename != NULL)
      DoLoad();
   else
      ResetSourceChanged(textwindow);

   /* :20 */
#line 743 "exedit.web"


}

/* :15 *//* 22: */
#line 930 "exedit.web"


Widget 
MakeCommandButton(box, name, function)

   Widget          box;
   char           *name;
   XtCallbackProc  function;

{

   Widget          w = XtCreateManagedWidget(name, commandWidgetClass, box, NULL, ZERO);

   if (function != NULL)
      XtAddCallback(w, XtNcallback, function, (caddr_t) NULL);
   return w;

}

/* :22 *//* 23: */
#line 957 "exedit.web"


Widget 
MakeStringBox(parent, name, string)
   Widget          parent;
   String          name, string;
{

   Arg             args[5];
   Cardinal        numargs = 0;
   Widget          StringW;

   XtSetArg(args[numargs], XtNeditType, XawtextEdit);
   numargs++;
   XtSetArg(args[numargs], XtNstring, string);
   numargs++;

   StringW = XtCreateManagedWidget(name, asciiTextWidgetClass,
				   parent, args, numargs);
   return (StringW);

}

/* :23 *//* 24: */
#line 998 "exedit.web"


void 
SourceChanged(w, junk, garbage)
   Widget          w;
   XtPointer       junk, garbage;

{

   XtRemoveCallback(w, XtNcallback, SourceChanged, NULL);
   source_changed = TRUE;

}

void 
ResetSourceChanged(widget)
   Widget          widget;

{

   XtAddCallback(XawTextGetSource(widget), XtNcallback, SourceChanged, NULL);
   source_changed = FALSE;

}

/* :24 *//* 26: */
#line 1051 "exedit.web"


void 
Feep()

{

   XBell(CurDpy, 0);

}

void 
DoQuit()

{

   extern void     AddDoubleClickCallback();
   extern void     XeditPrintf();
   extern int      child;

   if (double_click || !source_changed)
   {

#ifdef EXedit
      killpg(getpgrp(child), SIGKILL);
#endif

      exit(0);
   }
   XeditPrintf(messwidget, "Unsaved changes. Save them, or press Quit again.\n",
	       APPEND);
   Feep();
   double_click = TRUE;
   AddDoubleClickCallback(textwindow, TRUE);

}

/* :26 *//* 28: */
#line 1114 "exedit.web"


void 
AddDoubleClickCallback(w, state)
   Widget          w;
   Boolean         state;

{

   extern void     ResetDC();
   Arg             args[1];
   static XtCallbackRec cb[] = {{NULL, NULL}, {NULL, NULL}};

   if (state)
      cb[0].callback = ResetDC;
   else
      cb[0].callback = NULL;

   XtSetArg(args[0], XtNcallback, cb);
   XtSetValues(w, args, ONE);

}

void 
ResetDC(w, junk, garbage)
   Widget          w;
   caddr_t         junk, garbage;

{

   double_click = FALSE;
   AddDoubleClickCallback(w, FALSE);

}

/* :28 *//* 29: */
#line 1157 "exedit.web"


void 
DoSave()

{

   extern String   GetString();
   extern FileAccess MaybeCreateFile();
   String          filename = GetString(filenamewindow);
   char            buf[BUFSIZ];

   if ((filename == NULL) || (strlen(filename) == 0))
   {
      XeditPrintf(messwidget,
		  "Save: no file name specified -- nothing saved\n",
		  APPEND);
      Feep();
      return;
   }
   /* 31: */
#line 1222 "exedit.web"


   if (app_resources.enableBackups)
   {

      extern char    *makeBackupName();
      char            backup_file[BUFSIZ];

      makeBackupName(backup_file, filename);

      if (rename(filename, backup_file) != 0)
      {
	 sprintf(buf, "error backing up file:  %s\n", backup_file);
	 XeditPrintf(messwidget, buf, APPEND);
      }
   }
   /* :31 */
#line 1176 "exedit.web"


   /* 33: */
#line 1272 "exedit.web"


   switch (MaybeCreateFile(filename))
   {
   case NO_READ:
   case READ_OK:
      sprintf(buf, "File %s could not be opened for writing.\n", filename);
      break;
   case WRITE_OK:
      if (XawAsciiSaveAsFile(XawTextGetSource(textwindow), filename))
      {
	 sprintf(buf, "Saved file:  %s\n", filename);
	 ResetSourceChanged(textwindow);
      } else
	 sprintf(buf, "Error saving file:  %s\n", filename);
      break;
   default:
      sprintf(buf, "%s %s", "Internal function MaybeCreateFile()",
	      "returned unexpected value.\n");
   }

   XeditPrintf(messwidget, buf, APPEND);

   /* :33 */
#line 1178 "exedit.web"


}

/* :29 *//* 30: */
#line 1194 "exedit.web"


String 
GetString(w)
   Widget          w;

{

   String          str;
   Arg             arglist[1];

   XtSetArg(arglist[0], XtNstring, &str);
   XtGetValues(w, arglist, ONE);
   return (str);

}

/* :30 *//* 32: */
#line 1245 "exedit.web"


char           *
makeBackupName(buf, filename)
   String          buf, filename;

{

   sprintf(buf, "%s%s%s", app_resources.backupNamePrefix,
	   filename, app_resources.backupNameSuffix);
   return (buf);

}

/* :32 *//* 34: */
#line 1306 "exedit.web"


FileAccess 
MaybeCreateFile(file)
   char           *file;

{

   Boolean         exists;

   if (access(file, F_OK) != 0)
      creat(file, 0777);

   return (CheckFilePermissions(file, &exists));

}

/* :34 *//* 35: */
#line 1341 "exedit.web"


void 
DoLoad()

{

   Arg             args[5];
   Cardinal        num_args = 0;
   String          filename = GetString(filenamewindow);
   char            buf[BUFSIZ], label_buf[BUFSIZ];

   /* 36: */
#line 1374 "exedit.web"


   if (source_changed && !double_click)
   {
      XeditPrintf(messwidget,
		  "Unsaved changes. Save them, or press Load again.\n",
		  APPEND);
      Feep();
      double_click = TRUE;
      AddDoubleClickCallback(textwindow, TRUE);
      return;
   }
   /* :36 */
#line 1352 "exedit.web"


   /* 37: */
#line 1402 "exedit.web"


   double_click = FALSE;

   if ((filename != NULL) && (strlen(filename) > 0))
   {
      Boolean         exists;

      switch (CheckFilePermissions(filename, &exists))
      {
      case NO_READ:
	 if (exists)
	    sprintf(buf, "File %s, %s", filename,
		    "exists, and could not be opened for reading.\n");
	 else
	    sprintf(buf, "File %s %s %s", filename, "does not exist, and",
		    "the directory could not be opened for writing.\n");

	 XeditPrintf(messwidget, buf, APPEND);
	 Feep();
	 return;
      case READ_OK:
	 XtSetArg(args[num_args], XtNeditType, XawtextRead);
	 num_args++;
	 sprintf(label_buf, "%s       READ ONLY", filename);
	 sprintf(buf, "File %s opened READ ONLY.\n", filename);
	 break;
      case WRITE_OK:
	 XtSetArg(args[num_args], XtNeditType, XawtextEdit);
	 num_args++;
	 sprintf(label_buf, "%s       Read - Write", filename);
	 sprintf(buf, "File %s opened read - write.\n", filename);
	 break;
      default:
	 sprintf(buf, "%s %s", "Internal function MaybeCreateFile()",
		 "returned unexpected value.\n");
	 XeditPrintf(messwidget, buf, APPEND);
	 return;
      }

      XeditPrintf(messwidget, buf, APPEND);

      if (exists)
      {
	 XtSetArg(args[num_args], XtNstring, filename);
	 num_args++;
      } else
      {
	 XtSetArg(args[num_args], XtNstring, NULL);
	 num_args++;
      }

      XtSetValues(textwindow, args, num_args);

      num_args = 0;
      XtSetArg(args[num_args], XtNlabel, label_buf);
      num_args++;
      XtSetValues(labelwindow, args, num_args);
      ResetSourceChanged(textwindow);
      return;
   }
   /* :37 */
#line 1354 "exedit.web"


   /* 38: */
#line 1459 "exedit.web"


   XeditPrintf(messwidget, "Load: No file specified.\n", APPEND);
   Feep();

   /* :38 */
#line 1356 "exedit.web"


}


/* :35 *//* 39: */
#line 1532 "exedit.web"


void 
XeditPrintf(w, str, mode)
   Widget          w;
   char           *str;
   PrintMode       mode;

{

   XawTextBlock    text;
   XawTextPosition pos;

   text.length = strlen(str);
   text.ptr = str;
   text.firstPos = 0;
   text.format = FMT8BIT;

   switch (mode)
   {
   case IN_PLACE:
      pos = XawTextSourceScan(XawTextGetSource(w),
			      XawTextGetInsertionPoint(w), XawstEOL,
			      XawsdRight, 1, FALSE);
      break;
   case APPEND:
      pos = XawTextSourceScan(XawTextGetSource(w),
			      XawTextGetInsertionPoint(w), XawstAll,
			      XawsdRight, 1, TRUE);
      break;
   }

   XawTextReplace(w, pos, pos, &text);

   pos += text.length;
   XawTextSetInsertionPoint(w, pos);

}

/* :39 *//* 44: */
#line 1681 "exedit.web"

void 
WriteToShell(w, event, params, num_params)
   Widget          w;
   XKeyPressedEvent *event;
   String         *params;
   Cardinal       *num_params;

{
   extern void     Feep(), XeditPrintf(), free();
   extern String   ReadSelection();
   extern Boolean  status[NUM_MENU_ITEMS];
   extern Widget   messwidget, textwindow;
   extern int      master;
   String          mystring;
   int             length;

   if ((mystring = ReadSelection(w)) != NULL)
   {
      length = strlen(mystring);

      if (status[2])
	 fprintf(stderr, mystring);
      if (status[1])
	 XeditPrintf(messwidget, mystring, APPEND);
      write(master, mystring, sizeof(char) * length);

      if (mystring[length - 1] != '\n')
      {

	 if (status[2])
	    fprintf(stderr, "\n");
	 if (status[1])
	    XeditPrintf(messwidget, "\n", APPEND);
	 write(master, "\n", sizeof(char));
      }
      if (!status[0])
	 XeditPrintf(textwindow, "\n", IN_PLACE);
      else
	 XeditPrintf(textwindow, "\n", APPEND);
   }
}

/* :44 *//* 45: */
#line 1773 "exedit.web"


String 
ReadSelection(w)
   Widget          w;

{

   extern char    *malloc();
   extern char     prompt[BUFSIZ];
   extern char    *strchr();
   XawTextPosition begin_return, newbegin, end_return, length, newlength, returned, newreturned;
   static String   mystring, newstring;
   String          thestring;
   static int      lastsize = 0;
   XawTextBlock    text_block;
   Boolean         finished, single_line = FALSE;
   char           *ch;

   XawTextGetSelectionPos(w, &begin_return, &end_return);

   if (begin_return == end_return)
   {

      single_line = TRUE;

      /* 46: */
#line 1863 "exedit.web"


      begin_return = XawTextSourceScan(XawTextGetSource(w),
				       XawTextGetInsertionPoint(w),
				       XawstEOL, XawsdLeft, 1, FALSE);
      end_return = XawTextSourceScan(XawTextGetSource(w),
				     XawTextGetInsertionPoint(w),
				     XawstEOL, XawsdRight, 1, TRUE);

      /* :46 */
#line 1798 "exedit.web"


   }
   if (begin_return < end_return)
   {

      length = end_return - begin_return;
      if (length + 1 > lastsize)
      {
	 lastsize = length + 1;
	 mystring = malloc(lastsize * sizeof(char));
      }
      /* 47: */
#line 1925 "exedit.web"


      newbegin = begin_return;
      newlength = length;
      newstring = mystring;
      do
      {
	 returned = XawTextSourceRead(XawTextGetSource(w), newbegin,
				      &text_block, newlength);
	 if (returned < newlength)
	 {
	    strncpy(newstring, text_block.ptr, returned);
	    if ((newreturned = strlen(newstring)) < returned)
	       returned = newreturned;
	    newstring += returned;
	    newbegin += returned;
	    newlength -= returned;
	    finished = FALSE;
	 } else
	 {
	    strncpy(newstring, text_block.ptr, newlength);
	    if ((newreturned = strlen(newstring)) < newlength)
	    {
	       returned = newreturned;
	       newstring += returned;
	       newbegin += returned;
	       newlength -=
		  returned;
	       finished = FALSE;
	    } else
	       finished = TRUE;
	 }
      } while (!finished);
      *(mystring + length) = '\0';

      /* :47 */
#line 1810 "exedit.web"


      if (single_line)
      {
	 if (strcmp(prompt, "none") != 0)
	 {
	    if ((ch = strchr(mystring, *prompt)) != NULL)
	       thestring = ++ch;
	    else
	       thestring = mystring;
	 } else
	    thestring = mystring;

	 if (*thestring == '\0')
	 {
	    *thestring = '\n';
	    *(thestring + 1) = '\0';
	 }
      } else
	 thestring = mystring;

      return (thestring);

   } else
      return (NULL);

}

/* :45 *//* 51: */
#line 2059 "exedit.web"


#include <sys/types.h>
#include <sys/stat.h>
#include <sys/termios.h>

char           *line = "/dev/ptyXX";

struct termios  b;

int 
GetMaster()

{

   char            c;
   struct stat     stb;
   int             i, j;

   for (c = 'p'; c <= 's'; c++)
   {
      line[strlen("/dev/pty")] = c;
      line[strlen("/dev/ptyp")] = '0';
      if (stat(line, &stb) < 0)
	 break;
      for (i = 0; i < 16; i++)
      {
	 line[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
	 j = open(line, O_RDWR);
	 if (j >= 0)
	 {
	    ioctl(0, TCGETS, &b);
	    return (j);
	 }
      }
   }
   return (-1);
}

/* :51 *//* 53: */
#line 2132 "exedit.web"


void 
WakeUp()
{
   alarm(0);
}

/* :53 *//* 55: */
#line 2224 "exedit.web"


void 
DoShell()
{
   int             t, slave;
   char           *shell;
   extern int      GetSlave();
   extern char    *getenv();

   if ((t = open("/dev/tty", O_RDWR)) >= 0)
   {
      ioctl(t, TIOCNOTTY, NULL);
      close(t);
   }
   if ((slave = GetSlave()) < 0)
   {
      perror("exedit: child: cannot open slave");
      exit(errno);
   }
   close(master);
   dup2(slave, 0);
   dup2(slave, 1);
   dup2(slave, 2);
   close(slave);

   if ((shell = getenv("SHELL")) == 0)
      shell = "/bin/sh";

   execl(shell, "sh", "-i", NULL);

   perror("exedit: grandchild: cannot exec shell");
   exit(errno);
}

/* :55 *//* 56: */
#line 2277 "exedit.web"


int 
GetSlave()
{
   int             slv;

   line[strlen("/dev/")] = 't';

   if ((slv = open(line, O_RDWR)) >= 0)
   {
      b.c_lflag &= ~ECHO;
      b.c_oflag &= ~ONLCR;
      b.c_oflag |= NLDLY | CRDLY | TAB2 | BSDLY | VTDLY | FFDLY;
      ioctl(slv, TCSETS, &b);
   }
   return (slv);
}

/* :56 *//* 57: */
#line 2327 "exedit.web"


#define MYBUF 4096

XtInputCallbackProc 
ReadPipe(client_data, fid, id)
   caddr_t         client_data;
   int            *fid;
   XtInputId      *id;

{
   char            pbuf[MYBUF];
   int             c;
   char           *shell_path, *shell, *exeditrc, *home, command[BUFSIZ];
   static Boolean  first = TRUE;
   extern char    *getenv();
   extern char    *strrchr();

   c = read(*fid, pbuf, sizeof(pbuf) - 1);
   pbuf[c] = '\0';

   if (first)
   {
      shell_path = getenv("SHELL");
      if ((shell = strrchr(shell_path, '/')) != NULL)
	 shell++;
      else
	 shell = shell_path;
      home = getenv("HOME");
      exeditrc = strcat(home, "/.exeditrc");
      if (access(exeditrc, R_OK) == 0)
      {
	 if (strcmp(shell, "csh") == 0)
	    sprintf(command, "source %s\n", exeditrc);
	 else
	    sprintf(command, ". %s\n", exeditrc);
	 write(master, command, strlen(command));
      }
      first = FALSE;

   } else
   {
      if (status[2])
	 fprintf(stderr, pbuf);
      if (status[1])
	 XeditPrintf(messwidget, pbuf, APPEND);
      if (status[0])
	 XeditPrintf(textwindow, pbuf, APPEND);
      else
	 XeditPrintf(textwindow, pbuf, IN_PLACE);
   }

   XFlush(CurDpy);
}

/* :57 *//* 60: */
#line 2430 "exedit.web"


void 
SendDirect(w, event, params, num_params)
   Widget          w;
   XKeyEvent      *event;
   String         *params;
   Cardinal       *num_params;

{
   extern int      master;
   char            buffer[BUFSIZ];
   KeySym          keysym_return;
   XComposeStatus  status_in_out;
   int             length;

   if (event->type == KeyPress)
   {
      length = XLookupString(event, buffer, BUFSIZ, &keysym_return,
			     &status_in_out);
      buffer[length] = '\0';
      if (status[2])
      {
	 fprintf(stderr, buffer);
	 fflush(stderr);
      }
      if (status[1])
	 XeditPrintf(messwidget, buffer, APPEND);
      write(master, buffer, length);
   }
}

/* :60 *//* 65: */
#line 2673 "exedit.web"


void 
MenuSelect(w, entry_number, garbage)
   Widget          w;
   int             entry_number;
   caddr_t         garbage;
{
   Arg             arglist[5];
   Cardinal        num_args = 0;

   if (status[entry_number])
   {
      XtSetArg(arglist[num_args], XtNleftBitmap, None);
      num_args++;
   } else
   {
      XtSetArg(arglist[num_args], XtNleftBitmap, mark);
      num_args++;
   }

   XtSetValues(w, arglist, num_args);
   status[entry_number] = !status[entry_number];
}

/* :65 *//* 66: */
#line 2710 "exedit.web"


void 
PMenuSelect(w, entry_number, garbage)
   Widget          w;
   int             entry_number;
   caddr_t         garbage;
{
   extern Widget   p_entry[P_NUM_MENU_ITEMS];
   extern char     prompt[BUFSIZ];
   extern Boolean  p_status[P_NUM_MENU_ITEMS];
   Arg             arglist[1];
   Cardinal        j = 0;
   int             i;


   for (i = 0; i < P_NUM_MENU_ITEMS; i++)
   {
      j = 0;
      XtSetArg(arglist[j], XtNleftBitmap, None);
      j++;
      XtSetValues(p_entry[i], arglist, j);
      p_status[i] = FALSE;
   }


   j = 0;
   XtSetArg(arglist[j], XtNleftBitmap, mark);
   j++;
   XtSetValues(w, arglist, j);


   p_status[entry_number] = TRUE;


   strcpy(prompt, XtName(w));
}


/* :66 */
\Rogue\Monster\
else
  echo "will not over write ./exedit.0.91/exedit.c"
fi
if `test ! -s ./exedit.0.91/EXedit.ad`
then
echo "writing ./exedit.0.91/EXedit.ad"
cat > ./exedit.0.91/EXedit.ad << '\Rogue\Monster\'
EXedit*input:				TRUE

EXedit*filename*preferredPaneSize:	360
EXedit*editWindow*preferredPaneSize:	650

EXedit*labelWindow*justify:		center
EXedit*labelWindow*label:		no file yet

EXedit*quit.label:			Quit
EXedit*save.label:			Save
EXedit*load.label:			Load

EXedit*buttons*orientation:		horizontal
EXedit*buttons*showGrip:		False

EXedit*menus*orientation:		horizontal
EXedit*menus*showGrip:			False
EXedit*SimpleMenu*leftMargin:           30
EXedit*SimpleMenu*rightMargin:          15

EXedit*messageWindow*preferredPaneSize:	50
EXedit*Paned*Text*allowResize:		True

EXedit*messageWindow.autoFill:		True
EXedit*messageWindow.scrollVertical:	Always
EXedit*messageWindow.scrollHorizontal:  WhenNeeded

EXedit*editWindow.autoFill:		True
EXedit*editWindow.scrollVertical:	Always
EXedit*editWindow.scrollHorizontal:     WhenNeeded

EXedit*bc_label*label:			Use Control-S and Control-R to Search.

#ifdef COLOR
EXedit*background: lightgrey
EXedit*editWindow.background: lightgrey
EXedit*messageWindow.background: lightgrey
EXedit*labelWindow.background: slategrey
EXedit*labelWindow.foreground: white
EXedit*buttons*background: slategray
EXedit*buttons*foreground: white
EXedit*buttons*Command.background: slategray
EXedit*buttons*Command.foreground: white
EXedit*buttons*MenuButton.background: slategray
EXedit*menus*background: slategray
EXedit*menus*foreground: white
#endif

!
! Keep CR in filename window from confusing the user.
!

EXedit*filename.translations:	#override \
				<Key>Return: end-of-line()

EXedit*editWindow.translations: #override \
				Shift<Key>Return: shell() \n\
				Button1<Key>: direct()
\Rogue\Monster\
else
  echo "will not over write ./exedit.0.91/EXedit.ad"
fi
if `test ! -s ./exedit.0.91/Imakefile`
then
echo "writing ./exedit.0.91/Imakefile"
cat > ./exedit.0.91/Imakefile << '\Rogue\Monster\'
#ifdef BandAidCompiler
#include BandAidCompiler
#endif

        DEPLIBS = XawClientDepLibs
LOCAL_LIBRARIES = XawClientLibs
  SYS_LIBRARIES = -lm
           SRCS = exedit.c 
           OBJS = exedit.o

ComplexProgramTarget(exedit)
InstallAppDefaults(EXedit)
\Rogue\Monster\
else
  echo "will not over write ./exedit.0.91/Imakefile"
fi
if `test ! -s ./exedit.0.91/Makefile`
then
echo "writing ./exedit.0.91/Makefile"
cat > ./exedit.0.91/Makefile << '\Rogue\Monster\'
# Makefile generated by imake - do not edit!
# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
#
# The cpp used on this machine replaces all newlines and multiple tabs and
# spaces in a macro expansion with a single space.  Imake tries to compensate
# for this, but is not always successful.
#

###########################################################################
# Makefile generated from "Imake.tmpl" and <Imakefile>
# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
#
# Platform-specific parameters may be set in the appropriate .cf
# configuration files.  Site-wide parameters may be set in the file
# site.def.  Full rebuilds are recommended if any parameters are changed.
#
# If your C preprocessor doesn't define any unique symbols, you'll need
# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
# "make Makefile", "make Makefiles", or "make World").
#
# If you absolutely can't get imake to work, you'll need to set the
# variables at the top of each Makefile as well as the dependencies at the
# bottom (makedepend will do this automatically).
#

###########################################################################
# platform-specific configuration parameters - edit sun.cf to change

# platform:  $XConsortium: sun.cf,v 1.38 89/12/23 16:10:10 jim Exp $
# operating system:  SunOS 4.0.3

###########################################################################
# site-specific configuration parameters - edit site.def to change

# site:  $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $

            SHELL = /bin/sh

              TOP = .
      CURRENT_DIR = .

               AR = ar cq
  BOOTSTRAPCFLAGS =
               CC = cc

         COMPRESS = compress
              CPP = /lib/cpp $(STD_CPP_DEFINES)
    PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
          INSTALL = install
               LD = ld
             LINT = lint
      LINTLIBFLAG = -C
         LINTOPTS = -axz
               LN = ln -s
             MAKE = make
               MV = mv
               CP = cp
           RANLIB = ranlib
  RANLIBINSTFLAGS =
               RM = rm -f
     STD_INCLUDES =
  STD_CPP_DEFINES =
      STD_DEFINES =
 EXTRA_LOAD_FLAGS =
  EXTRA_LIBRARIES =
             TAGS = ctags

    SHAREDCODEDEF = -DSHAREDCODE
         SHLIBDEF = -DSUNSHLIB

    PROTO_DEFINES =

     INSTPGMFLAGS =

     INSTBINFLAGS = -m 0755
     INSTUIDFLAGS = -m 4755
     INSTLIBFLAGS = -m 0664
     INSTINCFLAGS = -m 0444
     INSTMANFLAGS = -m 0444
     INSTDATFLAGS = -m 0444
    INSTKMEMFLAGS = -m 4755

          DESTDIR =

     TOP_INCLUDES = -I$(INCROOT)

      CDEBUGFLAGS = -O
        CCOPTIONS =
      COMPATFLAGS = -DXAW_BC

      ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
       ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
           CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
        LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
           LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
        LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS)
   LDCOMBINEFLAGS = -X -r

        MACROFILE = sun.cf
           RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut

    IMAKE_DEFINES =

         IRULESRC = $(CONFIGDIR)
        IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)

     ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
			$(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
			$(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)

###########################################################################
# X Window System Build Parameters
# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $

###########################################################################
# X Window System make variables; this need to be coordinated with rules
# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $

          PATHSEP = /
        USRLIBDIR = $(DESTDIR)/usr/lib
           BINDIR = $(DESTDIR)/usr/bin/X11
          INCROOT = $(DESTDIR)/usr/include
     BUILDINCROOT = $(TOP)
      BUILDINCDIR = $(BUILDINCROOT)/X11
      BUILDINCTOP = ..
           INCDIR = $(INCROOT)/X11
           ADMDIR = $(DESTDIR)/usr/adm
           LIBDIR = $(USRLIBDIR)/X11
        CONFIGDIR = $(LIBDIR)/config
       LINTLIBDIR = $(USRLIBDIR)/lint

          FONTDIR = $(LIBDIR)/fonts
         XINITDIR = $(LIBDIR)/xinit
           XDMDIR = $(LIBDIR)/xdm
           AWMDIR = $(LIBDIR)/awm
           TWMDIR = $(LIBDIR)/twm
           GWMDIR = $(LIBDIR)/gwm
          MANPATH = $(DESTDIR)/usr/man
    MANSOURCEPATH = $(MANPATH)/man
           MANDIR = $(MANSOURCEPATH)n
        LIBMANDIR = $(MANSOURCEPATH)3
      XAPPLOADDIR = $(LIBDIR)/app-defaults

        SOXLIBREV = 4.2
          SOXTREV = 4.0
         SOXAWREV = 4.0
        SOOLDXREV = 4.0
         SOXMUREV = 4.0
        SOXEXTREV = 4.0

       FONTCFLAGS = -t

     INSTAPPFLAGS = $(INSTDATFLAGS)

            IMAKE = imake
           DEPEND = makedepend
              RGB = rgb
            FONTC = bdftosnf
        MKFONTDIR = mkfontdir
        MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier.sh

        CONFIGSRC = $(TOP)/config
        CLIENTSRC = $(TOP)/clients
          DEMOSRC = $(TOP)/demos
           LIBSRC = $(TOP)/lib
          FONTSRC = $(TOP)/fonts
       INCLUDESRC = $(TOP)/X11
        SERVERSRC = $(TOP)/server
          UTILSRC = $(TOP)/util
        SCRIPTSRC = $(UTILSRC)/scripts
       EXAMPLESRC = $(TOP)/examples
       CONTRIBSRC = $(TOP)/../contrib
           DOCSRC = $(TOP)/doc
           RGBSRC = $(TOP)/rgb
        DEPENDSRC = $(UTILSRC)/makedepend
         IMAKESRC = $(CONFIGSRC)
         XAUTHSRC = $(LIBSRC)/Xau
          XLIBSRC = $(LIBSRC)/X
           XMUSRC = $(LIBSRC)/Xmu
       TOOLKITSRC = $(LIBSRC)/Xt
       AWIDGETSRC = $(LIBSRC)/Xaw
       OLDXLIBSRC = $(LIBSRC)/oldX
      XDMCPLIBSRC = $(LIBSRC)/Xdmcp
      BDFTOSNFSRC = $(FONTSRC)/bdftosnf
     MKFONTDIRSRC = $(FONTSRC)/mkfontdir
     EXTENSIONSRC = $(TOP)/extensions

  DEPEXTENSIONLIB = $(USRLIBDIR)/libXext.a
     EXTENSIONLIB =  -lXext

          DEPXLIB = $(DEPEXTENSIONLIB)
             XLIB = $(EXTENSIONLIB) -lX11

      DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
         XAUTHLIB =  -lXau

        DEPXMULIB =
           XMULIB = -lXmu

       DEPOLDXLIB =
          OLDXLIB = -loldX

      DEPXTOOLLIB =
         XTOOLLIB = -lXt

        DEPXAWLIB =
           XAWLIB = -lXaw

 LINTEXTENSIONLIB = $(USRLIBDIR)/llib-lXext.ln
         LINTXLIB = $(USRLIBDIR)/llib-lX11.ln
          LINTXMU = $(USRLIBDIR)/llib-lXmu.ln
        LINTXTOOL = $(USRLIBDIR)/llib-lXt.ln
          LINTXAW = $(USRLIBDIR)/llib-lXaw.ln

        XWLIBSRC = $(CONTRIBSRC)/toolkits/Xw
        DEPXWLIB = $(USRLIBDIR)/libXw.a
        XWLIB =  -lXw

          DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)

         DEPLIBS1 = $(DEPLIBS)
         DEPLIBS2 = $(DEPLIBS)
         DEPLIBS3 = $(DEPLIBS)

###########################################################################
# Imake rules for building libraries, programs, scripts, and data files
# rules:  $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $

###########################################################################
# start of Imakefile

        DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
LOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
  SYS_LIBRARIES = -lm
           SRCS = exedit.c
           OBJS = exedit.o

 PROGRAM = exedit

all:: exedit

exedit: $(OBJS) $(DEPLIBS)
	$(RM) $@
	$(CC) -o $@ $(OBJS) $(LDOPTIONS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS)

saber_exedit:
	#load $(ALLDEFINES) $(SRCS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)

osaber_exedit:
	#load $(ALLDEFINES) $(OBJS) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)

install:: exedit
	$(INSTALL) -c $(INSTPGMFLAGS)   exedit $(BINDIR)

install.man:: exedit.man
	$(INSTALL) -c $(INSTMANFLAGS) exedit.man $(MANDIR)/exedit.n

depend::
	$(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)

lint:
	$(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
lint1:
	$(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)

clean::
	$(RM) $(PROGRAM)

install:: EXedit.ad
	$(INSTALL) -c $(INSTAPPFLAGS) EXedit.ad $(XAPPLOADDIR)/EXedit

###########################################################################
# common rules for all Makefiles - do not edit

emptyrule::

clean::
	$(RM_CMD) \#*

Makefile::
	-@if [ -f Makefile ]; then \
	echo "	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
	$(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
	else exit 0; fi
	$(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)

tags::
	$(TAGS) -w *.[ch]
	$(TAGS) -xw *.[ch] > TAGS

saber:
	#load $(ALLDEFINES) $(SRCS)

osaber:
	#load $(ALLDEFINES) $(OBJS)

###########################################################################
# empty rules for directories that do not have SUBDIRS - do not edit

install::
	@echo "install in $(CURRENT_DIR) done"

install.man::
	@echo "install.man in $(CURRENT_DIR) done"

Makefiles::

includes::

###########################################################################
# dependencies generated by makedepend

# DO NOT DELETE

exedit.o: /usr/include/stdio.h /usr/include/X11/Intrinsic.h
exedit.o: /usr/include/X11/Xlib.h /usr/include/sys/types.h
exedit.o: /usr/include/sys/sysmacros.h /usr/include/X11/X.h
exedit.o: /usr/include/X11/Xutil.h /usr/include/X11/Xresource.h
exedit.o: /usr/include/X11/Xos.h /usr/include/strings.h
exedit.o: /usr/include/sys/file.h /usr/include/sys/fcntlcom.h
exedit.o: /usr/include/sys/time.h /usr/include/sys/time.h
exedit.o: /usr/include/X11/Core.h /usr/include/X11/Composite.h
exedit.o: /usr/include/X11/Constraint.h /usr/include/X11/Object.h
exedit.o: /usr/include/X11/RectObj.h /usr/include/X11/StringDefs.h
exedit.o: /usr/include/X11/cursorfont.h /usr/include/X11/Xatom.h
exedit.o: /usr/include/X11/Xaw/Box.h /usr/include/X11/Xaw/Command.h
exedit.o: /usr/include/X11/Xaw/Label.h /usr/include/X11/Xaw/Simple.h
exedit.o: /usr/include/X11/Xmu/Converters.h /usr/include/X11/Xaw/AsciiText.h
exedit.o: /usr/include/X11/Xaw/Text.h /usr/include/X11/Xaw/TextSink.h
exedit.o: /usr/include/X11/Xaw/TextSrc.h /usr/include/X11/Xaw/AsciiSrc.h
exedit.o: /usr/include/X11/Xaw/AsciiSink.h /usr/include/X11/Xaw/Paned.h
exedit.o: /usr/include/X11/Xaw/Viewport.h /usr/include/X11/Xaw/Form.h
exedit.o: /usr/include/X11/Xaw/Cardinals.h /usr/include/signal.h
exedit.o: /usr/include/vm/faultcode.h /usr/include/X11/Xaw/MenuButton.h
exedit.o: /usr/include/X11/Xaw/SimpleMenu.h /usr/include/X11/Shell.h
exedit.o: /usr/include/X11/Xaw/SmeBSB.h /usr/include/X11/Xaw/Sme.h
exedit.o: /usr/include/X11/Xaw/SmeLine.h /usr/include/sys/stat.h
exedit.o: /usr/include/sys/termios.h /usr/include/sys/ioccom.h
exedit.o: /usr/include/sys/ttydev.h /usr/include/sys/ttycom.h
\Rogue\Monster\
else
  echo "will not over write ./exedit.0.91/Makefile"
fi
if `test ! -s ./exedit.0.91/README`
then
echo "writing ./exedit.0.91/README"
cat > ./exedit.0.91/README << '\Rogue\Monster\'






          _A_b_o_u_t _e_x_e_d_i_t

               Program  _e_x_e_d_i_t is  based  on  the  MIT  X11R4  program
          _x_e_d_i_t.   _E_x_e_d_i_t  adds  some  new  functionality  to  _x_e_d_i_t -
          mainly in the area of communicating with other processes. If
          you have ever worked with Apple's  MPW shell you will recog-
          nize some similarity.  _E_x_e_d_i_t, like  MPW  shell,  allows  to
          execute shell commands and selected programs from within the
          editing environment of _x_e_d_i_t. When you  start  _e_x_e_d_i_t,  your
          shell  of  choice,  as  defined by the evironmental variable
          SHELL, is invoked in the background.  If  you  have  a  file
          called   ._e_x_e_d_i_t_r_c in your HOME directory, this file will be
          sourced into your shell. Whenever you type Shift-Return, the
          whole  line  on which the cursor resides will be sent to the
          shell. If that line begins with a prompt string, you can ask
          _e_x_e_d_i_t  to  skip that string by making an appropriate selec-
          tion from the  prompts menu. If you have made a text  selec-
          tion  in  the editing window and you press  Shift-Return the
          whole selection will be sent to the shell. But  prompt  will
          not  be  skipped in this case. You can send a complex multi-
          line commands to the shell this way. You can even paste such
          multiline  commands  by selecting various parts from various
          places in your input file.

               Apart from the delayed input mode,  i.e.,  select  text
          and  press Shift-Return, there is also a direct mode. If you
          press  Button 1 key on the mouse  together  with  any  other
          combination  of keys, including the control key, that combi-
          nation is sent to the shell directly. It will not be  echoed
          in your main editing window, but you can make it echo in the
          message window or on standard error. In  this  way  you  can
          type   Control-C, Control-D, your password, etc. If you have
          Alt, Hyper or Super keys available on your keyboard, you may
          find  it  preferable to use these as the modifier instead of
          Button 1. Note that the Meta key is used by the text  widget
          for  various  editing functions, and thus should not be used
          as the modifier while invoking the direct() action.

               There are two basic modes used for  printing  the  text
          returned  by  the  shell.  You can have it printed  in situ,
          i.e., on the line following the line you have just  sent  to
          the  shell,  or you can have the text appended at the end of
          the file, regardless of where the input line came from.  You
          can switch between these modes using the menu.

               Using the same menu you can also  select   verbose  and
          debug  options.  In  verbose  mode  whatever you send to the
          shell and whatever comes back is also printed in the message
          window  above the main editing window. This may be useful if
          you send long multiline commands combined from parts of text
          scattered  all  over  your main editing window or if you use
          the  Meta key to send some characters to the shell directly.

               In the debug mode whatever is sent  to  the  shell  and



                                October 20, 1990





                                     - 2 -


          whatever  comes back is printed on standard error  before it
          is printed on the editing window.

               Whatever applies to   _x_e_d_i_t  applies  also  to   _e_x_e_d_i_t
          including  the  resource definitions. The only difference is
          that the class name for  _e_x_e_d_i_t is  EXedit instead of Xedit.
          The additional resources are:

                     EXedit*Prompt1: ... , through
                     EXedit*Prompt9: ...

          which define the prompts that appear in  the  prompts  menu.
          These  should be set to one character long strings, the only
          exception being the  word  |"none"|.   The  string  defining
          Prompt1  becomes the default prompt when  _e_x_e_d_i_t is invoked.
          Selecting any particular prompt  character  from  that  menu
          will  result in  _e_x_e_d_i_t skipping over all characters preced-
          ing the selected prompt character including the prompt char-
          acter  itself  while sending the contents of the line to the
          shell.

               Although in principle  _e_x_e_d_i_t can  be  used  as   _x_t_e_r_m
          replacement  it  has  not  been  designed  exactly for that.
          Rather, it should be treated  as  a  kind  of  a  "sheet  of
          thought"  that  allows  to  edit and process various complex
          expressions and formulas. You would probably use it in  con-
          junction  with  interactive  programs  which have unfriendly
          user interfaces, for instance with theorem provers, calcula-
          tors  (such as bc), lisps, with metalanguage or with prolog.
          I use it myself frequently with _M_a_t_h_e_m_a_t_i_c_a and with theorem
          provers such as _H_O_L and _I_s_a_b_e_l_l_e.

               Because the background shell runs on the slave  end  of
          the  pseudo  terminal  pair, which is set accordingly to the
          settings  of  the  terminal  from  which   _e_x_e_d_i_t  has  been
          invoked,  if  _e_x_e_d_i_t is to be detached the invocation should
          be as follows:

                      exedit < /dev/tty > /dev/tty 2>&1 &

          under Bourne shell and

                      exedit < /dev/tty >& dev/tty &

          under C shell.

               _E_x_e_d_i_t is the result of  wrapping  up  additional  code
          around  standard _x_e_d_i_t written by Chris D. Peterson from the
          MIT X Consortium.  The wrap was written by Zdzislaw Meglicki
          from the Australian National University.

               The annotated FWEB source of _e_x_e_d_i_t and the correspond-
          ing  TeX file are available from arp.anu.oz.au (130.56.4.90)
          via  anonymous  ftp.  They  live   in   /ARP/exedit.0.91/doc



                                October 20, 1990





                                     - 3 -


          directory.  The TeX file should be formatted with plain TeX.
          You will need the fwebmac.tex file which is also provided. I
          believe that the annotated source has some educational value
          and you may find it useful if you learn to program under  X,
          or if you would like to modify _e_x_e_d_i_t.

          _I_n_s_t_a_l_l_a_t_i_o_n

               To install _e_x_e_d_i_t go through the usual  X  compile  and
          install cycle:

                     % xmkmf
                     % make depend
                     % make
                     % make install
                     % make install.man

          I have compiled and tested _e_x_e_d_i_t only on the Suns (3 and 4)
          under  SunOS  4.0.1.  _E_x_e_d_i_t  relies  on the availability of
          pseudo terminals and uses system V termio  interface,  which
          under     SunOS     4.0.1     has    been    described    in
          /_u_s_r/_i_n_c_l_u_d_e/_s_y_s/_t_e_r_m_i_o_s._h. You will have problems if you do
          not have that file on your system.

               The version number 0.91 signifies a  "beta/pre-release"
          character  of _e_x_e_d_i_t.  Nevertheless, already at this stage I
          find it quite useful, hence the posting.

               In case of problems and/or new ideas contact

                  Gustav Meglicki, gustav@arp.anu.oz.au
                  Automated Reasoning Project, RSSS,
                     and Plasma Theory Group, RSPhysS,
                  The Australian National University,
                  G.P.O. Box 4, Canberra, A.C.T., 2601, Australia,

                  fax: (Australia)-6-249-0747
                  tel: (Australia)-6-249-0158



















                                October 20, 1990


\Rogue\Monster\
else
  echo "will not over write ./exedit.0.91/README"
fi
if `test ! -s ./exedit.0.91/exedit.man`
then
echo "writing ./exedit.0.91/exedit.man"
cat > ./exedit.0.91/exedit.man << '\Rogue\Monster\'
.TH EXEDIT 1 "Release 4" "X Version 11"
.SH NAME
exedit - simple X script facility
.SH SYNTAX
\fBexedit\fP [ \fI-toolkitoption\fP ...] [ filename ]
.SH OPTIONS
.I Exedit
accepts all of the standard X Toolkit command line
options (see \fIX(1)\fP).  The order of the command line options is
not important.
.TP 8
.I filename
Specifies the file that is to be loaded during start-up. This is the
file which will be edited. If a file is not specified,
.I exedit
lets you load a file or create a new file after it has started up.
.SH DESCRIPTION
.I Exedit
provides a window consisting of the following four areas:
.IP "Commands Section" 25
A set of commands that allow you to exit \fIexedit\fP, save the file, or
load a new file into the edit window, inform \fIexedit\fP about the
prompt, and set various I/O modes.
.IP "Message Window" 25
Displays \fIexedit\fP messages. In addition, this window can be used as
a scratch pad. 
.IP "Filename Display"
Displays the name of the file currently being edited, and whether this file
is \fIRead - Write\fP or \fIRead Only\fP.
.IP "Edit Window" 25
Displays the text of the file that you are editing or creating. Communicates
with the shell.
.SH EDITING
The Athena Text widget is used for the three sections of this
application that allow text input.  The characters typed will go to
the Text widget that the pointer cursor is currently over.  If the
pointer cursor is not over a text widget then the keypresses will have
no effect on the application.  This is also true for the special key
sequences that popup dialog widgets, so typing Control-S in the filename
widget will enable searching in that widget, not the edit widget.
.PP
Both the message window and the edit window will create a scrollbar if
the text to display is too large to fit in that window.  Horizontal scrolling
is not allowed by default, but can be turned on through the Text
widget's resources, see \fIAthena Widget Set\fP for the exact
resource definition.
.SH COMMUNICATING WITH THE SHELL
When \fIexedit\fP starts up, the interactive shell is simultaneously forked 
in the background. If there is a file \fI.exeditrc\fP in user's home directory
this file is sourced into the shell. Whenever the user presses simultaneously
Shift and Return keys the line on which the cursor resides in the
editing window is sent to the
shell. If a prompt has been selected different from the word "none" in the
"Prompts" menu, everything on the current line up to and including the first 
character
of the prompt string will be skipped before passing the line to the shell
(for this reason the entries in the "Prompts" menu should be one character
long - they should correspond to the \fIlast\fP character of the user's 
prompt).
If a selection has been made, the whole selection is sent to the
shell (but prompt is not processed in this case). If the user presses 
Button 1 key on the mouse
in combination with any other key
including the control key, that combination is sent to the shell directly
without echoing in the editing window. 
The text which is sent back by the shell is written on the editing window either
in situ, or appended to the end of the file, depending on the choices the
user has made in the "Settings" menu.
.SH COMMANDS
.IP "Quit" 8
Quits the current editing session. If any changes have not been saved,
.I exedit 
displays a warning message, allowing the user to save the file.
.IP "Save" 
If file backups are enabled (see RESOURCES) exedit stores a copy of the
original, unedited file in <prefix>\fIfile\fP<suffix>,
then overwrites the \fIfile\fP with the contents of the edit window.  The
filename is retrieved from the Text widget directly to the right of
the \fILoad\fP button.
.IP "Load"
Loads the file named in the text widget immediately to the right
of the this button and displays it in the Edit window.  If the
currently displayed file has been modified a warning message will ask
the user to save the changes, or press \fIload\fP again.
.IP "Settings"
The menu: choose between in-situ insertion into the edited file and 
appending to the end of that file of the text sent by the shell. Enable
or disable verbose and debug modes. In verbose mode the communication
with the shell is echoed in the message window. In debug mode the
communication is echoed first on standard error before being sent to any of the
windows of \fIexedit\fP.
.IP "Prompts"
The menu: select the character terminating the prompt in use at the moment.
.SH RESOURCES
For \fIexedit\fP the available resources are:
.TP 8
.B enableBackups (\fPClass\fB EnableBackups)
Specifies that, when edits made to an existing file are saved,
.I exedit
is to copy the original version of that file to <prefix>\fIfile\fP<suffix>
before it saves the changes.  The default value for this resource is
"off", stating that no backups should be created.
.TP 8
.B backupNamePrefix (\fPClass\fB BackupNamePrefix)
Specifies a string that is to be prepended to the backup filename.  The
default is that no string shall be prepended.
.TP 8
.B backupNameSuffix (\fPClass\fB BackupNameSuffix)
Specifies a string that is to be appended to the backup filename.  The
default is to append the string ".BAK".
.TP 8
.B prompt1 (\fPClass\fB Prompt1)
Specifies the character that terminates the 
prompt. The first selection is the default. Up to 9 prompt terminators 
("prompt2", "prompt3", etc.) can be
specified in this way. The no prompt entry is characterized by the
word "none".
.TP 8
.B actions shell() and direct()
These actions are bound to Shift<Key>Return and to Button1<Key> by default.
If the server recognizes other modifiers apart from "Control" and "Meta", it
may be preferable to bind \fBdirect()\fP to those. The "Meta" modifier is
already used by many editing actions and thus should not be used in the
context of \fBdirect()\fP.
.SH WIDGETS
In order to specify resources, it is useful to know the hierarchy of
the widgets which compose \fIexedit\fR.  In the notation below,
indentation indicates hierarchical structure.  The widget class name
is given first, followed by the widget instance name.
.sp
.nf
.TA .5i 1.0i 1.5i 2.0i
.ta .5i 1.0i 1.5i 2.0i
EXedit  exedit
	Paned  paned
		Paned  buttons
			Command  quit
			Command  save
			Command  load
			Text  filename
		Label  bc_label
		Text  messageWindow
		Label  labelWindow
		Text  editWindow
.fi
.sp
.SH ENVIRONMENT
.PP
.TP 8
.B DISPLAY
to get the default host and display number.
.TP 8
.B XENVIRONMENT
to get the name of a resource file that overrides the global resources
stored in the RESOURCE_MANAGER property.
.TP 8
.B SHELL
to get the name of the shell forked in the background.
.SH FILES
/usr/lib/X11/app-defaults/EXedit - specifies required resources
.br
$HOME/.exeditrc - the file which is sourced into the background shell
on startup
.SH SEE ALSO
X(1), xrdb(1), xedit(1), Athena Widget Set
.SH RESTRICTIONS
There is no \fIundo\fP function.
.SH BUGS
Terminating the background shell from within \fIexedit\fR will cause
a most undesirable effect, due to the way the communication between
the pseudo terminal and the text widget has been arranged. Don't do that.
To exit without
adventures just press the QUIT button. There ought to be more menus and
these should be configurable by the user without having to edit the .Xresources
data base. The treatment of the prompt should be more elaborate.
.SH COPYRIGHT
Copyright 1988, Digital Equipment Corporation.
.br
Copyright 1989, Massachusetts Institute of Technology.
.br
Copyright 1990, Australian National University.
.br
See \fIX(1)\fP for a full statement of rights and permissions.
.SH AUTHORS
Chris D. Peterson, MIT X Consortium, the xedit part of the code
.br
Zdzislaw Meglicki, Australian National University, all the rest of exedit
including bugs and problems

\Rogue\Monster\
else
  echo "will not over write ./exedit.0.91/exedit.man"
fi
if `test ! -s ./exedit.0.91/patchlevel.h`
then
echo "writing ./exedit.0.91/patchlevel.h"
cat > ./exedit.0.91/patchlevel.h << '\Rogue\Monster\'
/*
 * Track patch level of exedit
 */

#define	PATCHLEVEL	0
\Rogue\Monster\
else
  echo "will not over write ./exedit.0.91/patchlevel.h"
fi
echo "Finished archive 1 of 1"
# if you want to concatenate archives, remove anything after this line
exit

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.