Fermer2
squalylLe 10/06/2013 à 22:45
bon voila j'ai fait un readline trivial et un truc qui coupe un buffer terminé par zéro en tokens genre argc argv
je donne en vrac, pour le fun. Certainement incomplet et buggé, mais ça marchotte pour ce que ça me sert, je corrigerai plus tard ou selon vos suggestions.

ça gère correctement des trucs genre abc "de' f" (2 tokens ici)
/*released under WTFPL*/ #include <stdio.h> #ifdef __MINGW32__ #include <conio.h> #else #error dont know how to disable line buffering #endif // MINGW32 int readline(const char *prompt, char *buf, int len) { int n=0; int c; printf("%s",prompt); while(n<(len-1)) { c = getch(); //printf(">> %02X\n",c); if(c=='\n' || c=='\r') { //end of line printf("\n"); break; } else if(c==0x08) { //backspace if(n>0) { n--; printf("\x08 \x08"); } } else if(c==0x03) { //break buf[n++] = 0; return E_BREAK; } else if(c=='\t') { //tab //manage completion later } else { buf[n++]=c; printf("%c",c); } } //append final zero buf[n++] = 0; //done return 0; }
/*released under WTFPL*/ #define DEBUG_PARSER static char ** shell_parse(char *buf, int *out_total) { char ** toks = NULL; char *start; int index, count=0; int len = strlen(buf); int quotes = 0; //quoting state index = 0; start = buf; while(buf[index]) { #ifdef DEBUG_PARSER printf("-> [%02X] ", buf[index]); #endif if(buf[index]=='\'') { if(quotes!=2) { if(quotes == 1) { quotes = 0; } else if(quotes==0) { quotes = 1; } memmove(buf+index, buf+index+1, len-index); } #ifdef DEBUG_PARSER printf("quote->%d\n",quotes); #endif } else if(buf[index]=='"') { if(quotes!=1) { if(quotes == 2) { quotes = 0; } else if(quotes==0) { quotes = 2; } memmove(buf+index, buf+index+1, len-index); } #ifdef DEBUG_PARSER printf("quote->%d\n",quotes); #endif } else if(buf[index]==' ' && quotes==0) { //unquoted space, split token count++; toks = realloc(toks, count*sizeof(char*)); toks[count-1] = start; //save old token start buf[index] = 0; //mark end of token start = buf+index+1; //mark new token start #ifdef DEBUG_PARSER printf("split [%s]\n",toks[count-1]); #endif } else { //normal char #ifdef DEBUG_PARSER printf("normal\n"); #endif } index++; } if(strlen(start)>0) { //last characters form the last token count++; toks = realloc(toks, count*sizeof(char*)); toks[count-1] = start; //save old token start buf[index] = 0; //mark end of token #ifdef DEBUG_PARSER printf("last-> [%s]\n", toks[count-1]); #endif } *out_total = count; return toks; }