17 GSList *srcpadtemplates;
18 GSList *sinkpadtemplates;
40 void print_match_list (gchar *prefix, int len, GSList *wordlist) {
41 GSList *words = wordlist;
44 if (!len || !strncmp((gchar *)(words->data), prefix, len))
45 printf("%s\n",(gchar *)(words->data));
46 words = g_slist_next (words);
50 int match_element (comp_element *element, gchar *name) {
51 return strcmp(element->name,name);
54 int main(int argc,char *argv[]) {
56 xmlNodePtr rootnode, elementnode, propnode, argnode;
57 GList *element_list = NULL;
58 comp_element *element;
59 GSList *element_names = NULL;
60 comp_argument *argument;
75 setlocale (LC_ALL, "");
78 fprintf(stderr,"gst-complete called with invalid arguments\n");
83 partial_word = argv[2];
85 partial_len = strlen(partial_word);
87 /***** Loading the completion information from the registry *****/
89 if (stat (GST_CACHE_DIR"/compreg.xml", &stat_buf) == 0) {
90 doc = xmlParseFile (GST_CACHE_DIR"/compreg.xml");
94 rootnode = doc->xmlRootNode;
96 elementnode = rootnode->xmlChildrenNode;
98 if (!strcmp(elementnode->name, "element")) {
99 element = g_new0(comp_element,1);
100 propnode = elementnode->xmlChildrenNode;
103 if (!strcmp(propnode->name, "name")) {
104 element->name = xmlNodeGetContent(propnode);
105 /* fprintf(stderr,element->name); */
106 } else if (!strcmp(propnode->name, "srcpad")) {
107 element->srcpads = g_slist_prepend(element->srcpads, xmlNodeGetContent(propnode));
108 /* fprintf(stderr,"."); */
109 } else if (!strcmp(propnode->name, "sinkpad")) {
110 element->sinkpads = g_slist_prepend(element->sinkpads, xmlNodeGetContent(propnode));
111 } else if (!strcmp(propnode->name, "srcpadtemplate")) {
112 element->srcpadtemplates = g_slist_prepend(element->srcpadtemplates, xmlNodeGetContent(propnode));
113 /* fprintf(stderr,"."); */
114 } else if (!strcmp(propnode->name, "sinkpad")) {
115 element->sinkpadtemplates = g_slist_prepend(element->sinkpadtemplates, xmlNodeGetContent(propnode));
116 } else if (!strcmp(propnode->name, "argument")) {
117 argument = g_new0(comp_argument,1);
118 argument->name = xmlNodeGetContent(propnode);
119 argument->type = ARG_INT;
121 /* walk through the values data */
122 argnode = propnode->xmlChildrenNode;
124 if (!strcmp(argnode->name, "filename")) {
125 argument->type = ARG_FILENAME;
126 } else if (!strcmp(argnode->name,"option")) {
127 argument->type = ARG_ENUM;
128 option = g_new0(enum_value,1);
129 sscanf(xmlNodeGetContent(argnode),"%d",&option->value);
130 argument->enums = g_slist_prepend (argument->enums, option);
132 argnode = argnode->next;
135 element->arguments = g_slist_prepend(element->arguments, argument);
138 propnode = propnode->next;
140 element_list = g_list_prepend(element_list, element);
141 element_names = g_slist_prepend(element_names, element->name);
143 elementnode = elementnode->next;
148 /***** Completion *****/
150 /* The bulk of the work is in deciding exactly which words are an option. */
152 /* if we're right at the beginning, with -launch in the first word */
153 if (strstr(prev_word,"-launch")) {
154 /* print out only elements with no sink pad or padtemplate */
155 elements = element_list;
157 element = (comp_element *)(elements->data);
158 if (!element->sinkpads && !element->sinkpadtemplates)
159 words = g_slist_prepend (words, element->name);
160 elements = g_list_next(elements);
164 /* if the previous word is a connection */
165 if (strchr(prev_word, '!')) {
166 /* print out oly elements with a sink pad or template */
167 elements = element_list;
169 element = (comp_element *)(elements->data);
170 if (element->sinkpads || element->sinkpadtemplates)
171 words = g_slist_prepend (words, element->name);
172 elements = g_list_next (elements);
176 /* if the partial word is an argument, and it's an enum */
177 if (strchr(prev_word,'=')) {
178 fprintf(stderr,"it's an arg, but dunno what element yet\n");
181 /* if the previous word is an element, we need to list both pads and arguments*/
182 if ((elements = g_list_find_custom(element_list, prev_word, (GCompareFunc)match_element))) {
183 element = elements->data;
184 /* zero the numpads list so we can count them */
188 pads = element->srcpads;
191 words = g_slist_prepend (words, g_strdup_printf("%s!",(gchar *)(pads->data)));
192 pads = g_slist_next (pads);
196 pads = element->srcpadtemplates;
199 word = g_strdup_printf("%s!",(gchar *)(pads->data));
200 if (!g_slist_find_custom(words,word,(GCompareFunc)strcmp))
201 words = g_slist_prepend (words, word);
202 pads = g_slist_next (pads);
205 /* if there is only one pad, add '!' to the list of completions */
207 words = g_slist_prepend (words, "!");
211 args = element->arguments;
213 argument = (comp_argument *)(args->data);
214 word = strstr(argument->name,"::")+2;
215 words = g_slist_prepend (words, g_strdup_printf("%s=",word));
216 words = g_slist_prepend (words, g_strdup_printf("%s=...",word));
217 args = g_slist_next (args);
222 /* The easy part is ouptuting the correct list of possibilities. */
223 print_match_list (partial_word, partial_len, words);