Example #1
0
 def __mul__(self, unit):
     """
     SiPrefix * BaseUnit yields new BaseUnit
     SiPrefix * ScaledUnit yields new ScaledUnit
     SiPrefix * Unit with exactly one BaseUnit or ScaledUnit yields new Unit
     """
     if isinstance(unit, BaseUnit):
         # BaseUnit version
         symbol = self.symbol + unit.symbol
         name = self.prefix + unit.name
         factor = self.factor
         # TODO - check for existing BaseUnit with same name, symbol, and factor
         new_base_unit = BaseUnit(unit.dimension, name, symbol)
         new_base_unit.define_conversion_factor_to(unit, factor)
         return new_base_unit
     elif isinstance(unit, ScaledUnit):
         # ScaledUnit version
         symbol = self.symbol + unit.symbol
         name = self.prefix + unit.name
         factor = self.factor * unit.factor
         # TODO - check for existing BaseUnit with same name, symbol, and factor
         return ScaledUnit(factor, unit.master, name, symbol)
     elif isinstance(unit, Unit):
         base_units = list(unit.iter_base_or_scaled_units())
         if 1 != len(base_units):
             raise TypeError('Unit prefix "%s" can only be with simple Units containing one component.' % self.prefix)
         if 1 != base_units[0][1]:
             raise TypeError('Unit prefix "%s" can only be with simple Units with an exponent of 1.' % self.prefix)
         base_unit = base_units[0][0]
         # Delegate to Base or Scaled Unit multiply
         new_base_unit = self * base_unit
         new_unit = Unit({new_base_unit: 1.0})
         return new_unit
     else:
         raise TypeError('Unit prefix "%s" can only be applied to a Unit, BaseUnit, or ScaledUnit.' % self.prefix)
Example #2
0
 def __mul__(self, unit):
     """
     SiPrefix * BaseUnit yields new BaseUnit
     SiPrefix * ScaledUnit yields new ScaledUnit
     SiPrefix * Unit with exactly one BaseUnit or ScaledUnit yields new Unit
     """
     if isinstance(unit, BaseUnit):
         # BaseUnit version
         symbol = self.symbol + unit.symbol
         name = self.prefix + unit.name
         factor = self.factor
         # TODO - check for existing BaseUnit with same name, symbol, and factor
         new_base_unit = BaseUnit(unit.dimension, name, symbol)
         new_base_unit.define_conversion_factor_to(unit, factor)
         return new_base_unit
     elif isinstance(unit, ScaledUnit):
         # ScaledUnit version
         symbol = self.symbol + unit.symbol
         name = self.prefix + unit.name
         factor = self.factor * unit.factor
         # TODO - check for existing BaseUnit with same name, symbol, and factor
         return ScaledUnit(factor, unit.master, name, symbol)
     elif isinstance(unit, Unit):
         base_units = list(unit.iter_base_or_scaled_units())
         if 1 != len(base_units):
             raise TypeError('Unit prefix "%s" can only be with simple Units containing one component.' % self.prefix)
         if 1 != base_units[0][1]:
             raise TypeError('Unit prefix "%s" can only be with simple Units with an exponent of 1.' % self.prefix)
         base_unit = base_units[0][0]
         # Delegate to Base or Scaled Unit multiply
         new_base_unit = self * base_unit
         new_unit = Unit({new_base_unit: 1.0})
         return new_unit
     else:
         raise TypeError('Unit prefix "%s" can only be applied to a Unit, BaseUnit, or ScaledUnit.' % self.prefix)
Example #3
0
    def copy_stdqt_class(self, name, dstname):
        stdunit = BaseUnit('multicompress', 'StdQtStruct.h', self.config.root)
        cursor = stdunit.find_class_cursor(name)
        if not cursor:
            raise RuntimeError('cannot find class "{}" in file "{}"'.format(
                      name, stdunit.filepath))

        exists, target = util.find_or_insert(self.def_unit.cursor,
                            CursorKind.CLASS_DECL,
                            lambda c : self.is_cache_class(c.spelling),
                            lambda c : c.spelling == dstname)
        if exists:
            print('Class "{}" already exists in file "{}" at line {}'.format(
                    dstname, target.translation_unit.spelling, target.location.line
                ))
        else:
            util.copy_class(cursor, target.extent.end, dstname)

        return cursor
Example #4
0
 def create_unit(self, scale, name, symbol):
     """
     Convenience method for creating a new simple unit from another simple unit.
     Both units must consist of a single BaseUnit.
     """
     # TODO - also handle non-simple units, i.e. units with multiple BaseUnits/ScaledUnits
     assert len(self._top_base_units) == 1
     assert len(self._scaled_units) == 0
     dimension = self._top_base_units.iterkeys().next()
     base_unit_dict = self._top_base_units[dimension]
     assert len(base_unit_dict) == 1
     parent_base_unit = base_unit_dict.iterkeys().next()
     parent_exponent = base_unit_dict[parent_base_unit]
     new_base_unit = BaseUnit(parent_base_unit.dimension, name, symbol)
     # BaseUnit scale might be different depending on exponent
     true_scale = scale
     if parent_exponent != 1.0:
         true_scale = math.pow(scale, 1.0/parent_exponent)
     new_base_unit.define_conversion_factor_to(parent_base_unit, true_scale)
     new_unit = Unit({new_base_unit: 1.0})
     return new_unit
Example #5
0
    def add_notify_method(self, cache_class_name):
        method_name = 'Notify'
        result_type = 'void'
        args = [ ('const vector<SCltRegInfo> &', 'info') ]
        if self.config.notify.stockid:
            args.append(('const char *', 'stockID'))
        if self.config.notify.market:
            args.append(('unsigned short', 'marketID'))
        args.append(('const {} *'.format(cache_class_name), 'data'))
        args.append(('const {} *'.format(cache_class_name), 'old'))

        self.mcd_unit.add_method_declaration(
            'CDataNotify', method_name, result_type, args,
            func_type = util.PURE_VIRTUAL
        )

        unit = BaseUnit('multicachedata', 'notifytransfer.h', self.config.root)
        unit.add_method_declaration(
            'CNotifyTransfrer', method_name, result_type, args,
            func_type = util.VIRTUAL
        )
Example #6
0
    def add_mds_staff(self, cache_class_name):
        ph_unit = BaseUnit('multidatasvr', 'process.h', self.config.root)
        pcpp_unit = BaseUnit('multidatasvr', 'process.cpp', self.config.root)

        if self.config.stock_data:
            macro_name = 'PACK_PC_STK_{}'.format(self.config.DATA_MODEL)
        else:
            macro_name = 'PACK_PC_{}'.format(self.config.DATA_MODEL)

        same, def_cursor = ph_unit.find_or_insert(CursorKind.MACRO_DEFINITION,
                                lambda c : c.spelling.startswith('PACK_PC'),
                                lambda c : c.spelling == macro_name
                           )
        if not same:
            # TODO: libclang does not find macro definition at now.
            last_macro = () # 4-elements tuple(line, length, name, value)
            pattern = re.compile(r'#define +(PACK_PC_\w+) +(\d+)')
            with open(ph_unit.filepath) as f:
                for i, line in enumerate(f):
                    m = pattern.search(line)
                    if m:
                        last_macro = (i, m.group(1), m.group(2))
                        if m.group(2) == macro_name:
                            break

            if last_macro[1] == macro_name:
                print('Macro "{}" is already there'.format(macro_name))
            else:
                text = '#define {:<{}} {}'.format(macro_name, len(last_macro[1]),
                        int(last_macro[2]) + 1)
                util.insert_after_line(ph_unit.filepath, last_macro[0] + 1, text)

        # add the case statement to process.cpp
        cursor = pcpp_unit.find(CursorKind.CXX_METHOD,
                lambda c : c.spelling == '_ProcReq')
        if cursor:
            for c in cursor.get_children():
                if c.kind == CursorKind.COMPOUND_STMT:
                    for c in cursor.get_children():
                        print(c.kind, c.spelling)
Example #7
0
# needed for manipulation of units
from prefix import *
import math
import sys

#####################
### DIMENSIONLESS ###
#####################

# dimensionless = Unit({}); # defined in unit.py

##############
### LENGTH ###
##############

meter_base_unit = BaseUnit(length_dimension, "meter", "m")
meters = meter = Unit({meter_base_unit: 1.0})
define_prefixed_units(meter_base_unit, module=sys.modules[__name__])

angstrom_base_unit = BaseUnit(length_dimension, "angstrom", "A")
angstrom_base_unit.define_conversion_factor_to(meter_base_unit, 1e-10)
angstroms = angstrom = Unit({angstrom_base_unit: 1.0})

planck_length_base_unit = BaseUnit(length_dimension, "Planck length", "l_P")
planck_length_base_unit.define_conversion_factor_to(meter_base_unit,
                                                    1.61625281e-35)

inch_base_unit = BaseUnit(length_dimension, "inch", "in")
inch_base_unit.define_conversion_factor_to(centimeter_base_unit, 2.5400)
inch = inches = Unit({inch_base_unit: 1.0})
Example #8
0
#####################
### DIMENSIONLESS ###
#####################

# dimensionless = Unit({}); # defined in unit.py

##############
### LENGTH ###
##############

meter_base_unit = BaseUnit(length_dimension, "meter", "m")
meters = meter = Unit({meter_base_unit: 1.0})
define_prefixed_units(meter_base_unit, module = sys.modules[__name__])

angstrom_base_unit = BaseUnit(length_dimension, "angstrom", "A")
angstrom_base_unit.define_conversion_factor_to(meter_base_unit, 1e-10)
angstroms = angstrom = Unit({angstrom_base_unit: 1.0})

planck_length_base_unit = BaseUnit(length_dimension, "Planck length", "l_P")
planck_length_base_unit.define_conversion_factor_to(meter_base_unit, 1.61625281e-35)

inch_base_unit = BaseUnit(length_dimension, "inch", "in")
inch_base_unit.define_conversion_factor_to(centimeter_base_unit, 2.5400)
inch = inches = Unit({inch_base_unit: 1.0})

foot_base_unit = BaseUnit(length_dimension, "foot", "ft")
foot_base_unit.define_conversion_factor_to(inch_base_unit, 12.0)
foot = feet = Unit({foot_base_unit: 1.0})

yard_base_unit = BaseUnit(length_dimension, "yard", "yd")
Example #9
0
 def __init__(self, config = 'config'):
     self.config = importlib.import_module(config)
     self.def_unit = BaseUnit('multicachedata', 'stdstructdef.h', self.config.root)
     self.mcd_unit = BaseUnit('multicachedata', 'multicachedata.h', self.config.root)
Example #10
0
class MultiCache(object):
    def __init__(self, config = 'config'):
        self.config = importlib.import_module(config)
        self.def_unit = BaseUnit('multicachedata', 'stdstructdef.h', self.config.root)
        self.mcd_unit = BaseUnit('multicachedata', 'multicachedata.h', self.config.root)

    def add_new_class(self, name):
        if name.startswith(self.config.STD_CLASS_PREFIX):
            cache_class_name = self.config.CACHE_CLASS_PREFIX + \
                    name[len(self.config.STD_CLASS_PREFIX):]
            srccursor = self.copy_stdqt_class(name, cache_class_name)
            self.add_to_embeded_class(srccursor, cache_class_name)
            self.add_notify_method(cache_class_name)
            self.add_mds_staff(cache_class_name)
        else:
            print('class name "{}" does not start with "{}"'.format(name,
                    MultiCache.STD_CLASS_PREFIX))

    def copy_stdqt_class(self, name, dstname):
        stdunit = BaseUnit('multicompress', 'StdQtStruct.h', self.config.root)
        cursor = stdunit.find_class_cursor(name)
        if not cursor:
            raise RuntimeError('cannot find class "{}" in file "{}"'.format(
                      name, stdunit.filepath))

        exists, target = util.find_or_insert(self.def_unit.cursor,
                            CursorKind.CLASS_DECL,
                            lambda c : self.is_cache_class(c.spelling),
                            lambda c : c.spelling == dstname)
        if exists:
            print('Class "{}" already exists in file "{}" at line {}'.format(
                    dstname, target.translation_unit.spelling, target.location.line
                ))
        else:
            util.copy_class(cursor, target.extent.end, dstname)

        return cursor

    def _add_reg_type(self):
        cursor = self.mcd_unit.find(CursorKind.ENUM_DECL,
                    lambda c : c.spelling == 'DataModelType')
        if cursor:
            exist, pos = util.find_or_insert(
                cursor,
                CursorKind.ENUM_CONSTANT_DECL,
                lambda c : True,
                lambda c : c.spelling == self.config.REG_TYPE
            )
            if not exist:
                util.insert_after_line(self.mcd_unit.filepath, pos.extent.end.line,
                        util.INDENT + self.config.REG_TYPE + ',')
        else:
            print('Error: cannot find enum "{}" in file {}'.format(
                self.config.embed_class, self.mcd_unit.filepath)
            )

    def add_to_embeded_class(self, srccursor, cache_class_name):
        impl_class = self.config.embed_impl[1]
        impl_header = BaseUnit('multicachedata',
                               self.config.embed_impl[0]+ '.h',
                               self.config.root)
        impl_cpp = BaseUnit('multicachedata',
                            self.config.embed_impl[0]+ '.cpp',
                            self.config.root)
        def add_convert_method(srccursor):
            method_name = 'Convert'
            result_type = 'void'
            args = [ ('const {} &'.format(srccursor.spelling), 'src'),
                    ('{} &'.format(cache_class_name), 'dest') ]

            impl_header.add_method_declaration(
                impl_class, method_name, result_type, args
            )

            body = ''
            for c in srccursor.get_children():
                if c.kind == CursorKind.FIELD_DECL:
                    body += util.INDENT
                    if c.type.kind == TypeKind.CONSTANTARRAY:
                        body += 'memcpy(dest.{0}, src.{0}, sizeof(dest.{0}));\n'.format(c.spelling)
                    else:
                        body += 'dest.{0} = src.{0};\n'.format(c.spelling)

            impl_cpp.add_method_definitaion(
                impl_class, method_name, result_type, args, body = body
            )

        def add_update_method(data_type):
            method_name = 'Update'
            result_type = 'bool'
            args = [ ('const {} *'.format(data_type), 'data') ]
            impl_header.add_method_declaration(
                impl_class, method_name, result_type, args, func_type = True
            )

            body = ''
            if self.config.embed_impl[0] == 'stddataunitimp':
                body = update_method_tmpl.render(indent = util.INDENT,
                        cache_name = cache_class_name, reg_type = self.config.REG_TYPE,
                        member = self.field_name(cache_class_name)
                    )

            impl_cpp.add_method_definitaion(
                impl_class, method_name, result_type, args, body = body)

        if not self.config.is_embeded:
            return

        cls_cursor = self.mcd_unit.find_class_cursor(self.config.embed_class)
        if not cls_cursor:
            print('Error: cannot find class "{}"'.format(self.config.embed_class))
            return

        # Add field declaration into the embeded class
        exist, cursor = util.find_or_insert(cls_cursor, CursorKind.FIELD_DECL,
                            lambda c : self.is_cache_class(c.type.spelling),
                            lambda c : c.type.spelling == cache_class_name)
        if exist:
            print('Error: "{}" already has field "{}" of type "{}" at line {}'.format(
                   self.config.embed_class, cursor.spelling, cache_class_name,
                   cursor.location.line))
        else:
            util.insert_after_line(self.mcd_unit.filepath, cursor.extent.end.line,
                    util.INDENT + self.field_decl(cache_class_name))

        self._add_reg_type()
        add_convert_method(srccursor)
        add_update_method(srccursor.spelling)

    def add_notify_method(self, cache_class_name):
        method_name = 'Notify'
        result_type = 'void'
        args = [ ('const vector<SCltRegInfo> &', 'info') ]
        if self.config.notify.stockid:
            args.append(('const char *', 'stockID'))
        if self.config.notify.market:
            args.append(('unsigned short', 'marketID'))
        args.append(('const {} *'.format(cache_class_name), 'data'))
        args.append(('const {} *'.format(cache_class_name), 'old'))

        self.mcd_unit.add_method_declaration(
            'CDataNotify', method_name, result_type, args,
            func_type = util.PURE_VIRTUAL
        )

        unit = BaseUnit('multicachedata', 'notifytransfer.h', self.config.root)
        unit.add_method_declaration(
            'CNotifyTransfrer', method_name, result_type, args,
            func_type = util.VIRTUAL
        )

    def add_mds_staff(self, cache_class_name):
        ph_unit = BaseUnit('multidatasvr', 'process.h', self.config.root)
        pcpp_unit = BaseUnit('multidatasvr', 'process.cpp', self.config.root)

        if self.config.stock_data:
            macro_name = 'PACK_PC_STK_{}'.format(self.config.DATA_MODEL)
        else:
            macro_name = 'PACK_PC_{}'.format(self.config.DATA_MODEL)

        same, def_cursor = ph_unit.find_or_insert(CursorKind.MACRO_DEFINITION,
                                lambda c : c.spelling.startswith('PACK_PC'),
                                lambda c : c.spelling == macro_name
                           )
        if not same:
            # TODO: libclang does not find macro definition at now.
            last_macro = () # 4-elements tuple(line, length, name, value)
            pattern = re.compile(r'#define +(PACK_PC_\w+) +(\d+)')
            with open(ph_unit.filepath) as f:
                for i, line in enumerate(f):
                    m = pattern.search(line)
                    if m:
                        last_macro = (i, m.group(1), m.group(2))
                        if m.group(2) == macro_name:
                            break

            if last_macro[1] == macro_name:
                print('Macro "{}" is already there'.format(macro_name))
            else:
                text = '#define {:<{}} {}'.format(macro_name, len(last_macro[1]),
                        int(last_macro[2]) + 1)
                util.insert_after_line(ph_unit.filepath, last_macro[0] + 1, text)

        # add the case statement to process.cpp
        cursor = pcpp_unit.find(CursorKind.CXX_METHOD,
                lambda c : c.spelling == '_ProcReq')
        if cursor:
            for c in cursor.get_children():
                if c.kind == CursorKind.COMPOUND_STMT:
                    for c in cursor.get_children():
                        print(c.kind, c.spelling)

    def field_decl(self, cache_class_name):
        return cache_class_name + ' ' + self.field_name(cache_class_name)  + ';'

    def field_name(self, cache_class_name):
        name = cache_class_name[len(self.config.CACHE_CLASS_PREFIX):]
        return 'm_' + name[0].lower() + name[1:]

    def is_cache_class(self, class_name):
        return class_name.startswith(self.config.CACHE_CLASS_PREFIX)