Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

driver.cc

Go to the documentation of this file.
00001 /*
00002    File : driver.cc
00003 
00004 Modifications:
00005 13-Oct-2000 WPS changed gets to fgets and moved external canon variable definitions to canon.hh. (This may be temperary.)
00006 */
00007 
00008 #include "rs274ngc.hh"
00009 #include "rs274ngc_return.hh"
00010 #include <stdio.h>    /* gets, etc. */
00011 #include <stdlib.h>   /* exit       */
00012 #include <string.h>   /* strcpy     */
00013 
00014 
00015 
00016 /*
00017 
00018 This file contains the source code for an emulation of using the six-axis
00019 rs274 interpreter from the EMC system.
00020 
00021 */
00022 
00023 /*********************************************************************/
00024 
00025 /* report_error
00026 
00027 Returned Value: none
00028 
00029 Side effects: an error message is printed on stderr
00030 
00031 Called by:
00032   interpret_from_file
00033   interpret_from_keyboard
00034   main
00035 
00036 This
00037 
00038 1. calls rs274ngc_error_text to get the text of the error message whose
00039 code is error_code and prints the message,
00040 
00041 2. calls rs274ngc_line_text to get the text of the line on which the
00042 error occurred and prints the text, and
00043 
00044 3. if print_stack is on, repeatedly calls rs274ngc_stack_name to get
00045 the names of the functions on the function call stack and prints the
00046 names. The first function named is the one that sent the error
00047 message.
00048 
00049 
00050 */
00051 
00052 void report_error( /* ARGUMENTS                            */
00053  int error_code,   /* the code number of the error message */
00054  int print_stack)  /* print stack if ON, otherwise not     */
00055 {
00056   char buffer[RS274NGC_TEXT_SIZE];
00057   int k;
00058 
00059   rs274ngc_error_text(error_code, buffer, 5); /* for coverage of code */
00060   rs274ngc_error_text(error_code, buffer, RS274NGC_TEXT_SIZE);
00061   fprintf(stderr, "%s\n",
00062           ((buffer[0] IS 0) ? "Unknown error, bad error code" : buffer));
00063   rs274ngc_line_text(buffer, RS274NGC_TEXT_SIZE);
00064   fprintf(stderr, "%s\n", buffer);
00065   if (print_stack IS ON)
00066     {
00067       for (k SET_TO 0; ; k++)
00068         {
00069           rs274ngc_stack_name(k, buffer, RS274NGC_TEXT_SIZE);
00070           if (buffer[0] ISNT 0)
00071             fprintf(stderr, "%s\n", buffer);
00072           else
00073             break;
00074         }
00075     }
00076 }
00077 
00078 /***********************************************************************/
00079 
00080 /* interpret_from_keyboard
00081 
00082 Returned Value: int (0)
00083 
00084 Side effects:
00085   Lines of NC code entered by the user are interpreted.
00086 
00087 Called by:
00088   interpret_from_file
00089   main
00090 
00091 This prompts the user to enter a line of rs274 code. When the user
00092 hits <enter> at the end of the line, the line is executed.
00093 Then the user is prompted to enter another line.
00094 
00095 Any canonical commands resulting from executing the line are printed
00096 on the monitor (stdout).  If there is an error in reading or executing
00097 the line, an error message is printed on the monitor (stderr).
00098 
00099 To exit, the user must enter "quit" (followed by a carriage return).
00100 
00101 */
00102 
00103 int interpret_from_keyboard(  /* ARGUMENTS                 */
00104  int block_delete,            /* switch which is ON or OFF */
00105  int print_stack)             /* option which is ON or OFF */
00106 {
00107   char line[RS274NGC_TEXT_SIZE];
00108   int status;
00109 
00110   for(; ;)
00111     {
00112       printf("READ => ");
00113       fgets(line,RS274NGC_TEXT_SIZE,stdin);
00114       if (strcmp (line, "quit") IS 0)
00115         return 0;
00116       status SET_TO rs274ngc_read(line);
00117       if ((status IS RS274NGC_EXECUTE_FINISH) AND (block_delete IS ON));
00118       else if (status IS RS274NGC_ENDFILE);
00119       else if ((status ISNT RS274NGC_EXECUTE_FINISH) AND
00120                (status ISNT RS274NGC_OK))
00121         report_error(status, print_stack);
00122       else
00123         {
00124           status SET_TO rs274ngc_execute();
00125           if ((status IS RS274NGC_EXIT) OR
00126               (status IS RS274NGC_EXECUTE_FINISH));
00127           else if (status ISNT RS274NGC_OK)
00128             report_error(status, print_stack);
00129         }
00130     }
00131 }
00132 
00133 /*********************************************************************/
00134 
00135 /* interpret_from_file
00136 
00137 Returned Value: int (0 or 1)
00138    If any of the following errors occur, this returns 1.
00139    Otherwise, it returns 0.
00140    1. rs274ngc_read returns something other than RS274NGC_OK or
00141       RS274NGC_EXECUTE_FINISH, no_stop is off, and the user elects
00142       not to continue.
00143    2. rs274ngc_execute returns something other than RS274NGC_OK,
00144       EXIT, or RS274NGC_EXECUTE_FINISH, no_stop is off, and the user
00145       elects not to continue.
00146 
00147 Side Effects:
00148    An open NC-program file is interpreted.
00149 
00150 Called By:
00151    main
00152 
00153 This emulates the way the EMC system uses the interpreter.
00154 
00155 If the do_next argument is 1, this goes into MDI mode if an error is
00156 found. In that mode, the user may (1) enter code or (2) enter "quit" to
00157 get out of MDI. Once out of MDI, this asks the user whether to continue
00158 interpreting the file.
00159 
00160 If the do_next argument is 0, an error does not stop interpretation.
00161 
00162 If the do_next argument is 2, an error stops interpretation.
00163 
00164 */
00165 
00166 int interpret_from_file( /* ARGUMENTS                  */
00167  int do_next,            /* what to do if error        */
00168  int block_delete,       /* switch which is ON or OFF  */
00169  int print_stack)        /* option which is ON or OFF  */
00170 {
00171   int status;
00172   char line[RS274NGC_TEXT_SIZE];
00173 
00174   for(; ;)
00175     {
00176       status SET_TO rs274ngc_read(NULL);
00177       if ((status IS RS274NGC_EXECUTE_FINISH) AND (block_delete IS ON))
00178         continue;
00179       else if (status IS RS274NGC_ENDFILE)
00180         break;
00181       if ((status ISNT RS274NGC_OK) AND    // should not be EXIT
00182           (status ISNT RS274NGC_EXECUTE_FINISH))
00183         {
00184           report_error(status, print_stack);
00185           if ((status IS NCE_FILE_ENDED_WITH_NO_PERCENT_SIGN) OR
00186               (do_next IS 2)) /* 2 means stop */
00187             {
00188               status SET_TO 1;
00189               break;
00190             }
00191           else if (do_next IS 1) /* 1 means MDI */
00192             {
00193               fprintf(stderr, "starting MDI\n");
00194               interpret_from_keyboard(block_delete, print_stack);
00195               fprintf(stderr, "continue program? y/n =>");
00196               fgets(line,RS274NGC_TEXT_SIZE,stdin);
00197               if (line[0] ISNT 'y')
00198                 {
00199                   status SET_TO 1;
00200                   break;
00201                 }
00202               else
00203                 continue;
00204             }
00205           else /* if do_next IS 0 -- 0 means continue */
00206             continue;
00207         }
00208       status SET_TO rs274ngc_execute();
00209       if ((status ISNT RS274NGC_OK) AND
00210           (status ISNT RS274NGC_EXIT) AND
00211           (status ISNT RS274NGC_EXECUTE_FINISH))
00212         {
00213           report_error(status, print_stack);
00214           status SET_TO 1;
00215           if (do_next IS 1) /* 1 means MDI */
00216             {
00217               fprintf(stderr, "starting MDI\n");
00218               interpret_from_keyboard(block_delete, print_stack);
00219               fprintf(stderr, "continue program? y/n =>");
00220               fgets(line,RS274NGC_TEXT_SIZE,stdin);
00221               if (line[0] ISNT 'y')
00222                 break;
00223             }
00224           else if (do_next IS 2) /* 2 means stop */
00225             break;
00226         }
00227       else if (status IS RS274NGC_EXIT)
00228         break;
00229     }
00230   return ((status IS 1) ? 1 : 0);
00231 }
00232 
00233 /************************************************************************/
00234 
00235 /* read_tool_file
00236 
00237 Returned Value: int
00238   If any of the following errors occur, this returns 1.
00239   Otherwise, it returns 0.
00240   1. The file named by the user cannot be opened.
00241   2. No blank line is found.
00242   3. A line of data cannot be read.
00243   4. A tool slot number is less than 1 or >= _tool_max
00244 
00245 Side Effects:
00246   Values in the tool table of the machine setup are changed,
00247   as specified in the file.
00248 
00249 Called By: main
00250 
00251 Tool File Format
00252 -----------------
00253 Everything above the first blank line is read and ignored, so any sort
00254 of header material may be used.
00255 
00256 Everything after the first blank line should be data. Each line of
00257 data should have four or more items separated by white space. The four
00258 required items are slot, tool id, tool length offset, and tool diameter.
00259 Other items might be the holder id and tool description, but these are
00260 optional and will not be read. Here is a sample line:
00261 
00262 20  1419  4.299  1.0   1 inch carbide end mill
00263 
00264 The tool_table is indexed by slot number.
00265 
00266 */
00267 
00268 int read_tool_file(  /* ARGUMENTS         */
00269  char * file_name)   /* name of tool file */
00270 {
00271   FILE * tool_file_port;
00272   char buffer[1000];
00273   int slot;
00274   int tool_id;
00275   double offset;
00276   double diameter;
00277 
00278   if (file_name[0] IS 0) /* ask for name if given name is empty string */
00279     {
00280       fprintf(stderr, "name of tool file => ");
00281       fgets(buffer,1000,stdin);
00282       tool_file_port SET_TO fopen(buffer, "r");
00283     }
00284   else
00285       tool_file_port SET_TO fopen(file_name, "r");
00286   if (tool_file_port IS NULL)
00287     {
00288       fprintf(stderr, "Cannot open %s\n",
00289               ((file_name[0] IS 0) ? buffer : file_name));
00290       return 1;
00291     }
00292   for(;;)    /* read and discard header, checking for blank line */
00293     {
00294       if (fgets(buffer, 1000, tool_file_port) IS NULL)
00295         {
00296           fprintf(stderr, "Bad tool file format\n");
00297           return 1;
00298         }
00299       else if (buffer[0] IS '\n')
00300         break;
00301     }
00302 
00303   for (slot SET_TO 0; slot <= _tool_max; slot++) /* initialize */
00304     {
00305       _tools[slot].id SET_TO -1;
00306       _tools[slot].length SET_TO 0;
00307       _tools[slot].diameter SET_TO 0;
00308     }
00309   for (; (fgets(buffer, 1000, tool_file_port) ISNT NULL); )
00310     {
00311       if (sscanf(buffer, "%d %d %lf %lf", &slot,
00312                  &tool_id, &offset, &diameter) < 4)
00313         {
00314           fprintf(stderr, "Bad input line \"%s\" in tool file\n", buffer);
00315           return 1;
00316         }
00317       if ((slot < 0) OR (slot > _tool_max)) /* zero and max both OK */
00318         {
00319           fprintf(stderr, "Out of range tool slot number %d\n", slot);
00320           return 1;
00321         }
00322       _tools[slot].id SET_TO tool_id;
00323       _tools[slot].length SET_TO offset;
00324       _tools[slot].diameter SET_TO diameter;
00325     }
00326   fclose(tool_file_port);
00327   return 0;
00328 }
00329 
00330 /************************************************************************/
00331 
00332 /* designate_parameter_file
00333 
00334 Returned Value: int
00335   If any of the following errors occur, this returns 1.
00336   Otherwise, it returns 0.
00337   1. The file named by the user cannot be opened.
00338 
00339 Side Effects:
00340   The name of a parameter file given by the user is put in the
00341   file_name string.
00342 
00343 Called By: main
00344 
00345 */
00346 
00347 int designate_parameter_file(char * file_name)
00348 {
00349   FILE * test_port;
00350 
00351   fprintf(stderr, "name of parameter file => ");
00352   fgets(file_name,PARAMETER_FILE_NAME_LENGTH,stdin);
00353   test_port SET_TO fopen(file_name, "r");
00354   if (test_port IS NULL)
00355     {
00356       fprintf(stderr, "Cannot open %s\n", file_name);
00357       return 1;
00358     }
00359   fclose(test_port);
00360   return 0;
00361 }
00362 
00363 /************************************************************************/
00364 
00365 /* adjust_error_handling
00366 
00367 Returned Value: int (0)
00368 
00369 Side Effects:
00370   The values of print_stack and do_next are set.
00371 
00372 Called By: main
00373 
00374 This function allows the user to set one or two aspects of error handling.
00375 
00376 By default the driver does not print the function stack in case of error.
00377 This function always allows the user to turn stack printing on if it is off
00378 or to turn stack printing off if it is on.
00379 
00380 When interpreting from the keyboard, the driver always goes ahead if there
00381 is an error.
00382 
00383 When interpreting from a file, the default behavior is to stop in case of
00384 an error. If the user is interpreting from a file (indicated by args being
00385 2 or 3), this lets the user change what it does on an error.
00386 
00387 If the user has not asked for output to a file (indicated by args being 2),
00388 the user can choose any of three behaviors in case of an error (1) continue,
00389 (2) stop, (3) go into MDI mode. This function allows the user to cycle among
00390 the three.
00391 
00392 If the user has asked for output to a file (indicated by args being 3),
00393 the user can choose any of two behaviors in case of an error (1) continue,
00394 (2) stop. This function allows the user to toggle between the two.
00395 
00396 */
00397 
00398 int adjust_error_handling(
00399  int args,
00400  int * print_stack,
00401  int * do_next)
00402 {
00403   char buffer[80];
00404   int choice;
00405 
00406   for(;;)
00407     {
00408       fprintf(stderr, "enter a number:\n");
00409       fprintf(stderr, "1 = done with error handling\n");
00410       fprintf(stderr, "2 = %sprint stack on error\n",
00411               ((*print_stack IS ON) ? "do not " : ""));
00412       if (args IS 3)
00413         {
00414           if (*do_next IS 0) /* 0 means continue */
00415             fprintf(stderr,
00416                     "3 = stop on error (do not continue)\n");
00417           else /* if do_next IS 2 -- 2 means stopping on error */
00418             fprintf(stderr,
00419                     "3 = continue on error (do not stop)\n");
00420         }
00421       else if (args IS 2)
00422         {
00423           if (*do_next IS 0) /* 0 means continue */
00424             fprintf(stderr,
00425                     "3 = mdi on error (do not continue or stop)\n");
00426           else if (*do_next IS 1) /* 1 means MDI */
00427             fprintf(stderr,
00428                     "3 = stop on error (do not mdi or continue)\n");
00429           else /* if do_next IS 2 -- 2 means stopping on error */
00430             fprintf(stderr,
00431                     "3 = continue on error (do not stop or mdi)\n");
00432         }
00433       fprintf(stderr, "enter choice => ");
00434       fgets(buffer,80,stdin);
00435       if (sscanf(buffer, "%d", &choice) ISNT 1)
00436         continue;
00437       if (choice IS 1)
00438         break;
00439       else if (choice IS 2)
00440         *print_stack SET_TO ((*print_stack IS OFF) ? ON : OFF);
00441       else if ((choice IS 3) AND (args IS 3))
00442         *do_next SET_TO ((*do_next IS 0) ? 2 : 0);
00443       else if ((choice IS 3) AND (args IS 2))
00444         *do_next SET_TO ((*do_next IS 2) ? 0 : (*do_next + 1));
00445     }
00446   return 0;
00447 }
00448 
00449 /************************************************************************/
00450 
00451 /* main
00452 
00453 The executable exits with either 0 (under all conditions not listed
00454 below) or 1 (under the following conditions):
00455 1. A fatal error occurs while interpreting from a file.
00456 2. Read_tool_file fails.
00457 3. An error occurs in rs274ngc_init.
00458 
00459 ***********************************************************************
00460 
00461 Here are three ways in which the rs274abc executable may be called.
00462 Any other sort of call to the executable will cause an error message
00463 to be printed and the interpreter will not run. Other executables
00464 may be called similarly.
00465 
00466 1. If the rs274abc stand-alone executable is called with no arguments,
00467 input is taken from the keyboard, and an error in the input does not
00468 cause the rs274abc executable to exit.
00469 
00470 EXAMPLE:
00471 
00472 1A. To interpret from the keyboard, enter:
00473 
00474 rs274abc
00475 
00476 ***********************************************************************
00477 
00478 2. If the executable is called with one argument, the argument is
00479 taken to be the name of an NC file and the file is interpreted as
00480 described in the documentation of interpret_from_file.
00481 
00482 
00483 EXAMPLES:
00484 
00485 2A. To interpret the file "cds.abc" and read the results on the
00486 screen, enter:
00487 
00488 rs274abc cds.abc
00489 
00490 2B. To interpret the file "cds.abc" and print the results in the file
00491 "cds.prim", enter:
00492 
00493 rs274abc cds.abc > cds.prim
00494 
00495 ***********************************************************************
00496 
00497 Whichever way the executable is called, this gives the user several
00498 choices before interpretation starts
00499 
00500 1 = start interpreting
00501 2 = choose parameter file
00502 3 = read tool file ...
00503 4 = turn block delete switch ON
00504 5 = adjust error handling...
00505 
00506 Interpretation starts when option 1 is chosen. Until that happens, the
00507 user is repeatedly given the five choices listed above.  Item 4
00508 toggles between "turn block delete switch ON" and "turn block delete
00509 switch OFF".  See documentation of adjust_error_handling regarding
00510 what option 5 does.
00511 
00512 User instructions are printed to stderr (with fprintf) so that output
00513 can be redirected to a file. When output is redirected and user
00514 instructions are printed to stdout (with printf), the instructions get
00515 redirected and the user does not see them.
00516 
00517 */
00518 
00519 int main (int argc, char ** argv)
00520 {
00521   int status;
00522   int choice;
00523   int do_next; /* 0=continue, 1=mdi, 2=stop */
00524   int block_delete;
00525   char buffer[80];
00526   int tool_flag;
00527   int gees[RS274NGC_ACTIVE_G_CODES];
00528   int ems[RS274NGC_ACTIVE_M_CODES];
00529   double sets[RS274NGC_ACTIVE_SETTINGS];
00530   char default_name[] SET_TO "rs274ngc.var";
00531   int print_stack;
00532 
00533   if (argc > 3)
00534     {
00535       fprintf(stderr, "Usage \"%s\"\n", argv[0]);
00536       fprintf(stderr, "   or \"%s <input file>\"\n", argv[0]);
00537       fprintf(stderr, "   or \"%s <input file> <output file>\"\n", argv[0]);
00538       exit(1);
00539     }
00540 
00541   do_next SET_TO 2;  /* 2=stop */
00542   block_delete SET_TO OFF;
00543   print_stack SET_TO OFF;
00544   tool_flag SET_TO 0;
00545   strcpy(_parameter_file_name, default_name);
00546   _outfile SET_TO stdout; /* may be reset below */
00547 
00548   for(; ;)
00549     {
00550       fprintf(stderr, "enter a number:\n");
00551       fprintf(stderr, "1 = start interpreting\n");
00552       fprintf(stderr, "2 = choose parameter file ...\n");
00553       fprintf(stderr, "3 = read tool file ...\n");
00554       fprintf(stderr, "4 = turn block delete switch %s\n",
00555               ((block_delete IS OFF) ? "ON" : "OFF"));
00556       fprintf(stderr, "5 = adjust error handling...\n");
00557       fprintf(stderr, "enter choice => ");
00558       fgets(buffer,80,stdin);
00559       if (sscanf(buffer, "%d", &choice) ISNT 1)
00560         continue;
00561       if (choice IS 1)
00562         break;
00563       else if (choice IS 2)
00564         {
00565           if (designate_parameter_file(_parameter_file_name) ISNT 0)
00566             exit(1);
00567         }
00568       else if (choice IS 3)
00569         {
00570           if (read_tool_file("") ISNT 0)
00571             exit(1);
00572           tool_flag SET_TO 1;
00573         }
00574       else if (choice IS 4)
00575         block_delete SET_TO ((block_delete IS OFF) ? ON : OFF);
00576       else if (choice IS 5)
00577         adjust_error_handling(argc, &print_stack, &do_next);
00578     }
00579   fprintf(stderr, "executing\n");
00580   if (tool_flag IS 0)
00581     {
00582       if (read_tool_file("rs274ngc.tool_default") ISNT 0)
00583         exit(1);
00584     }
00585 
00586   if (argc IS 3)
00587     {
00588       _outfile SET_TO fopen(argv[2], "w");
00589       if (_outfile IS NULL)
00590         {
00591           fprintf(stderr, "could not open output file %s\n", argv[2]);
00592           exit(1);
00593         }
00594     }
00595 
00596   if ((status SET_TO rs274ngc_init()) ISNT RS274NGC_OK)
00597     {
00598       report_error(status, print_stack);
00599       exit(1);
00600     }
00601 
00602   if (argc IS 1)
00603     status SET_TO interpret_from_keyboard(block_delete, print_stack);
00604   else /* if (argc IS 2 or argc IS 3) */
00605     {
00606       status SET_TO rs274ngc_open(argv[1]);
00607       if (status ISNT RS274NGC_OK) /* do not need to close since not open */
00608         {
00609           report_error(status, print_stack);
00610           exit(1);
00611         }
00612       status SET_TO interpret_from_file(do_next, block_delete, print_stack);
00613       rs274ngc_file_name(buffer, 5);  /* called to exercise the function */
00614       rs274ngc_file_name(buffer, 79); /* called to exercise the function */
00615       rs274ngc_close();
00616     }
00617   rs274ngc_line_length();         /* called to exercise the function */
00618   rs274ngc_sequence_number();     /* called to exercise the function */
00619   rs274ngc_active_g_codes(gees);  /* called to exercise the function */
00620   rs274ngc_active_m_codes(ems);   /* called to exercise the function */
00621   rs274ngc_active_settings(sets); /* called to exercise the function */
00622   rs274ngc_exit(); /* saves parameters */
00623   exit(status);
00624 }
00625 
00626 /***********************************************************************/

Generated on Sun Dec 2 15:27:36 2001 for EMC by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001