18 GSList *srcpadtemplates;
19 GSList *sinkpadtemplates;
48 print_match_list (gchar * prefix, int len, GSList * wordlist)
50 GSList *words = wordlist;
53 if (!len || !strncmp ((gchar *) (words->data), prefix, len))
54 printf ("%s\n", (gchar *) (words->data));
55 words = g_slist_next (words);
60 match_element (comp_element * element, gchar * name)
62 return strcmp (element->name, name);
66 main (int argc, char *argv[])
69 xmlNodePtr rootnode, elementnode, propnode, argnode;
70 GList *element_list = NULL;
71 comp_element *element;
72 GSList *element_names = NULL;
73 comp_argument *argument;
88 setlocale (LC_ALL, "");
91 fprintf (stderr, "gst-complete called with invalid arguments\n");
96 partial_word = argv[2];
98 partial_len = strlen (partial_word);
100 /***** Loading the completion information from the registry *****/
102 if (stat (GST_CACHE_DIR "/compreg.xml", &stat_buf) == 0) {
103 doc = xmlParseFile (GST_CACHE_DIR "/compreg.xml");
107 rootnode = doc->xmlRootNode;
109 elementnode = rootnode->xmlChildrenNode;
110 while (elementnode) {
111 if (!strcmp (elementnode->name, "element")) {
112 element = g_new0 (comp_element, 1);
113 propnode = elementnode->xmlChildrenNode;
116 if (!strcmp (propnode->name, "name")) {
117 element->name = xmlNodeGetContent (propnode);
118 /* fprintf(stderr,element->name); */
119 } else if (!strcmp (propnode->name, "srcpad")) {
121 g_slist_prepend (element->srcpads, xmlNodeGetContent (propnode));
122 /* fprintf(stderr,"."); */
123 } else if (!strcmp (propnode->name, "sinkpad")) {
125 g_slist_prepend (element->sinkpads, xmlNodeGetContent (propnode));
126 } else if (!strcmp (propnode->name, "srcpadtemplate")) {
127 element->srcpadtemplates =
128 g_slist_prepend (element->srcpadtemplates,
129 xmlNodeGetContent (propnode));
130 /* fprintf(stderr,"."); */
131 } else if (!strcmp (propnode->name, "sinkpad")) {
132 element->sinkpadtemplates =
133 g_slist_prepend (element->sinkpadtemplates,
134 xmlNodeGetContent (propnode));
135 } else if (!strcmp (propnode->name, "argument")) {
136 argument = g_new0 (comp_argument, 1);
137 argument->name = xmlNodeGetContent (propnode);
138 argument->type = ARG_INT;
140 /* walk through the values data */
141 argnode = propnode->xmlChildrenNode;
143 if (!strcmp (argnode->name, "filename")) {
144 argument->type = ARG_FILENAME;
145 } else if (!strcmp (argnode->name, "option")) {
146 argument->type = ARG_ENUM;
147 option = g_new0 (enum_value, 1);
148 sscanf (xmlNodeGetContent (argnode), "%d", &option->value);
149 argument->enums = g_slist_prepend (argument->enums, option);
151 argnode = argnode->next;
154 element->arguments = g_slist_prepend (element->arguments, argument);
157 propnode = propnode->next;
159 element_list = g_list_prepend (element_list, element);
160 element_names = g_slist_prepend (element_names, element->name);
162 elementnode = elementnode->next;
167 /***** Completion *****/
169 /* The bulk of the work is in deciding exactly which words are an option. */
171 /* if we're right at the beginning, with -launch in the first word */
172 if (strstr (prev_word, "-launch")) {
173 /* print out only elements with no sink pad or padtemplate */
174 elements = element_list;
176 element = (comp_element *) (elements->data);
177 if (!element->sinkpads && !element->sinkpadtemplates)
178 words = g_slist_prepend (words, element->name);
179 elements = g_list_next (elements);
183 /* if the previous word is a connection */
184 if (strchr (prev_word, '!')) {
185 /* print out oly elements with a sink pad or template */
186 elements = element_list;
188 element = (comp_element *) (elements->data);
189 if (element->sinkpads || element->sinkpadtemplates)
190 words = g_slist_prepend (words, element->name);
191 elements = g_list_next (elements);
195 /* if the partial word is an argument, and it's an enum */
196 if (strchr (prev_word, '=')) {
197 fprintf (stderr, "it's an arg, but dunno what element yet\n");
200 /* if the previous word is an element, we need to list both pads and arguments */
202 g_list_find_custom (element_list, prev_word,
203 (GCompareFunc) match_element))) {
204 element = elements->data;
205 /* zero the numpads list so we can count them */
209 pads = element->srcpads;
213 g_slist_prepend (words, g_strdup_printf ("%s!",
214 (gchar *) (pads->data)));
215 pads = g_slist_next (pads);
219 pads = element->srcpadtemplates;
222 word = g_strdup_printf ("%s!", (gchar *) (pads->data));
223 if (!g_slist_find_custom (words, word, (GCompareFunc) strcmp))
224 words = g_slist_prepend (words, word);
225 pads = g_slist_next (pads);
228 /* if there is only one pad, add '!' to the list of completions */
230 words = g_slist_prepend (words, "!");
234 args = element->arguments;
236 argument = (comp_argument *) (args->data);
237 word = strstr (argument->name, "::") + 2;
238 words = g_slist_prepend (words, g_strdup_printf ("%s=", word));
239 words = g_slist_prepend (words, g_strdup_printf ("%s=...", word));
240 args = g_slist_next (args);
245 /* The easy part is ouptuting the correct list of possibilities. */
246 print_match_list (partial_word, partial_len, words);