Skip to content
Extraits de code Groupes Projets
_unitex.cpp 21,9 ko
Newer Older
  • Learn to ignore specific revisions
  • /*
     * NOTE: some parts of this file are an adaptation of the 'fr_umlv_unitex_jni_UnitexJni.cpp' file
     *       which is included in the Unitex source distribution.
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
     *
    
    #include <Python.h>
    
    #include "AbstractFilePlugCallback.h"
    #include "UnitexTool.h"
    #include "UnitexLibIO.h"
    
    #if defined(UNITEX_HAVING_PERSISTANCE_INTERFACE) && (!(defined(UNITEX_PREVENT_USING_PERSISTANCE_INTERFACE)))
    #include "PersistenceInterface.h"
    #endif
    
    #ifdef HAS_UNITEX_NAMESPACE
    using namespace unitex;
    #endif
    
    
    static char unitex_docstring[] = "\
    This module provides some usefull C++ functions to work with the Unitex\n\
    library.\
    ";
    
    
    
    
    /************************
     * UNITEX TOOL FUNCTION *
     ************************/
    
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_tool' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_tool_docstring[] = "\
    This function launches an Unitex command.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the Unitex command.\n\n\
    *Return [bool]:*\n\n\
      **True** if the command succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_tool(PyObject *self, PyObject *args);
    
    PyObject *unitex_tool(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *command;
        if (!PyArg_ParseTuple(args, "s", &command))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = UnitexTool_public_run_string(command);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_False: Py_True);
    
    }
    
    
    
    /*************************
     * PERSISTENCE FUNCTIONS *
     *************************/
    
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_load_persistent_dictionary' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_load_persistent_dictionary_docstring[] = "\
    This function loads a dictionary in the persistent space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the dictionary path.\n\n\
    *Return [str]:*\n\n\
      The persistent file path (derived from filename but not strictly\n\
      identical, depending of implementation). This path must be used by\n\
      the unitex tools and the 'free_persistent_dictionary' function.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_load_persistent_dictionary(PyObject *self, PyObject *args);
    
    PyObject *unitex_load_persistent_dictionary(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
        PyObject *result = NULL;
    
    pat's avatar
    pat a validé
        size_t length = strlen(path)+0x200;
    
    pat's avatar
    pat a validé
        char *persistent_path = (char*)malloc(length+1);
        if (persistent_path == NULL) {
            return NULL;
        }
    
    pat's avatar
    pat a validé
        if (persistence_public_load_dictionary(path, persistent_path, length)) {
            result = Py_BuildValue("s", persistent_path);
        }
        free(persistent_path);
    
    pat's avatar
    pat a validé
        return result;
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_load_persistent_fst2' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_load_persistent_fst2_docstring[] = "\
    This function loads a grammar in the persistent space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the fst2 path.\n\n\
    *Return [str]:*\n\n\
      The persistent file path (derived from filename but not strictly\n\
      identical, depending of implementation). This path must be used by\n\
      the unitex tools and the 'free_persistent_fst2' function.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_load_persistent_fst2(PyObject *self, PyObject *args);
    
    PyObject *unitex_load_persistent_fst2(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
        PyObject *result = NULL;
    
    pat's avatar
    pat a validé
        size_t length = strlen(path)+0x200;
    
    pat's avatar
    pat a validé
        char *persistent_path = (char*)malloc(length+1);
        if (persistent_path == NULL) {
            return NULL;
        }
    
    pat's avatar
    pat a validé
        if (persistence_public_load_fst2(path, persistent_path, length)) {
            result = Py_BuildValue("s", persistent_path);
        }
        free(persistent_path);
    
    pat's avatar
    pat a validé
        return result;
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_load_persistent_alphabet' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_load_persistent_alphabet_docstring[] = "\
    This function loads an alphabet in the persistent space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the alphabet path.\n\n\
    *Return [str]:*\n\n\
      The persistent file path (derived from filename but not strictly\n\
      identical, depending of implementation). This path must be used by\n\
      the unitex tools and the 'free_persistent_alphabet' function.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_load_persistent_alphabet(PyObject *self, PyObject *args);
    
    PyObject *unitex_load_persistent_alphabet(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
        PyObject *result = NULL;
    
    pat's avatar
    pat a validé
        size_t length = strlen(path)+0x200;
    
    pat's avatar
    pat a validé
        char *persistent_path = (char*)malloc(length+1);
        if (persistent_path == NULL) {
            return NULL;
        }
    
    pat's avatar
    pat a validé
        if (persistence_public_load_alphabet(path, persistent_path, length)) {
            result = Py_BuildValue("s", persistent_path);
        }
        free(persistent_path);
    
    pat's avatar
    pat a validé
        return result;
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_free_persistent_dictionary' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_free_persistent_dictionary_docstring[] = "\
    This function unloads a dictionary from persistent space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the persistent file path returned by the\n\
      'load_persistent_dictionary' function.\n\n\
    *No return.*\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_free_persistent_dictionary(PyObject *self, PyObject *args);
    
    PyObject *unitex_free_persistent_dictionary(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        persistence_public_unload_dictionary(path);
    
    pat's avatar
    pat a validé
        Py_RETURN_NONE;
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_free_persistent_fst2' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_free_persistent_fst2_docstring[] = "\
    This function unloads a grammar from persistent space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the persistent file path returned by the\n\
      'load_persistent_fst2' function.\n\n\
    *No return.*\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_free_persistent_fst2(PyObject *self, PyObject *args);
    
    PyObject *unitex_free_persistent_fst2(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        persistence_public_unload_fst2(path);
    
    pat's avatar
    pat a validé
        Py_RETURN_NONE;
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_free_persistent_alphabet' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_free_persistent_alphabet_docstring[] = "\
    This function unloads an alphabet from persistent space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the persistent file path returned by the\n\
      'load_persistent_alphabet' function.\n\n\
    *No return.*\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_free_persistent_alphabet(PyObject *self, PyObject *args);
    
    PyObject *unitex_free_persistent_alphabet(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        persistence_public_unload_alphabet(path);
    
    pat's avatar
    pat a validé
        Py_RETURN_NONE;
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_is_persistent_dictionary' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_is_persistent_dictionary_docstring[] = "\
    This function checks if a dictionary path points to the persistent\n\
    space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the file path to check.\n\n\
    *Return [bool]:*\n\n\
      **True** if the dictionary is persistent, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_is_persistent_dictionary(PyObject *self, PyObject *args);
    
    PyObject *unitex_is_persistent_dictionary(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = persistence_public_is_persisted_dictionary_filename(path);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_True: Py_False);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_is_persistent_fst2' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_is_persistent_fst2_docstring[] = "\
    This function checks if a grammar path points to the persistent\n\
    space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the file path to check.\n\n\
    *Return [bool]:*\n\n\
      **True** if the dictionary is persistent, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_is_persistent_fst2(PyObject *self, PyObject *args);
    
    PyObject *unitex_is_persistent_fst2(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = persistence_public_is_persisted_fst2_filename(path);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_True: Py_False);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_is_persistent_alphabet' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_is_persistent_alphabet_docstring[] = "\
    This function checks if an alphabet path points to the persistent\n\
    space.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the file path to check.\n\n\
    *Return [bool]:*\n\n\
      **True** if the dictionary is persistent, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_is_persistent_alphabet(PyObject *self, PyObject *args);
    
    PyObject *unitex_is_persistent_alphabet(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = persistence_public_is_persisted_alphabet_filename(path);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_True: Py_False);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_enable_stdout' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_enable_stdout_docstring[] = "\
    This function enables Unitex standard output. This is the default\n\
    but should be used for debug purposes only.\n\n\
    
    *No argument.*\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_enable_stdout(PyObject *self, PyObject *noarg);
    
    PyObject *unitex_enable_stdout(PyObject *self, PyObject *noarg) {
    
    pat's avatar
    pat a validé
        enum stdwrite_kind swk = stdwrite_kind_out;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = SetStdWriteCB(swk, 0, NULL, NULL);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_True: Py_False);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_enable_stderr' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_enable_stderr_docstring[] = "\
    This function enables Unitex error output. This is the default\n\
    but should be used for debug purposes only.\n\n\
    
    *No argument.*\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_enable_stderr(PyObject *self, PyObject *noarg);
    
    PyObject *unitex_enable_stderr(PyObject *self, PyObject *noarg) {
    
    pat's avatar
    pat a validé
        enum stdwrite_kind swk = stdwrite_kind_err;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = SetStdWriteCB(swk, 0, NULL, NULL);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_True: Py_False);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_disable_stdout' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_disable_stdout_docstring[] = "\
    This function disables Unitex standard output to ensure multithread\n\
    output consistency (i.e. avoid output mixing between threads) and to\n\
    improve performances.\n\n\
    
    *No argument.*\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_disable_stdout(PyObject *self, PyObject *noarg);
    
    PyObject *unitex_disable_stdout(PyObject *self, PyObject *noarg) {
    
    pat's avatar
    pat a validé
        enum stdwrite_kind swk = stdwrite_kind_out;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = SetStdWriteCB(swk, 1, NULL, NULL);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_True: Py_False);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_disable_stderr' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_disable_stderr_docstring[] = "\
    This function disables Unitex error output to ensure multithread\n\
    output consistency (i.e. avoid output mixing between threads) and to\n\
    improve performances.\n\n\
    
    *No argument.*\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_disable_stderr(PyObject *self, PyObject *noarg);
    
    PyObject *unitex_disable_stderr(PyObject *self, PyObject *noarg) {
    
    pat's avatar
    pat a validé
        enum stdwrite_kind swk = stdwrite_kind_err;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = SetStdWriteCB(swk, 1, NULL, NULL);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_True: Py_False);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_cp' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_cp_docstring[] = "\
    This function copies a file. Both pathes can be on the virtual\n\
    filesystem or the disk filesystem. Therefore, this function can be\n\
    used to virtualize a file or to dump a virtual file.\n\n\
    
    *Positional arguments (length: 2):*\n\n\
    - **0 [str]** -- the source file path.\n\
    - **1 [str]** -- the target file path.\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_cp(PyObject *self, PyObject *args);
    
    PyObject *unitex_cp(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *source_path;
        char *target_path;
        if (!PyArg_ParseTuple(args, "ss", &source_path, &target_path))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = CopyUnitexFile(source_path, target_path);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_False: Py_True);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_rm' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_rm_docstring[] = "\
    This function removes a file. The path can be on the virtual\n\
    filesystem or the disk filesystem.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the file path.\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_rm(PyObject *self, PyObject *args);
    
    PyObject *unitex_rm(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = RemoveUnitexFile(path);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_False: Py_True);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_mv' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_mv_docstring[] = "\
    This function moves/renames a file. Both pathes can be on the\n\
    virtual filesystem or the disk filesystem.\n\n\
    
    *Positional arguments (length: 2):*\n\n\
    - **0 [str]** -- the current file path.\n\
    - **1 [str]** -- the new file path.\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_mv(PyObject *self, PyObject *args);
    
    PyObject *unitex_mv(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *old_path;
        char *new_path;
        if (!PyArg_ParseTuple(args, "ss", &old_path, &new_path))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = RenameUnitexFile(old_path, new_path);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_False: Py_True);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_mkdir' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_mkdir_docstring[] = "\
    This function creates a directory on the disk.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the directory path.\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_mkdir(PyObject *self, PyObject *args);
    
    PyObject *unitex_mkdir(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = CreateUnitexFolder(path);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_False: Py_True);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_rmdir' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_rmdir_docstring[] = "\
    This function removes a directory from the disk.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the directory path.\n\n\
    *Return [bool]:*\n\n\
      **True** if it succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_rmdir(PyObject *self, PyObject *args);
    
    PyObject *unitex_rmdir(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = RemoveUnitexFolder(path);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_False: Py_True);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_ls' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_ls_docstring[] = "\
    This function lists (disk or virtual) directory contents.\n\n\
    
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the directory path.\n\n\
    *Return [list(str)]:*\n\n\
      The function returns a list of files (not directories) if the\n\
      directory is not empty and an empty list otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_ls(PyObject *self, PyObject *args);
    
    PyObject *unitex_ls(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
    
        char **_file_list = GetUnitexFileList(path);
        if (_file_list==NULL)
            return PyList_New(0);
    
        unsigned int size = 0;
        while ((*(_file_list + size))!=NULL) {
            size ++;
        }
    
        PyObject *file_list = PyList_New(size);
        for (unsigned int i = 0; i != size; ++i) {
            PyList_SET_ITEM(file_list, i, PyUnicode_FromString(_file_list[i]));
        }
    
        char **_file_list_walk=_file_list;
        while ((*_file_list_walk)!=NULL) {
            free(*_file_list_walk);
            _file_list_walk++;
        }
        free(_file_list);
    
        return file_list;
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_read_file' function (UTF-8 encoding only)*/
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_read_file_docstring[] = "\
    This function read a file from the disk or from the virtual filesystem.\n\
    
    **WARNING: The file must be encoded in UTF-8.**\n\n\
    *Positional arguments (length: 1):*\n\n\
    - **0 [str]** -- the file path.\n\n\
    *Return [str]:*\n\n\
      The function returns an unicode string.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_read_file(PyObject *self, PyObject *args);
    
    PyObject *unitex_read_file(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        if (!PyArg_ParseTuple(args, "s", &path))
            return NULL;
        PyObject *content = NULL;
    
    
        UNITEXFILEMAPPED *amf;
        const void *buffer;
        size_t file_size;
    
    
    pat's avatar
    pat a validé
        GetUnitexFileReadBuffer(path, &amf, &buffer, &file_size);
        const unsigned char* bufchar = (const unsigned char*)buffer;
    
    pat's avatar
    pat a validé
        size_t bom_size = 0;
    
        if (file_size>2) {
            if (((*(bufchar))==0xef) && ((*(bufchar+1))==0xbb) && ((*(bufchar+2))==0xbf)) {
                bom_size = 3;
            }
    
    pat's avatar
    pat a validé
        }
    
    pat's avatar
    pat a validé
        char* _content = (char*)malloc(file_size+1);
        memcpy(_content, bufchar+bom_size, file_size-bom_size);
    
    pat's avatar
    pat a validé
        *(_content+file_size-bom_size) = '\0';
    
    pat's avatar
    pat a validé
        content = PyUnicode_FromString(_content);
        free(_content);
    
    
        CloseUnitexFileReadBuffer(amf, buffer, file_size);
    
        return content;
    }
    
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_write_file' function (UTF-8 encoding only)*/
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_write_file_docstring[] = "\
    This function writes a file on the disk or on the virtual filesystem.\n\
    
    **WARNING: The file will be encoded in UTF-8.**\n\n\
    *Positional arguments (length: 3):*\n\n\
    - **0 [str]** -- the file path.\n\
    - **1 [unicode]** -- the file content.\n\
    - **2 [int]** -- 1 to writes the UTF-8 bom, 0 otherwise.\n\n\
    *Return [bool]:*\n\n\
      **True** if the function succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_write_file(PyObject *self, PyObject *args);
    
    PyObject *unitex_write_file(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        PyObject *ustring;
        int *use_bom;
        if (!PyArg_ParseTuple(args, "sUi", &path, &ustring, &use_bom))
            return NULL;
    
    pat's avatar
    pat a validé
        PyObject *bytes;
        char *content;
        Py_ssize_t length;
    
    pat's avatar
    pat a validé
        bytes = PyUnicode_AsUTF8String(ustring);
        PyBytes_AsStringAndSize(bytes, &content, &length);
    
    pat's avatar
    pat a validé
        const unsigned char UTF8BOM[3] = { 0xef,0xbb,0xbf };
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = WriteUnitexFile(path, UTF8BOM, use_bom ? 3:0, content, length);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_False: Py_True);
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    /* 'unitex_append_to_file' function */
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    static char unitex_append_to_file_docstring[] = "\
    This function writes at the end of an existing file (virtual or not).\n\
    
    **WARNING: The file must be encoded in UTF-8.**\n\n\
    *Positional arguments (length: 2):*\n\n\
    - **0 [str]** -- the file path.\n\
    - **1 [unicode]** -- the file content.\n\n\
    *Return [bool]:*\n\n\
      **True** if the function succeeds, **False** otherwise.\
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    ";
    
    static PyObject *unitex_append_to_file(PyObject *self, PyObject *args);
    
    PyObject *unitex_append_to_file(PyObject *self, PyObject *args) {
    
    pat's avatar
    pat a validé
        char *path;
        PyObject *ustring;
        if (!PyArg_ParseTuple(args, "sU", &path, &ustring))
            return NULL;
    
    pat's avatar
    pat a validé
        PyObject *bytes;
        char *content;
        Py_ssize_t length;
    
    pat's avatar
    pat a validé
        bytes = PyUnicode_AsUTF8String(ustring);
        PyBytes_AsStringAndSize(bytes, &content, &length);
    
    pat's avatar
    pat a validé
        unsigned int ret;
        ret = AppendUnitexFile(path, content, length);
    
    pat's avatar
    pat a validé
        return Py_BuildValue("O", ret ? Py_False: Py_True);
    
    static PyMethodDef unitex_methods[] = {
    
    pat's avatar
    pat a validé
        /* Unitex Tool function */
        {"unitex_tool", unitex_tool, METH_VARARGS, unitex_tool_docstring},
    
        /* Persistence functions */
        {"unitex_load_persistent_dictionary", unitex_load_persistent_dictionary, METH_VARARGS, unitex_load_persistent_dictionary_docstring},
        {"unitex_load_persistent_fst2", unitex_load_persistent_fst2, METH_VARARGS, unitex_load_persistent_fst2_docstring},
        {"unitex_load_persistent_alphabet", unitex_load_persistent_alphabet, METH_VARARGS, unitex_load_persistent_alphabet_docstring},
    
        {"unitex_free_persistent_dictionary", unitex_free_persistent_dictionary, METH_VARARGS, unitex_free_persistent_dictionary_docstring},
        {"unitex_free_persistent_fst2", unitex_free_persistent_fst2, METH_VARARGS, unitex_free_persistent_fst2_docstring},
        {"unitex_free_persistent_alphabet", unitex_free_persistent_alphabet, METH_VARARGS, unitex_free_persistent_alphabet_docstring},
    
        {"unitex_is_persistent_dictionary", unitex_is_persistent_dictionary, METH_VARARGS, unitex_is_persistent_dictionary_docstring},
        {"unitex_is_persistent_fst2", unitex_is_persistent_fst2, METH_VARARGS, unitex_is_persistent_fst2_docstring},
        {"unitex_is_persistent_alphabet", unitex_is_persistent_alphabet, METH_VARARGS, unitex_is_persistent_alphabet_docstring},
    
        /* I/O functions */
        {"unitex_enable_stdout", unitex_enable_stdout, METH_NOARGS, unitex_enable_stdout_docstring},
        {"unitex_disable_stdout", unitex_disable_stdout, METH_NOARGS, unitex_disable_stdout_docstring},
        {"unitex_enable_stderr", unitex_enable_stderr, METH_NOARGS, unitex_enable_stderr_docstring},
        {"unitex_disable_stderr", unitex_disable_stderr, METH_NOARGS, unitex_disable_stderr_docstring},
    
        {"unitex_cp", unitex_cp, METH_VARARGS, unitex_cp_docstring},
        {"unitex_rm", unitex_rm, METH_VARARGS, unitex_rm_docstring},
        {"unitex_mv", unitex_mv, METH_VARARGS, unitex_mv_docstring},
        {"unitex_mkdir", unitex_mkdir, METH_VARARGS, unitex_mkdir_docstring},
        {"unitex_rmdir", unitex_rmdir, METH_VARARGS, unitex_rmdir_docstring},
        {"unitex_ls", unitex_ls, METH_VARARGS, unitex_ls_docstring},
    
        {"unitex_read_file", unitex_read_file, METH_VARARGS, unitex_read_file_docstring},
        {"unitex_write_file", unitex_write_file, METH_VARARGS, unitex_write_file_docstring},
        {"unitex_append_to_file", unitex_append_to_file, METH_VARARGS, unitex_append_to_file_docstring},
    
        {NULL, NULL, 0, NULL}
    
    #if PY_MAJOR_VERSION >= 3
    
    static struct PyModuleDef unitex_module_def = {
    
    pat's avatar
    pat a validé
        PyModuleDef_HEAD_INIT,
        "_unitex",
        unitex_docstring,
        -1,
        unitex_methods
    
    };
    
    PyMODINIT_FUNC PyInit__unitex(void) {
    
    pat's avatar
    pat a validé
        PyObject *module = PyModule_Create(&unitex_module_def);
    
    pat's avatar
    pat a validé
        if (module == NULL)
            return NULL;
        return module;
    
    Patrick Watrin's avatar
    Patrick Watrin a validé
    PyMODINIT_FUNC init_unitex(void) {
    
    pat's avatar
    pat a validé
        PyObject *module = Py_InitModule3("_unitex", unitex_methods, unitex_docstring);
    
    pat's avatar
    pat a validé
        if (module == NULL)
            return;