@@ -38,7 +38,7 @@ bool command_cb_help(application & /*app*/, tokenizer & /*t*/)
3838{
3939 std::cout << " MetaCall Command Line Interface by Parra Studios" << std::endl;
4040 std::cout <<
" Copyright (C) 2016 - 2019 Vicente Eduardo Ferrer Garcia <[email protected] >" << std::endl;
41- std::cout << std::endl << " A command line interface example as MetaCall wrapper " << std::endl;
41+ std::cout << std::endl << " A command line interface for MetaCall Core " << std::endl;
4242
4343 /* Command list */
4444 std::cout << std::endl << " Command list:" << std::endl << std::endl;
@@ -315,8 +315,8 @@ bool command_cb_exit(application & app, tokenizer & /*t*/)
315315
316316/* -- Methods -- */
317317
318- application::parameter_iterator::parameter_iterator (application & app, const std::string & tag, application::script_list & scripts ) :
319- app(app), tag(tag), scripts(scripts )
318+ application::parameter_iterator::parameter_iterator (application & app, const char * command, const char * tag, application::arg_list & arguments ) :
319+ app(app), command(command), tag(tag), arguments(arguments )
320320{
321321
322322}
@@ -328,22 +328,113 @@ application::parameter_iterator::~parameter_iterator()
328328
329329void application::parameter_iterator::operator ()(const char * parameter)
330330{
331- std::string script (parameter);
331+ arguments.push_back (parameter);
332+ }
333+
334+ void application::parameter_iterator::evaluate ()
335+ {
336+ typedef std::function<void (application &, const std::string &, const std::string &, application::arg_list &)> parameter_callback;
337+
338+ /* List of scripts that run pip/npm/gem */
339+ static std::unordered_map<std::string, std::string> install_scripts =
340+ {
341+ {
342+ " py" ,
343+ " #!/usr/bin/env python3\n "
344+ " \n "
345+ " try:\n "
346+ " from pip import main as pipmain\n "
347+ " except ImportError:\n "
348+ " from pip._internal import main as pipmain\n "
349+ " \n "
350+ " def package_manager(args):\n "
351+ " return pipmain(args);\n "
352+ }
353+ };
354+
355+ /* List of available commands when installing */
356+ static std::unordered_map<std::string, parameter_callback> parameter_commands =
357+ {
358+ {
359+ " load" , [](application & app, const std::string & tag, const std::string &, application::arg_list & args)
360+ {
361+ std::for_each (args.begin (), args.end (), [&app, &tag](const std::string & script)
362+ {
363+ app.load (tag, script);
364+ });
365+ }
366+ },
367+ {
368+ " install" , [](application & app, const std::string & tag, const std::string & command, application::arg_list & args)
369+ {
370+ const std::string & script = install_scripts[tag];
371+
372+ if (script == " " )
373+ {
374+ std::cout << " Package manager script not available for tag (" << tag << " )" << std::endl;
375+
376+ app.shutdown ();
377+
378+ return ;
379+ }
380+
381+ if (metacall_load_from_memory (tag.c_str (), script.c_str (), script.size (), NULL ) != 0 )
382+ {
383+ std::cout << " Error when loading (" << tag << " ) package manager script" << std::endl;
332384
333- if (app.load (tag, script) == false )
385+ app.shutdown ();
386+
387+ return ;
388+ }
389+
390+ void * args_values[1 ] =
391+ {
392+ metacall_value_create_array (NULL , args.size () + 1 )
393+ };
394+
395+ void ** array_value = static_cast <void **>(metacall_value_to_array (args_values[0 ]));
396+
397+ size_t iterator = 0 ;
398+
399+ array_value[iterator++] = metacall_value_create_string (command.c_str (), command.length ());
400+
401+ std::for_each (args.begin (), args.end (), [&array_value, &iterator](const std::string & arg)
402+ {
403+ array_value[iterator++] = metacall_value_create_string (arg.c_str (), arg.length ());
404+ });
405+
406+ void * result = metacallv (" package_manager" , args_values);
407+
408+ metacall_value_destroy (args_values[0 ]);
409+
410+ /* TODO: Do something with result */
411+
412+ if (result != NULL )
413+ {
414+ metacall_value_destroy (result);
415+ }
416+
417+ app.shutdown ();
418+ }
419+ }
420+ };
421+
422+ const parameter_callback cb = parameter_commands[command];
423+
424+ if (cb != nullptr )
334425 {
335- std::cout << " Invalid parameter ( " << parameter << " ) " << std::endl ;
426+ cb (app, tag, command, arguments) ;
336427 }
337428}
338429
339430bool application::load (const std::string & tag, const std::string & script)
340431{
341- const char * script_list [] =
432+ const char * load_scripts [] =
342433 {
343434 script.c_str ()
344435 };
345436
346- if (metacall_load_from_file (tag.c_str (), script_list , sizeof (script_list ) / sizeof (script_list [0 ]), NULL ) != 0 )
437+ if (metacall_load_from_file (tag.c_str (), load_scripts , sizeof (load_scripts ) / sizeof (load_scripts [0 ]), NULL ) != 0 )
347438 {
348439 std::cout << " Script (" << script << " ) load error in loader (" << tag << " )" << std::endl;
349440
@@ -444,13 +535,16 @@ application::application(int argc, char * argv[]) : exit_condition(false), log_p
444535 /* Print MetaCall information */
445536 metacall_print_info ();
446537
447- /* Parse program arguments if any */
448- if (argc > 1 )
538+ /* Parse program arguments if any (e.g metacall (0) load (1) py (2) asd.py (3)) */
539+ if (argc > 3 )
449540 {
450- parameter_iterator param_it (*this , argv[1 ], scripts );
541+ parameter_iterator param_it (*this , argv[1 ], argv[ 2 ], arguments );
451542
452543 /* Parse program parameters */
453- std::for_each (&argv[2 ], argv + argc, param_it);
544+ std::for_each (&argv[3 ], argv + argc, param_it);
545+
546+ /* Execute the action */
547+ param_it.evaluate ();
454548 }
455549
456550 /* Define available commands */
@@ -480,7 +574,10 @@ application::~application()
480574void application::run ()
481575{
482576 /* Show welcome message */
483- std::cout << " Welcome to Tijuana, tequila, sexo & marijuana." << std::endl;
577+ if (exit_condition != true )
578+ {
579+ std::cout << " Welcome to Tijuana, tequila, sexo & marijuana." << std::endl;
580+ }
484581
485582 while (exit_condition != true )
486583 {
0 commit comments