/** Removes "." and ".." from a path */ char *getCanonicalPath(const char *path){ char *prefix = NULL; char *rest = NULL; char *tmp = NULL; size_t offset = 0; char **src = NULL; List *dst = NULL; size_t ii = 0; Buffer *buf = NULL; char *result = NULL; if (path != NULL && strlen(path) > 0) { tmp = strxreplace(astrcpy(path), '\\', '/'); if (isDosPath(tmp) || isUncPath(tmp)) { if (isDosPath(tmp)) { prefix = getPathPart(tmp, PATH_DRIVE); offset = 0; } else if (isUncPath(tmp)) { prefix = getPathPart(tmp, PATH_HOST); offset = 2; } rest = astrcpy(strchr(&tmp[offset], '/')); } else { rest = astrcpy(tmp); } src = astrtok(rest, "/"); dst = new_List(); while (src[ii] != NULL) { if (strxequals(src[ii], "..")) { List_remove(dst, -1, false); } else if (!strxequals(src[ii], ".")) { List_append(dst, src[ii]); } ii++; } buf = new_Buffer(0); if (prefix != NULL) { Buffer_appendString(buf, prefix); } for (ii = 0; ii < List_length(dst); ++ii) { Buffer_appendString(buf, List_get(dst, ii)); if (ii != (List_length(dst) - 1)) { Buffer_appendChar(buf, '/'); } } result = astrcpy(buf->data); delete_Buffer(buf); delete_List(dst, false); astrtokfree(src); mu_free(prefix); mu_free(rest); mu_free(tmp); } return result; }
/** Joins two paths together, allowing for relative/absolute paths */ char *getCombinedPath(const char *path1, const char *path2) { char *tmp1 = NULL; char *tmp2 = NULL; char *tmp = NULL; Buffer *buf = NULL; char *result = NULL; char *final = NULL; if (!strxnullorempty(path1) && !strxnullorempty(path2)) { tmp1 = strxreplace(astrcpy(path1), '\\', '/'); tmp2 = strxreplace(astrcpy(path2), '\\', '/'); if (isDosPath(tmp2) || isUncPath(tmp2)) { /* Path2 is a fully-qualified DOS/Windows path; return it */ result = astrcpy(tmp2); } else { buf = new_Buffer(0); if (tmp2[0] == '/') { /* Path2 is an absolute path. If Path1 is a DOS/Windows or ** UNC path, prepend the drive letter or hostname; otherwise ** return it. */ if (isDosPath(tmp1)) { tmp = getPathPart(tmp1, PATH_DRIVE); Buffer_appendString(buf, tmp); Buffer_appendString(buf, tmp2); mu_free(tmp); } else if (isUncPath(tmp1)) { tmp = getPathPart(tmp1, PATH_HOST); Buffer_appendString(buf, "//"); Buffer_appendString(buf, tmp); Buffer_appendString(buf, tmp2); mu_free(tmp); } else { Buffer_appendString(buf, tmp2); } } else { /* Simply concatenate the two paths */ Buffer_appendString(buf, tmp1); if (tmp1[strlen(tmp1) - 1] != '/') { Buffer_appendChar(buf, '/'); } Buffer_appendString(buf, tmp2); } result = astrcpy(buf->data); delete_Buffer(buf); } mu_free(tmp1); mu_free(tmp2); } /* Remove any "." and ".." in the path */ final = getCanonicalPath(result);
int main(int argc, char *argv[]){ char *currDir = NULL; char relPath[] = "../doc"; char testPart[] = "/foo/bar/test.txt"; char *filePart = NULL; char *newDir = NULL; Logging_setup(argv[0], LOG_TOSTDERR | LOG_LEVELTRACE, NULL); currDir = getCurrentDirectory(); Logging_infof("Current directory is: \"%s\"", currDir); newDir = getCombinedPath(currDir, relPath); Logging_infof("Doc directory is: \"%s\"", newDir); filePart = getPathPart(testPart, PATH_FILE); Logging_infof("The file part of \"%s\" with extension is: \"%s\"", testPart, filePart); mu_free(filePart); filePart = getPathPart(testPart, PATH_FILEONLY); Logging_infof("The file part of \"%s\" without extension is: \"%s\"", testPart, filePart); mu_free(filePart); mu_free(newDir); mu_free(currDir); exit(EXIT_SUCCESS); }
// Modifies fullpath with the path part including the trailing path separator int OlyUtility::getApplicationFullPath(char* fullpath, int sizeOfPath) { memset(fullpath, 0, sizeOfPath); #ifdef WIN32 int length = GetModuleFileName(NULL, fullpath, sizeOfPath); #else int length = readlink("/proc/self/exe", fullpath, sizeOfPath); #endif if (length == sizeOfPath) { return -1; } fullpath[length] = 0; fullpath = getPathPart(fullpath); return 0; }
// Modifies fullpath with the path part including the trailing path separator int OlyUtility::getApplicationFullPath(char* fullpath, int sizeOfPath) { memset(fullpath, 0, sizeOfPath); #if defined(WIN32) int length = GetModuleFileName(NULL, fullpath, sizeOfPath); #elif defined(__linux__) int length = readlink("/proc/self/exe", fullpath, sizeOfPath); #elif defined(DARWIN) uint32_t length_u = (uint32_t)sizeOfPath; int length = sizeOfPath; if (_NSGetExecutablePath(fullpath, &length_u) == 0) { length = strlen(fullpath); } #endif if (length == sizeOfPath) { return -1; } fullpath[length] = 0; getPathPart(fullpath); return 0; }
void Parser::load(std::string filename, std::string root) { this->reset(); //========================================================= // load input std::string fileData = deRepeat(replaceEx(loadText(filename), "\t", " "), ' ') + VBCRLF; fileData = replacePtn(fileData, "//", VBCRLF, VBCRLF); fileData = replacePtn(fileData, "/*", "*/", ""); //========================================================= bool table = (getPathPart(filename, PATH::EXTEN) == "par"); int mode = 0; int row = 0; //========================================================= int seed = 0; // init UID seed //========================================================= int i = 0; while (i < fileData.length()) { std::string token = trim(scanText(fileData, i, VBCRLF)); if (token == "") continue; if (token == "[cfg]") mode = 0; else if (token == "[par]") mode = 1; else { if (table) { // skip row prefix int j = 0; scanText(token, j, " "); token = right(token, token.length() - j); } switch (mode) { case 0: { std::string lhs = trim(getEntry(token, "->", 0)); std::string rhs = trim(getEntry(token, "->", 1)); int j = 0; this->addRule(lhs, "( " + rhs + " )", j, seed); break; } case 1: { std::string lhs = trim(getEntry(token, "|", 0)); std::string rhs = trim(getEntry(token, "|", 1)); if (!row) { mActionTable = new ParserTable(lhs); mGotoTable = new ParserTable(rhs); } else { mActionTable->addRow( new ParserRow(&mActionTable->getSymTableR(), lhs) ); mGotoTable->addRow( new ParserRow(&mGotoTable->getSymTableR(), rhs) ); } row++; } } } } //========================================================= // augment grammar if (BNF_Util::isTerm(&mRuleList, BNF_ROOT2)) mRuleList.push_back(new BNF_Rule(BNF_ROOT2, root)); //========================================================= // generate terminal and non-terminal list through rule list for (int j = 0; j < mRuleList.size(); j++) { BNF_Rule *rule = mRuleList[j]; if (rule->mLHS != BNF_ROOT2) // (exclude ROOT2) mNonTermList.insert(rule->mLHS); // LHS must be non-terminal for (int k = 0; k < rule->length(); k++) { std::string rhs = (*rule)[k]; if (rhs != BNF_EMPTY) // (epsilon fix; exclude EMPTY) mTermList.insert(rhs); // RHS can be terminal or non-terminal } } mTermList.insert(BNF_END); // first terminal is always END //========================================================= // remove non-terminals from terminal list std::set<std::string>::iterator p; for (p = mNonTermList.begin(); p != mNonTermList.end(); p++) if (mTermList.find(*p) != mTermList.end()) mTermList.erase(*p); //========================================================= }
/* * * * * * * * * * * * this routine returns a pointer to the seadif map */ MAPTABLEPTR look_up_seadif_map(char *view , char *lib , char *func , char *cir , char *lay ) { char *namestr, *remotelib, filepath[512], hstr[DM_MAXNAME+1]; register MAPTABLEPTR map; MAPTABLEPTR tmap; IMPCELL ** imp_p; struct stat buf; #ifdef NELSIS_REL4 DM_PROJECT *remote_projectkey; DM_CELL *cell_key; char *remote_cellname; #endif if(lib == NULL || func == NULL || cir == NULL) error(FATAL_ERROR, "look_up_seadif_map: null input"); /* * make name known to string manager */ if(view == layout_str) { namestr = canonicstring(lay); for(map = maptable; map != NULL; map = map->next) { if(map->layout == namestr && map->view == view && strcmp(map->circuit, cir) == 0 && strcmp(map->function, func) == 0 && strcmp(map->library, lib) == 0) { break; /* hit */ } } } else { namestr = canonicstring(cir); for(map = maptable; map != NULL; map = map->next) { if(map->circuit == cir && map->view == view && strcmp(map->function, func) == 0 && strcmp(map->library, lib) == 0) { break; /* hit */ } } } if(map != NULL) { /* was found */ forgetstring(namestr); return(map); } /* * else: create new map */ NewMaptable(map); map->next = maptable; maptable = map; map->view = canonicstring(view); map->library = canonicstring(lib); map->function = canonicstring(func); map->circuit = canonicstring(cir); if(map->view == circuit_str) { /* view is circuit: layoutname = dummy */ map->layout = dummy_str; } else map->layout = canonicstring(lay); map->nelseastatus = not_written_str; map->seanelstatus = not_written_str; map->internalstatus = not_in_core_str; map->num_read_attempts = 0; map->overrule_status = FALSE; map->no_alignment_found = FALSE; /* to overrule nelsea/seanelstatus: if true always write/read */ /* * set seadif times, and find out name.... */ if(Seadif_open == TRUE) { if(map->view == circuit_str) { if(existscir(map->circuit, map->function, map->library) == TRUE) { map->seadif_time = 1; if(sdfreadcir(SDFCIRSTAT, map->circuit, map->function, map->library) != TRUE) { fprintf(stderr,"WARNING: Cannot read sdf cirstatus of '%s'\n", map->circuit); fprintf(stderr," That is: %s(%s(%s)) doesn't have a stat\n", map->circuit, map->function, map->library); } else { map->seadif_time = thiscir->status->timestamp; map->circuitstruct = thiscir; } /* set nelsis name, if it exists */ if(NoAliases == FALSE) map->cell = sdfciralias(map->circuit, map->function, map->library); } } else { if(existslay(map->layout, map->circuit, map->function, map->library) == TRUE) { map->seadif_time = 1; if(sdfreadlay(SDFLAYSTAT, map->layout, map->circuit, map->function, map->library) != TRUE) { fprintf(stderr,"WARNING: Cannot read sdf laystatus of '%s'\n", map->circuit); fprintf(stderr," That is: (%s(%s(%s)))%s doesn't have a stat\n", map->layout, map->circuit, map->function, map->library); } else { map->seadif_time = thislay->status->timestamp; map->layoutstruct = thislay; } /* set nelsis name, if it exists */ if(NoAliases == FALSE) map->cell = sdflayalias(map->layout, map->circuit, map->function, map->library); } } } if(map->cell == NULL) { /* no alias name found: use sdf circuit name */ /* prepare name (truncate) */ if(strlen(cir) > DM_MAXNAME) { fprintf(stderr,"WARNING: seadif cir name '%s' is too long for nelsis (truncated)\n", cir); } strncpy(hstr, cir, DM_MAXNAME); hstr[DM_MAXNAME] = '\0'; map->cell = canonicstring(hstr); } /* * check for nelsis name clash */ for(tmap = maptable; tmap != NULL; tmap = tmap->next) { if(tmap->cell == map->cell && tmap->view == view && tmap->library == map->library && tmap != map) break; /* hit */ } if(tmap != NULL) { /* another cell with this nelsis name was found.... */ fprintf(stderr,"WARNING: name clash: two nelsis %s-cells have the same name:\n", view); fprintf(stderr," %s(%s(%s(%s))) = %s and\n", tmap->layout, tmap->circuit, tmap->function, tmap->library, tmap->cell); fprintf(stderr," %s(%s(%s(%s))) = %s\n", map->layout, map->circuit, map->function, map->library, map->cell); fprintf(stderr," This could result in strange effects\n"); /* maybe sometimes we can solve it by giving new names */ } if(Nelsis_open == FALSE) return(map); if(strcmp(map->library,"primitives") == 0 && map->view == circuit_str) return(map); /* * try to find out where the nelsis lib is, and * if found, set the nelsis time */ if(map->library == this_sdf_lib) { /* should be a local cell */ if((int) dmGetMetaDesignData(EXISTCELL, projectkey, map->cell, view) == TRUE) { /* it exists locally */ map->nelsis_time = 1; /* > 0: it exists.... */ if(map->view == circuit_str) sprintf(filepath,"circuit/%s/net", map->circuit); else sprintf(filepath,"layout/%s/box", map->layout); } else return(map); } else { /* a remote cell */ /* * scan imported cells: find proper cell name */ #ifdef NELSIS_REL4 if((imp_p = projectkey->impcelllist[_dmValidView(projectkey, view)]) == NULL) #else if((imp_p = projectkey->impcelllist[_dmValidView(view)]) == NULL) #endif { /* get the pointer */ if((imp_p = (IMPCELL **) dmGetMetaDesignData(IMPORTEDCELLLIST, projectkey, view)) == NULL) error(FATAL_ERROR, "look_up_seadif_map"); } for(; imp_p && *imp_p; imp_p++) if(strcmp(map->cell, (*imp_p)->cellname) == 0) break; if(imp_p == NULL || *imp_p == NULL) { /* no, not found.... */ fprintf(stderr,"WARNING: cannot find proper remote nelsis cell which corresponds\n"); fprintf(stderr," to sdf cell %s(%s(%s(%s)))\n", map->layout, map->circuit, map->function, map->library); if(Seadif_open == FALSE || (remotelib = sdflibalias(map->library)) == NULL) { /* lib alias doesn't exist..... */ fprintf(stderr,"WARNING: referred sdf library '%s' seems to be missing.\n", map->library); } else { fprintf(stderr," You should import the %s-cell '%s' of library\n", map->view, map->cell); fprintf(stderr," %s into your project. \n", remotelib); if((remotelib = RemToLocPath(getHostNamePart(remotelib), getPathPart(remotelib))) != NULL) { fprintf(stderr,"Hint: try typing : 'addproj %s'\n", remotelib); fprintf(stderr," followed by: 'impcell -a %s'\n", remotelib); } } return(map); /* cell does not exist */ } /* * use alias of nelsis */ map->cell = cs((*imp_p)->alias); map->nelsis_time = 1; /* marking it exists */ if(map->view == circuit_str) sprintf(filepath,"%s/circuit/%s/net", (*imp_p)->dmpath, (*imp_p)->cellname); else sprintf(filepath,"%s/layout/%s/box", (*imp_p)->dmpath, (*imp_p)->cellname); } #ifndef NELSIS_REL4 if(access(filepath, F_OK) != 0) { fprintf(stderr,"WARNING: access failed on '%s'\n", filepath); return(map); } if(stat(filepath, &buf) != 0) { fprintf(stderr,"WARNING: cannot stat file '%s'\n", filepath); return(map); } #else /* NELSIS REL 4 */ if((remote_projectkey = dmFindProjKey(map->library == this_sdf_lib ? LOCAL : IMPORTED, map->cell, projectkey, &remote_cellname, map->view)) == NULL) { /* ? */ fprintf(stderr,"ERROR: cannot find nasty project key\n"); return; } /* * open it */ if((cell_key = dmCheckOut (remote_projectkey, remote_cellname, ACTUAL, DONTCARE, map->view, READONLY)) == NULL) { /* ? */ fprintf(stderr,"ERROR: cannot open cell '%s' for stat\n", map->cell); return; } /* * stat it.. */ if(dmStat(cell_key, map->view == layout_str ? "box" : "net", &buf) != 0) { fprintf(stderr,"ERROR: Cannot dmStat cell '%s' for stat\n", map->cell); return; } /* * and close it again... */ dmCheckIn(cell_key, COMPLETE); #endif /* store time */ map->nelsis_time = buf.st_mtime; return(map); }