idf_main.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <windows.h>
  7. #include <shlwapi.h>
  8. #include <strsafe.h>
  9. #include <stdarg.h>
  10. #define LINESIZE 1024
  11. #ifdef __GNUC__
  12. static void fail(LPCSTR message, ...) __attribute__((noreturn));
  13. #else
  14. __declspec(noreturn) static void fail(LPCSTR message, ...);
  15. #endif
  16. static void fail(LPCSTR message, ...)
  17. {
  18. DWORD written;
  19. char msg[LINESIZE];
  20. va_list args = NULL;
  21. va_start(args, message);
  22. StringCchVPrintfA(msg, sizeof(msg), message, args);
  23. WriteFile(GetStdHandle(STD_ERROR_HANDLE), message, lstrlen(msg), &written, NULL);
  24. ExitProcess(1);
  25. }
  26. BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
  27. {
  28. switch (fdwCtrlType) {
  29. // Handle the CTRL-C signal.
  30. case CTRL_C_EVENT:
  31. return TRUE;
  32. default:
  33. return FALSE;
  34. }
  35. }
  36. int main(int argc, LPTSTR argv[])
  37. {
  38. /* Print the version of this wrapper tool, but only if invoked as "idf.exe".
  39. * "idf -v" will invoke idf.py as expected.
  40. */
  41. LPCTSTR cmdname = PathFindFileName(argv[0]);
  42. int cmdname_length = strlen(cmdname);
  43. if (argc == 2 &&
  44. cmdname_length > 4 &&
  45. StrCmp(cmdname + cmdname_length - 4, TEXT(".exe")) == 0 &&
  46. (StrCmp(argv[1], TEXT("--version")) == 0 ||
  47. StrCmp(argv[1], TEXT("-v")) == 0)) {
  48. LPCSTR msg = VERSION "\n";
  49. DWORD written;
  50. WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msg, lstrlen(msg), &written, NULL);
  51. return 0;
  52. }
  53. LPCTSTR idfpy_script_name = TEXT("idf.py");
  54. /* Get IDF_PATH */
  55. TCHAR idf_path[LINESIZE] = { 0 };
  56. if (GetEnvironmentVariable(TEXT("IDF_PATH"), idf_path, sizeof(idf_path)) == 0) {
  57. DWORD err = GetLastError();
  58. if (err == ERROR_ENVVAR_NOT_FOUND) {
  59. fail("IDF_PATH environment variable needs to be set to use this tool\n");
  60. } else {
  61. fail("Unknown error (%u)\n", err);
  62. }
  63. }
  64. /* Prepare the command line: python.exe "%IDF_PATH%\\tools\idf.py" <rest of the args> */
  65. TCHAR cmdline[LINESIZE] = { 0 };
  66. StringCchCat(cmdline, sizeof(cmdline), TEXT("python.exe \""));
  67. StringCchCat(cmdline, sizeof(cmdline), idf_path);
  68. StringCchCat(cmdline, sizeof(cmdline), TEXT("\\tools\\"));
  69. StringCchCat(cmdline, sizeof(cmdline), idfpy_script_name);
  70. StringCchCat(cmdline, sizeof(cmdline), TEXT("\" "));
  71. for (int i = 1; i < argc; ++i) {
  72. StringCchCat(cmdline, sizeof(cmdline), argv[i]);
  73. StringCchCat(cmdline, sizeof(cmdline), TEXT(" "));
  74. }
  75. SetEnvironmentVariable(TEXT("IDF_PY_PROGRAM_NAME"), idfpy_script_name);
  76. // Add processing for Ctrl+C
  77. SetConsoleCtrlHandler(CtrlHandler, TRUE);
  78. /* Reuse the standard streams of this process */
  79. STARTUPINFO start_info = {
  80. .cb = sizeof(STARTUPINFO),
  81. .hStdError = GetStdHandle(STD_ERROR_HANDLE),
  82. .hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE),
  83. .hStdInput = GetStdHandle(STD_INPUT_HANDLE),
  84. .dwFlags = STARTF_USESTDHANDLES
  85. };
  86. /* Run the child process */
  87. PROCESS_INFORMATION child_process;
  88. if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &start_info, &child_process)) {
  89. DWORD err = GetLastError();
  90. if (err == ERROR_FILE_NOT_FOUND) {
  91. fail("Can not find Python\n");
  92. } else {
  93. fail("Unknown error (%u)\n", err);
  94. }
  95. }
  96. /* Wait for it to complete */
  97. WaitForSingleObject(child_process.hProcess, INFINITE);
  98. /* Return with the exit code of the child process */
  99. DWORD exitcode;
  100. if (!GetExitCodeProcess(child_process.hProcess, &exitcode)) {
  101. fail("Couldn't get the exit code (%u)\n", GetLastError());
  102. }
  103. return exitcode;
  104. }