2 * Test program for PhysicsFS. May only work on Unix.
4 * Please see the file LICENSE.txt in the source's root directory.
6 * This file written by Ryan C. Gordon.
14 #if (defined __MWERKS__)
18 #if (defined PHYSFS_HAVE_READLINE)
20 #include <readline/readline.h>
21 #include <readline/history.h>
28 #define TEST_VERSION_MAJOR 1
29 #define TEST_VERSION_MINOR 1
30 #define TEST_VERSION_PATCH 1
32 static FILE *history_file = NULL;
33 static PHYSFS_uint32 do_buffer_size = 0;
35 static void output_versions(void)
37 PHYSFS_Version compiled;
38 PHYSFS_Version linked;
40 PHYSFS_VERSION(&compiled);
41 PHYSFS_getLinkedVersion(&linked);
43 printf("test_physfs version %d.%d.%d.\n"
44 " Compiled against PhysicsFS version %d.%d.%d,\n"
45 " and linked against %d.%d.%d.\n\n",
46 TEST_VERSION_MAJOR, TEST_VERSION_MINOR, TEST_VERSION_PATCH,
47 (int) compiled.major, (int) compiled.minor, (int) compiled.patch,
48 (int) linked.major, (int) linked.minor, (int) linked.patch);
49 } /* output_versions */
52 static void output_archivers(void)
54 const PHYSFS_ArchiveInfo **rc = PHYSFS_supportedArchiveTypes();
55 const PHYSFS_ArchiveInfo **i;
57 printf("Supported archive types:\n");
59 printf(" * Apparently, NONE!\n");
62 for (i = rc; *i != NULL; i++)
64 printf(" * %s: %s\n Written by %s.\n %s\n",
65 (*i)->extension, (*i)->description,
66 (*i)->author, (*i)->url);
71 } /* output_archivers */
74 static int cmd_quit(char *args)
80 static int cmd_init(char *args)
85 args[strlen(args) - 1] = '\0';
88 if (PHYSFS_init(args))
89 printf("Successful.\n");
91 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
97 static int cmd_deinit(char *args)
100 printf("Successful.\n");
102 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
108 static int cmd_addarchive(char *args)
110 char *ptr = strrchr(args, ' ');
111 int appending = atoi(ptr + 1);
120 /*printf("[%s], [%d]\n", args, appending);*/
122 if (PHYSFS_addToSearchPath(args, appending))
123 printf("Successful.\n");
125 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
128 } /* cmd_addarchive */
131 static int cmd_mount(char *args)
134 char *mntpoint = NULL;
140 ptr = strchr(args, '\"');
143 printf("missing string terminator in argument.\n");
150 ptr = strchr(args, ' ');
155 if (*mntpoint == '\"')
158 ptr = strchr(mntpoint, '\"');
161 printf("missing string terminator in argument.\n");
168 ptr = strchr(mntpoint, ' ');
171 appending = atoi(ptr + 1);
173 /*printf("[%s], [%s], [%d]\n", args, mntpoint, appending);*/
175 if (PHYSFS_mount(args, mntpoint, appending))
176 printf("Successful.\n");
178 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
184 static int cmd_removearchive(char *args)
189 args[strlen(args) - 1] = '\0';
192 if (PHYSFS_removeFromSearchPath(args))
193 printf("Successful.\n");
195 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
198 } /* cmd_removearchive */
201 static int cmd_enumerate(char *args)
208 args[strlen(args) - 1] = '\0';
211 rc = PHYSFS_enumerateFiles(args);
214 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
219 for (i = rc, file_count = 0; *i != NULL; i++, file_count++)
222 printf("\n total (%d) files.\n", file_count);
227 } /* cmd_enumerate */
230 static int cmd_getdirsep(char *args)
232 printf("Directory separator is [%s].\n", PHYSFS_getDirSeparator());
234 } /* cmd_getdirsep */
237 static int cmd_getlasterror(char *args)
239 printf("last error is [%s].\n", PHYSFS_getLastError());
241 } /* cmd_getlasterror */
244 static int cmd_getcdromdirs(char *args)
246 char **rc = PHYSFS_getCdRomDirs();
249 printf("Failure. Reason: [%s].\n", PHYSFS_getLastError());
254 for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++)
257 printf("\n total (%d) drives.\n", dir_count);
262 } /* cmd_getcdromdirs */
265 static int cmd_getsearchpath(char *args)
267 char **rc = PHYSFS_getSearchPath();
270 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
275 for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++)
278 printf("\n total (%d) directories.\n", dir_count);
283 } /* cmd_getcdromdirs */
286 static int cmd_getbasedir(char *args)
288 printf("Base dir is [%s].\n", PHYSFS_getBaseDir());
290 } /* cmd_getbasedir */
293 static int cmd_getuserdir(char *args)
295 printf("User dir is [%s].\n", PHYSFS_getUserDir());
297 } /* cmd_getuserdir */
300 static int cmd_getwritedir(char *args)
302 printf("Write dir is [%s].\n", PHYSFS_getWriteDir());
304 } /* cmd_getwritedir */
307 static int cmd_setwritedir(char *args)
312 args[strlen(args) - 1] = '\0';
315 if (PHYSFS_setWriteDir(args))
316 printf("Successful.\n");
318 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
321 } /* cmd_setwritedir */
324 static int cmd_permitsyms(char *args)
331 args[strlen(args) - 1] = '\0';
335 PHYSFS_permitSymbolicLinks(num);
336 printf("Symlinks are now %s.\n", num ? "permitted" : "forbidden");
338 } /* cmd_permitsyms */
341 static int cmd_setbuffer(char *args)
346 args[strlen(args) - 1] = '\0';
349 do_buffer_size = (unsigned int) atoi(args);
352 printf("Further tests will set a (%lu) size buffer.\n",
353 (unsigned long) do_buffer_size);
358 printf("Further tests will NOT use a buffer.\n");
362 } /* cmd_setbuffer */
365 static int cmd_stressbuffer(char *args)
372 args[strlen(args) - 1] = '\0';
377 printf("buffer must be greater than or equal to zero.\n");
383 printf("Stress testing with (%d) byte buffer...\n", num);
384 f = PHYSFS_openWrite("test.txt");
386 printf("Couldn't open test.txt for writing: %s.\n", PHYSFS_getLastError());
393 if (!PHYSFS_setBuffer(f, num))
395 printf("PHYSFS_setBuffer() failed: %s.\n", PHYSFS_getLastError());
397 PHYSFS_delete("test.txt");
401 strcpy(buf, "abcdefghijklmnopqrstuvwxyz0123456789");
402 srand((unsigned int) time(NULL));
404 for (i = 0; i < 10; i++)
406 for (j = 0; j < 10000; j++)
408 PHYSFS_uint32 right = 1 + (PHYSFS_uint32) (35.0 * rand() / (RAND_MAX + 1.0));
409 PHYSFS_uint32 left = 36 - right;
410 if (PHYSFS_write(f, buf, left, 1) != 1)
412 printf("PHYSFS_write() failed: %s.\n", PHYSFS_getLastError());
417 rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
420 if (!PHYSFS_flush(f))
422 printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
428 if (PHYSFS_write(f, buf + left, 1, right) != right)
430 printf("PHYSFS_write() failed: %s.\n", PHYSFS_getLastError());
435 rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
438 if (!PHYSFS_flush(f))
440 printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
447 if (!PHYSFS_flush(f))
449 printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
456 if (!PHYSFS_close(f))
458 printf("PHYSFS_close() failed: %s.\n", PHYSFS_getLastError());
459 return(1); /* oh well. */
462 printf(" ... test file written ...\n");
463 f = PHYSFS_openRead("test.txt");
466 printf("Failed to reopen stress file for reading: %s.\n", PHYSFS_getLastError());
470 if (!PHYSFS_setBuffer(f, num))
472 printf("PHYSFS_setBuffer() failed: %s.\n", PHYSFS_getLastError());
477 for (i = 0; i < 10; i++)
479 for (j = 0; j < 10000; j++)
481 PHYSFS_uint32 right = 1 + (PHYSFS_uint32) (35.0 * rand() / (RAND_MAX + 1.0));
482 PHYSFS_uint32 left = 36 - right;
483 if (PHYSFS_read(f, buf2, left, 1) != 1)
485 printf("PHYSFS_read() failed: %s.\n", PHYSFS_getLastError());
490 rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
493 if (!PHYSFS_flush(f))
495 printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
501 if (PHYSFS_read(f, buf2 + left, 1, right) != right)
503 printf("PHYSFS_read() failed: %s.\n", PHYSFS_getLastError());
508 rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
511 if (!PHYSFS_flush(f))
513 printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
519 if (memcmp(buf, buf2, 36) != 0)
521 printf("readback is mismatched on iterations (%d, %d).\n", i, j);
523 for (i = 0; i < 36; i++)
524 printf("%c", buf[i]);
528 for (i = 0; i < 36; i++)
529 printf("%c", buf2[i]);
536 if (!PHYSFS_flush(f))
538 printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
545 printf(" ... test file read ...\n");
548 printf("PHYSFS_eof() returned true! That's wrong.\n");
550 if (!PHYSFS_close(f))
552 printf("PHYSFS_close() failed: %s.\n", PHYSFS_getLastError());
553 return(1); /* oh well. */
556 PHYSFS_delete("test.txt");
557 printf("stress test completed successfully.\n");
562 } /* cmd_stressbuffer */
565 static int cmd_setsaneconfig(char *args)
576 ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; appName = ptr;
577 ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; arcExt = ptr;
578 ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; inclCD = atoi(arcExt);
579 arcsFirst = atoi(ptr);
581 if (strcmp(arcExt, "!") == 0)
584 if (PHYSFS_setSaneConfig(org, appName, arcExt, inclCD, arcsFirst))
585 printf("Successful.\n");
587 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
590 } /* cmd_setsaneconfig */
593 static int cmd_mkdir(char *args)
598 args[strlen(args) - 1] = '\0';
601 if (PHYSFS_mkdir(args))
602 printf("Successful.\n");
604 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
610 static int cmd_delete(char *args)
615 args[strlen(args) - 1] = '\0';
618 if (PHYSFS_delete(args))
619 printf("Successful.\n");
621 printf("Failure. reason: %s.\n", PHYSFS_getLastError());
627 static int cmd_getrealdir(char *args)
634 args[strlen(args) - 1] = '\0';
637 rc = PHYSFS_getRealDir(args);
639 printf("Found at [%s].\n", rc);
641 printf("Not found.\n");
644 } /* cmd_getrealdir */
647 static int cmd_exists(char *args)
654 args[strlen(args) - 1] = '\0';
657 rc = PHYSFS_exists(args);
658 printf("File %sexists.\n", rc ? "" : "does not ");
663 static int cmd_isdir(char *args)
670 args[strlen(args) - 1] = '\0';
673 rc = PHYSFS_isDirectory(args);
674 printf("File %s a directory.\n", rc ? "is" : "is NOT");
679 static int cmd_issymlink(char *args)
686 args[strlen(args) - 1] = '\0';
689 rc = PHYSFS_isSymbolicLink(args);
690 printf("File %s a symlink.\n", rc ? "is" : "is NOT");
692 } /* cmd_issymlink */
695 static int cmd_cat(char *args)
702 args[strlen(args) - 1] = '\0';
705 f = PHYSFS_openRead(args);
707 printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
712 if (!PHYSFS_setBuffer(f, do_buffer_size))
714 printf("failed to set file buffer. Reason: [%s].\n",
715 PHYSFS_getLastError());
726 rc = PHYSFS_read(f, buffer, 1, sizeof (buffer));
728 for (i = 0; i < rc; i++)
729 fputc((int) buffer[i], stdout);
731 if (rc < sizeof (buffer))
736 printf("\n (Error condition in reading. Reason: [%s])\n\n",
737 PHYSFS_getLastError());
749 static int cmd_filelength(char *args)
756 args[strlen(args) - 1] = '\0';
759 f = PHYSFS_openRead(args);
761 printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
764 PHYSFS_sint64 len = PHYSFS_fileLength(f);
766 printf("failed to determine length. Reason: [%s].\n", PHYSFS_getLastError());
768 printf(" (cast to int) %d bytes.\n", (int) len);
774 } /* cmd_filelength */
777 #define WRITESTR "The cat sat on the mat.\n\n"
779 static int cmd_append(char *args)
786 args[strlen(args) - 1] = '\0';
789 f = PHYSFS_openAppend(args);
791 printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
799 if (!PHYSFS_setBuffer(f, do_buffer_size))
801 printf("failed to set file buffer. Reason: [%s].\n",
802 PHYSFS_getLastError());
808 bw = strlen(WRITESTR);
809 rc = PHYSFS_write(f, WRITESTR, 1, bw);
812 printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
813 (int) rc, (int) bw, PHYSFS_getLastError());
817 printf("Successful.\n");
827 static int cmd_write(char *args)
834 args[strlen(args) - 1] = '\0';
837 f = PHYSFS_openWrite(args);
839 printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
847 if (!PHYSFS_setBuffer(f, do_buffer_size))
849 printf("failed to set file buffer. Reason: [%s].\n",
850 PHYSFS_getLastError());
856 bw = strlen(WRITESTR);
857 rc = PHYSFS_write(f, WRITESTR, 1, bw);
860 printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
861 (int) rc, (int) bw, PHYSFS_getLastError());
865 printf("Successful.\n");
875 static void modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
877 time_t t = (time_t) modtime;
878 char *str = ctime(&t);
879 strncpy(modstr, str, strsize);
880 modstr[strsize-1] = '\0';
884 static int cmd_getlastmodtime(char *args)
886 PHYSFS_sint64 rc = PHYSFS_getLastModTime(args);
888 printf("Failed to determine. Reason: [%s].\n", PHYSFS_getLastError());
892 modTimeToStr(rc, modstr, sizeof (modstr));
893 printf("Last modified: %s (%ld).\n", modstr, (long) rc);
897 } /* cmd_getLastModTime */
900 /* must have spaces trimmed prior to this call. */
901 static int count_args(const char *str)
908 for (; *str != '\0'; str++)
911 in_quotes = !in_quotes;
912 else if ((*str == ' ') && (!in_quotes))
922 static int cmd_help(char *args);
927 int (*func)(char *args);
932 static const command_info commands[] =
934 { "quit", cmd_quit, 0, NULL },
935 { "q", cmd_quit, 0, NULL },
936 { "help", cmd_help, 0, NULL },
937 { "init", cmd_init, 1, "<argv0>" },
938 { "deinit", cmd_deinit, 0, NULL },
939 { "addarchive", cmd_addarchive, 2, "<archiveLocation> <append>" },
940 { "mount", cmd_mount, 3, "<archiveLocation> <mntpoint> <append>" },
941 { "removearchive", cmd_removearchive, 1, "<archiveLocation>" },
942 { "enumerate", cmd_enumerate, 1, "<dirToEnumerate>" },
943 { "ls", cmd_enumerate, 1, "<dirToEnumerate>" },
944 { "getlasterror", cmd_getlasterror, 0, NULL },
945 { "getdirsep", cmd_getdirsep, 0, NULL },
946 { "getcdromdirs", cmd_getcdromdirs, 0, NULL },
947 { "getsearchpath", cmd_getsearchpath, 0, NULL },
948 { "getbasedir", cmd_getbasedir, 0, NULL },
949 { "getuserdir", cmd_getuserdir, 0, NULL },
950 { "getwritedir", cmd_getwritedir, 0, NULL },
951 { "setwritedir", cmd_setwritedir, 1, "<newWriteDir>" },
952 { "permitsymlinks", cmd_permitsyms, 1, "<1or0>" },
953 { "setsaneconfig", cmd_setsaneconfig, 5, "<org> <appName> <arcExt> <includeCdRoms> <archivesFirst>" },
954 { "mkdir", cmd_mkdir, 1, "<dirToMk>" },
955 { "delete", cmd_delete, 1, "<dirToDelete>" },
956 { "getrealdir", cmd_getrealdir, 1, "<fileToFind>" },
957 { "exists", cmd_exists, 1, "<fileToCheck>" },
958 { "isdir", cmd_isdir, 1, "<fileToCheck>" },
959 { "issymlink", cmd_issymlink, 1, "<fileToCheck>" },
960 { "cat", cmd_cat, 1, "<fileToCat>" },
961 { "filelength", cmd_filelength, 1, "<fileToCheck>" },
962 { "append", cmd_append, 1, "<fileToAppend>" },
963 { "write", cmd_write, 1, "<fileToCreateOrTrash>" },
964 { "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>" },
965 { "setbuffer", cmd_setbuffer, 1, "<bufferSize>" },
966 { "stressbuffer", cmd_stressbuffer, 1, "<bufferSize>" },
967 { NULL, NULL, -1, NULL }
971 static void output_usage(const char *intro, const command_info *cmdinfo)
973 if (cmdinfo->argcount == 0)
974 printf("%s \"%s\" (no arguments)\n", intro, cmdinfo->cmd);
976 printf("%s \"%s %s\"\n", intro, cmdinfo->cmd, cmdinfo->usage);
980 static int cmd_help(char *args)
982 const command_info *i;
984 printf("Commands:\n");
985 for (i = commands; i->cmd != NULL; i++)
986 output_usage(" -", i);
989 } /* output_cmd_help */
992 static void trim_command(const char *orig, char *copy)
995 char *writeptr = copy;
999 for (i = orig; *i != '\0'; i++)
1003 if ((*(i + 1) != ' ') && (*(i + 1) != '\0'))
1005 if ((have_first) && (!spacecount))
1025 printf("\n command is [%s].\n", copy);
1027 } /* trim_command */
1030 static int process_command(char *complete_cmd)
1032 const command_info *i;
1037 if (complete_cmd == NULL) /* can happen if user hits CTRL-D, etc. */
1043 cmd_copy = (char *) malloc(strlen(complete_cmd) + 1);
1044 if (cmd_copy == NULL)
1046 printf("\n\n\nOUT OF MEMORY!\n\n\n");
1050 trim_command(complete_cmd, cmd_copy);
1051 args = strchr(cmd_copy, ' ');
1058 if (cmd_copy[0] != '\0')
1060 for (i = commands; i->cmd != NULL; i++)
1062 if (strcmp(i->cmd, cmd_copy) == 0)
1064 if ((i->argcount >= 0) && (count_args(args) != i->argcount))
1065 output_usage("usage:", i);
1073 printf("Unknown command. Enter \"help\" for instructions.\n");
1075 #if (defined PHYSFS_HAVE_READLINE)
1076 add_history(complete_cmd);
1079 fprintf(history_file, "%s\n", complete_cmd);
1080 fflush(history_file);
1088 } /* process_command */
1091 static void open_history_file(void)
1093 #if (defined PHYSFS_HAVE_READLINE)
1095 const char *envr = getenv("TESTPHYSFS_HISTORY");
1100 strcpy(envr, PHYSFS_getUserDir());
1101 strcat(envr, ".testphys_history");
1104 if (access(envr, F_OK) == 0)
1107 FILE *f = fopen(envr, "r");
1111 "Could not open history file [%s] for reading!\n"
1112 " Will not have past history available.\n\n",
1119 fgets(buf, sizeof (buf), f);
1120 if (buf[strlen(buf) - 1] == '\n')
1121 buf[strlen(buf) - 1] = '\0';
1128 history_file = fopen(envr, "ab");
1132 "Could not open history file [%s] for appending!\n"
1133 " Will not be able to record this session's history.\n\n",
1137 } /* open_history_file */
1140 int main(int argc, char **argv)
1145 #if (defined __MWERKS__)
1146 extern tSIOUXSettings SIOUXSettings;
1147 SIOUXSettings.asktosaveonclose = 0;
1148 SIOUXSettings.autocloseonquit = 1;
1149 SIOUXSettings.rows = 40;
1150 SIOUXSettings.columns = 120;
1155 if (!PHYSFS_init(argv[0]))
1157 printf("PHYSFS_init() failed!\n reason: %s.\n", PHYSFS_getLastError());
1164 open_history_file();
1166 printf("Enter commands. Enter \"help\" for instructions.\n");
1170 #if (defined PHYSFS_HAVE_READLINE)
1171 buf = readline("> ");
1174 buf = (char *) malloc(512);
1175 memset(buf, '\0', 512);
1177 for (i = 0; i < 511; i++)
1179 int ch = fgetc(stdin);
1182 strcpy(buf, "quit");
1185 else if ((ch == '\n') || (ch == '\r'))
1190 else if (ch == '\b')
1202 rc = process_command(buf);
1207 if (!PHYSFS_deinit())
1208 printf("PHYSFS_deinit() failed!\n reason: %s.\n", PHYSFS_getLastError());
1211 fclose(history_file);
1214 printf("\n\ntest_physfs written by ryan c. gordon.\n");
1215 printf(" it makes you shoot teh railgun bettar.\n");
1221 /* end of test_physfs.c ... */