ESP8266 compiling error 'strtoul'

Hi guys,
I'm tring to program ESP8266 using arduino IDE and
http://arduino.esp8266.com/stable/package_esp8266com_index.json as additional board manager

I can't get rid of the compiling error

WiFiWebServer.ino:180: undefined reference to `strtoul'
collect2.exe: error: ld returned 1 exit status

line 180 is:
if (ch != -1)

here is a pieace of relevamt code:

bool readPOSTparam(char *name, int nameLen, char *value, int valueLen)
{
  // assume name is at current place in stream
  int ch;

  // clear out name and value so they'll be NUL terminated
  memset(name, 0, nameLen);
  memset(value, 0, valueLen);

  // decrement length so we don't write into NUL terminator
  --nameLen;
  --valueLen;

  while ((ch = read()) != -1)
  {
    if (ch == '+')
    {
      ch = ' ';
    }
    else if (ch == '=')
    {
      /* that's end of name, so switch to storing in value */
      nameLen = 0;
      continue;
    }
    else if (ch == '&')
    {
      /* that's end of pair, go away */
      return true;
    }
    else if (ch == '%')
    {
      /* handle URL encoded characters by converting back to original form */
      int ch1 = read();
      int ch2 = read();
      if (ch1 == -1 || ch2 == -1)
        return false;
      char hex[3] = { (char)ch1, (char)ch2, 0 };
      ch = strtoul(hex, NULL, 16);
    }

    // output the new character into the appropriate buffer or drop it if
    // there's no room in either one.  This code will malfunction in the
    // case where the parameter name is too long to fit into the name buffer,
    // but in that case, it will just overflow into the value buffer so
    // there's no harm.
    if (nameLen > 0)
    {
      *name++ = ch;
      --nameLen;
    }
    else if (valueLen > 0)
    {
      *value++ = ch;
      --valueLen;
    }
  }

  // if we get here, we hit the end-of-file, so POST is over and there
  // are no more parameters
  return false;
}

int read()
{
  if (NULL == client)
    return -1;

 // if (m_pushbackDepth == 0)
  if(1)
  {
    unsigned long timeoutTime = millis() + 1000;
    while (client.connected())
    {
      // stop reading the socket early if we get to content-length
      // characters in the POST.  This is because some clients leave
      // the socket open because they assume HTTP keep-alive.
/*
      if (m_readingContent)
      {
        if (m_contentLength == 0)
        {
          return -1;
        }
        --m_contentLength;
      }
*/
      int ch = client.read();

      // if we get a character, return it, otherwise continue in while
      // loop, checking connection status
      if (ch != -1)
      {
        return ch;
      }
      else
      {
        unsigned long now = millis();
        if (now > timeoutTime)
        {
          // connection timed out, destroy client, return EOF
        //  reset();
          return -1;
        }
      }
    }
    // connection lost, return EOF
    return -1;
  }
  else
  return 0;
  //  return m_pushback[--m_pushbackDepth];
}

Converting a 2 character HEX value does not result in an unsigned long. The result fits in a byte.

byte c1 = hex[0];
if(c1 >= '0' && c1 <= '9')
   c1 = (c1 - '0') * 16;
else if(c1 >= 'a' && c1 <= 'f')
   c1 = (c1 - 'a' + 10) * 16;
else if(c1 >= 'A' && c1 <= 'F')
   c1 = (c1 - 'a' + 10) * 16;

byte c2 = hex[1];
if(c2 >= '0' && c2 <= '9')
   c2 = (c2 - '0');
else if(c1 >= 'a' && c1 <= 'f')
   c2 = (c2 - 'a' + 10);
else if(c1 >= 'A' && c1 <= 'F')
   c2 = (c2 - 'a' + 10);

byte result = c1 + c2;

No need to use strtoul() for such a simple conversion.

I did not use strtoul anywhare in my code.. this is what I csn't understand.

PaulS:
Converting a 2 character HEX value does not result in an unsigned long. The result fits in a byte.

byte c1 = hex[0];

if(c1 >= '0' && c1 <= '9')
  c1 = (c1 - '0') * 16;
else if(c1 >= 'a' && c1 <= 'f')
  c1 = (c1 - 'a' + 10) * 16;
else if(c1 >= 'A' && c1 <= 'F')
  c1 = (c1 - 'a' + 10) * 16;

byte c2 = hex[1];
if(c2 >= '0' && c2 <= '9')
  c2 = (c2 - '0');
else if(c1 >= 'a' && c1 <= 'f')
  c2 = (c2 - 'a' + 10);
else if(c1 >= 'A' && c1 <= 'F')
  c2 = (c2 - 'a' + 10);

byte result = c1 + c2;




No need to use strtoul() for such a simple conversion.

What is this doing in readPOSTparam() then?

     ch = strtoul(hex, NULL, 16);

Pete

oooppss.. didn't noticed it :-[

yes you are right.. your solution solve it.

I was wonder why strtoul vaused me a proble, thought

I was wonder why strtoul vaused me a proble, thought

Well, I'm wondering what you were trying to say.

I'd try compiling your code for a regular (real) Arduino, to see if that caused any compilation issues, but, I know that it will since it is incomplete.

PaulS:
Well, I'm wondering what you were trying to say.

I'd try compiling your code for a regular (real) Arduino, to see if that caused any compilation issues, but, I know that it will since it is incomplete.

On a regular arduino (e.g Mega) it is compiling without errors but when I select ESP8266 it is not.
This makes me wonder why is it like that ?

On a regular arduino (e.g Mega) it is compiling without errors but when I select ESP8266 it is not.

The snippet of code you posted does not compile, on anything.

This makes me wonder why is it like that ?

Perhaps because the ESP thing is not really an Arduino.

Well, there's your problem:

platform.txt:

compiler.c.elf.flags=-g -Os -nostdlib ...
                            ^^^^^^^^^

So we don't have the standard C library that has strtoul().

Removing -nostdlib only makes the problem different:

.../xtensa-lx106-elf/bin/ld: cannot find crt1-sim.o: No such file or directory
.../xtensa-lx106-elf/bin/ld: cannot find _vectors.o: No such file or directory
.../build8540118121323437012.tmp/core.a(abi.cpp.o):(.bss+0x0): multiple definition of `__dso_handle'
.../lib/gcc/xtensa-lx106-elf/4.8.2/crtbegin.o:(.data+0x0): first defined here

collect2: error: ld returned 1 exit status

Next attempt: keep -nostdlib and add libc manually.

platform.local.txt:

compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig -lwps -lcrypto -lc

Bingo!

platform.txt and platform.local.txt are located in
.../Library/Arduino15/packages/esp8266/hardware/esp8266/‹version›

(If you dont't know where .../Library/Arduino15 is, open Preferences and see where preferences.txt is saved.)

platform.local.txt (112 Bytes)

Minimal sketch for testing:

void setup() {
  Serial.begin(115200);
  Serial.println(strtoul("xyzzy",NULL,36));
}

void loop() {}