help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sync with external program


From: Richard KIrk
Subject: Sync with external program
Date: Thu, 20 Jun 2013 03:52:59 -0700 (PDT)

Hi.

I modified my image viewer so it periodically looks for commands when it is
idle. This means I can get Octave to write an image and then post an
instruction to get the viewer to read it, and things like that. I would now
like to do the trick the other way around - to get Octave to look inputs
when it is idle, so I can pick up UI changes such as moved sliders, and
stuff like that.

I have attached a source for a program called 'echoFile'. This takes
keystrokes from the keyboard, and passes them to the output. If the keyboard
seems quiet and you are not in the middle of editing a line, it looks for
file input. If it finds any, it echoes the file contents and then deletes
the file. If you pipe the output to octave... 

> echoFile /tmp/oct_cmd | octave --interactive --line-editing

...then any commands sent to /tmp/oct_cmd turn up in octave as though you
just typed them.

This is not great. It does not work if you are running octave from an
editor. I am not sure if you can use it with gdb on octave either. If octave
is busy, then the commands from the file back up, then get executed in a
rush when the current task is done. However, the good parts are that every
command turns up in octave and gets executed in a particular numbered order,
just as typed commands normally do, and you can do this without altering
with Octave at all. It's pretty simple, and it did the job.

We could improve on this if we could tell whether octave is busy. I cannot
see any easy way of doing this in 'echoFile' as octave takes stuff from its
input even when it is executing code. The only thing I can see is to stick
something within 'octave' itself, so it only read the files when you were
not typing and it is not busy. 

The following code is given without any restriction on copyright. Hack as
you please. If you have any cunning suggestions, please post them on this
thread.


--- echoFile.cpp---

#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> 
#include <curses.h> 
#include <time.h>

void usage(void)
{
  printf("echoFile <file_name>\n"
         "\n"
         "This program copies any keyboard input straight to stdout.\n"
         "When the keyboard is idle, the program tries to read\n"
         "input from a file. The keyboard is deemed idle when\n"
         "the last character was '\\n' and the keyboard has not\n"
         "been used for over a second. This allows us to use keyboard\n"
         "entry for programs but also allows other tools to generate\n"
         "commands via standard file IO.\n"
         "\n"
         "If there is no command file, the program may sends nulls\n"
         "to stdout. This will trigger an exit if the output pipe\n"
         "is broken. This can happen if we have sent a quit command\n"
         "to the program we are trying to drive.\n"
         "\n"
         "When the program has read the command, it will delete the\n"
         "file. This stops the command being read more than once, and\n"
         "signals that we are ready for another command. If the program\n"
         "cannot remove the command file, the program gives a warning\n"
         "and stops trying to read it.\n"
         "\n"
         "Example:\n"
         "\n"
         "echoFile /tmp/oct_cmd | octave --interactive --line-editing\n"
         "\n"
         "While this is running, copy a file with an octave command in\n"
         "to /tmp/oct_cmd. The file should disappear, and the command\n"
         "should be passed to octave as though the user typed it.\n"
         "Copying or renaming the file is a good way of stopping this\n"
         "program trying to read the file while it is still being written.\n"
         );
}

int main(int argc, char* argv[])
{
  int n, c, idleFlag, readFlag;
  struct termios attr, old_attr;
  const char *file_name;
  FILE *cmd_file;

  if (argc != 2) {
    usage();
    exit(0);
  }

  file_name = argv[1];
  readFlag = 1;

  // Fast key read or ERR, no break or echo
  tcgetattr( STDIN_FILENO, &attr );
  old_attr = attr;
  attr.c_lflag &= ~( ICANON | BRKINT | ECHO );
  attr.c_cc[VMIN] = 0;
  attr.c_cc[VTIME] = 0;
  tcsetattr( STDIN_FILENO, TCSANOW, &attr );

  idleFlag = 1;

  for(;;) {
    c = getchar();
    if (c == ERR) {
      // No new keystrokes...

      if (idleFlag) {
        // Not half-way through editing a line...

        usleep(100000); // 0.1 sec sleep
        ++idleFlag;     // use idleFlag to count sleeps

        if (idleFlag > 10) {
          // Over a second since something last happened...
          idleFlag = 1;
          cmd_file = NULL;
          if (readFlag) cmd_file = fopen(file_name, "r");
          if (cmd_file) {
            for (;;) {
              c = fgetc(cmd_file);
              if (c == EOF) break;
              if (c == '\0') break;
              fputc(c, stdout);
            }
            fclose(cmd_file);
            if (remove(file_name)) {
              readFlag = 0;
              fprintf(stderr, "echoFile: cannot delete %s.\n", file_name);
            }
          } else {
            // Trigger an exit if the output pipe is broken
            fputc(0, stdout);
          }
          fflush(stdout);
        }
      }
    } else {
      // New keystroke...
      idleFlag = 0;
      fputc(c, stdout);
      fflush(stdout);
      if (c == '\n') {
        // Return ends command
        idleFlag = 1;
      }
    }
  }

  tcsetattr( STDIN_FILENO, TCSANOW, &old_attr );
  exit(0);
}




--
View this message in context: 
http://octave.1599824.n4.nabble.com/Sync-with-external-program-tp4654530.html
Sent from the Octave - General mailing list archive at Nabble.com.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]