#ifndef __RS232PARSER_H__
#define __RS232PARSER_H__

#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>

/*
 * Questo parser assume che istruzioni RS232 (ma un procedimento simile va 
 * per il protocollo GPIB) siano costituite da un comando, seguito 
 * eventualmente da argomeni.
 * I comandi hanno una struttura gerarchica a menù, i cui livelli sono 
 * separati da ':'. Chiameremo "token" le stringhe che identificano ogni 
 * livello.
 *
 * Il protocollo è case insensitive ed è spesso possibile abbreviare comandi.
 * Un token o un argomento stringa che può avere solo valori predeterminati.
 * Per indicare le possibili abbrevazioni di un token o un argomento stringa 
 * che può avere solo valori predeterminati, il template di un comando 
 * deve essere scritto, ad esempio, come "HORIzontal".
 * Un token corrisponde a questo template se è un'abbreviazione di horizontal
 * (maiuscole o minuscole sono indifferenti) e contiene almeno 4 caratteri 
 * (quelli indicati in maiuscolo nel template).
 *
 * È inoltre possibile concatenare comandi sulla stessa linea separandoli 
 * con dei ';'. In tal caso, si suppone che il prefisso del comando precedente
 * faccia da prefisso per il successivo, a meno che questi non inizi per ':'.
 * Ad esempio 
 *   :TRIGGER:EDGE:SOURCE CH1;SLOPE RISE
 * è identico a 
 *   :TRIGGER:EDGE:SOURCE CH1;:TRIGGER:EDGE:SLOPE RISE
 */


/*
 * Confronta un comando con un template. Restituisce 1 se il comando
 * corrisponde al template, 0 altrimenti.
 */
int RS232PMatchCommand(const char* command, const char* template);


/*
 * Data una riga di comandi buffer, questa funzione estrae il primo comando
 * ed il suo argomento. 
 * Il valore di ritorno è la lunghezza del comando estratto, ovvero di quanti 
 * caratteri bisogna avanzare in buffer per incontrare il comando successivo.
 * Un valore 0 indica che non esistono più comandi in buffer.
 */
int RS232PTekExtractCommand(const char* buffer, char* command, char* argument);


/*
 * Dato un vettore di stringhe choices, di dimensione Nchoices, confronta
 * confronta la stringa selection con le possibilità offerte e restituisce
 * un intero corrispondente alla locazione della scelta selezionata nel 
 * vettore choices.
 * Se nessuna corrispondenza viene trovata, restituisce -1.
 */
int RS232PSelectString(const char* selection, char *choices[], int Nchoices);


/*
 * Restituisce 1 se l'ultimo carattere di command è un '?', 0 altrimenti.
 */
int RS232PIsQuery(const char* command);


/*
 * QUELLE CHE SEGUONO SONO FUNZIONI DI UTILITÀ CHE DIFFICILMENTE VERRANNO 
 * USATE DIRETTAMENTE.
 */


/*
 * Dato un token (parte del comando tra ':'), restituisce la posizione
 * del token successivo nel comando, o 0 se quello corrente è l'ultimo 
 * token.
 */
const char* RS232PNextToken(const char* token);


/*
 * restituisce la lunghezza minima di un abbreviazione di un token
 * (la parte indicata con le lettere maiuscole nelle nostre convenzioni).
 */
int RS232PMinTokenLength(const char* template);


/*
 * Restituisce la lunghezza della parola chiave da usare per un confronto.
 */
int RS232PTokenLength(const char* keyword);

#endif
