fixed #123: implement timeout for wait known usb device apprear
[mfgtools/gsi.git] / uuu / uuu.cpp
blob638b59c77a0c990fe062f151416815322de6c7a4
1 /*
2 * Copyright 2018 NXP.
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution.
14 * Neither the name of the NXP Semiconductor nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
32 #include <iostream>
33 #include <stdio.h>
34 #include <thread>
35 #include <atomic>
36 #include <iomanip>
37 #include <map>
38 #include <mutex>
39 #include <vector>
40 #include <sstream>
41 #include <fstream>
42 #include <stdarg.h>
43 #include <time.h>
44 #include <string.h>
45 #include <signal.h>
46 #include "buildincmd.h"
48 #include "../libuuu/libuuu.h"
50 char * g_vt_yellow = (char*)"\x1B[93m";
51 char * g_vt_default = (char*) "\x1B[0m";
52 char * g_vt_green = (char*)"\x1B[92m";
53 char * g_vt_red = (char*)"\x1B[91m";
54 char * g_vt_kcyn = (char*)"\x1B[36m";
55 char * g_vt_boldwhite = (char*)"\x1B[97m";
57 void clean_vt_color()
59 g_vt_yellow = (char*)"";
60 g_vt_default = g_vt_yellow;
61 g_vt_green = g_vt_yellow;
62 g_vt_red = g_vt_yellow;
63 g_vt_kcyn = g_vt_yellow;
64 g_vt_boldwhite = g_vt_yellow;
67 using namespace std;
69 int get_console_width();
70 void print_oneline(string str);
71 int auto_complete(int argc, char**argv);
72 void print_autocomplete_help();
74 char g_sample_cmd_list[] = {
75 #include "uuu.clst"
78 vector<string> g_usb_path_filter;
80 int g_verbose = 0;
81 static bool g_start_usb_transfer;
83 class AutoCursor
85 public:
86 ~AutoCursor()
88 printf("\x1b[?25h\n\n\n");
92 void ctrl_c_handle(int)
94 do {
95 AutoCursor a;
96 } while(0);
98 exit(1);
101 class string_ex : public std::string
103 public:
104 int format(const char *fmt, ...)
106 va_list args;
107 va_start(args, fmt);
108 size_t len = std::vsnprintf(NULL, 0, fmt, args);
109 va_end(args);
111 this->resize(len);
113 va_start(args, fmt);
114 std::vsnprintf((char*)c_str(), len + 1, fmt, args);
115 va_end(args);
117 return 0;
121 void print_help(bool detail = false)
123 const char help[] =
124 "uuu [-d -m -v -V] <" "bootloader|cmdlists|cmd" ">\n\n"
125 " bootloader download bootloader to board by usb\n"
126 " cmdlist run all commands in cmdlist file\n"
127 " If it is path, search uuu.auto in dir\n"
128 " If it is zip, search uuu.auto in zip\n"
129 " cmd Run one command, use -H see detail\n"
130 " example: SDPS: boot -f flash.bin\n"
131 " -d Daemon mode, wait for forever.\n"
132 " -v -V verbose mode, -V enable libusb error\\warning info\n"
133 " -dry Dry run mode, check if script or cmd correct \n"
134 " -m USBPATH Only monitor these paths.\n"
135 " -m 1:2 -m 1:3\n\n"
136 " -t Timeout second for wait known usb device appeared\n"
137 "uuu -s Enter shell mode. uuu.inputlog record all input commands\n"
138 " you can use \"uuu uuu.inputlog\" next time to run all commands\n\n"
139 "uuu -udev linux: show udev rule to avoid sudo each time \n"
140 "uuu -lsusb List connected know devices\n"
141 "uuu -h -H show help, -H means detail helps\n\n";
142 printf("%s", help);
143 printf("uuu [-d -m -v] -b[run] ");
144 g_BuildScripts.ShowCmds();
145 printf(" arg...\n");
146 printf("\tRun Built-in scripts\n");
147 g_BuildScripts.ShowAll();
148 printf("\nuuu -bshow ");
149 g_BuildScripts.ShowCmds();
150 printf("\n");
151 printf("\tShow built-in script\n");
152 printf("\n");
154 print_autocomplete_help();
156 if (detail == false)
157 return;
159 size_t start = 0, pos = 0;
160 string str= g_sample_cmd_list;
162 bool bprint = false;
163 while ((pos = str.find('\n',pos)) != str.npos)
165 string s = str.substr(start, pos - start);
166 if (s.substr(0, 6) == "# ----")
167 bprint = true;
169 if (bprint)
171 if (s[0] == '#')
173 printf("%s\n", &(s[1]));
176 pos += 1;
177 start = pos;
180 void print_version()
182 printf("uuu (Universal Update Utility) for nxp imx chips -- %s\n\n", uuu_get_version_string());
185 int print_cfg(const char *pro, const char * chip, const char * /*compatible*/, uint16_t pid, uint16_t vid, uint16_t bcdmin, uint16_t bcdmax, void * /*p*/)
187 const char *ext;
188 if (strlen(chip) >= 7)
189 ext = "";
190 else
191 ext = "\t";
193 if (bcdmin == 0 && bcdmax == 0xFFFF)
194 printf("\t%s\t %s\t%s 0x%04x\t 0x%04x\n", pro, chip, ext, pid, vid);
195 else
196 printf("\t%s\t %s\t%s 0x%04x\t 0x%04x\t [0x%04x..0x%04x]\n", pro, chip, ext, pid, vid, bcdmin, bcdmax);
197 return 0;
200 int print_udev_rule(const char *pro, const char * chip, const char * /*compatible*/, uint16_t vid, uint16_t pid, uint16_t bcdmin, uint16_t bcdmax, void * /*p*/)
202 printf("SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", MODE=\"0666\"\n",
203 vid, pid);
204 return 0;
207 int polling_usb(std::atomic<int>& bexit);
209 int g_overall_status;
210 int g_overall_okay;
211 int g_overall_failure;
212 char g_wait[] = "|/-\\";
213 int g_wait_index;
216 string build_process_bar(size_t width, size_t pos, size_t total)
218 string str;
219 str.resize(width, ' ');
220 str[0] = '[';
221 str[width - 1] = ']';
223 if (total == 0)
225 if (pos == 0)
226 return str;
228 string_ex loc;
229 size_t s = pos / (1024 * 1024);
230 loc.format("%dM", s);
231 str.replace(1, loc.size(), loc);
232 return str;
235 size_t i;
237 if (pos > total)
238 pos = total;
240 for (i = 1; i < (width-2) * pos / total; i++)
242 str[i] = '=';
245 if (i > 1)
246 str[i] = '>';
248 if (pos == total)
249 str[str.size() - 2] = '=';
251 string_ex per;
252 per.format("%d%%", pos * 100 / total);
254 size_t start = (width - per.size()) / 2;
255 str.replace(start, per.size(), per);
256 str.insert(start, g_vt_yellow);
257 str.insert(start + per.size() + strlen(g_vt_yellow), g_vt_default);
258 return str;
261 void print_auto_scroll(string str, size_t len, size_t start)
263 if (str.size() <= len)
265 str.resize(len, ' ');
266 cout << str;
267 return;
270 if(str.size())
271 start = start % str.size();
272 else
273 start = 0;
275 string s = str.substr(start, len);
276 s.resize(len, ' ');
277 cout << s;
279 class ShowNotify
281 public:
282 string m_cmd;
283 string m_dev;
284 size_t m_trans_pos;
285 int m_status;
286 size_t m_cmd_total;
287 size_t m_cmd_index;
288 string m_last_err;
289 int m_done;
290 size_t m_start_pos;
291 size_t m_trans_size;
292 clock_t m_start_time;
293 uint64_t m_cmd_start_time;
294 uint64_t m_cmd_end_time;
295 bool m_IsEmptyLine;
297 ShowNotify()
299 m_trans_size = m_trans_pos = 0;
300 m_status = 0;
301 m_cmd_total = 0;
302 m_cmd_index = 0;
303 m_done = 0;
304 m_start_pos = 0;
305 m_IsEmptyLine = false;
306 m_start_time = clock();
309 bool update(uuu_notify nt)
311 if (nt.type == uuu_notify::NOFITY_DEV_ATTACH)
313 m_dev = nt.str;
314 m_done = 0;
315 m_status = 0;
317 if (nt.type == uuu_notify::NOTIFY_CMD_START)
319 m_start_pos = 0;
320 m_cmd = nt.str;
321 m_cmd_start_time = nt.timestamp;
323 if (nt.type == uuu_notify::NOTIFY_DECOMPRESS_START)
325 m_start_pos = 0;
326 m_cmd = nt.str;
327 m_cmd_start_time = nt.timestamp;
328 m_dev = "Prep";
330 if (nt.type == uuu_notify::NOTIFY_DOWNLOAD_START)
332 m_start_pos = 0;
333 m_cmd = nt.str;
334 m_cmd_start_time = nt.timestamp;
335 m_dev = "Prep";
337 if (nt.type == uuu_notify::NOTIFY_DOWNLOAD_END)
339 m_IsEmptyLine = true;
341 if (nt.type == uuu_notify::NOTIFY_TRANS_SIZE || nt.type == uuu_notify::NOTIFY_DECOMPRESS_SIZE)
343 m_trans_size = nt.total;
344 return false;
346 if (nt.type == uuu_notify::NOTIFY_CMD_TOTAL)
348 m_cmd_total = nt.total;
349 return false;
351 if (nt.type == uuu_notify::NOTIFY_CMD_INDEX)
353 m_cmd_index = nt.index;
354 return false;
356 if (nt.type == uuu_notify::NOTIFY_DONE)
358 if (m_status)
359 g_overall_failure++;
360 else
361 g_overall_okay++;
363 m_done = 1;
365 if (nt.type == uuu_notify::NOTIFY_CMD_END)
367 m_cmd_end_time = nt.timestamp;
368 if(nt.status)
370 g_overall_status = nt.status;
371 m_last_err = uuu_get_last_err_string();
373 m_status |= nt.status;
374 if (m_status)
375 g_overall_failure++;
377 if (nt.type == uuu_notify::NOTIFY_TRANS_POS || nt.type == uuu_notify::NOTIFY_DECOMPRESS_POS)
379 if (m_trans_size == 0) {
381 m_trans_pos = nt.index;
382 return true;
385 if ((nt.index - m_trans_pos) < (m_trans_size / 100)
386 && nt.index != m_trans_size)
387 return false;
389 m_trans_pos = nt.index;
392 return true;
394 void print_verbose(uuu_notify*nt)
396 if (this->m_dev == "Prep" && g_start_usb_transfer)
397 return;
399 if (nt->type == uuu_notify::NOFITY_DEV_ATTACH)
401 cout << "New USB Device Attached at " << nt->str << endl;
403 if (nt->type == uuu_notify::NOTIFY_CMD_START)
405 cout << m_dev << ">" << "Start Cmd:" << nt->str << endl;
407 if (nt->type == uuu_notify::NOTIFY_CMD_END)
409 double diff = m_cmd_end_time - m_cmd_start_time;
410 diff /= 1000;
411 if (nt->status)
413 cout << m_dev << ">" << g_vt_red <<"Fail " << uuu_get_last_err_string() << "("<< std::setprecision(4) << diff << "s)" << g_vt_default << endl;
415 else
417 cout << m_dev << ">" << g_vt_green << "Okay ("<< std::setprecision(4) << diff << "s)" << g_vt_default << endl;
421 if (nt->type == uuu_notify::NOTIFY_TRANS_POS || nt->type == uuu_notify::NOTIFY_DECOMPRESS_POS)
423 if (m_trans_size)
424 cout << g_vt_yellow << "\r" << m_trans_pos * 100 / m_trans_size <<"%" << g_vt_default;
425 else
426 cout << "\r" << m_trans_pos;
428 cout.flush();
431 if (nt->type == uuu_notify::NOTIFY_CMD_INFO)
432 cout << nt->str;
434 if (nt->type == uuu_notify::NOTIFY_WAIT_FOR)
435 cout << "\r" << nt->str << " "<< g_wait[((g_wait_index++) & 0x3)];
437 if (nt->type == uuu_notify::NOTIFY_DECOMPRESS_START)
438 cout << "Decompress file:" << nt->str << endl;
440 if (nt->type == uuu_notify::NOTIFY_DOWNLOAD_START)
441 cout << "Download file:" << nt->str << endl;
444 void print(int verbose = 0, uuu_notify*nt=NULL)
446 verbose ? print_verbose(nt) : print_simple();
448 string get_print_dev_string()
450 string str;
451 str = m_dev;
452 str.resize(8, ' ');
454 string_ex s;
455 s.format("%2d/%2d", m_cmd_index+1, m_cmd_total);
457 str += s;
458 return str;
460 void print_simple()
462 int width = get_console_width();
463 int info, bar;
464 info = 14;
465 bar = 40;
467 if (m_IsEmptyLine)
469 string str(width, ' ');
470 cout << str;
471 return;
473 if (width <= bar + info + 3)
475 string_ex str;
477 str += get_print_dev_string();
479 str += g_wait[(g_wait_index++) & 0x3];
481 print_oneline(str);
482 return ;
484 else
486 string_ex str;
487 str += get_print_dev_string();
489 str.resize(info, ' ');
490 cout << str;
492 if (m_done || m_status)
494 string str;
495 str.resize(bar, ' ');
496 str[0] = '[';
497 str[str.size() - 1] = ']';
498 string err;
499 if (m_status)
501 err = uuu_get_last_err_string();
502 err.resize(bar - 2, ' ');
503 str.replace(1, err.size(), err);
504 str.insert(1, g_vt_red);
505 str.insert(1 + strlen(g_vt_red) + err.size(), g_vt_default);
507 else
509 str.replace(1, 4, "Done");
510 str.insert(1, g_vt_green);
511 str.insert(1 + strlen(g_vt_green) + strlen("Done"), g_vt_default);
513 cout << str;
514 } else {
515 cout << build_process_bar(bar, m_trans_pos, m_trans_size);
517 cout << " ";
518 print_auto_scroll(m_cmd, width - bar - info-1, m_start_pos);
520 if (clock() - m_start_time > CLOCKS_PER_SEC / 4)
522 m_start_pos++;
523 m_start_time = clock();
525 cout << endl;
527 return;
532 static map<string, ShowNotify> g_map_path_nt;
533 mutex g_callback_mutex;
535 void print_oneline(string str)
537 size_t w = get_console_width();
538 if (w <= 3)
539 return;
541 if (str.size() >= w)
543 str.resize(w - 1);
544 str[str.size() - 1] = '.';
545 str[str.size() - 2] = '.';
546 str[str.size() - 3] = '.';
548 else
550 str.resize(w, ' ');
552 cout << str << endl;
556 ShowNotify Summary(map<uint64_t, ShowNotify> *np)
558 ShowNotify sn;
559 for (auto it = np->begin(); it != np->end(); it++)
561 if (it->second.m_dev == "Prep")
563 sn.m_trans_size += it->second.m_trans_size;
564 sn.m_trans_pos += it->second.m_trans_pos;
566 else
568 if (it->second.m_trans_pos || it->second.m_cmd_index)
569 g_start_usb_transfer = true; // Hidden HTTP download when USB start transfer
573 if(g_start_usb_transfer)
574 sn.m_IsEmptyLine = true; // Hidden HTTP download when USB start transfer
576 sn.m_dev = "Prep";
577 sn.m_cmd = "Http Download\\Uncompress";
578 return sn;
581 int progress(uuu_notify nt, void *p)
583 map<uint64_t, ShowNotify> *np = (map<uint64_t, ShowNotify>*)p;
584 map<string, ShowNotify>::iterator it;
586 std::lock_guard<std::mutex> lock(g_callback_mutex);
588 if ((*np)[nt.id].update(nt))
590 if (!(*np)[nt.id].m_dev.empty())
591 if ((*np)[nt.id].m_dev != "Prep")
592 g_map_path_nt[(*np)[nt.id].m_dev] = (*np)[nt.id];
594 if (g_verbose)
596 if((*np)[nt.id].m_dev == "Prep")
597 Summary(np).print(g_verbose, &nt);
598 else
599 (*np)[nt.id].print(g_verbose, &nt);
601 else
603 string_ex str;
604 str.format("\rSuccess %d Failure %d ", g_overall_okay, g_overall_failure);
606 if (g_map_path_nt.empty())
607 str += "Wait for Known USB Device Appear...";
609 if (!g_usb_path_filter.empty())
611 str += " at path ";
612 for (size_t i = 0; i < g_usb_path_filter.size(); i++)
613 str += g_usb_path_filter[i] + " ";
616 print_oneline(str);
617 print_oneline("");
618 if ((*np)[nt.id].m_dev == "Prep" && !g_start_usb_transfer)
620 Summary(np).print();
621 }else
622 print_oneline("");
624 for (it = g_map_path_nt.begin(); it != g_map_path_nt.end(); it++)
625 it->second.print();
627 for (size_t i = 0; i < g_map_path_nt.size() + 3; i++)
628 cout << "\x1B[1F";
632 //(*np)[nt.id] = g_map_path_nt[(*np)[nt.id].m_dev];
635 if (nt.type == uuu_notify::NOTIFY_THREAD_EXIT)
637 if(np->find(nt.id) != np->end())
638 np->erase(nt.id);
640 return 0;
642 #ifdef _MSC_VER
644 #define DEFINE_CONSOLEV2_PROPERTIES
645 #include <windows.h>
646 #include <stdlib.h>
647 #include <stdio.h>
649 bool enable_vt_mode()
651 // Set output mode to handle virtual terminal sequences
652 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
653 if (hOut == INVALID_HANDLE_VALUE)
655 clean_vt_color();
656 return false;
659 DWORD dwMode = 0;
660 if (!GetConsoleMode(hOut, &dwMode))
662 clean_vt_color();
663 return false;
666 dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
667 if (!SetConsoleMode(hOut, dwMode))
669 clean_vt_color();
670 return false;
672 return true;
675 int get_console_width()
677 CONSOLE_SCREEN_BUFFER_INFO sbInfo;
678 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &sbInfo);
679 return sbInfo.dwSize.X;
681 #else
682 #include <sys/ioctl.h>
683 bool enable_vt_mode() { return true; }
684 int get_console_width()
686 struct winsize w;
687 ioctl(0, TIOCGWINSZ, &w);
688 return w.ws_col;
690 #endif
691 void print_usb_filter()
693 if (!g_usb_path_filter.empty())
695 cout << " at path ";
696 for (size_t i = 0; i < g_usb_path_filter.size(); i++)
697 cout << g_usb_path_filter[i] << " ";
701 int runshell(int shell)
703 int uboot_cmd = 0;
704 string prompt = "U>";
706 if (shell)
708 cout << "Please input command: " << endl;
709 string cmd;
710 ofstream log("uuu.inputlog", ofstream::binary);
711 log << "uuu_version "
712 << ((uuu_get_version() & 0xFF0000) >> 16)
713 << "."
714 << ((uuu_get_version() & 0xFF00) >> 8)
715 << "."
716 << ((uuu_get_version() & 0xFF))
717 << endl;
718 while (1)
720 cout << prompt;
721 getline(cin, cmd);
723 if (cmd == "uboot")
725 uboot_cmd = 1;
726 prompt = "=>";
727 cout << "Enter into u-boot cmd mode" << endl;
728 cout << "Okay" << endl;
730 else if (cmd == "exit" && uboot_cmd == 1)
732 uboot_cmd = 0;
733 prompt = "U>";
734 cout << "Exit u-boot cmd mode" << endl;
735 cout << "Okay" << endl;
736 }else if (cmd == "help" || cmd == "?")
738 print_help();
740 else if (cmd == "q" || cmd == "quit")
742 return 0;
744 else
746 log << cmd << endl;
747 log.flush();
749 if (uboot_cmd)
750 cmd = "fb: ucmd " + cmd;
752 int ret = uuu_run_cmd(cmd.c_str(), 0);
753 if (ret)
754 cout << uuu_get_last_err_string() << endl;
755 else
756 cout << "Okay" << endl;
759 return 0;
762 return -1;
765 void print_udev()
767 uuu_for_each_cfg(print_udev_rule, NULL);
768 fprintf(stderr, "\n1: put above udev run into /etc/udev/rules.d/99-uuu.rules\n");
769 fprintf(stderr, "\tsudo sh -c \"uuu -udev >> /etc/udev/rules.d/99-uuu.rules\"\n");
770 fprintf(stderr, "2: update udev rule\n");
771 fprintf(stderr, "\tsudo udevadm control --reload-rules\n");
774 int print_usb_device(const char *path, const char *chip, const char *pro, uint16_t vid, uint16_t pid, uint16_t bcd, void *p)
776 printf("\t%s\t %s\t %s\t 0x%04X\t0x%04X\t 0x%04X\n", path, chip, pro, vid, pid, bcd);
777 return 0;
780 void print_lsusb()
782 cout << "Connected Known USB Devices\n";
783 printf("\tPath\t Chip\t Pro\t Vid\t Pid\t BcdVersion\n");
784 printf("\t==================================================\n");
786 uuu_for_each_devices(print_usb_device, NULL);
789 int main(int argc, char **argv)
791 if (auto_complete(argc, argv) == 0)
792 return 0;
794 if (argc >= 2)
796 string s = argv[1];
797 if(s == "-udev")
799 print_udev();
800 return 0;
804 AutoCursor a;
806 print_version();
808 if (!enable_vt_mode())
810 cout << "Your console don't support VT mode, fail back to verbose mode" << endl;
811 g_verbose = 1;
814 if (argc == 1)
816 print_help();
817 return 0;
820 int deamon = 0;
821 int shell = 0;
822 string filename;
823 string cmd;
824 int ret;
825 int dryrun = 0;
827 string cmd_script;
829 for (int i = 1; i < argc; i++)
831 string s = argv[i];
832 if (!s.empty() && s[0] == '-')
834 if (s == "-d")
836 deamon = 1;
837 }else if (s == "-s")
839 shell = 1;
840 g_verbose = 1;
842 else if (s == "-v")
844 g_verbose = 1;
846 else if (s == "-V")
848 g_verbose = 1;
849 uuu_set_debug_level(2);
850 }else if (s == "-dry")
852 dryrun = 1;
853 g_verbose = 1;
855 else if (s == "-h")
857 print_help(false);
858 return 0;
860 else if (s == "-H")
862 print_help(true);
863 return 0;
865 else if (s == "-m")
867 i++;
868 uuu_add_usbpath_filter(argv[i]);
869 g_usb_path_filter.push_back(argv[i]);
871 else if (s == "-t")
873 i++;
874 uuu_set_wait_timeout(atoll(argv[i]));
876 else if (s == "-lsusb")
878 print_lsusb();
879 return 0;
881 else if (s == "-b" || s == "-brun")
883 if (i + 1 == argc || g_BuildScripts.find(argv[i + 1]) == g_BuildScripts.end())
885 printf("error, must be have script name: ");
886 g_BuildScripts.ShowCmds();
887 printf("\n");
888 return -1;
891 vector<string> args;
892 for (int j = i + 2; j < argc; j++)
894 string s = argv[j];
895 if (s.find(' ') != string::npos)
897 s.insert(s.begin(), '"');
898 s.insert(s.end(), '"');
900 args.push_back(s);
903 cmd_script = g_BuildScripts[argv[i + 1]].replace_script_args(args);
904 break;
906 else if (s == "-bshow")
908 if (i + 1 == argc || g_BuildScripts.find(argv[i+1]) == g_BuildScripts.end())
910 printf("error, must be have script name: ");
911 g_BuildScripts.ShowCmds();
912 printf("\n");
913 return -1;
915 else
917 printf("%s", g_BuildScripts[argv[i + 1]].m_script.c_str());
918 return 0;
921 else
923 cout << "Unknown option: " << s.c_str();
924 return -1;
926 }else if (!s.empty() && s[s.size() - 1] == ':')
928 for (int j = i; j < argc; j++)
930 s = argv[j];
931 if (s.find(' ') != string::npos && s[s.size() - 1] != ':')
933 s.insert(s.begin(), '"');
934 s.insert(s.end(), '"');
936 cmd.append(s);
937 if(j != (argc -1)) /* Don't add space at last arg */
938 cmd.append(" ");
940 break;
942 else
944 filename = s;
945 break;
949 signal(SIGINT, ctrl_c_handle);
951 if (deamon && shell)
953 printf("Error: -d -s Can't apply at the same time\n");
954 return -1;
957 if (deamon && dryrun)
959 printf("Error: -d -dry Can't apply at the same time\n");
960 return -1;
963 if (shell && dryrun)
965 printf("Error: -dry -s Can't apply at the same time\n");
966 return -1;
969 if (g_verbose)
971 printf("%sBuild in config:%s\n", g_vt_boldwhite, g_vt_default);
972 printf("\tPctl\t Chip\t\t Vid\t Pid\t BcdVersion\n");
973 printf("\t==================================================\n");
974 uuu_for_each_cfg(print_cfg, NULL);
976 if (!cmd_script.empty())
977 printf("\n%sRun built-in script:%s\n %s\n\n", g_vt_boldwhite, g_vt_default, cmd_script.c_str());
979 if (!shell)
980 cout << "Wait for Known USB Device Appear...";
982 print_usb_filter();
984 printf("\n");
986 else {
987 cout << "Wait for Known USB Device Appear...";
988 print_usb_filter();
989 cout << "\r";
990 cout << "\x1b[?25l";
991 cout.flush();
994 map<uint64_t, ShowNotify> nt_session;
996 uuu_register_notify_callback(progress, &nt_session);
999 if (!cmd.empty())
1001 ret = uuu_run_cmd(cmd.c_str(), dryrun);
1003 for (size_t i = 0; i < g_map_path_nt.size()+3; i++)
1004 printf("\n");
1005 if(ret)
1006 printf("\nError: %s\n", uuu_get_last_err_string());
1007 else
1008 printf("Okay\n");
1010 runshell(shell);
1011 return ret;
1014 if (!cmd_script.empty())
1015 ret = uuu_run_cmd_script(cmd_script.c_str(), dryrun);
1016 else
1017 ret = uuu_auto_detect_file(filename.c_str());
1019 if (ret)
1021 runshell(shell);
1023 cout << g_vt_red << "\nError: " << g_vt_default << uuu_get_last_err_string();
1024 return ret;
1027 if (uuu_wait_uuu_finish(deamon, dryrun))
1029 cout << g_vt_red << "\nError: " << g_vt_default << uuu_get_last_err_string();
1030 return -1;
1033 runshell(shell);
1035 /*Wait for the other thread exit, after send out CMD_DONE*/
1036 std::this_thread::sleep_for(std::chrono::milliseconds(100));
1037 return g_overall_status;