home *** CD-ROM | disk | FTP | other *** search
- /* randfile.c
- * MACHINE: RISC OS 3.60
- * LANGUAGE: Acorn C v5.06
- * LIBRARIES: OSLib
- * AUTHOR: Cy Booker <cy@cheepnis.demon.co.uk>
- * LICENCE: Freeware, copyright 1995
- */
-
- #include "randfile.h"
-
-
- #include <assert.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
-
-
- #include "OS:osgbpb.h"
- #include "OS:macros.h"
-
-
- #include "main.h"
- #include "strings.h"
-
-
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- static void scan_files(
- strings *s,
- const char *path);
-
-
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- */
-
- extern char *rand_file(
- const char *path,
- const char *history_file) {
- static const strings empty = {NULL, NULL, 0};
- strings history = empty;
- strings todo = empty;
- strings done = empty;
- node *node;
- char *file;
-
- assert(path);
- strings_read(&history, history_file);
- scan_files(&todo, path);
- if (todo.count == 0) {
- strings_clear(&done);
- strings_clear(&todo);
- return NULL;
- }
-
- while (todo.count > 0) {
- node = strings_get(&todo, rand() % todo.count);
- if (strings_find(&history, node->text) == NULL) {
- /*
- * add this node to the history
- */
- strings_remove(&todo, node);
- goto done;
- }
- strings_remove(&todo, node);
- strings_insert(&done, node);
- }
- /*
- * ok, special case, we've done all of them!
- */
- strings_clear(&history);
- node = strings_get(&done, rand() % done.count);
- assert(node);
- strings_remove(&done, node);
- done:
- assert(node);
- strings_insert(&history, node);
- strings_clear(&done);
- strings_clear(&todo);
- file = xmalloc(strlen(node->text) + 1);
- strcpy(file, node->text);
- strings_write(&history, history_file);
- strings_clear(&history);
- return file;
- }
-
-
-
- /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- * for now path must be a directory name without the '.'
- */
-
- static void scan_files(
- strings *s,
- const char *path) {
- int context = 0;
- int count;
- char buffer[512]; /* nice and big */
- const osgbpb_info_stamped *info;
- char *obj;
-
- assert(s);
- assert(path);
-
- do {
- context = osgbpb_dir_entries_info_stamped(
- path,
- (osgbpb_info_stamped_list *)buffer,
- sizeof(buffer) / sizeof(osgbpb_info_stamped),
- context,
- sizeof(buffer),
- NULL, /* all entries */
- &count);
- info = (const osgbpb_info_stamped *)buffer;
- for (; (count > 0); count--) {
- obj = xmalloc(strlen(path) + 1 + strlen(info->name) + 1);
- strcat(strcat(strcpy(obj, path), "."), info->name);
- switch (info->obj_type) {
- case fileswitch_IS_DIR:
- case fileswitch_IS_IMAGE:
- scan_files(s, obj);
- break;
-
- case fileswitch_IS_FILE:
- if (info->file_type == 0xc85) {
- strings_add(s, obj);
- }
- break;
- }
- free(obj);
- info = (const osgbpb_info_stamped *)
- (((const char *)info)
- + offsetof(osgbpb_info_stamped, name)
- + ALIGN(strlen(info->name) + 1));
- }
- } while (context != -1);
- }
-
-
-