рд░реИрдЧреЗрд▓ рд╕реНрдЯреЗрдЯ рдорд╢реАрди рдХрдВрдкрд╛рдЗрд▓рд░ рдХрд╛ рдордЬреЗрджрд╛рд░ рдЙрдкрдпреЛрдЧ рдЗрдВрдЯ рдЖрд░реНрдЬреАрд╕реА, рдЪрд╛рд░ * рдЖрд░рдЬреАрд╡реА [] рдкрд░ рдПрдХ рд▓рд╛рдЗрди рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдПред
рдпрд╣ рд╕рдм рдЗрд╕ рддрдереНрдп рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реБрдЖ рдХрд┐ рдмрд╛рдж рдХреЗ рд╣рд╕реНрддрд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд┐рд▓реНрдбрдЧрд░реНрдЧ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА
int main (int argc, char *argv[]) { body }
рдореИрдВрдиреЗ рд╕реЛрдЪрд╛, рдпрд╣ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХрд╣реАрдВ рднреА рдЙрдзрд╛рд░ рд▓реЗрдирд╛ рдЕрд╕рдВрднрд╡ рдерд╛, рдЕрдм рд╣рдо рдкрд╛рддреЗ рд╣реИрдВ ... рдФрд░ рдореБрдЭреЗ рдирд╣реАрдВ рдорд┐рд▓рд╛ ...

рдЦреИрд░, рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рдорд┐рд▓рд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, https://github.com/gcc-mirror/gcc/blob/master/libiberty/argv.c (GPLv2 рд╣рдореЗрд╢рд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрддрд╛ рд╣реИ), рдореИрдВ рддреБрд░рдВрдд рдРрд╕реЗ рджрд╛рдпрд┐рддреНрд╡реЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реВрдВ рддреИрдпрд╛рд░ рдирд╣реАрдВ рдерд╛ред рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдмрд╛рд╢ рдореЗрдВ рдРрд╕рд╛ рдХрд╛рд░реНрдп рд╣реИ (GPLv3 рдФрд░ рднреА рдмреЗрд╣рддрд░ рд╣реИ)ред zsh? - рдЬрд╛рдУ рдвреВрдВрдвреЛ (рдореИрдВрдиреЗ рдкрд╛рдпрд╛ ... - рдореБрдЭреЗ рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдП)ред
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореБрдЭреЗ рд╡рд╣ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдЬреЛ рдореИрдВ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд╡рд╣ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдЬреИрд╕рд╛ рдореИрдВрдиреЗ рдкрд╛рдпрд╛ред рдЦреИрд░, рдЕрдВрдд рдореЗрдВ, рдореБрдЭреЗ рдЗрд╕рдХрд╛ рдЕрдзрд┐рдХрд╛рд░ рд╣реИ, рд╕рднреА рд╕рдорд╛рди рд╣реИрдВ, рдореИрдВ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЦреБрдж рдХреЛ рдордиреЛрд░рдВрдЬрди рдХреА рдкреНрдпрд╛рд╕ рдмрдирд╛рддрд╛ рд╣реВрдВред
рдореИрдВ рдЗрд╕ рдорд╛рдорд▓реЗ рдХреЛ рдкрд╛рд░рдВрдкрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╢рдмреНрдж рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдореИрдВ рдЗрд╕ рдЖрдзрд╛рд░ рдкрд░ рднреА рдкрд░реЗрд╢рд╛рди рдерд╛ред
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╣рдо рд░рдЧреЗрд▓ рд╕реНрдЯреЗрдЯ рдорд╢реАрди рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реЗ рдорд┐рд▓рддреЗ рд╣реИрдВред
рдЙрдкрдХрд░рдг
- рдЬреАрд╕реАрд╕реА;)
- ragel
- рдореЗрдХрдЕрдк
- lcov
- libcheck
рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: JOYFUL CMDLINE PARSER WRITTEN IN RAGEL
рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди
рдЗрдирдкреБрдЯ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ, рдХрд╛рд░реНрдп рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рдПрдХ рд╕реНрдерд╛рди рдпрд╛ рдЯреИрдм рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдП рдЧрдП рддрд░реНрдХреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ:
- рдмрдЪ рдЪрд░рд┐рддреНрд░ рдХреЗ рдмрд╛рдж рдХрд┐рд╕реА рднреА рдЪрд░рд┐рддреНрд░ рдХреЛ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
- рдХреЛрдИ рднреА рд╡рд░реНрдг рдЬреЛ рджреЛ рдбрдмрд▓реНрд╕ рдХреЗ рдмреАрдЪ рдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
рдПрдХ рддрддреНрд╡ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ - рдЕрдпреЛрдЧреНрдп
'
рдпрд╛ "
рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ рддреНрд░реБрдЯрд┐ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреА
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХрдИ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВред рдФрд░ рд░рдЧреЗрд▓ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдЙрдкрдпреБрдХреНрдд рд╣реИред
рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╕рдордЭрд╛рдпрд╛
рдЪрд▓рд┐рдП "buildargv" рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рдорд╢реАрди рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд░рд╛рдЧреЗрд▓ рдХреЛ рдлрд╝рд╛рдЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рдХреЛ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддреЗ рд╣реИрдВ (5.8.1 рдбреЗрдЯрд╛ рд▓рд┐рдЦреЗрдВ)ред
%%{ machine buildargv; write data; }%%
рдЕрдЧрд▓рд╛, рд╣рдо рдПрдХ lineElement
рдорд╢реАрди рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдмрджрд▓реЗ рдореЗрдВ (2.5.1 рд╕рдВрдШ) рджреЛ рдорд╢реАрдиреЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреА рд╣реИрдВ: arg
рдФрд░ whitespace
ред
lineElement = arg >start_arg %end_arg | whitespace; main := blineElements**;
arg
рдорд╢реАрди рдХреЗ рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ end_arg
рдХреНрд░рдорд╢рдГ start_arg
рдФрд░ end_arg
рдХрд╛рд░реНрдпреЛрдВ end_arg
рдЬрд╛рддрд╛ рд╣реИред
action start_arg { argv_s = p; } action end_arg { nargv = (char**)realloc((*argv), (argc_ + 1)*sizeof(char*)); (*argv) = nargv; (*argv)[argc_] = strndup(argv_s, p - argv_s); argc_++; }
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, start_arg
рдХрд╛рд░реНрдп рдЗрдирдкреБрдЯ рдкрд░ рд╡рд░реНрдг рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реБрд░рдХреНрд╖рд┐рдд рд░рдЦрддрд╛ рд╣реИ, рдФрд░ arg
рдорд╢реАрди рд╕реЗ рд╕рдлрд▓ рдирд┐рдХрд╛рд╕ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, end_arg
рдХрд╛рд░реНрдп argv
рд╕рд░рдгреА рдореЗрдВ end_arg
рдирдпрд╛ рддрддреНрд╡ end_arg
ред
рдЕрдм рд╣рдо arg
рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓рддреЗ рд╣реИрдВред
arg = '\''> { fcall squote; } | '"'>{ fcall dquote; } | ( '\\'>{fcall skip;} | ^[ \t"'\\] )+;
рдЗрд╕рдореЗрдВ рддреАрди рдорд╢реАрдиреЛрдВ '
, "
рдФрд░ '
(\ | ^[ \t"'\])
рдХрд╛ рд╕рдорд╛рд╡реЗрд╢ рд╣реЛрддрд╛ рд╣реИ, рдмрд╛рдж рдореЗрдВ рдХреНрд░рдорд╢рдГ рдХреНрд░рдорд╢рдГ ^[ \t"'\]
рдФрд░ ^[ \t"'\]
рдХрд╛ рдПрдХ рд╕рдВрдШ рд╣реЛрддрд╛ рд╣реИред
рдЬрдм рд╣рдореЗрдВ рдЪрд░рд┐рддреНрд░ squote
, рддреЛ рд╣рдо squote
рдХрд╣рддреЗ рд╣реИрдВ, '
рд╣рдо рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ squote
, рдпрд╛ рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рд╡рд░реНрдг рд╣реИ \
skip
рдХрд╣рддреЗ рд╣реИрдВ, рдЬреЛ рдЗрд╕рдХреЗ рдмрд╛рдж рдХрд┐рд╕реА рднреА рд╡рд░реНрдг рдХреЛ skip
рджреЗрддрд╛ рд╣реИ, рдФрд░ рдХреЛрдИ рднреА рд╡рд░реНрдг 0x20
(рд╕реНрдерд╛рди), 0x09
(рдЯреИрдм), '
, "
рдпрд╛ \
"
рдХреЛ рд╕рд╣реА рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ ред
рдпрд╣ рдПрдХ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ:
skip := any @{ fret; }; dquote := ( '\\'>{ fcall skip; } | ^[\\] )+ :> ["] @{ fret; } @err(dquote_err); squote := ( '\\'>{ fcall skip; } | ^[\\] )+ :> ['] @{ fret; } @err(squote_err);
skip
рд╕рд╛рде skip
рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдкрддрд╛ рд▓рдЧрд╛ рд▓рд┐рдпрд╛ рд╣реИ рдХрд┐ ^['\\]
рднреА рдХреНрдпрд╛ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдпрд╣рд╛рдБ :>
рдпрд╣ Entry-Guarded Concatenation
( '\\'>{ fcall skip; } | ^['\\] )+
(4.2 рдЧрд╛рд░реНрдб рдСрдкрд░реЗрдЯрд░реНрд╕ рдЬреЛ рдкреНрд░рд╛рдпреЛрд░рд┐рдЯреАрдЬ рдХреЛ ( '\\'>{ fcall skip; } | ^['\\] )+
) рдЗрд╕рдХрд╛ рдЕрд░реНрде рдпрд╣ рд╣реИ рдХрд┐ рдорд╢реАрди ( '\\'>{ fcall skip; } | ^['\\] )+
рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдЬрдм ["]
рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛ рдореЗрдВ рд▓реМрдЯрддрд╛ рд╣реИред
рдФрд░ рдЕрдВрдд рдореЗрдВ, рдЦреБрд▓реЗ рдЙрджреНрдзрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд▓рд╛рдЗрди рддреНрд░реБрдЯрд┐ рдХреЗ рдЕрдВрдд рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, dquote_err
рдФрд░ squote_err
рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рддреНрд░реБрдЯрд┐ рдХреЛрдб рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП squote_err
рд╣реИред
action dquote_err { ret = -1; errsv = BUILDARGV_EDQUOTE; } action squote_err { ret = -1; errsv = BUILDARGV_ESQUOTE; }
рдХреЛрдб рдкреАрдврд╝реА рдХрдорд╛рдВрдб рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
ragel -e -L -F0 -o buildargv.c buildargv.rl
рдкрд░реАрдХреНрд╖рдг рд▓рд╛рдЗрдиреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА test_cmdline.c
рдореЗрдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖
рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рд╣реЛ рдЧрдИ рд╣реИред
рдХреНрдпрд╛ рдпрд╣ рддреЗрдЬ рдерд╛? рдореБрдЭреЗ рдЗрд╕рдореЗрдВ рд╕рдВрджреЗрд╣ рд╣реИред рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ? рдпрджрд┐ рдХреЗрд╡рд▓ рдЖрдк рд░рдЧреЗрд▓ рдХреЗ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рд╣реИрдВред
рдореИрдВ рдирд┐рд░рдВрдХреБрд╢рддрд╛ рдХрд╛ рдвреЛрдВрдЧ рдирд╣реАрдВ рдХрд░рддрд╛, рд░реИрдЧреЗрд▓ рдХреЛрдб рдкрд░ рд░рдЪрдирд╛рддреНрдордХ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрднрд╛рд░реА рд░рд╣реВрдВрдЧрд╛ред
рд╕рд╛рдордЧреНрд░реА рд╕реВрдЪреА:
[^ 1]: рдПрдбреНрд░рд┐рдпрди рдерд░реНрд╕реНрдЯрдиред рд░рдЧреЗрд▓ рд╕реНрдЯреЗрдЯ рдорд╢реАрди рдХрдВрдкрд╛рдЗрд▓рд░ ред