+struct confread {
+ const char *filepath;
+ FILE *file;
+ int lineno;
+ int index;
+ int length;
+ char buffer[4096];
+};
+
+static void dump_launchers(struct launchers *launchs)
+{
+ int i, j, k;
+ for (i = 0 ; i < launchs->count ; i++) {
+ printf("%s\n", launchs->descs[i].type);
+ for ( j = 0 ; j < 2 ; j++)
+ if (launchs->descs[i].execs[j] != NULL) {
+ for (k = 0 ; launchs->descs[i].execs[j][k] != NULL ; k++)
+ printf(" %s", launchs->descs[i].execs[j][k]);
+ printf("\n");
+ }
+ }
+}
+
+static int next_token(struct confread *cread)
+{
+ cread->index += cread->length + strspn(&cread->buffer[cread->index + cread->length], separators);
+ cread->length = strcspn(&cread->buffer[cread->index], separators);
+ return cread->length;
+}
+
+static int read_line(struct confread *cread)
+{
+ while (fgets(cread->buffer, sizeof cread->buffer, cread->file) != NULL) {
+ cread->lineno++;
+ cread->index = strspn(cread->buffer, separators);
+ if (cread->buffer[cread->index] && cread->buffer[cread->index] != '#') {
+ cread->length = strcspn(&cread->buffer[cread->index], separators);
+ assert(cread->length > 0);
+ return cread->length;
+ }
+ }
+ if (ferror(cread->file)) {
+ ERROR("%s:%d: error while reading, %m", cread->filepath, cread->lineno);
+ return -1;
+ }
+ return 0;
+}
+
+static char *dup_token(struct confread *cread)
+{
+ assert(cread->length);
+ return strndup(&cread->buffer[cread->index], cread->length);
+}
+
+static char **dup_tokens_vector(struct confread *cread)
+{
+ int index0, length0;
+ char **vector, *args;
+ int count, length;
+
+ /* record origin */
+ index0 = cread->index;
+ length0 = cread->length;
+
+ /* count */
+ count = 0;
+ length = 0;
+ while(cread->length) {
+ count++;
+ length += cread->length;
+ next_token(cread);
+ }
+
+ /* allocates */
+ cread->index = index0;
+ cread->length = length0;
+ vector = malloc(length + count + (count + 1) * sizeof(char*));
+ if (vector == NULL)
+ return NULL;
+
+ /* copies */
+ args = (char*)(vector + count + 1);
+ count = 0;
+ while(cread->length) {
+ vector[count++] = args;
+ memcpy(args, &cread->buffer[cread->index], cread->length);
+ args += cread->length;
+ *args++ = 0;
+ next_token(cread);
+ }
+ vector[count] = NULL;
+ cread->index = index0;
+ cread->length = length0;
+ return vector;
+}
+
+static int read_type(struct confread *cread)