- fix filelist handling in repo_susetags and testcase
authorMichael Schroeder <mls@suse.de>
Thu, 16 Feb 2012 15:08:56 +0000 (16:08 +0100)
committerMichael Schroeder <mls@suse.de>
Thu, 16 Feb 2012 15:08:56 +0000 (16:08 +0100)
ext/repo_susetags.c
ext/testcase.c

index d452812..98b85ce 100644 (file)
@@ -40,6 +40,9 @@ struct parsedata {
   char *language;                      /* the default language */
   Id langcache[ID_NUM_INTERNAL];       /* cache for the default language */
   int lineno;
+  char *filelist;
+  int afilelist;                       /* allocated */
+  int nfilelist;                       /* used */
 };
 
 static char *flagtab[] = {
@@ -396,65 +399,24 @@ finish_solvable(struct parsedata *pd, Solvable *s, Id handle, Offset freshens)
 {
   Pool *pool = pd->repo->pool;
 
-#if 1
-  /* move file provides to filelist */
-  /* relies on the fact that rpm inserts self-provides at the end */
-  if (s->provides && (pd->flags & REPO_EXTEND_SOLVABLES) == 0)
+  if (pd->nfilelist)
     {
-      Id *p, *lastreal, did;
-      const char *str, *sp;
-      lastreal = pd->repo->idarraydata + s->provides;
-      for (p = lastreal; *p; p++)
-       if (ISRELDEP(*p))
-         lastreal = p + 1;
-      for (p = lastreal; *p; p++)
-       {
-         str = pool_id2str(pool, *p);
-         if (*str != '/')
-           lastreal = p + 1;
-       }
-      if (*lastreal)
-       {
-         for (p = lastreal; *p; p++)
-           {
-             char fname_buf[128];
-             const char *fname;
-             str = pool_id2str(pool, *p);
-             sp = strrchr(str, '/');
-             /* Need to copy filename now, before we add string that could
-                realloc the stringspace (and hence invalidate str).  */
-             fname = sp + 1;
-             if (strlen(fname) >= 128)
-               fname = solv_strdup(fname);
-             else
-               {
-                 memcpy(fname_buf, fname, strlen(fname) + 1);
-                 fname = fname_buf;
-               }
-             if (sp - str >= 128)
-               {
-                 char *sdup = solv_strdup(str);
-                 sdup[sp - str] = 0;
-                 did = repodata_str2dir(pd->data, sdup, 1);
-                 free(sdup);
-               }
-             else
-               {
-                 char sdup[128];
-                 strncpy(sdup, str, sp - str);
-                 sdup[sp - str] = 0;
-                 did = repodata_str2dir(pd->data, sdup, 1);
-               }
-             if (!did)
-               did = repodata_str2dir(pd->data, "/", 1);
-             repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, did, fname);
-             if (fname != fname_buf)
-               free((char*)fname);
-             *p = 0;
-           }
+      int l;
+      Id did;
+      for (l = 0; l < pd->nfilelist; l += strlen(pd->filelist + l) + 1)
+        {
+         char *p = strrchr(pd->filelist + l, '/');
+         if (!p)
+           continue;
+         *p++ = 0;
+         did = repodata_str2dir(pd->data, pd->filelist + l, 1);
+         p[-1] = '/';
+         if (!did)
+           did = repodata_str2dir(pd->data, "/", 1);
+         repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, did, p);
        }
+      pd->nfilelist = 0;
     }
-#endif
   /* A self provide, except for source packages.  This is harmless
      to do twice (in case we see the same package twice).  */
   if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
@@ -918,6 +880,26 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int
       switch (tag)
         {
          case CTAG('=', 'P', 'r', 'v'):                                        /* provides */
+           if (line[6] == '/')
+             {
+               /* probably a filelist entry. stash it away for now */
+               int l = strlen(line + 6) + 1;
+               if (pd.nfilelist + l > pd.afilelist)
+                 {
+                   pd.afilelist = pd.nfilelist + l + 512;
+                   pd.filelist = solv_realloc(pd.filelist, pd.afilelist);
+                 }
+               memcpy(pd.filelist + pd.nfilelist, line + 6, l);
+               pd.nfilelist += l;
+               break;
+             }
+           if (pd.nfilelist)
+             {
+               int l;
+               for (l = 0; l < pd.nfilelist; l += strlen(pd.filelist + l) + 1)
+                 s->provides = repo_addid_dep(pd.repo, s->provides, pool_str2id(pool, pd.filelist + l, 1), 0);
+               pd.nfilelist = 0;
+             }
            s->provides = adddep(pool, &pd, s->provides, line, 0, pd.kind);
            continue;
          case CTAG('=', 'R', 'e', 'q'):                                        /* requires */
@@ -1124,6 +1106,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int
            {
              char *p = strrchr(line + 6, '/');
              Id did;
+             /* strip trailing slash */
              if (p && p != line + 6 && !p[1])
                {
                  *p = 0;
@@ -1168,6 +1151,7 @@ repo_add_susetags(Repo *repo, FILE *fp, Id defvendor, const char *language, int
 
   if (s)
     finish_solvable(&pd, s, handle, freshens);
+  solv_free(pd.filelist);
 
   /* Shared attributes
    *  (e.g. multiple binaries built from same source)
index b905190..b1ef07d 100644 (file)
@@ -707,7 +707,7 @@ writedeps(Repo *repo, FILE *fp, const char *tag, Id key, Solvable *s, Offset off
        }
       if (key == SOLVABLE_PROVIDES && id == SOLVABLE_FILEMARKER)
        {
-         prvdp = dp + 1;
+         prvdp = dp;
          continue;
        }
       idstr = pool_dep2str(pool, id);
@@ -860,29 +860,23 @@ adddep(Repo *repo, Offset olddeps, char *str, Id marker)
 }
 
 static void
-finish_solvable(Pool *pool, Repodata *data, Solvable *s)
+finish_solvable(Pool *pool, Repodata *data, Solvable *s, char *filelist, int nfilelist)
 {
-  /* move file provides to filelist */
-  if (s->provides)
+  if (nfilelist)
     {
-      Id *p, *lastreal, did;
-      lastreal = s->repo->idarraydata + s->provides;
-      for (p = lastreal; *p; p++)
-        if (ISRELDEP(*p))
-         lastreal = p + 1;
-      for (p = lastreal; *p; p++)
-       if ((pool_id2str(pool, *p))[0] != '/')
-         lastreal = p + 1;
-      for (p = lastreal; *p; p++)
+      int l;
+      Id did; 
+      for (l = 0; l < nfilelist; l += strlen(filelist + l) + 1) 
        {
-         char *str = pool_tmpjoin(pool, pool_id2str(pool, *p), 0, 0);
-         char *sp = strrchr(str, '/');
-         *sp++ = 0;
-         did = repodata_str2dir(data, str, 1);
+         char *p = strrchr(filelist + l, '/');
+         if (!p) 
+           continue;
+         *p++ = 0; 
+         did = repodata_str2dir(data, filelist + l, 1);
+         p[-1] = '/'; 
          if (!did)
            did = repodata_str2dir(data, "/", 1);
-         repodata_add_dirstr(data, s - pool->solvables, SOLVABLE_FILELIST, did, sp);
-         *p = 0;
+         repodata_add_dirstr(data, handle, SOLVABLE_FILELIST, did, p);
        }
     }
   if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC)
@@ -904,6 +898,9 @@ testcase_add_susetags(Repo *repo, FILE *fp, int flags)
   char *sp[5];
   unsigned int t;
   int intag;
+  char *filelist = 0;
+  int afilelist = 0;
+  int nfilelist = 0;
 
   data = repo_add_repodata(repo, flags);
   s = 0;
@@ -955,7 +952,8 @@ testcase_add_susetags(Repo *repo, FILE *fp, int flags)
         {
        case 'P' << 16 | 'k' << 8 | 'g':
          if (s)
-           finish_solvable(pool, data, s);
+           finish_solvable(pool, data, s, filelist, nfilelist);
+         nfilelist = 0;
          if (split(line + 5, sp, 5) != 4)
            break;
          s = pool_id2solvable(pool, repo_add_solvable(repo));
@@ -984,6 +982,25 @@ testcase_add_susetags(Repo *repo, FILE *fp, int flags)
          s->requires = adddep(repo, s->requires, line + 6, SOLVABLE_PREREQMARKER);
          break;
        case 'P' << 16 | 'r' << 8 | 'v':
+         if (line[6] == '/')
+           {
+             int l = strlen(line + 6) + 1;
+             if (nfilelist + l > afilelist)
+               {
+                 afilelist = nfilelist + l + 512;
+                 filelist = solv_realloc(filelist, afilelist);
+               }
+             memcpy(filelist + nfilelist, line + 6, l);
+             nfilelist += l;
+             break;
+           }
+         if (nfilelist)
+           {
+             int l;
+             for (l = 0; l < nfilelist; l += strlen(filelist + l) + 1)
+                s->provides = repo_addid_dep(repo, s->provides, pool_str2id(pool, filelist + l, 1), 0);
+              nfilelist = 0;
+           }
          s->provides = adddep(repo, s->provides, line + 6, 0);
          break;
        case 'O' << 16 | 'b' << 8 | 's':
@@ -1009,10 +1026,11 @@ testcase_add_susetags(Repo *repo, FILE *fp, int flags)
         }
     }
   if (s)
-    finish_solvable(pool, data, s);
+    finish_solvable(pool, data, s, filelist, nfilelist);
+  solv_free(line);
+  solv_free(filelist);
   if (!(flags & REPO_NO_INTERNALIZE))
     repodata_internalize(data);
-  solv_free(line);
   return 0;
 }