From 24b87607c1353e94689e8a2190571ab3f3b36f31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Wed, 24 Oct 2018 22:30:18 +0100
Subject: [PATCH 07/32] Do not rely on dead code elimination, use array
 instead. Make options bits derived from size and count. Use size of option
 bits and last supported bit in computation. No new change would be required
 when new options are added. Just change OPT_LAST constant.

Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
---
 src/dnsmasq.h | 11 +++++++----
 src/option.c  | 10 ++--------
 2 files changed, 9 insertions(+), 12 deletions(-)

--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -200,9 +200,6 @@ struct event_desc {
 #define EC_MISC        5
 #define EC_INIT_OFFSET 10
 
-/* Trust the compiler dead-code eliminator.... */
-#define option_bool(x) (((x) < 32) ? daemon->options & (1u << (x)) : daemon->options2 & (1u << ((x) - 32)))
-
 #define OPT_BOGUSPRIV      0
 #define OPT_FILTER         1
 #define OPT_LOG            2
@@ -264,6 +261,12 @@ struct event_desc {
 #define OPT_UBUS           58
 #define OPT_LAST           59
 
+#define OPTION_BITS (sizeof(unsigned int)*8)
+#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
+#define option_var(x) (daemon->options[(x) / OPTION_BITS])
+#define option_val(x) ((1u) << ((x) % OPTION_BITS))
+#define option_bool(x) (option_var(x) & option_val(x))
+
 /* extra flags for my_syslog, we use a couple of facilities since they are known 
    not to occupy the same bits as priorities, no matter how syslog.h is set up. */
 #define MS_TFTP   LOG_USER
@@ -978,7 +981,7 @@ extern struct daemon {
      config file arguments. All set (including defaults)
      in option.c */
 
-  unsigned int options, options2;
+  unsigned int options[OPTION_SIZE];
   struct resolvc default_resolv, *resolv_files;
   time_t last_resolv;
   char *servers_file;
--- a/src/option.c
+++ b/src/option.c
@@ -1490,18 +1490,12 @@ static int parse_dhcp_opt(char *errstr,
 
 void set_option_bool(unsigned int opt)
 {
-  if (opt < 32)
-    daemon->options |= 1u << opt;
-  else
-    daemon->options2 |= 1u << (opt - 32);
+  option_var(opt) |= option_val(opt);
 }
 
 void reset_option_bool(unsigned int opt)
 {
-  if (opt < 32)
-    daemon->options &= ~(1u << opt);
-  else
-    daemon->options2 &= ~(1u << (opt - 32));
+  option_var(opt) &= ~(option_val(opt));
 }
 
 static int one_opt(int option, char *arg, char *errstr, char *gen_err, int command_line, int servers_only)
