This works for me. There is probably a neater way of doing it in PERL.

I made it case-independent because it was The Right Thing(tm) to do, and
``-lo-!'' two of the RPMs (DrakProfile and DrakSync) had changed from dual-case
to lowercase during mirroring. I don't know if that's how it's supposed to be.

-- 
The Chico, California, City Council enacted a ban on nuclear weapons,
setting a $500 fine for anyone detonating one within city limits.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define FREE(pointer) /* nothing: waste of CPU for a one-shot program */

void printname (char * name, int len) {
        printf ("%s-%s\n", name, name + len);
}

int main (int argc, char * * argv) {
        int chosen1, scan1, scan2, scanlen;
        long n1, n2;
        char * candidate, * competitor;
        if (argc < 2) {
                printf ("Useage: %s file(s)\n"
                  "I pick the latest versions of RPM files and print the\n"
                  "names of losers. Typical invokation (BASH style) is:\n\n"
                  "    rm -f $(oldrpms *.rpm)\n", * argv);
                exit (1);
        }
        /* pass 1: eliminate non-RPMs, reduce all names to base names by
           chopping at the second-last hyphen, leaving the tail behind for
           later comparisons */
// fprintf (stderr, "#nonRPMs#\n");
        for (chosen1 = 1; chosen1 < argc; ++ chosen1) {
                if (strcasecmp (".rpm", argv[chosen1] + strlen (argv[chosen1]) - 4)) {
// fprintf (stderr, "#notRPM#%s\n", argv[chosen1]);
                        printf ("%s\n", argv[chosen1]);
                        FREE (argv[chosen1]);
                        argv[chosen1] = NULL;
                        continue;
                }
                candidate = strrchr (argv[chosen1], '-');
                if (candidate != NULL && candidate != argv[chosen1]) {
                        competitor = candidate;
                        * competitor = '\0';
                        candidate = strrchr (argv[chosen1], '-');
                        * competitor = '-';
                }
                if (candidate == NULL) { /* not a systematic RPM name */
// fprintf (stderr, "#notSystematic#%s\n", argv[chosen1]);
                        printf ("%s\n", argv[chosen1]);
                        FREE (argv[chosen1]);
                        argv[chosen1] = NULL;
                        continue;
                }
                * candidate = '\0';
        }
        /* pass 2: compare basenames for duplicates, eliminate singletons,
           compare tails of any remaining names and print/delete older of
           each pair */
// fprintf (stderr, "#dupes#\n");
        for (chosen1 = 1; chosen1 < argc; ++ chosen1) {
// fprintf (stderr, "# %d%%\r", chosen1 * 100 / argc);
                if (argv[chosen1] == NULL)
                        continue;
                scan1 = chosen1;
                scanlen = strlen (argv[chosen1]) + 1;
                for (scan2 = 1; scan2 < argc; ++ scan2) {
                        if (scan2 == scan1)
                                continue;
                        if (argv[scan2] == NULL)
                                continue;
                        if (strcasecmp (argv[scan1], argv[scan2]))
                                continue;
                        candidate = argv [scan1] + scanlen;
                        competitor = argv [scan2] + scanlen;
                        while (* candidate && * competitor) {
                                if (isdigit (* candidate) && isdigit (* competitor)) {
                                        n1 = strtol (candidate, & candidate, 10);
                                        n2 = strtol (competitor, & competitor, 10);
                                        if (n1 > n2) {
                                                printname (argv[scan2], scanlen);
                                                FREE (argv[scan1]);
                                                argv[scan2] = NULL;
                                                break;
                                        }
                                        if (n1 < n2) {
                                                printname (argv[scan1], scanlen);
                                                FREE (argv[scan1]);
                                                argv[scan1] = NULL;
                                                scan1 = scan2;
                                                break;
                                        }
                                } else { /* not both numbers */
                                        if (tolower (* candidate) > tolower (* 
competitor)) {
                                                printname (argv[scan2], scanlen);
                                                FREE (argv[scan1]);
                                                argv[scan2] = NULL;
                                                break;
                                        }
                                        if (tolower (* candidate) < tolower (* 
competitor)) {
                                                printname (argv[scan1], scanlen);
                                                FREE (argv[scan1]);
                                                argv[scan1] = NULL;
                                                scan1 = scan2;
                                                break;
                                        }
                                        ++ candidate;
                                        ++ competitor;
                                }
                        } /* compare to end or difference */
                }
        }
//      for (chosen1 = 1; chosen1 < argc; ++ chosen1) {
//              if (argv[chosen1] != NULL) {
//                      argv[chosen1][strlen (argv[chosen1])] = '-';
//                      fprintf (stderr, "#kept#%s\n", argv[chosen1]);
//              }
//      }
        exit (0);
}
/* end */

Reply via email to