]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
29ad6f68 DL |
2 | /* |
3 | * clippy (CLI preparator in python) main executable | |
4 | * Copyright (C) 2016-2017 David Lamparter for NetDEF, Inc. | |
29ad6f68 DL |
5 | */ |
6 | ||
7 | #include "config.h" | |
8 | #include <Python.h> | |
9 | #include <string.h> | |
10 | #include <stdlib.h> | |
11 | #include <wchar.h> | |
12 | #include "getopt.h" | |
13 | ||
14 | #include "command_graph.h" | |
15 | #include "clippy.h" | |
16 | ||
17 | #if PY_MAJOR_VERSION >= 3 | |
18 | #define pychar wchar_t | |
19 | static wchar_t *wconv(const char *s) | |
20 | { | |
45ec351d | 21 | size_t outlen = s ? mbstowcs(NULL, s, 0) : 0; |
29ad6f68 | 22 | wchar_t *out = malloc((outlen + 1) * sizeof(wchar_t)); |
45ec351d | 23 | |
24 | if (outlen > 0) | |
25 | mbstowcs(out, s, outlen); | |
29ad6f68 DL |
26 | out[outlen] = 0; |
27 | return out; | |
28 | } | |
29 | #else | |
30 | #define pychar char | |
31 | #define wconv(x) x | |
32 | #endif | |
33 | ||
34 | int main(int argc, char **argv) | |
35 | { | |
36 | pychar **wargv; | |
37 | ||
38 | #if PY_VERSION_HEX >= 0x03040000 /* 3.4 */ | |
39 | Py_SetStandardStreamEncoding("UTF-8", NULL); | |
40 | #endif | |
0f307338 | 41 | wchar_t *name = wconv(argv[0]); |
4da4b9d4 | 42 | Py_SetProgramName(name); |
29ad6f68 DL |
43 | PyImport_AppendInittab("_clippy", command_py_init); |
44 | ||
45 | Py_Initialize(); | |
46 | ||
47 | wargv = malloc(argc * sizeof(pychar *)); | |
48 | for (int i = 1; i < argc; i++) | |
49 | wargv[i - 1] = wconv(argv[i]); | |
50 | PySys_SetArgv(argc - 1, wargv); | |
51 | ||
52 | const char *pyfile = argc > 1 ? argv[1] : NULL; | |
53 | FILE *fp; | |
54 | if (pyfile) { | |
55 | fp = fopen(pyfile, "r"); | |
56 | if (!fp) { | |
57 | fprintf(stderr, "%s: %s\n", pyfile, strerror(errno)); | |
f52aee04 DS |
58 | |
59 | free(name); | |
29ad6f68 DL |
60 | return 1; |
61 | } | |
62 | } else { | |
63 | fp = stdin; | |
64 | char *ver = strdup(Py_GetVersion()); | |
65 | char *cr = strchr(ver, '\n'); | |
66 | if (cr) | |
67 | *cr = ' '; | |
68 | fprintf(stderr, "clippy interactive shell\n(Python %s)\n", ver); | |
69 | free(ver); | |
d62a17ae | 70 | PyRun_SimpleString( |
71 | "import rlcompleter, readline\n" | |
72 | "readline.parse_and_bind('tab: complete')"); | |
29ad6f68 DL |
73 | } |
74 | ||
75 | if (PyRun_AnyFile(fp, pyfile)) { | |
76 | if (PyErr_Occurred()) | |
77 | PyErr_Print(); | |
f52aee04 DS |
78 | |
79 | free(name); | |
29ad6f68 DL |
80 | return 1; |
81 | } | |
d62a17ae | 82 | Py_Finalize(); |
29ad6f68 DL |
83 | |
84 | #if PY_MAJOR_VERSION >= 3 | |
85 | for (int i = 1; i < argc; i++) | |
86 | free(wargv[i - 1]); | |
87 | #endif | |
4da4b9d4 | 88 | free(name); |
29ad6f68 DL |
89 | free(wargv); |
90 | return 0; | |
91 | } | |
92 | ||
93 | /* and now for the ugly part... provide simplified logging functions so we | |
94 | * don't need to link libzebra (which would be a circular build dep) */ | |
95 | ||
29ad6f68 | 96 | #include "log.h" |
29ad6f68 | 97 | |
0f9de11a | 98 | PRINTFRR(3, 0) |
131879fb DL |
99 | void vzlogx(const struct xref_logmsg *xref, int prio, |
100 | const char *format, va_list args) | |
0bdeb5e5 DL |
101 | { |
102 | vfprintf(stderr, format, args); | |
103 | fputs("\n", stderr); | |
104 | } | |
29ad6f68 | 105 | |
d62a17ae | 106 | void memory_oom(size_t size, const char *name) |
29ad6f68 DL |
107 | { |
108 | abort(); | |
109 | } |