Zsnes's zlib detection code problem.

Hi. I recently tried to build zsnes, however its zlib detection code seems to be seriously broken, as no matter how I pass it to configure, it won't detect it.

While I was not able to detect the precise code piece responsible for the problem, I have a few suspect. First I will copy configure's zlib code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
if test "${with_zlib_prefix+set}" = set; then
  withval=$with_zlib_prefix; zlib_prefix="$withval"
else
  zlib_prefix=""
fi

min_zlib_version=1.2.3
{ echo "$as_me:$LINENO: checking for zlib - version >= $min_zlib_version" >&5
echo $ECHO_N "checking for zlib - version >= $min_zlib_version... $ECHO_C" >&6; }

tempLIBS="$LIBS"
tempCFLAGS="$CFLAGS"
if test x$zlib_prefix != x ; then
  ZLIB_LIBS="-L$zlib_prefix"
  ZLIB_CFLAGS="-I$zlib_prefix"
fi
ZLIB_LIBS="$ZLIB_LIBS -lz"
LIBS="$LIBS $ZLIB_LIBS"
CFLAGS="$CFLAGS $ZLIB_CFLAGS"

if test "$cross_compiling" = yes; then
  { echo "$as_me:$LINENO: result: cross-compiling" >&5
echo "${ECHO_T}cross-compiling" >&6; }
  with_zlib=""
  { echo "$as_me:$LINENO: WARNING: Assuming zlib is available" >&5
echo "$as_me: WARNING: Assuming zlib is available" >&2;}
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

#include <zlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* my_strdup (char *str)
{
  char *new_str;

  if (str)
  {
    new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
    strcpy (new_str, str);
  }
  else new_str = NULL;

  return new_str;
}

int main (int argc, char *argv[])
{
  int major, minor, micro, zlib_major_version, zlib_minor_version, zlib_micro_version;

  char *zlibver, *tmp_version;

  zlibver = ZLIB_VERSION;
	printf ("%c", ZLIB_VERSION);

  FILE *fp = fopen("conf.zlibtest", "a");
  if ( fp ) {
    fprintf(fp, "%s", zlibver);
    fclose(fp);
  }

  /* HP/UX 9 (%@#!) writes to sscanf strings */
  tmp_version = my_strdup("$min_zlib_version");
  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
    printf("%s, bad version string for\n\tmin_zlib_version... ", "$min_zlib_version");
    exit(1);
  }
  if (sscanf(zlibver, "%d.%d.%d", &zlib_major_version, &zlib_minor_version, &zlib_micro_version) != 3) {
    printf("%s, bad version string given\n", zlibver);
    puts("\tby zlib, sometimes due to very old zlibs that didnt correctly");
    printf("\tdefine their version. Please upgrade if you are running an\n\told zlib... ");
    exit(1);
  }

  if ((zlib_major_version > major) ||
     ((zlib_major_version == major) && (zlib_minor_version > minor)) ||
     ((zlib_major_version == major) && (zlib_minor_version == minor) && (zlib_micro_version >= micro)))
  {
    return 0;
  }
  else
  {
    return 1;
  }
}

_ACEOF
rm -f conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
  (eval "$ac_link") 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
  { (case "(($ac_try" in
  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
  *) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
  (eval "$ac_try") 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  with_zlib=yes
else
  echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

( exit $ac_status )
with_zlib=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi



if test x$with_zlib != x; then
  { echo "$as_me:$LINENO: result: $with_zlib" >&5
echo "${ECHO_T}$with_zlib" >&6; }
fi
if test x$with_zlib = xyes; then
  ZLIB_VERSION=$(<conf.zlibtest)
  :
else
  ZLIB_CFLAGS=""
  ZLIB_LIBS=""
  ZLIB_VERSION=""
  { { echo "$as_me:$LINENO: error: zlib >= 1.2.3 is required" >&5
echo "$as_me: error: zlib >= 1.2.3 is required" >&2;}
   { (exit 1); exit 1; }; }
fi
LIBS="$tempLIBS"
CFLAGS="$tempCFLAGS"
rm conf.zlibtest


My main suspect was if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {. However, a few tests running a slight modified version of the c code isolated into a single file, didn't show me an awkward result from the variables of this line.

A few echos that I added to the test seems to indicate that the problem shows up from the point where the c code starts or latter.

So I am basically asking for suggestions on some lines of this piece of code to conduct experiments as to locate the precise cause of the problem.
Don't you get any error message telling you what goes wrong?

Is this something you put there yourself?
 
printf ("%c", ZLIB_VERSION);

GCC wrote:
warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char *’

Since ZLIB_VERSION is a string you probably want to use %s instead of %c.
Last edited on
Don't you get any error message telling you what goes wrong?


Besides:
1
2
configure:3798: WARNING: Assuming zlib is available
configure:3913: error: zlib >= 1.2.3 is required
. no

Is this something you put there yourself?


Yes.

I was able to run a lot of tests today using my own conftest and came to conclusion that the two most likely responsible lines are these two:

if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
.
if (sscanf(zlibver, "%d.%d.%d", &zlib_major_version, &zlib_minor_version, &zlib_micro_version) != 3)

placing these two printf:


printf ("major.minor.micro: %d.%d.%d\n");
..
printf ("zlib_major_version.zlib_minor_version.zlib_micro_version: %d.%d.%d\n");

I receive this weird output:

major.minor.micro: 141205512.134515000.-143699968

zlib_major_version.zlib_minor_version.zlib_micro_version: 141205512.134515000.-143699968

..which seems weird.

This causes the execution of the the third if clause:



1
2
3
4
5
6
7
if ((zlib_major_version > major) ||
     ((zlib_major_version == major) && (zlib_minor_version > minor)) ||
     ((zlib_major_version == major) && (zlib_minor_version == minor) && (zlib_micro_version >= micro)))
  {
		 printf ("BOTO3");
    return 0;
  }


However, thinking a bit more, it makes no difference, as these identical, weird triple numbers also satisfies the third comparison inside the if, as it would if the number versions were correct.

So the real problem might be beyond the c code, back in the shell script code.

P.S:I had to make a number of small modifications to be able to run my own conftest without shell script code.

The most important was probably this:

tmp_version = my_strdup("$min_zlib_version");

tmp_version = my_strdup("$1.2.3");

I executed an echo in the configure script that revealed that $min_zlib_version really evaluates to 1.2.3, as it should.

So it doesn't there is a problem with tmp_version or zlibver, which makes even weird these strange numbers being printed in the zlib_major_version, major etc, variables.

***RESUME*** While it appears to be a bug in the two sscanf line of codes, they would not be causing the issue, even by luck. The problem would lie ahead, back in the shell script code. However, as my own conftest code has to be a bit different so to allow me to execute it, I cannot be 100% sure.
You're not passing any arguments to match the %d.%d.%d in the printf format strings. That's why you saw garbage values. You probably meant to do the following:

1
2
printf("%d.%d.%d\n", major, minor, micro);
printf("%d.%d.%d\n", zlib_major_version, zlib_minor_version, zlib_micro_version);


If you manually change
 
tmp_version = my_strdup("$min_zlib_version");
to
 
tmp_version = my_strdup("$1.2.3");
then I think you should not include the $ inside the string.
Last edited on
Registered users can post here. Sign in or register to post.