void setup (void) { head = path_init(5.0, 5.0); path_append(6.0, 6.0); path_append(7.0, 7.0); }
PJ_INFO proj_info (void) { /****************************************************************************** Basic info about the current instance of the PROJ.4 library. Returns PJ_INFO struct. ******************************************************************************/ const char * const *paths; size_t i, n; size_t buf_size = 0; char *buf = 0; pj_acquire_lock (); if (0!=info_initialized) { pj_release_lock (); return info; } info.major = PROJ_VERSION_MAJOR; info.minor = PROJ_VERSION_MINOR; info.patch = PROJ_VERSION_PATCH; /* This is a controlled environment, so no risk of sprintf buffer overflow. A normal version string is xx.yy.zz which is 8 characters long and there is room for 64 bytes in the version string. */ sprintf (version, "%d.%d.%d", info.major, info.minor, info.patch); info.searchpath = empty; info.version = version; info.release = pj_get_release (); /* build search path string */ buf = path_append (buf, getenv ("HOME"), &buf_size); buf = path_append (buf, getenv ("PROJ_LIB"), &buf_size); paths = proj_get_searchpath (); n = (size_t) proj_get_path_count (); for (i = 0; i < n; i++) buf = path_append (buf, paths[i], &buf_size); info.searchpath = buf ? buf : empty; info.paths = paths; info.path_count = n; info_initialized = 1; pj_release_lock (); return info; }
static int list_dir(const string& path, const FileRecord& rec, const vector<string>& excludes, vector<FileRecord>* more) { int err; string full = path_append(rec.sourceBase, rec.sourceName); full = path_append(full, path); DIR *d = opendir(full.c_str()); if (d == NULL) { return errno; } vector<string> dirs; struct dirent *ent; while (NULL != (ent = readdir(d))) { if (0 == strcmp(".", ent->d_name) || 0 == strcmp("..", ent->d_name)) { continue; } if (matches_excludes(ent->d_name, excludes)) { continue; } string entry = path_append(path, ent->d_name); #ifdef HAVE_DIRENT_D_TYPE bool is_directory = (ent->d_type == DT_DIR); #else // If dirent.d_type is missing, then use stat instead struct stat stat_buf; stat(entry.c_str(), &stat_buf); bool is_directory = S_ISDIR(stat_buf.st_mode); #endif add_more(entry, is_directory, rec, more); if (is_directory) { dirs.push_back(entry); } } closedir(d); for (vector<string>::iterator it=dirs.begin(); it!=dirs.end(); it++) { list_dir(*it, rec, excludes, more); } return 0; }
bool CONFIG::get_config_include_path(POOL_MEM &full_path, const char *config_dir) { bool found = false; if (m_config_include_dir) { /* * Set full_path to the initial part of the include path, * so it can be used as result, even on errors. * On success, full_path will be overwritten with the full path. */ full_path.strcpy(config_dir); path_append(full_path, m_config_include_dir); if (path_is_directory(full_path)) { m_config_dir = bstrdup(config_dir); /* * Set full_path to wildcard path. */ if (get_path_of_resource(full_path, NULL, NULL, NULL, true)) { m_use_config_include_dir = true; found = true; } } } return found; }
void item_add_path( item *it, char *p ) { if ( it->paths == NULL ) it->paths = path_create(p); else path_append( it->paths, p ); }
Npfcall* diod_lcreate(Npfid *fid, Npstr *name, u32 flags, u32 mode, u32 gid) { Npsrv *srv = fid->conn->srv; Fid *f = fid->aux; Npfcall *ret; Path opath = NULL; if ((f->flags & DIOD_FID_FLAGS_ROFS)) { np_uerror (EROFS); goto error_quiet; } flags = _remap_oflags (flags); if (flags & O_DIRECT) { np_uerror (EINVAL); /* O_DIRECT not allowed - see issue 110 */ goto error_quiet; } if (!(flags & O_CREAT)) /* can't happen? */ flags |= O_CREAT; if (f->ioctx != NULL) { msg ("diod_lcreate: fid is already open"); np_uerror (EINVAL); goto error; } opath = f->path; if (!(f->path = path_append (srv, opath, name))) { np_uerror (ENOMEM); goto error; } if (ioctx_open (fid, flags, mode) < 0) { if (np_rerror () == ENOMEM) goto error; goto error_quiet; } if (!((ret = np_create_rlcreate (ioctx_qid (f->ioctx), ioctx_iounit (f->ioctx))))) { (void)ioctx_close (fid, 0); (void)unlink (path_s (f->path)); np_uerror (ENOMEM); goto error; } path_decref (srv, opath); return ret; error: errn (np_rerror (), "diod_lcreate %s@%s:%s/%.*s", fid->user->uname, np_conn_get_client_id (fid->conn), opath ? path_s (opath) : path_s (f->path), name->len, name->str); error_quiet: if (opath) { if (f->path) path_decref (srv, f->path); f->path = opath; } return NULL; }
END_TEST START_TEST(test_path_append_neg) { Node *path = path_append (-1.0, -1.0); ck_assert_msg (path == NULL, "NULL should be returned on attempt to append with " "a negative value"); }
static void add_more(const string& entry, bool isDir, const FileRecord& rec, vector<FileRecord>*more) { FileRecord r; r.listFile = rec.listFile; r.listLine = rec.listLine; r.sourceName = path_append(rec.sourceName, entry); r.sourcePath = path_append(rec.sourceBase, r.sourceName); struct stat st; int err = stat(r.sourcePath.c_str(), &st); if (err == 0) { r.sourceMod = st.st_mtime; } r.sourceIsDir = isDir; r.outName = path_append(rec.outName, entry); more->push_back(r); }
END_TEST START_TEST(test_path_append_zero) { Node *path = path_append (0.0, 0.0); if (path_current_node(path)->x != 0.0 || path_current_node(path)->y != 0.0) { ck_abort_msg("Zero is a valid value"); } }
static char * make_absolute(char *p, char *pwd) { char *abs_str; /* Derelativise */ if (p && p[0] != '/') { abs_str = path_append(pwd, p); xfree(p); return(abs_str); } else return(p); }
static const char* _get_user_file_path(const char *path, unsigned flags, char* buf, const size_t bufsize) { const char *ret = path; const char *pos = path; /* replace ROCKBOX_DIR in path with $HOME/.config/rockbox.org */ pos += ROCKBOX_DIR_LEN; if (*pos == '/') pos += 1; #if (CONFIG_PLATFORM & PLATFORM_ANDROID) if (path_append(buf, "/sdcard/rockbox", pos, bufsize) >= bufsize) return NULL; #else if (path_append(buf, rbhome, ".config/rockbox.org", bufsize) >= bufsize || path_append(buf, PA_SEP_SOFT, pos, bufsize) >= bufsize) return NULL; #endif /* always return the replacement buffer (pointing to $HOME) if * write access is needed */ if (flags & NEED_WRITE) ret = buf; else if (os_file_exists(buf)) ret = buf; if (ret != buf) /* not found in $HOME, try ROCKBOX_BASE_DIR, !NEED_WRITE only */ { if (path_append(buf, ROCKBOX_SHARE_PATH, pos, bufsize) >= bufsize) return NULL; if (os_file_exists(buf)) ret = buf; } return ret; }
int main (int argc, char **argv) { point **ptoarr = malloc(4 * sizeof(point *)); *ptoarr = point_new(0.0, 0.0); *(ptoarr + 1) = point_new(1.0, 0.0); *(ptoarr + 2) = point_new(0.0, 0.0); ptoarr[3] = point_new(1.0, 0.0); path *p = path_new(ptoarr, 4); path_show(p); printf("The distance is %lf\n", path_length(p)); path_append(p, point_new(2.0, 2.0)); path_show(p); return 0; }
Npfcall* diod_symlink(Npfid *fid, Npstr *name, Npstr *symtgt, u32 gid) { Npsrv *srv = fid->conn->srv; Fid *f = fid->aux; Npfcall *ret; char *target = NULL; Path npath = NULL; Npqid qid; struct stat sb; if ((f->flags & DIOD_FID_FLAGS_ROFS)) { np_uerror (EROFS); goto error_quiet; } if (!(npath = path_append (srv, f->path, name))) { np_uerror (ENOMEM); goto error; } if (!(target = np_strdup (symtgt))) { np_uerror (ENOMEM); goto error; } if (symlink (target, path_s (npath)) < 0 || lstat (path_s (npath), &sb) < 0) { np_uerror (errno); goto error_quiet; } diod_ustat2qid (&sb, &qid); if (!((ret = np_create_rsymlink (&qid)))) { (void)unlink (path_s (npath)); np_uerror (ENOMEM); goto error; } path_decref (srv, npath); free (target); return ret; error: errn (np_rerror (), "diod_symlink %s@%s:%s/%.*s", fid->user->uname, np_conn_get_client_id (fid->conn), path_s (f->path), name->len, name->str); error_quiet: if (npath) path_decref (srv, npath); if (target) free (target); return NULL; }
void stat_out(const string& base, FileRecord* rec) { rec->outPath = path_append(base, rec->outName); int err; struct stat st; err = stat(rec->outPath.c_str(), &st); if (err == 0) { rec->outMod = st.st_mtime; rec->outIsDir = S_ISDIR(st.st_mode); } else { rec->outMod = 0; rec->outIsDir = false; } }
char* path_subdirectory_name( const char* path, const char* root ) { char* subpath; char* testpath; char* testroot; char* pathofpath; unsigned int pathprotocol, rootprotocol; char* cpath = string_clone( path ); char* croot = string_clone( root ); cpath = path_clean( cpath, path_is_absolute( cpath ) ); croot = path_clean( croot, path_is_absolute( croot ) ); pathofpath = path_directory_name( cpath ); testpath = pathofpath; pathprotocol = string_find_string( testpath, "://", 0 ); if( pathprotocol != STRING_NPOS ) testpath += pathprotocol + 2; // add two to treat as absolute path testroot = croot; rootprotocol = string_find_string( testroot, "://", 0 ); if( rootprotocol != STRING_NPOS ) testroot += rootprotocol + 2; if( ( rootprotocol != STRING_NPOS ) && ( ( pathprotocol == STRING_NPOS ) || ( pathprotocol != rootprotocol ) || !string_equal_substr( cpath, croot, rootprotocol ) ) ) subpath = string_allocate( 0 ); else if( !string_equal_substr( testpath, testroot, string_length( testroot ) ) ) subpath = string_allocate( 0 ); else { char* filename = path_file_name( cpath ); subpath = string_substr( testpath, string_length( testroot ), STRING_NPOS ); subpath = path_clean( path_append( subpath, filename ), false ); string_deallocate( filename ); } string_deallocate( pathofpath ); string_deallocate( cpath ); string_deallocate( croot ); return subpath; }
/* Twalk - walk a file path * Called from fcall.c::np_walk () on each wname component in succession. * On error, call np_uerror () and return 0. */ int diod_walk (Npfid *fid, Npstr* wname, Npqid *wqid) { Npsrv *srv = fid->conn->srv; Fid *f = fid->aux; struct stat sb, sb2; Path npath = NULL; if ((f->flags & DIOD_FID_FLAGS_MOUNTPT)) { np_uerror (ENOENT); goto error_quiet; } if (!(npath = path_append (srv, f->path, wname))) { np_uerror (ENOMEM); goto error; } if (lstat (path_s (npath), &sb) < 0) { np_uerror (errno); goto error_quiet; } if (lstat (path_s (f->path), &sb2) < 0) { np_uerror (errno); goto error; } if (sb.st_dev != sb2.st_dev) { if (_statmnt (path_s (npath), &sb) < 0) goto error; f->flags |= DIOD_FID_FLAGS_MOUNTPT; } path_decref (srv, f->path); f->path = npath; diod_ustat2qid (&sb, wqid); return 1; error: errn (np_rerror (), "diod_walk %s@%s:%s/%.*s", fid->user->uname, np_conn_get_client_id (fid->conn), path_s (f->path), wname->len, wname->str); error_quiet: if (npath) path_decref (srv, npath); return 0; }
bool CONFIG::get_config_file(POOL_MEM &full_path, const char *config_dir, const char *config_filename) { bool found = false; if (!path_is_directory(config_dir)) { return false; } if (config_filename) { full_path.strcpy(config_dir); if (path_append(full_path, config_filename)) { if (path_exists(full_path)) { m_config_dir = bstrdup(config_dir); found = true; } } } return found; }
/* Trename - rename a file, potentially to another directory */ Npfcall* diod_rename (Npfid *fid, Npfid *dfid, Npstr *name) { Npsrv *srv = fid->conn->srv; Fid *f = fid->aux; Fid *d = dfid->aux; Npfcall *ret; Path npath = NULL; int renamed = 0; if ((f->flags & DIOD_FID_FLAGS_ROFS)) { np_uerror (EROFS); goto error_quiet; } if (!(npath = path_append (srv, d->path, name))) { np_uerror (ENOMEM); goto error; } if (rename (path_s (f->path), path_s (npath)) < 0) { np_uerror (errno); goto error_quiet; } renamed = 1; if (!(ret = np_create_rrename ())) { np_uerror (ENOMEM); goto error; } path_decref (srv, f->path); f->path = npath; return ret; error: errn (np_rerror (), "diod_rename %s@%s:%s to %s/%.*s", fid->user->uname, np_conn_get_client_id (fid->conn), path_s (f->path), path_s (d->path), name->len, name->str); error_quiet: if (renamed && npath) (void)rename (path_s (npath), path_s (f->path)); if (npath) path_decref (srv, npath); return NULL; }
Npfcall* diod_mknod(Npfid *fid, Npstr *name, u32 mode, u32 major, u32 minor, u32 gid) { Npsrv *srv = fid->conn->srv; Npfcall *ret; Fid *f = fid->aux; Path npath = NULL; Npqid qid; struct stat sb; if ((f->flags & DIOD_FID_FLAGS_ROFS)) { np_uerror (EROFS); goto error_quiet; } if (!(npath = path_append (srv, f->path, name))) { np_uerror (ENOMEM); goto error; } if (mknod (path_s (npath), mode, makedev (major, minor)) < 0 || lstat (path_s (npath), &sb) < 0) { np_uerror (errno); goto error_quiet; } diod_ustat2qid (&sb, &qid); if (!((ret = np_create_rmknod (&qid)))) { (void)unlink (path_s (npath)); np_uerror (ENOMEM); goto error; } path_decref (srv, npath); return ret; error: errn (np_rerror (), "diod_mknod %s@%s:%s/%.*s", fid->user->uname, np_conn_get_client_id (fid->conn), path_s (f->path), name->len, name->str); error_quiet: if (npath) path_decref (srv, npath); return NULL; }
const char* environment_home_directory( void ) { if( _environment_home_dir[0] ) return _environment_home_dir; #if FOUNDATION_PLATFORM_WINDOWS { char* path; wchar_t* wpath = memory_allocate_zero( sizeof( wchar_t ) * FOUNDATION_MAX_PATHLEN, 0, MEMORY_TEMPORARY ); SHGetFolderPathW( 0, CSIDL_LOCAL_APPDATA, 0, 0, wpath ); path = path_clean( string_allocate_from_wstring( wpath, 0 ), true ); string_copy( _environment_home_dir, path, FOUNDATION_MAX_PATHLEN ); string_deallocate( path ); memory_deallocate( wpath ); } #elif FOUNDATION_PLATFORM_LINUX string_copy( _environment_home_dir, environment_variable( "HOME" ), FOUNDATION_MAX_PATHLEN ); #elif FOUNDATION_PLATFORM_APPLE if( environment_application()->flags & APPLICATION_UTILITY ) { CFStringRef home = NSHomeDirectory(); CFStringGetCString( home, _environment_home_dir, FOUNDATION_MAX_PATHLEN, kCFStringEncodingUTF8 ); } else { char bundle_identifier[FOUNDATION_MAX_PATHLEN+1]; environment_bundle_identifier( bundle_identifier ); char* path = path_append( path_merge( _environment_home_dir, "/Library/Application Support" ), bundle_identifier ); string_copy( _environment_home_dir, path, FOUNDATION_MAX_PATHLEN ); string_deallocate( path ); } #elif FOUNDATION_PLATFORM_ANDROID string_copy( _environment_home_dir, android_app()->activity->internalDataPath, FOUNDATION_MAX_PATHLEN ); #else # error Not implemented #endif return _environment_home_dir; }
bool CONFIG::get_path_of_resource(POOL_MEM &path, const char *component, const char *resourcetype, const char *name, bool set_wildcards) { POOL_MEM rel_path(PM_FNAME); POOL_MEM directory(PM_FNAME); POOL_MEM resourcetype_lowercase(resourcetype); resourcetype_lowercase.toLower(); if (!component) { if (m_config_include_dir) { component = m_config_include_dir; } else { return false; } } if (resourcetype_lowercase.strlen() <= 0) { if (set_wildcards) { resourcetype_lowercase.strcpy("*"); } else { return false; } } if (!name) { if (set_wildcards) { name = "*"; } else { return false; } } path.strcpy(m_config_dir); rel_path.bsprintf(m_config_include_naming_format, component, resourcetype_lowercase.c_str(), name); path_append(path, rel_path); return true; }
int locate(FileRecord* rec, const vector<string>& search) { int err; for (vector<string>::const_iterator it=search.begin(); it!=search.end(); it++) { string full = path_append(*it, rec->sourceName); struct stat st; err = stat(full.c_str(), &st); if (err == 0) { rec->sourceBase = *it; rec->sourcePath = full; rec->sourceMod = st.st_mtime; rec->sourceIsDir = S_ISDIR(st.st_mode); return 0; } } fprintf(stderr, "%s:%d: couldn't locate source file: %s\n", rec->listFile.c_str(), rec->listLine, rec->sourceName.c_str()); return 1; }
Npfcall* diod_link (Npfid *dfid, Npfid *fid, Npstr *name) { Npsrv *srv = fid->conn->srv; Fid *f = fid->aux; Npfcall *ret; Fid *df = dfid->aux; Path npath = NULL; if ((f->flags & DIOD_FID_FLAGS_ROFS)) { np_uerror (EROFS); goto error_quiet; } if (!(npath = path_append (srv, df->path, name))) { np_uerror (ENOMEM); goto error; } if (link (path_s (f->path), path_s (npath)) < 0) { np_uerror (errno); goto error_quiet; } if (!((ret = np_create_rlink ()))) { (void)unlink (path_s (npath)); np_uerror (ENOMEM); goto error; } path_decref (srv, npath); return ret; error: errn (np_rerror (), "diod_link %s@%s:%s %s/%.*s", fid->user->uname, np_conn_get_client_id (fid->conn), path_s (f->path), path_s (df->path), name->len, name->str); error_quiet: if (npath) path_decref (srv, npath); return NULL; }
//void svc_start(struct listitem *li, int strict) void svc_start(struct listitem *li) { char buf[CINIT_DATA_LEN]; struct timespec ts; int delay = 0; /* FIXME: to be calculated by waitpid status, if respawing */ /* first update status before forking ! */ if(li->status & CINIT_ST_SH_ONCE) li->status = CINIT_ST_ONCE_RUN; else li->status = CINIT_ST_RESPAWNING; /* set start time */ li->start = time(NULL); /* * FIXME: All cleanup must go here close(fds); reset signals reset env? * FIXME: Add logging possibility to here open (0,1,2) to other processes, * if specified */ /* * BUG: the following child may return _before_ the fork returns in the * parent. Thus this pid may not be registered. And that's the reason why * we need the global svc_lock! */ li->pid = fork(); /********************** parent ************************/ if(li->pid > 0) { printf("%s is at %d\n", li->abs_path, li->pid); return; } /********************** Error ************************/ if(li->pid < 0) { svc_report_status(li->abs_path, MSG_SVC_FORK, strerror(errno)); svc_set_status(li, CINIT_ST_BAD_ERR); return; } /********************** Client / fork() ************************/ /* * sleep, if necesseray */ if(delay) { ts.tv_sec = delay; ts.tv_nsec = 0; /* * FIXME: also report value; int2char */ printf("Delay: %d\n", delay); svc_report_status(li->abs_path, MSG_SVC_SLEEP, NULL); /* * do not need to check for errors, because we can continue anyway */ /* * WRONG: FIXME: look whether to sleep again */ nanosleep(&ts, NULL); } svc_report_status(li->abs_path, MSG_SVC_START, NULL); cinit_cp_data(buf, li->abs_path); if(!path_append(buf, C_ON)) return; /* * Check for existence */ li->status = file_exists(buf); if(li->status == FE_NOT) { svc_report_status(li->abs_path, "Nothing to execute :-)", NULL); _exit(0); /* nothing there? fine! */ } if(li->status == FE_FILE) { /* FIXME: I guess this a) does nothing b) should do more than only signals */ set_signals(SIGSTAGE_CLIENT); execute_sth(buf); } else { /* any kind of error, reported by file_exists already */ _exit(1); } }
void metacortex_find_subgraphs(dBGraph* graph, char* consensus_contigs_filename, int min_subgraph_kmers) { SubGraphInfo* sub_graphs; FILE* fp; Path *path_fwd = path_new(MAX_EXPLORE_PATH_LENGTH, graph->kmer_size); Path *path_rev = path_new(MAX_EXPLORE_PATH_LENGTH, graph->kmer_size); Path *final_path = path_new(MAX_EXPLORE_PATH_LENGTH, graph->kmer_size); char seq[256]; char analysis_filename[strlen(consensus_contigs_filename) + 10]; long int total_nodes = 0; int n_seeds = 0; int i; sprintf(analysis_filename, "%s.analysis", consensus_contigs_filename); log_and_screen_printf("Running metacortex subgraph analysis...\n"); log_and_screen_printf(" Contig file: %s\n", consensus_contigs_filename); log_and_screen_printf(" Analysis file: %s\n", analysis_filename); log_and_screen_printf("Minimum subgraph size: %i\n", min_subgraph_kmers); /* Initialise temporaray path array buffers */ path_array_initialise_buffers(graph->kmer_size); /* Create a list of subgraphs */ log_and_screen_printf("Allocating %d Mb to store subgraph information (max %d seeds)...\n", ((MAX_SEEDS * sizeof(SubGraphInfo)) / 1024) / 1024, MAX_SEEDS); sub_graphs = calloc(MAX_SEEDS, sizeof(SubGraphInfo)); if (!sub_graphs) { log_and_screen_printf("ERROR: Can't get memory for subgraphs\n"); exit(-1); } /* Open the analysis file */ fp = fopen(analysis_filename, "w"); if (!fp) { log_and_screen_printf("ERROR: Can't open analysis file.\n"); exit(-1); } /* For each node, if it's not pruned or visited, try and grow a graph */ void explore_node(dBNode * node) { if (node == NULL) { log_and_screen_printf("Error: NULL node passed to explore_node.\n"); exit(-1); } if (db_node_check_for_any_flag(node, PRUNED | VISITED) == false) { int nodes_in_graph; /* Grow graph from this node, returning the 'best' (highest coverage) node to store as seed point */ nodes_in_graph = grow_graph_from_node(node, &(sub_graphs[n_seeds].seed_node), graph); total_nodes += nodes_in_graph; if (sub_graphs[n_seeds].seed_node == NULL) { printf("ERROR: Seed node is NULL, nodes in graph is %d\n", nodes_in_graph); } else { /* Write data to analysis file */ binary_kmer_to_seq(&(node->kmer), graph->kmer_size, seq); fprintf(fp, "%i\t%i\t%ld\t%s\t", n_seeds, nodes_in_graph, total_nodes, seq); binary_kmer_to_seq(&(sub_graphs[n_seeds].seed_node->kmer), graph->kmer_size, seq); fprintf(fp, "%s\n", seq); /* Store nodes in this subgraph */ sub_graphs[n_seeds].graph_size = nodes_in_graph; n_seeds++; /* Check we've not run out of seed storage - in future, this should dynamically allocate */ if (n_seeds == MAX_SEEDS) { log_and_screen_printf("Error: MAX_SEEDS exceeded. Quitting.\n"); exit(-1); } } } } /* Traverse each node... */ log_and_screen_printf("Finding subgraphs...\n"); hash_table_traverse(&explore_node, graph); log_and_screen_printf("Finished. Total: %ld\n", total_nodes); fclose(fp); /* Open consensus contigs file */ fp = fopen(consensus_contigs_filename, "w"); if (!fp) { log_and_screen_printf("ERROR: Can't open contig file.\n"); exit(-1); } /* Now go through all the seed points and generate the consensus contigs by walking forward and backward from the seed */ db_graph_reset_flags(graph); log_and_screen_printf("Outputting contigs...\n"); log_progress_bar(0); long long one_percent = n_seeds/100; int percent; if (one_percent < 1) { one_percent = 1; } for (i=0; i<n_seeds; i++) { if (i % one_percent == 0) { percent = (100 * i) / n_seeds; log_progress_bar(percent); } //log_printf("Graph %i\n", i); if (sub_graphs[i].graph_size >= min_subgraph_kmers) { binary_kmer_to_seq(&(sub_graphs[i].seed_node->kmer), graph->kmer_size, seq); coverage_walk_get_path(sub_graphs[i].seed_node, forward, NULL, graph, path_fwd); coverage_walk_get_path(sub_graphs[i].seed_node, reverse, NULL, graph, path_rev); path_reverse(path_fwd, final_path); path_append(final_path, path_rev); final_path->id = i; path_to_fasta(final_path, fp); //log_printf(" Seed %s\tFwd path length %i\tRev path length %i\tFinal path length %i\n", seq, path_fwd->length, path_rev->length, final_path->length); path_reset(path_fwd); perfect_path_get_path(sub_graphs[i].seed_node, forward, &db_node_action_do_nothing, graph, path_fwd); //log_printf("\t\tPerfect path fwd length %i\n", path_fwd->length); path_reset(path_rev); path_reset(final_path); } else { log_printf(" Number of nodes (%i} too small. Not outputting contig.\n", sub_graphs[i].graph_size); } } log_progress_bar(100); printf("\n"); log_and_screen_printf("Finished contig output.\n"); fclose(fp); free(sub_graphs); }
DECLARE_TEST( fs, query ) { uint64_t subpathid = random64(); uint64_t subfileid = random64(); char* testpath = path_merge( environment_temporary_directory(), string_from_int_static( random64(), 0, 0 ) ); char* subtestpath = path_merge( testpath, string_from_int_static( subpathid, 0, 0 ) ); char* filepath[8]; char** subdirs; char** files; int ifp = 0; char* subfilepath; if( fs_is_file( testpath ) ) fs_remove_file( testpath ); if( !fs_is_directory( testpath ) ) fs_make_directory( testpath ); if( !fs_is_directory( subtestpath ) ) fs_make_directory( subtestpath ); for( ifp = 0; ifp < 8; ++ifp ) { filepath[ifp] = path_merge( testpath, string_from_int_static( random64(), 0, 0 ) ); filepath[ifp] = string_append( string_append( filepath[ifp], "." ), string_from_int_static( ifp, 0, 0 ) ); stream_deallocate( fs_open_file( filepath[ifp], STREAM_OUT ) ); } subfilepath = path_merge( subtestpath, string_from_int_static( subfileid, 0, 0 ) ); subfilepath = string_append( subfilepath, ".0" ); stream_deallocate( fs_open_file( subfilepath, STREAM_OUT ) ); files = fs_files( filepath[0] ); EXPECT_EQ( array_size( files ), 0 ); string_array_deallocate( files ); subdirs = fs_subdirs( subtestpath ); EXPECT_EQ( array_size( subdirs ), 0 ); string_array_deallocate( subdirs ); files = fs_files( testpath ); EXPECT_EQ( array_size( files ), 8 ); string_array_deallocate( files ); subdirs = fs_subdirs( testpath ); EXPECT_EQ( array_size( subdirs ), 1 ); string_array_deallocate( subdirs ); files = fs_matching_files( testpath, "*", false ); EXPECT_EQ( array_size( files ), 8 ); string_array_deallocate( files ); files = fs_matching_files( testpath, "*", true ); EXPECT_EQ( array_size( files ), 9 ); string_array_deallocate( files ); files = fs_matching_files( testpath, "*.0", false ); EXPECT_EQ( array_size( files ), 1 ); string_array_deallocate( files ); files = fs_matching_files( testpath, "*.0", true ); EXPECT_EQ( array_size( files ), 2 ); string_array_deallocate( files ); files = fs_matching_files( testpath, "*.1", false ); EXPECT_EQ( array_size( files ), 1 ); string_array_deallocate( files ); files = fs_matching_files( testpath, "*.1", true ); EXPECT_EQ( array_size( files ), 1 ); string_array_deallocate( files ); files = fs_matching_files( testpath, "*.?", true ); EXPECT_EQ( array_size( files ), 9 ); { char* verifypath = string_from_int( subpathid, 0, 0 ); verifypath = path_append( verifypath, string_from_int_static( subfileid, 0, 0 ) ); verifypath = string_append( verifypath, ".0" ); EXPECT_STREQ( files[8], verifypath ); string_deallocate( verifypath ); } string_array_deallocate( files ); fs_remove_directory( testpath ); string_array_deallocate( subdirs ); string_array_deallocate( files ); string_deallocate( subfilepath ); for( ifp = 0; ifp < 8; ++ifp ) string_deallocate( filepath[ifp] ); string_deallocate( subtestpath ); string_deallocate( testpath ); return 0; }
int main(int argc, char **argv) { char *me = argv[0], *data, **new_argv; char *exe_path, *lib_path, *dll_path; int start, prog_end, end, count, fd, v, en, x11; int argpos, inpos, collcount = 1, fix_argv; if (config[7] == '[') { write_str(2, argv[0]); write_str(2, ": this is an unconfigured starter\n"); return 1; } if (me[0] == '/') { /* Absolute path */ } else if (has_slash(me)) { /* Relative path with a directory: */ char *buf; long buflen = 4096; buf = (char *)malloc(buflen); me = path_append(getcwd(buf, buflen), me); } else { /* We have to find the executable by searching PATH: */ char *path = copy_string(getenv("PATH")), *p, *m; int more; if (!path) { path = ""; } while (1) { /* Try each element of path: */ for (p = path; *p && (*p != ':'); p++) { } if (*p) { *p = 0; more = 1; } else more = 0; if (!*path) break; m = path_append(path, me); if (executable_exists(m)) { if (m[0] != '/') m = path_append(getcwd(NULL, 0), m); me = m; break; } free(m); if (more) path = p + 1; else break; } } /* me is now an absolute path to the binary */ /* resolve soft links */ while (1) { int len, bufsize = 127; char *buf; buf = (char *)malloc(bufsize + 1); len = readlink(me, buf, bufsize); if (len < 0) { if (errno == ENAMETOOLONG) { /* Increase buffer size and try again: */ bufsize *= 2; buf = (char *)malloc(bufsize + 1); } else break; } else { /* Resolve buf relative to me: */ buf[len] = 0; buf = absolutize(buf, me); me = buf; buf = (char *)malloc(bufsize + 1); } } start = as_int(config + 8); prog_end = as_int(config + 12); end = as_int(config + 16); count = as_int(config + 20); x11 = as_int(config + 24); fix_argv = try_elf_section(me, &start, &prog_end, &end); { int offset, len; offset = _coldir_offset; while (1) { len = strlen(_coldir + offset); offset += len + 1; if (!_coldir[offset]) break; collcount++; } } data = (char *)malloc(end - prog_end); new_argv = (char **)malloc((count + argc + (2 * collcount) + 8) * sizeof(char*)); fd = open(me, O_RDONLY, 0); lseek(fd, prog_end, SEEK_SET); { int expected_length = end - prog_end; if (expected_length != read(fd, data, expected_length)) { printf("read failed to read all %i bytes from file %s\n", expected_length, me); abort(); } } close(fd); exe_path = data; data = next_string(data); lib_path = data; data = next_string(data); exe_path = absolutize(exe_path, me); lib_path = absolutize(lib_path, me); # ifdef OS_X # define LD_LIB_PATH "DYLD_LIBRARY_PATH" # else # define LD_LIB_PATH "LD_LIBRARY_PATH" # endif if (*lib_path) { dll_path = getenv(LD_LIB_PATH); if (!dll_path) { dll_path = ""; } dll_path = string_append(dll_path, ":"); dll_path = string_append(lib_path, dll_path); dll_path = string_append(LD_LIB_PATH "=", dll_path); putenv(dll_path); } new_argv[0] = me; argpos = 1; inpos = 1; /* Keep all X11 flags to the front: */ if (x11) { int n; while (inpos < argc) { n = is_x_flag(argv[inpos]); if (!n) break; if (inpos + n > argc) { write_str(2, argv[0]); write_str(2, ": missing an argument for "); write_str(2, argv[inpos]); write_str(2, "\n"); return 1; } while (n--) { new_argv[argpos++] = argv[inpos++]; } } } /* Add -X and -S flags */ { int offset, len; offset = _coldir_offset; new_argv[argpos++] = "-X"; new_argv[argpos++] = absolutize(_coldir + offset, me); while (1) { len = strlen(_coldir + offset); offset += len + 1; if (!_coldir[offset]) break; new_argv[argpos++] = "-S"; new_argv[argpos++] = absolutize(_coldir + offset, me); } } if (fix_argv) { /* next three args are "-k" and numbers; fix the numbers to match start and prog_end */ fix_argv = argpos + 1; } /* Add built-in flags: */ while (count--) { new_argv[argpos++] = data; data = next_string(data); } /* Propagate new flags (after the X11 flags) */ while (inpos < argc) { new_argv[argpos++] = argv[inpos++]; } new_argv[argpos] = NULL; if (fix_argv) { new_argv[fix_argv] = num_to_string(start); new_argv[fix_argv+1] = num_to_string(prog_end); } /* Execute the original binary: */ v = execv(exe_path, new_argv); en = errno; write_str(2, argv[0]); write_str(2, ": failed to start "); write_str(2, exe_path); write_str(2, " ("); write_str(2, strerror(en)); write_str(2, ")\n"); if (*lib_path) { write_str(2, " used library path "); write_str(2, lib_path); write_str(2, "\n"); } return v; }
jv jq_next(jq_state *jq) { jv cfunc_input[MAX_CFUNCTION_ARGS]; jv_nomem_handler(jq->nomem_handler, jq->nomem_handler_data); uint16_t* pc = stack_restore(jq); assert(pc); int backtracking = !jq->initial_execution; jq->initial_execution = 0; while (1) { uint16_t opcode = *pc; if (jq->debug_trace_enabled) { dump_operation(frame_current(jq)->bc, pc); printf("\t"); const struct opcode_description* opdesc = opcode_describe(opcode); stack_ptr param = 0; if (!backtracking) { int stack_in = opdesc->stack_in; if (stack_in == -1) stack_in = pc[1]; int i; for (i=0; i<stack_in; i++) { if (i == 0) { param = jq->stk_top; } else { printf(" | "); param = *stack_block_next(&jq->stk, param); } if (!param) break; jv_dump(jv_copy(*(jv*)stack_block(&jq->stk, param)), 0); //printf("<%d>", jv_get_refcnt(param->val)); //printf(" -- "); //jv_dump(jv_copy(jq->path), 0); } } else { printf("\t<backtracking>"); } printf("\n"); } if (backtracking) { opcode = ON_BACKTRACK(opcode); backtracking = 0; } pc++; switch (opcode) { default: assert(0 && "invalid instruction"); case LOADK: { jv v = jv_array_get(jv_copy(frame_current(jq)->bc->constants), *pc++); assert(jv_is_valid(v)); jv_free(stack_pop(jq)); stack_push(jq, v); break; } case DUP: { jv v = stack_pop(jq); stack_push(jq, jv_copy(v)); stack_push(jq, v); break; } case DUP2: { jv keep = stack_pop(jq); jv v = stack_pop(jq); stack_push(jq, jv_copy(v)); stack_push(jq, keep); stack_push(jq, v); break; } case SUBEXP_BEGIN: { jv v = stack_pop(jq); stack_push(jq, jv_copy(v)); stack_push(jq, v); jq->subexp_nest++; break; } case SUBEXP_END: { assert(jq->subexp_nest > 0); jq->subexp_nest--; jv a = stack_pop(jq); jv b = stack_pop(jq); stack_push(jq, a); stack_push(jq, b); break; } case POP: { jv_free(stack_pop(jq)); break; } case APPEND: { jv v = stack_pop(jq); uint16_t level = *pc++; uint16_t vidx = *pc++; jv* var = frame_local_var(jq, vidx, level); assert(jv_get_kind(*var) == JV_KIND_ARRAY); *var = jv_array_append(*var, v); break; } case INSERT: { jv stktop = stack_pop(jq); jv v = stack_pop(jq); jv k = stack_pop(jq); jv objv = stack_pop(jq); assert(jv_get_kind(objv) == JV_KIND_OBJECT); if (jv_get_kind(k) == JV_KIND_STRING) { stack_push(jq, jv_object_set(objv, k, v)); stack_push(jq, stktop); } else { print_error(jq, jv_invalid_with_msg(jv_string_fmt("Cannot use %s as object key", jv_kind_name(jv_get_kind(k))))); jv_free(stktop); jv_free(v); jv_free(k); jv_free(objv); goto do_backtrack; } break; } case ON_BACKTRACK(RANGE): case RANGE: { uint16_t level = *pc++; uint16_t v = *pc++; jv* var = frame_local_var(jq, v, level); jv max = stack_pop(jq); if (jv_get_kind(*var) != JV_KIND_NUMBER || jv_get_kind(max) != JV_KIND_NUMBER) { print_error(jq, jv_invalid_with_msg(jv_string_fmt("Range bounds must be numeric"))); jv_free(max); goto do_backtrack; } else if (jv_number_value(jv_copy(*var)) >= jv_number_value(jv_copy(max))) { /* finished iterating */ goto do_backtrack; } else { jv curr = jv_copy(*var); *var = jv_number(jv_number_value(*var) + 1); struct stack_pos spos = stack_get_pos(jq); stack_push(jq, jv_copy(max)); stack_save(jq, pc - 3, spos); stack_push(jq, curr); } break; } // FIXME: loadv/storev may do too much copying/freeing case LOADV: { uint16_t level = *pc++; uint16_t v = *pc++; jv* var = frame_local_var(jq, v, level); if (jq->debug_trace_enabled) { printf("V%d = ", v); jv_dump(jv_copy(*var), 0); printf("\n"); } jv_free(stack_pop(jq)); stack_push(jq, jv_copy(*var)); break; } // Does a load but replaces the variable with null case LOADVN: { uint16_t level = *pc++; uint16_t v = *pc++; jv* var = frame_local_var(jq, v, level); if (jq->debug_trace_enabled) { printf("V%d = ", v); jv_dump(jv_copy(*var), 0); printf("\n"); } jv_free(stack_pop(jq)); stack_push(jq, *var); *var = jv_null(); break; } case STOREV: { uint16_t level = *pc++; uint16_t v = *pc++; jv* var = frame_local_var(jq, v, level); jv val = stack_pop(jq); if (jq->debug_trace_enabled) { printf("V%d = ", v); jv_dump(jv_copy(val), 0); printf("\n"); } jv_free(*var); *var = val; break; } case PATH_BEGIN: { jv v = stack_pop(jq); stack_push(jq, jq->path); stack_save(jq, pc - 1, stack_get_pos(jq)); stack_push(jq, jv_number(jq->subexp_nest)); stack_push(jq, v); jq->path = jv_array(); jq->subexp_nest = 0; break; } case PATH_END: { jv v = stack_pop(jq); jv_free(v); // discard value, only keep path int old_subexp_nest = (int)jv_number_value(stack_pop(jq)); jv path = jq->path; jq->path = stack_pop(jq); struct stack_pos spos = stack_get_pos(jq); stack_push(jq, jv_copy(path)); stack_save(jq, pc - 1, spos); stack_push(jq, path); jq->subexp_nest = old_subexp_nest; break; } case ON_BACKTRACK(PATH_BEGIN): case ON_BACKTRACK(PATH_END): { jv_free(jq->path); jq->path = stack_pop(jq); goto do_backtrack; } case INDEX: case INDEX_OPT: { jv t = stack_pop(jq); jv k = stack_pop(jq); path_append(jq, jv_copy(k)); jv v = jv_get(t, k); if (jv_is_valid(v)) { stack_push(jq, v); } else { if (opcode == INDEX) print_error(jq, v); else jv_free(v); goto do_backtrack; } break; } case JUMP: { uint16_t offset = *pc++; pc += offset; break; } case JUMP_F: { uint16_t offset = *pc++; jv t = stack_pop(jq); jv_kind kind = jv_get_kind(t); if (kind == JV_KIND_FALSE || kind == JV_KIND_NULL) { pc += offset; } stack_push(jq, t); // FIXME do this better break; } case EACH: case EACH_OPT: stack_push(jq, jv_number(-1)); // fallthrough case ON_BACKTRACK(EACH): case ON_BACKTRACK(EACH_OPT): { int idx = jv_number_value(stack_pop(jq)); jv container = stack_pop(jq); int keep_going, is_last = 0; jv key, value; if (jv_get_kind(container) == JV_KIND_ARRAY) { if (opcode == EACH || opcode == EACH_OPT) idx = 0; else idx = idx + 1; int len = jv_array_length(jv_copy(container)); keep_going = idx < len; is_last = idx == len - 1; if (keep_going) { key = jv_number(idx); value = jv_array_get(jv_copy(container), idx); } } else if (jv_get_kind(container) == JV_KIND_OBJECT) { if (opcode == EACH || opcode == EACH_OPT) idx = jv_object_iter(container); else idx = jv_object_iter_next(container, idx); keep_going = jv_object_iter_valid(container, idx); if (keep_going) { key = jv_object_iter_key(container, idx); value = jv_object_iter_value(container, idx); } } else { assert(opcode == EACH || opcode == EACH_OPT); if (opcode == EACH) { print_error(jq, jv_invalid_with_msg(jv_string_fmt("Cannot iterate over %s", jv_kind_name(jv_get_kind(container))))); } keep_going = 0; } if (!keep_going) { jv_free(container); goto do_backtrack; } else if (is_last) { // we don't need to make a backtrack point jv_free(container); path_append(jq, key); stack_push(jq, value); } else { struct stack_pos spos = stack_get_pos(jq); stack_push(jq, container); stack_push(jq, jv_number(idx)); stack_save(jq, pc - 1, spos); path_append(jq, key); stack_push(jq, value); } break; } do_backtrack: case BACKTRACK: { pc = stack_restore(jq); if (!pc) { return jv_invalid(); } backtracking = 1; break; } case FORK: { stack_save(jq, pc - 1, stack_get_pos(jq)); pc++; // skip offset this time break; } case ON_BACKTRACK(FORK): { uint16_t offset = *pc++; pc += offset; break; } case CALL_BUILTIN: { int nargs = *pc++; jv top = stack_pop(jq); jv* in = cfunc_input; int i; in[0] = top; for (i = 1; i < nargs; i++) { in[i] = stack_pop(jq); } struct cfunction* function = &frame_current(jq)->bc->globals->cfunctions[*pc++]; typedef jv (*func_1)(jv); typedef jv (*func_2)(jv,jv); typedef jv (*func_3)(jv,jv,jv); typedef jv (*func_4)(jv,jv,jv,jv); typedef jv (*func_5)(jv,jv,jv,jv,jv); switch (function->nargs) { case 1: top = ((func_1)function->fptr)(in[0]); break; case 2: top = ((func_2)function->fptr)(in[0], in[1]); break; case 3: top = ((func_3)function->fptr)(in[0], in[1], in[2]); break; case 4: top = ((func_4)function->fptr)(in[0], in[1], in[2], in[3]); break; case 5: top = ((func_5)function->fptr)(in[0], in[1], in[2], in[3], in[4]); break; default: return jv_invalid_with_msg(jv_string("Function takes too many arguments")); } if (jv_is_valid(top)) { stack_push(jq, top); } else { print_error(jq, top); goto do_backtrack; } break; } case CALL_JQ: { jv input = stack_pop(jq); uint16_t nclosures = *pc++; uint16_t* retaddr = pc + 2 + nclosures*2; struct frame* new_frame = frame_push(jq, make_closure(jq, pc), pc + 2, nclosures); new_frame->retdata = jq->stk_top; new_frame->retaddr = retaddr; pc = new_frame->bc->code; stack_push(jq, input); break; } case RET: { jv value = stack_pop(jq); assert(jq->stk_top == frame_current(jq)->retdata); uint16_t* retaddr = frame_current(jq)->retaddr; if (retaddr) { // function return pc = retaddr; frame_pop(jq); } else { // top-level return, yielding value struct stack_pos spos = stack_get_pos(jq); stack_push(jq, jv_null()); stack_save(jq, pc - 1, spos); return value; } stack_push(jq, value); break; } case ON_BACKTRACK(RET): { // resumed after top-level return goto do_backtrack; } } } }
void racket_boot(int argc, char **argv, char *exec_file, char *run_file, char *boot_exe, long segment_offset, char *coldir, char *configdir, /* wchar_t * */void *dlldir, int pos1, int pos2, int pos3, int cs_compiled_subdir, int is_gui, int wm_is_gracket_or_x11_arg_count, char *gracket_guid_or_x11_args, void *dll_open, void *dll_find_object) /* exe argument already stripped from argv */ { #if !defined(RACKET_USE_FRAMEWORK) || !defined(RACKET_AS_BOOT) int fd; #endif #ifdef RACKET_USE_FRAMEWORK const char *fw_path; #endif #ifdef WIN32 if (dlldir) rktio_set_dll_path((wchar_t *)dlldir); if (dll_open) rktio_set_dll_procs(dll_open, dll_find_object); #endif Sscheme_init(NULL); #ifdef RACKET_USE_FRAMEWORK fw_path = get_framework_path(); Sregister_boot_file(path_append(fw_path, "petite.boot")); Sregister_boot_file(path_append(fw_path, "scheme.boot")); # ifdef RACKET_AS_BOOT Sregister_boot_file(path_append(fw_path, "racket.boot")); # endif #else fd = open(boot_exe, O_RDONLY | BOOT_O_BINARY); { int fd1, fd2; fd1 = dup(fd); lseek(fd1, pos1, SEEK_SET); Sregister_boot_file_fd("petite", fd1); fd2 = open(boot_exe, O_RDONLY | BOOT_O_BINARY); lseek(fd2, pos2, SEEK_SET); Sregister_boot_file_fd("scheme", fd2); # ifdef RACKET_AS_BOOT fd = open(boot_exe, O_RDONLY | BOOT_O_BINARY); lseek(fd, pos3, SEEK_SET); Sregister_boot_file_fd("racket", fd); # endif } #endif Sbuild_heap(NULL, init_foreign); { ptr l = Snil; int i; char segment_offset_s[32], wm_is_gracket_s[32]; for (i = argc; i--; ) { l = Scons(Sbytevector(argv[i]), l); } l = Scons(Sbytevector(gracket_guid_or_x11_args), l); sprintf(wm_is_gracket_s, "%d", wm_is_gracket_or_x11_arg_count); l = Scons(Sbytevector(wm_is_gracket_s), l); l = Scons(Sbytevector(is_gui ? "true" : "false"), l); l = Scons(Sbytevector(cs_compiled_subdir ? "true" : "false"), l); sprintf(segment_offset_s, "%ld", segment_offset); l = Scons(Sbytevector(segment_offset_s), l); l = Scons(Sbytevector(configdir), l); l = Scons(parse_coldirs(coldir), l); l = Scons(Sbytevector(run_file), l); l = Scons(Sbytevector(exec_file), l); #ifdef RACKET_AS_BOOT { ptr c, start, apply; c = Stop_level_value(Sstring_to_symbol("scheme-start")); start = Scall0(c); apply = Stop_level_value(Sstring_to_symbol("apply")); Scall2(apply, start, l); } #else Sset_top_level_value(Sstring_to_symbol("bytes-command-line-arguments"), l); #endif } #ifndef RACKET_AS_BOOT # ifdef RACKET_USE_FRAMEWORK fd = open(path_append(fw_path, "racket.so"), O_RDONLY); pos3 = 0; # endif { ptr c, p; if (pos3) lseek(fd, pos3, SEEK_SET); c = Stop_level_value(Sstring_to_symbol("open-fd-input-port")); p = Scall1(c, Sfixnum(fd)); Slock_object(p); c = Stop_level_value(Sstring_to_symbol("port-file-compressed!")); Scall1(c, p); Sunlock_object(p); c = Stop_level_value(Sstring_to_symbol("load-compiled-from-port")); Scall1(c, p); } #endif }
int main(int argc, char *argv[]) { struct dirent **dirents; const char *arg; if(argc == 1) { arg = getenv("PWD"); if(arg == NULL) { fputs("Could not list current directory\n", stderr); return EXIT_FAILURE; } } else { arg = argv[1]; } int size = scandir(arg, &dirents, NULL, alphasort); if(size == -1) { fprintf(stderr, "Could not list %s\n", arg); return EXIT_FAILURE; } else { for(int i = 0; i < size; i++) { char type; switch(dirents[i]->d_type) { case DT_DIR: type = 'd'; break; case DT_FILE: type = 'f'; break; case DT_LINK: type = 'l'; break; case DT_DEV: type = 'c'; break; default: type = ' '; } printf("%c\t%s", type, dirents[i]->d_name); if(dirents[i]->d_type == DT_FILE) { static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB" }; char *filepath = path_append(arg, dirents[i]->d_name); if(filepath != NULL) { FILE *fp = fopen(filepath, "rb"); if(fp != NULL) { fseek(fp, 0, SEEK_END); double filesize = ftell(fp); fclose(fp); size_t i = 0; while(filesize >= 1024 && i < sizeof(units) / sizeof(units[0]) - 1) { filesize /= 1024; i++; } printf("\t%.2f%s", filesize, units[i]); } free(filepath); } } else if(dirents[i]->d_type == DT_DIR) { char *dirpath = path_append(arg, dirents[i]->d_name); if(dirpath != NULL) { size_t count = 0; DIR *dir = opendir(dirpath); if(dir != NULL) { while(readdir(dir) != NULL) count++; closedir(dir); } printf("\t%zu", count); free(dirpath); } } putchar('\n'); free(dirents[i]); } free(dirents); } return EXIT_SUCCESS; }