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

interpl.cc

Go to the documentation of this file.
00001 
00002 /*
00003   interplist.cc
00004 
00005   Mechanism for queueing NML messages, used by the interpreter and
00006   canonical interface to report list of NML statements from program
00007   files to HME.
00008 
00009   Modification history:
00010 
00011   11-Dec-2000 WPS put in some checks in NML_INTERP_LIST append to catch invalid
00012 changes to the node structure and command messages that are too big. Also modified things so that we conserve memory by not always storing 1000 bytes for every message.
00013   25-Jul-1997  FMP removed nml_emc.hh dependency, changing how line
00014   numbers are done. Now they need to be given via set_line_number instead
00015   of read by interp_wm_line(). Got rid of non-reentrant get_last()
00016   14-Nov-1996 WPS corrected the size passed to store_at_tail which caused
00017   a "Read Invalid" error from TestCenter
00018   16-Nov-1995  Fred Proctor created
00019   */
00020 
00021 extern "C" {
00022 #include <string.h>             /* memcpy() */
00023 }
00024 
00025 #include "rcs.hh"               // RCS_LINKED_LIST
00026 #include "interpl.hh"           // these decls
00027 #include "emcglb.h"
00028 
00029 NML_INTERP_LIST interp_list;    /* NML Union, for interpreter */
00030 
00031  NML_INTERP_LIST::NML_INTERP_LIST()
00032 {
00033   linked_list_ptr = new RCS_LINKED_LIST;
00034 
00035   next_line_number = 0;
00036   line_number = 0;
00037 }
00038 
00039  NML_INTERP_LIST::~NML_INTERP_LIST()
00040 {
00041   if (NULL != linked_list_ptr)
00042   {
00043     delete linked_list_ptr;
00044     linked_list_ptr = NULL;
00045   }
00046 }
00047 
00048 int NML_INTERP_LIST::append(NMLmsg &nml_msg)
00049 {
00050   /* check for invalid data */
00051   if (0 == nml_msg.type)
00052   {
00053     rcs_print_error("NML_INTERP_LIST::append : attempt to append 0 type\n");
00054     return -1;
00055   }
00056 
00057   if (NULL == linked_list_ptr)
00058   {
00059     return -1;
00060   }
00061 
00062   if(nml_msg.size > MAX_NML_COMMAND_SIZE -64)
00063     {
00064       rcs_print_error("NML_INTERP_LIST::append : command size is too large.");
00065       return -1;
00066     }
00067   if(nml_msg.size < 4 ) 
00068     {
00069       rcs_print_error("NML_INTERP_LIST::append : command size is invalid.");
00070       return -1;
00071     }
00072 #ifdef DEBUG_INTERPL
00073   if(sizeof(temp_node) < MAX_NML_COMMAND_SIZE+4 ||
00074      sizeof(temp_node) > MAX_NML_COMMAND_SIZE+16   )
00075     {
00076       rcs_print_error("NML_INTERP_LIST::append : assumptions about NML_INTERP_LIST_NODE have been violated.\n");
00077       return -1;
00078     }
00079 #endif
00080 
00081   // fill in the NML_INTERP_LIST_NODE
00082   temp_node.line_number = next_line_number;
00083   memcpy(temp_node.command.commandbuf, &nml_msg, nml_msg.size);
00084 
00085   // stick it on the list
00086   linked_list_ptr->store_at_tail(&temp_node, nml_msg.size+sizeof(temp_node.line_number)+sizeof(temp_node.dummy)+32+(32-nml_msg.size%32), 1);
00087 
00088 #ifdef DEBUG_INTERPL
00089   if(EMC_DEBUG & EMC_DEBUG_INTERP_LIST)
00090     {
00091       rcs_print("NML_INTERP_LIST::append(nml_msg{size=%d,type=%d}) : list_size=%d, line_number = %d\n",
00092                 nml_msg.size,nml_msg.type,linked_list_ptr->list_size,
00093                 temp_node.line_number);
00094     }
00095 #endif
00096 
00097   return 0;
00098 }
00099 
00100 // sets the line number used for subsequent appends
00101 int NML_INTERP_LIST::set_line_number(int line)
00102 {
00103   next_line_number = line;
00104 
00105   return 0;
00106 }
00107 
00108 int NML_INTERP_LIST::append(NMLmsg *nml_msg_ptr)
00109 {
00110   /* check for invalid data */
00111   if (NULL == nml_msg_ptr)
00112   {
00113     rcs_print_error("NML_INTERP_LIST::append : attempt to append NULL msg\n");
00114     return -1;
00115   }
00116 
00117   if (0 == nml_msg_ptr->type)
00118   {
00119     rcs_print_error("NML_INTERP_LIST::append : attempt to append 0 type\n");
00120     return -1;
00121   }
00122 
00123   if(nml_msg_ptr->size > MAX_NML_COMMAND_SIZE -64 )
00124     {
00125       rcs_print_error("NML_INTERP_LIST::append : command size is too large.");
00126       return -1;
00127     }
00128   if(nml_msg_ptr->size < 4 ) 
00129     {
00130       rcs_print_error("NML_INTERP_LIST::append : command size is invalid.");
00131       return -1;
00132     }
00133 #ifdef DEBUG_INTERPL
00134   if(sizeof(temp_node) < MAX_NML_COMMAND_SIZE+4 ||
00135      sizeof(temp_node) > MAX_NML_COMMAND_SIZE+16 ||
00136      ((void *) &temp_node.line_number) > ((void *) &temp_node.command.commandbuf))
00137     {
00138       rcs_print_error("NML_INTERP_LIST::append : assumptions about NML_INTERP_LIST_NODE have been violated.");
00139       return -1;
00140     }
00141 #endif
00142 
00143   if (NULL == linked_list_ptr)
00144   {
00145     return -1;
00146   }
00147 
00148   // fill in the NML_INTERP_LIST_NODE
00149   temp_node.line_number = next_line_number;
00150   memcpy(temp_node.command.commandbuf, nml_msg_ptr, nml_msg_ptr->size);
00151 
00152   // stick it on the list
00153   linked_list_ptr->store_at_tail(&temp_node, nml_msg_ptr->size+sizeof(temp_node.line_number)+sizeof(temp_node.dummy)+32+(32-nml_msg_ptr->size%32), 1);
00154 
00155 #ifdef DEBUG_INTERPL
00156   if(EMC_DEBUG & EMC_DEBUG_INTERP_LIST)
00157     {
00158       rcs_print("NML_INTERP_LIST::append(nml_msg{size=%d,type=%d}) : list_size=%d, line_number = %d\n",
00159                 nml_msg_ptr->size,nml_msg_ptr->type,linked_list_ptr->list_size,
00160                 temp_node.line_number);
00161     }
00162 #endif
00163 
00164   return 0;
00165 }
00166 
00167 NMLmsg * NML_INTERP_LIST::get()
00168 {
00169   NMLmsg *ret;
00170   NML_INTERP_LIST_NODE *node_ptr;
00171 
00172   if (NULL == linked_list_ptr)
00173   {
00174     line_number = 0;
00175     return NULL;
00176   }
00177 
00178   node_ptr = (NML_INTERP_LIST_NODE *) linked_list_ptr->retrieve_head();
00179 
00180   if (NULL == node_ptr)
00181   {
00182     line_number = 0;
00183     return NULL;
00184   }
00185 
00186   // save line number of this one, for use by get_line_number
00187   line_number = node_ptr->line_number;
00188 
00189   // get it off the front
00190   ret = (NMLmsg *) ((char *) node_ptr->command.commandbuf);
00191 
00192   return ret;
00193 }
00194 
00195 void NML_INTERP_LIST::clear()
00196 {
00197   if (NULL != linked_list_ptr)
00198   {
00199     linked_list_ptr->delete_members();
00200   }
00201 }
00202 
00203 void NML_INTERP_LIST::print()
00204 {
00205   NMLmsg *nml_msg;
00206 
00207   if (NULL == linked_list_ptr)
00208   {
00209     return;
00210   }
00211 
00212   nml_msg = (NMLmsg *) linked_list_ptr->get_head();
00213 
00214   while (NULL != nml_msg)
00215   {
00216     rcs_print("%d ", nml_msg->type);
00217     nml_msg = (NMLmsg *)linked_list_ptr->get_next();
00218   }
00219 
00220   rcs_print("\n");
00221 }
00222 
00223 int NML_INTERP_LIST::len()
00224 {
00225   if (NULL == linked_list_ptr)
00226   {
00227     return 0;
00228   }
00229 
00230   return ((int) linked_list_ptr->list_size);
00231 }
00232 
00233 int NML_INTERP_LIST::get_line_number()
00234 {
00235   return line_number;
00236 }

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