[dpkdir] introducing dpkdeps.h
authorThomas Debesse <dev@illwieckz.net>
Sat, 22 Jul 2017 19:57:34 +0000 (21:57 +0200)
committerThomas Debesse <dev@illwieckz.net>
Sat, 29 Jul 2017 16:23:06 +0000 (18:23 +0200)
It was a change included in a commit by Neumond I haven't picked-up
because I disagreed with some other changes this commit introduced.

But this part is legit, it moves some DPK's DEPS file read and
version computation code to its own file. This clean-up a bit the
vfspk3 code and by the way it will be needed by future code to write
DEPS file from NetRadiant itself.

This commit is only about reorganizing code a better way.

include/CMakeLists.txt
include/dpkdeps.h [new file with mode: 0644]
plugins/vfspk3/vfs.cpp

index 02d7923..5c2a286 100644 (file)
@@ -1,6 +1,7 @@
 add_library(includes
         aboutmsg.h
         cullable.cpp cullable.h
+        dpkdeps.h
         editable.cpp editable.h
         iarchive.cpp iarchive.h
         ibrush.cpp ibrush.h
diff --git a/include/dpkdeps.h b/include/dpkdeps.h
new file mode 100644 (file)
index 0000000..424fbdc
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef __DPKDEPS_H__
+#define __DPKDEPS_H__
+
+#include <locale>
+#include "string/string.h"
+
+// Comparaison function for version numbers
+// Implementation is based on dpkg's version comparison code (verrevcmp() and order())
+// http://anonscm.debian.org/gitweb/?p=dpkg/dpkg.git;a=blob;f=lib/dpkg/version.c;hb=74946af470550a3295e00cf57eca1747215b9311
+inline int char_weight(char c){
+       if (std::isdigit(c))
+               return 0;
+       else if (std::isalpha(c))
+               return c;
+       else if (c == '~')
+               return -1;
+       else if (c)
+               return c + 256;
+       else
+               return 0;
+}
+
+inline int DpkPakVersionCmp(const char* a, const char* b){
+       while (*a || *b) {
+               int firstDiff = 0;
+
+               while ((*a && !std::isdigit(*a)) || (*b && !std::isdigit(*b))) {
+                       int ac = char_weight(*a);
+                       int bc = char_weight(*b);
+
+                       if (ac != bc)
+                               return ac - bc;
+
+                       a++;
+                       b++;
+               }
+
+               while (*a == '0')
+                       a++;
+               while (*b == '0')
+                       b++;
+
+               while (std::isdigit(*a) && std::isdigit(*b)) {
+                       if (firstDiff == 0)
+                               firstDiff = *a - *b;
+                       a++;
+                       b++;
+               }
+
+               if (std::isdigit(*a))
+                       return 1;
+               if (std::isdigit(*b))
+                       return -1;
+               if (firstDiff)
+                       return firstDiff;
+       }
+
+       return false;
+}
+
+// release strings after using
+inline bool DpkReadDepsLine( const char *line, char **pakname, char **pakversion ){
+       const char* c = line;
+       const char* p_name;
+       const char* p_name_end;
+       const char* p_version;
+       const char* p_version_end;
+
+       *pakname = 0;
+       *pakversion = 0;
+
+       while ( std::isspace( *c ) && *c != '\0' ) ++c;
+       p_name = c;
+       while ( !std::isspace( *c ) && *c != '\0' ) ++c;
+       p_name_end = c;
+       while ( std::isspace( *c ) && *c != '\0' ) ++c;
+       p_version = c;
+       while ( !std::isspace( *c ) && *c != '\0' ) ++c;
+       p_version_end = c;
+
+       if ( p_name_end - p_name > 0 ){
+               *pakname = string_clone_range( StringRange( p_name, p_name_end ) );
+       } else return false;
+
+       if ( p_version_end - p_version > 0 ) {
+               *pakversion = string_clone_range( StringRange( p_version, p_version_end ) );
+       }
+       return true;
+}
+
+#endif
index bee7403..bb3b5db 100644 (file)
@@ -59,6 +59,7 @@ ArchiveModules& FileSystemQ3API_getArchiveModules();
 #include "os/path.h"
 #include "moduleobservers.h"
 #include "filematch.h"
+#include "dpkdeps.h"
 
 
 #define VFS_MAXDIRS 64
@@ -322,60 +323,6 @@ void AddDpkPak( const char* name, const char* fullpath, bool is_pakfile ){
        g_pakfile_paths.insert( PakfilePathsKV( name, pakfile_path ) );
 }
 
-// Comparaison function for version numbers
-// Implementation is based on dpkg's version comparison code (verrevcmp() and order())
-// http://anonscm.debian.org/gitweb/?p=dpkg/dpkg.git;a=blob;f=lib/dpkg/version.c;hb=74946af470550a3295e00cf57eca1747215b9311
-static int char_weight(char c){
-       if (std::isdigit(c))
-               return 0;
-       else if (std::isalpha(c))
-               return c;
-       else if (c == '~')
-               return -1;
-       else if (c)
-               return c + 256;
-       else
-               return 0;
-}
-
-static int VersionCmp(const char* a, const char* b){
-       while (*a || *b) {
-               int firstDiff = 0;
-
-               while ((*a && !std::isdigit(*a)) || (*b && !std::isdigit(*b))) {
-                       int ac = char_weight(*a);
-                       int bc = char_weight(*b);
-
-                       if (ac != bc)
-                               return ac - bc;
-
-                       a++;
-                       b++;
-               }
-
-               while (*a == '0')
-                       a++;
-               while (*b == '0')
-                       b++;
-
-               while (std::isdigit(*a) && std::isdigit(*b)) {
-                       if (firstDiff == 0)
-                               firstDiff = *a - *b;
-                       a++;
-                       b++;
-               }
-
-               if (std::isdigit(*a))
-                       return 1;
-               if (std::isdigit(*b))
-                       return -1;
-               if (firstDiff)
-                       return firstDiff;
-       }
-
-       return false;
-}
-
 // takes name without ext, returns without ext
 static const char* GetLatestDpkPakVersion( const char* name ){
        const char* maxversion = 0;
@@ -389,7 +336,7 @@ static const char* GetLatestDpkPakVersion( const char* name ){
                pakname = i->first.c_str();
                if ( strncmp( pakname, name, namelen ) != 0 || pakname[namelen] != '_' ) continue;
                pakversion = pakname + (namelen + 1);
-               if ( maxversion == 0 || VersionCmp( pakversion, maxversion ) > 0 ){
+               if ( maxversion == 0 || DpkPakVersionCmp( pakversion, maxversion ) > 0 ){
                        maxversion = pakversion;
                        result = pakname;
                }
@@ -452,40 +399,22 @@ static void LoadDpkPakWithDeps( const char* pakname ){
                TextLinesInputStream<TextInputStream> istream = depsFile->getInputStream();
 
                CopiedString line;
-               const char* c;
-               const char* p_name;
-               const char* p_name_end;
-               const char* p_version;
-               const char* p_version_end;
+               char *p_name;
+               char *p_version;
                while ( line = istream.readLine(), string_length( line.c_str() ) ) {
-                       c = line.c_str();
-                       while ( std::isspace( *c ) && *c != '\0' ) ++c;
-                       p_name = c;
-                       while ( !std::isspace( *c ) && *c != '\0' ) ++c;
-                       p_name_end = c;
-                       while ( std::isspace( *c ) && *c != '\0' ) ++c;
-                       p_version = c;
-                       while ( !std::isspace( *c ) && *c != '\0' ) ++c;
-                       p_version_end = c;
-
-                       if ( p_name_end - p_name == 0 ) continue;
-                       if ( p_version_end - p_version == 0 ) {
-                               const char* p_pakname;
-                               CopiedString name_final = CopiedString( StringRange( p_name, p_name_end ) );
-                               p_pakname = GetLatestDpkPakVersion( name_final.c_str() );
-                               if ( p_pakname != NULL ) {
-                                       LoadDpkPakWithDeps( p_pakname );
-                               }
+                       if ( !DpkReadDepsLine( line.c_str(), &p_name, &p_version ) ) continue;
+                       if ( !p_version ) {
+                               const char* p_latest = GetLatestDpkPakVersion( p_name );
+                               if ( p_latest ) LoadDpkPakWithDeps( p_latest );
                        } else {
-                               int len = ( p_name_end - p_name ) + ( p_version_end - p_version ) + 1;
+                               int len = string_length( p_name ) + string_length( p_version ) + 1;
                                char* p_pakname = string_new( len );
-                               strncpy( p_pakname, p_name, p_name_end - p_name );
-                               p_pakname[ p_name_end - p_name ] = '\0';
-                               strcat( p_pakname, "_" );
-                               strncat( p_pakname, p_version, p_version_end - p_version );
+                               sprintf( p_pakname, "%s_%s", p_name, p_version );
                                LoadDpkPakWithDeps( p_pakname );
                                string_release( p_pakname, len );
                        }
+                       string_release( p_name, string_length( p_name ) );
+                       if ( p_version ) string_release( p_version, string_length( p_version ) );
                }
        }