Qd se faz um programa que compara a entrada padrao (ou parte dela) com varios comandos/funcoes
é comum pensar primeiro em if e logo em seguida em case.
Mas isso alem de ser ‘feio’ e complicar a leitura/compreensao do codigo, torna dificil sua manutencao.
Para isso existe o conceito de handler de funcoes, onde se cria uma estrutura com 2 campos:
o nome da funcao que sera utilizado para fazer o match com o comando (o nome do comando deve ser o mesmo que o comando informado), e um campo void que é um ponteiro para a funcao propriamente dita:
1
2
3
4
5
6
7
8
| typedef struct {
char *name;
void (*func)(char *what, char *which, int connfd);
} handler_t;
const handler_t handlers[] = {
{"add","add"}, {NULL}
}; |
crei um estrutura (handler_t) com o campo ‘name’, e o campo ‘(*func)’ o
‘(char *what, char *which, int connfd);’ sao os argumentos da funcao, claro q vc deve alterar para as suas necessidades.
logo em seguida eu defini um vetor do tipo ‘handler_t’ (minha estrutura) que contem um unico comando dentro:
add. Neste caso coloquei o name com o mesmo nome da funcao, isso pq claro, a funcao tem nome ‘add’.
agora pra fazer o match eh o mais simples:
1
2
3
4
5
| for(i=0; handlers[i].name != NULL; i++)
{
if(strcmp(handlers[i].name, cline.cmd) >= 0)
handlers[i].func(cline.what, cline.which);
} |
Ou seja, ele cai na iteracao, e enquanto o campo ‘name’ nao for NULL, ele vai andando pelo vetor, e comparando o que encontra dentro do campo ‘name’ com o cline.cmd (outra estrutura que é alimentada por outra parte do codigo, mas imagine o seguinte: cline.cmd é o comando em questao, add, remove ou qq outro q vc configurou). qd o comando ‘add’ for encontrado ele vai executar a funcao com os argumentos (que foram tratados em outra parte do codigo).
Pronto, codigo limpo, economia de linhas, e facilimo para adcionar ou remover um ou outro comando/funcao. Basta editar o vetor handlers com o nome apropriado da funcao
e claro certificarse que a funcao exista no codigo.
Thanks to Froz