| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -81,6 +81,9 @@ static struct { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} pst = {0}; // initialized by all zeros
 | 
					 | 
					 | 
					 | 
					} pst = {0}; // initialized by all zeros
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// buffer for error messages
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static char ebuf[256]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// ---------------- PRIVATE PROTOTYPES ------------------
 | 
					 | 
					 | 
					 | 
					// ---------------- PRIVATE PROTOTYPES ------------------
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -184,13 +187,33 @@ uint8_t scpi_error_count(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return pst.err_queue_used; | 
					 | 
					 | 
					 | 
						return pst.err_queue_used; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void err_no_such_command() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						char *b = ebuf; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						for (int i = 0; i < pst.cur_level_i; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (i > 0) b += sprintf(b, ":"); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							b += sprintf(b, "%s", pst.cur_levels[i]); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						scpi_add_error(E_CMD_UNDEFINED_HEADER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void err_no_such_command_partial() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						char *b = ebuf; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						for (int i = 0; i < pst.cur_level_i; i++) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							b += sprintf(b, "%s:", pst.cur_levels[i]); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						scpi_add_error(E_CMD_UNDEFINED_HEADER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// ----------------- INPUT PARSING ----------------
 | 
					 | 
					 | 
					 | 
					// ----------------- INPUT PARSING ----------------
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void scpi_handle_byte(const uint8_t b) | 
					 | 
					 | 
					 | 
					void scpi_handle_byte(const uint8_t b) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// TODO handle blob here
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const char c = (char) b; | 
					 | 
					 | 
					 | 
						const char c = (char) b; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						switch (pst.state) { | 
					 | 
					 | 
					 | 
						switch (pst.state) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -203,7 +226,7 @@ void scpi_handle_byte(const uint8_t b) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (pst.charbuf_i < SCPI_MAX_CMD_LEN) { | 
					 | 
					 | 
					 | 
									if (pst.charbuf_i < SCPI_MAX_CMD_LEN) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										charbuf_append(c); | 
					 | 
					 | 
					 | 
										charbuf_append(c); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									} else { | 
					 | 
					 | 
					 | 
									} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										printf("ERROR command part too long.\n");//TODO error
 | 
					 | 
					 | 
					 | 
										scpi_add_error(E_CMD_PROGRAM_MNEMONIC_TOO_LONG, NULL); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
										pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									} | 
					 | 
					 | 
					 | 
									} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -229,7 +252,8 @@ void scpi_handle_byte(const uint8_t b) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											break; | 
					 | 
					 | 
					 | 
											break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
										default: | 
					 | 
					 | 
					 | 
										default: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											printf("ERROR unexpected char '%c' in command.\n", c);//TODO error
 | 
					 | 
					 | 
					 | 
											sprintf(ebuf, "Unexpected '%c' in command.", c); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
											scpi_add_error(E_CMD_INVALID_CHARACTER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
											pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
											pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									} | 
					 | 
					 | 
					 | 
									} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} | 
					 | 
					 | 
					 | 
								} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -253,7 +277,8 @@ void scpi_handle_byte(const uint8_t b) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pars_reset_cmd(); | 
					 | 
					 | 
					 | 
									pars_reset_cmd(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else { | 
					 | 
					 | 
					 | 
								} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR unexpected char '%c' in trailing whitespace.\n", c);//TODO error
 | 
					 | 
					 | 
					 | 
									sprintf(ebuf, "Unexpected '%c' in trailing whitespace.", c); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_INVALID_CHARACTER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} | 
					 | 
					 | 
					 | 
								} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -287,7 +312,8 @@ void scpi_handle_byte(const uint8_t b) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									// end of string
 | 
					 | 
					 | 
					 | 
									// end of string
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_ARG; // next will be newline or comma (or ignored spaces)
 | 
					 | 
					 | 
					 | 
									pst.state = PARS_ARG; // next will be newline or comma (or ignored spaces)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else if (c == '\n') { | 
					 | 
					 | 
					 | 
								} else if (c == '\n') { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR string literal not terminated.\n");//TODO error
 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_STRING_DATA_ERROR, "String not terminated (unexpected newline)."); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else { | 
					 | 
					 | 
					 | 
								} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									if (pst.string_escape) { | 
					 | 
					 | 
					 | 
									if (pst.string_escape) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -422,7 +448,7 @@ static uint8_t cmd_level_count(const SCPI_command_t *cmd) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void charbuf_append(char c) | 
					 | 
					 | 
					 | 
					static void charbuf_append(char c) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (pst.charbuf_i >= MAX_CHARBUF_LEN) { | 
					 | 
					 | 
					 | 
						if (pst.charbuf_i >= MAX_CHARBUF_LEN) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR string buffer overflow.\n");//TODO error
 | 
					 | 
					 | 
					 | 
							scpi_add_error(E_DEV_INPUT_BUFFER_OVERRUN, NULL); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -452,7 +478,8 @@ static void pars_cmd_colon(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} else { | 
					 | 
					 | 
					 | 
							} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// colon after nothing - error
 | 
					 | 
					 | 
					 | 
								// colon after nothing - error
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								printf("ERROR unexpected colon in command.\n");//TODO error
 | 
					 | 
					 | 
					 | 
								scpi_add_error(E_CMD_SYNTAX_ERROR, "Unexpected colon."); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -461,7 +488,9 @@ static void pars_cmd_colon(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (match_cmd(true)) { | 
					 | 
					 | 
					 | 
							if (match_cmd(true)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// ok
 | 
					 | 
					 | 
					 | 
								// ok
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} else { | 
					 | 
					 | 
					 | 
							} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								printf("ERROR no such command: %s\n", pst.charbuf);//TODO error
 | 
					 | 
					 | 
					 | 
								// error
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								err_no_such_command_partial(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -473,22 +502,25 @@ static void pars_cmd_semicolon(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (pst.cur_level_i == 0 && pst.charbuf_i == 0) { | 
					 | 
					 | 
					 | 
						if (pst.cur_level_i == 0 && pst.charbuf_i == 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// nothing before semicolon
 | 
					 | 
					 | 
					 | 
							// nothing before semicolon
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR semicolon not allowed here.\n");//TODO error
 | 
					 | 
					 | 
					 | 
							scpi_add_error(E_CMD_SYNTAX_ERROR, "Semicolon not preceded by command."); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pars_reset_cmd(); | 
					 | 
					 | 
					 | 
							pars_reset_cmd(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (match_cmd(false)) { | 
					 | 
					 | 
					 | 
						if (match_cmd(false)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (cmd_param_count(pst.matched_cmd) == 0) { | 
					 | 
					 | 
					 | 
							int req_cnt = cmd_param_count(pst.matched_cmd); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (req_cnt == 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// no param command - OK
 | 
					 | 
					 | 
					 | 
								// no param command - OK
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								run_command_callback(); | 
					 | 
					 | 
					 | 
								run_command_callback(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pars_reset_cmd_keeplevel(); // keep level - that's what semicolon does
 | 
					 | 
					 | 
					 | 
								pars_reset_cmd_keeplevel(); // keep level - that's what semicolon does
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} else { | 
					 | 
					 | 
					 | 
							} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								printf("ERROR command missing arguments.\n");//TODO error
 | 
					 | 
					 | 
					 | 
								sprintf(ebuf, "Required %d, got 0.", req_cnt); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								scpi_add_error(E_CMD_MISSING_PARAMETER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else { | 
					 | 
					 | 
					 | 
						} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR no such command %s.\n", pst.charbuf);//TODO error
 | 
					 | 
					 | 
					 | 
							err_no_such_command(); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -505,16 +537,22 @@ static void pars_cmd_newline(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// complete match
 | 
					 | 
					 | 
					 | 
						// complete match
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (match_cmd(false)) { | 
					 | 
					 | 
					 | 
						if (match_cmd(false)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (cmd_param_count(pst.matched_cmd) == 0) { | 
					 | 
					 | 
					 | 
							int req_cnt = cmd_param_count(pst.matched_cmd); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (req_cnt == 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// no param command - OK
 | 
					 | 
					 | 
					 | 
								// no param command - OK
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								run_command_callback(); | 
					 | 
					 | 
					 | 
								run_command_callback(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} else { | 
					 | 
					 | 
					 | 
							} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								printf("ERROR command missing arguments.\n");//TODO error
 | 
					 | 
					 | 
					 | 
								// error
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								sprintf(ebuf, "Required %d, got 0.", req_cnt); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								scpi_add_error(E_CMD_MISSING_PARAMETER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else { | 
					 | 
					 | 
					 | 
						} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR no such command %s.\n", pst.charbuf);//TODO error
 | 
					 | 
					 | 
					 | 
							err_no_such_command(); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -536,7 +574,8 @@ static void pars_cmd_space(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pst.state = PARS_ARG; | 
					 | 
					 | 
					 | 
								pst.state = PARS_ARG; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else { | 
					 | 
					 | 
					 | 
						} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR no such command: %s.\n", pst.charbuf);//TODO error
 | 
					 | 
					 | 
					 | 
							// error
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							err_no_such_command(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -701,7 +740,9 @@ static void pars_arg_char(char c) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						switch (pst.matched_cmd->params[pst.arg_i]) { | 
					 | 
					 | 
					 | 
						switch (pst.matched_cmd->params[pst.arg_i]) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							case SCPI_DT_FLOAT: | 
					 | 
					 | 
					 | 
							case SCPI_DT_FLOAT: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (!IS_FLOAT_CHAR(c)) { | 
					 | 
					 | 
					 | 
								if (!IS_FLOAT_CHAR(c)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR unexpected char '%c' in float.\n", c);//TODO error
 | 
					 | 
					 | 
					 | 
									sprintf(ebuf, "'%c' not allowed in FLOAT.", c); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_INVALID_CHARACTER_IN_NUMBER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else { | 
					 | 
					 | 
					 | 
								} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									charbuf_append(c); | 
					 | 
					 | 
					 | 
									charbuf_append(c); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -710,7 +751,9 @@ static void pars_arg_char(char c) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							case SCPI_DT_INT: | 
					 | 
					 | 
					 | 
							case SCPI_DT_INT: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (!IS_INT_CHAR(c)) { | 
					 | 
					 | 
					 | 
								if (!IS_INT_CHAR(c)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR unexpected char '%c' in int.\n", c);//TODO error
 | 
					 | 
					 | 
					 | 
									sprintf(ebuf, "'%c' not allowed in INT.", c); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_INVALID_CHARACTER_IN_NUMBER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else { | 
					 | 
					 | 
					 | 
								} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									charbuf_append(c); | 
					 | 
					 | 
					 | 
									charbuf_append(c); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -723,7 +766,7 @@ static void pars_arg_char(char c) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.string_quote = c; | 
					 | 
					 | 
					 | 
									pst.string_quote = c; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.string_escape = false; | 
					 | 
					 | 
					 | 
									pst.string_escape = false; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else { | 
					 | 
					 | 
					 | 
								} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR invalid string quote, or chars after string.\n");//TODO error
 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_INVALID_STRING_DATA, "Invalid quote, or chars after string."); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} | 
					 | 
					 | 
					 | 
								} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								break; | 
					 | 
					 | 
					 | 
								break; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -733,7 +776,7 @@ static void pars_arg_char(char c) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_ARG_BLOB_PREAMBLE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_ARG_BLOB_PREAMBLE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.blob_cnt = 0; | 
					 | 
					 | 
					 | 
									pst.blob_cnt = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else { | 
					 | 
					 | 
					 | 
								} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR unexpected char '%c', binary block should start with #\n", c);//TODO error
 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_INVALID_BLOCK_DATA, "Block data must start with #"); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} | 
					 | 
					 | 
					 | 
								} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								break; | 
					 | 
					 | 
					 | 
								break; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -750,14 +793,13 @@ static void pars_arg_comma(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (pst.arg_i == cmd_param_count(pst.matched_cmd) - 1) { | 
					 | 
					 | 
					 | 
						if (pst.arg_i == cmd_param_count(pst.matched_cmd) - 1) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// it was the last argument
 | 
					 | 
					 | 
					 | 
							// it was the last argument
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// comma illegal
 | 
					 | 
					 | 
					 | 
							scpi_add_error(E_CMD_UNEXPECTED_NUMBER_OF_PARAMETERS, "Comma after last argument."); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR unexpected comma after the last argument\n");//TODO error
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (pst.charbuf_i == 0) { | 
					 | 
					 | 
					 | 
						if (pst.charbuf_i == 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR empty argument is not allowed.\n");//TODO error
 | 
					 | 
					 | 
					 | 
							scpi_add_error(E_CMD_SYNTAX_ERROR, "Missing command before comma."); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -768,11 +810,19 @@ static void pars_arg_comma(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void pars_arg_newline(void) | 
					 | 
					 | 
					 | 
					// line ended with \n or ;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void pars_arg_eol_do(bool keep_levels) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (pst.arg_i < cmd_param_count(pst.matched_cmd) - 1) { | 
					 | 
					 | 
					 | 
						int req_cnt = cmd_param_count(pst.matched_cmd); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (pst.arg_i < req_cnt - 1) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// not the last arg yet - fail
 | 
					 | 
					 | 
					 | 
							// not the last arg yet - fail
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR not enough arguments!\n");//TODO error
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (pst.charbuf_i > 0) pst.arg_i++; // acknowledge the last arg
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							sprintf(ebuf, "Required %d, got %d.", req_cnt, pst.arg_i); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							scpi_add_error(E_CMD_MISSING_PARAMETER, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -780,23 +830,23 @@ static void pars_arg_newline(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						arg_convert_value(); | 
					 | 
					 | 
					 | 
						arg_convert_value(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						run_command_callback(); | 
					 | 
					 | 
					 | 
						run_command_callback(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						pars_reset_cmd(); // start a new command
 | 
					 | 
					 | 
					 | 
						if (keep_levels) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							pars_reset_cmd_keeplevel(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							pars_reset_cmd(); // start a new command
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void pars_arg_semicolon(void) | 
					 | 
					 | 
					 | 
					static void pars_arg_newline(void) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (pst.arg_i < cmd_param_count(pst.matched_cmd) - 1) { | 
					 | 
					 | 
					 | 
						pars_arg_eol_do(false); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							// not the last arg yet - fail
 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							printf("ERROR not enough arguments!\n");//TODO error
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						arg_convert_value(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						run_command_callback(); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						pars_reset_cmd_keeplevel(); // start a new command, keep level
 | 
					 | 
					 | 
					 | 
					static void pars_arg_semicolon(void) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						pars_arg_eol_do(true); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -819,15 +869,19 @@ static void arg_convert_value(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else if (strcasecmp(pst.charbuf, "OFF") == 0) { | 
					 | 
					 | 
					 | 
								} else if (strcasecmp(pst.charbuf, "OFF") == 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									dest->BOOL = 0; | 
					 | 
					 | 
					 | 
									dest->BOOL = 0; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else { | 
					 | 
					 | 
					 | 
								} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR argument mismatch for type BOOL\n");//TODO error
 | 
					 | 
					 | 
					 | 
									sprintf(ebuf, "Invalid BOOL value: '%s'", pst.charbuf); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_NUMERIC_DATA_ERROR, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} | 
					 | 
					 | 
					 | 
								} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								break; | 
					 | 
					 | 
					 | 
								break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							case SCPI_DT_FLOAT: | 
					 | 
					 | 
					 | 
							case SCPI_DT_FLOAT: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								j = sscanf(pst.charbuf, "%f", &dest->FLOAT); | 
					 | 
					 | 
					 | 
								j = sscanf(pst.charbuf, "%f", &dest->FLOAT); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (j == 0) { | 
					 | 
					 | 
					 | 
								if (j == 0 || pst.charbuf[0] == '\0') { //fail or empty buffer
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR failed to convert %s to FLOAT\n", pst.charbuf);//TODO error
 | 
					 | 
					 | 
					 | 
									sprintf(ebuf, "Invalid FLOAT value: '%s'", pst.charbuf); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_NUMERIC_DATA_ERROR, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} | 
					 | 
					 | 
					 | 
								} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								break; | 
					 | 
					 | 
					 | 
								break; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -835,15 +889,18 @@ static void arg_convert_value(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							case SCPI_DT_INT: | 
					 | 
					 | 
					 | 
							case SCPI_DT_INT: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								j = sscanf(pst.charbuf, "%d", &dest->INT); | 
					 | 
					 | 
					 | 
								j = sscanf(pst.charbuf, "%d", &dest->INT); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (j == 0) { | 
					 | 
					 | 
					 | 
								if (j == 0 || pst.charbuf[0] == '\0') { //fail or empty buffer
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR failed to convert %s to INT\n", pst.charbuf);//TODO error
 | 
					 | 
					 | 
					 | 
									sprintf(ebuf, "Invalid INT value: '%s'", pst.charbuf); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_NUMERIC_DATA_ERROR, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} | 
					 | 
					 | 
					 | 
								} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								break; | 
					 | 
					 | 
					 | 
								break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							case SCPI_DT_STRING: | 
					 | 
					 | 
					 | 
							case SCPI_DT_STRING: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								if (strlen(pst.charbuf) > SCPI_MAX_STRING_LEN) { | 
					 | 
					 | 
					 | 
								if (strlen(pst.charbuf) > SCPI_MAX_STRING_LEN) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									printf("ERROR string too long.\n");//TODO error
 | 
					 | 
					 | 
					 | 
									scpi_add_error(E_CMD_INVALID_STRING_DATA, "String too long."); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
									pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								} else { | 
					 | 
					 | 
					 | 
								} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									strcpy(dest->STRING, pst.charbuf); // copy the string
 | 
					 | 
					 | 
					 | 
									strcpy(dest->STRING, pst.charbuf); // copy the string
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -853,7 +910,7 @@ static void arg_convert_value(void) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							default: | 
					 | 
					 | 
					 | 
							default: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								// impossible
 | 
					 | 
					 | 
					 | 
								// impossible
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								printf("ERROR unexpected data type\n");//TODO error
 | 
					 | 
					 | 
					 | 
								scpi_add_error(E_DEV_SYSTEM_ERROR, "Unexpected argument data type."); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -866,21 +923,26 @@ static void pars_blob_preamble_char(uint8_t c) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (pst.blob_cnt == 0) { | 
					 | 
					 | 
					 | 
						if (pst.blob_cnt == 0) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (!INRANGE(c, '1', '9')) { | 
					 | 
					 | 
					 | 
							if (!INRANGE(c, '1', '9')) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								printf("ERROR expected ASCII 1-9 after #\n");//TODO error
 | 
					 | 
					 | 
					 | 
								sprintf(ebuf, "Unexpected '%c' in binary data preamble.", c); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE;// not enough to remove the blob containing \n
 | 
					 | 
					 | 
					 | 
								scpi_add_error(E_CMD_BLOCK_DATA_ERROR, ebuf); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE;// (but not enough to remove the blob containing \n)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return; | 
					 | 
					 | 
					 | 
								return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							pst.blob_cnt = c - '0'; // 1-9
 | 
					 | 
					 | 
					 | 
							pst.blob_cnt = c - '0'; // 1-9
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else { | 
					 | 
					 | 
					 | 
						} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (c == '\n') { | 
					 | 
					 | 
					 | 
							if (c == '\n') { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								printf("ERROR unexpected newline in blob preamble\n");//TODO error
 | 
					 | 
					 | 
					 | 
								scpi_add_error(E_CMD_BLOCK_DATA_ERROR, "Unexpected newline in binary data preamble."); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
					 | 
					 | 
					 | 
								pars_reset_cmd(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return; | 
					 | 
					 | 
					 | 
								return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (!IS_NUMBER_CHAR(c)) { | 
					 | 
					 | 
					 | 
							if (!IS_NUMBER_CHAR(c)) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								printf("ERROR expected ASCII 0-9 after #n\n");//TODO error
 | 
					 | 
					 | 
					 | 
								sprintf(ebuf, "Unexpected '%c' in binary data preamble.", c); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								scpi_add_error(E_CMD_BLOCK_DATA_ERROR, ebuf); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE; | 
					 | 
					 | 
					 | 
								pst.state = PARS_DISCARD_LINE; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								return; | 
					 | 
					 | 
					 | 
								return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |