/
MadDAD
/
alterplast
Обзор
Документация
Войти
/
MadDAD
/
alterplast
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
OpenConf_Scripts/OpenIn1C/Get_Opt.cpp
170 строк
4 KB
trdm
24 мар 2017, 12:42
24 мар 2017, 12:42
988c847
Код
Авторство
О чём код?
#include <stdlib.h> #include <string.h> #include <ctype.h> #include "get_opt.h" void debug(char *msg, ...); char *SkipSpace(char *str) { while( isspace(*(unsigned char*)str) ) str++; return str; } char **StrToArgv(char *CmdLine, int *Argc) { char open_quote = 0; short slash = 0; int argc = 0; int arg = 0, argv_len = 0; char **argv = NULL, *buf = NULL; int i; #define PUT_CHAR(c) buf[argv_len++]=c; *Argc = 0; if( CmdLine==NULL ) return NULL; CmdLine = SkipSpace(CmdLine); for( i=strlen(CmdLine)-1; isspace((unsigned char)(CmdLine[i])); i-- ) // strip trailing blanks CmdLine[i]='\0'; debug("\tdup commandline: "); buf = strdup(CmdLine); debug("%s\n", buf); if( buf==NULL) return NULL; for( ; *CmdLine!='\0'; CmdLine++ ) { if( slash==1 ) { switch( *CmdLine ) { case '\"': PUT_CHAR('\"'); break; case '\'': PUT_CHAR('\''); break; /* case 'a': PUT_CHAR('\a'); break; case 'b': PUT_CHAR('\b'); break; case 'f': PUT_CHAR('\f'); break; case 'r': PUT_CHAR('\r'); break; case 't': PUT_CHAR('\t'); break; case 'v': PUT_CHAR('\v'); break; */ default: PUT_CHAR('\\'); PUT_CHAR(*CmdLine); break; } slash = 0; continue; } switch( *CmdLine ) { case '\\': slash++; continue; break; case '\"': case '\'': if( (open_quote!=0) && (*CmdLine==open_quote) ) open_quote = 0; // end quoted part else open_quote = *CmdLine; // begin quoted part continue; break; } if( open_quote!=0 ) {PUT_CHAR(*CmdLine); continue;} // character inside quotes if( isspace((unsigned char)*CmdLine) ) { argc++; debug("\targc = %i\n", argc); PUT_CHAR('\0'); CmdLine = SkipSpace(CmdLine) - 1; continue; } PUT_CHAR(*CmdLine); } //last argument argc++; PUT_CHAR('\0'); int len; char *dest, *src; debug("\talloc memory for argv[]\n"); argv = (char**)malloc((argc+1)*sizeof(char*) + argv_len); if( argv!=NULL ) { dest = ((char*)(argv + argc)) + 1; src = buf; for( i=0; i<argc; i++ ) { len = strlen(src) + 1; strcpy(dest, src); argv[i] = dest; dest += len; src += len; } // argv[argc] must be empty string argv[argc] = NULL; } debug("\tfree buffer\n"); free(buf); *Argc = argc; return argv; } // return: // on success - option index // on NULL or zero length string - -1 // on wrong option - -2 // on non-option - -3. int FindOpt(TOption *opts, char *opt) { short OptType = 0; // 1 - short, 2 - long int len; int i; if( opt==NULL ) return -1; len = strlen(opt); if( len<2 ) return -1; if( opt[0]=='-' ) if( opt[1]=='-' ) OptType = 2; else OptType = 1; if( OptType==0 ) return -3; if( (OptType==1) && (len!=2) ) return -2; i = 0; while( (opts[i].OptS!=0) || (opts[i].OptL!=NULL) ) { if( OptType==1 ) { if( opt[1]==opts[i].OptS ) return i; } else { if( strcmp(opt+2, opts[i].OptL)==0 ) return i; } i++; } return -2; } //=================================================================================== //=========== GetOpt ============================================================== //=================================================================================== BOOL GetOpt(TGetOptData *data) { if( *(data->argv)==NULL ) return FALSE; data->option_index = FindOpt(data->options, *(data->argv)); data->argv++; // shift to next arg data->unprocessed_arg++; data->option_arg = NULL; if( data->option_index>0 ) { if( data->options[data->option_index].HaveArg && (*(data->argv)!=NULL) ) { if( FindOpt(data->options, *(data->argv))==-3 ) data->option_arg = *(data->argv); } } return TRUE; }