Description: Sort icon list for reproducible gresource

 gretl-icons.gresource is compiled from gretl-icons.xml, which mkpnglist
 generates by walking the 16x16 and 24x24 icon directories with readdir().
 The resulting (unsorted) order is filesystem-dependent, so the compiled
 GResource differs between rebuilds. Sort the entries with scandir() and a
 locale-independent strcmp-based comparator.

Author: Dirk Eddelbuettel <edd@debian.org>
Last-Update: 2026-10-27

--- gretl-2026c.orig/gui/mkpnglist.c
+++ gretl-2026c/gui/mkpnglist.c
@@ -11,11 +11,14 @@
 #include <sys/types.h>
 #include <dirent.h>
 
+static int cmp_png (const struct dirent **a, const struct dirent **b)
+{
+    return strcmp((*a)->d_name, (*b)->d_name);
+}
+
 int main (int argc, char **argv)
 {
-    struct dirent *de;
     char dirname[512];
-    DIR *icond[2];
     int px[2] = {16, 24};
     FILE *fp;
     int i;
@@ -25,20 +29,6 @@
 	exit(EXIT_FAILURE);
     }
 
-    sprintf(dirname, "%s/icons/16x16", argv[1]);
-    icond[0] = opendir(dirname);
-    if (icond[0] == NULL) {
-	fprintf(stderr, "%s: couldn't open %s\n", argv[0], dirname);
-	exit(EXIT_FAILURE);
-    }
-
-    sprintf(dirname, "%s/icons/24x24", argv[1]);
-    icond[1] = opendir(dirname);
-    if (icond[1] == NULL) {
-	fprintf(stderr, "%s: couldn't open %s\n", argv[0], dirname);
-	exit(EXIT_FAILURE);
-    }    
-
     fp = fopen("gretl-icons.xml", "w");
     if (fp == NULL) {
 	fprintf(stderr, "%s: couldn't open %s\n", argv[0], "gretl-icons.xml");
@@ -51,19 +41,28 @@
     fputs("  <gresource prefix=\"/gretl\">\n", fp);
 
     for (i=0; i<2; i++) {
-	while ((de = readdir(icond[i])) != NULL) {
-	    if (strstr(de->d_name, ".png")) {
+	struct dirent **list;
+	int n, j;
+
+	sprintf(dirname, "%s/icons/%dx%d", argv[1], px[i], px[i]);
+	n = scandir(dirname, &list, NULL, cmp_png);
+	if (n < 0) {
+	    fprintf(stderr, "%s: couldn't open %s\n", argv[0], dirname);
+	    exit(EXIT_FAILURE);
+	}
+	for (j=0; j<n; j++) {
+	    if (strstr(list[j]->d_name, ".png")) {
 		fprintf(fp, "    <file>icons/%dx%d/%s</file>\n",
-			px[i], px[i], de->d_name);
+			px[i], px[i], list[j]->d_name);
 	    }
+	    free(list[j]);
 	}
+	free(list);
     }
 
     fputs("  </gresource>\n", fp);
     fputs("</gresources>\n", fp);
 
-    closedir(icond[0]);
-    closedir(icond[1]);
     fclose(fp);
 
     return 0;
