Exemplo n.º 1
0
static int
printVariable(D4printer* out, NCD4node* var, int depth)
{
    int ret = NC_NOERR;
    NCD4node* basetype = var->basetype;
    char* fqn = NULL;

    INDENT(depth); CAT("<");
    switch (var->subsort) {
    default:
	CAT(basetype->name);
	printXMLAttributeName(out, "name", var->name);
	break;
    case NC_ENUM:
	CAT("Enum");
	printXMLAttributeName(out, "name", var->name);
	printXMLAttributeName(out, "enum", (fqn=NCD4_makeFQN(basetype)));
	break;
    case NC_OPAQUE:
	CAT("Opaque");
	printXMLAttributeName(out, "name", var->name);
	printXMLAttributeName(out, "type", (fqn=NCD4_makeFQN(basetype)));
	break;
    case NC_SEQ:
	CAT("Seq");
	printXMLAttributeName(out, "name", var->name);
	printXMLAttributeName(out, "type", (fqn=NCD4_makeFQN(basetype)));
	break;
    case NC_STRUCT:
	CAT("Struct");
	printXMLAttributeName(out, "name", var->name);
	printXMLAttributeName(out, "type", (fqn=NCD4_makeFQN(basetype)));
	break;
    }
    if(hasMetaData(var)) {
	CAT(">\n");
	depth++;
	if((ret=printMetaData(out,var,depth))) goto done;
	depth--;
	INDENT(depth); CAT("</");
	if(basetype->subsort == NC_ENUM)
	    CAT("Enum");
	else if(basetype->subsort == NC_OPAQUE)
	    CAT("Opaque");
	else if(basetype->subsort == NC_STRUCT)
	    CAT("Struct");
	else if(basetype->subsort == NC_SEQ)
	    CAT("Sequence");
	else
	    CAT(basetype->name);
	CAT(">");
    } else
	CAT("/>");
done:
    nullfree(fqn);
    return THROW(ret);
}
Exemplo n.º 2
0
int main(int argc, char* argv[])
{
    //The current working directory:
    Directory* dir = NULL;

    //Checks if too many arguments have been given:
    if(argc > 2)
    {
        std::cerr << "Please pass a single, valid directory\n";
        return -1;
    }
    //Otherwise, sees if a directory has been given,
    //and if so, attempt to open it:
    else if(argc == 2)
    {
        //Attempt to open
        try
        {
            dir = new Directory(argv[1]);
        }
        //Give an error message and quit if it fails:
        catch(int e)
        {
            std::cerr << "Cannot open '" << argv[1] << "': ";
            switch(e)
            {
            case EACCES:
                std::cerr << "Permission denied.";
                break;
            case ENOENT:
                std::cerr << "No such directory.";
                break;
            case ENOTDIR:
                std::cerr << "Not a directory.";
                break;
            }
            std::cerr << std::endl;
            return -1;
        }
    }
    //Otherwise, there are no arguments given, so use
    //the user's current working directory:
    else
    {
        //Get the current working directory:
        char* cwd = getcwd(NULL, 0);

        //Attempt to open it:
        try
        {
            dir = new Directory(cwd);
        }
        //Give an error message and quit if it fails:
        catch(int e)
        {
            std::cerr << "Cannot open '" << cwd << "': ";
            switch(e)
            {
            case EACCES:
                std::cerr << "Permission denied.";
                break;
            case ENOENT:
                std::cerr << "No such directory.";
                break;
            case ENOTDIR:
                std::cerr << "Not a directory.";
                break;
            }
            std::cerr << std::endl;
            return -1;
        }
    }
    //Attempt to read the directory's contents:
    try
    {
        dir->read();
    }
    //Give an error message and quit if it fails:
    catch(int e)
    {
        std::cerr << "Cannot open '" << dir->getPath() << "': ";
        switch(errno)
        {
        case EACCES:
            std::cerr << "Permission denied.";
            break;
        case ENOENT:
            std::cerr << "No such directory.";
            break;
        case ENOTDIR:
            std::cerr << "Not a directory.";
            break;
        }
        std::cerr << std::endl;
        return -1;
    }

    if(dir->getName() == "../")
        dir->cleanPath();

    //Initialise ncurses:
    initscr();

    //The colour pairs:
    init_pair(2, COLOR_WHITE, COLOR_RED);
    //Enable keypad mode (allows use of the up and down arrows):
    keypad(stdscr, true);

    //Start using colour:
    start_color();

    //Update the screen:
    refresh();

    //Hides the cursor, set 'noecho()':
    curs_set(0);
    noecho();

    int input = 0;
    std::string path = "";
    unsigned int selection = 0;
    DiskItem* clipboard = NULL;

    //While the user has not quit:
    while((char(input) != 'q') && (char(input) != 'Q'))
    {
        //Redraw the windows and help:
        updateWindows();
        drawHelp();

        //If necessary, resizes the directory path:
        path = "";
        if(dir->getPath().length() >= screenX)
            path = fitToSize(dir->getPath(), (screenX - 2));
        else
            path = dir->getPath();

        //The X position needed to print the path in the centre:
        int pos = ((screenX - path.length()) / 2);
        //Write the user's current directory:
        mvprintw(0, pos, "%s", path.c_str());

        //Get the files and sort the contents:
        std::vector <DiskItem*> items = dir->getFiles();

        //Checks if the contents of the directory will fit in the window:
        if((fileview.height - 2) > (items.size() - dir->getDotfiles()))
        {
            //Print the contents, except the dotfiles, to the window:
            for(unsigned int i = dir->getDotfiles(); i < items.size(); i++)
            {
                //If we're printing the current selection, highlight it:
                if(selection == (i - dir->getDotfiles()))
                {
                    //Print the name:
                    mvwprintw(fileview.window,((i - dir->getDotfiles()) + 1), 1, "%s", items[i]->getName().c_str());

                    //Move to the beginning of the line, and highlight the line up to but excluding the window border:
                    mvwchgat(fileview.window, ((i - dir->getDotfiles()) + 1), 1, (fileview.width - 2), A_NORMAL, 1, NULL);
                }
                else
                    //Print the name:
                    mvwprintw(fileview.window, ((i - dir->getDotfiles()) + 1), 1, "%s", items[i]->getName().c_str());
            }
        }
        //Otherwise, we can only print part of the directory's contents:
        else
        {
            //If the selection is less than the height, display the first few items:
            if(selection < (fileview.height - 2))
            {
                for(unsigned int i = dir->getDotfiles(); i < ((fileview.height - 2) + dir->getDotfiles()); i++)
                {
                    //If we're printing the current selection, highlight it:
                    if(selection == (i - dir->getDotfiles()))
                    {
                        //Print the name:
                        mvwprintw(fileview.window,((i - dir->getDotfiles()) + 1), 1, "%s", items[i]->getName().c_str());

                        //Move to the beginning of the line, and highlight the line up to but excluding the window border:
                        mvwchgat(fileview.window, ((i - dir->getDotfiles()) + 1), 1, (fileview.width - 2), A_NORMAL, 1, NULL);
                    }
                    else
                        //Print the name:
                        mvwprintw(fileview.window, ((i - dir->getDotfiles()) + 1), 1, "%s", items[i]->getName().c_str());
                }
            }
            //Otherwise, display the selection as the last item:
            else
            {
                for(unsigned int i = (dir->getDotfiles() + ((selection + 1) - (fileview.height - 2))); i < ((selection + 1) + dir->getDotfiles()); i++)
                {
                    unsigned int y = i - ((selection - (fileview.height - 2)) + dir->getDotfiles());

                    //If we're printing the current selection, highlight it:
                    if(selection == (i - dir->getDotfiles()))
                    {
                        //Print the name:
                        mvwprintw(fileview.window, y, 1, "%s", items[i]->getName().c_str());

                        //Move to the beginning of the line, and highlight the line up to but excluding the window border:
                        mvwchgat(fileview.window, y, 1, (fileview.width - 2), A_NORMAL, 1, NULL);
                    }
                    else
                        //Print the name:
                        mvwprintw(fileview.window, y, 1, "%s", items[i]->getName().c_str());
                }
            }
        }

        //Print the selected file's metadata to the 'fileinfo' window:
        printMetaData(items[selection + dir->getDotfiles()]);

        //Print the contents of the clipboard to the 'extrainfo' window:
        printClipboard(clipboard);

        //Refresh the screen and windows:
        refresh();
        wrefresh(fileview.window);
        wrefresh(fileinfo.window);
        wrefresh(extrainfo.window);

        //Gets the input:
        input = getch();

        //Moves the selection up or down if those keys were pressed:
        if((input == KEY_UP) || (char(input) == 'k') || (char(input) == 'K'))
            if(selection > 0) selection--;
        if((input == KEY_DOWN) || (char(input) == 'j') || (char(input) == 'J'))
            if(selection < ((items.size() - dir->getDotfiles()) - 1)) selection++;

        //If the user has pressed Enter:
        if(char(input) == '\n')
        {
            //Attempts to cast the current selection to a Directory*:
            Directory* selected = dynamic_cast <Directory*>(items[selection + dir->getDotfiles()]);

            //If the user has selected a directory:
            if(selected != NULL)
            {
                //Keep the old directory so we can delete it:
                Directory* oldDir = dir;

                //Makes a copy of the directory we want to move to:
                try
                {
                    dir = new Directory(selected);
                    dir->read();

                    delete oldDir;
                    selection = 0;

                    clear();
                }
                //If an error occurs, inform the user with a message box:
                catch(int e)
                {
                    std::string error = "Cannot open '" + dir->getPath() + "' ";
                    switch(errno)
                    {
                    case EACCES:
                        error += "Permission denied.";
                        break;
                    case ENOENT:
                        error += "No such directory.";
                        break;
                    case ENOTDIR:
                        error += "Not a directory.";
                        break;
                    }
                    messageBox(error);
                }
            }
        }
        //Otherwise, if the user has pressed 'd' for delete:
        else if((char(input) == 'd') || (char(input) == 'D'))
        {
            DiskItem* selected = items[selection + dir->getDotfiles()];
            //Attempt to delete the selected item:
            if(selected->deletef())
            {
                delete selected;
                dir->getFiles().erase(dir->getFiles().begin() + (selection + dir->getDotfiles()));

                //If we deleted the last item, then 'selection + dir->getDotfiles()' will
                //go out of bounds on the 'item' array, so decrement selection:
                if((selection + dir->getDotfiles()) == dir->getFiles().size())
                    selection--;
            }
            //If an error occurs, inform the user with a message box:
            else
            {
                std::string error = "Could not delete '" + selected->getPath() + "'";
                messageBox(error);
            }
        }
        //Otherwise, if the user has pressed 'c' for copy:
        else if((char(input) == 'C') || (char(input) == 'c'))
        {
            if(items[selection + dir->getDotfiles()]->getName() != "../")
            {
                //Checks if we are trying to copy a directory or a file:
                clipboard = dynamic_cast <Directory*>(items[selection + dir->getDotfiles()]);

                if(clipboard == NULL)
                {
                    //We are copying a file:
                    clipboard = new File(dynamic_cast <File*>(items[selection + dir->getDotfiles()]));
                }
                else
                {
                    //We are copying a directory:
                    clipboard = new Directory(dynamic_cast <Directory*>(items[selection + dir->getDotfiles()]));
                }
            }
        }
        //Otherwise, if the user has pressed 'x' for cut:
        else if((char(input) == 'X') || (char(input) == 'x'))
        {
            if(items[selection + dir->getDotfiles()]->getName() != "../")
            {
                //Checks if we are trying to cut a directory or a file:
                clipboard = dynamic_cast <Directory*>(items[selection + dir->getDotfiles()]);

                if(clipboard == NULL)
                {
                    //We are cutting a file:
                    clipboard = new File(dynamic_cast <File*>(items[selection + dir->getDotfiles()]));
                }
                else
                {
                    //We are cutting a directory:
                    clipboard = new Directory(dynamic_cast <Directory*>(items[selection + dir->getDotfiles()]));
                }
                clipboard->cut();
            }
        }
        //Otherwise, if the user has pressed 'p' for paste:
        else if((char(input) == 'P') || (char(input) == 'p'))
        {
            if(clipboard != NULL)
            {
                //Attempt to paste the item in the clipboard:
                if(! clipboard->paste(dir->getPath()))
                {
                    //If an error occurs, inform the user with a message box:
                    std::string error = "Could not paste '" + clipboard->getName() + "'";
                    messageBox(error);
                }
                else
                {
                    //If it works fine, add the new item to the directory's list of items:
                    DiskItem* item = clipboard;
                    dir->getFiles().push_back(item);
                    std::sort(dir->getFiles().begin(), dir->getFiles().end(), byName);

                    //Empty the clipboard:
                    clipboard = NULL;
                }
            }
        }
        //Otherwise, if the user presses 'r' for rename:
        else if((char(input) == 'R') || (char(input) == 'r'))
        {
            //Get the new name, and attempt to rename the selected item:
            std::string newName = inputBox();
            if(newName != "")
            {
                //Check if we are renaming a directory:
                if(dynamic_cast <Directory*>(items[selection + dir->getDotfiles()]) != NULL)
                    newName += '/';

                if(! items[selection + dir->getDotfiles()]->rename(newName.c_str()))
                {
                    //If an error occurs, inform the user with a message box:
                    std::string error = "Cannot rename '" + items[selection + dir->getDotfiles()]->getName() + "'";
                    messageBox(error);
                }
            }
        }
    }

    //Delete the directory object:
    delete dir;

    //Close ncurses:
    endwin();
    return 0;
}
Exemplo n.º 3
0
static int
printNode(D4printer* out, NCD4node* node, int depth)
{
    int ret = NC_NOERR;
    int i;
    char* fqn = NULL;

    switch (node->sort) {
    case NCD4_GROUP:
	if(node->group.isdataset)
	    printDataset(out,node,depth);
	else
	    printGroup(out,node,depth);
	break;

    case NCD4_DIM:
	INDENT(depth);
	CAT("<Dimension");
	if(node->name != NULL)
	    printXMLAttributeName(out, "name", node->name);
	printXMLAttributeSize(out, "size", node->dim.size);
	if(node->dim.isunlimited)
	    printXMLAttributeString(out, UCARTAGUNLIM, "1");
	CAT("/>");
	break;

    case NCD4_TYPE:
	switch (node->subsort) {
	default: break;
	case NC_OPAQUE:
	    INDENT(depth); CAT("<Opaque");
	    ncbytesclear(out->tmp);
	    printXMLAttributeName(out, "name", node->name);
	    if(node->opaque.size > 0)
	        printXMLAttributeSize(out, "size", node->opaque.size);
	    CAT("/>");
	    break;	    
	case NC_ENUM:
	    INDENT(depth); CAT("<Enumeration");
	    printXMLAttributeName(out, "name", node->name);
	    if(node->basetype->subsort <= NC_MAX_ATOMIC_TYPE)
		printXMLAttributeName(out, "basetype", node->basetype->name);
	    else {
		char* fqn = NULL;
		printXMLAttributeName(out, "basetype", (fqn = NCD4_makeFQN(node->basetype)));
		nullfree(fqn);
	    }
	    CAT(">\n");
	    depth++;
	    for(i=0;i<nclistlength(node->en.econsts);i++) {
		NCD4node* ec = (NCD4node*)nclistget(node->en.econsts,i);
		INDENT(depth);
		CAT("<EnumConst");
		printXMLAttributeName(out, "name", ec->name);
		printXMLAttributeAtomics(out, "value", &ec->en.ecvalue, node->basetype->subsort);
		CAT("/>\n");
	    }
	    depth--;
	    INDENT(depth); CAT("</Enumeration>");
	    break;
	case NC_STRUCT:
	    INDENT(depth);
	    CAT("<Structure");
	    printXMLAttributeName(out, "name", node->name);
	    CAT(">\n");
	    depth++;
	    for(i=0;i<nclistlength(node->vars);i++) {
		NCD4node* field = (NCD4node*)nclistget(node->vars,i);
		printVariable(out,field,depth);
		CAT("\n");
	    }
	    if((ret=printMetaData(out,node,depth))) goto done;
	    depth--;
	    INDENT(depth);
	    CAT("</Structure>");
	    break;
	case NC_SEQ:
	    INDENT(depth);
	    CAT("<Vlen");
	    printXMLAttributeName(out, "name", node->name);
	    printXMLAttributeName(out, "type", (fqn=NCD4_makeFQN(node->basetype)));
	    if(hasMetaData(node)) {
		CAT(">\n");
		depth++;
		if((ret=printMetaData(out,node,depth))) goto done;
		depth--;
		INDENT(depth);
		CAT("</Vlen>");
	    } else
	        CAT("/>");
  	    break;
        } break;
    case NCD4_VAR: /* Only top-level vars are printed here */
	if(ISTOPLEVEL(node)) {
  	    if((ret=printVariable(out,node,depth))) goto done;
	    CAT("\n");
	}
	break;

    default: abort(); break;
    }
done:
    nullfree(fqn);
    return THROW(ret);
}