CANLibrary/pycrc/crc_symtable.py

1354 lines
44 KiB
Python

# -*- coding: Latin-1 -*-
# pycrc -- parametrisable CRC calculation utility and C source code generator
#
# Copyright (c) 2006-2012 Thomas Pircher <tehpeh@gmx.net>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
"""
Symbol table for the macro processor used by pycrc.
use as follows:
from crc_opt import Options
from crc_symtable import SymbolTable
opt = Options("0.6")
sym = SymbolTable(opt)
str = " .... "
terminal = sym.getTerminal(str)
"""
from crc_algorithms import Crc
import time
import os
# Class SymbolTable
###############################################################################
class SymbolTable:
"""
The symbol table class.
"""
opt = None
table = {}
# Class constructor
###############################################################################
def __init__(self, opt):
"""
The class constructor.
"""
self.opt = opt
self.table["nop"] = ""
self.table["datetime"] = time.asctime()
self.table["program_version"] = self.opt.VersionStr
self.table["program_url"] = self.opt.WebAddress
if self.opt.OutputFile == None:
self.table["filename"] = "pycrc_stdout"
else:
self.table["filename"] = self.opt.OutputFile
if self.opt.OutputFile == None:
self.table["header_filename"] = "pycrc_stdout.h"
elif self.opt.OutputFile[-2:] == ".c":
self.table["header_filename"] = self.opt.OutputFile[0:-1] + "h"
else:
self.table["header_filename"] = self.opt.OutputFile + ".h"
self.table["crc_width"] = self.__pretty_str(self.opt.Width)
self.table["crc_poly"] = self.__pretty_hex(self.opt.Poly, self.opt.Width)
self.table["crc_reflect_in"] = self.__pretty_bool(self.opt.ReflectIn)
self.table["crc_xor_in"] = self.__pretty_hex(self.opt.XorIn, self.opt.Width)
self.table["crc_reflect_out"] = self.__pretty_bool(self.opt.ReflectOut)
self.table["crc_xor_out"] = self.__pretty_hex(self.opt.XorOut, self.opt.Width)
self.table["crc_table_idx_width"] = str(self.opt.TableIdxWidth)
self.table["crc_table_width"] = str(1 << self.opt.TableIdxWidth)
self.table["crc_table_mask"] = self.__pretty_hex(self.opt.TableWidth - 1, 8)
self.table["crc_mask"] = self.__pretty_hex(self.opt.Mask, self.opt.Width)
self.table["crc_msb_mask"] = self.__pretty_hex(self.opt.MSB_Mask, self.opt.Width)
if self.opt.Algorithm == self.opt.Algo_Table_Driven and (self.opt.Width == None or self.opt.Width < 8):
self.table["crc_do_shift"] = self.__pretty_bool(True)
if self.opt.Width == None:
self.table["crc_shift"] = self.__pretty_str(None)
else:
self.table["crc_shift"] = self.__pretty_str(8 - self.opt.Width)
else:
self.table["crc_do_shift"] = self.__pretty_bool(False)
self.table["crc_shift"] = self.__pretty_str(0)
self.table["cfg_width"] = "$if ($crc_width != Undefined) {:$crc_width:} $else {:cfg->width:}"
self.table["cfg_poly"] = "$if ($crc_poly != Undefined) {:$crc_poly:} $else {:cfg->poly:}"
self.table["cfg_poly_shifted"] = "$if ($crc_do_shift == True) {:($cfg_poly << $cfg_shift):} $else {:$cfg_poly:}"
self.table["cfg_reflect_in"] = "$if ($crc_reflect_in != Undefined) {:$crc_reflect_in:} $else {:cfg->reflect_in:}"
self.table["cfg_xor_in"] = "$if ($crc_xor_in != Undefined) {:$crc_xor_in:} $else {:cfg->xor_in:}"
self.table["cfg_reflect_out"] = "$if ($crc_reflect_out != Undefined) {:$crc_reflect_out:} $else {:cfg->reflect_out:}"
self.table["cfg_xor_out"] = "$if ($crc_xor_out != Undefined) {:$crc_xor_out:} $else {:cfg->xor_out:}"
self.table["cfg_table_idx_width"] = "$if ($crc_table_idx_width != Undefined) {:$crc_table_idx_width:} $else {:cfg->table_idx_width:}"
self.table["cfg_table_width"] = "$if ($crc_table_width != Undefined) {:$crc_table_width:} $else {:cfg->table_width:}"
self.table["cfg_mask"] = "$if ($crc_mask != Undefined) {:$crc_mask:} $else {:cfg->crc_mask:}"
self.table["cfg_mask_shifted"] = "$if ($crc_do_shift == True) {:($cfg_mask << $cfg_shift):} $else {:$cfg_mask:}"
self.table["cfg_msb_mask"] = "$if ($crc_msb_mask != Undefined) {:$crc_msb_mask:} $else {:cfg->msb_mask:}"
self.table["cfg_msb_mask_shifted"] = "$if ($crc_do_shift == True) {:($cfg_msb_mask << $cfg_shift):} $else {:$cfg_msb_mask:}"
self.table["cfg_shift"] = "$if ($crc_shift != Undefined) {:$crc_shift:} $else {:cfg->crc_shift:}"
self.table["undefined_parameters"] = self.__pretty_bool(self.opt.UndefinedCrcParameters)
self.table["use_cfg_t"] = self.__pretty_bool(self.opt.UndefinedCrcParameters)
self.table["c_std"] = self.opt.CStd
self.table["c_bool"] = "$if ($c_std == C89) {:int:} $else {:bool:}"
self.table["c_true"] = "$if ($c_std == C89) {:1:} $else {:true:}"
self.table["c_false"] = "$if ($c_std == C89) {:0:} $else {:false:}"
self.table["underlying_crc_t"] = self.__get_underlying_crc_t()
self.table["include_file"] = self.__get_include_file()
self.table["crc_prefix"] = self.opt.SymbolPrefix
self.table["crc_t"] = self.opt.SymbolPrefix + "t"
self.table["cfg_t"] = self.opt.SymbolPrefix + "cfg_t"
self.table["crc_reflect_function"] = self.opt.SymbolPrefix + "reflect"
self.table["crc_table_gen_function"] = self.opt.SymbolPrefix + "table_gen"
self.table["crc_init_function"] = self.opt.SymbolPrefix + "init"
self.table["crc_update_function"] = self.opt.SymbolPrefix + "update"
self.table["crc_finalize_function"] = self.opt.SymbolPrefix + "finalize"
# function getTerminal
###############################################################################
def getTerminal(self, id):
"""
Return the expanded terminal, if it exists or None otherwise.
"""
if id != None:
if id == "":
return ""
if id in self.table:
return self.table[id]
key = self.__getTerminal(id)
if key != None:
self.table[id] = key
return key
raise LookupError
# function __getTerminal
###############################################################################
def __getTerminal(self, id):
"""
Return the expanded terminal, if it exists or None otherwise.
"""
if id == "constant_crc_init":
if self.__get_init_value() == None:
return self.__pretty_bool(False)
else:
return self.__pretty_bool(True)
if id == "constant_crc_table":
if self.opt.Width != None and self.opt.Poly != None and self.opt.ReflectIn != None:
return self.__pretty_bool(True)
else:
return self.__pretty_bool(False)
elif id == "simple_crc_update_def":
if self.opt.Algorithm in set([self.opt.Algo_Bit_by_Bit, self.opt.Algo_Bit_by_Bit_Fast]):
if self.opt.Width != None and self.opt.Poly != None and self.opt.ReflectIn != None:
return self.__pretty_bool(True)
elif self.opt.Algorithm == self.opt.Algo_Table_Driven:
if self.opt.Width != None and self.opt.ReflectIn != None:
return self.__pretty_bool(True)
return self.__pretty_bool(False)
elif id == "inline_crc_finalize":
if self.opt.Algorithm in set([self.opt.Algo_Bit_by_Bit_Fast, self.opt.Algo_Table_Driven]) and \
(self.opt.Width != None and self.opt.ReflectIn != None and self.opt.ReflectOut != None and self.opt.XorOut != None):
return self.__pretty_bool(True)
else:
return self.__pretty_bool(False)
elif id == "simple_crc_finalize_def":
if self.opt.Algorithm == self.opt.Algo_Bit_by_Bit:
if self.opt.Width != None and self.opt.Poly != None and self.opt.ReflectOut != None and self.opt.XorOut != None:
return self.__pretty_bool(True)
elif self.opt.Algorithm == self.opt.Algo_Bit_by_Bit_Fast:
if self.opt.Width != None and self.opt.ReflectOut != None and self.opt.XorOut != None:
return self.__pretty_bool(True)
elif self.opt.Algorithm == self.opt.Algo_Table_Driven:
if self.opt.Width != None and self.opt.ReflectIn != None and self.opt.ReflectOut != None and self.opt.XorOut != None:
return self.__pretty_bool(True)
return self.__pretty_bool(False)
elif id == "use_reflect_func":
if self.opt.ReflectOut == False and self.opt.ReflectIn == False:
return self.__pretty_bool(False)
else:
return self.__pretty_bool(True)
elif id == "static_reflect_func":
if self.opt.Algorithm == self.opt.Algo_Table_Driven:
return self.__pretty_bool(False)
elif self.opt.ReflectOut != None and self.opt.Algorithm == self.opt.Algo_Bit_by_Bit_Fast:
return self.__pretty_bool(False)
else:
return self.__pretty_bool(True)
elif id == "crc_algorithm":
if self.opt.Algorithm == self.opt.Algo_Bit_by_Bit:
return "bit-by-bit"
elif self.opt.Algorithm == self.opt.Algo_Bit_by_Bit_Fast:
return "bit-by-bit-fast"
elif self.opt.Algorithm == self.opt.Algo_Table_Driven:
return "table-driven"
else:
return "UNDEFINED"
elif id == "crc_table_init":
return self.__get_table_init()
elif id == "crc_table_core_algorithm_ni":
return self.__get_table_core_algorithm_ni()
elif id == "crc_table_core_algorithm_ri":
return self.__get_table_core_algorithm_ri()
elif id == "header_protection":
return self.__pretty_hdrprotection()
elif id == "crc_init_value":
ret = self.__get_init_value()
if ret == None:
return ""
else:
return ret
elif id == "crc_final_value":
return """\
$if ($crc_algorithm == "table-driven") {:
$if ($crc_reflect_in == $crc_reflect_out) {:
$if ($crc_do_shift == True) {:(crc >> $cfg_shift):} $else {:crc:} ^ $crc_xor_out\
:} $else {:
$crc_reflect_function($if ($crc_do_shift == True) {:(crc >> $cfg_shift):} $else {:crc:}, $crc_width) ^ $crc_xor_out\
:}:} $elif ($crc_reflect_out == True) {:
$crc_reflect_function(crc, $crc_width) ^ $crc_xor_out\
:} $else {:
crc ^ $crc_xor_out\
:}\
"""
elif id == "h_template":
return """\
$source_header
#ifndef $header_protection
#define $header_protection
$if ($include_file != Undefined) {:
#include $include_file
:}
#include <stdlib.h>
$if ($c_std != C89) {:
#include <stdint.h>
:}
$if ($undefined_parameters == True and $c_std != C89) {:
#include <stdbool.h>
:}
#ifdef __cplusplus
extern "C" {
#endif
/**
* The definition of the used algorithm.
*****************************************************************************/
$if ($crc_algorithm == "bit-by-bit") {:
#define CRC_ALGO_BIT_BY_BIT 1
:} $elif ($crc_algorithm == "bit-by-bit-fast") {:
#define CRC_ALGO_BIT_BY_BIT_FAST 1
:} $elif ($crc_algorithm == "table-driven") {:
#define CRC_ALGO_TABLE_DRIVEN 1
:}
/**
* The type of the CRC values.
*
* This type must be big enough to contain at least $cfg_width bits.
*****************************************************************************/
typedef $underlying_crc_t $crc_t;
$if ($undefined_parameters == True) {:
/**
* The configuration type of the CRC algorithm.
*****************************************************************************/
typedef struct {
$if ($crc_width == Undefined) {:
unsigned int width; /*!< The width of the polynomial */
:}
$if ($crc_poly == Undefined) {:
$crc_t poly; /*!< The CRC polynomial */
:}
$if ($crc_reflect_in == Undefined) {:
$c_bool reflect_in; /*!< Whether the input shall be reflected or not */
:}
$if ($crc_xor_in == Undefined) {:
$crc_t xor_in; /*!< The initial value of the algorithm */
:}
$if ($crc_reflect_out == Undefined) {:
$c_bool reflect_out; /*!< Wether the output shall be reflected or not */
:}
$if ($crc_xor_out == Undefined) {:
$crc_t xor_out; /*!< The value which shall be XOR-ed to the final CRC value */
:}
$if ($crc_width == Undefined) {:
/* internal parameters */
$crc_t msb_mask; /*!< a bitmask with the Most Significant Bit set to 1
initialise as 1UL << (width - 1) */
$crc_t crc_mask; /*!< a bitmask with all width bits set to 1
initialise as (cfg->msb_mask - 1) | cfg->msb_mask */
unsigned int crc_shift; /*!< a shift count that is used when width < 8
initialise as cfg->width < 8 ? 8 - cfg->width : 0 */
:}
} $cfg_t;
:}
$if ($use_reflect_func == True and $static_reflect_func != True) {:
$crc_reflect_doc
$crc_reflect_function_def;
:}
$if ($crc_algorithm == "table-driven" and $constant_crc_table != True) {:
$crc_table_gen_doc
$crc_table_gen_function_def;
:}
$crc_init_doc
$if ($constant_crc_init == False) {:
$crc_init_function_def;
:} $elif ($c_std == C89) {:
#define $crc_init_function() ($crc_init_value$if ($crc_do_shift == True) {: << $cfg_shift:})
:} $else {:
static inline $crc_init_function_def$nop
{
return $crc_init_value$if ($crc_do_shift == True) {: << $cfg_shift:};
}
:}
$crc_update_doc
$crc_update_function_def;
$crc_finalize_doc
$if ($inline_crc_finalize == True) {:
$if ($c_std == C89) {:
#define $crc_finalize_function(crc) ($crc_final_value)
:} $else {:
static inline $crc_finalize_function_def$nop
{
return $crc_final_value;
}
:}
:} $else {:
$crc_finalize_function_def;
:}
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
#endif /* $header_protection */
"""
elif id == "source_header":
return """\
/**
* \\file $filename
* Functions and types for CRC checks.
*
* Generated on $datetime,
* by $program_version, $program_url
* using the configuration:
* Width = $crc_width
* Poly = $crc_poly
* XorIn = $crc_xor_in
* ReflectIn = $crc_reflect_in
* XorOut = $crc_xor_out
* ReflectOut = $crc_reflect_out
* Algorithm = $crc_algorithm
*****************************************************************************/\
"""
elif id == "crc_reflect_doc":
return """\
/**
* Reflect all bits of a \\a data word of \\a data_len bytes.
*
* \\param data The data word to be reflected.
* \\param data_len The width of \\a data expressed in number of bits.
* \\return The reflected data.
*****************************************************************************/\
"""
elif id == "crc_reflect_function_def":
return """\
$crc_t $crc_reflect_function($crc_t data, size_t data_len)\
"""
elif id == "crc_reflect_function_body":
return """\
$if ($crc_reflect_in == Undefined or $crc_reflect_in == True or $crc_reflect_out == Undefined or $crc_reflect_out == True) {:
$crc_reflect_doc
$crc_reflect_function_def$nop
{
unsigned int i;
$crc_t ret;
ret = data & 0x01;
for (i = 1; i < data_len; i++) {
data >>= 1;
ret = (ret << 1) | (data & 0x01);
}
return ret;
}
:}\
"""
elif id == "crc_table_gen_doc":
return """\
/**
* Populate the private static crc table.
*
* \\param cfg A pointer to a initialised $cfg_t structure.
* \\return void
*****************************************************************************/\
"""
elif id == "crc_table_gen_function_def":
return """\
void $crc_table_gen_function(const $cfg_t *cfg)\
"""
elif id == "crc_init_doc":
return """\
/**
* Calculate the initial crc value.
*
$if ($use_cfg_t == True) {:
* \\param cfg A pointer to a initialised $cfg_t structure.
:}
* \\return The initial crc value.
*****************************************************************************/\
"""
elif id == "crc_init_function_def":
return """\
$if ($constant_crc_init == False) {:
$crc_t $crc_init_function(const $cfg_t *cfg)\
:} $else {:
$crc_t $crc_init_function(void)\
:}\
"""
elif id == "crc_update_doc":
return """\
/**
* Update the crc value with new data.
*
* \\param crc The current crc value.
$if ($simple_crc_update_def != True) {:
* \\param cfg A pointer to a initialised $cfg_t structure.
:}
* \\param data Pointer to a buffer of \\a data_len bytes.
* \\param data_len Number of bytes in the \\a data buffer.
* \\return The updated crc value.
*****************************************************************************/\
"""
elif id == "crc_update_function_def":
return """\
$if ($simple_crc_update_def != True) {:
$crc_t $crc_update_function(const $cfg_t *cfg, $crc_t crc, const unsigned char *data, size_t data_len)\
:} $else {:
$crc_t $crc_update_function($crc_t crc, const unsigned char *data, size_t data_len)\
:}\
"""
elif id == "crc_finalize_doc":
return """\
/**
* Calculate the final crc value.
*
$if ($simple_crc_finalize_def != True) {:
* \\param cfg A pointer to a initialised $cfg_t structure.
:}
* \\param crc The current crc value.
* \\return The final crc value.
*****************************************************************************/\
"""
elif id == "crc_finalize_function_def":
return """\
$if ($simple_crc_finalize_def != True) {:
$crc_t $crc_finalize_function(const $cfg_t *cfg, $crc_t crc)\
:} $else {:
$crc_t $crc_finalize_function($crc_t crc)\
:}\
"""
elif id == "c_template":
return """\
$source_header
$if ($include_file != Undefined) {:
#include $include_file
:}
#include "$header_filename" /* include the header file generated with pycrc */
#include <stdlib.h>
$if ($c_std != C89) {:
#include <stdint.h>
$if ($undefined_parameters == True or $crc_algorithm == "bit-by-bit" or $crc_algorithm == "bit-by-bit-fast") {:
#include <stdbool.h>
:}
:}
$if ($use_reflect_func == True and $static_reflect_func == True) {:
static $crc_reflect_function_def;
:}
$if ($crc_algorithm == "bit-by-bit") {:
$c_bit_by_bit
:} $elif ($crc_algorithm == "bit-by-bit-fast") {:
$c_bit_by_bit_fast
:} $elif ($crc_algorithm == "table-driven") {:
$c_table_driven
:}
"""
elif id == "c_table":
return """\
/**
* Static table used for the table_driven implementation.
$if ($undefined_parameters == True) {:
* Must be initialised with the $crc_init_function function.
:}
*****************************************************************************/
$if ($constant_crc_table != True) {:
static $crc_t crc_table[$crc_table_width];
:} $else {:
static const $crc_t crc_table[$crc_table_width] = {
$crc_table_init
};
:}
"""
elif id == "c_bit_by_bit":
return """\
$if ($use_reflect_func == True) {:
$crc_reflect_function_body
:}
$if ($constant_crc_init == False) {:
$crc_init_doc
$crc_init_function_def$nop
{
unsigned int i;
$c_bool bit;
$crc_t crc = $cfg_xor_in;
for (i = 0; i < $cfg_width; i++) {
bit = crc & 0x01;
if (bit) {
crc = ((crc ^ $cfg_poly) >> 1) | $cfg_msb_mask;
} else {
crc >>= 1;
}
}
return crc & $cfg_mask;
}
:}
$crc_update_doc
$crc_update_function_def$nop
{
unsigned int i;
$c_bool bit;
unsigned char c;
while (data_len--) {
$if ($crc_reflect_in == Undefined) {:
if ($cfg_reflect_in) {
c = $crc_reflect_function(*data++, 8);
} else {
c = *data++;
}
:} $elif ($crc_reflect_in == True) {:
c = $crc_reflect_function(*data++, 8);
:} $else {:
c = *data++;
:}
for (i = 0; i < 8; i++) {
bit = $if ($c_std == C89) {:!!(crc & $cfg_msb_mask):} $else {:crc & $cfg_msb_mask:};
crc = (crc << 1) | ((c >> (7 - i)) & 0x01);
if (bit) {
crc ^= $cfg_poly;
}
}
crc &= $cfg_mask;
}
return crc & $cfg_mask;
}
$crc_finalize_doc
$crc_finalize_function_def$nop
{
unsigned int i;
$c_bool bit;
for (i = 0; i < $cfg_width; i++) {
bit = $if ($c_std == C89) {:!!(crc & $cfg_msb_mask):} $else {:crc & $cfg_msb_mask:};
crc = (crc << 1) | 0x00;
if (bit) {
crc ^= $cfg_poly;
}
}
$if ($crc_reflect_out == Undefined) {:
if ($cfg_reflect_out) {
crc = $crc_reflect_function(crc, $cfg_width);
}
:} $elif ($crc_reflect_out == True) {:
crc = $crc_reflect_function(crc, $cfg_width);
:}
return (crc ^ $cfg_xor_out) & $cfg_mask;
}
"""
elif id == "c_bit_by_bit_fast":
return """\
$if ($use_reflect_func == True) {:
$crc_reflect_function_body
:}
$if ($constant_crc_init == False) {:
$crc_init_doc
$crc_init_function_def$nop
{
return $cfg_xor_in & $cfg_mask;
}
:}
$crc_update_doc
$crc_update_function_def$nop
{
unsigned int i;
$c_bool bit;
unsigned char c;
while (data_len--) {
$if ($crc_reflect_in == Undefined) {:
if ($cfg_reflect_in) {
c = $crc_reflect_function(*data++, 8);
} else {
c = *data++;
}
:} $else {:
c = *data++;
:}
$if ($crc_reflect_in == True) {:
for (i = 0x01; i & 0xff; i <<= 1) {
:} $else {:
for (i = 0x80; i > 0; i >>= 1) {
:}
bit = $if ($c_std == C89) {:!!(crc & $cfg_msb_mask):} $else {:crc & $cfg_msb_mask:};
if (c & i) {
bit = !bit;
}
crc <<= 1;
if (bit) {
crc ^= $cfg_poly;
}
}
crc &= $cfg_mask;
}
return crc & $cfg_mask;
}
$if ($inline_crc_finalize != True) {:
$crc_finalize_doc
$crc_finalize_function_def$nop
{
$if ($crc_reflect_out == Undefined) {:
if (cfg->reflect_out) {
crc = $crc_reflect_function(crc, $cfg_width);
}
:} $elif ($crc_reflect_out == True) {:
crc = $crc_reflect_function(crc, $cfg_width);
:}
return (crc ^ $cfg_xor_out) & $cfg_mask;
}
:}
"""
elif id == "c_table_driven":
return """\
$c_table
$if ($use_reflect_func == True) {:
$crc_reflect_function_body
:}
$if ($constant_crc_init == False) {:
$crc_init_doc
$crc_init_function_def$nop
{
$if ($crc_reflect_in == Undefined) {:
if ($cfg_reflect_in) {
return $crc_reflect_function($cfg_xor_in & $cfg_mask, $cfg_width)$if ($crc_do_shift == True) {: << $cfg_shift:};
} else {
return $cfg_xor_in & $cfg_mask$if ($crc_do_shift == True) {: << $cfg_shift:};
}
:} $elif ($crc_reflect_in == True) {:
return $crc_reflect_function($cfg_xor_in & $cfg_mask, $cfg_width)$if ($crc_do_shift == True) {: << $cfg_shift:};
:} $else {:
return $cfg_xor_in & $cfg_mask$if ($crc_do_shift == True) {: << $cfg_shift:};
:}
}
:}
$if ($constant_crc_table != True) {:
$crc_table_gen_doc
$crc_table_gen_function_def
{
$crc_t crc;
unsigned int i, j;
for (i = 0; i < $cfg_table_width; i++) {
$if ($crc_reflect_in == Undefined) {:
if (cfg->reflect_in) {
crc = $crc_reflect_function(i, $cfg_table_idx_width);
} else {
crc = i;
}
:} $elif ($crc_reflect_in == True) {:
crc = $crc_reflect_function(i, $cfg_table_idx_width);
:} $else {:
crc = i;
:}
$if ($crc_do_shift == True) {:
crc <<= ($cfg_width - $cfg_table_idx_width + $cfg_shift);
:} $else {:
crc <<= ($cfg_width - $cfg_table_idx_width);
:}
for (j = 0; j < $cfg_table_idx_width; j++) {
if (crc & $cfg_msb_mask_shifted) {
crc = (crc << 1) ^ $cfg_poly_shifted;
} else {
crc = crc << 1;
}
}
$if ($crc_reflect_in == Undefined) {:
if (cfg->reflect_in) {
$if ($crc_do_shift == True) {:
crc = $crc_reflect_function(crc >> $cfg_shift, $cfg_width) << $cfg_shift;
:} $else {:
crc = $crc_reflect_function(crc, $cfg_width);
:}
}
:} $elif ($crc_reflect_in == True) {:
$if ($crc_do_shift == True) {:
crc = $crc_reflect_function(crc >> $cfg_shift, $cfg_width) << $cfg_shift;
:} $else {:
crc = $crc_reflect_function(crc, $cfg_width);
:}
:}
crc_table[i] = crc & $cfg_mask_shifted;
}
}
:}
$crc_update_doc
$crc_update_function_def$nop
{
unsigned int tbl_idx;
$if ($crc_reflect_in == Undefined) {:
if (cfg->reflect_in) {
while (data_len--) {
$crc_table_core_algorithm_ri
data++;
}
} else {
while (data_len--) {
$crc_table_core_algorithm_ni
data++;
}
}
:} $else {:
while (data_len--) {
$if ($crc_reflect_in == True) {:
$crc_table_core_algorithm_ri
:} $elif ($crc_reflect_in == False) {:
$crc_table_core_algorithm_ni
:}
data++;
}
:}
return crc & $cfg_mask_shifted;
}
$if ($inline_crc_finalize == False) {:
$crc_finalize_doc
$crc_finalize_function_def$nop
{
$if ($crc_do_shift == True) {:
crc >>= $cfg_shift;
:}
$if ($crc_reflect_in == Undefined or $crc_reflect_out == Undefined) {:
$if ($crc_reflect_in == Undefined and $crc_reflect_out == Undefined) {:
if (cfg->reflect_in == !cfg->reflect_out):}
$elif ($crc_reflect_out == Undefined) {:
if ($if ($crc_reflect_in == True) {:!:}cfg->reflect_out):}
$elif ($crc_reflect_in == Undefined) {:
if ($if ($crc_reflect_out == True) {:!:}cfg->reflect_in):} {
crc = $crc_reflect_function(crc, $cfg_width);
}
:} $elif ($crc_reflect_in != $crc_reflect_out) {:
crc = $crc_reflect_function(crc, $cfg_width);
:}
return (crc ^ $cfg_xor_out) & $cfg_mask;
}
:}
"""
elif id == "main_template":
return """\
$if ($include_file != Undefined) {:
#include $include_file
:}
#include <stdio.h>
#include <getopt.h>
$if ($undefined_parameters == True) {:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
:}
$if ($c_std != C89) {:
#include <stdbool.h>
:}
#include <string.h>
static char str[256] = "123456789";
static $c_bool verbose = $c_false;
void print_params($if ($undefined_parameters == True) {:const $cfg_t *cfg:} $else {:void:});
$getopt_template
void print_params($if ($undefined_parameters == True) {:const $cfg_t *cfg:} $else {:void:})
{
char format[20];
snprintf(format, sizeof(format), "%%-16s = 0x%%0%dx\\n", (unsigned int)($cfg_width + 3) / 4);
printf("%-16s = %d\\n", "width", (unsigned int)$cfg_width);
printf(format, "poly", (unsigned int)$cfg_poly);
printf("%-16s = %s\\n", "reflect_in", $if ($crc_reflect_in == Undefined) {:$cfg_reflect_in ? "true": "false":} $else {:$if ($crc_reflect_in == True) {:"true":} $else {:"false":}:});
printf(format, "xor_in", $cfg_xor_in);
printf("%-16s = %s\\n", "reflect_out", $if ($crc_reflect_out == Undefined) {:$cfg_reflect_out ? "true": "false":} $else {:$if ($crc_reflect_out == True) {:"true":} $else {:"false":}:});
printf(format, "xor_out", (unsigned int)$cfg_xor_out);
printf(format, "crc_mask", (unsigned int)$cfg_mask);
printf(format, "msb_mask", (unsigned int)$cfg_msb_mask);
}
/**
* C main function.
*
* \\return 0 on success, != 0 on error.
*****************************************************************************/
int main(int argc, char *argv[])
{
$if ($undefined_parameters == True) {:
$cfg_t cfg = {
$if ($crc_width == Undefined) {:
0, /* width */
:}
$if ($crc_poly == Undefined) {:
0, /* poly */
:}
$if ($crc_xor_in == Undefined) {:
0, /* xor_in */
:}
$if ($crc_reflect_in == Undefined) {:
0, /* reflect_in */
:}
$if ($crc_xor_out == Undefined) {:
0, /* xor_out */
:}
$if ($crc_reflect_out == Undefined) {:
0, /* reflect_out */
:}
$if ($crc_width == Undefined) {:
0, /* crc_mask */
0, /* msb_mask */
0, /* crc_shift */
:}
};
:}
$crc_t crc;
$if ($undefined_parameters == True) {:
get_config(argc, argv, &cfg);
:} $else {:
get_config(argc, argv);
:}
$if ($crc_algorithm == "table-driven" and $constant_crc_table != True) {:
$crc_table_gen_function(&cfg);
:}
crc = $crc_init_function($if ($constant_crc_init != True) {:&cfg:});
crc = $crc_update_function($if ($simple_crc_update_def != True) {:&cfg, :}crc, (unsigned char *)str, strlen(str));
crc = $crc_finalize_function($if ($simple_crc_finalize_def != True) {:&cfg, :}crc);
if (verbose) {
print_params($if ($undefined_parameters == True) {:&cfg:});
}
printf("0x%lx\\n", (unsigned long)crc);
return 0;
}
"""
elif id == "getopt_template":
return """\
$if ($crc_reflect_in == Undefined or $crc_reflect_out == Undefined) {:
static $c_bool atob(const char *str);
:}
$if ($crc_poly == Undefined or $crc_xor_in == Undefined or $crc_xor_out == Undefined) {:
static crc_t xtoi(const char *str);
:}
static int get_config(int argc, char *argv[]$if ($undefined_parameters == True) {:, $cfg_t *cfg:});
$if ($crc_reflect_in == Undefined or $crc_reflect_out == Undefined) {:
$c_bool atob(const char *str)
{
if (!str) {
return 0;
}
if (isdigit(str[0])) {
return ($c_bool)atoi(str);
}
if (tolower(str[0]) == 't') {
return $c_true;
}
return $c_false;
}
:}
$if ($crc_poly == Undefined or $crc_xor_in == Undefined or $crc_xor_out == Undefined) {:
crc_t xtoi(const char *str)
{
crc_t ret = 0;
if (!str) {
return 0;
}
if (str[0] == '0' && tolower(str[1]) == 'x') {
str += 2;
while (*str) {
if (isdigit(*str))
ret = 16 * ret + *str - '0';
else if (isxdigit(*str))
ret = 16 * ret + tolower(*str) - 'a' + 10;
else
return ret;
str++;
}
} else if (isdigit(*str)) {
while (*str) {
if (isdigit(*str))
ret = 10 * ret + *str - '0';
else
return ret;
str++;
}
}
return ret;
}
:}
static int get_config(int argc, char *argv[]$if ($undefined_parameters == True) {:, $cfg_t *cfg:})
{
int c;
int option_index;
static struct option long_options[] = {
$if ($crc_width == Undefined) {:
{"width", 1, 0, 'w'},
:}
$if ($crc_poly == Undefined) {:
{"poly", 1, 0, 'p'},
:}
$if ($crc_reflect_in == Undefined) {:
{"reflect-in", 1, 0, 'n'},
:}
$if ($crc_xor_in == Undefined) {:
{"xor-in", 1, 0, 'i'},
:}
$if ($crc_reflect_out == Undefined) {:
{"reflect-out", 1, 0, 'u'},
:}
$if ($crc_xor_out == Undefined) {:
{"xor-out", 1, 0, 'o'},
:}
{"verbose", 0, 0, 'v'},
{"check-string", 1, 0, 's'},
$if ($crc_width == Undefined) {:
{"table-idx-with", 1, 0, 't'},
:}
{0, 0, 0, 0}
};
while (1) {
option_index = 0;
c = getopt_long (argc, argv, "w:p:n:i:u:o:s:vt", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\\n");
$if ($crc_width == Undefined) {:
case 'w':
cfg->width = atoi(optarg);
break;
:}
$if ($crc_poly == Undefined) {:
case 'p':
cfg->poly = xtoi(optarg);
break;
:}
$if ($crc_reflect_in == Undefined) {:
case 'n':
cfg->reflect_in = atob(optarg);
break;
:}
$if ($crc_xor_in == Undefined) {:
case 'i':
cfg->xor_in = xtoi(optarg);
break;
:}
$if ($crc_reflect_out == Undefined) {:
case 'u':
cfg->reflect_out = atob(optarg);
break;
:}
$if ($crc_xor_out == Undefined) {:
case 'o':
cfg->xor_out = xtoi(optarg);
break;
:}
case 's':
memcpy(str, optarg, strlen(optarg) < sizeof(str) ? strlen(optarg) + 1 : sizeof(str));
str[sizeof(str) - 1] = '\\0';
break;
case 'v':
verbose = $c_true;
break;
$if ($crc_width == Undefined) {:
case 't':
/* ignore --table_idx_width option */
break;
:}
case '?':
return -1;
case ':':
fprintf(stderr, "missing argument to option %c\\n", c);
return -1;
default:
fprintf(stderr, "unhandled option %c\\n", c);
return -1;
}
}
$if ($crc_width == Undefined) {:
cfg->msb_mask = 1UL << (cfg->width - 1);
cfg->crc_mask = (cfg->msb_mask - 1) | cfg->msb_mask;
cfg->crc_shift = cfg->width < 8 ? 8 - cfg->width : 0;
:}
$if ($crc_poly == Undefined) {:
cfg->poly &= $cfg_mask;
:}
$if ($crc_xor_in == Undefined) {:
cfg->xor_in &= $cfg_mask;
:}
$if ($crc_xor_out == Undefined) {:
cfg->xor_out &= $cfg_mask;
:}
return 0;
}\
"""
# function __pretty_str
###############################################################################
def __pretty_str(self, value):
"""
Return a value of width bits as a pretty string.
"""
if value == None:
return "Undefined"
return str(value)
# function __pretty_hex
###############################################################################
def __pretty_hex(self, value, width = None):
"""
Return a value of width bits as a pretty hexadecimal formatted string.
"""
if value == None:
return "Undefined"
if width == None:
return "0x%x" % value
width = (width + 3) // 4
hex_str = "0x%%0%dx" % width
return hex_str % value
# function __pretty_bool
###############################################################################
def __pretty_bool(self, value):
"""
Return a boolen value of width bits as a pretty formatted string.
"""
if value == None:
return "Undefined"
if value:
return "True"
else:
return "False"
# function __pretty_hdrprotection
###############################################################################
def __pretty_hdrprotection(self):
"""
Return the name of a C header protection (e.g. __CRC_IMPLEMENTATION_H__).
"""
tr_str = ""
for i in range(256):
if chr(i).isalpha():
tr_str += chr(i).upper()
else:
tr_str += '_'
if self.opt.OutputFile == None:
out_str = "pycrc_stdout"
else:
out_str = self.opt.OutputFile
out_str = os.path.basename(out_str)
out_str = out_str.upper()
out_str = out_str.translate(tr_str)
return "__" + out_str + "__"
# function __get_underlying_crc_t
###############################################################################
def __get_underlying_crc_t(self):
"""
Return the C type of the crc_t typedef.
"""
if self.opt.CrcType != None:
return self.opt.CrcType
if self.opt.Width == None:
return "unsigned long"
if self.opt.CStd == "C89":
if self.opt.Width <= 8:
return "unsigned char"
elif self.opt.Width <= 16:
return "unsigned int"
else:
return "unsigned long"
else: # C99
if self.opt.Width <= 8:
return "uint8_t"
elif self.opt.Width <= 16:
return "uint16_t"
elif self.opt.Width <= 32:
return "uint32_t"
else:
return "unsigned long"
return "unsigned long"
# function __get_include_file
###############################################################################
def __get_include_file(self):
"""
Return an addittional include instruction if specified.
"""
if self.opt.IncludeFile == None:
return None
if self.opt.IncludeFile[0] == '"' or self.opt.IncludeFile[0] == '<':
return self.opt.IncludeFile
return '"%s"' % self.opt.IncludeFile
# function __get_init_value
###############################################################################
def __get_init_value(self):
"""
Return the init value of a C implementation, according to the selected algorithm and
to the given options.
If no default option is given for a given parameter, value in the cfg_t structure must be used.
"""
if self.opt.Algorithm == self.opt.Algo_Bit_by_Bit:
if self.opt.XorIn == None or self.opt.Width == None or self.opt.Poly == None:
return None
crc = Crc(width = self.opt.Width, poly = self.opt.Poly,
reflect_in = self.opt.ReflectIn, xor_in = self.opt.XorIn,
reflect_out = self.opt.ReflectOut, xor_out = self.opt.XorOut,
table_idx_width = self.opt.TableIdxWidth)
init = crc.NonDirectInit
elif self.opt.Algorithm == self.opt.Algo_Bit_by_Bit_Fast:
if self.opt.XorIn == None:
return None
init = self.opt.XorIn
elif self.opt.Algorithm == self.opt.Algo_Table_Driven:
if self.opt.ReflectIn == None or self.opt.XorIn == None or self.opt.Width == None:
return None
if self.opt.Poly == None:
poly = 0
else:
poly = self.opt.Poly
crc = Crc(width = self.opt.Width, poly = poly,
reflect_in = self.opt.ReflectIn, xor_in = self.opt.XorIn,
reflect_out = self.opt.ReflectOut, xor_out = self.opt.XorOut,
table_idx_width = self.opt.TableIdxWidth)
if self.opt.ReflectIn:
init = crc.reflect(crc.DirectInit, self.opt.Width)
else:
init = crc.DirectInit
else:
init = 0
return self.__pretty_hex(init, self.opt.Width)
# function __get_table_init
###############################################################################
def __get_table_init(self):
"""
Return the precalculated CRC table for the table_driven implementation.
"""
if self.opt.Algorithm != self.opt.Algo_Table_Driven:
return "0"
if self.opt.Width == None or self.opt.Poly == None or self.opt.ReflectIn == None:
return "0"
crc = Crc(width = self.opt.Width, poly = self.opt.Poly,
reflect_in = self.opt.ReflectIn,
xor_in = 0, reflect_out = False, xor_out = 0, # set unimportant variables to known values
table_idx_width = self.opt.TableIdxWidth)
tbl = crc.gen_table()
if self.opt.Width >= 32:
values_per_line = 4
elif self.opt.Width >= 16:
values_per_line = 8
else:
values_per_line = 16
format_width = max(self.opt.Width, 8)
out = ""
for i in range(self.opt.TableWidth):
if i % values_per_line == 0:
out += " "
if i == (self.opt.TableWidth - 1):
out += "%s" % self.__pretty_hex(tbl[i], format_width)
elif i % values_per_line == (values_per_line - 1):
out += "%s,\n" % self.__pretty_hex(tbl[i], format_width)
else:
out += "%s, " % self.__pretty_hex(tbl[i], format_width)
return out
# function __get_table_core_algorithm_ni
###############################################################################
def __get_table_core_algorithm_ni(self):
"""
Return the core loop of the table-driven algorithm.
"""
if self.opt.Algorithm != self.opt.Algo_Table_Driven:
return ""
loop_core_ni = ""
loop_indent = ""
if self.opt.UndefinedCrcParameters:
loop_indent = " "
else:
loop_indent = " "
if self.opt.Width == None:
shr = "($cfg_width - $cfg_table_idx_width + $cfg_shift)"
elif self.opt.Width < 8:
shr = "%d" % (self.opt.Width - self.opt.TableIdxWidth + 8 - self.opt.Width)
else:
shr = "%d" % (self.opt.Width - self.opt.TableIdxWidth)
reg_shift = "$if ($crc_do_shift == True) {:($cfg_table_idx_width - $cfg_shift):} $else {:$cfg_table_idx_width:}"
if self.opt.TableIdxWidth == 8:
loop_core_ni += loop_indent + "tbl_idx = ((crc >> " + shr + ") ^ *data) & $crc_table_mask;" + '\n' + \
loop_indent + "crc = (crc_table[tbl_idx] ^ (crc << " + reg_shift + ")) & $cfg_mask_shifted;" + '\n'
else:
for i in range (8 / self.opt.TableIdxWidth):
str_idx = "%s" % (8 - (i + 1) * self.opt.TableIdxWidth)
loop_core_ni += loop_indent + "tbl_idx = (crc >> " + shr + ") ^ (*data >> " + str_idx + ");" + '\n' + \
loop_indent + "crc = crc_table[tbl_idx & $crc_table_mask] ^ (crc << " + reg_shift + ");" + '\n'
return loop_core_ni
# function __get_table_core_algorithm_ri
###############################################################################
def __get_table_core_algorithm_ri(self):
"""
Return the core loop of the table-driven algorithm.
"""
if self.opt.Algorithm != self.opt.Algo_Table_Driven:
return ""
loop_core_ri = ""
loop_indent = ""
if self.opt.UndefinedCrcParameters:
loop_indent = " "
else:
loop_indent = " "
crc_shifted = "$if ($crc_do_shift == True) {:(crc >> $cfg_shift):} $else {:crc:}"
if self.opt.TableIdxWidth == 8:
loop_core_ri += loop_indent + "tbl_idx = (" + crc_shifted + " ^ *data) & $crc_table_mask;" + '\n' + \
loop_indent + "crc = (crc_table[tbl_idx] ^ (crc >> $cfg_table_idx_width)) & $cfg_mask_shifted;" + '\n'
else:
for i in range (8 / self.opt.TableIdxWidth):
str_idx = "%d" % i
loop_core_ri += loop_indent + "tbl_idx = " + crc_shifted + " ^ (*data >> (" + str_idx + " * $cfg_table_idx_width));" + '\n' + \
loop_indent + "crc = crc_table[tbl_idx & $crc_table_mask] ^ (crc >> $cfg_table_idx_width);" + '\n'
return loop_core_ri