]> git.proxmox.com Git - mirror_frr.git/blob - lib/clippy.c
Merge remote-tracking branch 'origin/stable/3.0'
[mirror_frr.git] / lib / clippy.c
1 /*
2 * clippy (CLI preparator in python) main executable
3 * Copyright (C) 2016-2017 David Lamparter for NetDEF, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include "config.h"
21 #include <Python.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <wchar.h>
25 #include "getopt.h"
26
27 #include "command_graph.h"
28 #include "clippy.h"
29
30 #if PY_MAJOR_VERSION >= 3
31 #define pychar wchar_t
32 static wchar_t *wconv(const char *s)
33 {
34 size_t outlen = mbstowcs(NULL, s, 0);
35 wchar_t *out = malloc((outlen + 1) * sizeof(wchar_t));
36 mbstowcs(out, s, outlen + 1);
37 out[outlen] = 0;
38 return out;
39 }
40 #else
41 #define pychar char
42 #define wconv(x) x
43 #endif
44
45 int main(int argc, char **argv)
46 {
47 pychar **wargv;
48
49 #if PY_VERSION_HEX >= 0x03040000 /* 3.4 */
50 Py_SetStandardStreamEncoding("UTF-8", NULL);
51 #endif
52 Py_SetProgramName(wconv(argv[0]));
53 PyImport_AppendInittab("_clippy", command_py_init);
54
55 Py_Initialize();
56
57 wargv = malloc(argc * sizeof(pychar *));
58 for (int i = 1; i < argc; i++)
59 wargv[i - 1] = wconv(argv[i]);
60 PySys_SetArgv(argc - 1, wargv);
61
62 const char *pyfile = argc > 1 ? argv[1] : NULL;
63 FILE *fp;
64 if (pyfile) {
65 fp = fopen(pyfile, "r");
66 if (!fp) {
67 fprintf(stderr, "%s: %s\n", pyfile, strerror(errno));
68 return 1;
69 }
70 } else {
71 fp = stdin;
72 char *ver = strdup(Py_GetVersion());
73 char *cr = strchr(ver, '\n');
74 if (cr)
75 *cr = ' ';
76 fprintf(stderr, "clippy interactive shell\n(Python %s)\n", ver);
77 free(ver);
78 PyRun_SimpleString("import rlcompleter, readline\n"
79 "readline.parse_and_bind('tab: complete')");
80 }
81
82 if (PyRun_AnyFile(fp, pyfile)) {
83 if (PyErr_Occurred())
84 PyErr_Print();
85 else
86 printf("unknown python failure (?)\n");
87 return 1;
88 }
89 Py_Finalize();
90
91 #if PY_MAJOR_VERSION >= 3
92 for (int i = 1; i < argc; i++)
93 free(wargv[i - 1]);
94 #endif
95 free(wargv);
96 return 0;
97 }
98
99 /* and now for the ugly part... provide simplified logging functions so we
100 * don't need to link libzebra (which would be a circular build dep) */
101
102 #ifdef __ASSERT_FUNCTION
103 #undef __ASSERT_FUNCTION
104 #endif
105
106 #include "log.h"
107 #include "zassert.h"
108
109 #define ZLOG_FUNC(FUNCNAME) \
110 void FUNCNAME(const char *format, ...) \
111 { \
112 va_list args; \
113 va_start(args, format); \
114 vfprintf (stderr, format, args); \
115 fputs ("\n", stderr); \
116 va_end(args); \
117 }
118
119 ZLOG_FUNC(zlog_err)
120 ZLOG_FUNC(zlog_warn)
121 ZLOG_FUNC(zlog_info)
122 ZLOG_FUNC(zlog_notice)
123 ZLOG_FUNC(zlog_debug)
124
125 void
126 _zlog_assert_failed (const char *assertion, const char *file,
127 unsigned int line, const char *function)
128 {
129 fprintf(stderr, "Assertion `%s' failed in file %s, line %u, function %s",
130 assertion, file, line, (function ? function : "?"));
131 abort();
132 }
133
134 void memory_oom (size_t size, const char *name)
135 {
136 abort();
137 }