# zformat3.cpp

This sketch performs the same functions as zformat2::cpp, but uses recursive printf/scanf calls inside the custom handlers, to reduce the number of lines of code we have to write, and just to show we can. (Though convenient, note that this version consumes more stack space that the previous.)

    // Demonstrate recursive custom formatting and scanning using the '%Z'
    // and '%z' codes.

    struct TwoD {                   // Simple 2D coords based on shorts
      s16 x;                        // +-32K x range
      s16 y;                        // +-32K y range
    };

    void TwoDZPrinter(u8 face, void * arg, bool alt, int width, bool zerofill) {
      API_ASSERT_NONNULL(arg);      // Make sure we got an arg
      TwoD t = * (TwoD*) arg;       // Cast to the struct we require
      facePrintf(face,"(%d,%d)",t.x,t.y);  // Format our custom element, recursively
    }

    bool TwoDZScanner(u8 * packet, void * arg, bool alt, int width) {
      int x, y;
      if (packetScanf(packet,"(%d,%d)", &x, &y) != 5) // Recursive scanner call
        return false;
      if (arg) {                    // If they gave us a pointer
        TwoD * tp = (TwoD*) arg;    // Use it
        tp->x = x;
        tp->y = y;
      }
      return true;                  // Success!
    }

    void negateCoord(u8 * packet) {
      TwoD c;

      if (packetScanf(packet,"%Zn%z\n", TwoDZScanner, &c) != 3) {
        logNormal("Failed at %d\n",packetCursor(packet)); // Say where the parse died..
        return;
      }
      c.x = -c.x;                   // Negate the coord
      c.y = -c.y;                   // they gave us

      facePrintf(packetSource(packet),"n%Z%z\n", TwoDZPrinter, &c); // Print result
    }

    void setup() {
      Body.reflex('n',negateCoord);
    }

    void loop() {
      /* nothing to do */
    }