How to create folders in a patch?

Stephane Letz's icon

Hi,

We need to create folders from a Max patch on both OSX (universal) and Windows.

1) are they any standard and simple (no java based..) way to do that?

2) are they any third party objects available?

3) we tried to develop our C external but get very confused by the path syntax (like "MacOSX Tiger:/Applications/toto") that mixes ":" and "/" separators). Moreover the "conformpath" help says that "old colon style format" and "the new slash style" may be used... Are they any *clear* explanations of path management in Max, and of what external code would be supposed to do?

Thanks

Stephane Letz

Rob Ramirez's icon

on os x, use the shell exterenal and send it the message:
"mkdir /path/to/new/directory"

Stephane Letz's icon

I need to create folders with accentued letters and spaces... not the unix way

jasch's icon

OS X only - this is where the platforms are really different

below's the function, it even uses max's path utilities...

hth

/*j

//////////////

void createfolder_anything(t_createfolder *x, t_symbol *s, long ac,
t_atom *av)
{
    long            len, pos = 0;
    short            path = 0;
    char            *charptr;
    char            name[2048];
    char            inname[2048];
    char            parentname[2048];
    char            foldername[2048];    
    const FSRef        parentRef;
    CFStringRef        str;
    HFSUniStr255        folderNameU;
    OSStatus        err;
    Boolean            isDirectory;
    long result = 0;

    path_nameconform(s->s_name, inname, PATH_STYLE_SLASH, PATH_TYPE_BOOT);
    if(x->t_debug) post("path namecomform returns %s", inname);

    len = strlen(inname);
    if(inname[len-1] == '/') {
        inname[len-1] = 0;
        len--;
    }
    if (path_topathname(path, inname, name)) { // check if path alreay
exists
        charptr = strrchr(inname, '/');
        if(charptr != NULL){
            pos = (long)(charptr - inname + 1);
        }
        charptr = (char *)memmove(foldername, (inname + pos), (len - pos));
        foldername[(len - pos)] = 0;
        inname[MIN(len, pos)] = 0;
        strcpy(parentname, inname);
            if(x->t_debug) post("parentname is %s -- foldername is %s",
parentname, foldername);    

        err = FSPathMakeRef((const UInt8*)parentname, &parentRef,
&isDirectory);
        if((err == noErr) && (isDirectory)) {

            if(x->t_debug) post("makeFS returned noErr and isDirectory");

            str = CFStringCreateWithCString(kCFAllocatorDefault, foldername,
kCFStringEncodingMacRoman);
                            // encoding constant is important : shouldn't it come from
locale?

            folderNameU.length = (UInt16)CFStringGetLength(str);
            CFStringGetCharacters(str, CFRangeMake(0, folderNameU.length),
folderNameU.unicode);

            // see if it already exists?
            err = FSMakeFSRefUnicode(&parentRef,
folderNameU.length,folderNameU.unicode,
                                     kTextEncodingUnicodeDefault, NULL);
            // should now verify that is, in fact, a folder.

            if (err != noErr) { // no, so try to create it.        
                err = FSCreateDirectoryUnicode(&parentRef, folderNameU.length,
folderNameU.unicode,
                                                 kFSCatInfoNone, NULL, NULL, NULL, NULL);
                result = 1;
            }
        } else {
                if(x->t_debug) post("makeFS failed: %ld and %ld ",(int)err,
isDirectory);
            result = 0;
        }
    }
    outlet_int(x->t_outlet, result);
    return;
}

jasch's icon
Dan Nigrin's icon