@@ -66,12 +66,14 @@ init(_) ->
6666handle_call ({run , Command , Args }, From , State = # state {}) ->
6767 case ets :lookup (? ETS_TABLE_NAME , Command ) of
6868 [] ->
69- {reply , {error , command_not_found }, State };
70- [{_ , ArgsDef , Fun , _Description }] ->
71- CommandPid = spawn_run_command (Command , Args , ArgsDef , From , Fun ),
72- RunningCommands = State # state .running_commands ,
73- {noreply ,
74- State # state {running_commands = [{CommandPid , From } | RunningCommands ]}}
69+ case get_wildcard_command (Command ) of
70+ [] ->
71+ {reply , {error , command_not_found }, State };
72+ Result ->
73+ evaluate_command_lookup_result (Result , Command , Args , From , State )
74+ end ;
75+ Else ->
76+ evaluate_command_lookup_result (Else , Command , Args , From , State )
7577 end ;
7678handle_call ({get_help , Command }, _From , State = # state {}) ->
7779 Help = do_get_help (Command ),
@@ -107,6 +109,13 @@ spawn_run_command(Command, Args, ArgsDef, From, Fun) ->
107109 gen_server :reply (From , CommandResult )
108110 end ).
109111
112+ evaluate_command_lookup_result ([{CommandSpec , ArgsDef , Fun , _Description }],
113+ Command , Args , From , State ) ->
114+ NewArgs = extract_command_args (CommandSpec , Command , Args ),
115+ CommandPid = spawn_run_command (Command , NewArgs , ArgsDef , From , Fun ),
116+ RunningCommands = State # state .running_commands ,
117+ {noreply , State # state {running_commands = [{CommandPid , From } | RunningCommands ]}}.
118+
110119run_command (Command , Args , ArgsDef , Fun ) ->
111120 case convert (ArgsDef , Args ) of
112121 {ok , NewArgs } ->
@@ -223,7 +232,7 @@ is_numeric(Value) ->
223232do_get_help ([]) ->
224233 ets :foldr (fun ({Command , _ , _ , Desc }, Acc ) ->
225234 [{Command , Desc } | Acc ]
226- end , [], cli_commands );
235+ end , [], ? ETS_TABLE_NAME );
227236do_get_help (InCommands ) ->
228237 case ets :lookup (? ETS_TABLE_NAME , InCommands ) of
229238 [] ->
@@ -233,9 +242,9 @@ do_get_help(InCommands) ->
233242 end .
234243
235244do_help_lookup (InCommands ) ->
236- case ets :select (cli_commands , get_select_matchspec (InCommands , false )) of
245+ case ets :select (? ETS_TABLE_NAME , get_select_matchspec (InCommands , false )) of
237246 [] ->
238- ets :select (cli_commands , get_select_matchspec (InCommands , true ));
247+ ets :select (? ETS_TABLE_NAME , get_select_matchspec (InCommands , true ));
239248 Else ->
240249 Else
241250 end .
@@ -267,9 +276,15 @@ format_command({Commands, Desc, Args}) ->
267276 cli_console_formatter :text (" ~n Arguments: " ) |
268277 [format_arg (Arg ) || Arg <- Args ]];
269278format_command ({Commands , Desc }) ->
270- CommandStr = string :pad (string :join (Commands , " " ), 32 ),
279+ NewCommands = lists :map (fun format_command_string /1 , Commands ),
280+ CommandStr = string :pad (string :join (NewCommands , " " ), 32 ),
271281 cli_console_formatter :text (" ~ts ~ts " , [CommandStr , Desc ]).
272282
283+ format_command_string (# argument {name = Name }) ->
284+ " <" ++ Name ++ " >" ;
285+ format_command_string (Command ) ->
286+ Command .
287+
273288format_arg (# argument {name = Name , optional = Optional ,
274289 default = Default , description = Desc }) ->
275290
@@ -303,14 +318,31 @@ is_argument_defined(Arg, ArgsDef) ->
303318 end .
304319
305320register_command (Command , ArgsDef , Fun , Description ) ->
306- case check_multiple_argdefs (ArgsDef ) of
321+ CommandArguments = get_command_arguments (Command ),
322+ case check_multiple_argdefs (ArgsDef ++ CommandArguments ) of
307323 ok ->
324+ ets :match_delete (? ETS_TABLE_NAME , {generate_match_head (Command ),
325+ generate_filter (Command ), []}),
308326 true = ets :insert (? ETS_TABLE_NAME , {Command , ArgsDef , Fun , Description }),
309327 ok ;
310328 Else ->
311329 Else
312330 end .
313331
332+ get_command_arguments (Command ) ->
333+ lists :filter (fun (# argument {}) -> true ;
334+ (_ ) -> false
335+ end , Command ).
336+
337+ get_command_arguments_with_index (Command ) ->
338+ {_ , Result } =
339+ lists :foldl (fun (# argument {} = Item , {ItemSeq , Acc }) ->
340+ {ItemSeq + 1 , [{ItemSeq , Item } | Acc ]};
341+ (_ , {ItemSeq , Acc }) ->
342+ {ItemSeq + 1 , Acc }
343+ end , {1 , []}, Command ),
344+ Result .
345+
314346check_multiple_argdefs (Argdefs ) ->
315347 check_multiple_argdefs (Argdefs , []).
316348
@@ -333,4 +365,40 @@ format_help(HelpCommand, Acc) ->
333365 lists :foldr (fun (Item , Acc2 ) -> [Item | Acc2 ] end , Acc , Result );
334366 Item ->
335367 [Item | Acc ]
336- end .
368+ end .
369+
370+ get_wildcard_command (Command ) ->
371+ case ets :select (? ETS_TABLE_NAME , [{generate_match_head (Command ),
372+ generate_filter (Command ), ['$_' ]}]) of
373+ [] ->
374+ [];
375+ [{Commands , ArgsDef , Fun , Description }] ->
376+ CommandArguments = get_command_arguments (Commands ),
377+ [{Commands , ArgsDef ++ CommandArguments , Fun , Description }]
378+ end .
379+
380+ generate_match_head (Command ) ->
381+ CommandHead = [item_num (ItemNum ) || ItemNum <- lists :seq (1 , length (Command ))],
382+ {CommandHead , '_' , '_' , '_' }.
383+
384+ generate_filter (Command ) ->
385+ generate_filter (Command , 1 , []).
386+
387+ generate_filter ([], _ItemCount , Where ) ->
388+ lists :reverse (Where );
389+ generate_filter ([Command | Rest ], ItemCount , Where ) ->
390+ Item = item_num (ItemCount ),
391+ Filter = {'orelse' ,
392+ {'==' , Command , Item },
393+ {'==' , argument , {element , 1 , Item }}
394+ },
395+ generate_filter (Rest , ItemCount + 1 , [Filter | Where ]).
396+
397+ item_num (ItemNum ) ->
398+ list_to_atom (" $" ++ integer_to_list (ItemNum )).
399+
400+ extract_command_args (CommandSpec , Command , Args ) ->
401+ CommandArgWithIndex = get_command_arguments_with_index (CommandSpec ),
402+ lists :foldl (fun ({Index , # argument {name = Name }}, Acc ) ->
403+ [{Name , lists :nth (Index , Command )} | Acc ]
404+ end , Args , CommandArgWithIndex ).
0 commit comments