コード例 #1
0
ファイル: bitcask.c プロジェクト: alexband/beansdb
/*
 * bc_close() is not thread safe, should stop other threads before call it.
 * */
void bc_close(Bitcask *bc)
{
    char datapath[255], hintpath[255];

    if (bc->optimize_flag > 0)
    {
        bc->optimize_flag = 2;
        while (bc->optimize_flag > 0)
        {
            sleep(1);
        }
    }

    pthread_mutex_lock(&bc->write_lock);

    bc_flush(bc, 0, 0);

    if (NULL != bc->curr_tree)
    {
        if (bc->curr_bytes > 0)
        {
            build_hint(bc->curr_tree, new_path(hintpath, bc->mgr, HINT_FILE, bc->curr));
        }
        else
        {
            ht_destroy(bc->curr_tree);
        }
        bc->curr_tree = NULL;
    }

    if (bc->curr_bytes == 0) bc->curr --;
    if (bc->curr - bc->last_snapshot >= SAVE_HTREE_LIMIT)
    {
        if (ht_save(bc->tree, new_path(datapath, bc->mgr, HTREE_FILE, bc->curr)) == 0)
        {
            mgr_unlink(gen_path(datapath, mgr_base(bc->mgr), HTREE_FILE, bc->last_snapshot));
        }
        else
        {
            fprintf(stderr, "save HTree to %s failed\n", datapath);
        }
    }
    ht_destroy(bc->tree);

    mgr_destroy(bc->mgr);
    free(bc->write_buffer);
    free(bc);
}
コード例 #2
0
ファイル: Test4.cpp プロジェクト: sim9108/SDKS
int main() {
	{
		TimeCheck time;

		auto surface = create_surface(CAIRO_FORMAT_ARGB32, SURFACE_SIZE{ 256, 256 });
		auto cr = create(surface);

		arc(cr, POINT{ 128.0, 128.0 }, 76.8, DEGRESS{ 0 }, DEGRESS{ 360 });
		clip(cr);

		new_path(cr);  /* current path is not  consumed by cairo_clip() */
		rectangle(cr, POINT{ 0, 0 }, SIZE{ 255, 255 });
		fill(cr);
		
		source(cr, RGB{ 0, 1, 0 });
		move_to(cr, POINT{ 0, 0 });
		line_to(cr, POINT{ 256, 256 });
		move_to(cr, POINT{ 256, 0 });
		line_to(cr, POINT{ 0, 256 });
		line_width(cr, 10.0);
		stroke(cr);
		
		write_to_png(surface, "image.png");
	}
	return 0;
}
コード例 #3
0
ファイル: memory_manager.cpp プロジェクト: giucamp/mmemo
	// MemoryManager::_build_context_maps
	void MemoryManager::_build_context_maps( const ContextConfig & i_context, const NamePath & i_context_path )
	{
		// setup the entry
		ContextEntry entry;
		entry.m_config = &i_context;
		IAllocator * allocator = nullptr;
		if( i_context.allocator_config() != nullptr )
		{			
			allocator = i_context.allocator_config()->create_allocator();
		}
		entry.m_allocator = allocator;

		// insert it in the map 
		if( !m_contexts_map.insert( std::make_pair( i_context_path, entry ) ).second )
		{
			memo_externals::output_message( "hash collision in the context map: " );
			memo_externals::output_message( i_context.name().name() );
			memo_externals::output_message( "\n" );
			memo_externals::debug_break();
		}

		const ContextConfig::ContextVector & inner_contexts = i_context.inner_contexts();
		for( size_t index = 0; index < inner_contexts.size(); index++ )
		{
			const ContextConfig & child_config = *inner_contexts[ index ];
			
			NamePath new_path( i_context_path );
			new_path.append_context( child_config.name() );
			_build_context_maps( child_config, new_path );
		}
		
	}
コード例 #4
0
ファイル: path.cpp プロジェクト: KenjiTakahashi/newsoul
std::string path::expandvars(const std::string &path) {
    std::string new_path(path);
    if(new_path.find('$') == std::string::npos) {
        return new_path;
    }
    pcrecpp::StringPiece path_re(new_path);
    pcrecpp::RE expandvars_re(".*\\$(\\w+|\\{[^}]*\\})");
    int offset = 0;
    std::string _;
    std::string varname;
    while(expandvars_re.Consume(&path_re, &varname)) {
        int varname_size = varname.size();
        if(varname.find('{') == 0 && varname.find('}') == varname.size() - 1) {
            varname = varname.substr(1, varname.length() - 2);
        }
        char *_varval = getenv(varname.c_str());
        if(_varval != NULL) {
            std::string varval(_varval);
            offset = new_path.size() - path_re.size();
            std::string tail(new_path.substr(offset));
            new_path = new_path.substr(0, offset - varname_size - 1) + varval;
            offset = new_path.size();
            new_path += tail;
        } else {
            offset = new_path.size() - path_re.size();
        }
    }
    return new_path;
}
コード例 #5
0
ファイル: php_workspace.cpp プロジェクト: stahta01/codelite
void PHPWorkspace::Rename(const wxString& newname)
{
    wxFileName new_path(GetFilename());
    new_path.SetName(newname);

    if(!::wxRenameFile(m_workspaceFile.GetFullPath(), new_path.GetFullPath())) {
        wxString msg;
        msg << _("Failed to rename workspace file:\n'") << m_workspaceFile.GetFullName() << _("'\nto:\n'")
            << new_path.GetFullName() << "'\n" << strerror(errno);
        ::wxMessageBox(msg, "CodeLite", wxOK | wxCENTER | wxICON_ERROR, EventNotifier::Get()->TopFrame());
        return;
    }

    PHPEvent evt(wxEVT_PHP_WORKSPACE_RENAMED);
    evt.SetOldFilename(m_workspaceFile.GetFullPath());
    evt.SetFileName(new_path.GetFullPath());
    EventNotifier::Get()->AddPendingEvent(evt);

    // and now rename the actual file
    m_workspaceFile = new_path;

    // trigger a workspace parsing
    wxCommandEvent evtRetag(wxEVT_CMD_RETAG_WORKSPACE_FULL);
    EventNotifier::Get()->AddPendingEvent(evtRetag);
}
コード例 #6
0
int Lua_Monster_Move_By_Path(lua_State *L)
{
    int monster_index = Lua_Monster::Index(L, 1);
    int polygon_index = 0;
    if (lua_isnumber(L, 2))
    {
        polygon_index = static_cast<int>(lua_tonumber(L, 2));
        if (!Lua_Polygon::Valid(polygon_index))
            return luaL_error(L, "move_by_path: invalid polygon index");
    }
    else if (Lua_Polygon::Is(L, 2))
    {
        polygon_index = Lua_Polygon::Index(L, 2);
    }
    else
        return luaL_error(L, "move_by_path: incorrect argument type");

    monster_data *monster = get_monster_data(monster_index);
    if (MONSTER_IS_PLAYER(monster))
        return luaL_error(L, "move_by_path: monster is player");

    monster_definition *definition = get_monster_definition_external(monster->type);
    object_data *object = get_object_data(monster->object_index);
    monster_pathfinding_data path;
    world_point2d destination;

    if (!MONSTER_IS_ACTIVE(monster))
        activate_monster(monster_index);

    if (monster->path != NONE)
    {
        delete_path(monster->path);
        monster->path = NONE;
    }

    SET_MONSTER_NEEDS_PATH_STATUS(monster, false);
    path.definition = definition;
    path.monster = monster;
    path.cross_zone_boundaries = true;

    destination = get_polygon_data(polygon_index)->center;

    monster->path = new_path((world_point2d *) &object->location, object->polygon, &destination, polygon_index, 3 * definition->radius, monster_pathfinding_cost_function, &path);
    if (monster->path == NONE)
    {
        if (monster->action != _monster_is_being_hit || MONSTER_IS_DYING(monster))
        {
            set_monster_action(monster_index, _monster_is_stationary);
        }
        set_monster_mode(monster_index, _monster_unlocked, NONE);
        return 0;
    }

    advance_monster_path(monster_index);
    return 0;
}
コード例 #7
0
void Environment::addToFrontEnvironmentVariable(const std::string& variable, const std::string& value) {
	std::string		new_path(variable + "=");
	const char*		path_env = getenv(variable.c_str());
	new_path += value;
	new_path += ";";
	if (path_env) {
		new_path += path_env;
	}
	_putenv(new_path.c_str());
}
コード例 #8
0
// Take a path and convert to the conforming definition, back-slashes converted to forward slashes 
// and no trailing slash.
std::string make_conformal_path(const std::string& path) 
{
	std::string new_path(path);
	std::replace(new_path.begin(), new_path.end(),'\\','/');
	new_path = boost::regex_replace(new_path, boost::regex("//"), "/",  boost::match_default | boost::format_all);
	if(new_path[new_path.length()-1] == '/') {
		new_path.erase(new_path.length()-1);
	}
	return new_path;
}
コード例 #9
0
ファイル: short.c プロジェクト: mhspradlin/c
struct path *find_shortest_ (int **weights, struct path **cache, struct node **graph, int id1, int id2) {
    printf ("id1: %d, id2: %d\n", id1, id2);
    if (id1 == id2) {
        struct path *stub = new_path (id1);
        cache[id1] = stub;
        return stub;
    }

    // If the path passed to us is a cycl
    
    //struct node *start = get_node (graph, id1);
    struct node *end = get_node (graph, id2);

    // Get all of the shortest paths for the predecessors
    // Also, the shortest path to us is us plus the shortest of the paths to our
    // predecessors
    int i;
    int min = 65535;
    int minpath = 0;
    for (i = 0; i < end->num_back; i++) {
        struct path *cur = cache[end->back[i]];
        // Only do work if we have to
        if (cur == NULL) {
            cur = find_shortest_ (weights, cache, graph, id1, end->back[i]);
        }
	    // Now we definitely have a value
        if (cur->numelems > 0 && cur->length + weights[end->back[i]][id2] < min) {
            min = cur->length + weights[end->back[i]][id2];
            minpath = end->back[i];
        }
    }

    // If there's no path, return that
    // We also get here if there's nobody behind us
    if (min == 65535)
        return no_path ();


    // Add us to the cache and return
    struct path *our_shortest = add_stop (weights, cache[minpath], minpath, id2);

    // If we've cycled (only happens if there's a negative cycle) then print out
    // that we have a negative cycle and the path that has it
    // Might not terminate if we do... Hmm...
    if (has_cycle (our_shortest)) {
        printf ("======== We have a cycle =======\n");
        print_path (our_shortest);
        printf("================\n");
    }

    // Add us to the cache
    cache[id2] = our_shortest;
    return our_shortest;
}
コード例 #10
0
void generate_alt_paths(PathConsVector& paths, const std::string& base, const std::vector<std::string>& alts, 
                        const uint32_t k)
{
    // Generate alternatives
    for(uint32_t ai = 0; ai < alts.size(); ++ai) {
        const std::string& alt = alts[ai];

        if(alt.size() < k)
            continue;

        kLCSResult result = kLCS(base, alt, k);

#ifdef DEBUG_ALT_GENERATION
        printf("Match to alt %s\n", alt.c_str());
        for(size_t mi = 0; mi < result.size(); ++mi) {
            std::string extend = "";
            if(mi < result.size() - 1 && result[mi].j + 1 != result[mi + 1].j) {
                extend = alt.substr(result[mi].j, result[mi + 1].j - result[mi].j + k);
            }
            printf("\t%zu %zu %s %s\n", result[mi].i, result[mi].j, base.substr(result[mi].i, k).c_str(), extend.c_str());
        }
#endif

        uint32_t match_idx = 0;
        while(match_idx < result.size()) {
            uint32_t last_idx = result.size() - 1;

            // advance the match to the next point of divergence
            while(match_idx != last_idx && 
                  result[match_idx].i == result[match_idx + 1].i - 1 &&
                  result[match_idx].j == result[match_idx + 1].j - 1) {
                match_idx++;
            }
            // no more divergences to process
            if(match_idx == last_idx)
                break;

            uint32_t bl = result[match_idx + 1].i - result[match_idx].i;
            uint32_t rl = result[match_idx + 1].j - result[match_idx].j;

            std::string base_subseq = base.substr(result[match_idx].i, bl);
            std::string alt_subseq = alt.substr(result[match_idx].j, rl);
            
            // Perform the splice
            PathCons new_path(base);
            new_path.path.replace(result[match_idx].i, bl, alt_subseq);
            paths.push_back(new_path);
            
            match_idx += 1;
        }
    }
}
コード例 #11
0
bool TreeIterator::Reset(const std::wstring &path, bool ignore_err)
{
		Path new_path(path);
		if(new_path.GetPathType() == INVALID_PATH)
		{
				return false;
		}else
		{
				m_root = new_path;//Reset(path);
				m_ignore_error = ignore_err;
				clear();
				return true;
		}
}
コード例 #12
0
void Environment::addToEnvironmentVariable(const std::string& variable, const std::string& value) {
	std::string		new_path(variable + "=");
	const char*		path_env = getenv(variable.c_str());
	if (path_env) {
		new_path += path_env;
	}
	if (new_path.length() > 0) {
		if (!(new_path.back() == '=' || new_path.back() == ';')) {
			new_path += ";";
		}
	}
	new_path += value;
	_putenv(new_path.c_str());
}
コード例 #13
0
ファイル: bitcask.c プロジェクト: alexband/beansdb
void bc_rotate(Bitcask *bc)
{
    // build in new thread
    char hintpath[255];
    new_path(hintpath, bc->mgr, HINT_FILE, bc->curr);
    struct build_thread_args *args = (struct build_thread_args*)malloc(
                                         sizeof(struct build_thread_args));
    args->tree = bc->curr_tree;
    args->path = strdup(hintpath);
    pthread_t build_ptid;
    pthread_create(&build_ptid, NULL, build_thread, args);
    // next bucket
    bc->curr ++;
    bc->curr_tree = ht_new(bc->depth, bc->pos);
    bc->wbuf_start_pos = 0;
}
コード例 #14
0
ファイル: caps_routines.c プロジェクト: CaGe-graph/CaGe
EDGE *add_n_gon_inverse(int n, EDGE *start)

/* Like add_n_gon, but in counterclockwise direction */

{

EDGE *run, *last;
int length, i;

last=start->prev->invers->prev;


for (length=n-2; last->end!=outside; last=last->invers->prev) length--;

if (length<=0) 
 { if (length<0) 
     { fprintf(stderr,"Error -- %d-gon does not fit in %d-hole \n",n,n-length);
	exit(42); }
   if (length==0)
     { fprintf(stderr,"Didn't expect to add a polygon without a new vertex.\n");
	fprintf(stderr,"small changes necessary.\n");
	exit(52); }
 }

/* The path must be glued in the opposite direction: */

run=new_path_last(nv+1,length);
start->invers=run; run->invers=start;
start->end=nv+length; run->end=start->start;

for (i=length; i>=1; i--, run=run->next->invers) firstedge[nv+i]=run;

run=new_path(nv+1,length);
last->invers=run; run->invers=last;
last->end=nv+1; run->end=last->start;

nv += length;

if (n==5) { for ( start=start->invers ; n ; n--, start=start->invers->prev) 
             {  pentagons[pentagonedges]=start; pentagonedges++;
		 start->pentagon_right=1; }
           pentagoncounter++; } 

return(run->next);

}
コード例 #15
0
ファイル: pathobject.cpp プロジェクト: elaboris/gamera
static PyObject* path_concat(PyObject* py_self, PyObject* py_other) {
  if (!is_PathObject(py_other)) {
    PyErr_SetString(PyExc_TypeError, "Paths can only be concatenated with other path objects");
    return 0;
  }
  boost::shared_ptr<Path> self = ((PathObject*)py_self)->m_x;
  boost::shared_ptr<Path> other = ((PathObject*)py_other)->m_x;
  boost::shared_ptr<Path> new_path(new Path());
  new_path->reserve(self->size() + other->size());
  try {
    new_path->insert(new_path->begin(), self->begin(), self->end());
    new_path->insert(new_path->end(), other->begin(), other->end());
  } catch (path_exception e) {
    // delete new_path; Should be implicit by boost::shared_ptr
    PyErr_SetString(PyExc_PathException, e.what());
    return 0;
  }
  return create_PathObject(new_path);
}
コード例 #16
0
void myGraph::findAllPathesBetweenTwoNodes(int source, int target, int totalnode, int totaledge, vector<vector<int>> GRAPH, vector<vector<int>> &pathVector)
{    //sort the path from smallest length to longest
	set<vector<int>> pathInfoSet;
	vector<vector<int>> pathVector_t;
    vector<int>path;
    path.push_back(source);
    queue<vector<int> >q;
    q.push(path);
    int count=0;
	while(!q.empty())
    {
        path=q.front();
        q.pop();

        int last_nodeof_path=path[path.size()-1];
        if(last_nodeof_path==target)
        {
			vector<int> pathInfo;
			pathInfo.push_back(path.size());
			pathInfo.push_back(count);
			pathInfoSet.insert(pathInfo);

            pathVector_t.push_back(path); //a valid path
			
			count++;
        }
        for(int i=0;i<GRAPH[last_nodeof_path].size();++i)
        {
            if(isadjacency_node_not_present_in_current_path(GRAPH[last_nodeof_path][i],path))
            {
                vector<int>new_path(path.begin(),path.end());
                new_path.push_back(GRAPH[last_nodeof_path][i]);
                q.push(new_path);
            }
        }
	}	
	for(set<vector<int>>::iterator it=pathInfoSet.begin(); it!=pathInfoSet.end(); it++)
	{
	    vector<int>	item = *it;
	    pathVector.push_back(pathVector_t[item[1]]);
	}
}
コード例 #17
0
static int update_filter_files(update_t *update)
{
    unsigned char digest[SHA256_DIGEST_LENGTH];
    char* filename;
    update_item_t **prev = &(update->items);
    update_item_t *item = update->items;
    int excluded = 0;

    while (item)
    {
        filename = new_path(PATH_CONFIG_FOLDER_CARDPEEK,item->file,NULL);

        if (sha256sum(filename,digest)!=0)
        {
            if (memcmp(digest,bytestring_get_data(&item->digest),SHA256_DIGEST_LENGTH)!=0)
            {
                log_printf(LOG_INFO,"File %s needs to be updated.",filename);
                prev = &(item->next);
                item = item->next;
            }
            else
            {
                /* log_printf(LOG_DEBUG,"No update needed for %s",filename); */
                *prev = item->next;                    
                update_item_free(item);
                excluded++;
                item = *prev;
                update->item_count--;
            }
        }
        else
        {
            log_printf(LOG_INFO,"File %s is proposed for creation in current script updates.",filename);
            prev = &(item->next);
            item = item->next;
        }

        g_free(filename);
    }
    return excluded;
}
コード例 #18
0
bool copyFile(std::string old_path, std::string new_root, std::string &filename)
{
  //get just the filename part of the original file
  size_t slash_position = old_path.find_last_of('/');
  if (slash_position == std::string::npos) 
  {
    //no slash
    filename = old_path;
  } 
  else if (slash_position >= old_path.size() - 1)
  {
    //slash is the last character
    std::cerr << "Failed to parse input filename: " << old_path << "\n";
    return false;
  }
  else
  {
    //skip the last slash
    filename = old_path.substr(slash_position+1, std::string::npos);
  }
  std::string new_path(new_root);
  if (new_path.at(new_path.size() - 1) != '/') 
  {
    new_path.append("//");
  }
  new_path.append(filename);
  if ( boost::filesystem::exists(new_path) )
  {
    std::cerr << "File " << new_path << " already exists; skipping copy.\n";
    return true;
  }  
  boost::filesystem::copy_file(old_path, new_path);
  if ( !boost::filesystem::exists(new_path) )
  {
    std::cerr << "Failed to copy file " << filename << " to " << new_path << "\n";
    return false;
  }
  return true;
}
コード例 #19
0
int cardpeek_update_perform(void)
{
    const char* cardpeek_update_file = path_config_get_string(PATH_CONFIG_FILE_CARDPEEK_UPDATE);
    a_string_t *contents;
    update_t *update;
    int remove;
    update_item_t *item;
    time_t now = time(NULL);
    int updated = 0;
    char *url = NULL;
    char *local_file;
    char *local_dnld;
    unsigned char digest[SHA256_DIGEST_LENGTH];
    a_string_t *url_request;
    unsigned first_update;

    first_update = (unsigned)luax_variable_get_integer("cardpeek.updates.first_update");
    
    /* STEP 1: get cardpeek.update file */

    url=luax_variable_get_strdup("cardpeek.updates.url");

    if (url==NULL)
        url = g_strdup(DEFAULT_UPDATE_URL);

    log_printf(LOG_INFO,"Fetching '%s'",url);

    url_request = a_strnew(NULL);
    a_sprintf(url_request,"%s?u=%x&v=%s",url,first_update,VERSION);

    if (http_download(a_strval(url_request),cardpeek_update_file)==0)
    {
        g_free(url);
        return 0;
    }
    g_free(url);
    a_strfree(url_request);


    /* STEP 2: parse file */

    if ((contents=file_get_contents(cardpeek_update_file))==NULL)
    {
        log_printf(LOG_ERROR,"failed to read update file information.");
        unlink(cardpeek_update_file);
        return 0;
    }

    update = update_new();

    if ((update_load(update,a_strval(contents),a_strlen(contents)))==0)
    {
        unlink(cardpeek_update_file);
        a_strfree(contents);
        update_free(update);
        return 0;
    }
    a_strfree(contents);

    /* log_printf(LOG_DEBUG,"Updates correctly loaded from '%s'",cardpeek_update_file); */
    if ((remove = update_filter_version(update,VERSION))>0)
        log_printf(LOG_WARNING,"%d updates will not be installed because they require a newer version of Cardpeek.");
    
    remove = update_filter_files(update);

    if (update->item_count)
        log_printf(LOG_INFO,"A total of %d files will be updated, %d files are kept unchanged.",update->item_count,remove);
    else
        log_printf(LOG_INFO,"No files will be updated, %d files are kept unchanged.",remove);

    item = update->items;

    while (item)
    {
        local_dnld = new_path(PATH_CONFIG_FOLDER_CARDPEEK,item->file,".download");
        local_file = new_path(PATH_CONFIG_FOLDER_CARDPEEK,item->file,NULL);

        if (http_download(item->url,local_dnld)!=0)
        {        
            if (sha256sum(local_dnld,digest))
            {
                if (memcmp(digest,bytestring_get_data(&item->digest),SHA256_DIGEST_LENGTH)==0)
                {
                    unlink(local_file);

                    if (rename(local_dnld,local_file)==0)
                    {
                        log_printf(LOG_INFO,"Successfuly updated %s", local_file);
                        updated++;
                    }
                    else
                    {
                        log_printf(LOG_ERROR,"Failed to copy %s to %s: %s", 
                                local_dnld,
                                local_file, 
                                strerror(errno));
                    }
                }
                else
                {
                    log_printf(LOG_WARNING,"File %s was not updated: authentication failed.",local_file);
                }
            }
            unlink(local_dnld);
        }
        g_free(local_dnld);
        g_free(local_file);
        item =  item->next; 
    }

    if (updated == update->item_count)
    {    
        luax_variable_set_integer("cardpeek.updates.next_update",(int)(now+7*(24*3600)));  
        luax_config_table_save();
    }

    unlink(cardpeek_update_file);
    update_free(update);

    /* STEP 3: finish */

    return 1;

}
コード例 #20
0
ファイル: init.cpp プロジェクト: mr-abhi/DualBootPatcher
static bool strip_manual_mounts()
{
    autoclose::dir dir(autoclose::opendir("/"));
    if (!dir) {
        return true;
    }

    struct dirent *ent;
    while ((ent = readdir(dir.get()))) {
        // Look for *.rc files
        if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0
                || !util::ends_with(ent->d_name, ".rc")) {
            continue;
        }

        std::string path("/");
        path += ent->d_name;

        autoclose::file fp(autoclose::fopen(path.c_str(), "r"));
        if (!fp) {
            LOGE("Failed to open %s for reading: %s",
                 path.c_str(), strerror(errno));
            continue;
        }

        char *line = nullptr;
        size_t len = 0;
        ssize_t read = 0;

        auto free_line = util::finally([&] {
            free(line);
        });

        std::size_t count = 0;
        std::unordered_set<std::size_t> comment_out;

        // Find out which lines need to be commented out
        while ((read = getline(&line, &len, fp.get())) >= 0) {
            if (strstr(line, "mount")
                    && (strstr(line, "/system")
                        || strstr(line, "/cache")
                        || strstr(line, "/data"))) {
                std::vector<std::string> tokens = util::tokenize(line, " \t\n");
                if (tokens.size() >= 4 && tokens[0] == "mount"
                        && (tokens[3] == "/system"
                            || tokens[3] == "/cache"
                            || tokens[3] == "/data")) {
                    comment_out.insert(count);
                }
            }

            ++count;
        }

        if (comment_out.empty()) {
            continue;
        }

        // Go back to beginning of file for reread
        rewind(fp.get());
        count = 0;

        std::string new_path(path);
        new_path += ".new";

        autoclose::file fp_new(autoclose::fopen(new_path.c_str(), "w"));
        if (!fp_new) {
            LOGE("Failed to open %s for writing: %s",
                 new_path.c_str(), strerror(errno));
            continue;
        }

        // Actually comment out the lines
        while ((read = getline(&line, &len, fp.get())) >= 0) {
            if (comment_out.find(count) != comment_out.end()) {
                fputs("#", fp_new.get());
            }
            fputs(line, fp_new.get());

            ++count;
        }

        replace_file(path.c_str(), new_path.c_str());
    }

    return true;
}
コード例 #21
0
ファイル: pngTest12.cpp プロジェクト: sim9108/SDKS
void spc_new_path_perhaps(snap_path_closure_t &spc) {
	if (!spc.first)  return;
	new_path(spc.cr);
	spc.first = 0;
}
コード例 #22
0
ファイル: bitcask.c プロジェクト: alexband/beansdb
void bc_scan(Bitcask* bc)
{
    char datapath[255], hintpath[255];
    int i=0;
    struct stat st, hst;

    skip_empty_file(bc);

    const char* base = mgr_base(bc->mgr);
    // load snapshot of htree
    for (i=MAX_BUCKET_COUNT-1; i>=0; i--)
    {
        if (stat(gen_path(datapath, base, HTREE_FILE, i), &st) == 0
                && stat(gen_path(hintpath, base, HINT_FILE, i), &hst) == 0
                && st.st_mtime >= hst.st_mtime
                && (bc->before == 0 || st.st_mtime < bc->before))
        {
            bc->tree = ht_open(bc->depth, bc->pos, datapath);
            if (bc->tree != NULL)
            {
                bc->last_snapshot = i;
                break;
            }
            else
            {
                fprintf(stderr, "open HTree from %s failed\n", datapath);
                mgr_unlink(datapath);
            }
        }
    }
    if (bc->tree == NULL)
    {
        bc->tree = ht_new(bc->depth, bc->pos);
    }

    for (i=0; i<MAX_BUCKET_COUNT; i++)
    {
        if (stat(gen_path(datapath, base, DATA_FILE, i), &st) != 0)
        {
            break;
        }
        bc->bytes += st.st_size;
        if (i <= bc->last_snapshot) continue;

        gen_path(hintpath, base, HINT_FILE, i);
        if (bc->before == 0)
        {
            if (0 == stat(hintpath, &st))
            {
                scanHintFile(bc->tree, i, hintpath, NULL);
            }
            else
            {
                scanDataFile(bc->tree, i, datapath,
                             new_path(hintpath, bc->mgr, HINT_FILE, i));
            }
        }
        else
        {
            if (0 == stat(hintpath, &st) &&
                    (st.st_mtime < bc->before || 0 == stat(datapath, &st) && st.st_mtime < bc->before))
            {
                scanHintFile(bc->tree, i, hintpath, NULL);
            }
            else
            {
                scanDataFileBefore(bc->tree, i, datapath, bc->before);
            }
        }
    }

    if (i - bc->last_snapshot > SAVE_HTREE_LIMIT)
    {
        if (ht_save(bc->tree, new_path(datapath, bc->mgr, HTREE_FILE, i-1)) == 0)
        {
            mgr_unlink(gen_path(NULL, base, HTREE_FILE, bc->last_snapshot));

            bc->last_snapshot = i-1;
        }
        else
        {
            fprintf(stderr, "save HTree to %s failed\n", datapath);
        }
    }

    bc->curr = i;
}
コード例 #23
0
ファイル: main.cpp プロジェクト: eklukovich/CUDA-BFS
int RT_BFS_1(Graph &G, int source, std::ofstream & outputfile2, int * cost) {

    std::vector<int> path;
    
    path.push_back(source);
    std::queue<std::vector<int> >q;
    q.push(path);

    std::map <int, unsigned int> flag1, vertex_to_index;
    std::map <int, bool> flag2;

    int ii = 0;
    
    // for each vertex in the graph
    for (auto aa : G.graphVector) 
        {
            // set source to vertex distance to infinity
            flag1.insert(std::make_pair(aa.ID, 9999));
            
            // set vertex as not visited
            flag2.insert(std::make_pair(aa.ID, false));
            
            vertex_to_index.insert(std::make_pair(aa.ID, ii++));
        }
    
    int deepness = 1;
    
    // loop until queue is empty
    while (!q.empty()) 
        {
            // get a path from the queue
            path = q.front();
            q.pop();

            // get the last node in the path
            int last_nodeof_path = path[path.size() - 1];

            // print out the current path to the file
            //print_path(path, outputfile2);

            int grp_pos = last_nodeof_path;

            // loop through all the vertex's edges
            for (auto it : G.graphVector[grp_pos].edges) 
                {
                    // get the connected vertex id
                    int v_id = std::get<2>(it).get_Vertex_ID();
                    
                    // get the index of the vertex
                    int index_id = vertex_to_index.find(v_id)->second;
                    
                    // if the vertex distance is greater than the path size
                    if (flag1.find(v_id)->second >= path.size()) 
                        {
                            // if the vertex is not in the current path and has not been visited then add to queue
                            if (isadjacency_node_not_present_in_current_path(index_id, path) && flag2.find(v_id)->second == false) 
                                {
                                    // copy the current path vector into a new one
                                    std::vector<int> new_path(path.begin(), path.end());
                                    
                                    // add the new vertex
                                    new_path.push_back(index_id);
                                    
                                    // push the new path on the queue
                                    q.push(new_path);
                                    
                                    // set the distance to the vertex to the path size
                                    flag1[v_id] = path.size();
                                    cost[v_id] = path.size();
                                }
                        }
                }
            
            flag2.find(G.graphVector[grp_pos].ID)->second = true;

            deepness++;
        }

    //std::cout << "\nRT_BFS finished Process  \n ------------";

    return 1;
}
コード例 #24
0
ファイル: caps_routines.c プロジェクト: CaGe-graph/CaGe
void init_new_paths(int maxnv_cap)

/* Initialises the new_path entries. Must be called before the construction starts.
  The parameter maxnv_cap must be the maximum number of vertices a cap might have */

{
int nv,length,i;
EDGE *edges;

edges=(EDGE *) malloc(3*(1+2+3+4)*maxnv_cap*sizeof(EDGE));
if (edges==NULL) { fprintf(stderr,"Can not get enough space for the cap edges \n");
		   exit(1); }
{ int marki;
  EDGE *markrun;

  for (marki=0; (marki<MAX_EDGE_ARRAYS) && (edge_array_start[marki]!=0); marki++);
  if (marki==MAX_EDGE_ARRAYS) 
       { fprintf(stderr,"Constant MAX_EDGE_ARRAYS too small (1) -- increase.\n");
	  exit(1); }
  edge_array_start[marki]=edges;
  how_many_edges[marki]=3*(1+2+3+4)*maxnv_cap;
  for (marki=3*(1+2+3+4)*maxnv_cap, markrun=edges; marki>0; marki--, markrun++) markrun->mark__=0;
}

new__path=(EDGE **)malloc(sizeof(EDGE *)*(maxnv_cap+1)*4);
if (new__path==NULL) { fprintf(stderr,"Can not get enough space for the new__path entries \n");
		       exit(1); }
new__path_last=(EDGE **)malloc(sizeof(EDGE *)*(maxnv_cap+1)*4);
if (new__path_last==NULL) 
 { fprintf(stderr,"Can not get enough space for the new__path_last entries \n");
   exit(1); }


for (nv=1; nv<=maxnv_cap; nv++)
 for (length=1; length<=4; length++,edges++)
   { /* first the edge that is glued to the existing patch: */
	 new_path(nv,length)=edges;
	 edges->start=nv; 
	 edges->pentagon_right=0;
	 edges->prev=edges+2; edges->next=edges+1;
	 edges++; 
	 edges->start=nv; edges->end=outside; 
	 edges->pentagon_right=0;
	 edges->prev=edges-1; edges->next=edges+1;
	 edges++;
	 edges->start=nv; edges->pentagon_right=0;
	 edges->prev=edges-1; edges->next=edges-2;

     for (i=1; i<length; i++)
	{
	 edges++;
	 edges->start=nv+i; edges->end=nv+(i-1);
	 edges->pentagon_right=0;
	 edges->prev=edges+2; edges->next=edges+1;
	 edges->invers=edges-1; 
	 (edges-1)->invers=edges; (edges-1)->end=nv+i;
	 edges++; 
	 edges->start=nv+i; edges->end=outside; 
	 edges->pentagon_right=0;
	 edges->prev=edges-1; edges->next=edges+1;
	 edges++;
	 edges->start=nv+i;
	 edges->pentagon_right=0;
	 edges->prev=edges-1; edges->next=edges-2;
      }
	 new_path_last(nv,length)=edges;
      }
}
コード例 #25
0
ファイル: caps_routines.c プロジェクト: CaGe-graph/CaGe
EDGE *add_n_gon(int n, EDGE *start)

/* Adds an n-gon starting at "start" in clockwise direction. Returns the last
  edge of this polygon pointing to the outside, if such an edge exists.
  Otherwise (that is: if no new vertices are inserted, but just a gap
  closed) the routine exits, since this is not expected to be necessary in this
  program.

  The firstedge, nv entries are updated.

  In case construct_ipr==1 and n==5, it is checked whether this penatgon neighbours
  another. In case it does not, the global variable is_ipr is set to 0;

*/


{

EDGE *run, *last;
int length, i;

if (construct_ipr && (n==5))
   {
     last=start->next;
     if (last->pentagon_right) is_ipr=0;
     last=last->invers->next;
     for (length=n-2; last->end!=outside; last=last->invers->next) 
	{ if (last->pentagon_right) is_ipr=0;
         length--;
	}
   }
else
  {
    last=start->next->invers->next;
    for (length=n-2; last->end!=outside; last=last->invers->next) length--;
  }
/* length counts, how many new vertices are needed. */


if (length<=0) 
 { if (length<0) 
     { fprintf(stderr,"Error -- %d-gon does not fit in %d-hole \n",n,n-length);
	exit(4); }
   if (length==0)
     { fprintf(stderr,"Didn't expect to add a polygon without a new vertex.\n");
	fprintf(stderr,"small changes necessary.\n");
	exit(5); }
 }


run=new_path(nv+1,length);
start->invers=run; run->invers=start;
start->end=nv+1; run->end=start->start;

for (i=1; i<=length; i++, run=run->prev->invers) firstedge[nv+i]=run;

run=new_path_last(nv+1,length);
last->invers=run; run->invers=last;
last->end=nv+length; run->end=last->start;

nv += length;

if (n==5) { for ( ; n ; n--, start=start->invers->prev) 
             {  pentagons[pentagonedges]=start; pentagonedges++;
		 start->pentagon_right=1; }
           pentagoncounter++; } 

return(run->prev);

}
コード例 #26
0
ファイル: findevs.c プロジェクト: jasonbking/illumos-gate
static int
add_disk2controller(disk_t *diskp, struct search_args *args)
{
	di_node_t	pnode;
	controller_t	*cp;
	di_minor_t	minor;
	di_node_t	node;
	int		i;

	node = args->node;

	pnode = di_parent_node(node);
	if (pnode == DI_NODE_NIL) {
		return (0);
	}

	minor = di_minor_next(pnode, NULL);
	if (minor == NULL) {
		return (0);
	}

	if ((cp = add_controller(args, pnode, minor)) == NULL) {
		return (ENOMEM);
	}

	/* check if the disk <-> ctrl assoc is already there */
	for (i = 0; diskp->controllers[i]; i++) {
		if (cp == diskp->controllers[i]) {
			return (0);
		}
	}

	/* this is a new controller for this disk */

	/* add the disk to the controller */
	if (add_ptr2array(diskp, (void ***)&cp->disks) != 0) {
		return (ENOMEM);
	}

	/* add the controller to the disk */
	if (add_ptr2array(cp, (void ***)&diskp->controllers) != 0) {
		return (ENOMEM);
	}

	/*
	 * Set up paths for mpxio controlled drives.
	 */
	if (libdiskmgt_str_eq(di_node_name(pnode), "scsi_vhci")) {
		/* note: mpxio di_path stuff is all consolidation private */
		di_path_t   pi = DI_PATH_NIL;

		while (
		    (pi = di_path_client_next_path(node, pi)) != DI_PATH_NIL) {
			int	cnt;
			uchar_t	*bytes;
			char	str[MAXPATHLEN];
			char	*wwn;

			di_node_t phci_node = di_path_phci_node(pi);

			/* get the node wwn */
			cnt = di_path_prop_lookup_bytes(pi, WWN_PROP, &bytes);
			wwn = NULL;
			if (cnt > 0) {
				int	i;
				str[0] = 0;

				for (i = 0; i < cnt; i++) {
					/*
					 * A byte is only 2 hex chars + null.
					 */
					char bstr[8];

					(void) snprintf(bstr,
					    sizeof (bstr), "%.2x", bytes[i]);
					(void) strlcat(str, bstr, sizeof (str));
				}
				wwn = str;
			}

			if (new_path(cp, diskp, phci_node,
			    di_path_state(pi), wwn) == NULL) {
				return (ENOMEM);
			}
		}
	}

	return (0);
}
コード例 #27
0
ファイル: bitcask.c プロジェクト: alexband/beansdb
void bc_optimize(Bitcask *bc, int limit)
{
    int i, total, last = -1;
    bc->optimize_flag = 1;
    const char *base = mgr_base(bc->mgr);
    // remove htree
    for (i=0; i < bc->curr; i++)
    {
        mgr_unlink(gen_path(NULL, base, HTREE_FILE, i));
    }
    bc->last_snapshot = -1;

    time_t limit_time = 0;
    if (limit > 3600 * 24 * 365 * 10)   // more than 10 years
    {
        limit_time = limit; // absolute time
    }
    else
    {
        limit_time = time(NULL) - limit; // relative time
    }

    struct stat st;
    bool skipped = false;
    for (i=0; i < bc->curr && bc->optimize_flag == 1; i++)
    {
        char datapath[255], hintpath[255];
        gen_path(datapath, base, DATA_FILE, i);
        gen_path(hintpath, base, HINT_FILE, i);
        if (stat(datapath, &st) != 0)
        {
            continue; // skip empty file
        }
        // skip recent modified file
        if (st.st_mtime > limit_time)
        {
            skipped = true;

            last ++;
            if (last != i)   // rotate data file
            {
                char npath[255];
                gen_path(npath, base, DATA_FILE, last);
                if (symlink(datapath, npath) != 0)
                {
                    fprintf(stderr, "symlink failed: %s -> %s\n", datapath, npath);
                    last = i;
                    continue;
                }

                // update HTree to use new index
                if (stat(hintpath, &st) != 0)
                {
                    fprintf(stderr, "no hint file: %s, skip it\n", hintpath);
                    last = i;
                    continue;
                }
                HTree *tree = ht_new(bc->depth, bc->pos);
                scanHintFile(tree, i, hintpath, NULL);
                struct update_args args;
                args.tree = bc->tree;
                args.index = last;
                ht_visit(tree, update_item_pos, &args);
                ht_destroy(tree);

                unlink(npath);
                mgr_rename(datapath, npath);
                mgr_rename(hintpath, gen_path(npath, base, HINT_FILE, last));
            }
            continue;
        }

        int deleted = count_deleted_record(bc->tree, i, hintpath, &total);
        uint64_t curr_size = data_file_size(bc, i) * (total - deleted/2) / (total+1); // guess
        uint64_t last_size = last >= 0 ? data_file_size(bc, last) : -1;

        // last data file size
        uint32_t recoverd = 0;
        if (last == -1 || last_size + curr_size > MAX_BUCKET_SIZE)
        {
            last ++;
        }
        while (last < i)
        {
            char ldpath[255], lhpath[255];
            new_path(ldpath, bc->mgr, DATA_FILE, last);
            new_path(lhpath, bc->mgr, HINT_FILE, last);
            recoverd = optimizeDataFile(bc->tree, i, datapath, hintpath,
                                        skipped, MAX_BUCKET_SIZE, last, ldpath, lhpath);
            if (recoverd == 0)
            {
                last ++;
            }
            else
            {
                break;
            }
        }
        if (recoverd == 0)
        {
            // last == i
            recoverd = optimizeDataFile(bc->tree, i, datapath, hintpath,
                                        skipped, MAX_BUCKET_SIZE, last, NULL, NULL);
        }
        if (recoverd < 0) break; // failed

        pthread_mutex_lock(&bc->buffer_lock);
        bc->bytes -= recoverd;
        pthread_mutex_unlock(&bc->buffer_lock);
    }

    // update pos of items in curr_tree
    pthread_mutex_lock(&bc->write_lock);
    pthread_mutex_lock(&bc->flush_lock);
    if (i == bc->curr && ++last < bc->curr)
    {
        char opath[255], npath[255];
        gen_path(opath, base, DATA_FILE, bc->curr);

        if (file_exists(opath))
        {
            gen_path(npath, base, DATA_FILE, last);
            if (symlink(opath, npath) != 0)
                fprintf(stderr, "symlink failed: %s -> %s\n", opath, npath);

            struct update_args args;
            args.tree = bc->tree;
            args.index = last;
            ht_visit(bc->curr_tree, update_item_pos, &args);

            unlink(npath);
            mgr_rename(opath, npath);
        }

        bc->curr = last;
    }
    pthread_mutex_unlock(&bc->flush_lock);
    pthread_mutex_unlock(&bc->write_lock);

    bc->optimize_flag = 0;
}
コード例 #28
0
ファイル: bitcask.c プロジェクト: alexband/beansdb
void bc_flush(Bitcask *bc, int limit, int flush_period)
{
    if (bc->curr >= MAX_BUCKET_COUNT)
    {
        fprintf(stderr, "reach max bucket count\n");
        exit(1);
    }

    pthread_mutex_lock(&bc->flush_lock);
    pthread_mutex_lock(&bc->buffer_lock);

    time_t now = time(NULL);
    if (bc->wbuf_curr_pos > limit * 1024 ||
            now > bc->last_flush_time + flush_period && bc->wbuf_curr_pos > 0)
    {
        uint32_t size = bc->wbuf_curr_pos;
        char * tmp = (char*) malloc(size);
        memcpy(tmp, bc->write_buffer, size);
        pthread_mutex_unlock(&bc->buffer_lock);

        char buf[255];
        new_path(buf, bc->mgr, DATA_FILE, bc->curr);

        FILE *f = fopen(buf, "ab");
        if (f == NULL)
        {
            fprintf(stderr, "open file %s for flushing failed.\n", buf);
            exit(1);
        }
        // check file size
        uint64_t last_pos = ftello(f);
        if (last_pos > 0 && last_pos != bc->wbuf_start_pos)
        {
            fprintf(stderr, "last pos not match: %"PRIu64" != %d in %s\n", last_pos, bc->wbuf_start_pos, buf);
            exit(1);
        }

        int n = fwrite(tmp, 1, size, f);
        if (n < size)
        {
            fprintf(stderr, "write failed: return %d\n", n);
            exit(1);
        }
        free(tmp);
        fclose(f);
        bc->last_flush_time = now;

        pthread_mutex_lock(&bc->buffer_lock);
        bc->bytes += n;
        bc->curr_bytes += n;
        if (n < bc->wbuf_curr_pos)
        {
            memmove(bc->write_buffer, bc->write_buffer + n, bc->wbuf_curr_pos - n);
        }
        bc->wbuf_start_pos += n;
        bc->wbuf_curr_pos -= n;
        if (bc->wbuf_curr_pos == 0)
        {
            if (bc->wbuf_size < WRITE_BUFFER_SIZE)
            {
                bc->wbuf_size *= 2;
                free(bc->write_buffer);
                bc->write_buffer = (char*)malloc(bc->wbuf_size);
            }
            else if (bc->wbuf_size > WRITE_BUFFER_SIZE * 2)
            {
                bc->wbuf_size = WRITE_BUFFER_SIZE;
                free(bc->write_buffer);
                bc->write_buffer = (char*)malloc(bc->wbuf_size);
            }
        }

        if (bc->wbuf_start_pos + bc->wbuf_size > MAX_BUCKET_SIZE)
        {
            bc_rotate(bc);
        }
    }

    pthread_mutex_unlock(&bc->buffer_lock);
    pthread_mutex_unlock(&bc->flush_lock);
}
コード例 #29
0
ファイル: move.cpp プロジェクト: CliffsDover/wesnoth_ios
void move::execute(bool& success, bool& complete)
{
	if (!valid_) {
		success = false;
		//Setting complete to true signifies to side_actions to delete the planned action.
		complete = true;
		return;
	}

	if (get_source_hex() == get_dest_hex()) {
		//zero-hex move, used by attack subclass
		success = complete = true;
		return;
	}

	LOG_WB << "Executing: " << shared_from_this() << "\n";

	set_arrow_brightness(ARROW_BRIGHTNESS_HIGHLIGHTED);
	hide_fake_unit();

	events::mouse_handler& mouse_handler = resources::controller->get_mouse_handler_base();
	std::set<map_location> adj_enemies = mouse_handler.get_adj_enemies(get_dest_hex(), side_number());

	map_location final_location;
	bool steps_finished;
	bool enemy_sighted;
	{
		team const& owner_team = resources::teams->at(team_index());
		try {
			steps_finished = mouse_handler.move_unit_along_route(*route_, &final_location, owner_team.auto_shroud_updates(), &enemy_sighted);
		} catch (end_turn_exception&) {
			set_arrow_brightness(ARROW_BRIGHTNESS_STANDARD);
			throw; // we rely on the caller to delete this action
		}
		// final_location now contains the final unit location
		// if that isn't needed, pass NULL rather than &final_location
		// Also, enemy_sighted now tells whether a unit was sighted during the move
	}
	if(mouse_handler.get_adj_enemies(final_location,side_number()) != adj_enemies)
		enemy_sighted = true; //< "ambushed" on last hex

	unit_map::const_iterator unit_it;

	if (final_location == route_->steps.front())
	{
		LOG_WB << "Move execution resulted in zero movement.\n";
		success = false;
		complete = true;
	}
	else if (final_location.valid() &&
			(unit_it = resources::units->find(final_location)) != resources::units->end()
			&& unit_it->id() == unit_id_)
	{
		if (steps_finished && route_->steps.back() == final_location) //reached destination
		{
			complete = true;

			//check if new enemies are now visible
			if(enemy_sighted)
			{
				LOG_WB << "Move completed, but interrupted on final hex. Halting.\n";
				//reset to a single-hex path, just in case *this is a wb::attack
				arrow_.reset();
				route_->steps = std::vector<map_location>(1,route_->steps.back());
				success = false;
			}
			else // Everything went smoothly
				success = true;
		}
		else // Move was interrupted, probably by enemy unit sighted
		{
			success = false;

			LOG_WB << "Move finished at (" << final_location << ") instead of at (" << get_dest_hex() << "), analyzing\n";
			std::vector<map_location>::iterator start_new_path;
			bool found = false;
			for (start_new_path = route_->steps.begin(); ((start_new_path != route_->steps.end()) && !found); ++start_new_path)
			{
				if (*start_new_path == final_location)
				{
					found = true;
				}
			}
			if (found)
			{
				--start_new_path; //since the for loop incremented the iterator once after we found the right one.
				std::vector<map_location> new_path(start_new_path, route_->steps.end());
				LOG_WB << "Setting new path for this move from (" << new_path.front()
						<< ") to (" << new_path.back() << ").\n";
				//FIXME: probably better to use the new calculate_new_route instead of doing this
				route_->steps = new_path;
				arrow_->set_path(new_path);
				complete = false;
			}
			else //Unit ended up in location outside path, likely due to a WML event
			{
				WRN_WB << "Unit ended up in location outside path during move execution.\n";
				complete = true;
			}
		}
	}
	else //Unit disappeared from the map, likely due to a WML event
	{
		WRN_WB << "Unit disappeared from map during move execution.\n";
		success = false;
		complete = true;
	}

	if(!complete)
	{
		set_arrow_brightness(ARROW_BRIGHTNESS_STANDARD);
		show_fake_unit();
	}
}
コード例 #30
0
ファイル: filechooser.cpp プロジェクト: raynorpat/cake
const char* file_dialog_show(GtkWidget* parent, bool open, const char* title, const char* path, const char* pattern)
{
  filetype_t type;

  if(pattern == 0)
  {
    pattern = "*";
  }

  FileTypeList typelist;
  GlobalFiletypes().getTypeList(pattern, &typelist);

  GTKMasks masks(typelist);

  if (title == 0)
    title = open ? "Open File" : "Save File";
    
  GtkWidget* dialog;
  if (open)
  {
    dialog = gtk_file_chooser_dialog_new(title,
                                        GTK_WINDOW(parent),
                                        GTK_FILE_CHOOSER_ACTION_OPEN,
                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                        NULL);
  }
  else
  {
    dialog = gtk_file_chooser_dialog_new(title,
                                        GTK_WINDOW(parent),
                                        GTK_FILE_CHOOSER_ACTION_SAVE,
                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                        GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                                        NULL);
    gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "unnamed");
  }

  gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
  gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);

  // we expect an actual path below, if the path is 0 we might crash
  if (path != 0 && !string_empty(path))
  {
    ASSERT_MESSAGE(path_is_absolute(path), "file_dialog_show: path not absolute: " << makeQuoted(path));

    Array<char> new_path(strlen(path)+1);

    // copy path, replacing dir separators as appropriate
    Array<char>::iterator w = new_path.begin();
    for(const char* r = path; *r != '\0'; ++r)
    {
      *w++ = (*r == '/') ? G_DIR_SEPARATOR : *r;
    }
    // remove separator from end of path if required
    if(*(w-1) == G_DIR_SEPARATOR)
    {
      --w;
    }
    // terminate string
    *w = '\0';

    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), new_path.data());
  }

  // we should add all important paths as shortcut folder...
  // gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog), "/tmp/", NULL);

  
  for(std::size_t i = 0; i < masks.m_filters.size(); ++i)
  {
    GtkFileFilter* filter = gtk_file_filter_new();
    gtk_file_filter_add_pattern(filter, masks.m_filters[i].c_str());
    gtk_file_filter_set_name(filter, masks.m_masks[i].c_str());
    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
  }

  if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
  {
    strcpy(g_file_dialog_file, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));

    if(!string_equal(pattern, "*"))
    {
      GtkFileFilter* filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
      if(filter != 0) // no filter set? some file-chooser implementations may allow the user to set no filter, which we treat as 'all files'
      {
        type = masks.GetTypeForGTKMask(gtk_file_filter_get_name(filter)).m_type;
        // last ext separator
        const char* extension = path_get_extension(g_file_dialog_file);
        // no extension
        if(string_empty(extension))
        {
          strcat(g_file_dialog_file, type.pattern+1);
        }
        else
        {
          strcpy(g_file_dialog_file + (extension - g_file_dialog_file), type.pattern+2);
        }
      }
    }

    // convert back to unix format
    for(char* w = g_file_dialog_file; *w!='\0'; w++)
    {
      if(*w=='\\') 
      {
        *w = '/';
      }
    }
  }
  else
  {
    g_file_dialog_file[0] = '\0';
  }

  gtk_widget_destroy(dialog);

  // don't return an empty filename
  if(g_file_dialog_file[0] == '\0') return NULL;

  return g_file_dialog_file;
}