Пример #1
0
int32_t write_clusters(char* outname, char* outname_end, uintptr_t unfiltered_indiv_ct, uintptr_t* indiv_exclude, uintptr_t indiv_ct, char* person_ids, uintptr_t max_person_id_len, uint32_t omit_unassigned, uintptr_t cluster_ct, uint32_t* cluster_map, uint32_t* cluster_starts, char* cluster_ids, uintptr_t max_cluster_id_len) {
  unsigned char* wkspace_mark = wkspace_base;
  FILE* outfile = NULL;
  uintptr_t indiv_uidx = 0;
  int32_t retval = 0;
  uint32_t* indiv_to_cluster;
  char* person_id_ptr;
  char* bufptr;
  uintptr_t indiv_idx;
  uint32_t cluster_idx;
  uint32_t slen;
  if (wkspace_alloc_ui_checked(&indiv_to_cluster, unfiltered_indiv_ct * sizeof(int32_t))) {
    goto write_cluster_ret_NOMEM;
  }
  fill_unfiltered_indiv_to_cluster(unfiltered_indiv_ct, cluster_ct, cluster_map, cluster_starts, indiv_to_cluster);
  memcpy(outname_end, ".clst", 6);
  if (fopen_checked(&outfile, outname, "w")) {
    goto write_cluster_ret_OPEN_FAIL;
  }
  for (indiv_idx = 0; indiv_idx < indiv_ct; indiv_idx++) {
    indiv_uidx = next_non_set_unsafe(indiv_exclude, indiv_uidx);
    cluster_idx = indiv_to_cluster[indiv_uidx];
    if ((!omit_unassigned) || (cluster_idx != 0xffffffffU)) {
      person_id_ptr = &(person_ids[indiv_uidx * max_person_id_len]);
      slen = strlen_se(person_id_ptr);
      bufptr = memcpyax(tbuf, person_id_ptr, slen, ' ');
      bufptr = strcpyax(bufptr, &(person_id_ptr[slen + 1]), ' ');
      if (cluster_idx != 0xffffffffU) {
        bufptr = strcpyax(bufptr, &(cluster_ids[cluster_idx * max_cluster_id_len]), '\n');
      } else {
        bufptr = memcpyl3a(bufptr, "NA\n");
      }
      if (fwrite_checked(tbuf, bufptr - tbuf, outfile)) {
	goto write_cluster_ret_WRITE_FAIL;
      }
    }
    indiv_uidx++;
  }
  if (fclose_null(&outfile)) {
    goto write_cluster_ret_WRITE_FAIL;
  }
  sprintf(logbuf, "Pruned cluster assignments written to %s.\n", outname);
  logprintb();
  while (0) {
  write_cluster_ret_NOMEM:
    retval = RET_NOMEM;
    break;
  write_cluster_ret_OPEN_FAIL:
    retval = RET_OPEN_FAIL;
    break;
  write_cluster_ret_WRITE_FAIL:
    retval = RET_WRITE_FAIL;
    break;
  }
  fclose_cond(outfile);
  wkspace_reset(wkspace_mark);
  return retval;
}
Пример #2
0
const char* set_petsc_options_name (const char* petsc_options_name)
{
	static char full_name[STRLEN_MAX] = { 0, };
	sprintf(full_name,"%s%s%s%s",PROJECT_SOURCE_DIR,"external/petsc/options_files/",petsc_options_name,".txt");

	FILE* file = fopen_checked(full_name);
	fclose(file);

	return full_name;
}
struct Vector_T* constructor_file_name_Vector_T (const char*const var_name, const char*const file_name_full)
{
	struct Vector_T* dest = NULL;

	FILE* data_file = fopen_checked(file_name_full); // closed

	bool found_var = false;

	char line[STRLEN_MAX];
	while (fgets(line,sizeof(line),data_file) != NULL) {
		if (strstr(line,var_name)) {
			found_var = true;
			dest = constructor_file_Vector_T(data_file,true);
		}
	}
	fclose(data_file);

	if (!found_var)
		EXIT_ERROR("Did not find the '%s' variable in the file: %s",var_name,file_name_full);

	return dest;
}
Пример #4
0
int32_t load_clusters(char* fname, uintptr_t unfiltered_indiv_ct, uintptr_t* indiv_exclude, uintptr_t indiv_ct, char* person_ids, uintptr_t max_person_id_len, uint32_t mwithin_col, uint32_t keep_na, uintptr_t* cluster_ct_ptr, uint32_t** cluster_map_ptr, uint32_t** cluster_starts_ptr, char** cluster_ids_ptr, uintptr_t* max_cluster_id_len_ptr) {
  unsigned char* wkspace_mark = wkspace_base;
  FILE* infile = NULL;
  uintptr_t indiv_ctl = (indiv_ct + (BITCT - 1)) / BITCT;
  uintptr_t topsize = 0;
  int32_t retval = 0;
  char* idbuf = &(tbuf[MAXLINELEN]);
  uintptr_t max_cluster_id_len = 0;
  uintptr_t assigned_ct = 0;
  uintptr_t cluster_ct = 0;
  Ll_str* cluster_names = NULL;
  uintptr_t* already_seen;
  char* cluster_ids;
  uint32_t* cluster_map;
  uint32_t* cluster_starts;
  uint32_t* tmp_cluster_starts;
  uintptr_t topsize_bak;
  Ll_str* llptr;
  char* sorted_ids;
  uint32_t* id_map;
  char* fam_id;
  char* indiv_id;
  char* cluster_name_ptr;
  uintptr_t ulii;
  int32_t sorted_idx;
  uint32_t indiv_uidx;
  uint32_t slen;
  uint32_t uii;

  sorted_ids = (char*)top_alloc(&topsize, indiv_ct * max_person_id_len);
  if (!sorted_ids) {
    goto load_clusters_ret_NOMEM;
  }
  id_map = (uint32_t*)top_alloc(&topsize, indiv_ct * sizeof(int32_t));
  if (!id_map) {
    goto load_clusters_ret_NOMEM;
  }
  topsize_bak = topsize;
  already_seen = (uintptr_t*)top_alloc(&topsize, indiv_ctl * sizeof(intptr_t));
  if (!already_seen) {
    goto load_clusters_ret_NOMEM;
  }
  fill_ulong_zero(already_seen, indiv_ctl);
  memcpy(sorted_ids, person_ids, indiv_ct * max_person_id_len);
  wkspace_left -= topsize;
  retval = sort_item_ids_noalloc(sorted_ids, id_map, unfiltered_indiv_ct, indiv_exclude, indiv_ct, person_ids, max_person_id_len, 0, 0, strcmp_deref);
  wkspace_left += topsize;
  if (retval) {
    goto load_clusters_ret_1;
  }

  // two-pass load
  // 1. load cluster names, track longest length, validate format, verify no
  //    individual ID appears multiple times
  // intermission. sort cluster names, purge duplicates, allocate memory for
  //               return values
  // 2. populate return name arrays
  if (fopen_checked(&infile, fname, "r")) {
    goto load_clusters_ret_OPEN_FAIL;
  }
  tbuf[MAXLINELEN - 1] = ' ';
  if (!mwithin_col) {
    mwithin_col = 1;
  }
  while (fgets(tbuf, MAXLINELEN, infile)) {
    if (!tbuf[MAXLINELEN - 1]) {
      logprint("Error: Pathologically long line in --within file.\n");
      goto load_clusters_ret_INVALID_FORMAT;
    }
    fam_id = skip_initial_spaces(tbuf);
    if (is_eoln_kns(*fam_id)) {
      continue;
    }
    indiv_id = next_item(fam_id);
    cluster_name_ptr = next_item_mult(indiv_id, mwithin_col);
    if (no_more_items_kns(cluster_name_ptr)) {
      logprint("Error: Fewer entries than expected in --within file line.\n");
      goto load_clusters_ret_INVALID_FORMAT;
    }
    sorted_idx = bsearch_fam_indiv(idbuf, sorted_ids, max_person_id_len, indiv_ct, fam_id, indiv_id);
    if (sorted_idx == -1) {
      continue;
    }
    if (is_set(already_seen, sorted_idx)) {
      idbuf[strlen_se(fam_id)] = ' ';
      sprintf(logbuf, "Error: Duplicate individual %s in --within file.\n", idbuf);
      logprintb();
      goto load_clusters_ret_INVALID_FORMAT;
    }
    set_bit_noct(already_seen, sorted_idx);
    slen = strlen_se(cluster_name_ptr);
    if ((!keep_na) && (slen == 2) && (!memcmp(cluster_name_ptr, "NA", 2))) {
      // postponed to here because, even without 'keep-NA', we do not want to
      // ignore cluster=NA lines for the purpose of detecting duplicate indivs
      continue;
    }
    if (slen >= max_cluster_id_len) {
      max_cluster_id_len = slen + 1;
    }
    llptr = top_alloc_llstr(&topsize, slen + 1);
    llptr->next = cluster_names;
    memcpyx(llptr->ss, cluster_name_ptr, slen, '\0');
    cluster_names = llptr;
    assigned_ct++;
  }
  if (!feof(infile)) {
    goto load_clusters_ret_READ_FAIL;
  }
  if (cluster_names) {
    *max_cluster_id_len_ptr = max_cluster_id_len;
    wkspace_left -= topsize;
    if (wkspace_alloc_c_checked(cluster_ids_ptr, assigned_ct * max_cluster_id_len)) {
      goto load_clusters_ret_NOMEM2;
    }
    cluster_ids = *cluster_ids_ptr;
    for (ulii = 0; ulii < assigned_ct; ulii++) {
      strcpy(&(cluster_ids[ulii * max_cluster_id_len]), cluster_names->ss);
      cluster_names = cluster_names->next;
    }
    // deallocate cluster ID linked list and duplicate indiv ID detector from
    // top of stack, allocate cluster size tracker
    wkspace_left += topsize;
    topsize = topsize_bak;
    tmp_cluster_starts = (uint32_t*)top_alloc(&topsize, assigned_ct * sizeof(int32_t));
    if (!tmp_cluster_starts) {
      goto load_clusters_ret_NOMEM;
    }
    wkspace_left -= topsize;
    // may as well use natural sort of cluster names
    qsort(cluster_ids, assigned_ct, max_cluster_id_len, strcmp_natural);
    cluster_ct = collapse_duplicate_ids(cluster_ids, assigned_ct, max_cluster_id_len, tmp_cluster_starts);
    *cluster_ct_ptr = cluster_ct;
    // shrink
    wkspace_reset(cluster_ids);
    wkspace_alloc_c_checked(cluster_ids_ptr, cluster_ct * max_cluster_id_len);
    if (wkspace_alloc_ui_checked(cluster_map_ptr, assigned_ct * sizeof(int32_t)) ||
        wkspace_alloc_ui_checked(cluster_starts_ptr, (cluster_ct + 1) * sizeof(int32_t))) {
      goto load_clusters_ret_NOMEM2;
    }
    wkspace_left += topsize;
    cluster_map = *cluster_map_ptr;
    cluster_starts = *cluster_starts_ptr;
    memcpy(cluster_starts, tmp_cluster_starts, cluster_ct * sizeof(int32_t));
    cluster_starts[cluster_ct] = assigned_ct;
    rewind(infile);
    // second pass
    while (fgets(tbuf, MAXLINELEN, infile)) {
      fam_id = skip_initial_spaces(tbuf);
      if (is_eoln_kns(*fam_id)) {
	continue;
      }
      indiv_id = next_item(fam_id);
      cluster_name_ptr = next_item_mult(indiv_id, mwithin_col);
      slen = strlen_se(cluster_name_ptr);
      if ((!keep_na) && (slen == 2) && (!memcmp(cluster_name_ptr, "NA", 2))) {
	continue;
      }
      sorted_idx = bsearch_fam_indiv(idbuf, sorted_ids, max_person_id_len, indiv_ct, fam_id, indiv_id);
      if (sorted_idx == -1) {
	continue;
      }
      indiv_uidx = id_map[(uint32_t)sorted_idx];
      cluster_name_ptr[slen] = '\0';
      sorted_idx = bsearch_str_natural(cluster_name_ptr, cluster_ids, max_cluster_id_len, 0, cluster_ct - 1);
      uii = tmp_cluster_starts[(uint32_t)sorted_idx];
      tmp_cluster_starts[(uint32_t)sorted_idx] += 1;
      cluster_map[uii] = indiv_uidx;
    }
    if (!feof(infile)) {
      goto load_clusters_ret_READ_FAIL;
    }
    for (ulii = 0; ulii < cluster_ct; ulii++) {
      if (cluster_starts[ulii + 1] - cluster_starts[ulii] > 1) {
#ifdef __cplusplus
	std::sort(&(cluster_map[cluster_starts[ulii]]), &(cluster_map[cluster_starts[ulii + 1]]));
#else
	qsort(&(cluster_map[cluster_starts[ulii]]), cluster_starts[ulii + 1] - cluster_starts[ulii], sizeof(int32_t), intcmp);
#endif
      }
    }
    sprintf(logbuf, "--within: %" PRIuPTR " cluster%s loaded, covering a total of %" PRIuPTR " %s.\n", cluster_ct, (cluster_ct == 1)? "" : "s", assigned_ct, species_str(assigned_ct));
    logprintb();
  } else {
    logprint("Warning: No individuals named in --within file remain in the current analysis.\n");
  }

  while (0) {
  load_clusters_ret_NOMEM2:
    wkspace_left += topsize;
  load_clusters_ret_NOMEM:
    retval = RET_NOMEM;
    break;
  load_clusters_ret_OPEN_FAIL:
    retval = RET_OPEN_FAIL;
    break;
  load_clusters_ret_READ_FAIL:
    retval = RET_READ_FAIL;
    break;
  load_clusters_ret_INVALID_FORMAT:
    retval = RET_INVALID_FORMAT;
    break;
  }
 load_clusters_ret_1:
  if (retval) {
    wkspace_reset(wkspace_mark);
  }
  fclose_cond(infile);
  return retval;
}
Пример #5
0
int
main (int argc, char **argv)
{
    /* Return code of the program. */
    int ret = EXIT_SUCCESS;

    /* The mode of the generator, either START or ITERATING. */
    int mode;
    /* The argument index which points to the current lattice parameter to be
     * converted. */
    int param_arg;
    /* Total number of lattice parameters */
    int nparams;
    
    /* Array of the converted lattice parameters. */
    double *params;

    /* Various file streams for reading and writing. */
    FILE *output_inp_file, *output_pot_file, *input_pot_new_file = NULL;

    /* We've got to have at least one argument to do anything! */
    if (argc == 1)
        usage ();

    /* Check which mode we're operating in. We assume that we're in start mode,
     * unless we specifically find the option for iterating. */
    mode = (strcmp (argv[1], "-i")) ? START : ITERATING;

    if (mode == ITERATING) {
        /* We'll need a .pot_new file and at least one lattice parameter. */
        if (argc < 4)
            usage ();

        input_pot_new_file = fopen_checked (argv[2], "r", "previous potential file");
        param_arg = 3;
    } else {
        /* We may or may not have the "-s" explicitly, so we need to check. */
        if (!strcmp (argv[1], "-s")) {
            if (argc < 3)
                usage ();

            param_arg = 2;
        } else {
            param_arg = 1;
        }
    }

    /* Calculate the number of lattice parameters we've been given, and check
     * that it's the correct number. */
    nparams = argc - param_arg;
    if (!correct_number_of_parameters (nparams))
        usage ();

    /* Allocate space for these lattice parameters. */
    params = malloc (nparams * sizeof (*params));
    if (!params) {
        fprintf (stderr, "Couldn't allocate memory to store lattice parameters.\n");
        exit (EXIT_FAILURE);
    }

    /* Do the conversion for each parameter into a double. */
    for (int i = 0; param_arg < argc; param_arg++, i++)
        params[i] = strtod_checked (argv[param_arg]);

    /* Get the name of the dataset. */
    make_dataset (params);

    /* Generate the filenames for the two output files. */
    snprintf (output_inp_filename, sizeof(output_inp_filename), "%s.inp", dataset);
    snprintf (output_pot_filename, sizeof(output_pot_filename), "%s.pot", dataset);

    /* Open the output files for writing. */
    output_inp_file = fopen_checked (output_inp_filename, "w", "input file");
    output_pot_file = fopen_checked (output_pot_filename, "w", "potential file");

    /* Write the output files and check for success. */
    if (write_inp_file (output_inp_file, mode)
        || write_pot_file (output_pot_file, params, mode)) {
        ret = EXIT_FAILURE;
    } else {
        /* Print out the name of the dataset so bash scripts can use it. */
        puts (dataset);
    }

    /* Handle the cleanup operations. */
    fclose (output_inp_file);
    fclose (output_pot_file);
    if (mode == ITERATING)
        fclose (input_pot_new_file);
    free (params);

    return ret;
}
Пример #6
0
int32_t main(int32_t argc, char** argv) {
  FILE* infile = NULL;
  char* outname = NULL;
  uintptr_t column_sep = 2;
  uint32_t flags = 0;
  int32_t retval = 0;
  uintptr_t* col_widths = NULL;
  unsigned char* spacebuf = NULL;
  unsigned char* rjustify_buf = NULL;
  uintptr_t col_ct = 0;
  uint32_t infile_param_idx = 0;
  char* param_ptr;
#ifndef _WIN32
  char* cptr;
#endif
  uint32_t param_idx;
  uint32_t uii;
  int32_t ii;
  char cc;
  if (argc == 1) {
    goto main_ret_HELP;
  }
  for (param_idx = 1; param_idx < (uint32_t)argc; param_idx++) {
    if ((!strcmp(argv[param_idx], "--help")) || (!strcmp(argv[param_idx], "-help")) || (!strcmp(argv[param_idx], "-?")) || (!strcmp(argv[param_idx], "-h"))) {
      goto main_ret_HELP;
    }
  }

  if (argc > 10) {
    fputs("Error: Too many parameters.\n\n", stderr);
    goto main_ret_INVALID_CMDLINE_2;
  }
  for (param_idx = 1; param_idx < (uint32_t)argc; param_idx++) {
    if (argv[param_idx][0] != '-') {
      if (!infile_param_idx) {
	infile_param_idx = param_idx;
      } else if (!outname) {
	if (flags & FLAG_INPLACE) {
	  goto main_ret_INVALID_CMDLINE_3;
	}
        outname = argv[param_idx];
      } else {
	fputs("Error: Invalid parameter sequence.\n\n", stderr);
	goto main_ret_INVALID_CMDLINE_2;
      }
      continue;
    }
    param_ptr = &(argv[param_idx][1]);
    if (*param_ptr == '-') {
      // allow both single- and double-dash
      param_ptr++;
    }
    if (!strcmp(param_ptr, "inplace")) {
      if (outname) {
	goto main_ret_INVALID_CMDLINE_3;
      }
      flags |= FLAG_INPLACE;
    } else if ((!strcmp(param_ptr, "spacing")) || (!strcmp(param_ptr, "s"))) {
      if (++param_idx == (uint32_t)argc) {
	fputs("Error: Missing --spacing parameter.\n", stderr);
	goto main_ret_INVALID_CMDLINE;
      }
      ii = atoi(argv[param_idx]);
      if (ii < 1) {
	fprintf(stderr, "Error: Invalid --spacing parameter '%s'.\n", argv[param_idx]);
	goto main_ret_INVALID_CMDLINE;
      }
      column_sep = (uint32_t)ii;
    } else if (!strcmp(param_ptr, "ralign")) {
      flags |= FLAG_RJUSTIFY;
    } else if (!strcmp(param_ptr, "leading")) {
      flags |= FLAG_SPACES_BEFORE_FIRST;
    } else if (!strcmp(param_ptr, "extend-short")) {
      flags |= FLAG_PAD;
    } else if (!strcmp(param_ptr, "trailing")) {
      flags |= FLAG_SPACES_AFTER_LAST;
    } else if (!strcmp(param_ptr, "force-eoln")) {
      flags |= FLAG_FINAL_EOLN;
    } else if (!strcmp(param_ptr, "noblank")) {
      flags |= FLAG_STRIP_BLANK;
    } else {
      if ((argv[param_idx][1] != '-') && argv[param_idx][1]) {
	// permit abbreviated style
	while (1) {
	  cc = *param_ptr++;
	  if (!cc) {
	    break;
	  }
	  switch (cc) {
	  case 'i':
	    if (outname) {
	      goto main_ret_INVALID_CMDLINE_3;
	    }
	    flags |= FLAG_INPLACE;
	    break;
	  case 'r':
	    flags |= FLAG_RJUSTIFY;
	    break;
	  case 'l':
	    flags |= FLAG_SPACES_BEFORE_FIRST;
	    break;
	  case 'e':
	    flags |= FLAG_PAD;
	    break;
	  case 't':
	    flags |= FLAG_SPACES_AFTER_LAST;
	    break;
	  case 'f':
	    flags |= FLAG_FINAL_EOLN;
	    break;
	  case 'n':
	    flags |= FLAG_STRIP_BLANK;
	    break;
	  default:
            fprintf(stderr, "Error: Invalid flag '%s'.\n\n", argv[param_idx]);
	    goto main_ret_INVALID_CMDLINE_2;
	  }
	}
      } else {
	fprintf(stderr, "Error: Invalid flag '%s'.\n\n", argv[param_idx]);
	goto main_ret_INVALID_CMDLINE_2;
      }
    }
  }
  if (!infile_param_idx) {
    fputs("Error: No input filename.\n\n", stderr);
    goto main_ret_INVALID_CMDLINE_2;
  }
  if (flags & FLAG_INPLACE) {
    uii = strlen(argv[infile_param_idx]);
    outname = (char*)malloc(uii + 11);
    if (!outname) {
      goto main_ret_NOMEM;
    }
    memcpy(outname, argv[infile_param_idx], uii);
    memcpy(&(outname[uii]), "-temporary", 11);
  } else if (outname) {
#ifdef _WIN32
    uii = GetFullPathName(argv[infile_param_idx], FNAMESIZE, pathbuf, NULL);
    if ((!uii) || (uii > FNAMESIZE))
#else
    if (!realpath(argv[infile_param_idx], pathbuf))
#endif
    {
      fprintf(stderr, "Error: Failed to open %s.\n", argv[infile_param_idx]);
      goto main_ret_OPEN_FAIL;
    }
#ifdef _WIN32
    uii = GetFullPathName(outname, FNAMESIZE, &(pathbuf[FNAMESIZE + 64]), NULL);
    if (uii && (uii <= FNAMESIZE) && (!strcmp(pathbuf, &(pathbuf[FNAMESIZE + 64]))))
#else
    cptr = realpath(outname, &(pathbuf[FNAMESIZE + 64]));
    if (cptr && (!strcmp(pathbuf, &(pathbuf[FNAMESIZE + 64]))))
#endif
    {
      fputs("Error: Input and output files match.  Use --inplace instead.\n", stderr);
      goto main_ret_INVALID_CMDLINE;
    }
  }
  if (fopen_checked(&infile, argv[infile_param_idx], "rb")) {
    goto main_ret_OPEN_FAIL;
  }
  retval = scan_column_widths(infile, column_sep, &col_widths, &col_ct, &spacebuf, (flags & FLAG_RJUSTIFY)? (&rjustify_buf) : NULL);
  if (retval) {
    goto main_ret_1;
  }
  retval = pretty_write(infile, outname, flags, column_sep, col_widths, col_ct, spacebuf, rjustify_buf);
  if (retval) {
    goto main_ret_1;
  }
  fclose_null(&infile);
  if (flags & FLAG_INPLACE) {
    unlink(argv[infile_param_idx]);
    if (rename(outname, argv[infile_param_idx])) {
      fprintf(stderr, "Error: File rename failed.  Output is in %s instead of %s.\n", outname, argv[infile_param_idx]);
      goto main_ret_OPEN_FAIL;
    }
  }
  while (0) {
  main_ret_HELP:
    fputs(
"prettify v1.04 (21 Feb 2014)   Christopher Chang ([email protected])\n\n"
"Takes a tab-and/or-space-delimited text table, and generates a space-delimited\n"
"pretty-printed version.  Multibyte character encodings are not currently\n"
"supported.\n\n"
, stdout);
    disp_usage(stdout);
    fputs(
"\nTo perform the simplest reverse conversion (multiple spaces to one tab), you\n"
"can use\n"
"  cat [input filename] | tr -s ' ' '\\t' > [output filename]\n"
"For one-to-one conversion between spaces and tabs instead, omit the \"-s\".  And\n"
"to strip leading and trailing tabs and spaces, try\n"
"  cat [in] | sed 's/^[[:space:]]*//g' | sed 's/[[:space:]]*$//g' > [out]\n"
, stdout);
    retval = RET_HELP;
    break;
  main_ret_NOMEM:
    retval = RET_NOMEM;
    break;
  main_ret_OPEN_FAIL:
    retval = RET_OPEN_FAIL;
    break;
  main_ret_INVALID_CMDLINE_3:
    fputs("Error: --inplace cannot be used with an output filename.\n", stderr);
    retval = RET_INVALID_CMDLINE;
    break;
  main_ret_INVALID_CMDLINE_2:
    disp_usage(stderr);
  main_ret_INVALID_CMDLINE:
    retval = RET_INVALID_CMDLINE;
    break;
  }
 main_ret_1:
  free_cond(col_widths);
  fclose_cond(infile);
  dispmsg(retval);
  return retval;
}
Пример #7
0
int32_t pretty_write(FILE* infile, char* outname, uint32_t flags, uintptr_t column_sep, uintptr_t* col_widths, uintptr_t col_ct, unsigned char* spacebuf, unsigned char* rjustify_buf) {
  FILE* outfile = NULL;
  uintptr_t cur_col_idx = 0;
  uintptr_t cur_col_width = 0;
  uintptr_t prev_col_width = 0;
  uintptr_t rjbuf_len = 0;
  unsigned char* token_end = NULL;
  uint32_t spaces_before_first = flags & FLAG_SPACES_BEFORE_FIRST;
  uint32_t pad = flags & FLAG_PAD;
  uint32_t spaces_after_last = flags & FLAG_SPACES_AFTER_LAST;
  uint32_t final_eoln = flags & FLAG_FINAL_EOLN;
  uint32_t strip_blank = flags & FLAG_STRIP_BLANK;
  uint32_t no_final_newline = 0;
  int32_t retval = 0;
  unsigned char* readptr;
  unsigned char* line_end;
  unsigned char* readbuf_end;
  uintptr_t cur_read;
  if (!outname) {
    outfile = stdout;
  } else {
    if (fopen_checked(&outfile, outname, "w")) {
      goto pretty_write_ret_OPEN_FAIL;
    }
  }
  rewind(infile);
  cur_read = fread(g_readbuf, 1, BUFSIZE, infile);
  if (ferror(infile)) {
    goto pretty_write_ret_READ_FAIL;
  }
  readptr = g_readbuf;
  readbuf_end = &(g_readbuf[cur_read]);
  while (1) {
    line_end = (unsigned char*)memchr(readptr, '\n', (uintptr_t)(readbuf_end - readptr));
    if (!line_end) {
      if (readptr != readbuf_end) {
        no_final_newline = 1;
      }
      line_end = readbuf_end;
    }
    while (readptr < line_end) {
      if (!cur_col_width) {
	if (skip_spaces_ck(&readptr, line_end)) {
	  break;
	}
	if (cur_col_idx || spaces_before_first) {
	  if (!rjustify_buf) {
	    fwrite(spacebuf, 1, col_widths[cur_col_idx] + column_sep - prev_col_width, outfile);
	  } else {
	    fwrite(spacebuf, 1, column_sep, outfile);
	  }
	}
	cur_col_idx++;
      }
      token_end = get_token_end_ck(readptr, line_end);
      cur_col_width += (uintptr_t)(token_end - readptr);
      if (token_end == line_end) {
	break;
      }
      if (!rjustify_buf) {
        fwrite(readptr, 1, token_end - readptr, outfile);
        prev_col_width = cur_col_width;
      } else {
        fwrite(spacebuf, 1, col_widths[cur_col_idx] - cur_col_width, outfile);
	if (rjbuf_len) {
          fwrite(rjustify_buf, 1, rjbuf_len, outfile);
	  rjbuf_len = 0;
	}
        fwrite(readptr, 1, token_end - readptr, outfile);
      }
      cur_col_width = 0;
      readptr = token_end;
    }
    if ((line_end < readbuf_end) || (!cur_read)) {
      if (cur_col_idx) {
	if (!rjustify_buf) {
	  if (cur_col_width) {
	    // last column not dumped yet
	    fwrite(readptr, 1, token_end - readptr, outfile);
	    prev_col_width = cur_col_width;
	  }
	  if (pad || spaces_after_last) {
	    fwrite(spacebuf, 1, col_widths[cur_col_idx] - prev_col_width, outfile);
	  }
	} else {
	  fwrite(spacebuf, 1, col_widths[cur_col_idx] - cur_col_width, outfile);
	  if (rjbuf_len) {
	    fwrite(rjustify_buf, 1, rjbuf_len, outfile);
	    rjbuf_len = 0;
	  }
	  fwrite(readptr, 1, token_end - readptr, outfile);
	}
	if (pad) {
	  while (cur_col_idx < col_ct) {
	    fwrite(spacebuf, 1, col_widths[++cur_col_idx] + column_sep, outfile);
	  }
	}
	if (spaces_after_last) {
	  fwrite(spacebuf, 1, column_sep, outfile);
	}
      }
      if (!cur_read) {
	// EOF
	if (final_eoln && no_final_newline) {
	  putc('\n', outfile);
	}
	break;
      }
      if (cur_col_idx || (!strip_blank)) {
	putc('\n', outfile);
	if (ferror(outfile)) {
	  goto pretty_write_ret_WRITE_FAIL;
	}
      }
      readptr = &(line_end[1]);
      cur_col_idx = 0;
      cur_col_width = 0;
      prev_col_width = 0;
      continue;
    }
    // in middle of line
    if (cur_col_width) {
      if (!rjustify_buf) {
	fwrite(readptr, 1, token_end - readptr, outfile);
      } else {
	memcpy(&(rjustify_buf[rjbuf_len]), readptr, token_end - readptr);
	rjbuf_len += (uintptr_t)(token_end - readptr);
      }
    }

    cur_read = fread(g_readbuf, 1, BUFSIZE, infile);
    if (ferror(infile)) {
      goto pretty_write_ret_READ_FAIL;
    }
    if (cur_read) {
      no_final_newline = 0;
    }
    readptr = g_readbuf;
    readbuf_end = &(g_readbuf[cur_read]);
  }

  if (outname) {
    if (fclose_null(&outfile)) {
      goto pretty_write_ret_WRITE_FAIL;
    }
  }
  while (0) {
  pretty_write_ret_OPEN_FAIL:
    retval = RET_OPEN_FAIL;
    break;
  pretty_write_ret_READ_FAIL:
    retval = RET_READ_FAIL;
    break;
  pretty_write_ret_WRITE_FAIL:
    retval = RET_WRITE_FAIL;
    break;
  }
  if (outname) {
    fclose_cond(outfile);
  }
  return retval;
}