blob: e4cc58bd6ba987f149f4b980891b6e4dfc561ee6 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Charmonizer/Core/Util.h"
#include "Charmonizer/Core/ConfWriter.h"
#include "Charmonizer/Core/ConfWriterPython.h"
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Static vars. */
static struct {
FILE *fh;
} chaz_CWPython = { NULL };
static chaz_ConfWriter CWPython_conf_writer;
/* Open the charmony.py file handle.
*/
static void
chaz_ConfWriterPython_open_config_py(void);
static void
chaz_ConfWriterPython_clean_up(void);
static void
chaz_ConfWriterPython_vappend_conf(const char *fmt, va_list args);
static void
chaz_ConfWriterPython_add_def(const char *sym, const char *value);
static void
chaz_ConfWriterPython_add_global_def(const char *sym, const char *value);
static void
chaz_ConfWriterPython_add_typedef(const char *type, const char *alias);
static void
chaz_ConfWriterPython_add_global_typedef(const char *type, const char *alias);
static void
chaz_ConfWriterPython_add_sys_include(const char *header);
static void
chaz_ConfWriterPython_add_local_include(const char *header);
static void
chaz_ConfWriterPython_start_module(const char *module_name);
static void
chaz_ConfWriterPython_end_module(void);
void
chaz_ConfWriterPython_enable(void) {
CWPython_conf_writer.clean_up = chaz_ConfWriterPython_clean_up;
CWPython_conf_writer.vappend_conf = chaz_ConfWriterPython_vappend_conf;
CWPython_conf_writer.add_def = chaz_ConfWriterPython_add_def;
CWPython_conf_writer.add_global_def = chaz_ConfWriterPython_add_global_def;
CWPython_conf_writer.add_typedef = chaz_ConfWriterPython_add_typedef;
CWPython_conf_writer.add_global_typedef = chaz_ConfWriterPython_add_global_typedef;
CWPython_conf_writer.add_sys_include = chaz_ConfWriterPython_add_sys_include;
CWPython_conf_writer.add_local_include = chaz_ConfWriterPython_add_local_include;
CWPython_conf_writer.start_module = chaz_ConfWriterPython_start_module;
CWPython_conf_writer.end_module = chaz_ConfWriterPython_end_module;
chaz_ConfWriterPython_open_config_py();
chaz_ConfWriter_add_writer(&CWPython_conf_writer);
return;
}
static void
chaz_ConfWriterPython_open_config_py(void) {
/* Open the filehandle. */
chaz_CWPython.fh = fopen("charmony.py", "w+");
if (chaz_CWPython.fh == NULL) {
chaz_Util_die("Can't open 'charmony.py': %s", strerror(errno));
}
/* Start the module. */
fprintf(chaz_CWPython.fh,
"# Auto-generated by Charmonizer. \n"
"# DO NOT EDIT THIS FILE!!\n"
"\n"
"class Charmony(object):\n"
" @classmethod\n"
" def config(cls):\n"
" return cls.defs\n"
"\n"
" defs = {}\n"
"\n"
);
}
static void
chaz_ConfWriterPython_clean_up(void) {
/* No more code necessary to finish charmony.py, so just close. */
if (fclose(chaz_CWPython.fh)) {
chaz_Util_die("Couldn't close 'charmony.py': %s", strerror(errno));
}
}
static void
chaz_ConfWriterPython_vappend_conf(const char *fmt, va_list args) {
(void)fmt;
(void)args;
}
static char*
chaz_ConfWriterPython_quotify(const char *string, char *buf, size_t buf_size) {
char *quoted = buf;
/* Don't bother with NULL values here. */
if (!string) {
return NULL;
}
/* Allocate memory if necessary. */
{
const char *ptr;
size_t space = 3; /* Quotes plus NUL termination. */
for (ptr = string; *ptr; ptr++) {
if (*ptr == '\'' || *ptr == '\\') {
space += 2;
}
else {
space += 1;
}
}
if (space > buf_size) {
quoted = (char*)malloc(space);
}
}
/* Perform copying and escaping */
{
const char *ptr;
size_t pos = 0;
quoted[pos++] = '\'';
for (ptr = string; *ptr; ptr++) {
if (*ptr == '\'' || *ptr == '\\') {
quoted[pos++] = '\\';
}
quoted[pos++] = *ptr;
}
quoted[pos++] = '\'';
quoted[pos++] = '\0';
}
return quoted;
}
#define CFPYTHON_MAX_BUF 100
static void
chaz_ConfWriterPython_add_def(const char *sym, const char *value) {
char sym_buf[CFPYTHON_MAX_BUF + 1];
char value_buf[CFPYTHON_MAX_BUF + 1];
char *quoted_sym;
char *quoted_value;
/* Quote key. */
if (!sym) {
chaz_Util_die("Can't handle NULL key");
}
quoted_sym = chaz_ConfWriterPython_quotify(sym, sym_buf, CFPYTHON_MAX_BUF);
/* Quote value or use "None". */
if (!value) {
strcpy(value_buf, "None");
quoted_value = value_buf;
}
else {
quoted_value = chaz_ConfWriterPython_quotify(value, value_buf,
CFPYTHON_MAX_BUF);
}
fprintf(chaz_CWPython.fh, " defs[%s] = %s\n", quoted_sym, quoted_value);
if (quoted_sym != sym_buf) { free(quoted_sym); }
if (quoted_value != value_buf) { free(quoted_value); }
}
static void
chaz_ConfWriterPython_add_global_def(const char *sym, const char *value) {
(void)sym;
(void)value;
}
static void
chaz_ConfWriterPython_add_typedef(const char *type, const char *alias) {
(void)type;
(void)alias;
}
static void
chaz_ConfWriterPython_add_global_typedef(const char *type, const char *alias) {
(void)type;
(void)alias;
}
static void
chaz_ConfWriterPython_add_sys_include(const char *header) {
(void)header;
}
static void
chaz_ConfWriterPython_add_local_include(const char *header) {
(void)header;
}
static void
chaz_ConfWriterPython_start_module(const char *module_name) {
fprintf(chaz_CWPython.fh, " # %s\n", module_name);
}
static void
chaz_ConfWriterPython_end_module(void) {
fprintf(chaz_CWPython.fh, "\n");
}