From e0267013c4de07cf495b4488a66181e4027d88a4 Mon Sep 17 00:00:00 2001 From: Thomas O Fredericks Date: Fri, 19 Jun 2009 17:00:34 +0000 Subject: Added a few externals to tof svn path=/trunk/externals/tof/; revision=11801 --- src/path.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 src/path.c (limited to 'src/path.c') diff --git a/src/path.c b/src/path.c new file mode 100644 index 0000000..d0dc7ef --- /dev/null +++ b/src/path.c @@ -0,0 +1,252 @@ + +#include "tof.h" +#define SLASH '/' + +static t_class *path_class; + +typedef struct _path { + t_object x_obj; + //char buffer[MAXPDSTRING]; + t_outlet* outlet1; + //t_canvas* canvas; + t_symbol* dir; + t_symbol* mode; + t_symbol* dirmode; + t_symbol* s_current; + t_symbol* s_relative; +} t_path; + + +// Code from http://www.codeguru.com/cpp/misc/misc/fileanddirectorynaming/article.php/c263#more +static void getRelativeFilename(char* relativeFilename, char *currentDirectory, char *absoluteFilename) +{ + // declarations - put here so this should work in a C compiler + int afMarker = 0, rfMarker = 0; + int cdLen = 0, afLen = 0; + int i = 0; + int levels = 0; + //static char relativeFilename[MAX_FILENAME_LEN+1]; + + cdLen = strlen(currentDirectory); + afLen = strlen(absoluteFilename); + + + // Handle DOS names that are on different drives: + if(currentDirectory[0] != absoluteFilename[0]) + { + // not on the same drive, so only absolute filename will do + strcpy(relativeFilename, absoluteFilename); + return; + } + + // they are on the same drive, find out how much of the current directory + // is in the absolute filename + i = 1;//ABSOLUTE_NAME_START; + while(i < afLen && i < cdLen && currentDirectory[i] == absoluteFilename[i]) + { + i++; + } + + if(i == cdLen && (absoluteFilename[i] == SLASH || absoluteFilename[i-1] == SLASH)) + { + // the whole current directory name is in the file name, + // so we just trim off the current directory name to get the + // current file name. + if(absoluteFilename[i] == SLASH) + { + // a directory name might have a trailing slash but a relative + // file name should not have a leading one... + i++; + } + + strcpy(relativeFilename, &absoluteFilename[i]); + return; + } + + + // The file is not in a child directory of the current directory, so we + // need to step back the appropriate number of parent directories by + // using "..\"s. First find out how many levels deeper we are than the + // common directory + afMarker = i; + levels = 1; + + // count the number of directory levels we have to go up to get to the + // common directory + while(i < cdLen) + { + i++; + if(currentDirectory[i] == SLASH) + { + // make sure it's not a trailing slash + i++; + if(currentDirectory[i] != '\0') + { + levels++; + } + } + } + + // move the absolute filename marker back to the start of the directory name + // that it has stopped in. + while(afMarker > 0 && absoluteFilename[afMarker-1] != SLASH) + { + afMarker--; + } + + + + // add the appropriate number of "..\"s. + rfMarker = 0; + for(i = 0; i < levels; i++) + { + relativeFilename[rfMarker++] = '.'; + relativeFilename[rfMarker++] = '.'; + relativeFilename[rfMarker++] = SLASH; + } + + // copy the rest of the filename into the result string + strcpy(&relativeFilename[rfMarker], &absoluteFilename[afMarker]); + + //return relativeFilename; +} + + +// BANG: output the current root path +static void path_bang(t_path *x) +{ + + outlet_symbol(x->outlet1, x->dir ); + + +} + +static void path_anything(t_path *x, t_symbol *s, int ac, t_atom* av) { + + + + int length = tof_anything_to_string(s,ac,av,tof_buf_temp_a); + t_symbol* result; + + if ( x->mode == x->s_relative ) { + + // TRANSFORM ABSOLUTE PATHS TO RELATIVE PATHS + + // Is this a relative path? + // Checks for a starting / or a : as second character + if ( tof_path_is_absolute(tof_buf_temp_a,length )) { + getRelativeFilename(tof_buf_temp_b,x->dir->s_name,tof_buf_temp_a); + result = gensym(tof_buf_temp_b); + } else { + result = gensym(tof_buf_temp_a); + } + + } else { + + // TRANFORM RELATIVE PATHS TO ABSOLUTE PATHS + + // Is this a relative path? + if ( tof_path_is_absolute(tof_buf_temp_a,length) ) { + result = gensym(tof_buf_temp_a); + } else { + strcpy(tof_buf_temp_b,x->dir->s_name); + strcat(tof_buf_temp_b,tof_buf_temp_a); + result = gensym(tof_buf_temp_b); + } + } + + outlet_symbol(x->outlet1, result); +} + + + + +/* +void path_list(t_path *x,t_symbol *s, int argc, t_atom *argv) +{ + + + if ( argc >= 2) { + x->value = atom_getfloat(argv); + x->inc = atom_getfloat(argv+1); + } + + +} +*/ + + + + + +static void path_free(t_path *x) +{ + + //binbuf_free(x->binbuf); + +} + +void *path_new(t_symbol *s, int argc, t_atom *argv) +{ + t_path *x = (t_path *)pd_new(path_class); + + + x->s_current = gensym("current"); + x->s_relative = gensym("relative"); + + int i; + t_symbol * mode_temp; + for ( i = 0; i < argc; i++) { + if ( IS_A_SYMBOL(argv,i) ) { + mode_temp = atom_getsymbol(argv+i); + if ( mode_temp == x->s_current ) x->dirmode = x->s_current; + if ( mode_temp == x->s_relative) x->mode = x->s_relative; + } + } + + if ( x->dirmode == x->s_current) { + x->dir = tof_get_dir(tof_get_canvas()); + } else { + x->dir = tof_get_dir(tof_get_root_canvas(tof_get_canvas())); + + } + strcpy(tof_buf_temp_a,x->dir->s_name); + strcat(tof_buf_temp_a,"/"); + x->dir = gensym(tof_buf_temp_a); + + /* + inlet_new(&x->x_obj, &x->x_obj.ob_pd, + gensym("float"), gensym("set")); + + floatinlet_new(&x->x_obj, &x->inc); + */ + + x->outlet1 = outlet_new(&x->x_obj, &s_float); + + + + return (void *)x; +} + +void path_setup(void) { + path_class = class_new(gensym("path"), + (t_newmethod)path_new, + (t_method)path_free, sizeof(t_path), + CLASS_DEFAULT, + A_GIMME, 0); + + class_addbang(path_class, path_bang); + class_addanything(path_class,path_anything); + + //class_addmethod(path_class, + // (t_method)path_append, gensym("append"), + // A_GIMME, 0); + + //class_addfloat (path_class, path_float); + /*class_addmethod(path_class, + (t_method)path_set, gensym("set"), + A_DEFFLOAT, 0); +*/ + //class_addlist (path_class, path_list); + +} -- cgit v1.2.1