add pty-gpib-emulator from github

This commit is contained in:
S Groesz 2020-09-09 05:17:31 +00:00
parent 63554da593
commit 3fe71a6f3b
22 changed files with 997 additions and 0 deletions

View File

@ -0,0 +1,13 @@
#include "Device.h"
#include <string>
#include <iostream>
string Device::handleCMD(Interface *fpl,
string cmd,
vector<string> *args) {
std::cout << "$$ Device: " << cmd << std::endl;
return "";
}

View File

@ -0,0 +1,23 @@
#ifndef DEVICE
#define DEVICE
#include <string>
#include <iostream>
class Device;
#include "PTY_Interface.h"
#include <vector>
using namespace std;
class Device {
public:
virtual string handleCMD(Interface *fpl,
string cmd,
vector<string> *args) {
return "";
} /**/
};
#endif

View File

@ -0,0 +1,28 @@
CC=g++
CFLAGS=-c -std=c++11
LDFLAGS=
LIBRARIES=-lutil -lboost_system
SOURCES=PTY_Interface.cpp Prologix.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=
TEST_SRC=$(SOURCES) test.cpp
TEST_OBJ=$(TEST_SRC:.cpp=.o)
TEST_EXE=test
all: $(SOURCES) $(OBJECTS)
test: $(TEST_SRC) $(TEST_OBJ)
$(TEST_EXE):
$(CC) $(LDFLAGS) $(TEST_OBJ) $(LIBRARIES) -o $(TEST_EXE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
clean:
rm *.o *~ *.gch

View File

@ -0,0 +1,110 @@
#include "PTY_Interface.h"
#include <pty.h>
#include <iostream>
#include <unistd.h>
#include <boost/algorithm/string.hpp>
#include <termios.h>
using namespace boost::algorithm;
static void set_noecho(int fd) { // Turn off Slave echo
struct termios stermios;
if (tcgetattr(fd, &stermios) < 0)
std::cout << "Error tcgetattr()" << std::endl;
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
stermios.c_oflag &= ~(ONLCR);
/* also turn off NL to CR/NL mapping on output */
if (tcsetattr(fd, TCSANOW, &stermios) < 0)
std::cout << "Error tcsetattr()" << std::endl;
}
Interface::Interface(Device *default_device,
int default_address) {
char name[40];
this->addr = default_address;
this->addDevice(default_device, default_address);
if (openpty(&this->m, &this->s, name, NULL, NULL) < 0)
std::cerr << "Could not open pty device" << std::endl;
else {
set_noecho(this->s);
this->pname = name;
this->running = false;
}
}
Interface::~Interface() {
close(this->m);
}
string Interface::printFilename() {
std::cout << this->pname << std::endl;
return this->pname;
}
void Interface::run(int readLen) {
char *tty_in = new char[readLen+1];
vector<string> tty_out;
string tty_full;
int i;
this->running = true;
while (this->running) {
tty_full = "";
while (read(this->m, tty_in, readLen) >= readLen) {
std::cout << tty_in << std::endl;
tty_full += tty_in;
}
tty_full += tty_in;
i = tty_full.find("\n");
if ( i != string::npos )
tty_full = tty_full.substr(0, i);
tty_out = this->handleInput(tty_full);
for (std::vector<string>::iterator it = tty_out.begin();
it != tty_out.end();
it++) {
write(this->m, it->c_str(), it->length());
}
}
delete[] tty_in;
}
vector<string> Interface::handleInput(string tty_in) {
vector<string> out;
Device *dev = NULL;
vector<string> cmd;
vector<string> p;
string first;
int i;
trim(tty_in);
if (tty_in != "" && this->devices.count(this->addr) > 0) {
dev = this->devices.at(this->addr);
if (dev == NULL) {
out.push_back("ERROR! No Device at address: " +
to_string(this->addr));
}
boost::split(cmd, tty_in, boost::is_any_of(";\n"));
for (i=0;i<cmd.size();i++) {
boost::split(p, cmd.at(i), boost::is_any_of(" "));
first = p.at(0);
p.erase(p.begin());
out.push_back(dev->handleCMD(this, first, &p) + "\n");
}
}
out.push_back("");
return out;
}
void Interface::addDevice(Device *dev, int addr) {
this->devices.insert( std::pair<int, Device*>(addr, dev));
}

View File

@ -0,0 +1,35 @@
#ifndef PTY_INTERFACE
#define PTY_INTERFACE
#include <string>
#include <map>
class Interface;
#include "Device.h"
using namespace std;
class Interface {
public:
map<int, Device*> devices;
int addr, m, s;
bool running;
string pname;
Interface(Device *default_device=NULL,
int default_address=0);
~Interface();
string printFilename();
void run(int readLen=100);
vector<string> handleInput(string tty_in);
void addDevice(Device *dev, int addr);
};
#endif

View File

View File

@ -0,0 +1,66 @@
#include "Prologix.h"
#include <string>
#include <cstdlib>
#include <iostream>
Prologix_GPIB_USB::Prologix_GPIB_USB() {
this->addCMD("++ver", &Prologix_GPIB_USB::version);
this->addCMD("++addr", &Prologix_GPIB_USB::addr);
this->addCMD("++kill", &Prologix_GPIB_USB::kill);
}
Prologix_GPIB_USB::~Prologix_GPIB_USB() {
}
string Prologix_GPIB_USB::handleCMD(Interface *fpl,
string cmd,
vector<string> *args) {
string out = "";
handler h;
if (out != "") {
return out;
} else if ( this->cmds.count(cmd) > 0 ) {
h = this->cmds.at(cmd);
return (this->*h)(fpl, args);
}
return "";
}
string Prologix_GPIB_USB::version(Interface *fpl,
vector<string> *args) {
return "Prologix Version 1.1 Simulator (C++)";
}
string Prologix_GPIB_USB::addr(Interface *fpl,
vector<string> *args) {
if (args == NULL || args->size() == 0) {
return std::to_string(fpl->addr);
} else {
fpl->addr = atoi(args->at(0).c_str());
if ( fpl->devices.count(fpl->addr) == 0 )
fpl->addDevice(this, fpl->addr);
return "";
}
}
string Prologix_GPIB_USB::kill(Interface *fpl,
vector<string> *args) {
fpl->running = false;
return "";
}
void Prologix_GPIB_USB::addCMD(const char *cmd, handler h) {
this->cmds.insert( std::pair<string, handler>(cmd, h) );
}
void Prologix_GPIB_USB::addCMD(string cmd, handler h) {
this->cmds.insert( std::pair<string, handler>(cmd, h) );
}

View File

@ -0,0 +1,34 @@
#ifndef PROLOGIX
#define PROLOGIX
#include "Device.h"
#include <map>
#include "PTY_Interface.h"
#include <vector>
#include <string>
using namespace std;
class Prologix_GPIB_USB : public Device {
public:
typedef string (Prologix_GPIB_USB::*handler)(Interface *fpl,
vector<string> *args);
map<string, handler> cmds;
Prologix_GPIB_USB();
~Prologix_GPIB_USB();
string handleCMD(Interface *fpl, string cmd, vector<string> *args);
string version(Interface *fpl, vector<string> *args);
string addr(Interface *fpl, vector<string> *args);
string kill(Interface *fpl, vector<string> *args);
void addCMD(const char *cmd, handler h);
void addCMD(string cmd, handler h);
};
#endif

View File

@ -0,0 +1,28 @@
#include "PTY_Interface.h"
#include "Prologix.h"
#include <iostream>
#define TEST(A) std::cout << A << ": " << inter.handleInput(A).at(0) << std::endl;
int main() {
Prologix_GPIB_USB *plg = new Prologix_GPIB_USB();
Interface inter(plg);
vector<string> v;
inter.printFilename();
inter.addDevice(plg, 0);
TEST("++ver");
TEST("++addr");
TEST("++addr 2");
TEST("++addr");
TEST("++ver");
inter.printFilename();
inter.run();
delete plg;
return 0;
}

View File

@ -0,0 +1,20 @@
CC=g++
CFLAGS=-c -std=c++11
LDFLAGS=
LIBRARIES=-lutil
SOURCES=MiddleMan.cpp simple.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=simple
all: $(SOURCES) $(OBJECTS) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LIBRARIES)
.cpp.o:
$(CC) $(CFLAGS) $< -o $@ $(LIBRARIES)
clean:
rm *.o *~ *.gch

View File

@ -0,0 +1,143 @@
#include "MiddleMan.h"
#include <iostream>
#include <unistd.h>
#include <pty.h>
#include <termios.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
static void setPort(int fd) {
/* *** Configure Port *** */
struct termios tty;
memset (&tty, 0, sizeof tty);
/* Error Handling */
if ( tcgetattr ( fd, &tty ) != 0 ) {
std::cout << "Error tcgetattr()" << std::endl;
}
/* Set Baud Rate */
cfsetospeed (&tty, B9600);
cfsetispeed (&tty, B9600);
/* Setting other Port Stuff */
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS; // no flow control
// no signaling chars, no echo, no canonical processing
tty.c_lflag = 0;
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn't block
// 0.5 seconds read timeout
tty.c_cc[VTIME] = 5;
// turn on READ & ignore ctrl lines
tty.c_cflag |= CREAD | CLOCAL;
// turn off s/w flow ctrl
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
tty.c_oflag &= ~OPOST; // make raw
/* Flush Port, then applies attributes */
tcflush( fd, TCIFLUSH );
if ( tcsetattr ( fd, TCSANOW, &tty ) != 0) {
std::cout << "Error tcsetattr()" << std::endl;
}
}
static void set_noecho(int fd) { // Turn off Slave echo
struct termios stermios;
if (tcgetattr(fd, &stermios) < 0)
std::cout << "Error tcgetattr()" << std::endl;
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
stermios.c_oflag &= ~(ONLCR);
/* also turn off NL to CR/NL mapping on output */
if (tcsetattr(fd, TCSANOW, &stermios) < 0)
std::cout << "Error tcsetattr()" << std::endl;
}
MiddleMan::MiddleMan(const string tty,
const string fout_name,
int sleepTime) {
char name[40];
if (openpty(&this->mPTY, &this->sPTY, name, NULL, NULL) < 0)
std::cerr << "Could not open pty device" << std::endl;
else {
set_noecho(this->sPTY);
this->ptyname = name;
this->running = false;
}
if ( (this->mTTY = open(tty.c_str(), O_RDWR| O_NONBLOCK)) < 0 ) {
std::cerr << "Could not open tty device" << std::endl;
} else {
this->ttyname = tty;
setPort(this->mTTY);
}
if ( (this->fout = fopen(fout_name.c_str(), "w+")) == NULL )
std::cout << "Error upon opening the output file" << std::endl;
this->sleep = sleepTime;
}
MiddleMan::~MiddleMan() {
close(this->mPTY);
fclose(this->fout);
}
string MiddleMan::getPTY() {
return this->ptyname;
}
string readTTY(int master, int readLen=100) {
char *tty_in = new char[readLen+1];
string tty_full;
int i=0;
tty_full = "";
while ((i=read(master, tty_in, readLen)) >= readLen) {
tty_in[i] = '\0';
tty_full += tty_in;
}
tty_in[i] = '\0';
tty_full += tty_in;
delete[] tty_in;
return tty_full;
}
void MiddleMan::run(int readLen) {
this->running = true;
while (this->running) {
this->handleInput(readTTY(this->mPTY, readLen));
}
}
void MiddleMan::handleInput(string tty_in) {
string buf;
write(this->mTTY, tty_in.c_str(), tty_in.size());
usleep(this->sleep); // microseconds
buf = readTTY(this->mTTY);
write(this->mPTY, buf.c_str(), buf.size());
this->log(tty_in, buf);
}
void MiddleMan::log(string input, string output,
const string format) {
printf(format.c_str(), input.c_str(), output.c_str());
fprintf(this->fout, format.c_str(), input.c_str(), output.c_str());
fflush(this->fout);
}

View File

@ -0,0 +1,40 @@
#ifndef MIDDLEMAN
#define MIDDLEMAN
#include <string>
class MiddleMan;
using namespace std;
class MiddleMan {
private:
string ttyname;
int mPTY, sPTY;
int mTTY, sTTY;
string ptyname;
bool running;
int sleep; // Microseconds
FILE *fout;
public:
MiddleMan(const string iotty_name,
const string fout_name="out",
int sleepTime=200);
~MiddleMan();
void run(int readLen=100);
string getPTY();
void handleInput(string input);
void log(string input, string output,
const string format=">> %s\n<< %s\n");
string openPTY();
void closePTY();
};
#endif

View File

@ -0,0 +1,15 @@
#include "MiddleMan.h"
#include <iostream>
int main(int argc, char **argv) {
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " <tty device>" << std::endl;
}
MiddleMan m(argv[1]);
std::cout << m.getPTY() << std::endl;
m.run();
return 0;
}

View File

@ -0,0 +1,33 @@
##
## **** Device Class ****
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
##
## Standard framework for the a Device that is attached
## to the PTY_Interface
##
class Device:
##
##%% No initialization
##
##%% handleCMD(pty_interface, command, arguments)
## A device attached to a PTY_Interface will handle commands
## passed to it from the PTY_Interface by a call made to
## this function.
##
## pty_interface will be a referance to the interface that called
## this function
##
## command will be a string with the text of the command read
## from the pty device
##
## arguments is an array of the arguments to said command read
## from the pty device
##
## The string returned by this function will be written to
## the pty device
##
def handleCMD(self, fpl, cmd, args=[]):
return ""

View File

@ -0,0 +1,87 @@
##
## **** PTY_Interface Class ****
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
##
## This class generates a pty device that emulates the
## tty device created by GPIB controllers such as
## Prologix GPIB-USB Controller (prologix.biz)
##
## This class does NOT emulate the controller, but the
## controller must be attached to this PTY Interface
##
## I may switch between the terms tty device and pty device.
## They refer to the same thing.
##
import os
import Device, Prologix
class Interface:
##%% Initialization - Interface(default_device, default_address)
## accepts arguments default_device and default_address
## the default_device will be connected at the default_address
##
## If the Interface address (PTY_Interface.addr) is changed, the
## no longer have anything attached and will become functionless.
## UNLESS, the default device handles the address change and copies itself
## to the new address (Prologix_GPIB_USB does this, OR there is
## another device attached there.
##
## if no arguments are given at initialization, defaults are
## Device.Prologix_GPIB-USB at address 0
##
def __init__(self,
default_device=Prologix.Prologix_GPIB_USB(),
default_address=0 ):
self.m, self.s = os.openpty()
self.devices = {default_address:default_device}
self.addr = default_address
##%% printFilename()
## Prints the path to the PTY device generated (ie /dev/pts/2)
##
def printFilename(self):
name = os.ttyname(self.s)
print(name)
return name
##%% run(readLen)
## Runs the emulator which will read all statements written from the outside
## to the pty device at the location given by self.printFilename(), then
## runs what was read through self.handleInput(tty_in) and writes output
## back to the pty device to be read from the outside
##
def run(self, readLen=100):
self.running = True
while (self.running):
tty_in = os.read(self.m, readLen)
for tty_out in self.handleInput(tty_in):
os.write(self.m, tty_out)
##%% handleInput(tty_in)
## Recieves raw input that was read from the pty device, and
## breaks it up and send it to the device listed at the current
## address. That device must handle the command via dev.handleCMD(cmd, args)
##
def handleInput(self, tty_in):
tty_in = tty_in.strip()
if tty_in != "" and self.addr in self.devices:
dev = self.devices[self.addr]
for cmd in tty_in.strip().split(";"):
p = cmd.strip().split(" ")
yield dev.handleCMD(self, p[0], p[1:]) + "\n"
yield "" # Must be a null string to prevent infinite loop
##%% addDevice(device, address)
## Preferred way of connecting a device to the interface
## at a given address
##
def addDevice(self, dev, addr):
self.devices[addr] = dev

View File

@ -0,0 +1,129 @@
##
## <<<< Powersupply Emulators >>>>
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
##
## Contains classes that emulate powersupplies by
## building off the Device framework
##
import Device, Prologix
## **** Power Supply class ****
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
##
## General model of a basic Power Supply
##
class PowerSupply(Prologix.Prologix_GPIB_USB):
##%% Initialization PowerSupply(volt, current)
## Creates a framework for a Powersupply, but only binds
## a reset call to "RST?". All other functions have been
## left unbound so that children can bind them to respective
## commands
##
## voltage and current default to 10
##
def __init__(self, volt=10, cur=10):
Prologix.Prologix_GPIB_USB.__init__(self)
self.addCMD("RST?", self.reset)
self.voltage = volt
self.current = cur
##%% reset(pty, args)
## returns that the device has been reset
##
def reset(self, fpl, args=[]):
return "Power Supply has been reset"
##%% version(pty, args)
## overrides the version function from superclass
## left unbound here, because it was bound in the
## superclass.
##
def version(self, fpl, args=[]):
return "Power Supply Version 1.GEN"
##%% on(pty, args)
## turns power supply on
##
def on(self, fpl, args=[]):
return self.version(fpl, args) + " in now ON"
##%% off(pty, args)
## turns power supply off
##
def off(self, fpl, args=[]):
return self.version(fpl, args) + " in now OFF"
##%% getVoltage(pty, args)
## returns voltage
##
def getVoltage(self, fpl, args=[]):
return self.voltage
##%% getCurrent(pty, args)
## returns current
##
def getCurrent(self, fpl, args=[]):
return self.current
##%% setVoltage(pty, args)
## sets voltage
##
def setVoltage(self, fpl, args=[]):
try:
self.voltage = float(args[0])
return ""
except:
return "ERROR"
##%% setCurrent(pty, args)
## sets current
##
def setCurrent(self, fpl, args=[]):
try:
self.current = float(args[0])
return ""
except:
return "ERROR"
##
## **** E3631A Power Supply Class ****
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
##
## Emulates the E3631A Power Supply
##
class E3631A(PowerSupply):
##%% Initialization - E3631A(voltage, current)
## see PowerSupply.PowerSupply documentation
##
## adds bindings for all of the PowerSupply functions
##
def __init__(self, volt=10, cur=10):
PowerSupply.__init__(self, volt, cur)
self.addCMD("OUTP", self.outp)
self.addCMD("MEAS:VOLT:DC", self.getVoltage)
self.addCMD("MEAS:CURR:DC", self.getCurrent)
self.addCMD("SET:VOLT:DC", self.setVoltage)
self.addCMD("SET:CURR:DC", self.setCurrent)
##%% version(pty, args)
## returns version
##
def version(self, fpl, args=[]):
return "E3631A Power Supply"
##%% outp(pty, args)
## function binding for the "OUTP" command
## Used to turn the device on and off
##
def outp(self, fpl, args=[]):
if args[0] == "ON":
return self.on(fpl, args)
elif args[0] == "OFF":
return self.off(fpl, args)
return ""

View File

@ -0,0 +1,85 @@
##
## **** Prologix_GPIB_USB Class ****
##
## A Device that emulates the functionality of the
## Prologix GPIB-USB Controller (prologix.biz)
##
import Device, PTY_Interface
class Prologix_GPIB_USB(Device.Device):
##%% Initialization - Prologix_GPIB_USB()
## Does not take arguments, but is VERY important
## All classes that attempt to inherit this class,
## must call this initialization.
##
## This creates a dictionary containing all the commands
## to be run. If this dictionary is not created, this class
## does nothing
##
def __init__(self):
self.cmds = { "++ver":self.version, # "COMMAND":HANDLER
"++addr":self.addr,
"++kill":self.kill}
##%% handleCMD(pty_interface, command, arguments)
## See Device.handleCMD documentation
##
## In Prologix_GPIB_USB, this function makes use of the
## map made in initialization to find the command and
## its associated handler, then call the handler and pass in
## the pty_interface and the arguments
##
def handleCMD(self, fpl, cmd, args=[]):
out = Device.Device.handleCMD(self, fpl, cmd, args)
if out != "":
return out
elif cmd in self.cmds:
return self.cmds[cmd](fpl, args)
else:
return ""
##%% version(pty, args)
## Returns the device version
##
def version(self, fpl, args=[]):
return "Prologix Version 1.1 Simulator (Python)"
##%% addr(pty, args)
## If no arguments are given, returns the current address
## of the pty interface
##
## if args are given, then an integer is parsed out of
## the first argument and set as the address. This ensures
## that a device exists at the following address
##
## Any errors return "ERROR"
##
def addr(self, fpl, args=[]):
if args == []:
return str(fpl.addr)
else:
try:
fpl.addr = int(args[0])
if not fpl.addr in fpl.devices:
fpl.addDevice(PrologixAdapter(), fpl.addr)
return ""
except:
return "ERROR"
##%% kill(pty, args)
## Stops the pty interface from running
##
def kill(self, fpl, args=[]):
fpl.running = False
return ""
##%% addCMD(command, handler_function)
## Adds a command to the dictionary
## Handler function must be of the form
## func(pty_interface, arguments):
##
def addCMD(self, cmd, func):
self.cmds[cmd] = func

View File

@ -0,0 +1,77 @@
##
## <<<< Source Measurement Unit Emulators >>>>
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
##
## Contains classes that emulate Source Measurement Units
##
import Device, Prologix
## **** Source Measurement Class ****
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
##
## General model of a basic Source Measurement Unit
##
class SourceMeasurement(Prologix.Prologix_GPIB_USB):
##%% Initialization SourceMeasurement()
## Creates the framework
##
def __init__(self):
Prologix.Prologix_GPIB_USB.__init__(self)
## **** Keithley 2400 Class ****
## by Aidan Macdonald
##
## Support given for some commands
##
from random import uniform as rand
class Keithley_2400(SourceMeasurement):
##%% Initialization - Keithley_2400()
## Loads commands
##
def __init__(self):
SourceMeasurement.__init__(self)
self.addCMD("IDN?", self.version)
self.addCMD("*RST", self.noth)
self.addCMD("*CLS", self.noth)
self.addCMD("ABOR", self.noth)
self.addCMD("*CLS", self.noth)
self.addCMD("SYST:BEEP:STAT", self.noth)
self.addCMD("SOURCE:CLEAR:AUTO", self.noth)
self.addCMD("FORM:ELEM", self.noth)
self.addCMD(":SOUR:FUNC", self.noth)
self.addCMD("read?", self.randFloats)
## noth(pty, args)
## Does nothing
##
def noth(self, fpl, args):
pass # Do nothing
def version(self, fpl, args):
return 'KEITHLEY INSTRUMENTS INC.,MODEL 2400.EMULATOR'
## randFloats(pty, args)
## returns a string of random floats
##
def randFloats(self, fpl, args):
return str(rand(0, 2)) + ", " str(rand(0, 2))
## handleCMD(fpl, cmd, args)
## Modified to be case insensitive
##
def handleCMD(self, fpl, cmd, args):
SourceMeasurement.handleCMD(self, fpl, cmd.upper(), args)

View File

@ -0,0 +1,12 @@
#!/usr/bin/python
import PTY_Interface
import PowerSupply
pty = PTY_Interface.Interface()
pty.addDevice(PowerSupply.PowerSupply(), 5)
pty.addDevice(PowerSupply.E3631A(), 3)
pty.printFilename()
pty.run()

View File

@ -0,0 +1,5 @@
#!/bin/bash
NAME=`echo $1 | awk -F'.' '{ print $1 }'`
cat $1 | grep "##" | sed s/"##"//g | sed s/"\*\*"/"="/g | sed s/"<<<<"/"="/g | sed s/">>>>"/"="/g | sed s/"%%"/"*"/g > $2

View File

@ -0,0 +1,14 @@
#!/bin/bash
cat < $1 &
echo "++ver" > $1
echo "++addr" > $1
echo "++addr 12" > $1
echo "++addr" > $1
while true
do
read CMD
echo $CMD > $1
done