Salve.
Sto facendo una specie di shell sulla seriale, il particolare di questa shell è che non è ammissibile che ci siano tempi di wait.
Ovvero, non è possibile usare la scanf (perchè si mette in attesa del prossimo carattere).
Il codice l'ho gia fatto e funziona ottimamente, però cerco qualche consiglio per migliorarlo nella sua struttura.
Non badate tanto a come son dichiarati gli array (ed eventuali bufferoverflow) o alle routine di gestione della seriale (in realtà non sono quelle, visto che uso un microcontrollore, so che la getch() si mette in attesa, non badateci), ma piuttosto nella forma del programma, sulla sua elasticità a inserire nuovi comandi e menu.
In pratica ora come ora ogni comando è dichiarato come funzione e uso un puntatore a funzione (che si chiama "function") per gestire qual'è la prossima funzione da eseguire.
Per "comando" si intende una stringa terminata dalla pressione del tasto INVIO.
Naturalmente i comandi che vedete sono di puro esempio. echo fa l'eco della stringa passata come primo parametro, add fa la somma del 2 e terzo parametro.
Qualche altro miglioramento possibile?
Grazie.
codice:
#include <stdio.h>
#include <stdlib.h>
#define PASSWORD "test"
static char buffer[100];
static int chused;
static void (*function) (char * command);
int loop (void);
void prompt (void);
void motd (char * command);
void askpassword (char * command);
void checkpassword (char * command);
void mainmenu (char * command);
void printmainmenu (void);
void echocommand (char * command);
void mathmenu (char * command);
void printmathmenu (void);
void addition (char * command);
char readserial (void);
void clearbuffer (void);
int main(int argc, char *argv[])
{
function= motd;
for (;;)
loop();
system("PAUSE");
return 0;
}
int loop (void)
{
if (readserial() == 13) // è stato premuto INVIO, elabora comando
{
buffer[--chused] = 0; // elimino il tasto INVIO
function (buffer);
prompt ();
clearbuffer ();
}
}
void motd (char * command)
{
printf ("Interfaccia SERIAL/0 pronta. Premere INVIO per autenticarsi\n");
function = askpassword;
}
void askpassword (char * command)
{
printf ("Inserire la password: ");
function= checkpassword;
}
void checkpassword (char * command)
{
if (strcmp(command, PASSWORD) == 0)
{
printf ("PWD ok \n");
function = mainmenu;
printmainmenu();
}
else
{
printf ("PWD errata\n");
askpassword(command);
}
}
void prompt (void)
{
if (function == mainmenu)
printf ("main>");
if (function == mathmenu)
printf ("main>math>");
}
void mainmenu (char * command)
{
char s1 [100];
sscanf (command, "%s", s1);
if (strcmp(s1, "?") == 0)
printmainmenu ();
else if (strcmp(s1, "echo") == 0)
echocommand (command);
else if (strcmp (s1, "math") == 0)
{
printmathmenu();
function = mathmenu;
}
else if (strcmp (s1, "quit") == 0)
exit (0);
else
printf ("Comando non valido \n");
}
void printmainmenu (void)
{
printf ("--- MAIN MENU ---\n Comandi supportati:\n?\necho\nmath\nquit\n");
}
void echocommand (char * command)
{
char s1 [100];
char s2 [100];
sscanf (command, "%s %s", s1, s2);
printf ("%s \n", s2);
}
void mathmenu (char * command)
{
char s1 [100];
sscanf (command, "%s", s1);
if (strcmp(s1, "?") == 0)
printmathmenu ();
else if (strcmp(s1, "add") == 0)
addition (command);
else if (strcmp (s1, "back") == 0)
{
function= mainmenu;
}
else
printf ("Comando non valido \n");
}
void printmathmenu (void)
{
printf ("--- MATH MENU ---\n Comandi supportati:\n?\nadd\nback\n");
}
void addition (char * command)
{
char s1 [100], s2 [100] , s3 [100];
int a, b;
sscanf (command, "%s %s %s", s1, s2, s3);
a = atoi (s2);
b = atoi (s3);
printf ("%s + %s = %d \n", s2, s3, a+b);
}
// ROUTINE GESTIONE SERIALE //
char readserial (void)
{
char c = getch();
if (c != 8)
{
buffer[chused++]= c;
printf( "%c", c);
}
if (c==13)
printf ("%c", 10); // new-line
if (c==8) //backspace
{
printf( "%c", c);
printf ( "%c", 32);
printf ("%c", 8);
buffer[--chused]=0;
}
return c;
}
void clearbuffer (void)
{
int i;
chused = 0;
for (i=0; i<100; i++) buffer[i] = 0;
}