예제 #1
0
/* json_append_array args:
 * - lua_State
 * - JSON strbuf
 * - Size of passwd Lua array (top of stack) */
static void json_append_array(lua_State *l, json_config_t *cfg, strbuf_t *json,
                              int array_length)
{
    int comma, i;

    json_encode_descend(l, cfg);

    strbuf_append_char(json, '[');

    comma = 0;
    for (i = 1; i <= array_length; i++) {
        if (comma)
            strbuf_append_char(json, ',');
        else
            comma = 1;

        lua_rawgeti(l, -1, i);
        json_append_data(l, cfg, json);
        lua_pop(l, 1);
    }

    strbuf_append_char(json, ']');

    cfg->current_depth--;
}
예제 #2
0
static void
fix_string(bool retain_backslashes, int skip_count, char endchar)
{
	StrBuf *out = strbuf_new();
	int c;

	for (c = 1+skip_count; yytext[c] != endchar; c++) {
		char ch = yytext[c];

		if (ch == '\\' && c+1 < yyleng) {
			ch = yytext[++c];
			if (retain_backslashes) {
				strbuf_append_char(out, '\\');
			} else {
				switch (ch) {
				case 'a': ch = '\a'; break;
				case 'b': ch = '\b'; break;
				case 't': ch = '\t'; break;
				case 'n': ch = '\n'; break;
				case 'v': ch = '\v'; break;
				case 'f': ch = '\f'; break;
				case 'r': ch = '\r'; break;
				case 'e':
				case 'E': ch = 27; break;
				}
			}
		}

		strbuf_append_char(out, ch);
	}

	set_string(strbuf_free_to_string(out));
}
예제 #3
0
void graph_info_make_intersect(const GraphInfo *ginfo, StrBuf *intersect_name)
{
  if(intersect_name->end > 0) strbuf_append_char(intersect_name, ',');
  strbuf_append_str(intersect_name, ginfo->sample_name.b);

  if(ginfo->cleaning.is_graph_intersection) {
    strbuf_append_char(intersect_name, ',');
    strbuf_append_str(intersect_name, ginfo->cleaning.intersection_name.b);
  }
}
예제 #4
0
// Strip indels ('-') from allele and add to string buffer
static inline void print_vcf_allele(const char *allele, size_t len,
                                    int8_t prev_base, int8_t next_base,
                                    StrBuf *sbuf)
{
  size_t i;
  if(prev_base > 0) strbuf_append_char(sbuf, char_to_vcf_char(prev_base));
  strbuf_ensure_capacity(sbuf, sbuf->end+len);
  for(i = 0; i < len; i++) {
    if(allele[i] != '-')
      sbuf->b[sbuf->end++] = char_to_vcf_char(allele[i]);
  }
  sbuf->b[sbuf->end] = 0;
  if(next_base > 0) strbuf_append_char(sbuf, char_to_vcf_char(next_base));
}
예제 #5
0
// Remember to free the result
void futil_get_strbuf_of_dir_path(const char *path, StrBuf *dir)
{
  char *tmp = strdup(path);
  strbuf_set(dir, dirname(tmp));
  strbuf_append_char(dir, '/');
  ctx_free(tmp);
}
예제 #6
0
파일: curl.c 프로젝트: yazengo/gintoki
static void curl_thread_done(uv_work_t *w, int _) {
	luv_curl_t *lc = (luv_curl_t *)w->data;
	lua_State *L = lc->L;

	free(w);

	if (lc->stat == DOWNLOADING)
		lc->stat = DONE;

	// 1
	if (lc->curl_ret == 0 && lc->retsb) {
		strbuf_append_char(lc->retsb, 0);
		lua_pushstring(L, lc->retsb->buf);
	} else 
		lua_pushnil(L);

	if (lc->retfp)
		fclose(lc->retfp);

	// 2
	getinfo(lc);
	push_curl_stat(lc);

	lua_do_global_callback(lc->L, "curl_done", lc->c, 2, 1);
	lua_do_global_callback(lc->L, "curl_cancel", lc->c, 0, 0);

	curl_easy_cleanup(lc->c);
	if (lc->retsb)
		strbuf_free(lc->retsb);
	if (lc->retfname)
		free(lc->retfname);
}
예제 #7
0
파일: msgbox.c 프로젝트: semenovf/cwt
/**
 *
 * @param widget
 * @param msg
 */
void cwt_msgbox_set_msg(CWT_WIDGET_PTR widget, const CWT_CHAR* msg)
{
	if( msg ) {
		CWT_WIDGET_PTR label;
		const CWT_CHAR *ptr = msg;
		StringBufferPtr sb;

		sb = strbuf_new_defaults();

		while( *ptr ) {
			if( *ptr == '\n' ) {
				label = cwt_new_widget(0, CWT_WT_LABEL, widget);
				cwt_label_set_text(label, strbuf_cstr(sb));
				strbuf_clear(sb);
			} else {
				strbuf_append_char(sb, *ptr);
			}
			ptr++;
		}

		if( strbuf_size(sb) > 0 ) {
			label = cwt_new_widget(0, CWT_WT_LABEL, widget);
			cwt_label_set_text(label, strbuf_cstr(sb));
		}

		strbuf_delete(sb);
		widget->need_layout = TRUE;
	}
}
예제 #8
0
파일: lwan-config.c 프로젝트: ktsaou/lwan
static void *parse_section(struct parser *parser)
{
    struct lexeme *lexeme;
    size_t name_len;

    if (!lexeme_buffer_consume(&parser->buffer, &lexeme))
        return NULL;

    strbuf_append_str(&parser->strbuf, lexeme->value.value, lexeme->value.len);
    name_len = lexeme->value.len;
    strbuf_append_char(&parser->strbuf, '\0');

    while (lexeme_buffer_consume(&parser->buffer, &lexeme)) {
        strbuf_append_str(&parser->strbuf, lexeme->value.value, lexeme->value.len);

        if (parser->buffer.population >= 1)
            strbuf_append_char(&parser->strbuf, ' ');
    }

    struct config_line line = {
        .type = CONFIG_LINE_TYPE_SECTION,
        .name = strbuf_get_buffer(&parser->strbuf),
        .param = line.name + name_len + 1
    };
    if (!config_buffer_emit(&parser->items, &line))
        return NULL;

    return parse_config;
}

static void *parse_section_shorthand(struct parser *parser)
{
    void *next_state = parse_section(parser);

    if (next_state) {
        struct config_line line = { .type = CONFIG_LINE_TYPE_SECTION_END };

        if (!config_buffer_emit(&parser->items, &line))
            return NULL;

        return next_state;
    }

    return NULL;
}
예제 #9
0
static void json_append_object(lua_State *l, json_config_t *cfg,
                               strbuf_t *json)
{
    int comma, keytype;

    json_encode_descend(l, cfg);

    /* Object */
    strbuf_append_char(json, '{');

    lua_pushnil(l);
    /* table, startkey */
    comma = 0;
    while (lua_next(l, -2) != 0) {
        if (comma)
            strbuf_append_char(json, ',');
        else
            comma = 1;

        /* table, key, value */
        keytype = lua_type(l, -2);
        if (keytype == LUA_TNUMBER) {
            strbuf_append_char(json, '"');
            json_append_number(l, json, -2, cfg);
            strbuf_append_mem(json, "\":", 2);
        } else if (keytype == LUA_TSTRING) {
            json_append_string(l, json, -2);
            strbuf_append_char(json, ':');
        } else {
            json_encode_exception(l, cfg, -2,
                                  "table key must be a number or string");
            /* never returns */
        }

        /* table, key, value */
        json_append_data(l, cfg, json);
        lua_pop(l, 1);
        /* table, key */
    }

    strbuf_append_char(json, '}');

    cfg->current_depth--;
}
예제 #10
0
static char *list2lines(GList *list)
{
    struct strbuf *s = strbuf_new();
    while (list)
    {
        strbuf_append_str(s, (char*)list->data);
        strbuf_append_char(s, '\n');
        free(list->data);
        list = g_list_delete_link(list, list);
    }
    return strbuf_free_nobuf(s);
}
예제 #11
0
void graph_info_append_intersect(ErrorCleaning *cleaning, const char *intersect_name)
{
  if(!cleaning->is_graph_intersection)
  {
    strbuf_set(&cleaning->intersection_name, intersect_name);
  }
  else
  {
    strbuf_append_char(&cleaning->intersection_name, ',');
    strbuf_append_str(&cleaning->intersection_name, intersect_name);
  }
  cleaning->is_graph_intersection = true;
}
예제 #12
0
/* json_append_array args:
 * - lua_State
 * - JSON strbuf
 * - Size of passwd Lua array (top of stack) */
static void json_append_array(lua_State *l, struct luaL_serializer *cfg,
                  int current_depth, strbuf_t *json,
                  int array_length)
{
    int comma, i;

    strbuf_append_char(json, '[');

    comma = 0;
    for (i = 1; i <= array_length; i++) {
        if (comma)
            strbuf_append_char(json, ',');
        else
            comma = 1;

        lua_rawgeti(l, -1, i);
        json_append_data(l, cfg, current_depth, json);
        lua_pop(l, 1);
    }

    strbuf_append_char(json, ']');
}
예제 #13
0
static char *
var_get_display_flags(DCVariable *var)
{
    StrBuf *out;
    uint32_t c;
    uint32_t flags;

    flags = *(uint32_t *) var->value;
    out = strbuf_new();
    for (c = 0; c < display_flag_count; c++) {
	if (flags & display_flag_details[c].flag) {
	    if (!strbuf_is_empty(out))
		strbuf_append_char(out, ' ');
	    strbuf_append(out, display_flag_details[c].name);
	}
    }

    return strbuf_free_to_string(out);
}
예제 #14
0
char seq_read_all_bases_fasta(SeqFile *sf, StrBuf *sbuf)
{
  int c;

  while((c = seq_getc(sf)) != -1 && c != '>')
  {
    if(c != '\r' && c != '\n')
    {
      strbuf_append_char(sbuf, (char)c);
      seq_readline(sbuf, sf);
      strbuf_chomp(sbuf);
    }

    sf->line_number++;
  }

  if(c == '>')
    sf->read_line_start = 1;

  return 1;
}
예제 #15
0
파일: vcf_misc.c 프로젝트: Phelimb/mccortex
void vcf_hdrtxt_append_commands(cJSON *command, StrBuf *hdr, const char *path)
{
  bool first;
  for(; command != NULL; command = command->next)
  {
    cJSON *key  = json_hdr_get(command, "key",    cJSON_String,  path);
    cJSON *cmd  = json_hdr_get(command, "cmd",    cJSON_Array,   path);
    cJSON *cwd  = json_hdr_get(command, "cwd",    cJSON_String,  path);
    cJSON *prev = json_hdr_get(command, "prev",   cJSON_Array,   path);
    cJSON *ver  = json_hdr_try(command, "mccortex",cJSON_String, path);

    prev = prev->child; // result could be NULL
    if(prev && prev->type != cJSON_String) die("Invalid 'prev' field");
    strbuf_append_str(hdr, "##mccortex_");
    strbuf_append_str(hdr, key->valuestring);
    strbuf_append_str(hdr, "=<prev=\"");
    strbuf_append_str(hdr, prev ? prev->valuestring : "NULL");

    if(prev) {
      while((prev = prev->next) != NULL) {
        strbuf_append_str(hdr, ";");
        strbuf_append_str(hdr, prev->valuestring);
      }
    }
    strbuf_append_str(hdr, "\",cmd=\"");
    for(first = true, cmd = cmd->child; cmd; cmd = cmd->next, first = false) {
      if(!first) strbuf_append_char(hdr, ' ');
      strbuf_append_str(hdr, cmd->valuestring);
    }
    strbuf_append_str(hdr, "\",cwd=\"");
    strbuf_append_str(hdr, cwd->valuestring);
    strbuf_append_str(hdr, "\"");
    if(ver) {
      strbuf_append_str(hdr, ",version=\"");
      strbuf_append_str(hdr, ver->valuestring);
      strbuf_append_str(hdr, "\"");
    }
    strbuf_append_str(hdr, ">\n");
  }
}
예제 #16
0
/* Note: It is kind of stupid to first call strbuf_free_to_string,
 * then later free (above this function). But with the current API
 * of strbuf_free there's no other way!
 */
char *
expand_substitution(const char *repl, MatchState *ms, uint32_t subc, SubmatchSpec *subv)
{
	StrBuf *buf = strbuf_new(); /* XXX: memory management */
	bool escaped = false;
	uint32_t c;

	for (c = 0; repl[c] != '\0'; c++) {
		if (!escaped && repl[c] == '$') {
			uint32_t d;
			if (repl[c+1] == '{') {
				for (d = c+2; repl[d] != '}' && repl[d] != '\0'; d++);
				if (repl[d] != '\0') {
					if (expand_variable(buf, repl+c+2, d-c-2, ms, subc, subv)) {
						c = d;
						continue;
					}
				}
			} else if (isdigit(repl[c+1])) {
				for (d = c+2; isdigit(repl[d]); d++);
				if (expand_variable(buf, repl+c+1, d-c-1, ms, subc, subv)) {
					c = d-1;
					continue;
				}
			} else if (repl[c+1] != '\0' && strchr("`'&", repl[c+1]) != NULL) {
				expand_variable(buf, repl+c+1, 1, ms, subc, subv);
				c++;
				continue;
			}
		}
		escaped = (!escaped && repl[c] == '\\');
		if (!escaped)
			strbuf_append_char(buf, repl[c]);
	}

	return strbuf_free_to_string(buf);
}
예제 #17
0
void graph_info_merge(GraphInfo *dst, const GraphInfo *src)
{
  // Update sample name
  if(strcmp(src->sample_name.b,"undefined") != 0) {
    if(strcmp(dst->sample_name.b,"undefined") == 0) {
      strbuf_set_buff(&dst->sample_name, &src->sample_name);
    } else {
      strbuf_append_char(&dst->sample_name, ',');
      strbuf_append_str(&dst->sample_name, src->sample_name.b);
    }
  }

  uint64_t total_sequence = dst->total_sequence + src->total_sequence;

  if(total_sequence > 0)
  {
    // Average error rates
    dst->seq_err
      = (dst->seq_err * dst->total_sequence +
         src->seq_err * src->total_sequence) /
        total_sequence;

    // Update mean read length
    size_t src_num_contigs = 0;

    if(src->total_sequence && src->mean_read_length)
       src_num_contigs = ((double)src->total_sequence/src->mean_read_length)+0.5;

    graph_info_update_contigs(dst, src->total_sequence, src_num_contigs);
 }

  // Update error cleaning
  error_cleaning_merge(&dst->cleaning, &src->cleaning);

  dst->total_sequence = total_sequence;
}
예제 #18
0
static void json_append_object(lua_State *l, struct luaL_serializer *cfg,
                               int current_depth, strbuf_t *json)
{
    int comma;

    /* Object */
    strbuf_append_char(json, '{');

    lua_pushnil(l);
    /* table, startkey */
    comma = 0;
    while (lua_next(l, -2) != 0) {
        if (comma)
            strbuf_append_char(json, ',');
        else
            comma = 1;

    struct luaL_field field;
    luaL_checkfield(l, cfg, -2, &field);
    if (field.type == MP_UINT) {
        strbuf_append_char(json, '"');
        json_append_uint(cfg, json, field.ival);
        strbuf_append_mem(json, "\":", 2);
    } else if (field.type == MP_INT) {
        strbuf_append_char(json, '"');
        json_append_int(cfg, json, field.ival);
        strbuf_append_mem(json, "\":", 2);
    } else if (field.type == MP_STR) {
        json_append_string(cfg, json, field.sval.data, field.sval.len);
        strbuf_append_char(json, ':');
    } else {
        luaL_error(l, "table key must be a number or string");
    }

        /* table, key, value */
    json_append_data(l, cfg, current_depth + 1, json);
        lua_pop(l, 1);
        /* table, key */
    }

    strbuf_append_char(json, '}');
}
예제 #19
0
lwan_tpl_chunk_t *
lwan_tpl_apply_until(lwan_tpl_chunk_t *chunks, strbuf_t *buf,
    char *(*var_get)(const char *name, void *data), void *var_get_data,
    bool (*until)(lwan_tpl_chunk_t *chunk, void *data), void *until_data)
{
    lwan_tpl_chunk_t *chunk = chunks;

    for (; chunk; chunk = chunk->next) {
        if (until(chunk, until_data))
            break;

        switch (chunk->action) {
        case TPL_ACTION_APPEND:
            strbuf_append_str(buf, chunk->data, 0);
            break;
        case TPL_ACTION_APPEND_CHAR:
            strbuf_append_char(buf, (char)(uintptr_t)chunk->data);
            break;
        case TPL_ACTION_VARIABLE:
            {
                char *tmp = var_get((const char*)chunk->data, var_get_data);
                strbuf_append_str(buf, tmp, 0);
                free(tmp);
            }
            break;
        case TPL_ACTION_LIST_START_ITER:
            strbuf_append_str(buf, "[begin_iter:", 0);
            strbuf_append_str(buf, chunk->data, 0);
            strbuf_append_str(buf, "]", 0);
            break;
        case TPL_ACTION_LIST_END_ITER:
            strbuf_append_str(buf, "[end_iter:", 0);
            strbuf_append_str(buf, chunk->data, 0);
            strbuf_append_str(buf, "]", 0);
            break;
        case TPL_ACTION_IF_VARIABLE_NOT_EMPTY:
            {
                const char *var_name = (const char*)chunk->data;
                char *tmp = var_get(var_name, var_get_data);
                if (tmp && *tmp) {
                    chunk = lwan_tpl_apply_until(chunk->next, buf, var_get, var_get_data, 
                                        until_not_empty, chunk->data);
                } else {
                    for (chunk = chunk->next; chunk; chunk = chunk->next) {
                        if (chunk->action == TPL_ACTION_END_IF_VARIABLE_NOT_EMPTY && !strcmp(chunk->data, var_name))
                            break;
                    }
                }
                free(tmp);
            }
            break;
        case TPL_ACTION_END_IF_VARIABLE_NOT_EMPTY:
            /* Shouldn't happen */
            break;
        case TPL_ACTION_APPLY_TPL:
            {
                strbuf_t *tmp = lwan_tpl_apply(chunk->data, var_get, var_get_data);
                strbuf_append_str(buf, strbuf_get_buffer(tmp), strbuf_get_length(tmp));
                strbuf_free(tmp);
            }
        }
    }

    return chunk;
}
예제 #20
0
// caller is reposible for freeing *product* and *version*
static void parse_release(const char *release, char** product, char** version, int flags)
{
    /* Fedora has a single non-numeric release - Rawhide */
    if (strstr(release, "Rawhide"))
    {
        *product = xstrdup("Fedora");
        *version = xstrdup("rawhide");
        log_debug("%s: version:'%s' product:'%s'", __func__, *version, *product);
        return;
    }

    /* openSUSE has two non-numeric releases - Factory and Tumbleweed
       None of them is unfortunately identified in any of /etc/SuSE-brand,
       /etc/SuSE-release or /etc/os-release. Keep this piece of code commented
       just not to forget about that. */

    /*
    if (strstr(release, "Factory"))
    {
        *product = xstrdup("openSUSE");
        *version = xstrdup("Factory");
        log_debug("%s: version:'%s' product:'%s'", __func__, *version, *product);
        return;
    }

    if (strstr(release, "Tumbleweed"))
    {
        *product = xstrdup("openSUSE");
        *version = xstrdup("Tumbleweed");
        log_debug("%s: version:'%s' product:'%s'", __func__, *version, *product);
        return;
    }
    */

    bool it_is_rhel = false;

    struct strbuf *buf_product = strbuf_new();
    if (strstr(release, "Fedora"))
    {
        strbuf_append_str(buf_product, "Fedora");
    }
    else if (strstr(release, "Red Hat Enterprise Linux"))
    {
        strbuf_append_str(buf_product, "Red Hat Enterprise Linux");
        it_is_rhel = true;
    }
    else if (strstr(release, "openSUSE"))
    {
        strbuf_append_str(buf_product, "openSUSE");
    }
    else
    {
        /* TODO: add logic for parsing other distros' names here */
        strbuf_append_str(buf_product, release);
    }

    /* Examples of release strings:
     * installed system: "Red Hat Enterprise Linux Server release 6.2 Beta (Santiago)"
     * anaconda: "Red Hat Enterprise Linux 6.2"
     */
    struct strbuf *buf_version = strbuf_new();
    const char *r = strstr(release, "release");
    const char *space = r ? strchr(r, ' ') : NULL;
    if (!space)
    {
        /* Try to find "<space><digit>" sequence */
        space = release;
        while ((space = strchr(space, ' ')) != NULL)
        {
            if (space[1] >= '0' && space[1] <= '9')
                break;
            space++;
        }
    }
    if (space)
    {
        space++;
        /* Observed also: "Fedora 16-Alpha" rhbz#730887 */
        while ((*space >= '0' && *space <= '9') || *space == '.')
        {
            /* Eat string like "5.2" */
            strbuf_append_char(buf_version, *space);
            space++;
        }

        if (flags & RETAIN_ALPHA_BETA_TAIL_IN_VER)
        {
            /* Example: "... 6.2 [Beta ](Santiago)".
             * 'space' variable points to non-digit char after "2".
             * We assume that non-parenthesized text is "Alpha"/"Beta"/etc.
             * If this text is only whitespace, we won't append it.
             */
            const char *to_append = space;
            while (*space && *space != '(') /* go to '(' */
                space++;
            while (space > to_append && space[-1] == ' ') /* back to 1st non-space */
                space--;
            strbuf_append_strf(buf_version, "%.*s", (int)(space - to_append), to_append);
        }
    }

    if ((flags & APPEND_MAJOR_VER_TO_RHEL_PRODUCT) && it_is_rhel)
    {
        char *v = buf_version->buf;
        /* Append "integer part" of version to product:
         * "10.2<anything>" -> append " 10"
         * "10 <anything>"  -> append " 10"
         * "10"             -> append " 10"
         * "10abcde"        -> append ?????
         */
        unsigned idx_dot = strchrnul(v, '.') - v;
        unsigned idx_space = strchrnul(v, ' ') - v;
        strbuf_append_strf(buf_product, " %.*s",
                        (idx_dot < idx_space ? idx_dot : idx_space), v
        );
    }

    *version = strbuf_free_nobuf(buf_version);
    *product = strbuf_free_nobuf(buf_product);

    log_debug("%s: version:'%s' product:'%s'", __func__, *version, *product);
}
예제 #21
0
char *make_description(problem_data_t *problem_data, char **names_to_skip,
                       unsigned max_text_size, unsigned desc_flags)
{
    struct strbuf *buf_dsc = strbuf_new();

    const char *analyzer = problem_data_get_content_or_NULL(problem_data,
                                                            FILENAME_ANALYZER);

    GList *list = g_hash_table_get_keys(problem_data);
    list = g_list_sort(list, (GCompareFunc)strcmp);
    GList *l;

    /* Print one-liners. Format:
     * NAME1: <maybe more spaces>VALUE1
     * NAME2: <maybe more spaces>VALUE2
     */
    bool empty = true;
    l = list;
    while (l)
    {
        const char *key = l->data;
        l = l->next;

        /* Skip items we are not interested in */
//TODO: optimize by doing this once, not 3 times:
        if (names_to_skip
            && rejected_name(key, names_to_skip, desc_flags))
            continue;

        struct problem_item *item = g_hash_table_lookup(problem_data, key);
        if (!item)
            continue;

        if ((desc_flags & MAKEDESC_SHOW_ONLY_LIST) && !(item->flags & CD_FLAG_LIST))
            continue;

        if ((item->flags & CD_FLAG_TXT)
         && strlen(item->content) <= max_text_size
        ) {
            char *formatted = problem_item_format(item);
            char *output = formatted ? formatted : item->content;
            char *eol = strchr(output, '\n');
            if (!eol)
            {
                int pad = 16 - (strlen(key) + 2);
                if (pad < 0) pad = 0;
                strbuf_append_strf(buf_dsc, "%s: %*s%s\n", key, pad, "", output);
                empty = false;
            }
            free(formatted);
        }
    }

    bool append_empty_line = !empty;
    if (desc_flags & MAKEDESC_SHOW_FILES)
    {
        /* Print file info. Format:
         * <empty line if needed>
         * NAME1: <maybe more spaces>Binary file, NNN bytes
         * NAME2: <maybe more spaces>Text file, NNN bytes
         *
         * In many cases, it is useful to know how big binary files are
         * (for example, helps with diagnosing bug upload problems)
         */
        l = list;
        while (l)
        {
            const char *key = l->data;
            l = l->next;

            /* Skip items we are not interested in */
            if (names_to_skip
                && rejected_name(key, names_to_skip, desc_flags))
                continue;

            struct problem_item *item = g_hash_table_lookup(problem_data, key);
            if (!item)
                continue;

            if ((desc_flags & MAKEDESC_SHOW_ONLY_LIST) && !(item->flags & CD_FLAG_LIST))
                continue;

            if ((item->flags & CD_FLAG_BIN)
             || ((item->flags & CD_FLAG_TXT) && strlen(item->content) > max_text_size)
            ) {
                if (append_empty_line)
                    strbuf_append_char(buf_dsc, '\n');
                append_empty_line = false;

                struct stat statbuf;
                int stat_err = 0;
                if (item->flags & CD_FLAG_BIN)
                    stat_err = stat(item->content, &statbuf);
                else
                    statbuf.st_size = strlen(item->content);

                /* We don't print item->content for CD_FLAG_BIN, as it is
                 * always "/path/to/dump/dir/KEY" - not informative.
                 */
                int pad = 16 - (strlen(key) + 2);
                if (pad < 0) pad = 0;
                strbuf_append_strf(buf_dsc,
                        (!stat_err ? "%s: %*s%s file, %llu bytes\n" : "%s: %*s%s file\n"),
                        key,
                        pad, "",
                        ((item->flags & CD_FLAG_BIN) ? "Binary" : "Text"),
                        (long long)statbuf.st_size
                );
                empty = false;
            }
        }
    }

    if (desc_flags & MAKEDESC_SHOW_MULTILINE)
    {
        /* Print multi-liners. Format:
         * <empty line if needed>
         * NAME:
         * :LINE1
         * :LINE2
         * :LINE3
         */
        l = list;
        while (l)
        {
            const char *key = l->data;
            l = l->next;

            /* Skip items we are not interested in */
            if (names_to_skip
                && rejected_name(key, names_to_skip, desc_flags))
                continue;

            struct problem_item *item = g_hash_table_lookup(problem_data, key);
            if (!item)
                continue;

            if ((desc_flags & MAKEDESC_SHOW_ONLY_LIST) && !(item->flags & CD_FLAG_LIST))
                continue;

            if ((item->flags & CD_FLAG_TXT)
                && (strlen(item->content) <= max_text_size
                    || (!strcmp(analyzer, "Kerneloops") && !strcmp(key, FILENAME_BACKTRACE))))
            {
                char *formatted = problem_item_format(item);
                char *output = make_description_item_multiline(key, formatted ? formatted : item->content);

                if (output)
                {
                    if (!empty)
                        strbuf_append_str(buf_dsc, "\n");

                    strbuf_append_str(buf_dsc, output);
                    empty = false;
                    free(output);
                }

                free(formatted);
            }
        }
    }

    g_list_free(list);

    return strbuf_free_nobuf(buf_dsc);
}
예제 #22
0
/* Quote STRING with double quotes if QUOTED is true, otherwise
 * by escaping whitespace, double quote and backslash as well
 * as characters in QC. Also, if the first character in STRING
 * is found in LEADING_QC, that character will be escaped.
 */
char *
quote_word_full(const char *string, bool quoted, bool add_end_quote,
		const char *qc, const char *leading_qc, bool quote_non_print_hex,
		bool quote_non_print_oct, bool quote_non_print_c, bool quote_wc)
{
    StrBuf *r = strbuf_new();
    const char *s;
    const unsigned char *u_s;

    if (quoted) {
        strbuf_append_char(r, '"');
        for (s = string; *s != '\0'; s++) {
	    if (quote_non_print_c) {
		int chr = 0;
		switch (*s) {
		case '\a': chr = 'a'; break;
		case '\b': chr = 'b'; break;
		case '\f': chr = 'f'; break;
		case '\n': chr = 'n'; break;
		case '\r': chr = 'r'; break;
		case '\t': chr = 't'; break;
		case '\v': chr = 'v'; break;
		}
		if (chr != 0) {
		    strbuf_appendf(r, "\\%c", chr);
		    continue;
		}
	    }
	    u_s = (const unsigned char *)s;
            if (quote_non_print_hex && !isprint(*u_s)) {
                strbuf_appendf(r, "\\x%02x", (unsigned)*s);
	    } else if (quote_non_print_oct && !isprint(*u_s)) {
		strbuf_appendf(r, "\\%03o", (unsigned)*s);
            } else {
                if (*s == '"' || *s == '\\')
                    strbuf_append_char(r, '\\');
                strbuf_append_char(r, *s);
            }
        }
        if (add_end_quote)
            strbuf_append_char(r, '"');
    } else {
        for (s = string; *s != '\0'; s++) {
	    if (quote_non_print_c) {
		int chr = 0;
		switch (*s) {
		case '\a': chr = 'a'; break;
		case '\b': chr = 'b'; break;
		case '\f': chr = 'f'; break;
		case '\n': chr = 'n'; break;
		case '\r': chr = 'r'; break;
		case '\t': chr = 't'; break;
		case '\v': chr = 'v'; break;
		}
		if (chr != 0) {
		    strbuf_appendf(r, "\\%c", chr);
		    continue;
		}
	    }
	    u_s = (const unsigned char *)s;
            if (quote_non_print_hex && !isprint(*u_s)) {
                strbuf_appendf(r, "\\x%02x", (unsigned)*s);
	    } else if (quote_non_print_oct && !isprint(*u_s)) {
		strbuf_appendf(r, "\\%03o", (unsigned)*u_s);
	    } else {
	        if (*s == '"'
      	                || *s == '\\'
	                || (quote_wc && *s == ' ')
  		        || strchr(qc, *s) != NULL
		        || (s == string && strchr(leading_qc, *u_s) != NULL))
		    strbuf_append_char(r, '\\');
                strbuf_append_char(r, *s);
            }
        }
    }

    return strbuf_free_to_string(r);
}
예제 #23
0
// Potential bubble - filter ref and duplicate alleles
static void print_bubble(BubbleCaller *caller,
                         GCacheStep **steps, size_t num_paths)
{
  const BubbleCallingPrefs prefs = caller->prefs;
  const dBGraph *db_graph = caller->db_graph;
  GCacheSnode *snode;
  size_t i;

  dBNodeBuffer *flank5p = &caller->flank5p;
  if(flank5p->len == 0)
  {
    // Haven't fetched 5p flank yet
    // flank5p[0] already contains the first node
    flank5p->len = 1;
    supernode_extend(flank5p, prefs.max_flank_len, db_graph);
    db_nodes_reverse_complement(flank5p->b, flank5p->len);
  }

  //
  // Print Bubble
  //

  // write to string buffer then flush to gzFile
  StrBuf *sbuf = &caller->output_buf;
  strbuf_reset(sbuf);

  // Temporary node buffer to use
  dBNodeBuffer *pathbuf = &caller->pathbuf;
  db_node_buf_reset(pathbuf);

  // Get bubble number (threadsafe num_bubbles_ptr++)
  size_t id = __sync_fetch_and_add((volatile size_t*)caller->num_bubbles_ptr, 1);

  // This can be set to anything without a '.' in it
  const char prefix[] = "call";

  // 5p flank
  // strbuf_sprintf(sbuf, ">bubble.%s%zu.5pflank kmers=%zu\n", prefix, id, flank5p->len);
  strbuf_append_str(sbuf, ">bubble.");
  strbuf_append_str(sbuf, prefix);
  strbuf_append_ulong(sbuf, id);
  strbuf_append_str(sbuf, ".5pflank kmers=");
  strbuf_append_ulong(sbuf, flank5p->len);
  strbuf_append_char(sbuf, '\n');
  branch_to_str(flank5p->b, flank5p->len, true, sbuf, db_graph);

  // 3p flank
  db_node_buf_reset(pathbuf);
  snode = graph_cache_snode(&caller->cache, steps[0]->supernode);
  graph_cache_snode_fetch_nodes(&caller->cache, snode, steps[0]->orient, pathbuf);

  // strbuf_sprintf(sbuf, ">bubble.%s%zu.3pflank kmers=%zu\n", prefix, id, pathbuf->len);
  strbuf_append_str(sbuf, ">bubble.");
  strbuf_append_str(sbuf, prefix);
  strbuf_append_ulong(sbuf, id);
  strbuf_append_str(sbuf, ".3pflank kmers=");
  strbuf_append_ulong(sbuf, pathbuf->len);
  strbuf_append_char(sbuf, '\n');
  branch_to_str(pathbuf->b, pathbuf->len, false, sbuf, db_graph);

  // Print alleles
  for(i = 0; i < num_paths; i++)
  {
    db_node_buf_reset(pathbuf);
    graph_cache_step_fetch_nodes(&caller->cache, steps[i], pathbuf);

    // strbuf_sprintf(sbuf, ">bubble.%s%zu.branch.%zu kmers=%zu\n",
    //                prefix, id, i, pathbuf->len);
    strbuf_append_str(sbuf, ">bubble.");
    strbuf_append_str(sbuf, prefix);
    strbuf_append_ulong(sbuf, id);
    strbuf_append_str(sbuf, ".branch.");
    strbuf_append_ulong(sbuf, i);
    strbuf_append_str(sbuf, " kmers=");
    strbuf_append_ulong(sbuf, pathbuf->len);
    strbuf_append_char(sbuf, '\n');

    branch_to_str(pathbuf->b, pathbuf->len, false, sbuf, db_graph);
  }

  strbuf_append_char(sbuf, '\n');

  ctx_assert(strlen(sbuf->b) == sbuf->end);

  // lock, print, unlock
  pthread_mutex_lock(caller->out_lock);
  gzwrite(caller->gzout, sbuf->b, sbuf->end);
  pthread_mutex_unlock(caller->out_lock);
}
예제 #24
0
static
char *format_percented_string(const char *str, problem_data_t *pd)
{
    size_t old_pos[MAX_OPT_DEPTH] = { 0 };
    int okay[MAX_OPT_DEPTH] = { 1 };
    int opt_depth = 1;
    struct strbuf *result = strbuf_new();

    while (*str) {
        switch (*str) {
        default:
            strbuf_append_char(result, *str);
            str++;
            break;
        case '\\':
            if (str[1])
                str++;
            strbuf_append_char(result, *str);
            str++;
            break;
        case '[':
            if (str[1] == '[' && opt_depth < MAX_OPT_DEPTH)
            {
                old_pos[opt_depth] = result->len;
                okay[opt_depth] = 1;
                opt_depth++;
                str += 2;
            } else {
                strbuf_append_char(result, *str);
                str++;
            }
            break;
        case ']':
            if (str[1] == ']' && opt_depth > 1)
            {
                opt_depth--;
                if (!okay[opt_depth])
                {
                    result->len = old_pos[opt_depth];
                    result->buf[result->len] = '\0';
                }
                str += 2;
            } else {
                strbuf_append_char(result, *str);
                str++;
            }
            break;
        case '%': ;
            char *nextpercent = strchr(++str, '%');
            if (!nextpercent)
            {
                error_msg_and_die("Unterminated %%element%%: '%s'", str - 1);
            }

            *nextpercent = '\0';
            const problem_item *item = problem_data_get_item_or_NULL(pd, str);
            *nextpercent = '%';

            if (item && (item->flags & CD_FLAG_TXT))
                strbuf_append_str(result, item->content);
            else
                okay[opt_depth - 1] = 0;
            str = nextpercent + 1;
            break;
        }
    }

    if (opt_depth > 1)
    {
        error_msg_and_die("Unbalanced [[ ]] bracket");
    }

    if (!okay[0])
    {
        error_msg("Undefined variable outside of [[ ]] bracket");
    }

    return strbuf_free_nobuf(result);
}
예제 #25
0
static bcf_hdr_t* make_vcf_hdr(cJSON *json, const char *in_path,
                               bool is_breakpoint, size_t kmer_size,
                               char const*const* ref_paths, size_t nref_paths,
                               read_t *chroms, size_t nchroms)
{
  ctx_assert(json != NULL);

  StrBuf hdrbuf;
  strbuf_alloc(&hdrbuf, 1024);

  char datestr[9];
  time_t date = time(NULL);
  strftime(datestr, 9, "%Y%m%d", localtime(&date));

  strbuf_append_str(&hdrbuf, "##fileformat=VCFv4.2\n##fileDate=");
  strbuf_append_str(&hdrbuf, datestr);
  strbuf_append_str(&hdrbuf, "\n");

  // Print commands used to generate header
  cJSON *commands = json_hdr_get(json, "commands", cJSON_Array, in_path);
  cJSON *command = commands->child;

  // Print this command
  char keystr[8];
  char *prevstr = NULL;
  size_t i;

  if(command) {
    cJSON *key = json_hdr_get(command, "key", cJSON_String, in_path);
    prevstr = key->valuestring;
  }

  // Print command entry for this command
  strbuf_append_str(&hdrbuf, "##mccortex_");
  strbuf_append_str(&hdrbuf, hex_rand_str(keystr, sizeof(keystr)));
  strbuf_append_str(&hdrbuf, "=<prev=\"");
  strbuf_append_str(&hdrbuf, prevstr ? prevstr : "NULL");
  strbuf_append_str(&hdrbuf, "\",cmd=\"");
  strbuf_append_str(&hdrbuf, cmd_get_cmdline());
  strbuf_append_str(&hdrbuf, "\",cwd=\"");
  strbuf_append_str(&hdrbuf, cmd_get_cwd());
  strbuf_append_str(&hdrbuf, "\",version="CTX_VERSION">\n");

  // Print previous commands
  vcf_hdrtxt_append_commands(command, &hdrbuf, in_path);

  // Print field definitions
  if(is_breakpoint)
    strbuf_append_str(&hdrbuf, "##INFO=<ID=BRKPNT,Number=1,Type=String,Description=\"Breakpoint call\">\n");
  else
    strbuf_append_str(&hdrbuf, "##INFO=<ID=BUBBLE,Number=1,Type=String,Description=\"Bubble call\">\n");

  strbuf_sprintf(&hdrbuf, "##INFO=<ID=K%zu,Number=0,Type=Flag,Description=\"Found at k=%zu\">\n", kmer_size, kmer_size);

  strbuf_append_str(&hdrbuf, "##FORMAT=<ID=GT,Number=1,Type=String,Description=\"Genotype\">\n");
  strbuf_append_str(&hdrbuf, "##FILTER=<ID=PASS,Description=\"All filters passed\">\n");

  // Print reference paths
  strbuf_append_str(&hdrbuf, "##reference=");
  strbuf_append_str(&hdrbuf, ref_paths[0]);
  for(i = 1; i < nref_paths; i++) {
    strbuf_append_char(&hdrbuf, ',');
    strbuf_append_str(&hdrbuf, ref_paths[i]);
  }
  strbuf_append_str(&hdrbuf, "\n");

  // Print contigs lengths
  for(i = 0; i < nchroms; i++) {
    strbuf_sprintf(&hdrbuf, "##contig=<ID=%s,length=%zu>\n",
                   chroms[i].name.b, chroms[i].seq.end);
  }

  // Print VCF column header
  strbuf_append_str(&hdrbuf, "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT");

  if(is_breakpoint)
  {
    // Print a column for each sample
    cJSON *graph_json   = json_hdr_get(json,       "graph",   cJSON_Object, in_path);
    cJSON *colours_json = json_hdr_get(graph_json, "colours", cJSON_Array,  in_path);
    cJSON *colour_json  = colours_json->child;
    if(colour_json == NULL) die("Missing colours");
    for(; colour_json; colour_json = colour_json->next)
    {
      if(!json_hdr_colour_is_ref(colour_json)) {
        cJSON *sample_json = json_hdr_get(colour_json, "sample", cJSON_String, in_path);
        strbuf_append_str(&hdrbuf, "\t");
        strbuf_append_str(&hdrbuf, sample_json->valuestring);
      }
    }
  }

  strbuf_append_char(&hdrbuf, '\n');
  bcf_hdr_t *hdr = bcf_hdr_init("w");
  if(bcf_hdr_parse(hdr, hdrbuf.b) != 0) die("Cannot construct VCF header");

  strbuf_dealloc(&hdrbuf);

  return hdr;
}
예제 #26
0
파일: lwan-config.c 프로젝트: ktsaou/lwan
static void *parse_key_value(struct parser *parser)
{
    struct config_line line = { .type = CONFIG_LINE_TYPE_LINE };
    struct lexeme *lexeme;
    size_t key_size;

    while (lexeme_buffer_consume(&parser->buffer, &lexeme)) {
        strbuf_append_str(&parser->strbuf, lexeme->value.value, lexeme->value.len);

        if (parser->buffer.population >= 1)
            strbuf_append_char(&parser->strbuf, '_');
    }
    key_size = strbuf_get_length(&parser->strbuf);
    strbuf_append_char(&parser->strbuf, '\0');

    while (lex_next(&parser->lexer, &lexeme)) {
        switch (lexeme->type) {
        case LEXEME_VARIABLE: {
            const char *value;

            value = secure_getenv_len(lexeme->value.value, lexeme->value.len);
            if (!value) {
                lwan_status_error("Variable '$%.*s' not defined in environment",
                    (int)lexeme->value.len, lexeme->value.value);
                return NULL;
            }

            strbuf_append_str(&parser->strbuf, value, 0);
            break;
        }

        case LEXEME_EQUAL:
            strbuf_append_char(&parser->strbuf, '=');
            break;

        case LEXEME_STRING:
            strbuf_append_str(&parser->strbuf, lexeme->value.value, lexeme->value.len);
            break;

        case LEXEME_CLOSE_BRACKET:
            backup(&parser->lexer);
            /* fallthrough */

        case LEXEME_LINEFEED:
            line.key = strbuf_get_buffer(&parser->strbuf);
            line.value = line.key + key_size + 1;
            if (!config_buffer_emit(&parser->items, &line))
                return NULL;

            return parse_config;

        default:
            lwan_status_error("Unexpected token while parsing key-value: %s",
                lexeme_type_str[lexeme->type]);
            return NULL;
        }
    }

    lwan_status_error("EOF while parsing key-value");
    return NULL;
}
예제 #27
0
unsigned parse_opts(int argc, char **argv, const struct options *opt,
                const char *usage)
{
    int help = 0;
    int size = parse_opt_size(opt);
    const int LONGOPT_OFFSET = 256;

    struct strbuf *shortopts = strbuf_new();

    struct option *longopts = xzalloc(sizeof(longopts[0]) * (size+2));
    struct option *curopt = longopts;
    int ii;
    for (ii = 0; ii < size; ++ii)
    {
        curopt->name = opt[ii].long_name;
        /*curopt->flag = 0; - xzalloc did it */
        if (opt[ii].short_name)
            curopt->val = opt[ii].short_name;
        else
            curopt->val = LONGOPT_OFFSET + ii;

        switch (opt[ii].type)
        {
            case OPTION_BOOL:
                curopt->has_arg = no_argument;
                if (opt[ii].short_name)
                    strbuf_append_char(shortopts, opt[ii].short_name);
                break;
            case OPTION_INTEGER:
            case OPTION_STRING:
            case OPTION_LIST:
                curopt->has_arg = required_argument;
                if (opt[ii].short_name)
                    strbuf_append_strf(shortopts, "%c:", opt[ii].short_name);
                break;
            case OPTION_OPTSTRING:
                curopt->has_arg = optional_argument;
                if (opt[ii].short_name)
                    strbuf_append_strf(shortopts, "%c::", opt[ii].short_name);
                break;
            case OPTION_GROUP:
            case OPTION_END:
                break;
        }
        //log("curopt[%d].name:'%s' .has_arg:%d .flag:%p .val:%d", (int)(curopt-longopts),
        //      curopt->name, curopt->has_arg, curopt->flag, curopt->val);
        /*
         * getopt_long() thinks that NULL name marks the end of longopts.
         * Example:
         * [0] name:'verbose' val:'v'
         * [1] name:NULL      val:'c'
         * [2] name:'force'   val:'f'
         * ... ... ...
         * In this case, --force won't be accepted!
         * Therefore we can only advance if name is not NULL.
         */
        if (curopt->name)
            curopt++;
    }
    curopt->name = "help";
    curopt->has_arg = no_argument;
    curopt->flag = &help;
    curopt->val = 1;
    /* xzalloc did it already:
    curopt++;
    curopt->name = NULL;
    curopt->has_arg = 0;
    curopt->flag = NULL;
    curopt->val = 0;
    */

    unsigned retval = 0;
    while (1)
    {
        int c = getopt_long(argc, argv, shortopts->buf, longopts, NULL);

        if (c == -1)
            break;

        if (c == '?' || help)
        {
            free(longopts);
            strbuf_free(shortopts);
            xfunc_error_retval = 0; /* this isn't error, exit code = 0 */
            show_usage_and_die(usage, opt);
        }

        for (ii = 0; ii < size; ++ii)
        {
            if (opt[ii].short_name == c || LONGOPT_OFFSET + ii == c)
            {
                if (ii < sizeof(retval)*8)
                    retval |= (1 << ii);

                if (opt[ii].value != NULL) switch (opt[ii].type)
                {
                    case OPTION_BOOL:
                        *(int*)(opt[ii].value) += 1;
                        break;
                    case OPTION_INTEGER:
                        *(int*)(opt[ii].value) = xatoi(optarg);
                        break;
                    case OPTION_STRING:
                    case OPTION_OPTSTRING:
                        if (optarg)
                            *(char**)(opt[ii].value) = (char*)optarg;
                        break;
                    case OPTION_LIST:
                        *(GList**)(opt[ii].value) = g_list_append(*(GList**)(opt[ii].value), optarg);
                        break;
                    case OPTION_GROUP:
                    case OPTION_END:
                        break;
                }
            }
        }
    }

    free(longopts);
    strbuf_free(shortopts);

    return retval;
}
예제 #28
0
lwan_tpl_t *
lwan_tpl_compile(const char *filename)
{
    lwan_tpl_t *tpl;
    strbuf_t *buf;
    FILE *file;
    int state = STATE_DEFAULT;
    char error_msg[512];
    
    tpl = calloc(1, sizeof(*tpl));
    if (!tpl)
        return NULL;

    buf = strbuf_new();
    if (!buf) {
        free(tpl);
        return NULL;
    }
    
    file = fopen(filename, "r");
    if (!file) {
        strbuf_free(buf);
        free(tpl);
        return NULL;
    }

    int line = 1;
    int column = 1;
    char ch;
    while ((ch = fgetc(file)) != EOF) {
        if (ch == '\n') {
            if (state == STATE_DEFAULT)
                strbuf_append_char(buf, '\n');

            line++;
            column = 1;
            continue;
        }
        ++column;

        switch (state) {
        case STATE_DEFAULT:
            if (ch == '{') {
                state = STATE_FIRST_BRACE;
                continue;
            }

            strbuf_append_char(buf, ch);
            break;
        case STATE_FIRST_BRACE:
            if (ch == '{') {
                switch (compile_append_text(tpl, buf)) {
                case -ENOMEM:
                    PARSE_ERROR("Out of memory while appending text.");
                }

                state = STATE_SECOND_BRACE;
                continue;
            }

            strbuf_append_char(buf, '{');
            strbuf_append_char(buf, ch);
            state = STATE_DEFAULT;
            break;
        case STATE_SECOND_BRACE:
            if (ch == '{')
                PARSE_ERROR("Unexpected open brace.");

            if (ch == '}') {
                state = STATE_FIRST_CLOSING_BRACE;
                continue;
            }

            strbuf_append_char(buf, ch);
            break;
        case STATE_FIRST_CLOSING_BRACE:
            if (ch == '}') {
                state = STATE_SECOND_CLOSING_BRACE;
                continue;
            }
            PARSE_ERROR("Closing brace expected.");
        case STATE_SECOND_CLOSING_BRACE:
            if (ch == '}')
                PARSE_ERROR("Unexpected close brace.");

            if (strbuf_get_length(buf) == 0)
                PARSE_ERROR("Expecting variable name.");

            switch (compile_append_var(tpl, buf)) {
            case -ENOMEM:
                PARSE_ERROR("Out of memory while appending variable.");
            case -ENOENT:
                PARSE_ERROR("Cannot find included template: ``%s''.", strbuf_get_buffer(buf) + 1);
            }

            if (ch == '{') {
                state = STATE_FIRST_BRACE;
                continue;
            }

            strbuf_append_char(buf, ch);
            state = STATE_DEFAULT;
        }
    }

    switch (state) {
    case STATE_DEFAULT:
        switch (compile_append_text(tpl, buf)) {
        case -ENOMEM:
            PARSE_ERROR("Out of memory while appending text.");
        }
        break;
    case STATE_FIRST_BRACE:
    case STATE_SECOND_BRACE:
        PARSE_ERROR("Expecting close brace.");
    case STATE_FIRST_CLOSING_BRACE:
        PARSE_ERROR("Expecting second close brace.");
    case STATE_SECOND_CLOSING_BRACE:
        if (strbuf_get_length(buf) == 0)
            PARSE_ERROR("Expecting variable name.");

        switch (compile_append_var(tpl, buf)) {
        case -ENOMEM:
            PARSE_ERROR("Out of memory while appending variable.");
        case -ENOENT:
            PARSE_ERROR("Cannot find included template: ``%s''.", strbuf_get_buffer(buf));
        }
    }

    lwan_tpl_chunk_t *last = malloc(sizeof(*last));
    if (!last)
        goto error;
    last->action = TPL_ACTION_LAST;
    last->data = NULL;
    last->next = tpl->chunks;
    tpl->chunks = last;

    lwan_tpl_chunk_t *prev = NULL;
    while (tpl->chunks) {
        lwan_tpl_chunk_t *next = tpl->chunks->next;
        tpl->chunks->next = prev;
        prev = tpl->chunks;
        tpl->chunks = next;
    }
    tpl->chunks = prev;

    strbuf_free(buf);
    return tpl;

error:
    lwan_tpl_free(tpl);
    strbuf_free(buf);
    fclose(file);
    
    printf("Line %d, column %d: %s\n", line, column, error_msg);
    return NULL;
}
예제 #29
0
// @param vcf_pos is 0-based
// @param prev_base is -1 if SNP otherwise previous base
// @param next_base is -1 unless indel at position 0
static void print_vcf_entry(size_t vcf_pos, int8_t prev_base, int8_t next_base,
                            const char *ref, const char *alt, size_t len,
                            const uint8_t *gts, size_t nsamples,
                            CallDecomp *dc, const AlignedCall *call,
                            size_t max_allele_len)
{
  dc->stats.nvars++;

  StrBuf *sbuf = &dc->sbuf;
  strbuf_reset(sbuf);

  // Check actual allele length
  size_t i, alt_bases = 0;
  for(i = 0; i < len; i++) alt_bases += (alt[i] != '-');
  if(alt_bases > max_allele_len) { dc->stats.nallele_too_long++; return; }

  // CHROM POS ID REF ALT QUAL FILTER INFO
  strbuf_append_str(sbuf, call->chrom->name.b);
  strbuf_append_char(sbuf, '\t');
  strbuf_append_ulong(sbuf, vcf_pos+1);
  strbuf_append_str(sbuf, "\t.\t");
  print_vcf_allele(ref, len, prev_base, next_base, sbuf);
  strbuf_append_char(sbuf, '\t');
  print_vcf_allele(alt, len, prev_base, next_base, sbuf);
  strbuf_append_str(sbuf, "\t.\tPASS\t");
  strbuf_append_str(sbuf, call->info.b ? call->info.b : ".");
  strbuf_append_str(sbuf, "\tGT");

  // Print genotypes
  for(i = 0; i < nsamples; i++) {
    strbuf_append_char(sbuf, '\t');
    strbuf_append_char(sbuf, gts[i] ? '1' : '.');
  }

  strbuf_append_char(sbuf, '\n');

  // fprintf(stderr, " prev_base:%i next_base:%i info:%s\n", prev_base, next_base, call->info.b);
  // fprintf(stderr, "%s [%zu vs %zu]\n", sbuf->b, sbuf->end, strlen(sbuf->b));

  kstring_t ks = {.l = sbuf->end, .m = sbuf->size, .s = sbuf->b};
  if(vcf_parse(&ks, dc->vcfhdr, dc->v) != 0)
    die("Cannot construct VCF entry: %s", sbuf->b);
  if(bcf_write(dc->vcffh, dc->vcfhdr, dc->v) != 0)
    die("Cannot write VCF entry [nsamples: %zu vs %zu]", nsamples, (size_t)bcf_hdr_nsamples(dc->vcfhdr));
  // Move back into our string buffer
  sbuf->b = ks.s;
  sbuf->size = ks.m;

  dc->stats.nvars_printed++;
}

// `ref` and `alt` are aligned alleles - should both be same length strings
// of 'ACGT-'
// return first mismatch position or -1
static int align_get_start(const char *ref, const char *alt)
{
  const char *start = ref;
  while(*ref) {
    if(*ref != *alt) return (ref - start);
    ref++; alt++;
  }
  return -1;
}

// `ref` and `alt` are aligned alleles - should both be same length strings
// of 'ACGT-'
// return first matching position
static int align_get_end(const char *ref, const char *alt)
{
  int i = 0;
  while(ref[i] && ref[i] != alt[i]) i++;
  return i;
}
예제 #30
0
/**
 * Print paths to a string buffer. Paths are sorted before being written.
 *
 * @param hkey    All paths associated with hkey are written to the buffer
 * @param sbuf    paths are written this string buffer
 * @param subset  is a temp variable that is reused each time
 * @param nbuf    temporary buffer, if not NULL, used to add seq=... to output
 * @param jposbuf temporary buffer, if not NULL, used to add juncpos=... to output
 */
void gpath_save_sbuf(hkey_t hkey, StrBuf *sbuf, GPathSubset *subset,
                     dBNodeBuffer *nbuf, SizeBuffer *jposbuf,
                     const dBGraph *db_graph)
{
  ctx_assert(db_graph->num_of_cols == 1 || nbuf == NULL);
  ctx_assert(db_graph->num_of_cols == 1 || jposbuf == NULL);

  const GPathStore *gpstore = &db_graph->gpstore;
  const GPathSet *gpset = &gpstore->gpset;
  const size_t ncols = gpstore->gpset.ncols;
  GPath *first_gpath = gpath_store_fetch(gpstore, hkey);
  const GPath *gpath;
  size_t i, j, col;

  // Load and sort paths for given kmer
  gpath_subset_reset(subset);
  gpath_subset_load_llist(subset, first_gpath);
  gpath_subset_sort(subset);

  if(subset->list.len == 0) return;

  // Print "<kmer> <npaths>"
  BinaryKmer bkmer = db_graph->ht.table[hkey];
  char bkstr[MAX_KMER_SIZE+1];
  binary_kmer_to_str(bkmer, db_graph->kmer_size, bkstr);

  // strbuf_sprintf(sbuf, "%s %zu\n", bkstr, subset->list.len);
  strbuf_append_strn(sbuf, bkstr, db_graph->kmer_size);
  strbuf_append_char(sbuf, ' ');
  strbuf_append_ulong(sbuf, subset->list.len);
  strbuf_append_char(sbuf, '\n');

  char orchar[2] = {0};
  orchar[FORWARD] = 'F';
  orchar[REVERSE] = 'R';
  const uint8_t *nseenptr;

  for(i = 0; i < subset->list.len; i++)
  {
    gpath = subset->list.b[i];
    nseenptr = gpath_set_get_nseen(gpset, gpath);

    // strbuf_sprintf(sbuf, "%c %zu %u %u", orchar[gpath->orient], klen,
    //                                      gpath->num_juncs, (uint32_t)nseenptr[0]);

    strbuf_append_char(sbuf, orchar[gpath->orient]);
    strbuf_append_char(sbuf, ' ');
    strbuf_append_ulong(sbuf, gpath->num_juncs);
    strbuf_append_char(sbuf, ' ');
    strbuf_append_ulong(sbuf, nseenptr[0]);

    for(col = 1; col < ncols; col++) {
      // strbuf_sprintf(sbuf, ",%u", (uint32_t)nseenptr[col]);
      strbuf_append_char(sbuf, ',');
      strbuf_append_ulong(sbuf, nseenptr[col]);
    }

    strbuf_append_char(sbuf, ' ');
    strbuf_ensure_capacity(sbuf, sbuf->end + gpath->num_juncs + 2);
    binary_seq_to_str(gpath->seq, gpath->num_juncs, sbuf->b+sbuf->end);
    sbuf->end += gpath->num_juncs;

    if(nbuf)
    {
      // Trace this path through the graph
      // First, find a colour this path is in
      for(col = 0; col < ncols && !gpath_has_colour(gpath, ncols, col); col++) {}
      if(col == ncols) die("path is not in any colours");

      dBNode node = {.key = hkey, .orient = gpath->orient};
      db_node_buf_reset(nbuf);
      if(jposbuf) size_buf_reset(jposbuf); // indices of junctions in nbuf
      gpath_fetch(node, gpath, nbuf, jposbuf, col, db_graph);

      strbuf_append_str(sbuf, " seq=");
      strbuf_ensure_capacity(sbuf, sbuf->end + db_graph->kmer_size + nbuf->len);
      sbuf->end += db_nodes_to_str(nbuf->b, nbuf->len, db_graph,
                                   sbuf->b+sbuf->end);

      if(jposbuf) {
        strbuf_append_str(sbuf, " juncpos=");
        strbuf_append_ulong(sbuf, jposbuf->b[0]);

        for(j = 1; j < jposbuf->len; j++) {
          strbuf_append_char(sbuf, ',');
          strbuf_append_ulong(sbuf, jposbuf->b[j]);
        }
      }
    }

    strbuf_append_char(sbuf, '\n');
  }
}

// @subset is a temp variable that is reused each time
// @sbuf   is a temp variable that is reused each time
static inline int _gpath_gzsave_node(hkey_t hkey,
                                     StrBuf *sbuf, GPathSubset *subset,
                                     dBNodeBuffer *nbuf, SizeBuffer *jposbuf,
                                     gzFile gzout, pthread_mutex_t *outlock,
                                     const dBGraph *db_graph)
{
  gpath_save_sbuf(hkey, sbuf, subset, nbuf, jposbuf, db_graph);

  if(sbuf->end > DEFAULT_IO_BUFSIZE)
    _gpath_save_flush(gzout, sbuf, outlock);

  return 0; // => keep iterating
}