FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/textformat/tf_ini.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 44 52 84.6%
Functions: 4 5 80.0%
Branches: 20 29 69.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) The FFmpeg developers
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <limits.h>
22 #include <stdarg.h>
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 #include "avtextformat.h"
28
29 #include "libavutil/bprint.h"
30 #include "libavutil/opt.h"
31
32 #define writer_w8(wctx_, b_) (wctx_)->writer->writer->writer_w8((wctx_)->writer, b_)
33 #define writer_put_str(wctx_, str_) (wctx_)->writer->writer->writer_put_str((wctx_)->writer, str_)
34 #define writer_printf(wctx_, fmt_, ...) (wctx_)->writer->writer->writer_printf((wctx_)->writer, fmt_, __VA_ARGS__)
35
36 #define DEFINE_FORMATTER_CLASS(name) \
37 static const char *name##_get_name(void *ctx) \
38 { \
39 return #name ; \
40 } \
41 static const AVClass name##_class = { \
42 .class_name = #name, \
43 .item_name = name##_get_name, \
44 .option = name##_options \
45 }
46
47 /* Default output */
48
49 typedef struct DefaultContext {
50 const AVClass *class;
51 int nokey;
52 int noprint_wrappers;
53 int nested_section[SECTION_MAX_NB_LEVELS];
54 } DefaultContext;
55
56 /* INI format output */
57
58 typedef struct INIContext {
59 const AVClass *class;
60 int hierarchical;
61 } INIContext;
62
63 #undef OFFSET
64 #define OFFSET(x) offsetof(INIContext, x)
65
66 static const AVOption ini_options[] = {
67 {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
68 {"h", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1 },
69 {NULL},
70 };
71
72 DEFINE_FORMATTER_CLASS(ini);
73
74 724 static char *ini_escape_str(AVBPrint *dst, const char *src)
75 {
76 724 int i = 0;
77 724 char c = 0;
78
79
2/2
✓ Branch 0 taken 6141 times.
✓ Branch 1 taken 724 times.
6865 while (c = src[i++]) {
80
2/7
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 6127 times.
6141 switch (c) {
81 case '\b': av_bprintf(dst, "%s", "\\b"); break;
82 case '\f': av_bprintf(dst, "%s", "\\f"); break;
83 case '\n': av_bprintf(dst, "%s", "\\n"); break;
84 case '\r': av_bprintf(dst, "%s", "\\r"); break;
85 case '\t': av_bprintf(dst, "%s", "\\t"); break;
86 14 case '\\':
87 case '#' :
88 case '=' :
89 14 case ':' : av_bprint_chars(dst, '\\', 1);
90 6141 default:
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6141 times.
6141 if ((unsigned char)c < 32)
92 av_bprintf(dst, "\\x00%02x", c & 0xff);
93 else
94 6141 av_bprint_chars(dst, c, 1);
95 6141 break;
96 }
97 }
98 724 return dst->str;
99 }
100
101 42 static void ini_print_section_header(AVTextFormatContext *wctx, const void *data)
102 {
103 42 INIContext *ini = wctx->priv;
104 42 AVBPrint *buf = &wctx->section_pbuf[wctx->level];
105 42 const struct AVTextFormatSection *section = wctx->section[wctx->level];
106 84 const struct AVTextFormatSection *parent_section = wctx->level ?
107
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 1 times.
42 wctx->section[wctx->level-1] : NULL;
108
109 42 av_bprint_clear(buf);
110
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 41 times.
42 if (!parent_section) {
111 1 writer_put_str(wctx, "# ffprobe output\n\n");
112 1 return;
113 }
114
115
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 3 times.
41 if (wctx->nb_item[wctx->level-1])
116 38 writer_w8(wctx, '\n');
117
118 41 av_bprintf(buf, "%s", wctx->section_pbuf[wctx->level-1].str);
119
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (ini->hierarchical ||
120 !(section->flags & (AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY|AV_TEXTFORMAT_SECTION_FLAG_IS_WRAPPER))) {
121
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 3 times.
41 av_bprintf(buf, "%s%s", buf->str[0] ? "." : "", wctx->section[wctx->level]->name);
122
123
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 10 times.
41 if (parent_section->flags & AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY) {
124 62 int n = parent_section->flags & AV_TEXTFORMAT_SECTION_FLAG_NUMBERING_BY_TYPE ?
125
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 3 times.
31 wctx->nb_item_type[wctx->level-1][section->id] :
126 3 wctx->nb_item[wctx->level-1];
127 31 av_bprintf(buf, ".%d", n);
128 }
129 }
130
131
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 2 times.
41 if (!(section->flags & (AV_TEXTFORMAT_SECTION_FLAG_IS_ARRAY|AV_TEXTFORMAT_SECTION_FLAG_IS_WRAPPER)))
132 39 writer_printf(wctx, "[%s]\n", buf->str);
133 }
134
135 362 static void ini_print_str(AVTextFormatContext *wctx, const char *key, const char *value)
136 {
137 AVBPrint buf;
138
139 362 av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
140 362 writer_printf(wctx, "%s=", ini_escape_str(&buf, key));
141 362 av_bprint_clear(&buf);
142 362 writer_printf(wctx, "%s\n", ini_escape_str(&buf, value));
143 362 av_bprint_finalize(&buf, NULL);
144 362 }
145
146 316 static void ini_print_int(AVTextFormatContext *wctx, const char *key, int64_t value)
147 {
148 316 writer_printf(wctx, "%s=%"PRId64"\n", key, value);
149 316 }
150
151 const AVTextFormatter avtextformatter_ini = {
152 .name = "ini",
153 .priv_size = sizeof(INIContext),
154 .print_section_header = ini_print_section_header,
155 .print_integer = ini_print_int,
156 .print_string = ini_print_str,
157 .flags = AV_TEXTFORMAT_FLAG_SUPPORTS_OPTIONAL_FIELDS|AV_TEXTFORMAT_FLAG_SUPPORTS_MIXED_ARRAY_CONTENT,
158 .priv_class = &ini_class,
159 };
160