165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#!/usr/bin/env python
265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#
465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# Copyright (C) 2011 The Android Open Source Project
565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#
665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# Licensed under the Apache License, Version 2.0 (the "License");
765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# you may not use this file except in compliance with the License.
865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# You may obtain a copy of the License at
965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#
1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#      http://www.apache.org/licenses/LICENSE-2.0
1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#
1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# Unless required by applicable law or agreed to in writing, software
1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# distributed under the License is distributed on an "AS IS" BASIS,
1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# See the License for the specific language governing permissions and
1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn# limitations under the License.
1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#
1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport os
2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport sys
2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennhFileTemplate = """/**
2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * This file is auto-generated by platform/system/media/mca/structgen.py! Do NOT modify!
2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn **/
2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#ifndef %s
2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#define %s
2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn%s
3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#endif // %s
3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn"""
3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennjniFileTemplate = """/**
3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * This file is auto-generated by platform/system/media/mca/structgen.py! Do NOT modify!
3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn **/
3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <stdint.h>
3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "native/%s.h"
4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#ifdef __cplusplus
4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennextern "C" {
4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#endif
4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "jni.h"
4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Helper functions ////////////////////////////////////////////////////////////////////////////////
4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn%s* Get%sAtIndex(JNIEnv* env, jobject buffer, int index) {
4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  jclass base_class = (*env)->FindClass(env, "android/filterfw/core/NativeBuffer");
5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  jfieldID ptr_field = (*env)->GetFieldID(env, base_class, "mDataPointer", "J");
5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  uintptr_t data_ptr = (*env)->GetLongField(env, buffer, ptr_field);
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  %s* array = (%s*)data_ptr;
5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  (*env)->DeleteLocalRef(env, base_class);
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return &array[index];
5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Declarations ////////////////////////////////////////////////////////////////////////////////////
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennJNIEXPORT jint JNICALL
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennJava_%s_getElementSize(JNIEnv* env, jobject thiz);
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn%s
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#ifdef __cplusplus
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#endif
6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Implementation //////////////////////////////////////////////////////////////////////////////////
6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjint Java_%s_getElementSize(JNIEnv* env, jobject thiz) {
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return sizeof(%s);
7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn%s
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn"""
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennjavaFileTemplate = """/**
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * This file is auto-generated by platform/system/media/mca/structgen.py! Do NOT modify!
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn **/
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennpackage %s;
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennimport android.filterfw.core.NativeBuffer;
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn%s
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn"""
8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renndef ToJavaName(cname, start_upper_at = 1):
8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  lower = cname.split("_")
8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  upper = [c.title() for c in lower]
9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return "".join(lower[:start_upper_at] + upper[start_upper_at:])
9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renndef ToJNIPackage(package, jclassname):
9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return "%s_%s" % (package.replace(".", "_"), jclassname)
9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renndef ToMacroDefName(cname, pname):
9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  return "%s_%s" % (pname.replace(".", "_").upper(), cname.upper())
9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass ParseError:
9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def __init__(self, lineno, message):
10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.lineno = lineno
10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.message = message
10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def __str__(self):
10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "On line %d: %s" % (self.lineno, self.message)
10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass FieldType_BasePOD:
10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def __init__(self, name, structname, jclassname, package, javatype, ctype, jtype, defval):
10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.name = name
10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.structname = structname
11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.jclassname = jclassname
11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.package = package
11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.javatype = javatype
11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.ctype = ctype
11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.jtype = jtype
11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.defval = defval
11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def cString(self):
11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "  %s %s;" % (self.ctype, self.name)
11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def javaGetter(self):
12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "    public %s get%s(int index) {\n"\
12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "        assertReadable();\n"\
12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "        return nativeGet%s(index);\n"\
12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    }" % (self.javatype, ToJavaName(self.name, 0), ToJavaName(self.name, 0))
12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def javaSetter(self):
12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "    public void set%s(int index, %s value) {\n"\
12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "        assertWritable();\n"\
12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "        nativeSet%s(index, value);\n"\
13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    }" % (ToJavaName(self.name, 0), self.javatype, ToJavaName(self.name, 0))
13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def javaNativeGetter(self):
13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "    private native %s nativeGet%s(int index);"\
13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           % (self.javatype, ToJavaName(self.name, 0))
13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def javaNativeSetter(self):
13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "    private native boolean nativeSet%s(int index, %s value);"\
13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           % (ToJavaName(self.name, 0), self.javatype)
13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def jniGetterDefString(self):
14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "JNIEXPORT %s JNICALL\n" \
14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "Java_%s_nativeGet%s(JNIEnv* env, jobject thiz, jint index);" \
14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           % (self.jtype, ToJNIPackage(self.package, self.jclassname), ToJavaName(self.name, 0))
14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def jniGetterImplString(self):
14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return \
14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "%s Java_%s_nativeGet%s(JNIEnv* env, jobject thiz, jint index) {\n"\
14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "  %s* instance = Get%sAtIndex(env, thiz, index);\n"\
14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "  return instance ? instance->%s : %s;\n"\
15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "}\n" % (self.jtype, ToJNIPackage(self.package, self.jclassname), ToJavaName(self.name, 0),\
15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn               self.structname, self.structname, self.name, self.defval)
15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def jniSetterDefString(self):
15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "JNIEXPORT jboolean JNICALL\n" \
15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "Java_%s_nativeSet%s(JNIEnv* env, jobject thiz, jint index, %s value);" \
15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           % (ToJNIPackage(self.package, self.jclassname), ToJavaName(self.name, 0), self.jtype)
15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def jniSetterImplString(self):
15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return \
16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "jboolean Java_%s_nativeSet%s(JNIEnv* env, jobject thiz, jint index, %s value) {\n"\
16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "  %s* instance = Get%sAtIndex(env, thiz, index);\n"\
16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "  if (instance) {\n"\
16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "    instance->%s = value;\n"\
16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "    return JNI_TRUE;\n"\
16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "  }\n"\
16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "  return JNI_FALSE;\n"\
16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      "}\n" % (ToJNIPackage(self.package, self.jclassname), ToJavaName(self.name, 0),\
16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn               self.jtype, self.structname, self.structname, self.name)
16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass FieldType_Float(FieldType_BasePOD):
17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def __init__(self, name, structname, jclassname, package):
17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    FieldType_BasePOD.__init__(self, name, structname, jclassname, package, "float", "float", "jfloat", "0.0")
17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass FieldType_Int(FieldType_BasePOD):
17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def __init__(self, name, structname, jclassname, package):
17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    FieldType_BasePOD.__init__(self, name, structname, jclassname, package, "int", "int", "jint", "0")
17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass FieldType_Long(FieldType_BasePOD):
17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def __init__(self, name, structname, jclassname, package):
18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    FieldType_BasePOD.__init__(self, name, structname, jclassname, package, "long", "long long", "jlong", "0")
18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass StructSpec:
18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def parseTextFile(self, filepath):
18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    # Init
18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.name = None
18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.package = None
18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.fields = []
18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.structname = None
19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.jclassname = None
19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    self.libname = None
19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    # Open the file
19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    txtfile = open(filepath)
19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    # Parse it line by line
19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    lineno = 0
19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    for line in txtfile:
19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      # Split line into components
20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      linecomps = line.split()
20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      if len(linecomps) == 0:
20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        continue
20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      # Execute command
20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      cmd = linecomps[0]
20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      if cmd == "@name":
20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.commandArgAssert(linecomps, 1, lineno)
20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.name = linecomps[1]
20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        if not self.structname:
21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn          self.structname = self.name
21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        if not self.jclassname:
21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn          self.jclassname = self.name
21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      elif cmd == "@package":
21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.commandArgAssert(linecomps, 1, lineno)
21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.package = linecomps[1]
21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      elif cmd == "@libname":
21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.commandArgAssert(linecomps, 1, lineno)
21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.libname = linecomps[1]
21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      elif cmd == "@structname":
22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.commandArgAssert(linecomps, 1, lineno)
22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.structname = linecomps[1]
22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      elif cmd == "@javaclassname":
22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.commandArgAssert(linecomps, 1, lineno)
22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.jclassname = linecomps[1]
22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      elif cmd == "@field":
22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.commandArgAssert(linecomps, 2, lineno)
22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        typestr = linecomps[1]
22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        if typestr == "int":
22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn          fieldtype = FieldType_Int(linecomps[2], self.structname, self.jclassname, self.package)
23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        elif typestr == "long":
23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn          fieldtype = FieldType_Long(linecomps[2], self.structname, self.jclassname, self.package)
23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        elif typestr == "float":
23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn          fieldtype = FieldType_Float(linecomps[2], self.structname, self.jclassname, self.package)
23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        else:
23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn          raise ParseError(lineno, "Unknown field type '%s'!" % typestr)
23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        self.fields.append(fieldtype)
23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      else:
23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn        raise ParseError(lineno, "Unknown command: '%s'!" % cmd)
23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      lineno = lineno + 1
24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    # Make sure we have all required info
24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if not self.name:
24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      raise ParseError(lineno, "Required field '@name' missing!")
24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    elif not self.package:
24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      raise ParseError(lineno, "Required field '@package' missing!")
24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    elif not self.libname:
24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      raise ParseError(lineno, "Required field '@libname' missing!")
24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    # Normalize values
25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if self.libname[:3] == "lib":
25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      self.libname = self.libname[3:]
25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def commandArgAssert(self, linecomps, expectedcount, lineno):
25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    foundcount = len(linecomps) - 1
25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    if foundcount < expectedcount:
25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      raise ParseError(lineno, "Not enough arguments specifed for command '%s'! Expected %d, " \
25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                       "but got only %d!" % (linecomps[0], expectedcount, foundcount))
25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    elif foundcount > expectedcount + 1:
26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn      raise ParseError(lineno, "Too many arguments specifed for command '%s'! Expected %d, " \
26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                       "but got %d!" % (linecomps[0], expectedcount, foundcount))
26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def cStructString(self):
26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    cfields = [f.cString() for f in self.fields]
26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "typedef struct Struct%s {\n%s\n} %s;\n" % (self.structname,\
26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                       "\n".join(cfields),\
26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                                                       self.structname)
26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def javaClassString(self):
27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jgetters = [f.javaGetter() for f in self.fields]
27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jsetters = [f.javaSetter() for f in self.fields]
27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jnativesetters = [f.javaNativeSetter() for f in self.fields]
27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jnativegetters = [f.javaNativeGetter() for f in self.fields]
27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "public class %s extends NativeBuffer {\n\n"\
27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    public %s() {\n"\
27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "        super();\n"\
27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    }\n"\
27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "\n"\
28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    public %s(int count) {\n"\
28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "        super(count);\n"\
28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    }\n"\
28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "\n"\
28465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    public native int getElementSize();\n"\
28565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "\n"\
28665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "%s\n\n"\
28765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "%s\n\n"\
28865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "%s\n\n"\
28965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "%s\n\n"\
29065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    static {\n"\
29165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "        System.loadLibrary(\"%s\");\n"\
29265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "    }\n"\
29365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "\n"\
29465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn           "};\n" % (self.jclassname,\
29565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                     self.jclassname,\
29665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                     self.jclassname,\
29765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                     "\n\n".join(jgetters),\
29865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                     "\n\n".join(jsetters),\
29965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                     "\n\n".join(jnativegetters),\
30065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                     "\n\n".join(jnativesetters),\
30165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                     self.libname)
30265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
30365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def jniDeclString(self):
30465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jnigetters = [f.jniGetterDefString() for f in self.fields]
30565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jnisetters = [f.jniSetterDefString() for f in self.fields]
30665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "\n\n".join(jnigetters + jnisetters)
30765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
30865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def jniImplString(self):
30965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jnigetters = [f.jniGetterImplString() for f in self.fields]
31065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    jnisetters = [f.jniSetterImplString() for f in self.fields]
31165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return "\n\n".join(jnigetters + jnisetters)
31265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
31365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def hFileString(self):
31465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    defname = ToMacroDefName(self.structname, self.package)
31565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return hFileTemplate % (defname, defname, self.cStructString(), defname)
31665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
31765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def javaFileString(self):
31865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return javaFileTemplate % (self.package, self.javaClassString())
31965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
32065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  def jniFileString(self):
32165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return jniFileTemplate % (self.structname.lower(),\
32265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              self.structname,\
32365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              self.structname,\
32465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              self.structname,\
32565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              self.structname,\
32665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              ToJNIPackage(self.package, self.jclassname),\
32765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              self.jniDeclString(),\
32865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              ToJNIPackage(self.package, self.jclassname),\
32965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              self.structname,
33065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn                              self.jniImplString())
33165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
33265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renndef main(argv):
33365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  if len(argv) != 2:
33465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    print("Usage: %s <file.struct>" % argv[0])
33565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn    return -1
33665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
33765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  filepath = argv[1]
33865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
33965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  structspec = StructSpec()
34065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  structspec.parseTextFile(filepath)
34165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
34265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  hfilename = "%s.h" % structspec.structname.lower()
34365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  javafilename = "%s.java" % structspec.jclassname
34465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  jnifilename = "jni_%s.c" % structspec.structname.lower()
34565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
34665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  javapackagepath = structspec.package.replace('.','/')
34765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
34865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  rootdir = os.path.dirname(filepath)
34965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  hfilepath = "%s/../native/%s" % (rootdir, hfilename)
35065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  javafilepath = "%s/../java/%s/%s" % (rootdir, javapackagepath, javafilename)
35165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  jnifilepath = "%s/../jni/%s" % (rootdir, jnifilename)
35265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
35365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  hfile = open(hfilepath, 'w')
35465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  hfile.write(structspec.hFileString())
35565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  hfile.close()
35665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
35765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  javafile = open(javafilepath, 'w')
35865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  javafile.write(structspec.javaFileString())
35965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  javafile.close()
36065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
36165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  jnifile = open(jnifilepath, 'w')
36265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  jnifile.write(structspec.jniFileString())
36365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  jnifile.close()
36465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
36565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
36665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennif __name__ == "__main__":
36765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn  sys.exit(main(sys.argv))
368