标题: 用C语言实现PHP的dirname函数
作者: Demon
链接: https://demon.tw/programming/c-php-dirname.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
写一个程序要用到,于是整理了一下。在PHP源码中的ext/standard/string.c中。
赞赏#include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> /*********************************** Author : Demon Website : https://demon.tw E-mail : 380401911@qq.com ***********************************/ #define IS_SLASH_P(c) (*(c) == '/' || (*(c) == '\\' && !IsDBCSLeadByte(*(c-1)))) #define DEFAULT_SLASH '\\' char *estrndup(const char *s, size_t length) { char *p; p = (char *) malloc(length+1); if (p == NULL) { return p; } memcpy(p, s, length); p[length] = 0; return p; } /* {{{ php_dirname Returns directory name component of path */ size_t php_dirname(char *path, size_t len) { register char *end = path + len - 1; unsigned int len_adjust = 0; /* Note that on Win32 CWD is per drive (heritage from CP/M). * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive. */ if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) { /* Skip over the drive spec (if any) so as not to change */ path += 2; len_adjust += 2; if (2 == len) { /* Return "c:" on Win32 for dirname("c:"). * It would be more consistent to return "c:." * but that would require making the string *longer*. */ return len; } } if (len == 0) { /* Illegal use of this function */ return 0; } /* Strip trailing slashes */ while (end >= path && IS_SLASH_P(end)) { end--; } if (end < path) { /* The path only contained slashes */ path[0] = DEFAULT_SLASH; path[1] = '\0'; return 1 + len_adjust; } /* Strip filename */ while (end >= path && !IS_SLASH_P(end)) { end--; } if (end < path) { path[0] = '.'; path[1] = '\0'; return 1 + len_adjust; } /* Strip slashes which came before the file name */ while (end >= path && IS_SLASH_P(end)) { end--; } if (end < path) { path[0] = DEFAULT_SLASH; path[1] = '\0'; return 1 + len_adjust; } *(end+1) = '\0'; return (size_t)(end + 1 - path) + len_adjust; } /* }}} */ /* {{{ proto string dirname(string path) Returns the directory name component of the path */ char *dirname(char *str) { char *ret; size_t ret_len; ret = estrndup(str, strlen(str)); ret_len = php_dirname(ret, strlen(str)); return ret; } /* }}} */ int main(void) { char *file = dirname("/etc/passwd"); printf("%s\n", file); free(file); return 0; }
微信赞赏支付宝赞赏
随机文章:
man 3 dirname 里说到返回值不要用free,你这个。。。