+int
+parse_colon_separated_list(const char *paths, struct vect *vec)
+{
+ /* PATHS contains a colon-separated list of directories and
+ * files to load. It's modeled after shell PATH variable,
+ * which doesn't allow escapes. PYTHONPATH in CPython behaves
+ * the same way. So let's follow suit, it makes things easier
+ * to us. */
+
+ char *clone = strdup(paths);
+ if (clone == NULL) {
+ fprintf(stderr, "Couldn't parse argument %s: %s.\n",
+ paths, strerror(errno));
+ return -1;
+ }
+
+ /* It's undesirable to use strtok, because we want the string
+ * "a::b" to have three elements. */
+ char *tok = clone - 1;
+ char *end = clone + strlen(clone);
+ while (tok < end) {
+ ++tok;
+ size_t len = strcspn(tok, ":");
+ tok[len] = 0;
+
+ struct opt_F_t arg = {
+ .pathname = tok,
+ .own_pathname = tok == clone,
+ };
+ if (VECT_PUSHBACK(vec, &arg) < 0)
+ /* Presumably this is not a deal-breaker. */
+ fprintf(stderr, "Couldn't store component of %s: %s.\n",
+ paths, strerror(errno));
+
+ tok += len;
+ }
+
+ return 0;
+}
+
+void
+opt_F_destroy(struct opt_F_t *entry)
+{
+ if (entry == NULL)
+ return;
+ if (entry->own_pathname)
+ free(entry->pathname);
+}
+
+enum opt_F_kind
+opt_F_get_kind(struct opt_F_t *entry)
+{
+ if (entry->kind == OPT_F_UNKNOWN) {
+ struct stat st;
+ if (lstat(entry->pathname, &st) < 0) {
+ fprintf(stderr, "Couldn't stat %s: %s\n",
+ entry->pathname, strerror(errno));
+ entry->kind = OPT_F_BROKEN;
+ } else if (S_ISDIR(st.st_mode)) {
+ entry->kind = OPT_F_DIR;
+ } else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
+ entry->kind = OPT_F_FILE;
+ } else {
+ fprintf(stderr, "%s is neither a regular file, "
+ "nor a directory.\n", entry->pathname);
+ entry->kind = OPT_F_BROKEN;
+ }
+ }
+ assert(entry->kind != OPT_F_UNKNOWN);
+ return entry->kind;
+}
+