geneet/geneet.py

1116 lines
33 KiB
Python
Executable File

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# install pyparsing with: easy_install pyparsing
#
# eet.py
# Creates all the C boilerplate to use with the EET library.
#
# Author: Leandro A. F. Pereira <leandro@profusion.mobi>
# Copyright (C) 2010 ProFUSION Embedded Systems
# Licensed under the same terms as EET itself; see COPYING for
# details.
#
from pyparsing import *
import os
import string
import sys
identifier = Word(string.letters + "_")
digits = Word(string.digits)
default_value = Keyword('default').suppress() + QuotedString(quoteChar = '"', endQuoteChar = '"')
enum = ZeroOrMore(identifier + Literal(',').suppress()) + identifier
type = Keyword('str') + Optional(default_value) | \
Keyword('int') | \
Keyword('uint') | \
Keyword('float') | \
Keyword('double') | \
Keyword('char') | \
Keyword('uchar') | \
Keyword('enum') + Keyword('of').suppress() + enum | \
Keyword('image') + (Keyword('raw') | (Keyword('compress') + digits) | Keyword('lossy') + digits) | \
Keyword('list') + Keyword('of').suppress() + identifier | \
Keyword('hash') + Keyword('of').suppress() + identifier + Keyword('by').suppress() + identifier | \
Keyword('pointer') + Keyword('to').suppress() + identifier
definition = Group(identifier + \
Literal(':').suppress() + \
type + \
Optional(Keyword('noencode')) + \
Literal(';').suppress())
block = OneOrMore( \
Group(identifier + \
Literal('{').suppress() + \
Group(OneOrMore(definition)) + \
Literal('}').suppress()) + \
Optional(Keyword(';').suppress()))
block.ignore(cppStyleComment)
EINA_HASH_FUNCTIONS = {
"str" : "eina_hash_stringshared_new",
"int" : "eina_hash_int32_new",
"enum" : "eina_hash_int32_new",
"uint" : "eina_hash_int32_new",
"char" : "eina_hash_int32_new",
"uchar" : "eina_hash_int32_new",
"image" : "eina_hash_pointer_new",
}
FIELD_CONVERTER = {
"str" : "const char *",
"int" : "int",
"uint" : "unsigned int",
"float" : "float",
"double" : "double",
"list" : "Eina_List *",
"hash" : "Eina_Hash *",
"char" : "char",
"uchar" : "unsigned char",
"image" : "Evas_Object *",
"enum" : "unsigned int",
}
FIELD_CONVERTER_EET = {
"str" : "EET_T_STRING",
"int" : "EET_T_INT",
"uint" : "EET_T_UINT",
"float" : "EET_T_FLOAT",
"double" : "EET_T_DOUBLE",
"char" : "EET_T_CHAR",
"uchar" : "EET_T_UCHAR",
"enum" : "EET_T_UINT",
}
__images = set()
__deps = set()
__structs = {}
__subtypes = {}
def check(base_name, parsed_block):
blocks = set()
for name, fields in parsed_block:
if name in blocks:
raise NameError('Block %s already defined' % name)
blocks.add(name)
for field in fields:
if field[1] in ('list', 'hash', 'pointer'):
if not field[2] in blocks:
raise NameError('Block %s is not defined' % field[2])
__deps.add((name, field[2], field[0]))
for block in blocks:
if base_name.lower() == block.lower():
raise NameError('Block %s has the same name as the output file' % base_name)
def _write_headers(header, impl):
print >> header, "/* This file has been automatically generated by geneet.py */"
print >> header, "/* DO NOT MODIFY */\n"
print >> impl, "/* This file has been automatically generated by geneet.py */"
print >> impl, "/* DO NOT MODIFY */\n"
def _write_includes(parsed_block, base_name, header, impl):
print >> impl, """#include <limits.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "%s"
""" % header.name
print >> header, """#ifndef __%s_H__
#define __%s_H__
#include <Eina.h>
#include <Eet.h>""" % (
base_name.upper(),
base_name.upper()
)
if any(field[1] == 'image' for name, fields in parsed_block for field in fields):
print >> header, "#include <Evas.h>"
print >> header, ""
def _write_structs(parsed_block, header, impl):
for name, fields in parsed_block:
__structs[name] = {}
__subtypes[name] = {}
print >> impl, """struct _%s {""" % name
for field in fields:
__structs[name][field[0]] = field[1]
if field[1] == 'hash':
__subtypes[name][field[0]] = (field[2], field[3])
elif field[1] == 'list':
__subtypes[name][field[0]] = (field[2], None)
if field[1] == 'enum':
print >> impl, " %s_%s %s;" % (name, field[0].title(), field[0])
elif field[1] == 'pointer':
print >> impl, " %s *%s;" % (field[2], field[2].lower())
else:
print >> impl, " %s %s;" % (FIELD_CONVERTER[field[1]], field[0])
if field[1] == 'image':
print >> impl, " unsigned int %s__id;" % field[0]
if not any(dep[1] == name for dep in __deps):
print >> impl, " const char *__eet_filename;";
print >> impl, """};\n"""
print >> header, "typedef struct _%s %s;" % (name, name)
for field in fields:
if field[1] == 'enum':
print >> header, "typedef enum {"
for value in field[2:]:
print >> header, " %s_%s_%s%s," % (name.upper(), field[0].upper(), value.upper(), value is field[2] and " = 0" or "")
print >> header, " %s_%s_LAST_VALUE" % (name.upper(), field[0].upper())
print >> header, "} %s_%s;" % (name, field[0].title())
def _write_reprs(parsed_block, header, impl):
have_reprs = False
for name, fields in parsed_block:
for field in fields:
if field[1] == 'enum':
print >> impl, "static const char *%s_%s_REPR[] = { %s, NULL };" % (
name.upper(), field[0].upper(),
", ".join('"%s"' % f for f in field[2:])
)
have_reprs = True
if have_reprs:
print >> impl, ""
def _write_entry_names(parsed_block, header, impl):
for name, fields in parsed_block:
print >> impl, """static const char %s_ENTRY[] = "%s";""" % (name.upper(), name.lower())
print >> impl, ""
def _write_descriptors(parsed_block, header, impl):
for name, fields in parsed_block:
print >> impl, """static Eet_Data_Descriptor *_%s_descriptor = NULL;""" % (name.lower())
def _write_initializers(name, fields, header, impl):
print >> impl, """\nstatic inline void
_%s_init(void)
{
Eet_Data_Descriptor_Class eddc;
if (_%s_descriptor) return;
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, %s);
_%s_descriptor = eet_data_descriptor_stream_new(&eddc);
""" % (name.lower(), name.lower(), name, name.lower())
for field in fields:
if field[-1] == 'noencode':
continue
if field[1] == 'list':
print >> impl, """ EET_DATA_DESCRIPTOR_ADD_LIST(_%s_descriptor, %s, "%s", %s, _%s_descriptor);""" % (
name.lower(),
name,
field[0],
field[0],
field[2].lower()
)
elif field[1] == 'hash':
print >> impl, """ EET_DATA_DESCRIPTOR_ADD_HASH(_%s_descriptor, %s, "%s", %s, _%s_descriptor);""" % (
name.lower(),
name,
field[0],
field[0],
field[2].lower()
)
elif field[1] == 'image':
__images.add(name)
print >> impl, """ EET_DATA_DESCRIPTOR_ADD_BASIC(_%s_descriptor, %s, "%s", %s, EET_T_UINT);""" % (
name.lower(),
name,
field[0] + '__id',
field[0] + '__id'
)
elif field[1] == 'pointer':
print >> impl, """ EET_DATA_DESCRIPTOR_ADD_SUB(_%s_descriptor, %s, "%s", %s, _%s_descriptor);""" % (
name.lower(),
name,
field[0],
field[0],
field[2].lower()
)
else:
type = FIELD_CONVERTER_EET[field[1]]
print >> impl, """ EET_DATA_DESCRIPTOR_ADD_BASIC(_%s_descriptor, %s, "%s", %s, %s);""" % (
name.lower(),
name,
field[0],
field[0],
type
)
print >> impl, """}\n"""
def _write_shutdowns(name, fields, header, impl):
print >> impl, """static inline void
_%s_shutdown(void)
{
if (!_%s_descriptor) return;
eet_data_descriptor_free(_%s_descriptor);
_%s_descriptor = NULL;
}\n""" % (name.lower(), name.lower(), name.lower(), name.lower())
def _write_allocators(name, fields, header, impl):
arg_fields = []
for field in fields:
if field[1] == 'hash':
continue
elif field[1] == 'image':
arg_fields.append('Evas_Object * %s' % field[0])
elif field[1] == 'enum':
arg_fields.append('%s_%s %s' % (
name,
field[0].title(),
field[0]
))
elif field[1] == 'pointer':
arg_fields.append('%s *%s' % (
field[2],
field[2].lower(),
))
else:
type = FIELD_CONVERTER[field[1]]
arg_fields.append('%s %s' % (type, field[0]))
print >> header, """%s *%s_new(%s);""" % (name, name.lower(), ', '.join(arg_fields))
print >> impl, """%s *
%s_new(%s)
{
%s *%s = calloc(1, sizeof(%s));
if (!%s)
{
fprintf(stderr, "ERROR: could not calloc %s\\n");
return NULL;
}
""" % (
name,
name.lower(),
', '.join(arg_fields),
name,
name.lower(),
name,
name.lower(),
name)
for field in fields:
if field[1] == 'str':
if len(field) > 2:
print >> impl, """ %s->%s = eina_stringshare_add(%s ? %s : "%s");""" % (
name.lower(),
field[0],
field[0],
field[0],
field[2]
)
else:
print >> impl, """ %s->%s = eina_stringshare_add(%s);""" % (
name.lower(),
field[0],
field[0]
)
elif field[1] == 'hash':
hashed_type = field[2]
hashed_field = field[3]
if hashed_field in __structs[hashed_type]:
print >> impl, """ %s->%s = %s(EINA_FREE_CB(%s_free));""" % (
name.lower(),
field[0],
EINA_HASH_FUNCTIONS[__structs[hashed_type][hashed_field]],
hashed_type.lower()
)
else:
print >> impl, """ %s->%s = NULL;""" % (
name.lower(),
field[0]
)
elif field[1] == 'list':
print >> impl, """ %s->%s = %s;""" % (
name.lower(),
field[0],
field[0]
)
elif field[1] == 'image':
print >> impl, """ %s->%s = %s;""" % (
name.lower(),
field[0],
field[0]
)
print >> impl, """ %s->%s__id = 0;""" % (
name.lower(),
field[0],
)
elif field[1] == 'pointer':
print >> impl, """ %s->%s = %s;""" % (
name.lower(),
field[2].lower(),
field[2].lower()
)
else:
print >> impl, """ %s->%s = %s;""" % (
name.lower(),
field[0],
field[0]
)
print >> impl, "\n return %s;\n}\n" % name.lower()
def _write_deallocators(name, fields, header, impl):
has_pointer = any(field[1] == 'pointer' for field in fields)
if has_pointer:
print >> header, """void %s_free(%s *%s, Eina_Bool free_contents);""" % (name.lower(), name, name.lower())
print >> impl, """void
%s_free(%s *%s, Eina_Bool free_contents)
{""" % (
name.lower(),
name,
name.lower()
)
else:
print >> header, """void %s_free(%s *%s);""" % (name.lower(), name, name.lower())
print >> impl, """void
%s_free(%s *%s)
{""" % (
name.lower(),
name,
name.lower()
)
for field in fields:
if isinstance(field[1], str):
if field[1] == 'str':
print >> impl, """ eina_stringshare_del(%s->%s);""" % (
name.lower(),
field[0]
)
elif field[1] == 'pointer':
if any(field == 'pointer' for field in __structs[field[2]].values()):
print >> impl, """ if (free_contents) %s_free(%s->%s, free_contents);""" % (field[2].lower(), name.lower(), field[2].lower())
else:
print >> impl, """ if (free_contents) %s_free(%s->%s);""" % (field[2].lower(), name.lower(), field[2].lower())
elif field[1] == 'list':
print >> impl, """ if (%s->%s)
{
%s *%s_elem;
EINA_LIST_FREE(%s->%s, %s_elem)
%s_free(%s_elem);
}""" % (
name.lower(),
field[0],
field[2],
field[0],
name.lower(),
field[0],
field[0],
field[2].lower(),
field[0]
)
elif field[1] == 'image':
print >> impl, """ if (%s->%s) evas_object_del(%s->%s);""" %(
name.lower(),
field[0],
name.lower(),
field[0]
)
elif field[1] == 'hash':
print >> impl, """ if (%s->%s) eina_hash_free(%s->%s);""" %(
name.lower(),
field[0],
name.lower(),
field[0]
)
print >> impl, " free(%s);\n}\n" % name.lower()
def _write_loaders(name, fields, header, impl):
extra = ''
for field in fields:
if field[-1] == 'noencode':
continue
if field[1] == 'image':
extra = 'Evas *evas, '
break
print >> header, """%s *%s_load(%sconst char *filename);""" % (name, name.lower(), extra)
print >> impl, """%s *
%s_load(%sconst char *filename)
{
%s *%s = NULL;
Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
if (!ef)
{
fprintf(stderr, "ERROR: could not open '%%s' for read\\n", filename);
return NULL;
}
%s = eet_data_read(ef, _%s_descriptor, %s_ENTRY);
if (!%s) goto end;""" % (
name,
name.lower(),
extra,
name,
name.lower(),
name.lower(),
name.lower(),
name.upper(),
name.lower())
print >> impl, " %s->__eet_filename = eina_stringshare_add(filename);" % name.lower();
for field in fields:
if field[-1] == 'noencode':
continue
if field[1] == 'pointer':
for pointee_field, pointee_type in __structs[field[2]].items():
if pointee_type != 'hash': continue
hashed_type, hashed_field = __subtypes[field[2]][pointee_field]
allocator = "%s(EINA_FREE_CB(%s_free))" % (
EINA_HASH_FUNCTIONS[__structs[hashed_type][hashed_field]],
hashed_type.lower()
)
if pointee_type == 'hash':
print >> impl, """ if (!%(pname)s->%(bname)s->%(fname)s) %(pname)s->%(bname)s->%(fname)s = %(allocator)s;""" % {
"bname" : field[0],
"fname" : pointee_field,
"pname" : name.lower(),
"allocator" : allocator
}
elif field[1] == 'hash':
hashed_type = field[2]
hashed_field = field[3]
if hashed_field in __structs[hashed_type]:
allocator = "%s(EINA_FREE_CB(%s_free))" % (
EINA_HASH_FUNCTIONS[__structs[hashed_type][hashed_field]],
hashed_type.lower()
)
print >> impl, """\n if (!%(bname)s->%(fname)s) %(bname)s->%(fname)s = %(allocator)s;""" % {
"bname" : name.lower(),
"fname" : field[0],
"allocator" : allocator
}
elif field[1] == 'image':
print >> impl, """\n if (%(bname)s->%(fname)s__id)
{
char %(fname)s_buf[256];
unsigned int %(fname)s_w, %(fname)s_h;
int %(fname)s_alpha, %(fname)s_compress, %(fname)s_quality, %(fname)s_lossy;
void *%(fname)s_data;
sprintf(%(fname)s_buf, "/image/%(perc)sd", %(bname)s->%(fname)s__id);
%(fname)s_data = eet_data_image_read(ef, %(fname)s_buf, &%(fname)s_w, &%(fname)s_h, &%(fname)s_alpha, &%(fname)s_compress, &%(fname)s_quality, &%(fname)s_lossy);
if (%(fname)s_data)
{
%(bname)s->%(fname)s = evas_object_image_add(evas);
evas_object_image_size_set(%(bname)s->%(fname)s, %(fname)s_w, %(fname)s_h);
evas_object_image_alpha_set(%(bname)s->%(fname)s, %(fname)s_alpha);
evas_object_image_data_set(%(bname)s->%(fname)s, %(fname)s_data);
}
}""" % {
"bname": name.lower(),
"fname": field[0],
"perc": "%"
}
print >> impl, "\nend:"
print >> impl, " eet_close(ef);"
print >> impl, " return %s;\n}\n" % name.lower();
def _write_dumpers(name, fields, header, impl):
print >> header, """Eina_Bool %s_save(%s *%s, const char *filename);""" % (name.lower(), name, name.lower())
print >> impl, """Eina_Bool
%s_save(%s *%s, const char *filename)
{
Eet_File *ef;
Eina_Bool ret;
if (filename) eina_stringshare_replace(&(%s->__eet_filename), filename);
else if (%s->__eet_filename) filename = %s->__eet_filename;
else return EINA_FALSE;
ef = eet_open(filename, EET_FILE_MODE_READ_WRITE);
if (!ef)
{
fprintf(stderr, "ERROR: could not open '%%s' for write\\n", filename);
return EINA_FALSE;
}
""" % (
name.lower(),
name,
name.lower(),
name.lower(),
name.lower(),
name.lower(),
)
has_images = any(field[-1] != 'noencode' and field[1] == 'image' for field in fields)
dep_has_images = any(dep in __images for struct, dep, depee in __deps)
if has_images or dep_has_images:
print >> impl, " i = 1;"
if has_images:
print >> impl, " i = _write_%s_images(%s, ef, i);" % (
name.lower(), name.lower()
)
if dep_has_images:
for struct, dep, depee in __deps:
if dep in __images:
if __structs[name][depee] == 'list':
print >> impl, """ if (%s->%s)
{
%s *%s;
Eina_List *%s_list;
EINA_LIST_FOREACH(%s->%s, %s_list, %s)
i = _write_%s_images(%s, ef, i);
}""" % (
name.lower(), depee,
dep, dep.lower(),
dep.lower(),
name.lower(), depee, dep.lower(), dep.lower(),
dep.lower(), dep.lower()
)
elif __structs[name][depee] == 'hash':
# Too lazy right now
pass
print >> impl, """ ret = !!eet_data_write(ef, _%s_descriptor, %s_ENTRY, %s, EINA_TRUE);
eet_close(ef);
return ret;
}""" % (
name.lower(),
name.upper(),
name.lower()
)
def _write_getters_setters(name, fields, header, impl):
for field in fields:
if field[1] == 'pointer':
print >> header, """void %s_%s_set(%s *%s, %s *%s);
%s *%s_%s_get(%s *%s);""" % (
name.lower(), field[2].lower(), name, name.lower(), field[2], field[2].lower(),
field[2], name.lower(), field[2].lower(), name, name.lower()
)
print >> impl, """void %s_%s_set(%s *%s, %s *%s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
%s->%s = %s;
}
%s *%s_%s_get(%s *%s)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(%s, NULL);
return %s->%s;
}
""" % (
name.lower(), field[2].lower(), name, name.lower(), field[2], field[2].lower(),
name.lower(),
name.lower(), field[2].lower(), field[2].lower(),
field[2], name.lower(), field[2].lower(), name, name.lower(),
name.lower(),
name.lower(), field[2].lower()
)
elif field[1] == 'list':
print >> header, """void %s_%s_add(%s *%s, %s *%s);
void %s_%s_del(%s *%s, %s *%s);
%s *%s_%s_get(const %s *%s, unsigned int nth);
unsigned int %s_%s_count(const %s *%s);
Eina_List *%s_%s_list_get(const %s *%s);
void %s_%s_list_clear(%s *%s);
void %s_%s_list_set(%s *%s, Eina_List *list);""" % (
name.lower(), field[0], name, name.lower(), field[2],
field[2].lower(), name.lower(), field[0], name,
name.lower(), field[2], field[2].lower(), field[2],
name.lower(), field[0], name, name.lower(),
name.lower(), field[0], name, name.lower(),
name.lower(), field[0], name, name.lower(),
name.lower(), field[0], name, name.lower(),
name.lower(), field[0], name, name.lower()
)
print >> impl, """inline void
%s_%s_add(%s *%s, %s *%s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
%s->%s = eina_list_append(%s->%s, %s);
}
""" % (
name.lower(), field[0], name, name.lower(),
field[2], field[2].lower(), name.lower(),
name.lower(), field[0], name.lower(),
field[0], field[2].lower()
)
print >> impl, """inline void
%s_%s_del(%s *%s, %s *%s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
%s->%s = eina_list_remove(%s->%s, %s);
}
""" % (
name.lower(), field[0], name, name.lower(), field[2],
field[2].lower(), name.lower(), name.lower(), field[0],
name.lower(), field[0], field[2].lower()
)
print >> impl, """inline %s *
%s_%s_get(const %s *%s, unsigned int nth)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(%s, NULL);
return eina_list_nth(%s->%s, nth);
}
""" % (
field[2], name.lower(), field[0], name, name.lower(),
name.lower(), name.lower(), field[0]
)
print >> impl, """inline unsigned int
%s_%s_count(const %s *%s)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(%s, 0);
return eina_list_count(%s->%s);
}
""" % (
name.lower(), field[0], name, name.lower(),
name.lower(),
name.lower(), field[0]
)
print >> impl, """void
%s_%s_list_clear(%s *%s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
%s *data;
EINA_LIST_FREE(%s->%s, data) %s_free(data);
}
""" % (
name.lower(), field[0], name, name.lower(),
name.lower(),
field[2],
name.lower(), field[0], field[2].lower(),
)
print >> impl, """inline Eina_List *
%s_%s_list_get(const %s *%s)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(%s, NULL);
return %s->%s;
}
""" % (
name.lower(), field[0], name, name.lower(),
name.lower(),
name.lower(), field[0]
)
print >> impl, """inline void
%s_%s_list_set(%s *%s, Eina_List *list)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
%s->%s = list;
}
""" % (
name.lower(), field[0], name, name.lower(),
name.lower(),
name.lower(), field[0]
)
elif field[1] == 'hash':
hashed_type = field[2]
hashed_field = field[3]
print >> header, """void %s_%s_add(%s *%s, %s %s, %s *%s);
void %s_%s_del(%s *%s, %s %s);
%s *%s_%s_get(const %s *%s, %s key);
Eina_Hash *%s_%s_hash_get(const %s *%s);
void %s_%s_modify(%s *%s, %s key, void *value);""" % (
name.lower(), field[0], name, name.lower(),
FIELD_CONVERTER[__structs[hashed_type][hashed_field]], hashed_field,
hashed_type, hashed_type.lower(), name.lower(), field[0], name,
name.lower(), FIELD_CONVERTER[__structs[hashed_type][hashed_field]], hashed_field,
hashed_type, name.lower(), field[0], name, name.lower(), FIELD_CONVERTER[__structs[hashed_type][hashed_field]],
name.lower(), field[0], name, name.lower(),
name.lower(), field[0], name, name.lower(), FIELD_CONVERTER[__structs[hashed_type][hashed_field]]
)
print >> impl, """void
%s_%s_add(%s *%s, %s %s, %s *%s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
eina_hash_add(%s->%s, %s, %s);
}
""" % (
name.lower(), field[0], name, name.lower(),
FIELD_CONVERTER[__structs[hashed_type][hashed_field]], hashed_field,
hashed_type, hashed_type.lower(), name.lower(), name.lower(), field[0],
hashed_field, hashed_type.lower()
)
print >> impl, """void
%s_%s_del(%s *%s, %s %s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
eina_hash_del(%s->%s, %s, NULL);
}
""" % (
name.lower(), field[0], name, name.lower(),
FIELD_CONVERTER[__structs[hashed_type][hashed_field]], hashed_field,
name.lower(), name.lower(), field[0], hashed_field
)
print >> impl, """inline %s *
%s_%s_get(const %s *%s, %s %s)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(%s, NULL);
return eina_hash_find(%s->%s, %s);
}
""" % (
hashed_type, name.lower(), field[0], name, name.lower(),
FIELD_CONVERTER[__structs[hashed_type][hashed_field]], hashed_field,
name.lower(), name.lower(), field[0], hashed_field
)
print >> impl, """inline Eina_Hash *
%s_%s_hash_get(const %s *%s)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(%s, NULL);
return %s->%s;
}
""" % (
name.lower(), field[0], name, name.lower(),
name.lower(),
name.lower(), field[0]
)
print >> impl, """void
%s_%s_modify(%s *%s, %s key, void *value)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
eina_hash_modify(%s->%s, key, value);
}
""" % (
name.lower(), field[0], name, name.lower(), FIELD_CONVERTER[__structs[hashed_type][hashed_field]],
name.lower(),
name.lower(), field[0]
)
elif field[1] == 'image':
print >> header, """void %s_%s_set(%s *%s, Evas_Object *%s);
Evas_Object *%s_%s_get(const %s *%s, Evas *evas, const char *eet_file);""" % (
name.lower(), field[0], name, name.lower(), field[0],
name.lower(), field[0], name, name.lower()
)
print >> impl, """void
%s_%s_set(%s *%s, Evas_Object *%s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
if (%s->%s) evas_object_del(%s->%s);
%s->%s__id = 0;
%s->%s = %s;
}
""" % (
name.lower(), field[0], name, name.lower(), field[0],
name.lower(),
name.lower(), field[0], name.lower(), field[0],
name.lower(), field[0],
name.lower(), field[0], field[0]
)
print >> impl, """Evas_Object *
%s_%s_get(const %s *%s, Evas *evas, const char *eet_file)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(%s, NULL);
if (%s->%s) return %s->%s;
_load_%s_images(%s, evas, eet_file);
return %s->%s;
}
""" % (
name.lower(), field[0], name, name.lower(),
name.lower(),
name.lower(), field[0], name.lower(), field[0],
name.lower(), name.lower(),
name.lower(), field[0]
)
elif field[1] == 'enum':
print >> header, """void %s_%s_set(%s *%s, %s %s);
%s %s_%s_get(const %s *%s);
const char * %s_%s_repr_get(const %s *%s);
const char * %s_%s_str_get(%s %s);""" % (
name.lower(), field[0], name, name.lower(), name + '_' + field[0].title(),
field[0], name + '_' + field[0].title(), name.lower(), field[0],
name, name.lower(),
name.lower(), field[0], name, name.lower(),
name.lower(), field[0], name + '_' + field[0].title(), field[0]
)
print >> impl, """inline %s
%s_%s_get(const %s *%s)
{
return %s->%s;
}
""" % (
name + '_' + field[0].title(),
name.lower(), field[0],
name, name.lower(),
name.lower(), field[0]
)
print >> impl, """inline const char *
%s_%s_repr_get(const %s *%s)
{
return %s_%s_REPR[%s->%s];
}
""" % (
name.lower(), field[0],
name, name.lower(),
name.upper(), field[0].upper(),
name.lower(), field[0]
)
print >> impl, """inline void
%s_%s_set(%s *%s, %s %s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
if (%s >= %s_%s_LAST_VALUE) return;
%s->%s = %s;
}
""" % (
name.lower(), field[0], name, name.lower(),
name + '_' + field[0].title(), field[0],
name.lower(),
field[0], name.upper(), field[0].upper(),
name.lower(), field[0], field[0]
)
print >> impl, """inline const char *
%s_%s_str_get(%s %s)
{
if (%s >= %s_%s_LAST_VALUE) return NULL;
return %s_%s_REPR[%s];
}
""" % (
name.lower(), field[0],
name + '_' + field[0].title(), field[0],
field[0], name.upper(), field[0].upper(),
name.upper(), field[0].upper(), field[0]
)
else:
print >> header, """void %s_%s_set(%s *%s, %s %s);
%s %s_%s_get(const %s *%s);""" % (
name.lower(), field[0], name, name.lower(), FIELD_CONVERTER[field[1]],
field[0], FIELD_CONVERTER[field[1]], name.lower(), field[0], name, name.lower(),
)
print >> impl, """inline %s
%s_%s_get(const %s *%s)
{
return %s->%s;
}
""" % (
FIELD_CONVERTER[field[1]],
name.lower(), field[0],
name, name.lower(),
name.lower(), field[0]
)
if field[1] == 'str':
print >> impl, """inline void
%s_%s_set(%s *%s, const char *%s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
eina_stringshare_replace(&(%s->%s), %s);
}
""" % (
name.lower(), field[0], name, name.lower(), field[0],
name.lower(),
name.lower(), field[0], field[0]
)
else:
print >> impl, """inline void
%s_%s_set(%s *%s, %s %s)
{
EINA_SAFETY_ON_NULL_RETURN(%s);
%s->%s = %s;
}
""" % (
name.lower(), field[0], name, name.lower(), FIELD_CONVERTER[field[1]], field[0],
name.lower(),
name.lower(), field[0], field[0]
)
def _write_image_loaders(name, fields, impl):
if not any(field[1] == 'image' for field in fields):
return
print >> impl, """static void
_load_%s_images(%s *%s, Evas *evas, const char *filename)
{
Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
if (!ef)
{
fprintf(stderr, "ERROR: could not open '%%s' for read\\n", filename);
return;
}""" % (
name.lower(), name, name.lower()
)
for field in (f for f in fields if f[1] == 'image'):
print >> impl, """\n if (%(bname)s->%(fname)s__id)
{
char %(fname)s_buf[256];
unsigned int %(fname)s_w, %(fname)s_h;
int %(fname)s_alpha, %(fname)s_compress, %(fname)s_quality, %(fname)s_lossy;
void *%(fname)s_data;
sprintf(%(fname)s_buf, "/image/%(perc)sd", %(bname)s->%(fname)s__id);
%(fname)s_data = eet_data_image_read(ef, %(fname)s_buf, &%(fname)s_w, &%(fname)s_h, &%(fname)s_alpha, &%(fname)s_compress, &%(fname)s_quality, &%(fname)s_lossy);
if (%(fname)s_data)
{
%(bname)s->%(fname)s = evas_object_image_add(evas);
evas_object_image_size_set(%(bname)s->%(fname)s, %(fname)s_w, %(fname)s_h);
evas_object_image_alpha_set(%(bname)s->%(fname)s, %(fname)s_alpha);
evas_object_image_data_set(%(bname)s->%(fname)s, %(fname)s_data);
}
}""" % {
"bname": name.lower(),
"fname": field[0],
"perc": "%"
}
print >> impl, "\n eet_close(ef);\n}\n"
def _write_image_savers(name, fields, impl):
if not any(field[1] == 'image' for field in fields):
return
print >> impl, """static int
_write_%s_images(%s *%s, Eet_File *ef, int image_id)
{""" % (
name.lower(), name, name.lower()
)
for field in fields:
if field[-1] == 'noencode':
continue
if field[1] == 'image':
if field[2] == "raw":
compress = False
lossy = False
quality = 100
elif field[2] == "lossy":
compress = True
lossy = True
quality = int(field[3])
else:
compress = True
lossy = False
quality = int(field[3])
print >> impl, """ if (%(bname)s->%(fname)s)
{
char %(fname)s_buf[256];
int %(fname)s_w, %(fname)s_h;
int %(fname)s_alpha;
void *%(fname)s_data;
%(bname)s->%(fname)s__id = image_id;
sprintf(%(fname)s_buf, "/image/%(perc)sd", image_id++);
evas_object_image_size_get(%(bname)s->%(fname)s, &%(fname)s_w, &%(fname)s_h);
%(fname)s_alpha = evas_object_image_alpha_get(%(bname)s->%(fname)s);
%(fname)s_data = evas_object_image_data_get(%(bname)s->%(fname)s, EINA_FALSE);
eet_data_image_write(ef, %(fname)s_buf, %(fname)s_data, %(fname)s_w, %(fname)s_h, %(fname)s_alpha, %(compress)d, %(quality)d, %(lossy)d);
}""" % {
"bname": name.lower(),
"fname": field[0],
"perc": "%",
"lossy": lossy,
"compress": compress,
"quality": quality
}
print >> impl, """ return image_id;
}
"""
def _write_block(parsed_block, header, impl):
print >> header, ""
for name, fields in parsed_block:
print >> header, """/* %s */""" % name
_write_initializers(name, fields, header, impl)
_write_shutdowns(name, fields, header, impl)
_write_allocators(name, fields, header, impl)
_write_deallocators(name, fields, header, impl)
print >> header, ""
_write_image_loaders(name, fields, impl)
_write_image_savers(name, fields, impl)
_write_getters_setters(name, fields, header, impl)
if not any(dep[1] == name for dep in __deps):
print >> header, ""
_write_loaders(name, fields, header, impl)
_write_dumpers(name, fields, header, impl)
print >> header, ""
def _write_global_initializers(parsed_block, base_name, header, impl):
print >> header, "/* Global initializer / shutdown functions */"
print >> header, "void %s_init(void);" % base_name
print >> header, "void %s_shutdown(void);" % base_name
print >> header, ""
print >> impl, """\nvoid
%s_init(void)
{""" % base_name
for name, fields in parsed_block:
print >> impl, " _%s_init();" % name.lower()
print >> impl, "}\n"
print >> impl, """void
%s_shutdown(void)
{""" % base_name
for name, fields in parsed_block:
print >> impl, " _%s_shutdown();" % name.lower()
print >> impl, "}\n"
def write_output(parsed_block, base_name, dir_name):
header = file(dir_name + base_name + '.h', 'w')
impl = file(dir_name + base_name + '.c', 'w')
_write_headers(header, impl)
_write_includes(parsed_block, base_name, header, impl)
_write_structs(parsed_block, header, impl)
_write_reprs(parsed_block, header, impl)
_write_entry_names(parsed_block, header, impl)
_write_descriptors(parsed_block, header, impl)
_write_block(parsed_block, header, impl)
_write_global_initializers(parsed_block, base_name, header, impl)
print >> header, """#endif /* __%s_H__ */""" % base_name.upper()
header.close()
impl.close()
if __name__ == '__main__':
if len(sys.argv) < 2:
print 'Usage: %s file.geneet' % sys.argv[0]
else:
dir_name = os.path.dirname(sys.argv[1])
if dir_name:
dir_name = dir_name + '/'
base_name = os.path.basename('.'.join(sys.argv[1].split('.')[:-1]))
try:
parsed_block = block.parseFile(sys.argv[1])
except ParseException, e:
print 'Syntax error:', e
sys.exit(1)
check(base_name, parsed_block)
write_output(parsed_block, base_name, dir_name)