static void osd_setWorkingDirectory (void) { # if defined (UNIX) char *buf = dmalloc (sizeof (*buf) * MAXPATHLEN); char *cwd = getcwd (buf, MAXPATHLEN); #elif defined (OS2) char *buf = dmalloc (sizeof (*buf) * MAXPATHLEN); char *cwd = _getcwd2 (buf, MAXPATHLEN); char *slash; while ((slash = strchr (cwd, '/')) != NULL) { *slash = '\\'; } #endif # if defined (UNIX) || defined (OS2) llassert (cstring_isUndefined (osd_cwd)); if (cwd == NULL) { lldiagmsg (message ("Cannot get working directory: %s\n", lldecodeerror (errno))); osd_cwd = cstring_makeLiteral ("<missing directory>"); } else { osd_cwd = cstring_fromCharsNew (cwd); } sfree (buf); # else ; /* Don't know how to do this for non-POSIX platforms */ # endif }
cstring osd_outputPath (cstring filename) { # if defined (UNIX) || defined (OS2) char *rel_buffer; char *rel_buf_p; cstring cwd_p = osd_cwd; char *path_p; int unmatched_slash_count = 0; size_t filename_len = cstring_length (filename); llassertretval (filename_len > 0, filename); /*@access cstring@*/ path_p = filename; rel_buffer = (char *) dmalloc (filename_len); rel_buf_p = rel_buffer; *rel_buf_p = '\0'; if (cwd_p == NULL) { /* Need to prevent recursive assertion failures */ return cstring_copy (filename); } llassert (cwd_p != NULL); llassert (path_p != NULL); while ((*cwd_p != '\0') && (*cwd_p == *path_p)) { cwd_p++; path_p++; } if ((*cwd_p == '\0') && (*path_p == '\0' || osd_isConnectChar (*path_p))) /* whole pwd matched */ { if (*path_p == '\0') /* input *is* the current path! */ { cstring_free (rel_buffer); return cstring_makeLiteral ("."); } else { cstring_free (rel_buffer); return cstring_fromCharsNew (path_p + 1); } } else { /* drl 2002-10/14 I had to put this code back*/ /* the case that needs it is when splint is given an absolute path name of a file outside of the current directory and the subdirectories below the current directory. e.g. cd /home/; splint /tmp/prog.c */ /* evans 2002-02-05 This is horrible code, which I've removed. I couldn't find any ** test cases that need it, so I hope I'm not breaking anything. */ /*#if 0*/ if (*path_p != '\0') { --cwd_p; --path_p; while (cwd_p >= osd_cwd && !osd_isConnectChar (*cwd_p)) /* backup to last slash */ { --cwd_p; --path_p; } cwd_p++; path_p++; unmatched_slash_count++; } /* Find out how many directory levels in cwd were *not* matched. */ while (*cwd_p != '\0') { if (osd_isConnectChar (*cwd_p++)) unmatched_slash_count++; } /* Now we know how long the "short name" will be. Reject it if longer than the input. */ if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len) { cstring_free (rel_buffer); /* fprintf (stderr, "Returning filename: %s [%p]\n", filename); */ return cstring_copy (filename); } /*drl 10-14-2002 end previously removed code */ /*#endif*/ /* For each of them, put a `../' at the beginning of the short name. */ while (unmatched_slash_count-- > 0) { /* Give up if the result gets to be longer than the absolute path name. */ char * temp_rel_buf_p; /*drl This comment is necessary because for some reason Splint does not realize that the pasts where rel_buf_p is released do not reach here*/ /*@-usereleased@*/ temp_rel_buf_p = rel_buf_p; /*@-usereleased@*/ if (rel_buffer + filename_len <= temp_rel_buf_p + 3) { sfree (rel_buffer); return cstring_copy (filename); } *rel_buf_p++ = '.'; *rel_buf_p++ = '.'; *rel_buf_p++ = CONNECTCHAR; } /* Then tack on the unmatched part of the desired file's name. */ do { if (rel_buffer + filename_len <= rel_buf_p) { cstring_free (rel_buffer); return cstring_copy (filename); } } /*@-usereleased@*/ while ((*rel_buf_p++ = *path_p++) != '\0') ; /*@=usereleased@*/ /* Splint limitation: shouldn't need these */ --rel_buf_p; if (osd_isConnectChar (*(rel_buf_p-1))) *--rel_buf_p = '\0'; /* fprintf (stderr, "Returning buffer: %s [%p]\n", rel_buffer, rel_buffer); */ return rel_buffer; } /*@noaccess cstring@*/ # else return cstring_copy (filename); # endif }