#!/usr/bin/env python3

from datetime import datetime

CURRENT_YEAR: int = datetime.now().year

runtime_header = f"""/*
 * This file belongs to the OpenModelica Run-Time System
 *
 * Copyright (c) 1998-{CURRENT_YEAR}, Open Source Modelica Consortium (OSMC), c/o Linköpings
 * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights
 * reserved.
 *
 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE
 * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY
 * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
 * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL
 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
 *
 * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License
 * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs:
 * http://www.openmodelica.org or https://github.com/OpenModelica/ or
 * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU
 * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW
 * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY
 * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF
 * OSMC-PL.
 *
 */
"""

functions = [
'arrayAppend',
'arrayCopy',
'arrayGet',
'arrayList',
'arrayUpdate',
'boolAnd',
'boolEq',
'boolNot',
'boolOr',
'boolString',
'cons',
'equality',
'getGlobalRoot',
'intAbs',
'intAdd',
'intDiv',
'intEq',
'intGe',
'intGt',
'intLe',
'intLt',
'intMax',
'intMin',
'intMod',
'intMul',
'intNe',
'intNeg',
'intReal',
'intString',
'intStringChar',
'intSub',
'isNone',
'isSome',
'listAppend',
'listAppendDestroy',
'listArray',
'listDelete',
'listEmpty',
'listGet',
'listHead',
'listLength',
'listMember',
'listRest',
'listReverse',
'listReverseInPlace',
'print',
'realAbs',
'realAdd',
'realDiv',
'realEq',
'realGe',
'realGt',
'realInt',
'realLe',
'realLt',
'realMax',
'realMin',
'realMod',
'realMul',
'realNe',
'realNeg',
'realPow',
'realString',
'realSub',
'setGlobalRoot',
'stringAppend',
'stringCharInt',
'stringCompare',
'stringDelimitList',
'stringEq',
'stringEqual',
'stringGet',
'stringGetStringChar',
'stringHash',
'stringHashDjb2',
'stringHashDjb2Mod',
'stringHashSdbm',
'stringInt',
'stringLength',
'stringReal',
'stringUpdateStringChar',
'substring',
'valueConstructor',
'valueEq',
'valueHashMod'
]

print(runtime_header)
print('/* Code generated by meta_modelica_gen_boxvar.py */')
print('')
print('#ifndef META_MODELICA__GEN_BOXVAR_H_')
print('#define META_MODELICA__GEN_BOXVAR_H_')
print('')
print('#if defined(__cplusplus)')
print('extern "C" {')
print('#endif')
print('')
print('#include "meta_modelica_data.h"')
print('')
print('/* This generated code intentionally casts function pointers to object pointers/')
print(' * (void* modelica_metatype) as part of the MetaModelica boxing mechanism. ISO')
print(' * C forbids this, but it is a well-defined GNU extension on all supported')
print(' * platforms.')
print(' */')
print('#pragma GCC diagnostic push')
print('#pragma GCC diagnostic ignored "-Wpedantic"')
print('')
print('#if !(defined(OMC_MINIMAL_RUNTIME) || defined(OMC_FMI_RUNTIME))')
print('')
print('#if !defined(OMC_GENERATE_RELOCATABLE_CODE)')
print('#define OMC_SYM_BOXPTR(X) &boxptr_##X')
print('#else')
print('#define OMC_SYM_BOXPTR(X) &boxvar_fn_##X')
for f in functions:
  print('static void* boxvar_fn_%s = (void*) boxptr_%s;' % (f,f))
print('#endif')
for f in functions:
  print('static const MMC_DEFSTRUCTLIT(boxvar_lit_%s,2,0) {(modelica_metatype) OMC_SYM_BOXPTR(%s),0}};' % (f,f))
  print('#define boxvar_%s MMC_REFSTRUCTLIT(boxvar_lit_%s)' % (f,f))
print('')
print('#undef OMC_SYM_BOXPTR')
print('')
print('#pragma GCC diagnostic pop')
print('')
print('#endif /* #if !(defined(OMC_MINIMAL_RUNTIME) || defined(OMC_FMI_RUNTIME)) */')
print('#if defined(__cplusplus)')
print('}')
print('#endif')
print('#endif /* META_MODELICA__GEN_BOXVAR_H_ */')
