/* Copyright (C) 2012 Equinor ASA, Norway. The file 'path_stack.c' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ #include #include #include #include #include #include #include #include #include #include #include /** This file implements the structure path_stack which is vaguely inspired by the emacs-lisp scecial form (save-excursion ...). The intentiation with the 'class' is to push directories onto a stack, and then each time you pop from the stack the the process will chdir() back to directory which is popped. Observe that the constructor path_stack_alloc() and destructor path_stack_free() do *not* alter the stack or the cwd of the process. */ struct path_stack_struct { std::stack> stack; }; /** This will create a new path_stack instance; it will push anything on the current stack of paths. */ path_stack_type * path_stack_alloc() { path_stack_type * path_stack = new path_stack_type(); return path_stack; } void path_stack_free( path_stack_type * path_stack ) { delete path_stack; } /** This will push a path on to the stack. The function will start by chdir() to the input path. If the chdir() call fails the function will return false, and the stack will be unmodified; if the chdir() succeeds the input @path will be pushed onto the stack. If path is NULL that is interpreted as cwd. */ bool path_stack_push( path_stack_type * path_stack , const char * path ) { if (path != NULL) if (util_chdir( path ) != 0) return false; path_stack_push_cwd( path_stack ); return true; } void path_stack_push_cwd( path_stack_type * path_stack ) { char * cwd = util_alloc_cwd(); path_stack->stack.push(cwd); free(cwd); } void path_stack_pop( path_stack_type * path_stack ) { const std::string& path = path_stack->stack.top(); if (util_chdir( path.c_str() ) != 0) // The directory has become inaccesible ... util_abort("%s: could not pop back to directory:%s Error:%s\n", __func__ , path.c_str() , strerror( errno )); path_stack->stack.pop(); } int path_stack_size( const path_stack_type * path_stack ) { return path_stack->stack.size(); }