Exemplo n.º 1
0
/**
 * Parse the incoming command line and put resulting parameters in to the state
 *
 * @param argc Number of arguments in command line
 * @param argv Array of pointers to strings from command line
 * @param state Pointer to state structure to assign any discovered parameters to
 * @return non-0 if failed for some reason, 0 otherwise
 */
static int parse_cmdline(int argc, const char **argv, RASPISTILLYUV_STATE *state)
{
   // Parse the command line arguments.
   // We are looking for --<something> or -<abreviation of something>

   int valid = 1; // set 0 if we have a bad parameter
   int i;

   for (i = 1; i < argc && valid; i++)
   {
      int command_id, num_parameters;

      if (!argv[i])
         continue;

      if (argv[i][0] != '-')
      {
         valid = 0;
         continue;
      }

      // Assume parameter is valid until proven otherwise
      valid = 1;

      command_id = raspicli_get_command_id(cmdline_commands, cmdline_commands_size, &argv[i][1], &num_parameters);

      // If we found a command but are missing a parameter, continue (and we will drop out of the loop)
      if (command_id != -1 && num_parameters > 0 && (i + 1 >= argc) )
         continue;

      //  We are now dealing with a command line option
      switch (command_id)
      {
      case CommandHelp:
         display_valid_parameters(basename(argv[0]));
         return -1;

      case CommandWidth: // Width > 0
         if (sscanf(argv[i + 1], "%u", &state->width) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandHeight: // Height > 0
         if (sscanf(argv[i + 1], "%u", &state->height) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandOutput:  // output filename
      {
         int len = strlen(argv[i + 1]);
         if (len)
         {
            state->filename = malloc(len + 10); // leave enough space for any timelapse generated changes to filename
            vcos_assert(state->filename);
            if (state->filename)
               strncpy(state->filename, argv[i + 1], len+1);
            i++;
         }
         else
            valid = 0;
         break;
      }

      case CommandLink :
      {
         int len = strlen(argv[i+1]);
         if (len)
         {
            state->linkname = malloc(len + 10);
            vcos_assert(state->linkname);
            if (state->linkname)
               strncpy(state->linkname, argv[i + 1], len+1);
            i++;
         }
         else
            valid = 0;
         break;

      }

      case CommandVerbose: // display lots of data during run
         state->verbose = 1;
         break;

      case CommandTimeout: // Time to run viewfinder for before taking picture, in seconds
      {
         if (sscanf(argv[i + 1], "%u", &state->timeout) == 1)
         {
            // Ensure that if previously selected CommandKeypress we don't overwrite it
            if (state->timeout == 0 && state->frameNextMethod == FRAME_NEXT_SINGLE)
               state->frameNextMethod = FRAME_NEXT_FOREVER;

            i++;
         }
         else
            valid = 0;
         break;
      }

      case CommandTimelapse:
         if (sscanf(argv[i + 1], "%u", &state->timelapse) != 1)
            valid = 0;
         else
         {
            if (state->timelapse)
               state->frameNextMethod = FRAME_NEXT_TIMELAPSE;
            else
               state->frameNextMethod = FRAME_NEXT_IMMEDIATELY;


            i++;
         }
         break;

      case CommandUseRGB: // display lots of data during run
         state->useRGB = 1;
         break;
      
      case CommandCamSelect:  //Select camera input port
      {
         if (sscanf(argv[i + 1], "%u", &state->cameraNum) == 1)
         {
            i++;
         }
         else
            valid = 0;
		  break;
	  }

      case CommandFullResPreview:
         state->fullResPreview = 1;
         break;

      case CommandKeypress: // Set keypress between capture mode
         state->frameNextMethod = FRAME_NEXT_KEYPRESS;
         break;

      case CommandSignal:   // Set SIGUSR1 between capture mode
         state->frameNextMethod = FRAME_NEXT_SIGNAL;
         // Reenable the signal
         signal(SIGUSR1, signal_handler);
         break;

      case CommandSettings:
         state->settings = 1;
         break;

      case CommandBurstMode: 
         state->burstCaptureMode=1;
         break;
         
      default:
      {
         // Try parsing for any image specific parameters
         // result indicates how many parameters were used up, 0,1,2
         // but we adjust by -1 as we have used one already
         const char *second_arg = (i + 1 < argc) ? argv[i + 1] : NULL;

         int parms_used = (raspicamcontrol_parse_cmdline(&state->camera_parameters, &argv[i][1], second_arg));

         // Still unused, try preview options
         if (!parms_used)
            parms_used = raspipreview_parse_cmdline(&state->preview_parameters, &argv[i][1], second_arg);


         // If no parms were used, this must be a bad parameters
         if (!parms_used)
            valid = 0;
         else
            i += parms_used - 1;

         break;
      }
      }
   }

   if (!valid)
   {
      fprintf(stderr, "Invalid command line option (%s)\n", argv[i-1]);
      return 1;
   }

   return 0;
}
Exemplo n.º 2
0
/**
 * Parse the incoming command line and put resulting parameters in to the state
 *
 * @param argc Number of arguments in command line
 * @param argv Array of pointers to strings from command line
 * @param state Pointer to state structure to assign any discovered parameters to
 * @return non-0 if failed for some reason, 0 otherwise
 */
static int parse_cmdline(int argc, const char **argv, RASPISTILL_STATE *state)
{
   // Parse the command line arguments.
   // We are looking for --<something> or -<abreviation of something>

   int valid = 1;
   int i;

   for (i = 1; i < argc && valid; i++)
   {
      int command_id, num_parameters;

      if (!argv[i])
         continue;

      if (argv[i][0] != '-')
      {
         valid = 0;
         continue;
      }

      // Assume parameter is valid until proven otherwise
      valid = 1;

      command_id = raspicli_get_command_id(cmdline_commands, cmdline_commands_size, &argv[i][1], &num_parameters);

      // If we found a command but are missing a parameter, continue (and we will drop out of the loop)
      if (command_id != -1 && num_parameters > 0 && (i + 1 >= argc) )
         continue;

      //  We are now dealing with a command line option
      switch (command_id)
      {
      case CommandHelp:
         display_valid_parameters(basename(argv[0]));
         // exit straight away if help requested
         return -1;

      case CommandWidth: // Width > 0
         if (sscanf(argv[i + 1], "%u", &state->width) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandHeight: // Height > 0
         if (sscanf(argv[i + 1], "%u", &state->height) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandQuality: // Quality = 1-100
         if (sscanf(argv[i + 1], "%u", &state->quality) == 1)
         {
            if (state->quality > 100)
            {
               fprintf(stderr, "Setting max quality = 100\n");
               state->quality = 100;
            }
            i++;
         }
         else
            valid = 0;

         break;

      case CommandRaw: // Add raw bayer data in metadata
         state->wantRAW = 1;
         break;

      case CommandOutput:  // output filename
      {
         int len = strlen(argv[i + 1]);
         if (len)
         {
            state->filename = malloc(len + 10); // leave enough space for any timelapse generated changes to filename
            vcos_assert(state->filename);
            if (state->filename)
               strncpy(state->filename, argv[i + 1], len);
            i++;
         }
         else
            valid = 0;
         break;
      }

      case CommandLink :
      {
         int len = strlen(argv[i+1]);
         if (len)
         {
            state->linkname = malloc(len + 10);
            vcos_assert(state->linkname);
            if (state->linkname)
               strncpy(state->linkname, argv[i + 1], len);
            i++;
         }
         else
            valid = 0;
         break;
         
      }
      case CommandVerbose: // display lots of data during run
         state->verbose = 1;
         break;

      case CommandTimeout: // Time to run viewfinder for before taking picture, in seconds
      {
         if (sscanf(argv[i + 1], "%u", &state->timeout) == 1)
         {
            // TODO : What limits do we need for timeout?
            i++;
         }
         else
            valid = 0;
         break;
      }
      case CommandThumbnail : // thumbnail parameters - needs string "x:y:quality"
         sscanf(argv[i + 1], "%d:%d:%d", &state->thumbnailConfig.width,&state->thumbnailConfig.height,
                  &state->thumbnailConfig.quality);
         i++;
         break;

      case CommandDemoMode: // Run in demo mode - no capture
      {
         // Demo mode might have a timing parameter
         // so check if a) we have another parameter, b) its not the start of the next option
         if (i + 1 < argc  && argv[i+1][0] != '-')
         {
            if (sscanf(argv[i + 1], "%u", &state->demoInterval) == 1)
            {
               // TODO : What limits do we need for timeout?
               state->demoMode = 1;
               i++;
            }
            else
               valid = 0;
         }
         else
         {
            state->demoMode = 1;
         }

         break;
      }

      case CommandEncoding :
      {
         int len = strlen(argv[i + 1]);
         valid = 0;

         if (len)
         {
            int j;
            for (j=0;j<encoding_xref_size;j++)
            {
               if (strcmp(encoding_xref[j].format, argv[i+1]) == 0)
               {
                  state->encoding = encoding_xref[j].encoding;
                  valid = 1;
                  i++;
                  break;
               }
            }
         }
         break;
      }

      case CommandExifTag:
         store_exif_tag(state, argv[i+1]);
         i++;
         break;

      case CommandTimelapse:
         if (sscanf(argv[i + 1], "%u", &state->timelapse) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandFullResPreview:
         state->fullResPreview = 1;
         break;

      default:
      {
         // Try parsing for any image specific parameters
         // result indicates how many parameters were used up, 0,1,2
         // but we adjust by -1 as we have used one already
         const char *second_arg = (i + 1 < argc) ? argv[i + 1] : NULL;
         int parms_used = raspicamcontrol_parse_cmdline(&state->camera_parameters, &argv[i][1], second_arg);

         // Still unused, try preview options
         if (!parms_used)
            parms_used = raspipreview_parse_cmdline(&state->preview_parameters, &argv[i][1], second_arg);

         // If no parms were used, this must be a bad parameters
         if (!parms_used)
            valid = 0;
         else
            i += parms_used - 1;

         break;
      }
      }
   }

   if (!valid)
   {
      fprintf(stderr, "Invalid command line option (%s)\n", argv[i]);
      return 1;
   }

   return 0;
}
Exemplo n.º 3
0
/**
 * Parse the incoming command line and put resulting parameters in to the state
 *
 * @param argc Number of arguments in command line
 * @param argv Array of pointers to strings from command line
 * @param state Pointer to state structure to assign any discovered parameters to
 * @return Non-0 if failed for some reason, 0 otherwise
 */
static int parse_cmdline(int argc, const char **argv, RASPIVID_STATE *state)
{
   // Parse the command line arguments.
   // We are looking for --<something> or -<abreviation of something>

   int valid = 1;
   int i;

   for (i = 1; i < argc && valid; i++)
   {
      int command_id, num_parameters;

      if (!argv[i])
         continue;

      if (argv[i][0] != '-')
      {
         valid = 0;
         continue;
      }

      // Assume parameter is valid until proven otherwise
      valid = 1;

      command_id = raspicli_get_command_id(cmdline_commands, cmdline_commands_size, &argv[i][1], &num_parameters);

      // If we found a command but are missing a parameter, continue (and we will drop out of the loop)
      if (command_id != -1 && num_parameters > 0 && (i + 1 >= argc) )
         continue;

      //  We are now dealing with a command line option
      switch (command_id)
      {
      case CommandHelp:
         display_valid_parameters(basename(argv[0]));
         return -1;

      case CommandWidth: // Width > 0
         if (sscanf(argv[i + 1], "%u", &state->width) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandHeight: // Height > 0
         if (sscanf(argv[i + 1], "%u", &state->height) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandBitrate: // 1-100
         if (sscanf(argv[i + 1], "%u", &state->bitrate) == 1)
         {
            if (state->bitrate > MAX_BITRATE)
            {
               state->bitrate = MAX_BITRATE;
            }
            i++;
         }
         else
            valid = 0;

         break;

      case CommandOutput:  // output filename
      {
         int len = strlen(argv[i + 1]);
         if (len)
         {
            state->filename = malloc(len + 1);
            vcos_assert(state->filename);
            if (state->filename)
               strncpy(state->filename, argv[i + 1], len);
            i++;
         }
         else
            valid = 0;
         break;
      }

      case CommandVerbose: // display lots of data during run
         state->verbose = 1;
         break;

      case CommandTimeout: // Time to run viewfinder/capture
      {
         if (sscanf(argv[i + 1], "%u", &state->timeout) == 1)
         {
            // TODO : What limits do we need for timeout?
            i++;
         }
         else
            valid = 0;
         break;
      }

      case CommandDemoMode: // Run in demo mode - no capture
      {
         // Demo mode might have a timing parameter
         // so check if a) we have another parameter, b) its not the start of the next option
         if (i + 1 < argc  && argv[i+1][0] != '-')
         {
            if (sscanf(argv[i + 1], "%u", &state->demoInterval) == 1)
            {
               // TODO : What limits do we need for timeout?
               if (state->demoInterval == 0)
                  state->demoInterval = 250; // ms

               state->demoMode = 1;
               i++;
            }
            else
               valid = 0;
         }
         else
         {
            state->demoMode = 1;
         }

         break;
      }

      case CommandFramerate: // fps to record
      {
         if (sscanf(argv[i + 1], "%u", &state->framerate) == 1)
         {
            // TODO : What limits do we need for fps 1 - 30 - 120??
            i++;
         }
         else
            valid = 0;
         break;
      }

      case CommandPreviewEnc:
         state->immutableInput = 0;
         break;

      case CommandIntraPeriod: // key frame rate
      {
         if (sscanf(argv[i + 1], "%u", &state->intraperiod) == 1)
            i++;
         else
            valid = 0;
         break;
      }

      default:
      {
         // Try parsing for any image specific parameters
         // result indicates how many parameters were used up, 0,1,2
         // but we adjust by -1 as we have used one already
         const char *second_arg = (i + 1 < argc) ? argv[i + 1] : NULL;
         int parms_used = (raspicamcontrol_parse_cmdline(&state->camera_parameters, &argv[i][1], second_arg));

         // Still unused, try preview options
         if (!parms_used)
            parms_used = raspipreview_parse_cmdline(&state->preview_parameters, &argv[i][1], second_arg);


         // If no parms were used, this must be a bad parameters
         if (!parms_used)
            valid = 0;
         else
            i += parms_used - 1;

         break;
      }
      }
   }

   if (!valid)
   {
      fprintf(stderr, "Invalid command line option (%s)\n", argv[i]);
      return 1;
   }

   // Always disable verbose if output going to stdout
   if (state->filename && state->filename[0] == '-')
   {
      state->verbose = 0;
   }

   return 0;
}
Exemplo n.º 4
0
/**
 * Parse the incoming command line and put resulting parameters in to the state
 *
 * @param argc Number of arguments in command line
 * @param argv Array of pointers to strings from command line
 * @param state Pointer to state structure to assign any discovered parameters to
 * @return 0 if failed for some reason, non-0 otherwise
 */
static int parse_cmdline(int argc, const char **argv, RASPISTILLYUV_STATE *state)
{
   // Parse the command line arguments.
   // We are looking for --<something> or -<abreviation of something>

   int valid = 1; // set 0 if we have a bad parameter
   int i;

   for (i = 1; i < argc && valid; i++)
   {
      int command_id, num_parameters;

      if (!argv[i])
         continue;

      if (argv[i][0] != '-')
      {
         valid = 0;
         continue;
      }

      // Assume parameter is valid until proven otherwise
      valid = 1;

      command_id = raspicli_get_command_id(cmdline_commands, cmdline_commands_size, &argv[i][1], &num_parameters);

      // If we found a command but are missing a parameter, continue (and we will drop out of the loop)
      if (command_id != -1 && num_parameters > 0 && (i + 1 >= argc) )
         continue;

      //  We are now dealing with a command line option
      switch (command_id)
      {
      case CommandHelp:
         display_valid_parameters();
         break;

      case CommandWidth: // Width > 0
         if (sscanf(argv[i + 1], "%u", &state->width) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandHeight: // Height > 0
         if (sscanf(argv[i + 1], "%u", &state->height) != 1)
            valid = 0;
         else
            i++;
         break;

      case CommandOutput:  // output filename
      {
         int len = strlen(argv[i + 1]);
         if (len)
         {
            state->filename = malloc(len + 1);
            vcos_assert(state->filename);
            if (state->filename)
               strncpy(state->filename, argv[i + 1], len);
            i++;
         }
         else
            valid = 0;
         break;
      }

      case CommandVerbose: // display lots of data during run
         state->verbose = 1;
         break;

      case CommandTimeout: // Time to run viewfinder for before taking picture, in seconds
      {
         if (sscanf(argv[i + 1], "%u", &state->timeout) == 1)
         {
            // TODO : What limits do we need for timeout?
            i++;
         }
         else
            valid = 0;
         break;
      }

      default:
      {
         // Try parsing for any image specific parameters
         // result indicates how many parameters were used up, 0,1,2
         // but we adjust by -1 as we have used one already
         const char *second_arg = (i + 1 < argc) ? argv[i + 1] : NULL;

         int parms_used = (raspicamcontrol_parse_cmdline(&state->camera_parameters, &argv[i][1], second_arg));

         // Still unused, try preview options
         if (!parms_used)
            parms_used = raspipreview_parse_cmdline(&state->preview_parameters, &argv[i][1], second_arg);


         // If no parms were used, this must be a bad parameters
         if (!parms_used)
            valid = 0;
         else
            i += parms_used - 1;

         break;
      }
      }
   }

   if (!valid)
   {
      printf("Invalid command line option (%s)\n", argv[i]);
      return 1;
   }

   return 0;
}
Exemplo n.º 5
0
int catcierge_parse_setting(catcierge_args_t *args, const char *key, char **values, size_t value_count)
{
	size_t i;
	int ret;
	assert(args);
	assert(key);

	if (!strcmp(key, "matcher"))
	{
		if (value_count == 1)
		{
			args->matcher = values[0];
			if (strcmp(args->matcher, "template")
				&& strcmp(args->matcher, "haar"))
			{
				fprintf(stderr, "Invalid template type \"%s\"\n", args->matcher);
				return -1;
			}

			args->matcher_type = !strcmp(args->matcher, "template")
				? MATCHER_TEMPLATE : MATCHER_HAAR;

			return 0;
		}
		else
		{
			fprintf(stderr, "Missing value for --matcher\n");
			return -1;
		}

		return 0;
	}

	ret = catcierge_haar_matcher_parse_args(&args->haar, key, values, value_count);
	if (ret < 0) return -1;
	else if (!ret) return 0;

	ret = catcierge_template_matcher_parse_args(&args->templ, key, values, value_count);
	if (ret < 0) return -1;
	else if (!ret) return 0;

	if (!strcmp(key, "show"))
	{
		args->show = 1;
		if (value_count == 1) args->show = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "ok_matches_needed"))
	{
		if (value_count == 1)
		{
			args->ok_matches_needed = atoi(values[0]);

			if ((args->ok_matches_needed < 0)
				|| (args->ok_matches_needed > MATCH_MAX_COUNT))
			{
				fprintf(stderr, "--ok_matches_needed must be between 0 and %d\n", MATCH_MAX_COUNT);
				return -1;
			}

			return 0;
		}

		fprintf(stderr, "--ok_matches_needed missing an integer value\n");
		return -1;
	}

	if (!strcmp(key, "lockout_method"))
	{
		if (value_count == 1)
		{
			args->lockout_method = atoi(values[0]);

			if ((args->lockout_method < OBSTRUCT_OR_TIMER_1)
			 || (args->lockout_method > TIMER_ONLY_3))
			{
				fprintf(stderr, "--lockout_method needs a value between %d and %d\n",
					OBSTRUCT_OR_TIMER_1, TIMER_ONLY_3);
				return -1;
			}

			return 0;
		}

		fprintf(stderr, "--lockout_method missing an integer value\n");
		return -1;
	}

	if (!strcmp(key, "save"))
	{
		args->saveimg = 1;
		if (value_count == 1) args->saveimg = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "save_obstruct"))
	{
		args->save_obstruct_img = 1;
		if (value_count == 1) args->save_obstruct_img = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "new_execute"))
	{
		args->new_execute = 1;
		if (value_count == 1) args->new_execute = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "highlight"))
	{
		args->highlight_match = 1;
		if (value_count == 1) args->highlight_match = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "lockout"))
	{
		args->lockout_time = DEFAULT_LOCKOUT_TIME;
		if (value_count == 1) args->lockout_time = atoi(values[0]);

		return 0;
	}

	if (!strcmp(key, "lockout_error_delay"))
	{
		if (value_count == 1)
		{
			args->consecutive_lockout_delay = atof(values[0]);
			return 0;
		}

		fprintf(stderr, "--lockout_error_delay missing a seconds value\n");
		return -1;
	}

	if (!strcmp(key, "lockout_error"))
	{
		if (value_count == 1)
		{
			args->max_consecutive_lockout_count = atoi(values[0]);
			return 0;
		}

		fprintf(stderr, "--lockout_error missing a value\n");
		return -1;
	}

	if (!strcmp(key, "lockout_dummy"))
	{
		args->lockout_dummy = 1;
		if (value_count == 1) args->lockout_dummy = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "matchtime"))
	{
		args->match_time = DEFAULT_MATCH_WAIT;
		if (value_count == 1) args->match_time = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "no_final_decision"))
	{
		args->no_final_decision = 1;
		if (value_count == 1) args->no_final_decision = atoi(values[0]);
		return 0;
	}

	#ifdef WITH_ZMQ
	if (!strcmp(key, "zmq"))
	{
		args->zmq = 1;
		if (value_count == 1) args->zmq = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "zmq_port"))
	{
		args->zmq_port = DEFAULT_ZMQ_PORT;

		if (value_count < 1)
		{
			fprintf(stderr, "--zmq_port missing value\n");
			return -1;
		}

		args->zmq_port = atoi(values[0]);

		return 0;
	}

	if (!strcmp(key, "zmq_iface"))
	{
		if (value_count < 1)
		{
			fprintf(stderr, "--zmq_iface missing interface name\n");
			return -1;
		}

		args->zmq_iface = values[0];

		return 0;
	}

	if (!strcmp(key, "zmq_transport"))
	{
		if (value_count != 1)
		{
			fprintf(stderr, "--zmq_transport missing value\n");
			return -1;
		}

		args->zmq_transport = values[0];

		return 0;
	}
	#endif // WITH_ZMQ

	if (!strcmp(key, "output") || !strcmp(key, "output_path"))
	{
		if (value_count == 1)
		{
			args->output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "match_output_path"))
	{
		if (value_count == 1)
		{
			args->match_output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--match_output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "steps_output_path"))
	{
		if (value_count == 1)
		{
			args->steps_output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--steps_output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "obstruct_output_path"))
	{
		if (value_count == 1)
		{
			args->obstruct_output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--obstruct_output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "template_output_path"))
	{
		if (value_count == 1)
		{
			args->template_output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--template_output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "input") || !strcmp(key, "template"))
	{
		if (value_count == 0)
		{
			fprintf(stderr, "--template missing value\n");
			return -1;
		}

		for (i = 0; i < value_count; i++)
		{
			if (args->input_count >= MAX_INPUT_TEMPLATES)
			{
				fprintf(stderr, "Max template input reached %d\n", MAX_INPUT_TEMPLATES);
				return -1;
			}
			args->inputs[args->input_count] = values[i];
			args->input_count++;
		}

		return 0;
	}

	#ifdef WITH_RFID
	if (!strcmp(key, "rfid_in"))
	{
		if (value_count == 1)
		{
			args->rfid_inner_path = values[0];
			return 0;
		}

		fprintf(stderr, "--rfid_in missing path value\n");
		return -1;
	}

	if (!strcmp(key, "rfid_out"))
	{
		if (value_count == 1)
		{
			args->rfid_outer_path = values[0];
			return 0;
		}

		fprintf(stderr, "--rfid_out missing path value\n");
		return -1;
	}

	if (!strcmp(key, "rfid_allowed"))
	{
		if (value_count == 1)
		{
			if (catcierge_create_rfid_allowed_list(args, values[0]))
			{
				CATERR("Failed to create RFID allowed list\n");
				return -1;
			}

			return 0;
		}

		fprintf(stderr, "--rfid_allowed missing comma separated list of values\n");
		return -1;
	}

	if (!strcmp(key, "rfid_time"))
	{
		if (value_count == 1)
		{
			args->rfid_lock_time = (double)atof(values[0]);
			return 0;
		}

		fprintf(stderr, "--rfid_time missing seconds value (float)\n");
		return -1;
	}

	if (!strcmp(key, "rfid_lock"))
	{
		args->lock_on_invalid_rfid = 1;
		if (value_count == 1) args->lock_on_invalid_rfid = atoi(values[0]);
		return 0;
	}
	#endif // WITH_RFID

	if (!strcmp(key, "log"))
	{
		if (value_count == 1)
		{
			args->log_path = values[0];
			return 0;
		}

		fprintf(stderr, "--log missing path value\n");
		return -1;
	}

	if (!strcmp(key, "match_cmd"))
	{
		if (value_count == 1)
		{
			args->match_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--match_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "save_img_cmd"))
	{
		if (value_count == 1)
		{
			args->save_img_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--save_img_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "frame_obstructed_cmd"))
	{
		if (value_count == 1)
		{
			args->frame_obstructed_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--frame_obstructed_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "save_imgs_cmd") || !strcmp(key, "match_group_done_cmd"))
	{
		if (value_count == 1)
		{
			args->match_group_done_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--match_group_done_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "match_done_cmd"))
	{
		if (value_count == 1)
		{
			args->match_done_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--match_done_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "do_lockout_cmd"))
	{
		if (value_count == 1)
		{
			args->do_lockout_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--do_lockout_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "do_unlock_cmd"))
	{
		if (value_count == 1)
		{
			args->do_unlock_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--do_unlock cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "state_change_cmd"))
	{
		if (value_count == 1)
		{
			args->state_change_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--state_change_cmd cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "nocolor"))
	{
		args->nocolor = 1;
		if (value_count == 1) args->nocolor = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "noanim"))
	{
		args->noanim = 1;
		if (value_count == 1) args->noanim = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "save_steps"))
	{
		args->save_steps = 1;
		if (value_count == 1) args->save_steps = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "chuid"))
	{
		if (value_count == 1)
		{
			args->chuid = values[0];
			return 0;
		}

		fprintf(stderr, "--chuid missing value\n");
		return -1;
	}

	#ifdef WITH_RFID
	if (!strcmp(key, "rfid_detect_cmd"))
	{
		if (value_count == 1)
		{
			args->rfid_detect_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--rfid_detect_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "rfid_match_cmd"))
	{
		if (value_count == 1)
		{
			args->rfid_match_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--rfid_match_cmd missing value\n");
		return -1;
	}
	#endif // WITH_RFID

	#ifndef _WIN32
	// TODO: Support this on windows.
	if (!strcmp(key, "base_time"))
	{
		if (value_count == 1)
		{
			struct tm base_time_tm;
			time_t base_time_t;
			struct timeval base_time_now;
			long base_time_diff;

			memset(&base_time_tm, 0, sizeof(base_time_tm));
			memset(&base_time_now, 0, sizeof(base_time_now));

			args->base_time = values[0];

			if (!strptime(args->base_time, "%Y-%m-%dT%H:%M:%S", &base_time_tm))
			{
				goto fail_base_time;
			}

			if ((base_time_t = mktime(&base_time_tm)) == -1)
			{
				goto fail_base_time;
			}

			gettimeofday(&base_time_now, NULL);
			base_time_diff = base_time_now.tv_sec - base_time_t;

			catcierge_strftime_set_base_diff(base_time_diff);

			return 0;

		fail_base_time:
			fprintf(stderr, "Failed to parse --base_time %s\n", values[0]);
			return -1;
		}

		fprintf(stderr, "--base_time missing value\n");
		return -1;
	}
	#endif // _WIN32

	#ifdef RPI
	if (!strncmp(key, "rpi-", 4))
	{
		int rpiret = 0;
		const char *rpikey = key + strlen("rpi");

		if (!raspicamcontrol_parse_cmdline(&args->rpi_settings.camera_parameters,
			rpikey, (value_count == 1) ? values[0] : NULL))
		{
			return -1;
		}
		return 0;
	}
	#endif // RPI

	return -1;
}