@@ -353,10 +353,25 @@ size_t fill_pathname(char *s, const char *in_path,
353353 **/
354354char * find_last_slash (const char * str )
355355{
356- const char * slash = strrchr (str , '/' );
357- const char * backslash = strrchr (str , '\\' );
358- char * last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
359- return last_slash ;
356+ const char * p ;
357+ const char * last_slash = NULL ;
358+ const char * last_backslash = NULL ;
359+
360+ /* Traverse the string once */
361+ for (p = str ; * p != '\0' ; ++ p )
362+ {
363+ if (* p == '/' )
364+ last_slash = p ; /* Update last forward slash */
365+ else if (* p == '\\' )
366+ last_backslash = p ; /* Update last backslash */
367+ }
368+
369+ /* Determine which one is last */
370+ if (!last_slash ) /* Backslash */
371+ return (char * )last_backslash ;
372+ if (!last_backslash ) /* Forward slash */
373+ return (char * )last_slash ;
374+ return (last_backslash > last_slash ) ? (char * )last_backslash : (char * )last_slash ;
360375}
361376
362377/**
@@ -369,14 +384,15 @@ char *find_last_slash(const char *str)
369384 **/
370385size_t fill_pathname_slash (char * s , size_t len )
371386{
372- const char * slash = strrchr (s , '/' );
373- const char * backslash = strrchr (s , '\\' );
374- char * last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
387+ char * last_slash = find_last_slash (s );
388+ len = strlen (s );
375389 if (!last_slash )
376- return strlcat (s , PATH_DEFAULT_SLASH (), len );
377- len = strlen (s );
390+ {
391+ s [ len ] = PATH_DEFAULT_SLASH_C ();
392+ s [++ len ] = '\0' ;
393+ }
378394 /* Try to preserve slash type. */
379- if (last_slash != (s + len - 1 ))
395+ else if (last_slash != (s + len - 1 ))
380396 {
381397 s [ len ] = last_slash [0 ];
382398 s [++ len ] = '\0' ;
@@ -462,16 +478,12 @@ size_t fill_pathname_parent_dir_name(char *s, const char *in_dir, size_t len)
462478{
463479 size_t _len = 0 ;
464480 char * tmp = strdup (in_dir );
465- const char * slash = strrchr (tmp , '/' );
466- const char * backslash = strrchr (tmp , '\\' );
467- char * last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
481+ char * last_slash = find_last_slash (tmp );
468482
469483 if (last_slash && last_slash [1 ] == 0 )
470484 {
471485 * last_slash = '\0' ;
472- slash = strrchr (tmp , '/' );
473- backslash = strrchr (tmp , '\\' );
474- last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
486+ last_slash = find_last_slash (tmp );
475487 }
476488
477489 /* Cut the last part of the string (the filename) after the slash,
@@ -482,9 +494,7 @@ size_t fill_pathname_parent_dir_name(char *s, const char *in_dir, size_t len)
482494 /* Point in_dir to the address of the last slash.
483495 * If in_dir is NULL, it means there was no slash in tmp,
484496 * so use tmp as-is. */
485- slash = strrchr (tmp , '/' );
486- backslash = strrchr (tmp , '\\' );
487- in_dir = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
497+ in_dir = find_last_slash (tmp );
488498 if (!in_dir )
489499 in_dir = tmp ;
490500
@@ -592,23 +602,19 @@ size_t fill_str_dated_filename(char *s,
592602 **/
593603size_t path_basedir (char * s )
594604{
595- const char * slash ;
596- const char * backslash ;
597605 char * last_slash = NULL ;
598606 if (!s || s [0 ] == '\0' || s [1 ] == '\0' )
599607 return (s && s [0 ] != '\0' ) ? 1 : 0 ;
600- slash = strrchr (s , '/' );
601- backslash = strrchr (s , '\\' );
602- last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
603- if (last_slash )
608+ last_slash = find_last_slash (s );
609+ if (!last_slash )
604610 {
605- last_slash [1 ] = '\0' ;
606- return last_slash + 1 - s ;
611+ s [0 ] = '.' ;
612+ s [1 ] = PATH_DEFAULT_SLASH_C ();
613+ s [2 ] = '\0' ;
614+ return 2 ;
607615 }
608- s [0 ] = '.' ;
609- s [1 ] = PATH_DEFAULT_SLASH_C ();
610- s [2 ] = '\0' ;
611- return 2 ;
616+ last_slash [1 ] = '\0' ;
617+ return last_slash + 1 - s ;
612618}
613619
614620/**
@@ -630,15 +636,9 @@ size_t path_parent_dir(char *s, size_t len)
630636 if (len && PATH_CHAR_IS_SLASH (s [len - 1 ]))
631637 {
632638 char * last_slash ;
633- const char * slash ;
634- const char * backslash ;
635639 bool was_absolute = path_is_absolute (s );
636-
637640 s [len - 1 ] = '\0' ;
638-
639- slash = strrchr (s , '/' );
640- backslash = strrchr (s , '\\' );
641- last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
641+ last_slash = find_last_slash (s );
642642
643643 if (was_absolute && !last_slash )
644644 {
@@ -667,9 +667,7 @@ const char *path_basename(const char *path)
667667 /* We cut either at the first compression-related hash,
668668 * or we cut at the last slash */
669669 const char * ptr = NULL ;
670- const char * slash = strrchr (path , '/' );
671- const char * backslash = strrchr (path , '\\' );
672- char * last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
670+ char * last_slash = find_last_slash (path );
673671 return ((ptr = path_get_archive_delim (path )) || (ptr = last_slash ))
674672 ? (ptr + 1 ) : path ;
675673}
@@ -687,9 +685,7 @@ const char *path_basename(const char *path)
687685const char * path_basename_nocompression (const char * path )
688686{
689687 /* We cut at the last slash */
690- const char * slash = strrchr (path , '/' );
691- const char * backslash = strrchr (path , '\\' );
692- char * last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
688+ char * last_slash = find_last_slash (path );
693689 return (last_slash ) ? (last_slash + 1 ) : path ;
694690}
695691
@@ -999,22 +995,18 @@ size_t fill_pathname_join_special(char *s,
999995
1000996 if (* s )
1001997 {
1002- const char * slash = strrchr (s , '/' );
1003- const char * backslash = strrchr (s , '\\' );
1004- char * last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
1005- if (last_slash )
998+ char * last_slash = find_last_slash (s );
999+ if (!last_slash )
10061000 {
1007- /* Try to preserve slash type. */
1008- if (last_slash != (s + _len - 1 ))
1009- {
1010- s [ _len ] = last_slash [0 ];
1011- s [++ _len ] = '\0' ;
1012- }
1001+ s [ _len ] = PATH_DEFAULT_SLASH_C ();
1002+ s [++ _len ] = '\0' ;
1003+
10131004 }
1014- else
1005+ /* Try to preserve slash type. */
1006+ else if (last_slash != (s + _len - 1 ))
10151007 {
1016- s [ _len ] = PATH_DEFAULT_SLASH_C () ;
1017- s [++ _len ] = '\0' ;
1008+ s [ _len ] = last_slash [ 0 ] ;
1009+ s [++ _len ] = '\0' ;
10181010 }
10191011 }
10201012
@@ -1327,8 +1319,6 @@ size_t fill_pathname_abbreviated_or_relative(char *s,
13271319 **/
13281320void path_basedir_wrapper (char * s )
13291321{
1330- const char * slash ;
1331- const char * backslash ;
13321322 char * last_slash = NULL ;
13331323 if (!s || s [0 ] == '\0' || s [1 ] == '\0' )
13341324 return ;
@@ -1337,9 +1327,7 @@ void path_basedir_wrapper(char *s)
13371327 if ((last_slash = (char * )path_get_archive_delim (s )))
13381328 * last_slash = '\0' ;
13391329#endif
1340- slash = strrchr (s , '/' );
1341- backslash = strrchr (s , '\\' );
1342- last_slash = (!slash || (backslash > slash )) ? (char * )backslash : (char * )slash ;
1330+ last_slash = find_last_slash (s );
13431331 if (last_slash )
13441332 last_slash [1 ] = '\0' ;
13451333 else
0 commit comments