Exemplo n.º 1
0
static int process_trimming(const char *input, char **storage, const char *input_end, int fail_when_empty)
{
    const char *left, *right;
    int trimmed_input_length;

    left = skip_leading_spaces(input, input_end);
    right = skip_trailing_spaces(input, input_end - 1);

    if (right < left) {
        if (fail_when_empty)
            return git__throw(GIT_EINVALIDARGS, "Failed to trim. Input is either empty or only contains spaces");
        else
            right = left - 1;
    }

    trimmed_input_length = right - left + 1;

    *storage = git__malloc(trimmed_input_length + 1);
    if (*storage == NULL)
        return GIT_ENOMEM;

    memcpy(*storage, left, trimmed_input_length);
    (*storage)[trimmed_input_length] = 0;

    return GIT_SUCCESS;
}
Exemplo n.º 2
0
static int process_trimming(const char *input, char **storage, const char *input_end, int fail_when_empty)
{
	const char *left, *right;
	size_t trimmed_input_length;

	assert(storage);

	left = skip_leading_spaces(input, input_end);
	right = skip_trailing_spaces(input, input_end - 1);

	if (right < left) {
		if (fail_when_empty)
			return signature_error("input is either empty of contains only spaces");

		right = left - 1;
	}

	trimmed_input_length = right - left + 1;

	*storage = git__malloc(trimmed_input_length + 1);
	GITERR_CHECK_ALLOC(*storage);

	memcpy(*storage, left, trimmed_input_length);
	(*storage)[trimmed_input_length] = 0;

	return 0;
}
Exemplo n.º 3
0
static void parse_header(char* header, char** name, long* bytes,
    int nparam, int* params)
{
  char* saveptr = NULL;
  int i;
  assert(header != NULL);
  header = strtok_r(header, ":", &saveptr);
  if (name) {
    *name = header;
    skip_leading_spaces(name);
    cut_trailing_spaces(*name);
  }
  strtok_r(NULL, "<", &saveptr);
  header = strtok_r(NULL, ">", &saveptr);
  if (bytes)
    sscanf(header, "%ld", bytes);
  for (i = 0; i < nparam; ++i) {
    header = strtok_r(NULL, " \n", &saveptr);
    sscanf(header, "%d", &params[i]);
  }
}
Exemplo n.º 4
0
    /* Process the argument character and its associated value.
     * This function processes arguments from the command line and
     * from an argument file associated with the -A argument.
     *
     * An argument -ofile.pgn would be passed in as:
     *                'o' and "file.pgn".
     * A zero-length string for associated_value is not necessarily
     * an error, e.g. -e has an optional following filename.
     * NB: If the associated_value is to be used beyond this function,
     * it must be copied.
     */
void
process_argument(char arg_letter,const char *associated_value)
{   /* Provide an alias for associated_value because it will
     * often represent a file name.
     */
    const char *filename = skip_leading_spaces(associated_value);

    switch(arg_letter){
        case WRITE_TO_OUTPUT_FILE_ARGUMENT:
        case APPEND_TO_OUTPUT_FILE_ARGUMENT:
          if(GlobalState.ECO_level > 0){
              fprintf(GlobalState.logfile,"-%c conflicts with -E\n",
                      arg_letter);
          }
          else if(GlobalState.games_per_file > 0){
              fprintf(GlobalState.logfile,"-%c conflicts with -#\n",
                      arg_letter);
          }
          else if(GlobalState.output_filename != NULL){
              fprintf(GlobalState.logfile,
                      "-%c: File %s has already been selected for output.\n",
                      arg_letter,GlobalState.output_filename);
              exit(1);
          }
          else if(*filename == '\0'){
              fprintf(GlobalState.logfile,"Usage: -%cfilename.\n",arg_letter);
              exit(1);
          }
          else{
              if(GlobalState.outputfile != NULL){
                  (void) fclose(GlobalState.outputfile);
              }
              if(arg_letter == WRITE_TO_OUTPUT_FILE_ARGUMENT){
                  GlobalState.outputfile = must_open_file(filename,"w");
              }
              else{
                  GlobalState.outputfile = must_open_file(filename,"a");
              }
              GlobalState.output_filename = filename;
          }
          break;
        case WRITE_TO_LOG_FILE_ARGUMENT:
        case APPEND_TO_LOG_FILE_ARGUMENT:
          /* Take precautions against multiple log files. */
          if((GlobalState.logfile != stderr) && (GlobalState.logfile != NULL)){
                (void) fclose(GlobalState.logfile);
          }
          if(arg_letter == WRITE_TO_LOG_FILE_ARGUMENT){
                GlobalState.logfile = fopen(filename,"w");
          }
          else{
                GlobalState.logfile = fopen(filename,"a");
          }
          if(GlobalState.logfile == NULL){
                fprintf(stderr,"Unable to open %s for writing.\n",filename);
                GlobalState.logfile = stderr;
          }
          break;
        case DUPLICATES_FILE_ARGUMENT:
          if(*filename == '\0'){
              fprintf(GlobalState.logfile,"Usage: -%cfilename.\n",arg_letter);
              exit(1);
          }
          else if(GlobalState.suppress_duplicates){
              fprintf(GlobalState.logfile,
                      "-%c clashes with the -%c flag.\n",arg_letter,
                      DONT_KEEP_DUPLICATES_ARGUMENT);
              exit(1);
          }
          else{
              GlobalState.duplicate_file = must_open_file(filename,"w");
          }
          break;
        case USE_ECO_FILE_ARGUMENT:
          GlobalState.add_ECO = TRUE;
          if(*filename != '\0'){
              GlobalState.eco_file = copy_string(filename);
          }
          else if((filename = getenv("ECO_FILE")) != NULL){
              GlobalState.eco_file = filename;
          }
          else{
              /* Use the default which is already set up. */
          }
          initEcoTable();
          break;
        case ECO_OUTPUT_LEVEL_ARGUMENT:
          {   unsigned level;

              if(GlobalState.output_filename != NULL){
                  fprintf(GlobalState.logfile,
                          "-%c: File %s has already been selected for output.\n",
                          arg_letter,
                          GlobalState.output_filename);
                  exit(1);
              }
              else if(GlobalState.games_per_file > 0){
                  fprintf(GlobalState.logfile,
                            "-%c conflicts with -#.\n",
                            arg_letter);
                  exit(1);
              }
              else if(sscanf(associated_value,"%u",&level) != 1){
                    fprintf(GlobalState.logfile,
                            "-%c requires a number attached, e.g., -%c1.\n",
                            arg_letter,arg_letter);
                     exit(1);
              }
              else if((level < MIN_ECO_LEVEL) || (level > MAX_ECO_LEVEL)){
                    fprintf(GlobalState.logfile,
                            "-%c level should be between %u and %u.\n",
                            MIN_ECO_LEVEL,MAX_ECO_LEVEL,arg_letter);
                    exit(1);
              }
              else{
                    GlobalState.ECO_level = level;
              }
          }
          break;
        case CHECK_FILE_ARGUMENT:
          if(*filename != '\0'){
              /* See if it is a single PGN file, or a list
               * of files.
               */
              size_t len = strlen(filename);
              /* Check for a .PGN suffix. */
              const char *suffix = output_file_suffix(SAN);

              if((len > strlen(suffix)) &&
                    (stringcompare(&filename[len-strlen(suffix)],
                                            suffix) == 0)){
                  add_filename_to_source_list(filename,CHECKFILE);
              }
              else{
                  FILE *fp = must_open_file(filename,"r");
                  add_filename_list_from_file(fp,CHECKFILE);
                  (void) fclose(fp);
              }
          }
          break;
        case FILE_OF_FILES_ARGUMENT:
          if(*filename != '\0'){
              FILE *fp = must_open_file(filename,"r");
              add_filename_list_from_file(fp,NORMALFILE);
              (void) fclose(fp);
          }
          else{
              fprintf(GlobalState.logfile,"Filename expected with -%c\n",
                      arg_letter);
          }
          break;
        case BOUNDS_ARGUMENT:
          {
              /* Bounds on the number of moves are to be found.
               * "l#" means less-than-or-equal-to.
               * "g#" means greater-than-or-equal-to.
               * Otherwise "#" (or "e#") means that number.
               */
              /* Equal by default. */
              char which = 'e';
              unsigned value;
              Boolean Ok = TRUE;
              const char *bound = associated_value;

              switch(*bound){
                case 'l':
                case 'u':
                case 'e':
                  which = *bound;
                  bound++;
                  break;
                default:
                  if(!isdigit((int) *bound)){
                      fprintf(GlobalState.logfile,
                              "-%c must be followed by e, l, or u.\n",
                              arg_letter);
                      Ok = FALSE;
                  }
                  break;
              }
              if(Ok && (sscanf(bound,"%u",&value) == 1)){
                GlobalState.check_move_bounds = TRUE;
                switch(which){
                  case 'e':
                        GlobalState.lower_move_bound = value; 
                        GlobalState.upper_move_bound = value; 
                        break;
                  case 'l':
                    if(value <= GlobalState.upper_move_bound){
                        GlobalState.lower_move_bound = value; 
                    }
                    else{
                        fprintf(GlobalState.logfile,
                           "Lower bound is greater than the upper bound; -%c ignored.\n",
                           arg_letter);
                        Ok = FALSE;
                    }
                    break;
                  case 'u':
                    if(value >= GlobalState.lower_move_bound){
                        GlobalState.upper_move_bound = value; 
                    }
                    else{
                        fprintf(GlobalState.logfile,
                           "Upper bound is smaller than the lower bound; -%c ignored.\n",
                           arg_letter);
                        Ok = FALSE;
                    }
                    break;
                }
             }
             else{
               fprintf(GlobalState.logfile,
                       "-%c should be in the form -%c[elu]number.\n",
                       arg_letter,arg_letter);
               Ok = FALSE;
             }
             if(!Ok){
                exit(1);
             }
         }
         break;
        case GAMES_PER_FILE_ARGUMENT:
          if(GlobalState.ECO_level > 0){
              fprintf(GlobalState.logfile,
                      "-%c conflicts with -E.\n",arg_letter);
              exit(1);
          }
          else if(GlobalState.output_filename != NULL){
              fprintf(GlobalState.logfile,
                        "-%c: File %s has already been selected for output.\n",
                        arg_letter,
                        GlobalState.output_filename);
              exit(1);
          }
          else if(sscanf(associated_value,"%u",
                       &GlobalState.games_per_file) != 1){
            fprintf(GlobalState.logfile,
                    "-%c should be followed by an unsigned integer.\n",
                    arg_letter);
            exit(1);
          }
          else{
            /* Value set. */
          }
          break;
        case FILE_OF_ARGUMENTS_ARGUMENT:
          if(*filename != '\0'){
              /* @@@ Potentially recursive call. Is this safe? */
              read_args_file(filename);
          }
          else{
              fprintf(GlobalState.logfile,"Usage: -%cfilename.\n",
                      arg_letter);
          }
          break;
        case NON_MATCHING_GAMES_ARGUMENT:
          if(*filename != '\0'){
              if(GlobalState.non_matching_file != NULL){
                  (void) fclose(GlobalState.non_matching_file);
              }
              GlobalState.non_matching_file = must_open_file(filename,"w");
          }
          else{
              fprintf(GlobalState.logfile,"Usage: -%cfilename.\n",arg_letter);
              exit(1);
          }
          break;
        case TAG_EXTRACTION_ARGUMENT:
            /* A single tag extraction criterion. */
            extract_tag_argument(associated_value);
            break;
        case LINE_WIDTH_ARGUMENT:
            { /* Specify an output line width. */
              unsigned length;

              if(sscanf(associated_value,"%u",&length) > 0){
                  set_output_line_length(length);
              }
              else{
                  fprintf(GlobalState.logfile,
                          "-%c should be followed by an unsigned integer.\n",
                          arg_letter);
                  exit(1);
              }
            }
            break;
        case HELP_ARGUMENT:
            usage_and_exit();
            break;
        case OUTPUT_FORMAT_ARGUMENT:
            /* Whether to use the source form of moves or
             * rewrite them into another format.
             */
	    {
		OutputFormat format = which_output_format(associated_value);
		if(format == UCI) {
		    /* Rewrite the game in a format suitable for input to
		     * a UCI-compatible engine.
		     * This is actually LALG but involves adjusting a lot of
		     * the other statuses, too.
		     */
		    GlobalState.keep_NAGs = FALSE;
		    GlobalState.keep_comments = FALSE;
		    GlobalState.keep_move_numbers = FALSE;
		    GlobalState.keep_checks = FALSE;
		    GlobalState.keep_variations = FALSE;
		    set_output_line_length(5000);
		    format = LALG;
		}
		GlobalState.output_format = format;
	    }
            break;
        case SEVEN_TAG_ROSTER_ARGUMENT:
            if(GlobalState.tag_output_format == ALL_TAGS ||
               GlobalState.tag_output_format == SEVEN_TAG_ROSTER) {
                GlobalState.tag_output_format = SEVEN_TAG_ROSTER;
            }
            else {
                fprintf(GlobalState.logfile,
                        "-%c clashes with another argument.\n",
                        SEVEN_TAG_ROSTER_ARGUMENT);
                exit(1);
            }
            break;
        case DONT_KEEP_COMMENTS_ARGUMENT:
            GlobalState.keep_comments = FALSE;
            break;
        case DONT_KEEP_DUPLICATES_ARGUMENT:
            /* Make sure that this doesn't clash with -d. */
            if(GlobalState.duplicate_file == NULL){
                GlobalState.suppress_duplicates = TRUE;
            }
            else{
                fprintf(GlobalState.logfile,
                            "-%c clashes with -%c flag.\n",
                            DONT_KEEP_DUPLICATES_ARGUMENT,
                            DUPLICATES_FILE_ARGUMENT);
                exit(1);
            }
            break;
        case DONT_MATCH_PERMUTATIONS_ARGUMENT:
            GlobalState.match_permutations = FALSE;
            break;
        case DONT_KEEP_NAGS_ARGUMENT:
            GlobalState.keep_NAGs = FALSE;
            break;
        case OUTPUT_FEN_STRING_ARGUMENT:
            /* Output a FEN string of the final position.
             * This is displayed in a comment.
             */
	    if(GlobalState.add_FEN_comments) {
		/* Already implied. */
	        GlobalState.output_FEN_string = FALSE;
	    }
	    else {
		GlobalState.output_FEN_string = TRUE;
	    }
            break;
        case CHECK_ONLY_ARGUMENT:
            /* Report errors, but don't convert. */
            GlobalState.check_only = TRUE;
            break;
        case KEEP_SILENT_ARGUMENT:
            /* Turn off progress reporting. */
            GlobalState.verbose = FALSE;
            break;
        case USE_SOUNDEX_ARGUMENT:
            /* Use soundex matches for player tags. */
            GlobalState.use_soundex = TRUE;
            break;
        case MATCH_CHECKMATE_ARGUMENT:
            /* Match only games that end in checkmate. */
            GlobalState.match_only_checkmate = TRUE;
            break;
        case SUPPRESS_ORIGINALS_ARGUMENT:
            GlobalState.suppress_originals = TRUE;
            break;
        case DONT_KEEP_VARIATIONS_ARGUMENT:
            GlobalState.keep_variations = FALSE;
            break;
        case USE_VIRTUAL_HASH_TABLE_ARGUMENT:
            GlobalState.use_virtual_hash_table = TRUE;
            break;

        case TAGS_ARGUMENT:
            if(*filename != '\0'){
                read_tag_file(filename);
            }
            break;
        case TAG_ROSTER_ARGUMENT:
            if(*filename != '\0'){
                read_tag_roster_file(filename);
            }
            break;
        case MOVES_ARGUMENT:
            if(*filename != '\0'){
                /* Where the list of variations of interest are kept. */
                FILE *variation_file = must_open_file(filename,"r");
                /* We wish to search for particular variations. */
                add_textual_variations_from_file(variation_file);
                fclose(variation_file);
            }
            break;
        case POSITIONS_ARGUMENT:
            if(*filename != '\0'){
                FILE *variation_file = must_open_file(filename,"r");
                /* We wish to search for positional variations. */
                add_positional_variations_from_file(variation_file);
                fclose(variation_file);
            }
            break;
        case ENDINGS_ARGUMENT:
            if(*filename != '\0'){
                if(!build_endings(filename)){
                    exit(1);
                }
            }
            break;
        default:
            fprintf(GlobalState.logfile,
                    "Unrecognized argument -%c\n", arg_letter);
    }
}
Exemplo n.º 5
0
void
read_args_file(const char *infile)
{   char *line;
    FILE *fp = fopen(infile,"r");

    if(fp == NULL){
        fprintf(GlobalState.logfile,"Cannot open %s for reading.\n",infile);
        exit(1);
    }
    else{
        ArgType linetype = NO_ARGUMENT_MATCH;
        ArgType nexttype;
        while((line = read_line(fp)) != NULL){
            if(blank_line(line)){
                (void) free(line);
                continue;
            }
            nexttype = classify_arg(line);
            if(nexttype == NO_ARGUMENT_MATCH){
                if(*line == argument_prefix[0]){
                    /* Treat the line as a source file name. */
                    add_filename_to_source_list(&line[1],NORMALFILE);
                }
                else if(linetype != NO_ARGUMENT_MATCH){
                    /* Handle the line. */
                    switch(linetype){
                        case MOVES_ARGUMENT:
                            add_textual_variation_from_line(line);
                            break;
                        case POSITIONS_ARGUMENT:
                            add_positional_variation_from_line(line);
                            break;
                        case TAGS_ARGUMENT:
                            process_tag_line(infile,line);
                            break;
                        case TAG_ROSTER_ARGUMENT:
                            process_roster_line(line);
                            break;
                        case ENDINGS_ARGUMENT:
                            process_ending_line(line);
                            (void) free(line);
                            break;
                        default:
                            fprintf(GlobalState.logfile,
                                    "Internal error: unknown linetype %d in read_args_file\n",
                                    linetype);
                            (void) free(line);
                            exit(-1);
                    }
                }
                else{
                    /* It should have been a line applying to the
                     * current linetype.
                     */
                    fprintf(GlobalState.logfile,
                        "Missing argument type for line %s in the argument file.\n",
                        line);
                    exit(1);
                }
            }
            else{
                switch(nexttype){
                        /* Arguments with a possible additional
                         * argument value.
                         * All of these apply only to the current
                         * line in the argument file.
                         */
                    case WRITE_TO_OUTPUT_FILE_ARGUMENT:
                    case APPEND_TO_OUTPUT_FILE_ARGUMENT:
                    case WRITE_TO_LOG_FILE_ARGUMENT:
                    case APPEND_TO_LOG_FILE_ARGUMENT:
                    case DUPLICATES_FILE_ARGUMENT:
                    case USE_ECO_FILE_ARGUMENT:
                    case CHECK_FILE_ARGUMENT:
                    case FILE_OF_FILES_ARGUMENT:
                    case BOUNDS_ARGUMENT:
                    case GAMES_PER_FILE_ARGUMENT:
                    case ECO_OUTPUT_LEVEL_ARGUMENT:
                    case FILE_OF_ARGUMENTS_ARGUMENT:
                    case NON_MATCHING_GAMES_ARGUMENT:
                    case TAG_EXTRACTION_ARGUMENT:
                    case LINE_WIDTH_ARGUMENT:
                    case OUTPUT_FORMAT_ARGUMENT:
                        process_argument(line[argument_prefix_len],
                                         &line[argument_prefix_len+1]);
                        linetype = NO_ARGUMENT_MATCH;
                        break;
                    case LONG_FORM_ARGUMENT:
			{
			    char *arg = &line[argument_prefix_len+1];
			    char *space = strchr(arg, ' ');
			    if(space != NULL) {
				/* We need to drop an associated value from arg. */
				int arglen = space - arg;
				char *just_arg = (char *) MallocOrDie(arglen + 1);
				strncpy(just_arg, arg, arglen);
				just_arg[arglen] = '\0';
				process_long_form_argument(just_arg,
							   skip_leading_spaces(space));
			    }
			    else {
				process_long_form_argument(arg, "");
				linetype = NO_ARGUMENT_MATCH;
			    }
			}
                        break;

                        /* Arguments with no additional
                         * argument value.
                         * All of these apply only to the current
                         * line in the argument file.
                         */
                    case SEVEN_TAG_ROSTER_ARGUMENT:
                    case HELP_ARGUMENT:
                    case ALTERNATIVE_HELP_ARGUMENT:
                    case DONT_KEEP_COMMENTS_ARGUMENT:
                    case DONT_KEEP_DUPLICATES_ARGUMENT:
                    case DONT_MATCH_PERMUTATIONS_ARGUMENT:
                    case DONT_KEEP_NAGS_ARGUMENT:
                    case OUTPUT_FEN_STRING_ARGUMENT:
                    case CHECK_ONLY_ARGUMENT:
                    case KEEP_SILENT_ARGUMENT:
                    case USE_SOUNDEX_ARGUMENT:
                    case MATCH_CHECKMATE_ARGUMENT:
                    case SUPPRESS_ORIGINALS_ARGUMENT:
                    case DONT_KEEP_VARIATIONS_ARGUMENT:
                    case USE_VIRTUAL_HASH_TABLE_ARGUMENT:
                        process_argument(line[argument_prefix_len],"");
                        linetype = NO_ARGUMENT_MATCH;
                        break;

                        /* Arguments whose values persist beyond
                         * the current line.
                         */
                    case MOVES_ARGUMENT:
                    case POSITIONS_ARGUMENT:
                    case ENDINGS_ARGUMENT:
                    case TAGS_ARGUMENT:
                    case TAG_ROSTER_ARGUMENT:
                        process_argument(line[argument_prefix_len],
                                         &line[argument_prefix_len+1]);
                        /* Apply this type to subsequent lines. */
                        linetype = nexttype;
                        break;
                    default:
                        linetype = nexttype;
                        break;
                }
                (void) free(line);
            }
        }
        (void) fclose(fp);
    }
}