/ src / emc / nml_intf / interpl.cc
interpl.cc
  1  /********************************************************************
  2  * Description: interpl.cc
  3  *   Mechanism for queueing NML messages, used by the interpreter and
  4  *   canonical interface to report list of NML statements from program
  5  *   files to HME.
  6  *
  7  *   Derived from a work by Fred Proctor & Will Shackleford
  8  *
  9  * Author:
 10  * License: GPL Version 2
 11  * System: Linux
 12  *    
 13  * Copyright (c) 2004 All rights reserved.
 14  *
 15  * Last change:
 16  ********************************************************************/
 17  
 18  
 19  #include <string.h>		/* memcpy() */
 20  
 21  #include "rcs.hh"		// LinkedList
 22  #include "interpl.hh"		// these decls
 23  #include "emc.hh"
 24  #include "emcglb.h"
 25  #include "linklist.hh"
 26  #include "nmlmsg.hh"            /* class NMLmsg */
 27  #include "rcs_print.hh"
 28  
 29  NML_INTERP_LIST interp_list;	/* NML Union, for interpreter */
 30  
 31  NML_INTERP_LIST::NML_INTERP_LIST()
 32  {
 33      linked_list_ptr = new LinkedList;
 34  
 35      next_line_number = 0;
 36      line_number = 0;
 37  }
 38  
 39  NML_INTERP_LIST::~NML_INTERP_LIST()
 40  {
 41      if (NULL != linked_list_ptr) {
 42  	delete linked_list_ptr;
 43  	linked_list_ptr = NULL;
 44      }
 45  }
 46  
 47  int NML_INTERP_LIST::append(NMLmsg & nml_msg)
 48  {
 49      return append(&nml_msg);
 50  }
 51  
 52  // sets the line number used for subsequent appends
 53  int NML_INTERP_LIST::set_line_number(int line)
 54  {
 55      next_line_number = line;
 56  
 57      return 0;
 58  }
 59  
 60  int NML_INTERP_LIST::append(NMLmsg * nml_msg_ptr)
 61  {
 62      /* check for invalid data */
 63      if (NULL == nml_msg_ptr) {
 64  	rcs_print_error
 65  	    ("NML_INTERP_LIST::append : attempt to append NULL msg\n");
 66  	return -1;
 67      }
 68  
 69      if (0 == nml_msg_ptr->type) {
 70  	rcs_print_error
 71  	    ("NML_INTERP_LIST::append : attempt to append 0 type\n");
 72  	return -1;
 73      }
 74  
 75      if (nml_msg_ptr->size > MAX_NML_COMMAND_SIZE - 64) {
 76  	rcs_print_error
 77  	    ("NML_INTERP_LIST::append : command size is too large.");
 78  	return -1;
 79      }
 80      if (nml_msg_ptr->size < 4) {
 81  	rcs_print_error
 82  	    ("NML_INTERP_LIST::append : command size is invalid.");
 83  	return -1;
 84      }
 85  #ifdef DEBUG_INTERPL
 86      if (sizeof(temp_node) < MAX_NML_COMMAND_SIZE + 4 ||
 87  	sizeof(temp_node) > MAX_NML_COMMAND_SIZE + 16 ||
 88  	((void *) &temp_node.line_number) >
 89  	((void *) &temp_node.command.commandbuf)) {
 90  	rcs_print_error
 91  	    ("NML_INTERP_LIST::append : assumptions about NML_INTERP_LIST_NODE have been violated.");
 92  	return -1;
 93      }
 94  #endif
 95  
 96      if (NULL == linked_list_ptr) {
 97  	return -1;
 98      }
 99      // fill in the NML_INTERP_LIST_NODE
100      temp_node.line_number = next_line_number;
101      memcpy(temp_node.command.commandbuf, nml_msg_ptr, nml_msg_ptr->size);
102  
103      // stick it on the list
104      linked_list_ptr->store_at_tail(&temp_node,
105  				   nml_msg_ptr->size +
106  				   sizeof(temp_node.line_number) +
107  				   sizeof(temp_node.dummy) + 32 + (32 -
108  								   nml_msg_ptr->
109  								   size %
110  								   32), 1);
111  
112      if (emc_debug & EMC_DEBUG_INTERP_LIST) {
113  	rcs_print
114  	    ("NML_INTERP_LIST(%p)::append(nml_msg_ptr{size=%ld,type=%s}) : list_size=%d, line_number=%d\n",
115               this,
116  	     nml_msg_ptr->size, emc_symbol_lookup(nml_msg_ptr->type),
117  	     linked_list_ptr->list_size, temp_node.line_number);
118      }
119  
120      return 0;
121  }
122  
123  NMLmsg *NML_INTERP_LIST::get()
124  {
125      NMLmsg *ret;
126      NML_INTERP_LIST_NODE *node_ptr;
127  
128      if (NULL == linked_list_ptr) {
129  	line_number = 0;
130  	return NULL;
131      }
132  
133      node_ptr = (NML_INTERP_LIST_NODE *) linked_list_ptr->retrieve_head();
134  
135      if (NULL == node_ptr) {
136  	line_number = 0;
137  	return NULL;
138      }
139      // save line number of this one, for use by get_line_number
140      line_number = node_ptr->line_number;
141  
142      // get it off the front
143      ret = (NMLmsg *) ((char *) node_ptr->command.commandbuf);
144  
145      if (emc_debug & EMC_DEBUG_INTERP_LIST) {
146          rcs_print(
147              "NML_INTERP_LIST(%p)::get(): {size=%ld, type=%s}, list_size=%d\n",
148              this,
149              ret->size,
150              emc_symbol_lookup(ret->type),
151              linked_list_ptr->list_size
152          );
153      }
154  
155      return ret;
156  }
157  
158  void NML_INTERP_LIST::clear()
159  {
160      if (NULL != linked_list_ptr) {
161          if (emc_debug & EMC_DEBUG_INTERP_LIST) {
162              rcs_print("NML_INTERP_LIST(%p)::clear(): discarding %d items\n", this, linked_list_ptr->list_size);
163          }
164  
165  	linked_list_ptr->delete_members();
166      }
167  }
168  
169  void NML_INTERP_LIST::print()
170  {
171      NMLmsg *ret;
172      NML_INTERP_LIST_NODE *node_ptr;
173      int line_number;
174  
175      if (NULL == linked_list_ptr) {
176  	return;
177      }
178      node_ptr = (NML_INTERP_LIST_NODE *) linked_list_ptr->get_head();
179  
180      rcs_print("NML_INTERP_LIST::print(): list size=%d\n",linked_list_ptr->list_size);
181      while (NULL != node_ptr) {
182  	line_number = node_ptr->line_number;
183  	ret = (NMLmsg *) ((char *) node_ptr->command.commandbuf);
184  	rcs_print("--> type=%s,  line_number=%d\n",
185  		  emc_symbol_lookup((int)ret->type),
186  		  line_number);
187  	node_ptr = (NML_INTERP_LIST_NODE *) linked_list_ptr->get_next();
188      }
189      rcs_print("\n");
190  }
191  
192  int NML_INTERP_LIST::len()
193  {
194      if (NULL == linked_list_ptr) {
195  	return 0;
196      }
197  
198      return ((int) linked_list_ptr->list_size);
199  }
200  
201  int NML_INTERP_LIST::get_line_number()
202  {
203      return line_number;
204  }