Esempio n. 1
0
File: cue.c Progetto: ThreeGe/mpv
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;
}
Esempio n. 2
0
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;
    }
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}