@@ -362,18 +362,18 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
362
362
return (* argv ) - orig_argv ;
363
363
}
364
364
365
- static int handle_alias (int * argcp , const char * * * argv )
365
+ static int handle_alias (struct strvec * args )
366
366
{
367
367
int envchanged = 0 , ret = 0 , saved_errno = errno ;
368
368
int count , option_count ;
369
369
const char * * new_argv ;
370
370
const char * alias_command ;
371
371
char * alias_string ;
372
372
373
- alias_command = ( * argv ) [0 ];
373
+ alias_command = args -> v [0 ];
374
374
alias_string = alias_lookup (alias_command );
375
375
if (alias_string ) {
376
- if (* argcp > 1 && !strcmp (( * argv ) [1 ], "-h" ))
376
+ if (args -> nr > 1 && !strcmp (args -> v [1 ], "-h" ))
377
377
fprintf_ln (stderr , _ ("'%s' is aliased to '%s'" ),
378
378
alias_command , alias_string );
379
379
if (alias_string [0 ] == '!' ) {
@@ -390,7 +390,7 @@ static int handle_alias(int *argcp, const char ***argv)
390
390
child .wait_after_clean = 1 ;
391
391
child .trace2_child_class = "shell_alias" ;
392
392
strvec_push (& child .args , alias_string + 1 );
393
- strvec_pushv (& child .args , ( * argv ) + 1 );
393
+ strvec_pushv (& child .args , args -> v + 1 );
394
394
395
395
trace2_cmd_alias (alias_command , child .args .v );
396
396
trace2_cmd_name ("_run_shell_alias_" );
@@ -423,15 +423,13 @@ static int handle_alias(int *argcp, const char ***argv)
423
423
trace_argv_printf (new_argv ,
424
424
"trace: alias expansion: %s =>" ,
425
425
alias_command );
426
-
427
- REALLOC_ARRAY (new_argv , count + * argcp );
428
- /* insert after command name */
429
- COPY_ARRAY (new_argv + count , * argv + 1 , * argcp );
430
-
431
426
trace2_cmd_alias (alias_command , new_argv );
432
427
433
- * argv = new_argv ;
434
- * argcp += count - 1 ;
428
+ /* Replace the alias with the new arguments. */
429
+ strvec_splice (args , 0 , 1 , new_argv , count );
430
+
431
+ free (alias_string );
432
+ free (new_argv );
435
433
436
434
ret = 1 ;
437
435
}
@@ -800,10 +798,10 @@ static void execv_dashed_external(const char **argv)
800
798
exit (128 );
801
799
}
802
800
803
- static int run_argv (int * argcp , const char * * * argv )
801
+ static int run_argv (struct strvec * args )
804
802
{
805
803
int done_alias = 0 ;
806
- struct string_list cmd_list = STRING_LIST_INIT_NODUP ;
804
+ struct string_list cmd_list = STRING_LIST_INIT_DUP ;
807
805
struct string_list_item * seen ;
808
806
809
807
while (1 ) {
@@ -817,8 +815,8 @@ static int run_argv(int *argcp, const char ***argv)
817
815
* process.
818
816
*/
819
817
if (!done_alias )
820
- handle_builtin (* argcp , * argv );
821
- else if (get_builtin (* * argv )) {
818
+ handle_builtin (args -> nr , args -> v );
819
+ else if (get_builtin (args -> v [ 0 ] )) {
822
820
struct child_process cmd = CHILD_PROCESS_INIT ;
823
821
int i ;
824
822
@@ -834,8 +832,8 @@ static int run_argv(int *argcp, const char ***argv)
834
832
commit_pager_choice ();
835
833
836
834
strvec_push (& cmd .args , "git" );
837
- for (i = 0 ; i < * argcp ; i ++ )
838
- strvec_push (& cmd .args , ( * argv ) [i ]);
835
+ for (i = 0 ; i < args -> nr ; i ++ )
836
+ strvec_push (& cmd .args , args -> v [i ]);
839
837
840
838
trace_argv_printf (cmd .args .v , "trace: exec:" );
841
839
@@ -850,13 +848,13 @@ static int run_argv(int *argcp, const char ***argv)
850
848
i = run_command (& cmd );
851
849
if (i >= 0 || errno != ENOENT )
852
850
exit (i );
853
- die ("could not execute builtin %s" , * * argv );
851
+ die ("could not execute builtin %s" , args -> v [ 0 ] );
854
852
}
855
853
856
854
/* .. then try the external ones */
857
- execv_dashed_external (* argv );
855
+ execv_dashed_external (args -> v );
858
856
859
- seen = unsorted_string_list_lookup (& cmd_list , * argv [0 ]);
857
+ seen = unsorted_string_list_lookup (& cmd_list , args -> v [0 ]);
860
858
if (seen ) {
861
859
int i ;
862
860
struct strbuf sb = STRBUF_INIT ;
@@ -873,14 +871,14 @@ static int run_argv(int *argcp, const char ***argv)
873
871
" not terminate:%s" ), cmd_list .items [0 ].string , sb .buf );
874
872
}
875
873
876
- string_list_append (& cmd_list , * argv [0 ]);
874
+ string_list_append (& cmd_list , args -> v [0 ]);
877
875
878
876
/*
879
877
* It could be an alias -- this works around the insanity
880
878
* of overriding "git log" with "git show" by having
881
879
* alias.log = show
882
880
*/
883
- if (!handle_alias (argcp , argv ))
881
+ if (!handle_alias (args ))
884
882
break ;
885
883
done_alias = 1 ;
886
884
}
@@ -892,6 +890,7 @@ static int run_argv(int *argcp, const char ***argv)
892
890
893
891
int cmd_main (int argc , const char * * argv )
894
892
{
893
+ struct strvec args = STRVEC_INIT ;
895
894
const char * cmd ;
896
895
int done_help = 0 ;
897
896
@@ -951,25 +950,32 @@ int cmd_main(int argc, const char **argv)
951
950
*/
952
951
setup_path ();
953
952
953
+ for (size_t i = 0 ; i < argc ; i ++ )
954
+ strvec_push (& args , argv [i ]);
955
+
954
956
while (1 ) {
955
- int was_alias = run_argv (& argc , & argv );
957
+ int was_alias = run_argv (& args );
956
958
if (errno != ENOENT )
957
959
break ;
958
960
if (was_alias ) {
959
961
fprintf (stderr , _ ("expansion of alias '%s' failed; "
960
962
"'%s' is not a git command\n" ),
961
- cmd , argv [0 ]);
963
+ cmd , args .v [0 ]);
964
+ strvec_clear (& args );
962
965
exit (1 );
963
966
}
964
967
if (!done_help ) {
965
- cmd = argv [0 ] = help_unknown_cmd (cmd );
968
+ strvec_replace (& args , 0 , help_unknown_cmd (cmd ));
969
+ cmd = args .v [0 ];
966
970
done_help = 1 ;
967
- } else
971
+ } else {
968
972
break ;
973
+ }
969
974
}
970
975
971
976
fprintf (stderr , _ ("failed to run command '%s': %s\n" ),
972
977
cmd , strerror (errno ));
978
+ strvec_clear (& args );
973
979
974
980
return 1 ;
975
981
}
0 commit comments