OILS / pyext / fastfunc.c View on Github | oilshell.org

107 lines, 69 significant
1// Python wrapper for FANOS library in cpp/fanos_shared.h
2
3#include <assert.h>
4#include <stdarg.h> // va_list, etc.
5#include <stdio.h> // vfprintf
6#include <stdlib.h>
7
8#include "data_lang/j8.h" // CanOmitQuotes
9#include "data_lang/j8_libc.h"
10#include "data_lang/utf8_impls/bjoern_dfa.h"
11
12#include <Python.h>
13
14#if 0
15// Log messages to stderr.
16static void debug(const char* fmt, ...) {
17 va_list args;
18 va_start(args, fmt);
19 vfprintf(stderr, fmt, args);
20 va_end(args);
21 fprintf(stderr, "\n");
22}
23#endif
24
25static PyObject *
26func_J8EncodeString(PyObject *self, PyObject *args) {
27 j8_buf_t in;
28 int j8_fallback;
29
30 if (!PyArg_ParseTuple(args, "s#i", &(in.data), &(in.len), &j8_fallback)) {
31 return NULL;
32 }
33
34 j8_buf_t out;
35 J8EncodeString(in, &out, j8_fallback);
36
37 PyObject *ret = PyString_FromStringAndSize(out.data, out.len);
38 return ret;
39}
40
41static PyObject *
42func_ShellEncodeString(PyObject *self, PyObject *args) {
43 j8_buf_t in;
44 int ysh_fallback;
45
46 if (!PyArg_ParseTuple(args, "s#i", &(in.data), &(in.len), &ysh_fallback)) {
47 return NULL;
48 }
49
50 j8_buf_t out;
51 ShellEncodeString(in, &out, ysh_fallback);
52
53 PyObject *ret = PyString_FromStringAndSize(out.data, out.len);
54 return ret;
55}
56
57static PyObject *
58func_PartIsUtf8(PyObject *self, PyObject *args) {
59 j8_buf_t in;
60 int start;
61 int end;
62
63 if (!PyArg_ParseTuple(args, "s#ii", &(in.data), &(in.len), &start, &end)) {
64 return NULL;
65 }
66 // Bounds check for safety
67 assert(0 <= start);
68 assert(end <= in.len);
69
70 uint32_t codepoint;
71 uint32_t state = UTF8_ACCEPT;
72
73 for (int i = start; i < end; ++i) {
74 // This var or a static_cast<> is necessary. Should really change BigStr*
75 // to use unsigned type
76 unsigned char c = in.data[i];
77 decode(&state, &codepoint, c);
78 if (state == UTF8_REJECT) {
79 return PyBool_FromLong(0);
80 }
81 }
82
83 return PyBool_FromLong(state == UTF8_ACCEPT);
84}
85
86static PyObject *
87func_CanOmitQuotes(PyObject *self, PyObject *args) {
88 j8_buf_t in;
89 if (!PyArg_ParseTuple(args, "s#", &(in.data), &(in.len))) {
90 return NULL;
91 }
92 int result = CanOmitQuotes(in.data, in.len);
93 return PyBool_FromLong(result);
94}
95
96static PyMethodDef methods[] = {
97 {"J8EncodeString", func_J8EncodeString, METH_VARARGS, ""},
98 {"ShellEncodeString", func_ShellEncodeString, METH_VARARGS, ""},
99 {"PartIsUtf8", func_PartIsUtf8, METH_VARARGS, ""},
100 {"CanOmitQuotes", func_CanOmitQuotes, METH_VARARGS, ""},
101
102 {NULL, NULL},
103};
104
105void initfastfunc(void) {
106 Py_InitModule("fastfunc", methods);
107}