/*
* Basically, we are trying to do this in C PreProcessor (a.k.a CPP)::
*
* int start = 1;
* int end = 20;
* for (i = start; i != end; i ++) {
* for (j = start; j != end; j ++)
* printf("%2d x %2d = %3d\n", i, j, (i * j));
* printf("\n");
* }
*
* References:
* goo.gl/1HGxJX
* goo.gl/wcfeFK
*/
#define START (1, )
#define END (0, 2) // this is 20
#define PRINT_FORMAT "%2d x %2d = %3d\n"
/* Let's start with some utility functions */
#define EAT(...)
#ifndef DEBUG
#define TEST(...) EAT
#endif
#define LITERAL(x) #x
#define CAT_0(x, y) x ## y
#define CAT_1(x, y) CAT_0(x, y)
#define CAT(x, y) CAT_1(x, y)
#define EXPAND(...) __VA_ARGS__
#define EMPTY() // empty
#define DEFER_0(...) __VA_ARGS__ EMPTY() // defer once
#define DEFER_1(...) __VA_ARGS__ DEFER_0(EMPTY) ()
#define DEFER_2(...) __VA_ARGS__ DEFER_1(EMPTY) ()
#define DEFER_3(...) __VA_ARGS__ DEFER_2(EMPTY) ()
#define DEFER_4(...) __VA_ARGS__ DEFER_3(EMPTY) ()
#define DEFER_5(...) __VA_ARGS__ DEFER_4(EMPTY) ()
#define DEFER_6(...) __VA_ARGS__ DEFER_5(EMPTY) ()
#define DEFER_7(...) __VA_ARGS__ DEFER_6(EMPTY) ()
#define DEFER_8(...) __VA_ARGS__ DEFER_7(EMPTY) ()
#define DEFER_9(...) __VA_ARGS__ DEFER_8(EMPTY) ()
#define EVAL_1(...) __VA_ARGS__ /* evaluate 1 time */
#define EVAL_2(...) EVAL_1(EVAL_1(EVAL_1(__VA_ARGS__)))
#define EVAL_3(...) EVAL_2(EVAL_2(EVAL_2(__VA_ARGS__)))
#define EVAL_4(...) EVAL_3(EVAL_3(EVAL_3(__VA_ARGS__)))
#define EVAL_5(...) EVAL_4(EVAL_4(EVAL_4(__VA_ARGS__)))
#define EVAL_6(...) EVAL_5(EVAL_5(EVAL_5(__VA_ARGS__)))
#define EVAL_7(...) EVAL_6(EVAL_6(EVAL_6(__VA_ARGS__)))
#define EVAL_8(...) EVAL_7(EVAL_7(EVAL_7(__VA_ARGS__)))
#define EVAL_9(...) EVAL_8(EVAL_8(EVAL_8(__VA_ARGS__)))
#define EVAL__1(...) __VA_ARGS__
#define INNER_EVAL(...) EVAL__1(EVAL__1(__VA_ARGS__))
#define IF_1(TRUE_BLOCK, ...) TRUE_BLOCK
#define IF_0(TRUE_BLOCK, ...) __VA_ARGS__
#define IIF(cond) CAT(IF_, cond)
#define CHECK_N(_, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0, 0)
#define PROBE(x) x, 1,
/*
* NOT(0) = 1, NOT(otherwise) = 0
*/
#define NOT(x) CHECK(CAT(NOT_, x))
#define NOT_0 PROBE(~)
/*
* BOOLEAN OPERATIONS
*/
#define XOR(a, b) CHECK(CAT(CAT(XOR_, a), b))
#define XOR_10 PROBE(1)
#define XOR_01 PROBE(1)
#define AND(a, b) CHECK(CAT(CAT(AND_, a), b))
#define AND_11 PROBE(1)
#define OR(a, b) CHECK(CAT(CAT(OR_, a), b))
#define OR_01 PROBE(1)
#define OR_10 PROBE(1)
#define OR_11 PROBE(1)
/* 0 => 1, 1 => 0 */
#define COMP(BIT) CAT(COMP_, BIT)
#define COMP_0 1
#define COMP_1 0
/* END OF BOOLEAN OPERATIONS */
/*
* DECIMAL OPERATIONS
*/
#define DEC_INC(a) CAT(DEC_INC_, a)
#define DEC_INC_0 1
#define DEC_INC_1 2
#define DEC_INC_2 3
#define DEC_INC_3 4
#define DEC_INC_4 5
#define DEC_INC_5 6
#define DEC_INC_6 7
#define DEC_INC_7 8
#define DEC_INC_8 9
#define DEC_INC_9 0
#define DEC_EQUIV(a, b) CHECK(CAT(CAT(DEC_EQUIV_, a), b))
#define DEC_EQUIV_00 PROBE(1)
#define DEC_EQUIV_11 PROBE(1)
#define DEC_EQUIV_22 PROBE(1)
#define DEC_EQUIV_33 PROBE(1)
#define DEC_EQUIV_44 PROBE(1)
#define DEC_EQUIV_55 PROBE(1)
#define DEC_EQUIV_66 PROBE(1)
#define DEC_EQUIV_77 PROBE(1)
#define DEC_EQUIV_88 PROBE(1)
#define DEC_EQUIV_99 PROBE(1)
/* END OF DECIMAL OPERATIONS */
/* Basically, BOOL(x) := !!x */
#define BOOL(x) COMP(NOT(x))
#define IF(N, ...) IIF(BOOL(N))
#define WHEN(N) IF(N)(EXPAND, EAT)
#define EXPAND_TEST_EXISTS(...) GOOD, EXISTS(__VA_ARGS__) ) EAT (
#define DO_EXPAND_TEST_EXISTS(x) (CAT(EXPAND_TEST_, x), DOESNT_EXIST)
#define GET_TEST_EXISTS_VALUE_(_, value) value
#define GET_TEST_EXISTS_VALUE(x) GET_TEST_EXISTS_VALUE_ x
#define TEST_EXISTS(x) GET_TEST_EXISTS_VALUE ( DO_EXPAND_TEST_EXISTS (x) )
TEST( EXISTS) (
EXISTS( FOO) TEST_EXISTS( EXISTS( FOO) )
DOESNT_EXIST TEST_EXISTS( FOO)
)
#define EXTRACT_VALUE(exist_value) CAT(EXTRACT_VALUE_, exist_value)
#define EXTRACT_VALUE_EXISTS(...) __VA_ARGS__
#define CONVERT_EXISTS_TO_BOOL(value) CAT(CONVERT_EXISTS_TO_BOOL_, value)
#define CONVERT_EXISTS_TO_BOOL_EXISTS(...) 1
#define CONVERT_EXISTS_TO_BOOL_DOESNT_EXIST 0
#define TRY_EXTRACT_EXISTS(value, ...) \
IF(CONVERT_EXISTS_TO_BOOL(TEST_EXISTS(value))) \
(EXTRACT_VALUE(value), __VA_ARGS__)
TEST( TRY_EXTRACT_EXISTS) (
FOO TRY_EXTRACT_EXISTS( EXISTS( FOO) , DEFAULT)
DEFUALT TRY_EXTRACT_EXISTS( FOO, DEFAULT)
)
/*
* We are going to represent a number by list of digits, e.g.
*
* 1 => (1, )
* 13 => (3, 1)
*
* Let's define some list operations.
*/
#define HEAD(head, ...) head
#define TAIL(head, ...) __VA_ARGS__
#define ENCLOSE(...) ( __VA_ARGS__ )
#define EXPLODE_(...) __VA_ARGS__
#define EXPLODE(...) EXPLODE_ __VA_ARGS__
#define EXPLODE_INDIRECT() EXPLODE_
#define IS_LIST_EMPTY(...) \
TRY_EXTRACT_EXISTS( \
DEFER_0(HEAD) (__VA_ARGS__ EXISTS(1)), \
0)
TEST( IS_LIST_EMPTY) (
1 IS_LIST_EMPTY( )
0 IS_LIST_EMPTY( 0 )
0 IS_LIST_EMPTY( 0 , 0 )
)
#define EMPTY_LIST_TO_ZERO(...) \
IF (IS_LIST_EMPTY(__VA_ARGS__)) ( \
(0, ), \
(__VA_ARGS__))
/*
* Now, let's define INCrease function, where,
*
* INC LIST_REPR(N) = LIST_REPR(N + 1)
*
* E.g.
*
* INC(1, ) = (2, )
* INC(9, ) = (0, 1)
*/
#define INC_INDIRECT() INC_NO_EVAL
#define TRY_CARRY(x) CHECK(CAT(TRY_CARRY_, x), x)
#define TRY_CARRY_DEC_INC_ PROBE(~)
#define INC_NO_EVAL(head, ...) \
DEFER_1(EXPLODE_INDIRECT) () \
IF (DEC_INC(head)) ( \
(TRY_CARRY(DEC_INC(head)), __VA_ARGS__), \
(0, DEFER_2(INC_INDIRECT) () (__VA_ARGS__)) \
)
#define INC(...) (INNER_EVAL(INC_NO_EVAL(__VA_ARGS__)))
TEST( INC) (
( 1 , ) INC( 0 )
( 2 , ) INC( 1 )
( 0 , 2 ) INC( 9 , 1 )
/*
* Oops, this is actually (0, 0, EXPLODE_INDIRECT () (1, ))
* Can't count to 100 Orz...
* possible fix is to make INNER_EVAL evaluates more times.
*/
( 0 , 0 , 1 ) INC( 9 , 9 )
)
/*
* Apply @func_before and @func_after to each elements of a list.
*/
#define FOR_EACH_INDIRECT() FOR_EACH
#define FOR_EACH(func_before, func_after, ...) \
WHEN (NOT(IS_LIST_EMPTY(__VA_ARGS__))) ( \
DEFER_1(func_before) (HEAD(__VA_ARGS__)) \
DEFER_1(FOR_EACH_INDIRECT) () ( \
func_before, func_after, TAIL(__VA_ARGS__) \
) \
DEFER_1(func_after) (HEAD(__VA_ARGS__)) \
)
TEST( FOR_EACH) (
/* PRINT(1) PRINT(2) PRINT(3) PRINT(4) */
EVAL_7( FOR_EACH( PRINT, EAT, 1 , 2 , 3 , 4 ) )
/* PRINT(4) PRINT(3) PRINT(2) PRINT(1) */
EVAL_7( FOR_EACH( EAT, PRINT, 1 , 2 , 3 , 4 ) )
)
#define BOTH_EMPTY(list_a, list_b) \
AND(IS_LIST_EMPTY list_a, IS_LIST_EMPTY list_b)
TEST( BOTH_EMPTY) (
1 BOTH_EMPTY( ( ) , ( ) )
0 BOTH_EMPTY( ( 1 ) , ( ) )
0 BOTH_EMPTY( ( ) , ( 1 ) )
0 BOTH_EMPTY( ( 1 ) , ( 1 ) )
)
#define IS_HEAD_EQUAL(list_a, list_b) \
DEC_EQUIV ( HEAD list_a, HEAD list_b )
TEST( IS_HEAD_EQUAL) (
0 IS_HEAD_EQUAL( ( ) , ( ) )
0 IS_HEAD_EQUAL( ( 1 ) , ( ) )
0 IS_HEAD_EQUAL( ( ) , ( 1 , 1 ) )
1 IS_HEAD_EQUAL( ( 1 ) , ( 1 ) )
0 IS_HEAD_EQUAL( ( 1 ) , ( 0 ) )
1 IS_HEAD_EQUAL( ( 1 ) , ( 1 , 0 ) )
)
#define IS_LIST_EQUAL_INDIRECT() IS_LIST_EQUAL_NO_EVAL
#define IS_LIST_EQUAL_NO_EVAL(a, b) \
IF( BOTH_EMPTY( a, b ) ) ( \
1, \
/* else */ \
IF( IS_HEAD_EQUAL(a, b) ) ( \
DEFER_2(IS_LIST_EQUAL_INDIRECT) () ((TAIL a), (TAIL b)), \
0) \
)
#define IS_LIST_EQUAL(a, b) INNER_EVAL(IS_LIST_EQUAL_NO_EVAL(a, b))
#define IS_LIST_NOT_EQUAL(a, b) NOT(IS_LIST_EQUAL(a, b))
TEST( IS_LIST_EQUAL) (
1 NOT( IS_LIST_EQUAL( ( 1 , 2 ) , ( 1 , 3 ) ) )
1 IS_LIST_NOT_EQUAL( ( 1 , 2 ) , ( 1 , 3 ) )
0 IS_LIST_NOT_EQUAL( ( 0 , 1 ) , ( 0 , 1 ) )
1 IS_LIST_NOT_EQUAL( ( 0 , 1 ) , ( 1 ) )
1 IS_LIST_NOT_EQUAL( ( ) , ( 1 ) )
1 IS_LIST_NOT_EQUAL( ( 1 , 0 , 1 ) , ( 1 , 0 , 0 , 1 ) )
)
#define FOLD_INDIRECT() FOLD_NO_EVAL
#define FOLD_NO_EVAL(func, list, init) \
IF ( IS_LIST_EMPTY list) ( \
init, \
DEFER_1(FOLD_INDIRECT) () (func, (TAIL list), func(init, HEAD list)) \
)
#define FOLD(func, list, init) INNER_EVAL(FOLD_NO_EVAL(func, list, init))
#define TAC(x, y) CAT(y, x)
#define TO_INT(list) CAT(, FOLD(TAC, list, ))
TEST( TO_INT) (
102 TO_INT( INC( 1 , 0 , 1 ) )
)
#define IS_LIST_NOT_EQUAL_() IS_LIST_NOT_EQUAL
#define FOR_LOOP_INDIRECT() FOR_LOOP_NO_EVAL
#define FOR_LOOP_NO_EVAL(index, max, macro, ...) \
WHEN ( IS_LIST_NOT_EQUAL (index, max) ) ( \
DEFER_1(macro) (index, __VA_ARGS__) \
FOR_LOOP_INDIRECT EMPTY EMPTY () () () ( \
ENCLOSE( EXPLODE( DEFER_1(INC) index ) ), \
max, \
macro, \
__VA_ARGS__ \
) \
)
#define FOR_LOOP(...) EVAL_2(EVAL_1(EVAL_1(FOR_LOOP_NO_EVAL(__VA_ARGS__))))
#define PRINT(list_b, list_a) \
printf(PRINT_FORMAT, \
TO_INT (list_a), \
TO_INT (list_b), \
(TO_INT (list_a)) * (TO_INT (list_b)));
#define INNER_LOOP(x, ...) \
FOR_LOOP_NO_EVAL(START, END, PRINT, x) \
printf("\n");
#ifndef DEBUG
#include <stdio.h>
int main( ) {
EVAL_7( FOR_LOOP( START, END, INNER_LOOP) )
}
#endif
LyoKICogQmFzaWNhbGx5LCB3ZSBhcmUgdHJ5aW5nIHRvIGRvIHRoaXMgaW4gQyBQcmVQcm9jZXNzb3IgKGEuay5hIENQUCk6OgogKgogKiAgIGludCBzdGFydCA9IDE7CiAqICAgaW50IGVuZCA9IDIwOwogKiAgIGZvciAoaSA9IHN0YXJ0OyBpICE9IGVuZDsgaSArKykgewogKiAgICAgZm9yIChqID0gc3RhcnQ7IGogIT0gZW5kOyBqICsrKQogKiAgICAgICBwcmludGYoIiUyZCB4ICUyZCA9ICUzZFxuIiwgaSwgaiwgKGkgKiBqKSk7CiAqICAgICBwcmludGYoIlxuIik7CiAqICAgfQogKgogKiBSZWZlcmVuY2VzOiAgCiAqICAgZ29vLmdsLzFIR3hKWAogKiAgIGdvby5nbC93Y2ZlRksKICovCgojZGVmaW5lIFNUQVJUICgxLCAgKQojZGVmaW5lIEVORCAgICgwLCAyKSAgIC8vIHRoaXMgaXMgMjAKI2RlZmluZSBQUklOVF9GT1JNQVQgIiUyZCB4ICUyZCA9ICUzZFxuIgoKLyogTGV0J3Mgc3RhcnQgd2l0aCBzb21lIHV0aWxpdHkgZnVuY3Rpb25zICovCiNkZWZpbmUgRUFUKC4uLikKI2lmbmRlZiBERUJVRwojZGVmaW5lIFRFU1QoLi4uKSBFQVQKI2VuZGlmCgojZGVmaW5lIExJVEVSQUwoeCkgI3gKI2RlZmluZSBDQVRfMCh4LCB5KSAgeCAjIyB5CiNkZWZpbmUgQ0FUXzEoeCwgeSkgIENBVF8wKHgsIHkpCiNkZWZpbmUgQ0FUKHgsIHkpIENBVF8xKHgsIHkpCgojZGVmaW5lIEVYUEFORCguLi4pIF9fVkFfQVJHU19fCgojZGVmaW5lIEVNUFRZKCkgIC8vIGVtcHR5CiNkZWZpbmUgREVGRVJfMCguLi4pICBfX1ZBX0FSR1NfXyBFTVBUWSgpICAvLyBkZWZlciBvbmNlCiNkZWZpbmUgREVGRVJfMSguLi4pIF9fVkFfQVJHU19fIERFRkVSXzAoRU1QVFkpICgpCiNkZWZpbmUgREVGRVJfMiguLi4pIF9fVkFfQVJHU19fIERFRkVSXzEoRU1QVFkpICgpCiNkZWZpbmUgREVGRVJfMyguLi4pIF9fVkFfQVJHU19fIERFRkVSXzIoRU1QVFkpICgpCiNkZWZpbmUgREVGRVJfNCguLi4pIF9fVkFfQVJHU19fIERFRkVSXzMoRU1QVFkpICgpCiNkZWZpbmUgREVGRVJfNSguLi4pIF9fVkFfQVJHU19fIERFRkVSXzQoRU1QVFkpICgpCiNkZWZpbmUgREVGRVJfNiguLi4pIF9fVkFfQVJHU19fIERFRkVSXzUoRU1QVFkpICgpCiNkZWZpbmUgREVGRVJfNyguLi4pIF9fVkFfQVJHU19fIERFRkVSXzYoRU1QVFkpICgpCiNkZWZpbmUgREVGRVJfOCguLi4pIF9fVkFfQVJHU19fIERFRkVSXzcoRU1QVFkpICgpCiNkZWZpbmUgREVGRVJfOSguLi4pIF9fVkFfQVJHU19fIERFRkVSXzgoRU1QVFkpICgpCgojZGVmaW5lIEVWQUxfMSguLi4pICBfX1ZBX0FSR1NfXyAgLyogZXZhbHVhdGUgMSB0aW1lICovCiNkZWZpbmUgRVZBTF8yKC4uLikgIEVWQUxfMShFVkFMXzEoRVZBTF8xKF9fVkFfQVJHU19fKSkpCiNkZWZpbmUgRVZBTF8zKC4uLikgIEVWQUxfMihFVkFMXzIoRVZBTF8yKF9fVkFfQVJHU19fKSkpCiNkZWZpbmUgRVZBTF80KC4uLikgIEVWQUxfMyhFVkFMXzMoRVZBTF8zKF9fVkFfQVJHU19fKSkpCiNkZWZpbmUgRVZBTF81KC4uLikgIEVWQUxfNChFVkFMXzQoRVZBTF80KF9fVkFfQVJHU19fKSkpCiNkZWZpbmUgRVZBTF82KC4uLikgIEVWQUxfNShFVkFMXzUoRVZBTF81KF9fVkFfQVJHU19fKSkpCiNkZWZpbmUgRVZBTF83KC4uLikgIEVWQUxfNihFVkFMXzYoRVZBTF82KF9fVkFfQVJHU19fKSkpCiNkZWZpbmUgRVZBTF84KC4uLikgIEVWQUxfNyhFVkFMXzcoRVZBTF83KF9fVkFfQVJHU19fKSkpCiNkZWZpbmUgRVZBTF85KC4uLikgIEVWQUxfOChFVkFMXzgoRVZBTF84KF9fVkFfQVJHU19fKSkpCgojZGVmaW5lIEVWQUxfXzEoLi4uKSAgX19WQV9BUkdTX18KI2RlZmluZSBJTk5FUl9FVkFMKC4uLikgRVZBTF9fMShFVkFMX18xKF9fVkFfQVJHU19fKSkKCiNkZWZpbmUgSUZfMShUUlVFX0JMT0NLLCAuLi4pIFRSVUVfQkxPQ0sKI2RlZmluZSBJRl8wKFRSVUVfQkxPQ0ssIC4uLikgX19WQV9BUkdTX18KCiNkZWZpbmUgSUlGKGNvbmQpIENBVChJRl8sIGNvbmQpCgojZGVmaW5lIENIRUNLX04oXywgbiwgLi4uKSBuCiNkZWZpbmUgQ0hFQ0soLi4uKSBDSEVDS19OKF9fVkFfQVJHU19fLCAwLCAwKQojZGVmaW5lIFBST0JFKHgpIHgsIDEsCgovKgogKiBOT1QoMCkgPSAxLCBOT1Qob3RoZXJ3aXNlKSA9IDAKICovCiNkZWZpbmUgTk9UKHgpIENIRUNLKENBVChOT1RfLCB4KSkKI2RlZmluZSBOT1RfMCBQUk9CRSh+KQoKLyoKICogQk9PTEVBTiBPUEVSQVRJT05TCiAqLwojZGVmaW5lIFhPUihhLCBiKSBDSEVDSyhDQVQoQ0FUKFhPUl8sIGEpLCBiKSkKI2RlZmluZSBYT1JfMTAgUFJPQkUoMSkKI2RlZmluZSBYT1JfMDEgUFJPQkUoMSkKCiNkZWZpbmUgQU5EKGEsIGIpIENIRUNLKENBVChDQVQoQU5EXywgYSksIGIpKQojZGVmaW5lIEFORF8xMSBQUk9CRSgxKQoKI2RlZmluZSBPUihhLCBiKSBDSEVDSyhDQVQoQ0FUKE9SXywgYSksIGIpKQojZGVmaW5lIE9SXzAxIFBST0JFKDEpCiNkZWZpbmUgT1JfMTAgUFJPQkUoMSkKI2RlZmluZSBPUl8xMSBQUk9CRSgxKQoKLyogMCA9PiAxLCAxID0+IDAgKi8KI2RlZmluZSBDT01QKEJJVCkgQ0FUKENPTVBfLCBCSVQpCiNkZWZpbmUgQ09NUF8wIDEKI2RlZmluZSBDT01QXzEgMAovKiBFTkQgT0YgQk9PTEVBTiBPUEVSQVRJT05TICovCgovKgogKiBERUNJTUFMIE9QRVJBVElPTlMKICovCiNkZWZpbmUgREVDX0lOQyhhKSBDQVQoREVDX0lOQ18sIGEpCiNkZWZpbmUgREVDX0lOQ18wIDEKI2RlZmluZSBERUNfSU5DXzEgMgojZGVmaW5lIERFQ19JTkNfMiAzCiNkZWZpbmUgREVDX0lOQ18zIDQKI2RlZmluZSBERUNfSU5DXzQgNQojZGVmaW5lIERFQ19JTkNfNSA2CiNkZWZpbmUgREVDX0lOQ182IDcKI2RlZmluZSBERUNfSU5DXzcgOAojZGVmaW5lIERFQ19JTkNfOCA5CiNkZWZpbmUgREVDX0lOQ185IDAKCiNkZWZpbmUgREVDX0VRVUlWKGEsIGIpIENIRUNLKENBVChDQVQoREVDX0VRVUlWXywgYSksIGIpKQojZGVmaW5lIERFQ19FUVVJVl8wMCBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl8xMSBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl8yMiBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl8zMyBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl80NCBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl81NSBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl82NiBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl83NyBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl84OCBQUk9CRSgxKQojZGVmaW5lIERFQ19FUVVJVl85OSBQUk9CRSgxKQovKiBFTkQgT0YgREVDSU1BTCBPUEVSQVRJT05TICovCgovKiBCYXNpY2FsbHksIEJPT0woeCkgOj0gISF4ICovCiNkZWZpbmUgQk9PTCh4KSBDT01QKE5PVCh4KSkKI2RlZmluZSBJRihOLCAuLi4pICBJSUYoQk9PTChOKSkKI2RlZmluZSBXSEVOKE4pIElGKE4pKEVYUEFORCwgRUFUKQoKI2RlZmluZSBFWFBBTkRfVEVTVF9FWElTVFMoLi4uKSBHT09ELCBFWElTVFMoX19WQV9BUkdTX18pICkgRUFUICgKI2RlZmluZSBET19FWFBBTkRfVEVTVF9FWElTVFMoeCkgKENBVChFWFBBTkRfVEVTVF8sIHgpLCBET0VTTlRfRVhJU1QpCgojZGVmaW5lIEdFVF9URVNUX0VYSVNUU19WQUxVRV8oXywgdmFsdWUpIHZhbHVlCiNkZWZpbmUgR0VUX1RFU1RfRVhJU1RTX1ZBTFVFKHgpIEdFVF9URVNUX0VYSVNUU19WQUxVRV8geAoKI2RlZmluZSBURVNUX0VYSVNUUyh4KSBHRVRfVEVTVF9FWElTVFNfVkFMVUUgKCBET19FWFBBTkRfVEVTVF9FWElTVFMgKHgpICkKClRFU1QoRVhJU1RTKSAoCiAgICBFWElTVFMoRk9PKSAgVEVTVF9FWElTVFMoRVhJU1RTKEZPTykpCiAgICBET0VTTlRfRVhJU1QgVEVTVF9FWElTVFMoRk9PKQopCgojZGVmaW5lIEVYVFJBQ1RfVkFMVUUoZXhpc3RfdmFsdWUpIENBVChFWFRSQUNUX1ZBTFVFXywgZXhpc3RfdmFsdWUpCiNkZWZpbmUgRVhUUkFDVF9WQUxVRV9FWElTVFMoLi4uKSBfX1ZBX0FSR1NfXwoKI2RlZmluZSBDT05WRVJUX0VYSVNUU19UT19CT09MKHZhbHVlKSBDQVQoQ09OVkVSVF9FWElTVFNfVE9fQk9PTF8sIHZhbHVlKQojZGVmaW5lIENPTlZFUlRfRVhJU1RTX1RPX0JPT0xfRVhJU1RTKC4uLikgMQojZGVmaW5lIENPTlZFUlRfRVhJU1RTX1RPX0JPT0xfRE9FU05UX0VYSVNUIDAKCiNkZWZpbmUgVFJZX0VYVFJBQ1RfRVhJU1RTKHZhbHVlLCAuLi4pIFwKICBJRihDT05WRVJUX0VYSVNUU19UT19CT09MKFRFU1RfRVhJU1RTKHZhbHVlKSkpIFwKICAgIChFWFRSQUNUX1ZBTFVFKHZhbHVlKSwgX19WQV9BUkdTX18pCgpURVNUKFRSWV9FWFRSQUNUX0VYSVNUUykgKAogICAgRk9PICAgICAgVFJZX0VYVFJBQ1RfRVhJU1RTKEVYSVNUUyhGT08pLCBERUZBVUxUKQogICAgREVGVUFMVCAgVFJZX0VYVFJBQ1RfRVhJU1RTKEZPTywgREVGQVVMVCkKKQoKLyoKICogV2UgYXJlIGdvaW5nIHRvIHJlcHJlc2VudCBhIG51bWJlciBieSBsaXN0IG9mIGRpZ2l0cywgZS5nLgogKgogKiAgIDEgPT4gKDEsICkKICogICAxMyA9PiAoMywgMSkKICoKICogTGV0J3MgZGVmaW5lIHNvbWUgbGlzdCBvcGVyYXRpb25zLgogKi8KI2RlZmluZSBIRUFEKGhlYWQsIC4uLikgaGVhZAojZGVmaW5lIFRBSUwoaGVhZCwgLi4uKSBfX1ZBX0FSR1NfXwoKI2RlZmluZSBFTkNMT1NFKC4uLikgICggX19WQV9BUkdTX18gKQojZGVmaW5lIEVYUExPREVfKC4uLikgIF9fVkFfQVJHU19fCiNkZWZpbmUgRVhQTE9ERSguLi4pICBFWFBMT0RFXyAgX19WQV9BUkdTX18KCiNkZWZpbmUgRVhQTE9ERV9JTkRJUkVDVCgpIEVYUExPREVfCiNkZWZpbmUgSVNfTElTVF9FTVBUWSguLi4pIFwKICBUUllfRVhUUkFDVF9FWElTVFMoIFwKICAgICAgREVGRVJfMChIRUFEKSAoX19WQV9BUkdTX18gRVhJU1RTKDEpKSwgXAogICAgICAwKQpURVNUKElTX0xJU1RfRU1QVFkpICgKICAgIDEgSVNfTElTVF9FTVBUWSgpCiAgICAwIElTX0xJU1RfRU1QVFkoMCkKICAgIDAgSVNfTElTVF9FTVBUWSgwLCAwKQopCgojZGVmaW5lIEVNUFRZX0xJU1RfVE9fWkVSTyguLi4pIFwKICBJRiAoSVNfTElTVF9FTVBUWShfX1ZBX0FSR1NfXykpICggXAogICAgICAoMCwgKSwgXAogICAgICAoX19WQV9BUkdTX18pKQoKLyoKICogTm93LCBsZXQncyBkZWZpbmUgSU5DcmVhc2UgZnVuY3Rpb24sIHdoZXJlLAogKgogKiAgIElOQyBMSVNUX1JFUFIoTikgPSBMSVNUX1JFUFIoTiArIDEpCiAqCiAqIEUuZy4KICoKICogICBJTkMoMSwgKSA9ICgyLCApCiAqICAgSU5DKDksICkgPSAoMCwgMSkKICovCiNkZWZpbmUgSU5DX0lORElSRUNUKCkgSU5DX05PX0VWQUwKCiNkZWZpbmUgVFJZX0NBUlJZKHgpIENIRUNLKENBVChUUllfQ0FSUllfLCB4KSwgeCkKI2RlZmluZSBUUllfQ0FSUllfREVDX0lOQ18gUFJPQkUofikKCiNkZWZpbmUgSU5DX05PX0VWQUwoaGVhZCwgLi4uKSBcCiAgREVGRVJfMShFWFBMT0RFX0lORElSRUNUKSAoKSBcCiAgSUYgKERFQ19JTkMoaGVhZCkpICggXAogICAgICAoVFJZX0NBUlJZKERFQ19JTkMoaGVhZCkpLCBfX1ZBX0FSR1NfXyksIFwKICAgICAgKDAsIERFRkVSXzIoSU5DX0lORElSRUNUKSAoKSAoX19WQV9BUkdTX18pKSBcCiAgKQoKI2RlZmluZSBJTkMoLi4uKSAoSU5ORVJfRVZBTChJTkNfTk9fRVZBTChfX1ZBX0FSR1NfXykpKQpURVNUKElOQykgKAogICAgKDEsICkgSU5DKDApCiAgICAoMiwgKSBJTkMoMSkKICAgICgwLCAyKSBJTkMoOSwgMSkKICAgIC8qCiAgICAgKiBPb3BzLCB0aGlzIGlzIGFjdHVhbGx5ICgwLCAwLCBFWFBMT0RFX0lORElSRUNUICgpICgxLCApKQogICAgICogQ2FuJ3QgY291bnQgdG8gMTAwIE9yei4uLgogICAgICogcG9zc2libGUgZml4IGlzIHRvIG1ha2UgSU5ORVJfRVZBTCBldmFsdWF0ZXMgbW9yZSB0aW1lcy4KICAgICAqLwogICAgKDAsIDAsIDEpIElOQyg5LCA5KQopCgovKgogKiBBcHBseSBAZnVuY19iZWZvcmUgYW5kIEBmdW5jX2FmdGVyIHRvIGVhY2ggZWxlbWVudHMgb2YgYSBsaXN0LgogKi8KI2RlZmluZSBGT1JfRUFDSF9JTkRJUkVDVCgpIEZPUl9FQUNICiNkZWZpbmUgRk9SX0VBQ0goZnVuY19iZWZvcmUsIGZ1bmNfYWZ0ZXIsIC4uLikgXAogIFdIRU4gKE5PVChJU19MSVNUX0VNUFRZKF9fVkFfQVJHU19fKSkpICggXAogICAgICBERUZFUl8xKGZ1bmNfYmVmb3JlKSAoSEVBRChfX1ZBX0FSR1NfXykpIFwKICAgICAgREVGRVJfMShGT1JfRUFDSF9JTkRJUkVDVCkgKCkgKCBcCiAgICAgICAgICBmdW5jX2JlZm9yZSwgZnVuY19hZnRlciwgVEFJTChfX1ZBX0FSR1NfXykgXAogICAgICApIFwKICAgICAgREVGRVJfMShmdW5jX2FmdGVyKSAoSEVBRChfX1ZBX0FSR1NfXykpIFwKICApCgpURVNUKEZPUl9FQUNIKSAoCiAgICAvKiBQUklOVCgxKSBQUklOVCgyKSBQUklOVCgzKSBQUklOVCg0KSAqLwogICAgRVZBTF83KEZPUl9FQUNIKFBSSU5ULCBFQVQsIDEsIDIsIDMsIDQpKQogICAgLyogUFJJTlQoNCkgUFJJTlQoMykgUFJJTlQoMikgUFJJTlQoMSkgKi8KICAgIEVWQUxfNyhGT1JfRUFDSChFQVQsIFBSSU5ULCAxLCAyLCAzLCA0KSkKKQoKI2RlZmluZSBCT1RIX0VNUFRZKGxpc3RfYSwgbGlzdF9iKSBcCiAgQU5EKElTX0xJU1RfRU1QVFkgbGlzdF9hLCBJU19MSVNUX0VNUFRZIGxpc3RfYikKClRFU1QoQk9USF9FTVBUWSkgKAogICAgMSBCT1RIX0VNUFRZKCAoICksICggKSApCiAgICAwIEJPVEhfRU1QVFkoICgxKSwgKCApICkKICAgIDAgQk9USF9FTVBUWSggKCApLCAoMSkgKQogICAgMCBCT1RIX0VNUFRZKCAoMSksICgxKSApCikKCiNkZWZpbmUgSVNfSEVBRF9FUVVBTChsaXN0X2EsIGxpc3RfYikgXAogIERFQ19FUVVJViAoIEhFQUQgbGlzdF9hLCBIRUFEIGxpc3RfYiApCgpURVNUKElTX0hFQURfRVFVQUwpICgKICAgIDAgSVNfSEVBRF9FUVVBTCggKCApLCAoICkgKQogICAgMCBJU19IRUFEX0VRVUFMKCAoMSksICggKSApCiAgICAwIElTX0hFQURfRVFVQUwoICggKSwgKDEsIDEpICkKICAgIDEgSVNfSEVBRF9FUVVBTCggKDEpLCAoMSkgKQogICAgMCBJU19IRUFEX0VRVUFMKCAoMSksICgwKSApCiAgICAxIElTX0hFQURfRVFVQUwoICgxKSwgKDEsIDApICkKKQoKI2RlZmluZSBJU19MSVNUX0VRVUFMX0lORElSRUNUKCkgSVNfTElTVF9FUVVBTF9OT19FVkFMCiNkZWZpbmUgSVNfTElTVF9FUVVBTF9OT19FVkFMKGEsIGIpIFwKICAgIElGKCBCT1RIX0VNUFRZKCBhLCBiICkgKSAoIFwKICAgICAgICAxLCBcCiAgICAgICAgLyogZWxzZSAqLyBcCiAgICAgICAgSUYoIElTX0hFQURfRVFVQUwoYSwgYikgKSAoIFwKICAgICAgICAgIERFRkVSXzIoSVNfTElTVF9FUVVBTF9JTkRJUkVDVCkgKCkgKChUQUlMIGEpLCAoVEFJTCBiKSksIFwKICAgICAgICAgIDApIFwKICAgICkKI2RlZmluZSBJU19MSVNUX0VRVUFMKGEsIGIpIElOTkVSX0VWQUwoSVNfTElTVF9FUVVBTF9OT19FVkFMKGEsIGIpKQojZGVmaW5lIElTX0xJU1RfTk9UX0VRVUFMKGEsIGIpIE5PVChJU19MSVNUX0VRVUFMKGEsIGIpKQoKVEVTVChJU19MSVNUX0VRVUFMKSAoCiAgICAxIE5PVChJU19MSVNUX0VRVUFMKCgxLCAyKSwgKDEsIDMpKSkKICAgIDEgSVNfTElTVF9OT1RfRVFVQUwoKDEsIDIpLCAoMSwgMykpCiAgICAwIElTX0xJU1RfTk9UX0VRVUFMKCgwLCAxKSwgKDAsIDEpKQogICAgMSBJU19MSVNUX05PVF9FUVVBTCgoMCwgIDEpLCAoMSkpCiAgICAxIElTX0xJU1RfTk9UX0VRVUFMKCgpLCAoMSkpCiAgICAxIElTX0xJU1RfTk9UX0VRVUFMKCgxLCAwLCAxKSwgKDEsIDAsIDAsIDEpKQopCgojZGVmaW5lIEZPTERfSU5ESVJFQ1QoKSBGT0xEX05PX0VWQUwKI2RlZmluZSBGT0xEX05PX0VWQUwoZnVuYywgbGlzdCwgaW5pdCkgXAogICAgSUYgKCBJU19MSVNUX0VNUFRZIGxpc3QpICAoIFwKICAgICAgICBpbml0LCBcCiAgICAgICAgREVGRVJfMShGT0xEX0lORElSRUNUKSAoKSAoZnVuYywgKFRBSUwgbGlzdCksIGZ1bmMoaW5pdCwgSEVBRCBsaXN0KSkgXAogICAgKQojZGVmaW5lIEZPTEQoZnVuYywgbGlzdCwgaW5pdCkgSU5ORVJfRVZBTChGT0xEX05PX0VWQUwoZnVuYywgbGlzdCwgaW5pdCkpCgojZGVmaW5lIFRBQyh4LCB5KSBDQVQoeSwgeCkKI2RlZmluZSBUT19JTlQobGlzdCkgQ0FUKCwgRk9MRChUQUMsIGxpc3QsICkpClRFU1QoVE9fSU5UKSAoCiAgICAxMDIgVE9fSU5UKElOQygxLCAwLCAxKSkKKQoKI2RlZmluZSBJU19MSVNUX05PVF9FUVVBTF8oKSBJU19MSVNUX05PVF9FUVVBTAoKI2RlZmluZSBGT1JfTE9PUF9JTkRJUkVDVCgpIEZPUl9MT09QX05PX0VWQUwKI2RlZmluZSBGT1JfTE9PUF9OT19FVkFMKGluZGV4LCBtYXgsIG1hY3JvLCAuLi4pIFwKICAgIFdIRU4gKCBJU19MSVNUX05PVF9FUVVBTCAoaW5kZXgsIG1heCkgKSAoIFwKICAgICAgICBERUZFUl8xKG1hY3JvKSAoaW5kZXgsICBfX1ZBX0FSR1NfXykgXAogICAgICAgIEZPUl9MT09QX0lORElSRUNUIEVNUFRZIEVNUFRZICgpICgpICgpICggXAogICAgICAgICAgICBFTkNMT1NFKCBFWFBMT0RFKCBERUZFUl8xKElOQykgaW5kZXggKSApLCBcCiAgICAgICAgICAgIG1heCwgXAogICAgICAgICAgICBtYWNybywgXAogICAgICAgICAgICBfX1ZBX0FSR1NfXyBcCiAgICAgICAgKSBcCiAgICApCgojZGVmaW5lIEZPUl9MT09QKC4uLikgRVZBTF8yKEVWQUxfMShFVkFMXzEoRk9SX0xPT1BfTk9fRVZBTChfX1ZBX0FSR1NfXykpKSkKCiNkZWZpbmUgUFJJTlQobGlzdF9iLCBsaXN0X2EpIFwKICAgIHByaW50ZihQUklOVF9GT1JNQVQsIFwKICAgICAgICBUT19JTlQgKGxpc3RfYSksIFwKICAgICAgICBUT19JTlQgKGxpc3RfYiksIFwKICAgICAgICAoVE9fSU5UIChsaXN0X2EpKSAqIChUT19JTlQgKGxpc3RfYikpKTsKCiNkZWZpbmUgSU5ORVJfTE9PUCh4LCAuLi4pIFwKICAgIEZPUl9MT09QX05PX0VWQUwoU1RBUlQsIEVORCwgUFJJTlQsIHgpIFwKICAgIHByaW50ZigiXG4iKTsKCiNpZm5kZWYgREVCVUcKI2luY2x1ZGUgPHN0ZGlvLmg+CmludCBtYWluKCkgewogIEVWQUxfNyhGT1JfTE9PUChTVEFSVCwgRU5ELCBJTk5FUl9MT09QKSkKfQojZW5kaWYK