KiCad PCB EDA Suite
class_am_param.cpp File Reference

Go to the source code of this file.

Functions

int ReadInt (char *&text, bool aSkipSeparator=true)
 Function ReadInt reads an int from an ASCII character buffer. More...
 
double ReadDouble (char *&text, bool aSkipSeparator=true)
 Function ReadDouble reads a double from an ASCII character buffer. More...
 
double Evaluate (AM_PARAM_EVAL_STACK &aExp)
 Evaluate an basic arithmetic expression (infix notation) with precedence The expression is a sequence of numbers (double) and arith operators: operators are + - x / ( and ) the expression is stored in a std::vector each item is a AM_PARAM_EVAL (each item is an operator or a double) More...
 

Function Documentation

double Evaluate ( AM_PARAM_EVAL_STACK aExp)

Evaluate an basic arithmetic expression (infix notation) with precedence The expression is a sequence of numbers (double) and arith operators: operators are + - x / ( and ) the expression is stored in a std::vector each item is a AM_PARAM_EVAL (each item is an operator or a double)

Parameters
aExp= the arithmetic expression to evaluate
Returns
the value

Definition at line 102 of file evaluate.cpp.

References ADD, CLOSE_PAR, DIV, AM_PARAM_EVAL::GetOperator(), AM_PARAM_EVAL::GetPriority(), AM_PARAM_EVAL::GetValue(), AM_PARAM_EVAL::IsOperator(), MUL, OPEN_PAR, POPVALUE, and SUB.

Referenced by AM_PARAM::GetValue().

103 {
104  class OP_CODE // A small class to store a operator and its priority
105  {
106  public:
107  parm_item_type m_Optype;
108  int m_Priority;
109 
110  OP_CODE( AM_PARAM_EVAL& aAmPrmEval )
111  : m_Optype( aAmPrmEval.GetOperator() ),
112  m_Priority( aAmPrmEval.GetPriority() )
113  {}
114 
115  OP_CODE( parm_item_type aOptype )
116  : m_Optype( aOptype ), m_Priority( 0 )
117  {}
118  };
119 
120  double result = 0.0;
121 
122  std::vector<double> values; // the current list of values
123  std::vector<OP_CODE> optype; // the list of arith operators
124 
125  double curr_value = 0.0;
126  int extra_priority = 0;
127 
128  for( unsigned ii = 0; ii < aExp.size(); ii++ )
129  {
130  AM_PARAM_EVAL& prm = aExp[ii];
131 
132  if( prm.IsOperator() )
133  {
134  if( prm.GetOperator() == OPEN_PAR )
135  {
136  extra_priority += AM_PARAM_EVAL::GetPriority( OPEN_PAR );
137  }
138  else if( prm.GetOperator() == CLOSE_PAR )
139  {
140  extra_priority -= AM_PARAM_EVAL::GetPriority( CLOSE_PAR );
141  }
142  else
143  {
144  optype.push_back( OP_CODE( prm ) );
145  optype.back().m_Priority += extra_priority;
146  }
147  }
148  else // we have a value:
149  {
150  values.push_back( prm.GetValue() );
151 
152  if( optype.size() < 2 )
153  continue;
154 
155  OP_CODE& previous_optype = optype[optype.size() - 2];
156 
157  if( optype.back().m_Priority > previous_optype.m_Priority )
158  {
159  double op1 = 0.0;
160 
161  double op2 = values.back();
162  values.pop_back();
163 
164  if( values.size() )
165  {
166  op1 = values.back();
167  values.pop_back();
168  }
169 
170  switch( optype.back().m_Optype )
171  {
172  case ADD:
173  values.push_back( op1+op2 );
174  break;
175 
176  case SUB:
177  values.push_back( op1-op2 );
178  break;
179 
180  case MUL:
181  values.push_back( op1*op2 );
182  break;
183 
184  case DIV:
185  values.push_back( op1/op2 );
186  break;
187 
188  default:
189  break;
190  }
191 
192  optype.pop_back();
193  }
194  }
195  }
196 
197  // Now all operators have the same priority, or those having the higher priority
198  // are before others, calculate the final result by combining initial values and/or
199  // replaced values.
200  if( values.size() > optype.size() )
201  // If there are n values, the number of operator is n-1 or n if the first
202  // item of the expression to evaluate is + or - (like -$1/2)
203  // If the number of operator is n-1 the first value is just copied to result
204  optype.insert( optype.begin(), OP_CODE( POPVALUE ) );
205 
206  wxASSERT( values.size() == optype.size() );
207 
208  for( unsigned idx = 0; idx < values.size(); idx++ )
209  {
210  curr_value = values[idx];
211 
212  switch( optype[idx].m_Optype )
213  {
214  case POPVALUE:
215  result = curr_value;
216  break;
217 
218  case ADD:
219  result += curr_value;
220  break;
221 
222  case SUB:
223  result -= curr_value;
224  break;
225 
226  case MUL:
227  result *= curr_value;
228  break;
229 
230  case DIV:
231  result /= curr_value;
232  break;
233 
234  default:
235  break;
236  }
237  }
238 
239  return result;
240 }
parm_item_type GetOperator() const
int GetPriority() const
This helper class hold a value or an arithmetic operator to calculate the final value of a aperture m...
bool IsOperator() const
parm_item_type
double GetValue() const
double ReadDouble ( char *&  text,
bool  aSkipSeparator = true 
)

Function ReadDouble reads a double from an ASCII character buffer.

If there is a comma after the double, then skip over that.

Parameters
textA reference to a character pointer from which the ASCII double is read from and the pointer advanced for each character read.
aSkipSeparator= true (default) to skip comma
Returns
double

Definition at line 302 of file rs274_read_XY_and_IJ_coordinates.cpp.

Referenced by AM_PARAM::ReadParam().

303 {
304  double ret;
305 
306  // For strtod, a string starting by 0X or 0x is a valid number in hexadecimal or octal.
307  // However, 'X' is a separator in Gerber strings with numbers.
308  // We need to detect that
309  if( strncasecmp( text, "0X", 2 ) == 0 )
310  {
311  text++;
312  ret = 0.0;
313  }
314  else
315  ret = strtod( text, &text );
316 
317  if( *text == ',' || isspace( *text ) )
318  {
319  if( aSkipSeparator )
320  ++text;
321  }
322 
323  return ret;
324 }
int ReadInt ( char *&  text,
bool  aSkipSeparator = true 
)

Function ReadInt reads an int from an ASCII character buffer.

If there is a comma after the int, then skip over that.

Parameters
textA reference to a character pointer from which bytes are read and the pointer is advanced for each byte read.
aSkipSeparator= true (default) to skip comma
Returns
int - The int read in.

Definition at line 268 of file rs274_read_XY_and_IJ_coordinates.cpp.

Referenced by AM_PARAM::ReadParam().

269 {
270  int ret;
271 
272  // For strtol, a string starting by 0X or 0x is a valid number in hexadecimal or octal.
273  // However, 'X' is a separator in Gerber strings with numbers.
274  // We need to detect that
275  if( strncasecmp( text, "0X", 2 ) == 0 )
276  {
277  text++;
278  ret = 0;
279  }
280  else
281  ret = (int) strtol( text, &text, 10 );
282 
283  if( *text == ',' || isspace( *text ) )
284  {
285  if( aSkipSeparator )
286  ++text;
287  }
288 
289  return ret;
290 }