title: Simplify and reduce the amount of code without using macros
body: <p>Sometimes, there are situations where the repetition of simple code blocks is unavoidable. To illustrate, with this example code:</p>
  
  <p><em>Note: this code is for illustration purpose only, real-life code is much bigger and more complex. Also it may contain errors, but the point of this question is not that.</em></p>
  
  <pre><code>switch(cmd) {
      case CMD_BLOCK_READ:
          if(current_user != key) {
              ERROR("Access violation - invalid key!");
              res = CR_ACCESS_DENIED;
              break; 
          }
          if(current_state &lt; STATE_BUSY) {
              WARN("Command %s is not allowed in this state!", cmd_name[cmd]);
              res = CR_NOT_PERMITTED;
              break;
          }
          if(ioctl(fd, HPI_CTL_BR) != 0) {
              WARN("Handshake failed (%s). Aborted!", strerror(errno));
              res = CR_TIME_OUT;
              goto post_resp;
          }
          if(block_read(id) != 0) {
              ERROR("Failed to read %d block (%s)! Aborted!", id, strerror(errno));
              res = CR_FAIL;
              goto send_nop;
          }
  
          res = CR_SUCCESS;
          break;
      case CMD_BLOCK_WRITE:
          if(current_user != key) {
              ERROR("Access violation - invalid key!");
              res = CR_ACCESS_DENIED;
              break; 
          }
          if(current_state &lt; STATE_BUSY) {
              WARN("Command %s is not allowed in this state!", cmd_name[cmd]);
              res = CR_NOT_PERMITTED;
              break;
          }
          if(ioctl(fd, HPI_CTL_BR) != 0) {
              WARN("Handshake failed (%s). Aborted!", strerror(errno));
              res = CR_TIME_OUT;
              goto post_resp;
          }
          if(block_write(id) != 0) {
              ERROR("Failed to write %d block - %s. Command aborted!", id, strerror(errno));
              res = CR_FAIL;
              goto send_nop;
          }
          res = CR_SUCCESS;
          break;
      case CMD_REQ_START:
          if(current_state &lt; STATE_READY) {
              WARN("Command %s is not allowed in this state!", cmd_name[cmd]);
              res = CR_NOT_PERMITTED;
              break;
          }
          state = STATE_BUSY;
          if(ioctl(fd, HPI_CTL_BR) != 0) {
              WARN("Handshake failed (%s). Aborted!", strerror(errno));
              res = CR_TIME_OUT;
              goto send_nop;
          }
          if(block_read(id) != 0) {
              ERROR("Failed to read %d block (%s)! Aborted!", id, strerror(errno));
              res = CR_FAIL;
              goto post_resp;
          }
          res = CR_SUCCESS;
          break;
      }
  
      /* The remaining 28 or so similar commands */
  }
  </code></pre>
  
  <p>As you can see, due to minor differences and the extensive use of <em>break/goto</em> statements, it is not possible to use functions or inlines. What I usually do is define some macros:</p>
  
  <pre><code>/* NOTE: DO NOT USE these macros outside of Big Switch */
  #define CHECK_KEY(_key) \
     if(current_user != (_key)) \
     { \
        ERROR("Access violation!"); \
        res = CR_ACCESS_DENIED; \
        break; \
     }
  #define CHECK_STATE(_state) \
     if(current_state &lt; _state) \
     { \
        WARN("Command %s is not allowed in this state!", cmd_name[cmd]); \
        res = CR_NOT_PERMITTED; \
        break; \
     }
  
  #define HANDSHAKE(_fail) \
     if(ioctl(fd, CTL_BR) != 0) \
     { \
        WARN("Handshake failed (%s). Aborted!", strerror(errno)); \
        res = CR_TIME_OUT; \
        goto _fail; \
     }
  
  #define BLOCK_READ(_id, _fail) \
     if(block_read((int)(_id))!= 0) \
     { \
        ERROR("Failed to read %d block (%s)! Aborted!", (int)_id, strerror(errno)); \
        res = CR_FAIL; \
        goto _fail; \
     }
  
  #define BLOCK_WRITE(_id, _fail) \
     if(block_write((int)(_id)) != 0) \
     { \
        ERROR("Failed to write %d block - %s. Aborted!", (int)_id, strerror(errno)); \
        res = CR_FAIL; \
        goto _fail; \
     }
  </code></pre>
  
  <p>..and write the same code using them. The code becomes <strong>much</strong> smaller and (arguably) more readable:</p>
  
  <pre><code>switch(cmd) 
  {
  case CMD_BLOCK_READ:
     CHECK_KEY(key);
     CHECK_STATE(STATE_BUSY);
     HANDSHAKE(post_resp);
     BLOCK_READ(id, send_nop);
     res = CR_SUCCESS;
     break;
  case CMD_BLOCK_WRITE:
     CHECK_KEY(key);
     CHECK_STATE(STATE_BUSY);
     HANDSHAKE(post_resp);
     BLOCK_WRITE(id, send_nop);
     res = CR_SUCCESS;
     break;
  case CMD_REQ_START:
  {
     CHECK_STATE(STATE_READY);
     state = STATE_BUSY;
     HANDSHAKE(send_nop);
     BLOCK_READ(id, post_resp);
     res = CR_SUCCESS;
     break;
  }
  /* The remaining 28 or so similar commands */
  &lt;..&gt;
  </code></pre>
  
  <p>The code looks more like some kind of scripting language than good old <em>C</em> and is really ugly, but I'm willing to sacrifice that for the sake of readability.</p>
  
  <p><strong>The question</strong> is how do you cope with similar situations? What are more elegant solutions and best practises?</p>
  
  <p><strong>P.S.</strong> I admit that in general case macros and <em>goto</em> statement is a sign of bad design, so no need to flame about how evil they are or how poor my programming style is.</p>