configure: fetch a specific revision of FFmpeg.
[vaapi:challenzhous-mplayer.git] / m_struct.c
1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 /// \file
20 /// \ingroup OptionsStruct
21
22 #include "config.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "m_option.h"
28 #include "m_struct.h"
29 #include "mp_msg.h"
30
31 const m_option_t*
32 m_struct_get_field(const m_struct_t* st,const char* f) {
33   int i;
34
35   for(i = 0 ; st->fields[i].name ; i++) {
36     if(strcasecmp(st->fields[i].name,f) == 0)
37       return &st->fields[i];
38   }
39   return NULL;
40 }
41
42 void*
43 m_struct_alloc(const m_struct_t* st) {
44   int i;
45   void* r;
46
47   if(!st->defaults) {
48     mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Struct %s needs defaults\n",st->name);
49     return NULL;
50   }
51   // Check the struct fields
52   for(i = 0 ; st->fields[i].name ; i++) {
53     if(st->fields[i].type->flags & M_OPT_TYPE_INDIRECT) {
54       mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Struct %s->%s: Option types with the indirect flag are forbidden.\n",st->name,st->fields[i].name);
55       return NULL;
56     }
57   }
58
59   r = calloc(1,st->size);
60   memcpy(r,st->defaults,st->size);
61
62   for(i = 0 ; st->fields[i].name ; i++) {
63     if(st->fields[i].type->flags & M_OPT_TYPE_DYNAMIC)
64       memset(M_ST_MB_P(r,st->fields[i].p),0,st->fields[i].type->size);
65     m_option_copy(&st->fields[i],M_ST_MB_P(r,st->fields[i].p),M_ST_MB_P(st->defaults,st->fields[i].p));
66   }
67   return r;
68 }
69
70 int
71 m_struct_set(const m_struct_t* st, void* obj, const char* field, const char* param) {
72   const m_option_t* f = m_struct_get_field(st,field);
73
74   if(!f) {
75     mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Struct %s doesn't have any %s field\n",
76            st->name,field);
77     return 0;
78   }
79
80   if(f->type->parse(f,field,param,M_ST_MB_P(obj,f->p),M_CONFIG_FILE) < 0) {
81     mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Struct %s, field %s parsing error: %s\n",
82            st->name,field,param);
83     return 0;
84   }
85
86   return 1;
87 }
88
89 void
90 m_struct_reset(const m_struct_t* st, void* obj, const char* field) {
91   const m_option_t* f;
92
93   if(!field) { // Reset all options
94     int i;
95     for(i = 0 ; st->fields[i].name ; i++)
96       m_option_copy(&st->fields[i],M_ST_MB_P(obj,st->fields[i].p),M_ST_MB_P(st->defaults,st->fields[i].p));
97     return;
98   }
99
100   // Only one
101   f = m_struct_get_field(st,field);
102   if(!f) {
103     mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Struct %s doesn't have any %s field\n",
104            st->name,field);
105     return;
106   }
107   m_option_copy(f,M_ST_MB_P(obj,f->p),M_ST_MB_P(st->defaults,f->p));
108 }
109
110 /// Free an allocated struct
111 void
112 m_struct_free(const m_struct_t* st, void* obj) {
113   int i;
114
115   for(i = 0 ; st->fields[i].name ; i++)
116     m_option_free(&st->fields[i],M_ST_MB_P(obj,st->fields[i].p));
117   free(obj);
118 }
119
120 void*
121 m_struct_copy(const m_struct_t* st, void* obj) {
122   void* r = malloc(st->size);
123   int i;
124
125   memcpy(r,obj,st->size);
126   for(i = 0 ; st->fields[i].name ; i++) {
127     if(st->fields[i].type->flags & M_OPT_TYPE_DYNAMIC)
128       memset(M_ST_MB_P(r,st->fields[i].p),0,st->fields[i].type->size);
129     m_option_copy(&st->fields[i],M_ST_MB_P(r,st->fields[i].p),M_ST_MB_P(obj,st->fields[i].p));
130   }
131
132   return r;
133 }