#include "rs274ngc.hh"
#include "rs274ngc_interp.hh"
#include "rs274ngc_return.hh"
#include "inifile.hh"
#include "canon.hh"
#include "config.h"
#include "tool_parse.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <stdarg.h>
#include <string>
#include <readline/readline.h>
#include <readline/history.h>
#include <glob.h>
#include <wordexp.h>
#include <saicanon.hh>
InterpBase *pinterp;
#define interp_new (*pinterp)
const char *prompt = "READ => ";
const char *history = "~/.rs274";
#define RS274_HISTORY "RS274_HISTORY"
#define active_settings interp_new.active_settings
#define active_g_codes interp_new.active_g_codes
#define active_m_codes interp_new.active_m_codes
#define error_text interp_new.error_text
#define interp_execute interp_new.execute
#define file_name interp_new.file_name
#define interp_init interp_new.init
#define stack_name interp_new.stack_name
#define line_text interp_new.line_text
#define line_length interp_new.line_length
#define sequence_number interp_new.sequence_number
#define interp_close interp_new.close
#define interp_exit interp_new.exit
#define interp_open interp_new.open
#define interp_read interp_new.read
#define interp_load_tool_table interp_new.load_tool_table
#define interp_set_loglevel interp_new.set_loglevel
#define interp_task_init interp_new.task_init
void report_error(
int error_code,
int print_stack)
{
char interp_error_text_buf[LINELEN];
int k;
error_text(error_code, interp_error_text_buf, 5);
error_text(error_code, interp_error_text_buf, LINELEN);
fprintf(stderr, "%s\n",
((interp_error_text_buf[0] == 0) ? "Unknown error, bad error code" : interp_error_text_buf));
line_text(interp_error_text_buf, LINELEN);
fprintf(stderr, "%s\n", interp_error_text_buf);
if (print_stack == ON)
{
for (k = 0; ; k++)
{
stack_name(k, interp_error_text_buf, LINELEN);
if (interp_error_text_buf[0] != 0)
fprintf(stderr, "%s\n", interp_error_text_buf);
else
break;
}
}
}
void initialize_readline ()
{
wordexp_t p;
const char *s;
rl_readline_name = "rs274";
if ((s = getenv(RS274_HISTORY)))
history = s;
if (wordexp(history, &p, WRDE_SHOWERR|WRDE_UNDEF )) {
perror("wordexp");
} else {
history = strdup(p.we_wordv[0]);
}
if (history)
read_history(history);
}
int interpret_from_keyboard(
int block_delete,
int print_stack)
{
char *line;
int status;
initialize_readline ();
for(; ;)
{
line = readline ( prompt);
if (!line || strcmp (line, "quit") == 0) {
if (history)
write_history(history);
return 0;
}
if (*line)
add_history(line);
status = interp_read(line);
if ((status == INTERP_EXECUTE_FINISH) && (block_delete == ON));
else if (status == INTERP_ENDFILE);
else if ((status != INTERP_EXECUTE_FINISH) &&
(status != INTERP_OK))
report_error(status, print_stack);
else
{
status = interp_execute();
if ((status == INTERP_EXIT) ||
(status == INTERP_EXECUTE_FINISH));
else if (status != INTERP_OK)
report_error(status, print_stack);
}
}
}
int interpret_from_file(
int do_next,
int block_delete,
int print_stack)
{
int status=0;
char line[LINELEN];
SET_BLOCK_DELETE(block_delete);
for(; ;)
{
status = interp_read();
if ((status == INTERP_EXECUTE_FINISH) && (block_delete == ON))
continue;
else if (status == INTERP_ENDFILE)
break;
if ((status != INTERP_OK) && (status != INTERP_EXECUTE_FINISH))
{
report_error(status, print_stack);
if (do_next == 2)
{
status = 1;
break;
}
else if (do_next == 1)
{
fprintf(stderr, "starting MDI\n");
interpret_from_keyboard(block_delete, print_stack);
fprintf(stderr, "continue program? y/n =>");
if (!fgets(line, LINELEN, stdin) || line[0] != 'y')
{
status = 1;
break;
}
else
continue;
}
else
continue;
}
status = interp_execute();
if ((status != INTERP_OK) &&
(status != INTERP_EXIT) &&
(status != INTERP_EXECUTE_FINISH))
{
report_error(status, print_stack);
status = 1;
if (do_next == 1)
{
fprintf(stderr, "starting MDI\n");
interpret_from_keyboard(block_delete, print_stack);
fprintf(stderr, "continue program? y/n =>");
if (!fgets(line, LINELEN, stdin) || line[0] != 'y')
break;
}
else if (do_next == 2)
break;
}
else if (status == INTERP_EXIT)
return 0;
}
return ((status == 1) ? 1 : 0);
}
int read_tool_file(
const char * tool_file_name)
{
char buffer[1000];
if (tool_file_name[0] == 0)
{
fprintf(stderr, "name of tool file => ");
if(!fgets(buffer, 1000, stdin)) return 1;
buffer[strlen(buffer) - 1] = 0;
tool_file_name = buffer;
}
return loadToolTable(tool_file_name, _sai._tools, 0, 0);
}
int designate_parameter_file(char * parameter_file_name)
{
FILE * test_port;
fprintf(stderr, "name of parameter file => ");
if(!fgets(parameter_file_name, PARAMETER_FILE_NAME_LENGTH, stdin))
return 1;
parameter_file_name[strlen(parameter_file_name) - 1] = 0;
test_port = fopen(parameter_file_name, "r");
if (test_port == NULL)
{
fprintf(stderr, "Cannot open %s\n", parameter_file_name);
return 1;
}
fclose(test_port);
return 0;
}
int adjust_error_handling(
int args,
int * print_stack,
int * do_next)
{
char buffer[80];
int choice;
for(;;)
{
fprintf(stderr, "enter a number:\n");
fprintf(stderr, "1 = done with error handling\n");
fprintf(stderr, "2 = %sprint stack on error\n",
((*print_stack == ON) ? "do not " : ""));
if (args == 3)
{
if (*do_next == 0)
fprintf(stderr,
"3 = stop on error (do not continue)\n");
else
fprintf(stderr,
"3 = continue on error (do not stop)\n");
}
else if (args == 2)
{
if (*do_next == 0)
fprintf(stderr,
"3 = mdi on error (do not continue or stop)\n");
else if (*do_next == 1)
fprintf(stderr,
"3 = stop on error (do not mdi or continue)\n");
else
fprintf(stderr,
"3 = continue on error (do not stop or mdi)\n");
}
fprintf(stderr, "enter choice => ");
if (!fgets(buffer, 80, stdin))
break;
if (sscanf(buffer, "%d", &choice) != 1)
continue;
if (choice == 1)
break;
else if (choice == 2)
*print_stack = ((*print_stack == OFF) ? ON : OFF);
else if ((choice == 3) && (args == 3))
*do_next = ((*do_next == 0) ? 2 : 0);
else if ((choice == 3) && (args == 2))
*do_next = ((*do_next == 2) ? 0 : (*do_next + 1));
}
return 0;
}
int _task = 0;
int main (int argc, char ** argv)
{
int status;
int choice;
int do_next;
int block_delete;
char buffer[80];
int tool_flag;
int gees[ACTIVE_G_CODES];
int ems[ACTIVE_M_CODES];
double sets[ACTIVE_SETTINGS];
char default_name[] = "/etc/emc2/sample-configs/sim/sim.var";
int print_stack;
int go_flag;
char *inifile = NULL;
int log_level = -1;
std::string interp;
do_next = 2;
block_delete = OFF;
print_stack = OFF;
tool_flag = 0;
SET_PARAMETER_FILE_NAME(default_name);
_outfile = stdout;
go_flag = 0;
while(1) {
int c = getopt(argc, argv, "p:t:v:bsn:gi:l:T");
if(c == -1) break;
switch(c) {
case 'p': interp = optarg; break;
case 't': read_tool_file(optarg); tool_flag=1; break;
case 'v': SET_PARAMETER_FILE_NAME(optarg); break;
case 'b': block_delete = (block_delete == OFF) ? ON : OFF; break;
case 's': print_stack = (print_stack == OFF) ? ON : OFF; break;
case 'n': do_next = atoi(optarg); break;
case 'l': log_level = atoi(optarg); break;
case 'g': go_flag = !go_flag; break;
case 'i': inifile = optarg; break;
case 'T': _task = 1; break;
case '?': default: goto usage;
}
}
if (argc - optind > 3)
{
usage:
fprintf(stderr,
"Usage: %s [-p interp.so] [-t tool.tbl] [-v var-file.var] [-n 0|1|2]\n"
" [-b] [-s] [-g] [input file [output file]]\n"
"\n"
" -p: Specify the pluggable interpreter to use\n"
" -t: Specify the .tbl (tool table) file to use\n"
" -v: Specify the .var (parameter) file to use\n"
" -n: Specify the continue mode:\n"
" 0: continue\n"
" 1: enter MDI mode\n"
" 2: stop (default)\n"
" -b: Toggle the 'block delete' flag (default: OFF)\n"
" -s: Toggle the 'print stack' flag (default: OFF)\n"
" -g: Toggle the 'go (batch mode)' flag (default: OFF)\n"
" -i: specify the .ini file (default: no ini file)\n"
" -T: call task_init()\n"
" -l: specify the log_level (default: -1)\n"
, argv[0]);
exit(1);
}
if(!interp.empty()) {
pinterp = interp_from_shlib(interp.c_str());
}
if(!pinterp) pinterp = new Interp;
for(; !go_flag ;)
{
fprintf(stderr, "enter a number:\n");
fprintf(stderr, "1 = start interpreting\n");
fprintf(stderr, "2 = choose parameter file ...\n");
fprintf(stderr, "3 = read tool file ...\n");
fprintf(stderr, "4 = turn block delete switch %s\n",
((block_delete == OFF) ? "ON" : "OFF"));
fprintf(stderr, "5 = adjust error handling...\n");
fprintf(stderr, "enter choice => ");
if (!fgets(buffer, 80, stdin))
break;
if (sscanf(buffer, "%d", &choice) != 1)
continue;
if (choice == 1)
break;
else if (choice == 2)
{
if (designate_parameter_file(_parameter_file_name) != 0)
exit(1);
}
else if (choice == 3)
{
if (read_tool_file("") != 0)
exit(1);
tool_flag = 1;
}
else if (choice == 4)
block_delete = ((block_delete == OFF) ? ON : OFF);
else if (choice == 5)
adjust_error_handling(argc, &print_stack, &do_next);
}
fprintf(stderr, "executing\n");
if (tool_flag == 0)
{
if (read_tool_file(EMC2_DEFAULT_TOOLTABLE) != 0)
exit(1);
}
argc = argc - optind + 1;
argv = argv + optind - 1;
if (argc == 3)
{
_outfile = fopen(argv[2], "w");
if (_outfile == NULL)
{
fprintf(stderr, "could not open output file %s\n", argv[2]);
exit(1);
}
}
if (inifile!= 0) {
setenv("INI_FILE_NAME",inifile,1);
} else
unsetenv("INI_FILE_NAME");
if ((status = interp_init()) != INTERP_OK)
{
report_error(status, print_stack);
exit(1);
}
if (log_level != -1)
interp_set_loglevel(log_level);
if (argc == 1)
status = interpret_from_keyboard(block_delete, print_stack);
else
{
status = interp_open(argv[1]);
if (status != INTERP_OK)
{
report_error(status, print_stack);
exit(1);
}
status = interpret_from_file(do_next, block_delete, print_stack);
file_name(buffer, 5);
file_name(buffer, 79);
interp_close();
}
line_length();
sequence_number();
active_g_codes(gees);
active_m_codes(ems);
active_settings(sets);
interp_exit();
exit(status);
}
int emcOperatorError(int id, const char *fmt, ...)
{
va_list ap;
if (id)
fprintf(stderr,"[%d] ", id);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
return 0;
}