// File: /workspace/github_c_makefile_star2_O1/canboat[P]canboat/analyzer/analyzer-explain.c
// Function: explainPGN
static void explainPGN(Pgn pgn)
{
  int  i;
  int  len;
  bool isVariable;

  printf("PGN: %d / %08o / %05X - %s\n\n", pgn.pgn, pgn.pgn, pgn.pgn, pgn.description);

  if (pgn.explanation != NULL)
  {
    printf("     %s\n", pgn.explanation);
  }
  if (pgn.url != NULL)
  {
    printf("     URL: %s\n", pgn.url);
  }
  len = getMinimalPgnLength(&pgn, &isVariable);
  if (isVariable)
  {
    printf("     The length is variable but at least %d bytes\n", len);
  }
  else
  {
    printf("     The length is %d bytes\n", len);
  }

  if (pgn.repeatingCount1 > 0)
  {
    if (pgn.repeatingField1 < 255)
    {
      printf("     Fields %u thru %u repeat n times, where n is the value contained in field %u.\n\n",
             pgn.repeatingStart1,
             pgn.repeatingStart1 + pgn.repeatingCount1,
             pgn.repeatingField1);
    }
    else
    {
      printf("     Fields %u thru %u repeat until the data in the PGN is exhausted.\n\n",
             pgn.repeatingStart1,
             pgn.repeatingStart1 + pgn.repeatingCount1);
    }
  }

  if (pgn.repeatingCount2 > 0)
  {
    if (pgn.repeatingField2 < 255)
    {
      printf("     Fields %u thru %u repeat n times, where n is the value contained in field %u.\n\n",
             pgn.repeatingStart2,
             pgn.repeatingStart2 + pgn.repeatingCount2,
             pgn.repeatingField2);
    }
    else
    {
      printf("     Fields %u thru %u repeat until the data in the PGN is exhausted.\n\n",
             pgn.repeatingStart2,
             pgn.repeatingStart2 + pgn.repeatingCount2);
    }
  }

  if (pgn.interval != 0 && pgn.interval < UINT16_MAX)
  {
    printf("     The PGN is normally transmitted every %u ms\n", pgn.interval);
  }
  if (pgn.interval == UINT16_MAX)
  {
    printf("     The PGN is transmitted on-demand or when data is available\n");
  }
  if (pgn.priority != 0)
  {
    printf("     The default priority is %u\n", pgn.priority);
  }

  for (i = 0; i < ARRAY_SIZE(pgn.fieldList) && pgn.fieldList[i].name; i++)
  {
    Field f = pgn.fieldList[i];
    printf("  Field #%d: %s%s%s\n",
           i + 1,
           f.name,
           f.name[0] && (f.description && f.description[0] && f.description[0] != ',') ? " - " : "",
           (!f.description || f.description[0] == ',') ? "" : f.description);
    if (f.size == LEN_VARIABLE)
    {
      printf("                  Bits: variable\n");
    }
    else
    {
      printf("                  Bits: %u\n", f.size);
    }

    if (f.unit && f.unit[0] == '=')
    {
      printf("                  Match: %s\n", &f.unit[1]);
    }
    else if (f.unit && f.unit[0] != ',')
    {
      printf("                  Unit: %s\n", f.unit);
    }

    if (f.resolution != 0.0)
    {
      printf("                  Resolution: %g\n", f.resolution);
    }
    printf("                  Signed: %s\n", (f.hasSign) ? "true" : "false");
    if (f.offset != 0)
    {
      if (f.resolution == 1.0 || f.resolution == 0.0)
      {
        printf("                  Offset: %d\n", f.offset);
      }
      else
      {
        printf("                  Offset: %" PRId64 "\n", (int64_t) (f.offset * f.resolution));
      }
    }
    if (f.partOfPrimaryKey)
    {
      printf("                  Part Of Primary Key: true\n");
    }

    if (f.lookup.function.pairEnumerator != NULL)
    {
      switch (f.lookup.type)
      {
        case LOOKUP_TYPE_PAIR: {
          printf("                  Enumeration: %s\n", f.lookup.name);
          if (!(f.unit && f.unit[0] == '='))
          {
            uint64_t maxValue = (UINT64_C(1) << f.size) - 1;
            printf("                  Range: 0..%" PRIu64 "\n", maxValue);
            (f.lookup.function.pairEnumerator)(explainPairText);
          }
          break;
        }

        case LOOKUP_TYPE_TRIPLET: {
          uint64_t maxValue = (UINT64_C(1) << f.size) - 1;
          printf("                  IndirectEnumeration: %s\n", f.lookup.name);
          printf("                  Range: 0..%" PRIu64 "\n", maxValue);
          (f.lookup.function.tripletEnumerator)(explainTripletText);
          break;
        }

        case LOOKUP_TYPE_BIT: {
          uint64_t maxValue = f.size;

          printf("                  BitEnumeration: %s\n", f.lookup.name);
          printf("                  BitRange: 0..%" PRIu64 "\n", maxValue);
          (f.lookup.function.bitEnumerator)(explainBitText);
          break;
        }

        case LOOKUP_TYPE_FIELDTYPE: {
          printf("                  Enumeration: %s\n", f.lookup.name);
          if (!(f.unit && f.unit[0] == '='))
          {
            uint64_t maxValue = (UINT64_C(1) << f.size) - 1;
            printf("                  Range: 0..%" PRIu64 "\n", maxValue);
            (f.lookup.function.fieldtypeEnumerator)(explainFieldtypeText);
          }
          break;
        }

        default:
          break;
      }
    }
  }

  printf("\n\n");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
leaq 0x70(%rsp), %rbx
movl 0x8(%rbx), %ecx
movq (%rbx), %r8
leaq 0x1c306(%rip), %rdi     # 0x2b27e
movl %ecx, %esi
movl %ecx, %edx
xorl %eax, %eax
callq 0xd110
movq %rbx, %rax
movq 0x15d8(%rbx), %rsi
testq %rsi, %rsi
je 0xefa5
leaq 0x1c302(%rip), %rdi     # 0x2b29b
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rax
movq 0x15e0(%rax), %rsi
testq %rsi, %rsi
je 0xefbf
leaq 0x1c2ec(%rip), %rdi     # 0x2b2a4
xorl %eax, %eax
callq 0xd110
leaq 0xf(%rsp), %r14
leaq 0x70(%rsp), %rdi
movq %r14, %rsi
callq 0xf42d
leaq 0x1c2da(%rip), %rcx     # 0x2b2b2
leaq 0x1c306(%rip), %rdi     # 0x2b2e5
cmpb $0x0, (%r14)
cmovneq %rcx, %rdi
movl %eax, %esi
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rdi
movzbl 0x15eb(%rdi), %edx
testl %edx, %edx
je 0xf044
movzbl 0x15ef(%rdi), %ecx
cmpl $0xff, %ecx
je 0xf028
movzbl 0x15ed(%rdi), %esi
addl %esi, %edx
leaq 0x1c2e3(%rip), %rdi     # 0x2b302
xorl %eax, %eax
callq 0xd110
jmp 0xf03f
movzbl 0x15ed(%rdi), %esi
addl %esi, %edx
leaq 0x1c31f(%rip), %rdi     # 0x2b357
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rdi
movzbl 0x15ec(%rdi), %edx
testl %edx, %edx
je 0xf093
movzbl 0x15f0(%rdi), %ecx
cmpl $0xff, %ecx
je 0xf077
movzbl 0x15ee(%rdi), %esi
addl %esi, %edx
leaq 0x1c294(%rip), %rdi     # 0x2b302
xorl %eax, %eax
callq 0xd110
jmp 0xf08e
movzbl 0x15ee(%rdi), %esi
addl %esi, %edx
leaq 0x1c2d0(%rip), %rdi     # 0x2b357
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rdi
movzwl 0x15e8(%rdi), %r14d
leal -0x1(%r14), %eax
cmpw $-0x3, %ax
ja 0xf0bb
leaq 0x1c2f3(%rip), %rdi     # 0x2b39f
movl %r14d, %esi
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rdi
cmpl $0xffff, %r14d          # imm = 0xFFFF
jne 0xf0d5
leaq 0x1e213(%rip), %rdi     # 0x2d2de
callq 0xd0c0
leaq 0x70(%rsp), %rdi
movzbl 0x15ea(%rdi), %esi
testl %esi, %esi
je 0xf0f3
leaq 0x1c2ea(%rip), %rdi     # 0x2b3d1
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rdi
movl $0x88, %r14d
movl $0x1, %esi
leaq 0x1c299(%rip), %r9      # 0x2b39e
movq -0x70(%rdi,%r14), %rdx
testq %rdx, %rdx
je 0xf413
movq -0x50(%rdi,%r14), %rax
cmpb $0x0, (%rdx)
setne %cl
testq %rax, %rax
setne %r8b
andb %cl, %r8b
movq %r9, %rcx
cmpb $0x1, %r8b
jne 0xf14b
movb (%rax), %r8b
movq %r9, %rcx
testb %r8b, %r8b
je 0xf14b
cmpb $0x2c, %r8b
leaq 0x1c2c0(%rip), %rcx     # 0x2b407
cmoveq %r9, %rcx
movq %r9, %r8
testq %rax, %rax
je 0xf15d
cmpb $0x2c, (%rax)
cmoveq %r9, %rax
movq %rax, %r8
movl -0x60(%rdi,%r14), %r15d
movq -0x58(%rdi,%r14), %rbp
movl -0x48(%rdi,%r14), %r13d
movsd -0x40(%rdi,%r14), %xmm0
movsd %xmm0, 0x20(%rsp)
movb -0x27(%rdi,%r14), %r12b
movb -0x26(%rdi,%r14), %al
movb %al, 0xe(%rsp)
movq -0x10(%rdi,%r14), %rax
movq %rax, 0x18(%rsp)
movl -0x8(%rdi,%r14), %ebx
movq (%rdi,%r14), %rax
movq %rax, 0x30(%rsp)
leaq 0x1c24c(%rip), %rdi     # 0x2b3f2
movl %esi, 0x2c(%rsp)
xorl %eax, %eax
callq 0xd110
testq %r15, %r15
movq %r15, 0x10(%rsp)
je 0xf1ce
leaq 0x1c249(%rip), %rdi     # 0x2b40b
movl %r15d, %esi
xorl %eax, %eax
callq 0xd110
jmp 0xf1da
leaq 0x1e149(%rip), %rdi     # 0x2d31e
callq 0xd0c0
testq %rbp, %rbp
movsd 0x20(%rsp), %xmm0
je 0xf217
movzbl (%rbp), %eax
cmpl $0x2c, %eax
je 0xf217
cmpl $0x3d, %eax
jne 0xf200
leaq 0x1(%rbp), %rsi
leaq 0x1c229(%rip), %rdi     # 0x2b427
jmp 0xf20a
leaq 0x1c23d(%rip), %rdi     # 0x2b444
movq %rbp, %rsi
xorl %eax, %eax
callq 0xd110
movsd 0x20(%rsp), %xmm0
ucomisd 0x19181(%rip), %xmm0    # 0x283a0
jne 0xf223
jnp 0xf231
leaq 0x1c236(%rip), %rdi     # 0x2b460
movb $0x1, %al
callq 0xd110
testb $0x1, %r12b
leaq 0x1c264(%rip), %rsi     # 0x2b4a0
leaq 0x1e123(%rip), %rax     # 0x2d366
cmovneq %rax, %rsi
leaq 0x1c234(%rip), %rdi     # 0x2b482
xorl %eax, %eax
callq 0xd110
testl %r13d, %r13d
movq 0x30(%rsp), %r12
je 0xf2af
movsd 0x20(%rsp), %xmm1
ucomisd 0x1912b(%rip), %xmm1    # 0x28398
jne 0xf271
jnp 0xf29e
ucomisd 0x19127(%rip), %xmm1    # 0x283a0
jne 0xf27d
jnp 0xf29e
xorps %xmm0, %xmm0
cvtsi2sd %r13d, %xmm0
mulsd %xmm0, %xmm1
cvttsd2si %xmm1, %rsi
leaq 0x1c22f(%rip), %rdi     # 0x2b4c4
xorl %eax, %eax
callq 0xd110
jmp 0xf2af
leaq 0x1c201(%rip), %rdi     # 0x2b4a6
movl %r13d, %esi
xorl %eax, %eax
callq 0xd110
testb $0x1, 0xe(%rsp)
je 0xf2c2
leaq 0x1e082(%rip), %rdi     # 0x2d33f
callq 0xd0c0
testq %r12, %r12
je 0xf3ed
decl %ebx
cmpl $0x3, %ebx
ja 0xf3ed
leaq 0x190cb(%rip), %rcx     # 0x283a8
movslq (%rcx,%rbx,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x1c1f6(%rip), %rdi     # 0x2b4e3
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
testq %rbp, %rbp
je 0xf308
cmpb $0x3d, (%rbp)
je 0xf3ed
movq $-0x1, %rsi
movq 0x10(%rsp), %rcx
shlq %cl, %rsi
notq %rsi
leaq 0x1c1e5(%rip), %rdi     # 0x2b506
xorl %eax, %eax
callq 0xd110
leaq 0x1e2(%rip), %rdi       # 0xf511
jmp 0xf3ea
leaq 0x1c217(%rip), %rdi     # 0x2b552
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
leaq 0x1c22a(%rip), %rdi     # 0x2b578
movq 0x10(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
leaq 0x1db(%rip), %rdi       # 0xf53c
jmp 0xf3ea
leaq 0x1c176(%rip), %rdi     # 0x2b4e3
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
testq %rbp, %rbp
je 0xf384
cmpb $0x3d, (%rbp)
je 0xf3ed
movq $-0x1, %rsi
movq 0x10(%rsp), %rcx
shlq %cl, %rsi
notq %rsi
leaq 0x1c169(%rip), %rdi     # 0x2b506
xorl %eax, %eax
callq 0xd110
leaq 0x1a5(%rip), %rdi       # 0xf550
jmp 0xf3ea
movq $-0x1, %r15
movq 0x10(%rsp), %rcx
shlq %cl, %r15
notq %r15
leaq 0x1c161(%rip), %rdi     # 0x2b527
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
leaq 0x1c12d(%rip), %rdi     # 0x2b506
movq %r15, %rsi
xorl %eax, %eax
callq 0xd110
leaq 0x13b(%rip), %rdi       # 0xf525
callq *%r12
addq $0xa8, %r14
movl 0x2c(%rsp), %esi
incl %esi
cmpq $0x1630, %r14           # imm = 0x1630
leaq 0x70(%rsp), %rdi
leaq 0x1bf91(%rip), %r9      # 0x2b39e
jne 0xf105
leaq 0x1bf83(%rip), %rdi     # 0x2b39d
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xd0c0