title: GNU argp "too few arguments"
body: <p>My program is supposed to take two required arguments, and three optional arguments, like follows</p>
  
  <p><code>ATE &lt;input file&gt; &lt;output file&gt; [--threads] [--bass] [--treble]</code></p>
  
  <p>(note, I haven't figured out how to take <code>&lt;required&gt;</code> arguments yet, so input and output file is defined in the code as -i input_file and -o output_file)</p>
  
  <p>I'm using the GNU library argp to parse the command line arguments, my file is based off the <a href="http://www.gnu.org/software/libc/manual/html_node/Argp-Example-3.html" rel="nofollow">third example</a>.</p>
  
  <p>I run my program using the following command</p>
  
  <pre><code>$ ./ATE -i input_file.pcm -o output_file.pcm
  Too few arguments!
  Usage: ATE [OPTION...]
              -p AMOUNT_OF_THREADS -b BASS_INTENSITY -t TREBLE_INTENSITY
              input_file.pcm output_file.pcm
  Try `ATE --help' or `ATE --usage' for more information.
  threads: 2, bass: 4, treble: 4
  opening file input.pcm
  RUNNING!
  done, saving to out.pcm
  </code></pre>
  
  <p>When running my program, I get "too few arguments", even though argp succesfully parsed the input and output option, as you can see in the output. </p>
  
  <p>Printing out the number of arguments in parse_opt, <code>cout &lt;&lt; state-&gt;arg_num &lt;&lt; endl;</code> gives me 0's at every call.</p>
  
  <p>The code is a little long, but it's completely self-contained so you can compile it to see for yourself.</p>
  
  <p>commands.cpp
      using namespace std;</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;argp.h&gt;
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;errno.h&gt;
  
  struct arguments {
      string input_file;
      string output_file;
      int threads;
      int bass;
      int treble;
  };
  
  static char doc[] = "Parallequaliser - a multithreaded equaliser application written in c++";
  static char args_doc[] = "-p AMOUNT_OF_THREADS -b BASS_INTENSITY -t TREBLE_INTENSITY input_file.pcm output_file.pcm";
  
  static struct argp_option options[] = {
    {"input_file",  'i', "IN_FILE",           0,                   "an input file in pcm format"},
    {"output_file", 'o', "OUT_FILE",          0,                   "an output file in pcm format"},
    {"threads",     'p', "AMOUNT_OF_THREADS", OPTION_ARG_OPTIONAL, "amount of threads, min 2"},
    {"bass",        'b', "BASS_INTENSITY",    OPTION_ARG_OPTIONAL, "bass intensity, from 0 to 7"},
    {"treble",      't', "TREBLE_INTENSITY",  OPTION_ARG_OPTIONAL, "treble intensity, from 0 to 7"},
    {0}
  };
  
  static error_t parse_opt (int key, char *arg, struct argp_state *state) {
      struct arguments *arguments = (struct arguments *) state-&gt;input;
  
      switch (key) {
          case 'p':
              if (arg == NULL) {
                  arguments-&gt;threads = 4;
              } else {
                  arguments-&gt;threads = strtol(arg, NULL, 10);
              }
              break;
          case 'b':
              if (arg == NULL) {
                  arguments-&gt;bass = 4;
              } else {
                  arguments-&gt;bass = strtol(arg, NULL, 10);
              }
              break;
          case 't':
              if (arg == NULL) {
                  arguments-&gt;treble = 4;
              } else {
                  arguments-&gt;treble = strtol(arg, NULL, 10);
              }
              break;
          case 'i':
              if (arg == NULL) {
                  cout &lt;&lt; "You forgot to specify the input file using the -i input_file.pcm option" &lt;&lt; endl;
              } else {
                  arguments-&gt;input_file = (string) arg;
              }
              break;
          case 'o':
              if (arg == NULL) {
                  cout &lt;&lt; "You forgot to specify the out file using the -i output_file.pcm option" &lt;&lt; endl;
              } else {
                  arguments-&gt;output_file = (string) arg;
              }
              break;
          case ARGP_KEY_ARG:
              cout &lt;&lt; "Key arg... " &lt;&lt; key &lt;&lt; endl;
              if (state-&gt;arg_num &gt; 5){
                  cout &lt;&lt; "Too many arguments!" &lt;&lt; endl;
                  argp_usage(state);
              }
              break;
          case ARGP_KEY_END:
              if (state-&gt;arg_num &lt; 2){
                  cout &lt;&lt; "Too few arguments!" &lt;&lt; endl;
                  argp_usage(state);
              }
              break;
  
              default:
                  return ARGP_ERR_UNKNOWN;
      }
  
  
      return 0;
  }
  
  static struct argp argp = { options, parse_opt, args_doc, doc };
  
  int main (int argc, char **argv) {
      struct arguments arguments;
  
      arguments.threads  = 2;
      arguments.bass     = 4;
      arguments.treble   = 4;
  
      argp_parse(&amp;argp, argc, argv, ARGP_NO_EXIT, 0, &amp;arguments);
  
      cout &lt;&lt; "threads: " &lt;&lt; arguments.threads &lt;&lt; ", bass: " &lt;&lt; arguments.bass &lt;&lt; ", treble: " &lt;&lt; arguments.treble &lt;&lt; endl;
      cout &lt;&lt; "opening file " &lt;&lt; arguments.input_file &lt;&lt; endl;
      cout &lt;&lt; "RUNNING!" &lt;&lt; endl;
      cout &lt;&lt; "done, saving to " &lt;&lt; arguments.output_file &lt;&lt; endl;
  
      return 0;
  }
  </code></pre>