Skip to content

Instantly share code, notes, and snippets.

@rindeal
Last active August 16, 2018 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rindeal/ef4ece6e61347b061b6ce8e0657d1279 to your computer and use it in GitHub Desktop.
Save rindeal/ef4ece6e61347b061b6ce8e0657d1279 to your computer and use it in GitHub Desktop.
PP_NARG
/**
* Copyright (C) 2018 Jan Chren (rindeal)
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#define PP_NARG(...) \
PP_NARG_(0, ## __VA_ARGS__, PP_NARG_RSEQ_N_())
#define PP_NARG_(...) \
PP_NARG_ARG_N_(__VA_ARGS__)
#define PP_NARG_ARG_N_( \
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, \
_10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \
_20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \
_30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \
_40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \
_50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \
_60, _61, _62, _63, _64, _65, _66, _67, _68, _69, \
_70, _71, _72, _73, _74, _75, _76, _77, _78, _79, \
_80, _81, _82, _83, _84, _85, _86, _87, _88, _89, \
_90, _91, _92, _93, _94, _95, _96, _97, _98, _99, \
_100, _101, _102, _103, _104, _105, _106, _107, _108, _109, \
_110, _111, _112, _113, _114, _115, _116, _117, _118, _119, \
_120, _121, _122, _123, _124, _125, _126, _127, _128, N, ...) N
#define PP_NARG_RSEQ_N_() \
128, 127, 126, 125, 124, 123, 122, 121, 120, \
119, 118, 117, 116, 115, 114, 113, 112, 111, 110, \
109, 108, 107, 106, 105, 104, 103, 102, 101, 100, \
99, 98, 97, 96, 95, 94, 93, 92, 91, 90, \
89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
79, 78, 77, 76, 75, 74, 73, 72, 71, 70, \
69, 68, 67, 66, 65, 64, 63, 62, 61, 60, \
59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#!/bin/bash
##
# Copyright (C) 2018 Jan Chren (rindeal)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-only
##
MAX_ARGS=128
MAIN_NAME="PP_NARG"
ARG_N_NAME="${MAIN_NAME}_ARG_N_"
RSEQ_N_NAME="${MAIN_NAME}_RSEQ_N_"
INDENT=$'\t'
BR_=' \\\n'
EOL_='\n'
ASSERT=0
printf "#define ${MAIN_NAME}(...)${BR_}"
printf "${INDENT}${MAIN_NAME}_(0, ## __VA_ARGS__, ${RSEQ_N_NAME}())${EOL_}"
printf "#define ${MAIN_NAME}_(...)${BR_}"
printf "${INDENT}${ARG_N_NAME}(__VA_ARGS__)${EOL_}"
printf "#define ${ARG_N_NAME}("
for (( i = 0 ; i <= MAX_ARGS ; i++ ))
do
if (( i%10 == 0 ))
then
printf "${BR_}${INDENT}"
else
printf " "
fi
printf "%4s," "_${i}"
done
printf "%4s, ...) N${EOL_}" "N"
printf "#define ${RSEQ_N_NAME}()${BR_}${INDENT}"
for (( i = MAX_ARGS ; i >= 0 ; i-- ))
do
if (( i == 0 ))
then
printf "%4s${EOL_}" "${i}"
break
fi
printf "%4s," "${i}"
if (( i%10 == 0 ))
then
printf "${BR_}${INDENT}"
else
printf " "
fi
done
if (( ASSERT ))
then
echo
echo
printf "#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))${EOL_}"
printf "int main(void) {${EOL_}"
for (( i = 0 ; i <= MAX_ARGS ; i ++ ))
do
printf "BUILD_BUG_ON( ${MAIN_NAME}("
for (( j = 1 ; j <= i ; j++ ))
do
printf "a${j}"
if (( j != i ))
then
printf ", "
fi
done
printf ") != ${i} );${EOL_}"
done
printf "}${EOL_}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment