static enum cue_command read_cmd(struct bstr *data, struct bstr *out_params) { struct bstr line = bstr_strip_linebreaks(bstr_getline(*data, data)); line = bstr_lstrip(line); if (line.len == 0) return CUE_EMPTY; for (int n = 0; cue_command_strings[n].command != -1; n++) { struct bstr name = bstr0(cue_command_strings[n].text); if (bstr_startswith(line, name)) { struct bstr rest = bstr_cut(line, name.len); if (rest.len && !strchr(WHITESPACE, rest.start[0])) continue; if (out_params) *out_params = rest; return cue_command_strings[n].command; } } return CUE_ERROR; }
int mp_event_drop_mime_data(struct input_ctx *ictx, const char *mime_type, bstr data) { // X11 and Wayland file list format. if (strcmp(mime_type, "text/uri-list") == 0) { void *tmp = talloc_new(NULL); int num_files = 0; char **files = NULL; while (data.len) { bstr line = bstr_getline(data, &data); line = bstr_strip_linebreaks(line); if (bstr_startswith0(line, "#")) continue; char *s = bstrto0(tmp, line); MP_TARRAY_APPEND(tmp, files, num_files, s); } mp_event_drop_files(ictx, num_files, files); talloc_free(tmp); return num_files > 0; } else { return -1; } }
int m_config_parse(m_config_t *config, const char *location, bstr data, char *initial_section, int flags) { m_profile_t *profile = m_config_add_profile(config, initial_section); void *tmp = talloc_new(NULL); int line_no = 0; int errors = 0; bstr_eatstart0(&data, "\xEF\xBB\xBF"); // skip BOM while (data.len) { talloc_free_children(tmp); bool ok = false; line_no++; char loc[512]; snprintf(loc, sizeof(loc), "%s:%d:", location, line_no); bstr line = bstr_strip_linebreaks(bstr_getline(data, &data)); if (!skip_ws(&line)) continue; // Profile declaration if (bstr_eatstart0(&line, "[")) { bstr profilename; if (!bstr_split_tok(line, "]", &profilename, &line)) { MP_ERR(config, "%s missing closing ]\n", loc); goto error; } if (skip_ws(&line)) { MP_ERR(config, "%s unparseable extra characters: '%.*s'\n", loc, BSTR_P(line)); goto error; } profile = m_config_add_profile(config, bstrto0(tmp, profilename)); continue; } bstr_eatstart0(&line, "--"); bstr option = line; while (line.len && (mp_isalnum(line.start[0]) || line.start[0] == '_' || line.start[0] == '-')) line = bstr_cut(line, 1); option.len = option.len - line.len; skip_ws(&line); bstr value = {0}; if (bstr_eatstart0(&line, "=")) { skip_ws(&line); if (line.len && (line.start[0] == '"' || line.start[0] == '\'')) { // Simple quoting, like "value" char term[2] = {line.start[0], 0}; line = bstr_cut(line, 1); if (!bstr_split_tok(line, term, &value, &line)) { MP_ERR(config, "%s unterminated quote\n", loc); goto error; } } else if (bstr_eatstart0(&line, "%")) { // Quoting with length, like %5%value bstr rest; long long len = bstrtoll(line, &rest, 10); if (rest.len == line.len || !bstr_eatstart0(&rest, "%") || len > rest.len) { MP_ERR(config, "%s fixed-length quoting expected - put " "\"quotes\" around the option value if you did not " "intend to use this, but your option value starts " "with '%%'\n", loc); goto error; } value = bstr_splice(rest, 0, len); line = bstr_cut(rest, len); } else { // No quoting; take everything until the comment or end of line int end = bstrchr(line, '#'); value = bstr_strip(end < 0 ? line : bstr_splice(line, 0, end)); line.len = 0; } } if (skip_ws(&line)) { MP_ERR(config, "%s unparseable extra characters: '%.*s'\n", loc, BSTR_P(line)); goto error; } int res; if (profile) { if (bstr_equals0(option, "profile-desc")) { m_profile_set_desc(profile, value); res = 0; } else { res = m_config_set_profile_option(config, profile, option, value); } } else { res = m_config_set_option_ext(config, option, value, flags); } if (res < 0) { MP_ERR(config, "%s setting option %.*s='%.*s' failed.\n", loc, BSTR_P(option), BSTR_P(value)); goto error; } ok = true; error: if (!ok) errors++; if (errors > 16) { MP_ERR(config, "%s: too many errors, stopping.\n", location); break; } } talloc_free(tmp); return 1; }
int parse_codec_cfg(const char *cfgfile) { codecs_t *codec = NULL; // current codec codecs_t **codecsp = NULL;// points to audio_codecs or to video_codecs char *endptr; // strtoul()... int *nr_codecsp; int codec_type; /* TYPE_VIDEO/TYPE_AUDIO */ int tmp, i; int codec_cfg_min; for (struct bstr s = builtin_codecs_conf; ; bstr_getline(s, &s)) { if (!s.len) abort(); if (bstr_eatstart0(&s, "release ")) { codec_cfg_min = atoi(s.start); break; } } // in case we call it a second time codecs_uninit_free(); nr_vcodecs = 0; nr_acodecs = 0; if (cfgfile) { // Avoid printing errors from open_stream when trying optional files if (!mp_path_exists(cfgfile)) { mp_tmsg(MSGT_CODECCFG, MSGL_V, "No optional codecs config file: %s\n", cfgfile); return 0; } mp_msg(MSGT_CODECCFG, MSGL_V, "Reading codec config file: %s\n", cfgfile); struct stream *s = open_stream(cfgfile, NULL, NULL); if (!s) return 0; filetext = stream_read_complete(s, NULL, 10000000, 1); free_stream(s); if (!filetext.start) return 0; } else // Parsing modifies the data filetext = bstrdup(NULL, builtin_codecs_conf); void *tmpmem = filetext.start; read_nextline = 1; /* * this only catches release lines at the start of * codecs.conf, before audiocodecs and videocodecs. */ while ((tmp = get_token(1, 1)) == RET_EOL) /* NOTHING */; if (tmp == RET_EOF) goto out; if (!strcmp(token[0], "release")) { if (get_token(1, 2) < 0) goto err_out_parse_error; tmp = atoi(token[0]); if (tmp < codec_cfg_min) goto err_out_release_num; codecs_conf_release = tmp; while ((tmp = get_token(1, 1)) == RET_EOL) /* NOTHING */; if (tmp == RET_EOF) goto out; } else goto err_out_release_num; /* * check if the next block starts with 'audiocodec' or * with 'videocodec' */ if (!strcmp(token[0], "audiocodec") || !strcmp(token[0], "videocodec")) goto loop_enter; goto err_out_parse_error; while ((tmp = get_token(1, 1)) != RET_EOF) { if (tmp == RET_EOL) continue; if (!strcmp(token[0], "audiocodec") || !strcmp(token[0], "videocodec")) { if (!validate_codec(codec, codec_type)) goto err_out_not_valid; loop_enter: if (*token[0] == 'v') { codec_type = TYPE_VIDEO; nr_codecsp = &nr_vcodecs; codecsp = &video_codecs; } else { assert(*token[0] == 'a'); codec_type = TYPE_AUDIO; nr_codecsp = &nr_acodecs; codecsp = &audio_codecs; } if (!(*codecsp = realloc(*codecsp, sizeof(codecs_t) * (*nr_codecsp + 2)))) { mp_tmsg(MSGT_CODECCFG,MSGL_FATAL,"Can't realloc '*codecsp': %s\n", strerror(errno)); goto err_out; } codec=*codecsp + *nr_codecsp; ++*nr_codecsp; memset(codec,0,sizeof(codecs_t)); memset(codec->fourcc, 0xff, sizeof(codec->fourcc)); memset(codec->outfmt, 0xff, sizeof(codec->outfmt)); memset(codec->infmt, 0xff, sizeof(codec->infmt)); if (get_token(1, 1) < 0) goto err_out_parse_error; for (i = 0; i < *nr_codecsp - 1; i++) { if(( (*codecsp)[i].name!=NULL) && (!strcmp(token[0], (*codecsp)[i].name)) ) { mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Codec name '%s' isn't unique.", token[0]); goto err_out_print_linenum; } } if (!(codec->name = strdup(token[0]))) { mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Can't strdup -> 'name': %s\n", strerror(errno)); goto err_out; } } else if (!strcmp(token[0], "info")) { if (codec->info || get_token(1, 1) < 0) goto err_out_parse_error; if (!(codec->info = strdup(token[0]))) { mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Can't strdup -> 'info': %s\n", strerror(errno)); goto err_out; } } else if (!strcmp(token[0], "comment")) { if (get_token(1, 1) < 0) goto err_out_parse_error; add_comment(token[0], &codec->comment); } else if (!strcmp(token[0], "fourcc")) { if (get_token(1, 2) < 0) goto err_out_parse_error; if (!add_to_fourcc(token[0], token[1], codec->fourcc, codec->fourccmap)) goto err_out_print_linenum; } else if (!strcmp(token[0], "format")) { if (get_token(1, 2) < 0) goto err_out_parse_error; if (!add_to_format(token[0], token[1], codec->fourcc,codec->fourccmap)) goto err_out_print_linenum; } else if (!strcmp(token[0], "driver")) { if (get_token(1, 1) < 0) goto err_out_parse_error; if (!(codec->drv = strdup(token[0]))) { mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Can't strdup -> 'driver': %s\n", strerror(errno)); goto err_out; } } else if (!strcmp(token[0], "dll")) { if (get_token(1, 1) < 0) goto err_out_parse_error; if (!(codec->dll = strdup(token[0]))) { mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Can't strdup -> 'dll': %s", strerror(errno)); goto err_out; } } else if (!strcmp(token[0], "guid")) { if (get_token(11, 11) < 0) goto err_out_parse_error; codec->guid.f1=strtoul(token[0],&endptr,0); if ((*endptr != ',' || *(endptr + 1) != '\0') && *endptr != '\0') goto err_out_parse_error; codec->guid.f2=strtoul(token[1],&endptr,0); if ((*endptr != ',' || *(endptr + 1) != '\0') && *endptr != '\0') goto err_out_parse_error; codec->guid.f3=strtoul(token[2],&endptr,0); if ((*endptr != ',' || *(endptr + 1) != '\0') && *endptr != '\0') goto err_out_parse_error; for (i = 0; i < 8; i++) { codec->guid.f4[i]=strtoul(token[i + 3],&endptr,0); if ((*endptr != ',' || *(endptr + 1) != '\0') && *endptr != '\0') goto err_out_parse_error; } } else if (!strcmp(token[0], "out")) { if (get_token(1, 2) < 0) goto err_out_parse_error; if (!add_to_inout(token[0], token[1], codec->outfmt, codec->outflags)) goto err_out_print_linenum; } else if (!strcmp(token[0], "in")) { if (get_token(1, 2) < 0) goto err_out_parse_error; if (!add_to_inout(token[0], token[1], codec->infmt, codec->inflags)) goto err_out_print_linenum; } else if (!strcmp(token[0], "flags")) { if (get_token(1, 1) < 0) goto err_out_parse_error; if (!strcmp(token[0], "seekable")) codec->flags |= CODECS_FLAG_SEEKABLE; else if (!strcmp(token[0], "align16")) codec->flags |= CODECS_FLAG_ALIGN16; else goto err_out_parse_error; } else if (!strcmp(token[0], "status")) { if (get_token(1, 1) < 0) goto err_out_parse_error; if (!strcasecmp(token[0], "working")) codec->status = CODECS_STATUS_WORKING; else if (!strcasecmp(token[0], "crashing")) codec->status = CODECS_STATUS_NOT_WORKING; else if (!strcasecmp(token[0], "untested")) codec->status = CODECS_STATUS_UNTESTED; else if (!strcasecmp(token[0], "buggy")) codec->status = CODECS_STATUS_PROBLEMS; else goto err_out_parse_error; } else if (!strcmp(token[0], "anyinput")) { codec->anyinput = true; } else goto err_out_parse_error; } if (!validate_codec(codec, codec_type)) goto err_out_not_valid; mp_tmsg(MSGT_CODECCFG, MSGL_V, "%d audio & %d video codecs\n", nr_acodecs, nr_vcodecs); if(video_codecs) video_codecs[nr_vcodecs].name = NULL; if(audio_codecs) audio_codecs[nr_acodecs].name = NULL; out: talloc_free(tmpmem); line=NULL; return 1; err_out_parse_error: mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"parse error"); err_out_print_linenum: PRINT_LINENUM; err_out: codecs_uninit_free(); talloc_free(tmpmem); line=NULL; line_num = 0; return 0; err_out_not_valid: mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"Codec is not defined correctly."); goto err_out_print_linenum; err_out_release_num: mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"This codecs.conf is too old and incompatible with this MPlayer release!"); goto err_out_print_linenum; }
static int get_token(int min, int max) { static int line_pos; int i; char c; if (max >= MAX_NR_TOKEN) { mp_tmsg(MSGT_CODECCFG,MSGL_ERR,"get_token(): max >= MAX_MR_TOKEN!"); goto out_eof; } memset(token, 0x00, sizeof(*token) * max); if (read_nextline) { if (!filetext.len) goto out_eof; struct bstr nextline = bstr_getline(filetext, &filetext); line = nextline.start; line[nextline.len - 1] = 0; line_pos = 0; ++line_num; read_nextline = 0; } for (i = 0; i < max; i++) { while (isspace(line[line_pos])) ++line_pos; if (line[line_pos] == '\0' || line[line_pos] == '#' || line[line_pos] == ';') { read_nextline = 1; if (i >= min) goto out_ok; goto out_eol; } token[i] = line + line_pos; c = line[line_pos]; if (c == '"' || c == '\'') { token[i]++; while (line[++line_pos] != c && line[line_pos]) /* NOTHING */; } else { for (/* NOTHING */; !isspace(line[line_pos]) && line[line_pos]; line_pos++) /* NOTHING */; } if (!line[line_pos]) { read_nextline = 1; if (i >= min - 1) goto out_ok; goto out_eol; } line[line_pos] = '\0'; line_pos++; } out_ok: return i; out_eof: read_nextline = 1; return RET_EOF; out_eol: return RET_EOL; }