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

driver.cc

Go to the documentation of this file.
00001 /*
00002   driver.cc
00003   This file contains the source code for an emulation of using the
00004   rs274 interpreter from the EMC system (including the main
00005   function).
00006 
00007   Modification history:
00008 
00009   9-Jun-1999  FMP fixed fgets() calls to strip off terminal newline
00010   16-Feb-1999  FMP replaced gets() calls to fgets()
00011   ---  TRK created
00012 */
00013 
00014 /*********************************************************************/
00015 
00016 #include "rs274ngc.hh"
00017 #include <stdio.h>
00018 #include <stdlib.h>  /* for atof, atoi */
00019 
00020 /* note that the message must be a string with a %s in it */
00021 #define DRIVER_ERROR(message,item) if(1)    \
00022    {fprintf(stderr, message, item);         \
00023     fprintf(stderr, "\n");                  \
00024     return RS274NGC_ERROR; }                \
00025    else
00026 
00027 extern setup _interpreter_settings;
00028 extern FILE* _interpreter_fp;
00029 extern char  _interpreter_linetext[];
00030 extern char  _interpreter_blocktext[];
00031 
00032 /*********************************************************************/
00033 
00034 /* strip_terminal_newline
00035 
00036 Returned Value: char ptr to string passed
00037 
00038 Side effects: destructively replaces terminal newline, if any, with null
00039 
00040 Called by: read_keyboard_line(), main()
00041 
00042 This takes the terminal newline, if any, off the string passed. It
00043 effectively makes fgets() behave like gets(), which is what the calls
00044 to fgets() used to be before we changed them due to problems with gets()
00045 potentially running past the end of the destination string.
00046 
00047 */
00048 
00049 static char * strip_terminal_newline(char *string)
00050 {
00051   int index = strlen(string) - 1;
00052 
00053   while (index >= 0) {
00054     if (string[index] == '\n' ||
00055         string[index] == '\r') {
00056       string[index] = 0;
00057     }
00058     index--;
00059   }
00060 
00061   return string;
00062 }
00063 
00064 /*********************************************************************/
00065 
00066 /* close_and_down
00067 
00068 Returned Value: int (RS274NGC_OK or RS274NGC_ERROR)
00069    If one of the following errors occurs, this returns RS274NGC_ERROR
00070    Otherwise, it returns RS274NGC_OK.
00071    1. A left parenthesis is found inside a comment.
00072    2. The line ends before an open comment is closed
00073    3. A newline character is found that is not followed by null
00074    4. The input line was too long
00075 
00076 Side effects:
00077    see below.
00078 
00079 Called by:
00080    read_keyboard_line
00081 
00082 To simplify handling upper case letters, spaces, and tabs, this
00083 function removes spaces and and tabs and downcases everything on a
00084 line which is not part of a comment.
00085 
00086 Comments are left unchanged in place. Comments are anything
00087 enclosed in parentheses. Nested comments, indicated by a left
00088 parenthesis inside a comment, are illegal.
00089 
00090 The line must have a null character at the end when it comes in.
00091 The line may have one newline character just before the end. If
00092 there is a newline, it will be removed.
00093 
00094 Although this software system detects and rejects all illegal characters
00095 and illegal syntax, this particular function does not detect problems
00096 with anything but comments.
00097 
00098 We are treating RS274 code here as case-insensitive and spaces and
00099 tabs as if they have no meaning. RS274D, page 6 says spaces and tabs
00100 are to be ignored by control.
00101 
00102 The manual [NCMS] says nothing about case or spaces and tabs.
00103 
00104 */
00105 
00106 int close_and_down( /* ARGUMENT VALUES             */
00107  char * line)       /* string: one line of NC code */
00108 {
00109   int m;
00110   int n;
00111   int comment;
00112   char item;
00113   comment SET_TO 0;
00114   for (n SET_TO 0, m SET_TO 0; (item SET_TO line[m]) ISNT (char) NULL; m++)
00115     {
00116       if (comment)
00117         {
00118           line[n++] SET_TO item;
00119           if (item IS ')')
00120             {
00121               comment SET_TO 0;
00122             }
00123           else if (item IS '(')
00124             DRIVER_ERROR("Nested comment found%s", "");
00125         }
00126       else if ((item IS ' ') OR (item IS '\t') OR (item IS '\r'));
00127                                       /* don't copy blank or tab  or CR */
00128       else if (item IS '\n')          /* don't copy newline             */
00129         {                             /* but check null follows         */
00130           if (line[m+1] ISNT 0)
00131             DRIVER_ERROR("Null missing after newline%s", "");
00132         }
00133       else if ((64 < item) AND (item < 91)) /* downcase upper case letters */
00134         {
00135           line[n++] SET_TO (32 + item);
00136         }
00137       else if (item IS '(')   /* comment is starting */
00138         {
00139           comment SET_TO 1;
00140           line[n++] SET_TO item;
00141         }
00142       else
00143         {
00144           line[n++] SET_TO item; /* copy anything else */
00145         }
00146     }
00147   if (m IS (INTERP_TEXT_SIZE - 1)) /* line was too long */
00148     DRIVER_ERROR("Command too long%s", "");
00149   else if (comment)
00150     DRIVER_ERROR("Unclosed comment found%s", "");
00151   line[n] SET_TO 0;
00152   return RS274NGC_OK;
00153 }
00154 
00155 /****************************************************************************/
00156 
00157 /* read_keyboard_line
00158 
00159 Returned Value: int - (RS274NGC_OK or RS274NGC_ERROR)
00160    If gets or close_and_downcase returns RS274NGC_ERROR,
00161    this returns RS274NGC_ERROR. Otherwise, it returns RS274NGC_OK.
00162 
00163 Side effects:
00164    The value of the length argument is set to the number of
00165    characters on the reduced line. The line is written into.
00166 
00167 Called by: interpret_from_keyboard
00168 
00169 This calls fgets to read one line of RS274 code and calls
00170 close_and_downcase to downcase and remove spaces from everything that
00171 is not part of a comment. The newline character is removed from the
00172 end of the line by strip_terminal_newline().
00173 
00174 */
00175 
00176 int read_keyboard_line( /* ARGUMENT VALUES                 */
00177  char * raw_line,       /* array to write into             */
00178  char * line,           /* array in which to process text  */
00179  int * length)          /* pointer to an integer to be set */
00180 {
00181   char * returned_value;
00182 
00183   returned_value SET_TO fgets(raw_line, INTERP_TEXT_SIZE, stdin);
00184   strip_terminal_newline(raw_line);
00185   if (returned_value IS NULL)
00186     DRIVER_ERROR("fgets failed%s", "");
00187   strcpy(line, raw_line);
00188   if (close_and_down(line) IS RS274NGC_ERROR)
00189     return RS274NGC_ERROR;
00190   *length SET_TO strlen(line);
00191   return RS274NGC_OK;
00192 }
00193 
00194 /****************************************************************************/
00195 
00196 /* read_setup_file
00197 
00198 Returned Value: (RS274NGC_OK or RS274NGC_ERROR)
00199   If any of the following errors occur, this returns RS274NGC_ERROR.
00200   Otherwise, it returns RS274NGC_OK.
00201   1. The file named by the user cannot be opened.
00202   2. No blank line is found.
00203   3. A line of data cannot be read.
00204   4. An illegal value is given for any attribute.
00205   5. An unknown attribute name has been used.
00206 
00207 Side Effects:
00208   Values of machine settings are changed, as specified in the file.
00209 
00210 Called By:
00211   interpret_from_file
00212   interpret_from_keyboard
00213 
00214 Setup File Format
00215 -----------------
00216 
00217 Everything above the first blank line in a setup file is read and
00218 ignored, so any sort of header material may be used. The blank
00219 line should have nothing on it (spaces or tabs may not be used).
00220 
00221 Everything after the first blank line should be data. Each line of
00222 data should have the name of an attribute followed by its value,
00223 with white space in between. For example:
00224 
00225 current_x   3.0
00226 
00227 The value may be followed by white space and then comments. For example:
00228 
00229 current_x   3.0   X is set to three.
00230 
00231 Only certain attribute names are recognized. The use of an unknown
00232 attribute name will cause an error.
00233 
00234 */
00235 
00236 int read_setup_file(     /* ARGUMENT VALUES             */
00237  char * setup_file,      /* name of setup file          */
00238  setup_pointer settings) /* pointer to machine settings */
00239 {
00240   static char name[] SET_TO "read_setup_file";
00241   FILE * setup_file_port;
00242   char buffer[1000];
00243   char attribute[100];
00244   char value[100];
00245 
00246   setup_file_port SET_TO fopen(setup_file, "r");
00247   if (setup_file_port IS NULL)
00248     DRIVER_ERROR("Cannot open %s", setup_file);
00249   for(;;)    /* read and discard header, checking for blank line */
00250     {
00251       if (fgets(buffer, 1000, setup_file_port) IS NULL)
00252         DRIVER_ERROR("Bad %s file format", "setup");
00253       else if (buffer[0] IS '\n')
00254         break;
00255     }
00256 
00257   for (;;)
00258     {
00259       if (fgets(buffer, 1000, setup_file_port) IS NULL)
00260         break;
00261       if (sscanf(buffer, "%s%s", attribute, value) IS 0)
00262         DRIVER_ERROR("Bad input line \"%s\" in setup file", buffer);
00263       if (strcmp(attribute, "block_delete") IS 0)
00264         {
00265           if (strcmp(value, "ON") IS 0)
00266             settings->block_delete SET_TO ON;
00267           else if (strcmp(value, "OFF") IS 0)
00268             settings->block_delete SET_TO OFF;
00269           else
00270             DRIVER_ERROR("Bad value %s for block_delete in setup file", value);
00271         }
00272       else if (strcmp(attribute, "current_x") IS 0)
00273         settings->current_x SET_TO atof(value);
00274       else if (strcmp(attribute, "current_y") IS 0)
00275         settings->current_y SET_TO atof(value);
00276       else if (strcmp(attribute, "current_z") IS 0)
00277         settings->current_z SET_TO atof(value);
00278       else if (strcmp(attribute, "cutter_radius_comp") IS 0)
00279         {
00280           if (strcmp(value, "OFF") IS 0)
00281             settings->cutter_radius_compensation SET_TO OFF;
00282           else if (strcmp(value, "LEFT") IS 0)
00283             settings->cutter_radius_compensation SET_TO LEFT;
00284           else if (strcmp(value, "RIGHT") IS 0)
00285             settings->cutter_radius_compensation SET_TO RIGHT;
00286           else
00287             DRIVER_ERROR("Bad value %s for cutter_radius_comp in setup file",
00288                          value);
00289         }
00290       else if (strcmp(attribute, "cycle_i") IS 0)
00291         settings->cycle_i SET_TO atof(value);
00292       else if (strcmp(attribute, "cycle_j") IS 0)
00293         settings->cycle_j SET_TO atof(value);
00294       else if (strcmp(attribute, "cycle_k") IS 0)
00295         settings->cycle_k SET_TO atof(value);
00296       else if (strcmp(attribute, "cycle_l") IS 0)
00297         settings->cycle_l SET_TO atoi(value);
00298       else if (strcmp(attribute, "cycle_p") IS 0)
00299         settings->cycle_p SET_TO atof(value);
00300       else if (strcmp(attribute, "cycle_q") IS 0)
00301         settings->cycle_q SET_TO atof(value);
00302       else if (strcmp(attribute, "cycle_r") IS 0)
00303         settings->cycle_r SET_TO atof(value);
00304       else if (strcmp(attribute, "cycle_z") IS 0)
00305         settings->cycle_z SET_TO atof(value);
00306       else if (strcmp(attribute, "distance_mode") IS 0)
00307         {
00308           if (strcmp(value, "ABSOLUTE") IS 0)
00309             settings->distance_mode SET_TO MODE_ABSOLUTE;
00310           else if (strcmp(value, "INCREMENTAL") IS 0)
00311             settings->distance_mode SET_TO MODE_INCREMENTAL;
00312           else
00313             DRIVER_ERROR("Bad value %s for distance_mode in setup file",
00314                          value);
00315         }
00316       else if (strcmp(attribute, "feed_mode") IS 0)
00317         {
00318           if (strcmp(value, "PER_MINUTE") IS 0)
00319             settings->feed_mode SET_TO UNITS_PER_MINUTE;
00320           else if (strcmp(value, "INVERSE_TIME") IS 0)
00321             settings->feed_mode SET_TO INVERSE_TIME;
00322           else
00323             DRIVER_ERROR("Bad value %s for feed_mode in setup file", value);
00324         }
00325       else if (strcmp(attribute, "feed_rate") IS 0)
00326         settings->feed_rate SET_TO atof(value);
00327       else if (strcmp(attribute, "flood") IS 0)
00328         {
00329           if (strcmp(value, "OFF") IS 0)
00330             settings->flood SET_TO OFF;
00331           else if (strcmp(value, "ON") IS 0)
00332             settings->flood SET_TO ON;
00333           else
00334             DRIVER_ERROR("Bad value %s for flood in setup file", value);
00335         }
00336       else if (strcmp(attribute, "length_units") IS 0)
00337         {
00338           if (strcmp(value, "MILLIMETERS") IS 0)
00339             settings->length_units SET_TO CANON_UNITS_MM;
00340           else if (strcmp(value, "INCHES") IS 0)
00341             settings->length_units SET_TO CANON_UNITS_INCHES;
00342           else
00343             DRIVER_ERROR("Bad value %s for length_units in setup file", value);
00344         }
00345       else if (strcmp(attribute, "mist") IS 0)
00346         {
00347           if (strcmp(value, "OFF") IS 0)
00348             settings->mist SET_TO OFF;
00349           else if (strcmp(value, "ON") IS 0)
00350             settings->mist SET_TO ON;
00351           else
00352             DRIVER_ERROR("Bad value %s for mist in setup file", value);
00353         }
00354       else if (strcmp(attribute, "motion_mode") IS 0)
00355         settings->motion_mode SET_TO atoi(value);
00356       else if (strcmp(attribute, "plane") IS 0)
00357         {
00358           if (strcmp(value, "XY") IS 0)
00359             settings->plane SET_TO CANON_PLANE_XY;
00360           else if (strcmp(value, "YZ") IS 0)
00361             settings->plane SET_TO CANON_PLANE_YZ;
00362           else if (strcmp(value, "XZ") IS 0)
00363             settings->plane SET_TO CANON_PLANE_XZ;
00364           else
00365             DRIVER_ERROR("Bad value %s for plane in setup file", value);
00366         }
00367       else if (strcmp(attribute, "axis_offset_x") IS 0)
00368         settings->axis_offset_x SET_TO atof(value);
00369       else if (strcmp(attribute, "axis_offset_y") IS 0)
00370         settings->axis_offset_y SET_TO atof(value);
00371       else if (strcmp(attribute, "axis_offset_z") IS 0)
00372         settings->axis_offset_z SET_TO atof(value);
00373       else if (strcmp(attribute, "origin_offset_x") IS 0)
00374         settings->origin_offset_x SET_TO atof(value);
00375       else if (strcmp(attribute, "origin_offset_y") IS 0)
00376         settings->origin_offset_y SET_TO atof(value);
00377       else if (strcmp(attribute, "origin_offset_z") IS 0)
00378         settings->origin_offset_z SET_TO atof(value);
00379       else if (strcmp(attribute, "slot_for_length_offset") IS 0)
00380         settings->length_offset_index SET_TO atoi(value);
00381       else if (strcmp(attribute, "slot_for_radius_comp") IS 0)
00382         settings->tool_table_index SET_TO atoi(value);
00383       else if (strcmp(attribute, "slot_in_use") IS 0)
00384         settings->current_slot SET_TO atoi(value);
00385       else if (strcmp(attribute, "slot_selected") IS 0)
00386         settings->selected_tool_slot SET_TO atoi(value);
00387       else if (strcmp(attribute, "spindle_speed") IS 0)
00388         settings->speed SET_TO atof(value);
00389       else if (strcmp(attribute, "speed_feed_mode") IS 0)
00390         {
00391           if (strcmp(value, "INDEPENDENT") IS 0)
00392             settings->speed_feed_mode SET_TO CANON_INDEPENDENT;
00393           else if (strcmp(value, "SYNCHED") IS 0)
00394             settings->speed_feed_mode SET_TO CANON_SYNCHED;
00395           else
00396             DRIVER_ERROR("Bad value %s for speed_feed_mode in setup file",
00397                          value);
00398         }
00399       else if (strcmp(attribute, "spindle_turning") IS 0)
00400         {
00401           if (strcmp(value, "STOPPED") IS 0)
00402             settings->spindle_turning SET_TO CANON_STOPPED;
00403           else if (strcmp(value, "CLOCKWISE") IS 0)
00404             settings->spindle_turning SET_TO CANON_CLOCKWISE;
00405           else if (strcmp(value, "COUNTERCLOCKWISE") IS 0)
00406             settings->spindle_turning SET_TO CANON_COUNTERCLOCKWISE;
00407           else
00408             DRIVER_ERROR("Bad value %s for spindle_turning in setup file",
00409                       value);
00410         }
00411       else if (strcmp(attribute, "tool_length_offset") IS 0)
00412         settings->tool_length_offset SET_TO atof(value);
00413       else if (strcmp(attribute, "traverse_rate") IS 0)
00414         settings->traverse_rate SET_TO atof(value);
00415       else
00416         DRIVER_ERROR("Unknown attribute %s in setup file", attribute);
00417     }
00418   fclose(setup_file_port);
00419   return RS274NGC_OK;
00420 }
00421 
00422 /***********************************************************************/
00423 
00424 /* read_tool_file
00425 
00426 Returned Value: (RS274NGC_OK or RS274NGC_ERROR)
00427   If any of the following errors occur, this returns RS274NGC_ERROR.
00428   Otherwise, it returns RS274NGC_OK.
00429   1. The file named by the user cannot be opened.
00430   2. No blank line is found.
00431   3. A line of data cannot be read.
00432 
00433 Side Effects:
00434   Values in the tool table of the machine setup are changed,
00435   as specified in the file.
00436 
00437 Called By:
00438   interpret_from_file
00439   interpret_from_keyboard
00440 
00441 Tool File Format
00442 -----------------
00443 Everything above the first blank line is read and ignored, so any sort
00444 of header material may be used.
00445 
00446 Everything after the first blank line should be data. Each line of
00447 data should have four or more items separated by white space. The four
00448 required items are slot, tool id, tool length offset, and tool diameter.
00449 Other items might be the holder id and tool description, but these are
00450 optional and will not be read. Here is a sample line:
00451 
00452 20  1419  4.299  1.0  0        1 inch carbide end mill
00453 
00454 The tool_table is indexed by slot number. Index number 0 is not a
00455 valid slot number.
00456 
00457 */
00458 
00459 int read_tool_file(      /* ARGUMENT VALUES             */
00460  char * tool_file,       /* name of tool file           */
00461  setup_pointer settings) /* pointer to machine settings */
00462 {
00463   FILE * tool_file_port;
00464   int slot;
00465   int tool_id;
00466   double offset;
00467   double diameter;
00468   char buffer[1000];
00469 
00470   tool_file_port SET_TO fopen(tool_file, "r");
00471   if (tool_file_port IS NULL)
00472     DRIVER_ERROR("Cannot open %s", tool_file);
00473   for(;;)    /* read and discard header, checking for blank line */
00474     {
00475       if (fgets(buffer, 1000, tool_file_port) IS NULL)
00476         DRIVER_ERROR("Bad %s file format", "tool");
00477       else if (buffer[0] IS '\n')
00478         break;
00479     }
00480 
00481   for (;;)
00482     {
00483       if (fgets(buffer, 1000, tool_file_port) IS NULL)
00484         break;
00485       if (sscanf(buffer, "%d %d %lf %lf", &slot,
00486                  &tool_id, &offset, &diameter) IS 0)
00487         DRIVER_ERROR("Bad input line \"%s\" in tool file", buffer);
00488       settings->tool_table[slot].id SET_TO tool_id;
00489       settings->tool_table[slot].length SET_TO offset;
00490       settings->tool_table[slot].diameter SET_TO diameter;
00491     }
00492   fclose(tool_file_port);
00493   return RS274NGC_OK;
00494 }
00495 
00496 /*********************************************************************/
00497 
00498 /* interpret_from_file
00499 
00500 Returned Value: (RS274NGC_OK or RS274NGC_ERROR)
00501   If the end of the file has been reached without an m2 or m30
00502   having been read, this returns ENDFILE.
00503   Otherwise, if any of the following errors occur, this returns RS274NGC_ERROR.
00504    Otherwise, it returns RS274NGC_OK.
00505    1. rs274ngc_init returns RS274NGC_ERROR.
00506    2. read_tool_file returns RS274NGC_ERROR.
00507    3. read_setup_file returns RS274NGC_ERROR.
00508    4. rs274ngc_open returns RS274NGC_ERROR.
00509    5. rs274ngc_read returns RS274NGC_ERROR and no_stop is off.
00510    6. rs274ngc_execute returns RS274NGC_ERROR and no_stop is off.
00511    7. fgets is called and returns NULL.
00512 
00513 Side Effects:
00514    An NC-program file is opened, interpreted, and closed.
00515 
00516 Called By:
00517    main
00518 
00519 This emulates the way the EMC system uses the interpreter.
00520 
00521 When this function starts, it prompts the user for the name of a
00522 tool file and then the name of a setup file.  The user may enter a
00523 file name followed by a carriage return or just enter a carriage
00524 return after both prompts. If a file name is entered, the file will be
00525 used. If not, default tool or setup information will be used.
00526 
00527 If the no_stop argument is OFF, this returns if an error is found.
00528 
00529 If the no_stop argument is ON, an error does not stop interpretation.
00530 However, since the file will have been closed, it has to be reopened
00531 and reread up to the next unread line.
00532 
00533 An alternate method of getting back to the right place in a file
00534 would be to use fgetpos and fsetpos.
00535 
00536 */
00537 
00538 int interpret_from_file( /* ARGUMENT VALUES                   */
00539  char * filename,        /* string: name of the rs274kt file  */
00540  char * tool_file,       /* name of tool file                 */
00541  char * setup_file,      /* name of setup file                */
00542  int no_stop)            /* switch which is ON or OFF         */
00543 {
00544   int status;
00545   int reads;
00546   int k;
00547   char trash[INTERP_TEXT_SIZE];
00548   char * read_ok;
00549   int program_status;
00550 
00551   program_status SET_TO RS274NGC_OK;
00552   if (rs274ngc_init() IS RS274NGC_ERROR)
00553     return RS274NGC_ERROR;
00554   if (tool_file[0] ISNT 0)
00555     if (read_tool_file(tool_file, &_interpreter_settings) IS RS274NGC_ERROR)
00556       return RS274NGC_ERROR;
00557   if (setup_file[0] ISNT 0)
00558     if (read_setup_file(setup_file, &_interpreter_settings) IS RS274NGC_ERROR)
00559       return RS274NGC_ERROR;
00560   if (rs274ngc_open(filename) ISNT RS274NGC_OK)
00561     return RS274NGC_ERROR;
00562   for(reads SET_TO 0; ; reads++)
00563     {
00564       status SET_TO rs274ngc_read();
00565       if (status IS RS274NGC_ENDFILE)
00566         return RS274NGC_ENDFILE;
00567       if (status ISNT RS274NGC_OK)
00568         {         /* should not be RS274NGC_EXIT or RS274NGC_ERROR */
00569           fprintf(stderr, "%s\n", _interpreter_linetext);
00570           if (no_stop IS OFF)
00571             return RS274NGC_ERROR;
00572           else
00573             {
00574               program_status SET_TO RS274NGC_ERROR;
00575               rs274ngc_open(filename);       /* will have been closed    */
00576               for(k SET_TO -1; k < reads; k++) /* read up to where we were */
00577                 {
00578                   read_ok SET_TO
00579                     fgets(trash, INTERP_TEXT_SIZE, _interpreter_fp);
00580                   if (read_ok IS NULL)
00581                     return RS274NGC_ERROR;
00582                 }
00583               continue;
00584             }
00585         }
00586       status SET_TO rs274ngc_execute(NULL);
00587       if (status IS RS274NGC_ERROR)
00588         {
00589           fprintf(stderr, "%s\n", _interpreter_linetext);
00590           if (no_stop IS OFF)
00591             return RS274NGC_ERROR;
00592           else
00593             {
00594               program_status SET_TO RS274NGC_ERROR;
00595               rs274ngc_open(filename); /* will have been closed */
00596               for(k SET_TO -1; k < reads; k++) /* read up to where we were */
00597                 {
00598                   read_ok SET_TO
00599                     fgets(trash, INTERP_TEXT_SIZE, _interpreter_fp);
00600                   if (read_ok IS NULL)
00601                     return RS274NGC_ERROR;
00602                 }
00603               continue;
00604             }
00605         }
00606       else if (status IS RS274NGC_EXIT)
00607         return program_status;
00608     }
00609 }
00610 
00611 /***********************************************************************/
00612 
00613 /* interpret_from_keyboard
00614 
00615 Returned Value: int (RS274NGC_OK or RS274NGC_ERROR)
00616    If any of the following errors occur, this returns RS274NGC_ERROR.
00617    Otherwise, it returns RS274NGC_OK.
00618    1. rs274ngc_init returns RS274NGC_ERROR.
00619    2. read_tool_file returns RS274NGC_ERROR.
00620    3. read_setup_file returns RS274NGC_ERROR.
00621 
00622 Side effects:
00623   Lines of NC code entered by the user are interpreted.
00624 
00625 Called by:
00626   main
00627 
00628 When this function starts, it prompts the user for the name of a
00629 tool file and then the name of a setup file.  The user may enter a
00630 file name followed by a carriage return or just enter a carriage
00631 return after both prompts. If a file name is entered, the file will be
00632 used. If not, default tool or setup information will be used.
00633 
00634 This then prompts the user to enter a line of rs274 code, If the
00635 line is blank or the first printing character on the line is a slash,
00636 the user is prompted to enter another line. If the line cannot be
00637 parsed, an error message is sent and the user is prompted to enter
00638 another line.
00639 
00640 If the line is parsed without error, the user is prompted to enter
00641 a signal that the user wants the line to be executed (which is a
00642 semicolon followed by a carriage return). If this signal is given,
00643 the line is executed. If anything else is entered (followed by a
00644 carriage return), the line is not executed. Then the user is prompted
00645 to enter another line.
00646 
00647 To exit, the user must enter "quit" (followed by a carriage return).
00648 
00649 */
00650 
00651 int interpret_from_keyboard( /* ARGUMENT VALUES      */
00652  char * tool_file,           /* name of tool file    */
00653  char * setup_file)          /* name of setup file   */
00654 {
00655   char confirm[INTERP_TEXT_SIZE];
00656   int length;
00657   int command_ready;
00658 
00659   if (rs274ngc_init() IS RS274NGC_ERROR)
00660     return RS274NGC_ERROR;
00661   if (tool_file[0] ISNT 0)
00662     if (read_tool_file(tool_file, &_interpreter_settings) IS RS274NGC_ERROR)
00663       return RS274NGC_ERROR;
00664   if (setup_file[0] ISNT 0)
00665     if (read_setup_file(setup_file, &_interpreter_settings) IS RS274NGC_ERROR)
00666       return RS274NGC_ERROR;
00667   for(command_ready SET_TO FALSE; ; )
00668     {
00669       if (command_ready)
00670         {
00671           command_ready SET_TO FALSE;
00672           printf("EXEC <-");
00673           fgets(confirm, INTERP_TEXT_SIZE, stdin);
00674           if (confirm[0] IS ';')
00675             {
00676               rs274ngc_execute(_interpreter_blocktext);
00677               confirm[0] SET_TO 0;
00678             }
00679           else {}
00680         }
00681       else
00682         {
00683           printf("READ => ");
00684           if (read_keyboard_line(_interpreter_linetext,
00685                                  _interpreter_blocktext, &length)
00686               IS RS274NGC_ERROR);
00687           else if (strcmp (_interpreter_blocktext, "quit") IS 0)
00688             return RS274NGC_OK;
00689           else if (length > 0)
00690             {
00691               command_ready SET_TO TRUE;
00692             }
00693         }
00694     }
00695 }
00696 
00697 /************************************************************************/
00698 
00699 /* main
00700 
00701 1. If the rs274ngc stand-alone executable is called with no arguments,
00702 input is taken from the keyboard, and an error in the input does not
00703 cause the rs274ngc executable to exit.
00704 
00705 EXAMPLE:
00706 
00707 1A. To interpret from the keyboard, enter:
00708 
00709 rs274ngc
00710 
00711 ***********************************************************************
00712 
00713 2. If the executable is called with one argument, the argument is
00714 taken to be the name of an NC file and the file is interpreted. An
00715 error in the file will cause the interpreter to exit at the point of
00716 the error.  Interpreted output is printed to the computer screen
00717 unless output is redirected to an output file, in which case primitive
00718 machining function calls generated by the interpreter are printed in
00719 the output file, but error messages still appear on the screen.
00720 
00721 EXAMPLES:
00722 
00723 2A. To interpret the file "cds.ngc" and read the results on the
00724 screen, enter:
00725 
00726 rs274ngc cds.ngc
00727 
00728 2B. To interpret the file "cds.ngc" and print the results in the file
00729 "cds.prim", enter:
00730 
00731 rs274ngc cds.ngc > cds.prim
00732 
00733 ***********************************************************************
00734 
00735 3. If the executable is called with two arguments and the second
00736 argument is "continue", the first argument is taken to be the name of
00737 an NC file and the file is interpreted. An error in the file will not
00738 cause the interpreter to exit. Rather, it will continue to the end of
00739 the file. Output may be redirected as described above.
00740 
00741 EXAMPLES:
00742 
00743 3A. To interpret the file "nas.ngc" and read the results on the
00744 screen, and not be stopped by errors, enter:
00745 
00746 rs274ngc nas.ngc continue
00747 
00748 3B. To interpret the file "ncs.ngc" and print the results in the file
00749 "nas.prim", and not be stopped by errors, enter:
00750 
00751 rs274ngc nas.ngc continue > nas.prim
00752 
00753 ***********************************************************************
00754 
00755 4. Any other sort of call to the executable will cause an error message
00756 to be printed and the interpreter will not run.
00757 
00758 */
00759 
00760 int main(int argc, char ** argv)
00761 {
00762   char tool_file[200];
00763   char setup_file[200];
00764 
00765   if ((argc > 3) OR ((argc IS 3) AND (strcmp (argv[2], "continue") ISNT 0)))
00766     {
00767       fprintf(stderr, "Usage \"rs274ngc\"\n");
00768       fprintf(stderr, "   or \"rs274ngc filename\"\n");
00769       fprintf(stderr, "   or \"rs274ngc filename continue\"\n");
00770       exit(1);
00771     }
00772   fprintf(stderr, "name of tool file => ");
00773   fflush(stderr);
00774   fgets(tool_file, 200, stdin);
00775   strip_terminal_newline(tool_file);
00776   if (tool_file[0] IS 0)
00777     fprintf(stderr, "using default tool table\n");
00778 
00779   fprintf(stderr, "name of setup file => ");
00780   fflush(stderr);
00781   fgets(setup_file, 200, stdin);
00782   strip_terminal_newline(setup_file);
00783   if (setup_file[0] IS 0)
00784     fprintf(stderr, "using default machine setup\n");
00785 
00786   if (argc IS 1)
00787     exit (interpret_from_keyboard(tool_file, setup_file));
00788   else if (argc IS 2)
00789     exit (interpret_from_file( argv[1], tool_file, setup_file, OFF));
00790   else /* if (argc IS 3) */
00791     exit (interpret_from_file( argv[1], tool_file, setup_file, ON));
00792 }
00793 
00794 /***********************************************************************/

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