📄 fileutils.c
字号:
*outPtr=0; strcpy(pathname, buf); /* compress out . and .. */ inPtr = pathname; outPtr = buf; /* copy initial / */ copyThruSlash(&outPtr, &inPtr); while (inPtr != NULL) { /* if the next component is "../", remove previous component */ if (compareThruSlash(inPtr, "../")) { *outPtr = 0; /* If the ../ is at the beginning, or if the previous component is a symbolic link, preserve the ../. It is not valid to compress ../ when the previous component is a symbolic link because ../ is relative to where the link points. If there's no S_ISLNK macro, assume system does not do symbolic links. */#ifdef S_ISLNK if(outPtr-1 == buf || (lstat(buf, &statbuf) == 0 && S_ISLNK(statbuf.st_mode))) { copyThruSlash(&outPtr, &inPtr); } else#endif { /* back up outPtr to remove last path name component */ outPtr = prevSlash(outPtr); inPtr = nextSlash(inPtr); } } else if (compareThruSlash(inPtr, "./")) { /* don't copy the component if it's the redundant "./" */ inPtr = nextSlash(inPtr); } else { /* copy the component to outPtr */ copyThruSlash(&outPtr, &inPtr); } } /* updated pathname with the new value */ if (strlen(buf)>MAXPATHLEN) { fprintf(stderr, "NEdit: CompressPathname(): file name too long %s\n", pathname); free(buf); return 1; } else { strcpy(pathname, buf); free(buf); return 0; }}static char*nextSlash(char *ptr){ for(; *ptr!='/'; ptr++) { if (*ptr == '\0') return NULL; } return ptr + 1;}static char*prevSlash(char *ptr){ for(ptr -= 2; *ptr!='/'; ptr--); return ptr + 1;}static intcompareThruSlash(const char *string1, const char *string2){ while (TRUE) { if (*string1 != *string2) return FALSE; if (*string1 =='\0' || *string1=='/') return TRUE; string1++; string2++; }}static voidcopyThruSlash(char **toString, char **fromString){ char *to = *toString; char *from = *fromString; while (TRUE) { *to = *from; if (*from =='\0') { *fromString = NULL; return; } if (*from=='/') { *toString = to + 1; *fromString = from + 1; return; } from++; to++; }}#else /* VMS *//* ** Dummy versions of the public functions for VMS.*//*** Return 0 if everything's fine, 1 else.*/int NormalizePathname(char *pathname){ return 0;}/*** Return 0 if everything's fine, 1 else.*/int CompressPathname(char *pathname){ return 0;}/* * Returns: * TRUE if no error occured * * FALSE if an error occured. */int ResolvePath(const char * pathIn, char * pathResolved){ if (strlen(pathIn) < MAXPATHLEN) { strcpy(pathResolved, pathIn); return TRUE; } else { return FALSE; }}#endif /* VMS *//*** Return the trailing 'n' no. of path components*/const char*GetTrailingPathComponents(const char* path, int noOfComponents){ /* Start from the rear */ const char* ptr = path + strlen(path); int count = 0; while (--ptr > path) { if (*ptr == '/') { if (count++ == noOfComponents) { break; } } } return(ptr);} /*** Samples up to a maximum of FORMAT_SAMPLE_LINES lines and FORMAT_SAMPLE_CHARS** characters, to determine whether fileString represents a MS DOS or Macintosh** format file. If there's ANY ambiguity (a newline in the sample not paired** with a return in an otherwise DOS looking file, or a newline appearing in** the sampled portion of a Macintosh looking file), the file is judged to be** Unix format.*/int FormatOfFile(const char *fileString){ const char *p; int nNewlines = 0, nReturns = 0; for (p=fileString; *p!='\0' && p < fileString + FORMAT_SAMPLE_CHARS; p++) { if (*p == '\n') { nNewlines++; if (p == fileString || *(p-1) != '\r') return UNIX_FILE_FORMAT; if (nNewlines >= FORMAT_SAMPLE_LINES) return DOS_FILE_FORMAT; } else if (*p == '\r') nReturns++; } if (nNewlines > 0) return DOS_FILE_FORMAT; if (nReturns > 1) return MAC_FILE_FORMAT; return UNIX_FILE_FORMAT;}/*** Converts a string (which may represent the entire contents of the file)** from DOS or Macintosh format to Unix format. Conversion is done in-place.** In the DOS case, the length will be shorter, and passed length will be** modified to reflect the new length. The routine has support for blockwise** file to string conversion: if the fileString has a trailing '\r' and ** 'pendingCR' is not zero, the '\r' is deposited in there and is not** converted. If there is no trailing '\r', a 0 is deposited in 'pendingCR'** It's the caller's responsability to make sure that the pending character, ** if present, is inserted at the beginning of the next block to convert.*/void ConvertFromDosFileString(char *fileString, int *length, char* pendingCR){ char *outPtr = fileString; char *inPtr = fileString; if (pendingCR) *pendingCR = 0; while (inPtr < fileString + *length) { if (*inPtr == '\r') { if (inPtr < fileString + *length - 1) { if (*(inPtr + 1) == '\n') inPtr++; } else { if (pendingCR) { *pendingCR = *inPtr; break; /* Don't copy this trailing '\r' */ } } } *outPtr++ = *inPtr++; } *outPtr = '\0'; *length = outPtr - fileString;}void ConvertFromMacFileString(char *fileString, int length){ char *inPtr = fileString; while (inPtr < fileString + length) { if (*inPtr == '\r' ) *inPtr = '\n'; inPtr++; }}/*** Converts a string (which may represent the entire contents of the file) from** Unix to DOS format. String is re-allocated (with malloc), and length is** modified. If allocation fails, which it may, because this can potentially** be a huge hunk of memory, returns FALSE and no conversion is done.**** This could be done more efficiently by asking doSave to allocate some** extra memory for this, and only re-allocating if it wasn't enough. If** anyone cares about the performance or the potential for running out of** memory on a save, it should probably be redone.*/int ConvertToDosFileString(char **fileString, int *length){ char *outPtr, *outString; char *inPtr = *fileString; int inLength = *length; int outLength = 0; /* How long a string will we need? */ while (inPtr < *fileString + inLength) { if (*inPtr == '\n') outLength++; inPtr++; outLength++; } /* Allocate the new string */ outString = XtMalloc(outLength + 1); if (outString == NULL) return FALSE; /* Do the conversion, free the old string */ inPtr = *fileString; outPtr = outString; while (inPtr < *fileString + inLength) { if (*inPtr == '\n') *outPtr++ = '\r'; *outPtr++ = *inPtr++; } *outPtr = '\0'; XtFree(*fileString); *fileString = outString; *length = outLength; return TRUE;}/*** Converts a string (which may represent the entire contents of the file)** from Unix to Macintosh format.*/void ConvertToMacFileString(char *fileString, int length){ char *inPtr = fileString; while (inPtr < fileString + length) { if (*inPtr == '\n' ) *inPtr = '\r'; inPtr++; }}/*** Reads a text file into a string buffer, converting line breaks to ** unix-style if appropriate. */char *ReadAnyTextFile(const char *fileName){ struct stat statbuf; FILE *fp; int fileLen, readLen; char *fileString; int format; /* Read the whole file into fileString */ if ((fp = fopen(fileName, "r")) == NULL) { return NULL; } if (fstat(fileno(fp), &statbuf) != 0) { fclose(fp); return NULL; } fileLen = statbuf.st_size; fileString = XtMalloc(fileLen+1); /* +1 = space for null */ readLen = fread(fileString, sizeof(char), fileLen, fp); if (ferror(fp)) { XtFree(fileString); fclose(fp); return NULL; } fclose(fp); fileString[readLen] = 0; /* Convert linebreaks? */ format = FormatOfFile(fileString); if (format == DOS_FILE_FORMAT){ char pendingCR; ConvertFromDosFileString(fileString, &readLen, &pendingCR); } else if (format == MAC_FILE_FORMAT){ ConvertFromMacFileString(fileString, readLen); } return fileString;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -