5 #include <gst/gstconfig.h>
14 GSList *srcpadtemplates;
15 GSList *sinkpadtemplates;
37 void print_match_list (gchar *prefix, int len, GSList *wordlist) {
38 GSList *words = wordlist;
41 if (!len || !strncmp((gchar *)(words->data), prefix, len))
42 printf("%s\n",(gchar *)(words->data));
43 words = g_slist_next (words);
47 int match_element (comp_element *element, gchar *name) {
48 return strcmp(element->name,name);
51 int main(int argc,char *argv[]) {
53 xmlNodePtr rootnode, elementnode, propnode, argnode;
54 GList *element_list = NULL;
55 comp_element *element;
56 GSList *element_names = NULL;
57 comp_argument *argument;
60 gchar *prev_word = argv[3];
61 gchar *partial_word = argv[2];
72 partial_len = strlen(partial_word);
74 /***** Loading the completion information from the registry *****/
76 if (stat (GST_CONFIG_DIR"/compreg.xml", &stat_buf) == 0) {
77 doc = xmlParseFile (GST_CONFIG_DIR"/compreg.xml");
81 rootnode = doc->xmlRootNode;
83 elementnode = rootnode->xmlChildrenNode;
85 if (!strcmp(elementnode->name, "element")) {
86 element = g_new0(comp_element,1);
87 propnode = elementnode->xmlChildrenNode;
90 if (!strcmp(propnode->name, "name")) {
91 element->name = xmlNodeGetContent(propnode);
92 /* fprintf(stderr,element->name); */
93 } else if (!strcmp(propnode->name, "srcpad")) {
94 element->srcpads = g_slist_prepend(element->srcpads, xmlNodeGetContent(propnode));
95 /* fprintf(stderr,"."); */
96 } else if (!strcmp(propnode->name, "sinkpad")) {
97 element->sinkpads = g_slist_prepend(element->sinkpads, xmlNodeGetContent(propnode));
98 } else if (!strcmp(propnode->name, "srcpadtemplate")) {
99 element->srcpadtemplates = g_slist_prepend(element->srcpadtemplates, xmlNodeGetContent(propnode));
100 /* fprintf(stderr,"."); */
101 } else if (!strcmp(propnode->name, "sinkpad")) {
102 element->sinkpadtemplates = g_slist_prepend(element->sinkpadtemplates, xmlNodeGetContent(propnode));
103 } else if (!strcmp(propnode->name, "argument")) {
104 argument = g_new0(comp_argument,1);
105 argument->name = xmlNodeGetContent(propnode);
106 argument->type = ARG_INT;
108 /* walk through the values data */
109 argnode = propnode->xmlChildrenNode;
111 if (!strcmp(argnode->name, "filename")) {
112 argument->type = ARG_FILENAME;
113 } else if (!strcmp(argnode->name,"option")) {
114 argument->type = ARG_ENUM;
115 option = g_new0(enum_value,1);
116 sscanf(xmlNodeGetContent(argnode),"%d",&option->value);
117 argument->enums = g_slist_prepend (argument->enums, option);
119 argnode = argnode->next;
122 element->arguments = g_slist_prepend(element->arguments, argument);
125 propnode = propnode->next;
127 element_list = g_list_prepend(element_list, element);
128 element_names = g_slist_prepend(element_names, element->name);
130 elementnode = elementnode->next;
135 /***** Completion *****/
137 /* The bulk of the work is in deciding exactly which words are an option. */
139 /* if we're right at the beginning, with -launch in the first word */
140 if (strstr(prev_word,"-launch")) {
141 /* print out only elements with no sink pad or padtemplate */
142 elements = element_list;
144 element = (comp_element *)(elements->data);
145 if (!element->sinkpads && !element->sinkpadtemplates)
146 words = g_slist_prepend (words, element->name);
147 elements = g_list_next(elements);
151 /* if the previous word is a connection */
152 if (strchr(prev_word, '!')) {
153 /* print out oly elements with a sink pad or template */
154 elements = element_list;
156 element = (comp_element *)(elements->data);
157 if (element->sinkpads || element->sinkpadtemplates)
158 words = g_slist_prepend (words, element->name);
159 elements = g_list_next (elements);
163 /* if the partial word is an argument, and it's an enum */
164 if (strchr(prev_word,'=')) {
165 fprintf(stderr,"it's an arg, but dunno what element yet\n");
168 /* if the previous word is an element, we need to list both pads and arguments*/
169 if ((elements = g_list_find_custom(element_list, prev_word, (GCompareFunc)match_element))) {
170 element = elements->data;
171 /* zero the numpads list so we can count them */
175 pads = element->srcpads;
178 words = g_slist_prepend (words, g_strdup_printf("%s!",(gchar *)(pads->data)));
179 pads = g_slist_next (pads);
183 pads = element->srcpadtemplates;
186 word = g_strdup_printf("%s!",(gchar *)(pads->data));
187 if (!g_slist_find_custom(words,word,(GCompareFunc)strcmp))
188 words = g_slist_prepend (words, word);
189 pads = g_slist_next (pads);
192 /* if there is only one pad, add '!' to the list of completions */
194 words = g_slist_prepend (words, "!");
198 args = element->arguments;
200 argument = (comp_argument *)(args->data);
201 word = strstr(argument->name,"::")+2;
202 words = g_slist_prepend (words, g_strdup_printf("%s=",word));
203 words = g_slist_prepend (words, g_strdup_printf("%s=...",word));
204 args = g_slist_next (args);
209 /* The easy part is ouptuting the correct list of possibilities. */
210 print_match_list (partial_word, partial_len, words);