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 }