Function to check whether a path is valid or not needs your critique Here is my code, I use it to verify whether an input path is correct or not. I assume that the input path is encoded in UTF8. Is there any way to make it better?

#define MAX_PATH_LEN MAX_PATH

#define IN
#define OUT

typedef int Bool_T;

static
int GetCharsNumInPath( IN const char * path )
{
    int cnt;

    int i;
    int n = strlen( path );

    for( i = 0; i &lt; n; i++ )
    {
        if( ( path[i] &lt; 0x80 ) || ( path[i] &gt; 0xbf ) )
            cnt++;
    }

    return cnt;
}


Bool_T PathValid( IN const char * path )
{
    if( path != NULL )
    {
        if( GetCharsNumInPath( IN path ) &lt;= MAX_PATH_LEN )
        {
            int i;
            int n = strlen( path );

            for( i = 0; i &lt; n; i++ )
            {
                switch( path[i] )
                {
                    // ? " / &lt; &gt; * |
                    // these characters can not be used in file or folder names
                    //
                    case '?':
                    case '\"':
                    case '/':
                    case '&lt;':
                    case '&gt;':
                    case '*':
                    case '|':
                        return false;

                    // Can meet only between a local disk letter and full path
                    // for example D:\folder\file.txt
                    //
                    case ':':
                    {
                        if( i != 1 )
                        {
                            return false;

                        }else{

                            break;
                        }
                    }

                    // Space and point can not be the last character of a file or folder names
                    //
                    case ' ':
                    case '.':
                    {
                        if( ( i + 1 == n ) || ( path[i+1] == PATH_SEPERATOR_CHAR ) )
                        {
                            return false;

                        }else{

                            break;
                        }
                    }

                    // two backslashes can not go straight
                    //
                    case PATH_SEPERATOR_CHAR:
                    {
                        if( i &gt; 0 &amp;&amp; path[i - 1] == PATH_SEPERATOR_CHAR )
                        {
                            return false;

                        }else{

                            break;
                        }
                    }
                }
            }

            return true;

        }else{ // if( GetCharsNumInPath( IN path ) &lt;= MAX_PATH_LEN )

            LOG_ERROR( "PathValid FAILURE --&gt; path is too long" );
            return false;
        }

    }else{ // if( path != NULL )

        // wrong argument
        //
        return false;
    }
}
Personally if  the preconditions to the function are not met then I like to return quickly and this not add to the nesting:

Bool_T PathValid( IN const char * path )
{
    if( path != NULL )
    {
        // wrong argument
        return false;
    }

    if( GetCharsNumInPath( IN path ) &lt;= MAX_PATH_LEN )
    {
        LOG_ERROR( "PathValid FAILURE --&gt; path is too long" );
        return false;
    }

    // Main Function body here.
}


Of course in C you don't want to have too many return points from a function (as at each return point you need to close all open resources and tidy up. So in C (unlike C++) I find my code looking like this:

&lt;type&gt;   function(&lt;Parameters&gt;)
{
      if (!&lt;pre-condition1&gt;)
      {    return &lt;errorStat1&gt;;
      }

      if (!&lt;pre-condition2&gt;)
      {    return &lt;errorStat2&gt;;
      }

      ....

      if (!&lt;pre-condition-N&gt;)
      {    return &lt;errorStat-N&gt;;
      }


      &lt;type&gt;   result = &lt;initial Result&gt;;
      &lt;Set all Resource to NULL&gt;

      // Code Which can generate errors&gt;
      // If it does then set error state. and stop processing.
      // BUT DO NOT RETURN from this code.

      &lt; Close all resource &gt;
      return result;
}


Your check for invalid characters is Windows specific. The OS will usually have a platform or OS specific set of functions for checking valid characters.


Your set of invalid characters is not true for all platforms.
The use of ':' as the second character is Windows only.

If it is there the first character should be 'A' - 'Z'

Limiting the use of space is Windows only
Are you sure about "." not being allowed as last character?
On windows two '\\' can be used as the first two characters to indicate network resource.
Windows has more than one path separator.

The old style '\' (traditional backslash)
The new style '/'  (normal slash).



In your function counting characters in the path. You basically traverse the string twice. Why not combine the two traversals into a single pass:

// int n = strlen( path );
// Not requires (all this does is look for '\0')

for( i = 0; path[i]; i++ )
{       //  ^^^^^^^  Test for '\0'  character

    if( ( path[i] &lt; 0x80 ) || ( path[i] &gt; 0xbf ) )
    {    cnt++;
    }
}