+struct launchparam {
+ int port;
+ const char *secret;
+ const char *datadir;
+};
+
+static char **instantiate_arguments(const char **args, struct af_launch_desc *desc, struct launchparam *params)
+{
+ const char **iter, *p, *v;
+ char *data, **result, port[20], width[20], height[20], mini[3], c;
+ int n, s, x;
+
+ /* init */
+ mini[0] = '%';
+ mini[2] = 0;
+
+ /* loop that either compute the size and build the result */
+ n = s = x = 0;
+ for (;;) {
+ iter = args;
+ n = 0;
+ while (*iter) {
+ p = *iter++;
+ if (x)
+ result[n] = data;
+ n++;
+ while((c = *p++) != 0) {
+ if (c != '%') {
+ if (x)
+ *data++ = c;
+ else
+ s++;
+ } else {
+ c = *p++;
+ switch (c) {
+ case 'I': v = FWK_ICON_DIR; break;
+ case 'P': if(!x) sprintf(port, "%d", params->port); v = port; break;
+ case 'S': v = params->secret; break;
+ case 'D': v = params->datadir; break;
+ case 'r': v = desc->path; break;
+ case 'h': v = desc->home; break;
+ case 't': v = desc->tag; break;
+ case 'a': v = desc->appid; break;
+ case 'c': v = desc->content; break;
+ case 'm': v = desc->type; break;
+ case 'n': v = desc->name; break;
+ case 'p': v = "" /*desc->plugins*/; break;
+ case 'W': if(!x) sprintf(width, "%d", desc->width); v = width; break;
+ case 'H': if(!x) sprintf(height, "%d", desc->height); v = height; break;
+ case '%': c = 0;
+ default: mini[1] = c; v = mini; break;
+ }
+ if (x)
+ data = stpcpy(data, v);
+ else
+ s += strlen(v);
+ }
+ }
+ if (x)
+ *data++ = 0;
+ else
+ s++;
+ }
+ if (x) {
+ result[n] = NULL;
+ return result;
+ }
+ /* allocation */
+ result = malloc((n+1)*sizeof(char*) + s);
+ if (result == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ data = (char*)(&result[n + 1]);
+ x = 1;
+ }
+}
+