]> granicus.if.org Git - php/commitdiff
- Add initial virtual_getcwd() and virtual_chdir() for discussing with the
authorAndi Gutmans <andi@php.net>
Thu, 16 Mar 2000 16:54:42 +0000 (16:54 +0000)
committerAndi Gutmans <andi@php.net>
Thu, 16 Mar 2000 16:54:42 +0000 (16:54 +0000)
  rest of the folks

main/php_virtual_cwd.c [new file with mode: 0644]

diff --git a/main/php_virtual_cwd.c b/main/php_virtual_cwd.c
new file mode 100644 (file)
index 0000000..168067d
--- /dev/null
@@ -0,0 +1,112 @@
+#include <string.h>
+#include <stdio.h>
+
+typedef unsigned int uint;
+
+#if WINDOWS
+# define IS_SLASH(c)   ((c) == '/' || (c) == '\\')
+# define DEFAULT_SLASH '\\'
+# define TOKENIZER_STRING "/\\"
+#else
+# define IS_SLASH(c)   ((c) == '/')
+# define DEFAULT_SLASH '/'
+# define TOKENIZER_STRING "/"
+#endif
+
+
+
+typedef struct _cwd_state {
+       char *cwd;
+       uint cwd_length;
+} cwd_state;
+
+char *virtual_getcwd(cwd_state *state, uint *length)
+{
+       if (state->cwd_length == 0) {
+               char *retval;
+
+               *length = 1;
+               retval = (char *) malloc(2);
+               retval[0] = DEFAULT_SLASH;
+               retval[1] = '\0';       
+               return retval;
+       }
+
+#if WINDOWS
+       /* If we have something like C: */
+       if (state->cwd_length == 2 && state->cwd[state->cwd_length-1] == ':') {
+               char *retval;
+
+               *length = state->cwd_length+1;
+               retval = (char *) malloc(*length+1);
+               memcpy(retval, state->cwd, *length);
+               retval[*length-1] = DEFAULT_SLASH;
+               retval[*length] = '\0';
+               return retval;
+       }
+#endif
+       *length = state->cwd_length;
+       return strdup(state->cwd);
+}
+
+void virtual_chdir(cwd_state *state, char *path)
+{
+       uint path_length = strlen(path);
+       char *ptr = path;
+       uint ptr_length;
+
+       if (path_length == 0) {
+               return;
+       }
+#if WINDOWS
+       /* Full path includes anything starting with C: */
+       if (IS_SLASH(*ptr) || (path_length >= 2 && path[1] == ':'))
+#else
+       if (IS_SLASH(*ptr))
+#endif
+       {
+               state->cwd = (char *) realloc(state->cwd, 1);
+               state->cwd[0] = '\0';
+               state->cwd_length = 0;
+       }       
+
+       ptr = strtok(path, TOKENIZER_STRING);
+       while(ptr) {
+               ptr_length = strlen(ptr);       
+               if (ptr_length == 2 && !memcmp(ptr, "..", 2)) {
+                       while (!IS_SLASH(state->cwd[state->cwd_length-1])) {
+                               state->cwd[--(state->cwd_length)] = '\0';
+                       }
+                       state->cwd[--(state->cwd_length)] = '\0';
+               } else if (ptr_length == 1 && *ptr == '.') {
+                       /* Do nothing */
+               } else {
+                       state->cwd = (char *) realloc(state->cwd, state->cwd_length+ptr_length+1+1);
+                       state->cwd[state->cwd_length] = DEFAULT_SLASH;
+                       memcpy(&state->cwd[state->cwd_length+1], ptr, ptr_length+1);
+                       state->cwd_length += (ptr_length+1);
+               }
+               ptr = strtok(NULL, TOKENIZER_STRING);
+       }
+}
+
+main()
+{
+       cwd_state state;
+       uint length;
+       
+       state.cwd = strdup("");
+       state.cwd_length = 0;
+
+       printf("%s\n", virtual_getcwd(&state, &length));
+       virtual_chdir(&state, strdup("/foo/barbara"));
+       printf("%s\n", virtual_getcwd(&state, &length));
+       virtual_chdir(&state, strdup("../andi"));
+       printf("%s\n", virtual_getcwd(&state, &length));
+       virtual_chdir(&state, strdup("/////andi"));
+       printf("%s\n", virtual_getcwd(&state, &length));
+       virtual_chdir(&state, strdup("andi/././././././////bar"));
+       printf("%s\n", virtual_getcwd(&state, &length));
+       virtual_chdir(&state, strdup("../andi/../bar"));
+       printf("%s\n", virtual_getcwd(&state, &length));
+}