// File: /workspace/github_c_makefile_star2_O3/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 0x14366(%rip), %rdi     # 0x2327e
movl %ecx, %esi
movl %ecx, %edx
xorl %eax, %eax
callq 0xd110
movq %rbx, %rax
movq 0x15d8(%rbx), %rsi
testq %rsi, %rsi
je 0xef45
leaq 0x14362(%rip), %rdi     # 0x2329b
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rax
movq 0x15e0(%rax), %rsi
testq %rsi, %rsi
je 0xef5f
leaq 0x1434c(%rip), %rdi     # 0x232a4
xorl %eax, %eax
callq 0xd110
leaq 0xf(%rsp), %r14
leaq 0x70(%rsp), %rdi
movq %r14, %rsi
callq 0xf3cf
leaq 0x1433a(%rip), %rcx     # 0x232b2
leaq 0x14366(%rip), %rdi     # 0x232e5
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 0xefe4
movzbl 0x15ef(%rdi), %ecx
cmpl $0xff, %ecx
je 0xefc8
movzbl 0x15ed(%rdi), %esi
addl %esi, %edx
leaq 0x14343(%rip), %rdi     # 0x23302
xorl %eax, %eax
callq 0xd110
jmp 0xefdf
movzbl 0x15ed(%rdi), %esi
addl %esi, %edx
leaq 0x1437f(%rip), %rdi     # 0x23357
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rdi
movzbl 0x15ec(%rdi), %edx
testl %edx, %edx
je 0xf033
movzbl 0x15f0(%rdi), %ecx
cmpl $0xff, %ecx
je 0xf017
movzbl 0x15ee(%rdi), %esi
addl %esi, %edx
leaq 0x142f4(%rip), %rdi     # 0x23302
xorl %eax, %eax
callq 0xd110
jmp 0xf02e
movzbl 0x15ee(%rdi), %esi
addl %esi, %edx
leaq 0x14330(%rip), %rdi     # 0x23357
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rdi
movzwl 0x15e8(%rdi), %esi
leal -0x1(%rsi), %eax
cmpw $-0x3, %ax
ja 0xf053
leaq 0x14355(%rip), %rdi     # 0x2339f
xorl %eax, %eax
callq 0xd110
jmp 0xf067
cmpl $0xffff, %esi           # imm = 0xFFFF
jne 0xf06c
leaq 0x1627c(%rip), %rdi     # 0x252de
callq 0xd0c0
leaq 0x70(%rsp), %rdi
movzbl 0x15ea(%rdi), %esi
testl %esi, %esi
je 0xf08a
leaq 0x14353(%rip), %rdi     # 0x233d1
xorl %eax, %eax
callq 0xd110
leaq 0x70(%rsp), %rdi
movl $0x88, %r14d
movl $0x1, %esi
leaq 0x14302(%rip), %r9      # 0x2339e
movq -0x70(%rdi,%r14), %rdx
testq %rdx, %rdx
je 0xf3b5
movq -0x50(%rdi,%r14), %rax
cmpb $0x0, (%rdx)
setne %cl
testq %rax, %rax
setne %r8b
andb %cl, %r8b
cmpb $0x1, %r8b
jne 0xf0e4
movb (%rax), %r10b
movq %r9, %rcx
movq %rax, %r8
testb %r10b, %r10b
je 0xf100
cmpb $0x2c, %r10b
leaq 0x14329(%rip), %rcx     # 0x23407
cmoveq %r9, %rcx
jmp 0xf0f5
movq %r9, %rcx
movq %r9, %r8
testq %rax, %rax
je 0xf100
movb (%rax), %r10b
movq %r9, %rcx
cmpb $0x2c, %r10b
cmoveq %r9, %rax
movq %rax, %r8
movl -0x60(%rdi,%r14), %ebp
movq -0x58(%rdi,%r14), %r15
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 0x142a9(%rip), %rdi     # 0x233f2
movl %esi, 0x2c(%rsp)
xorl %eax, %eax
callq 0xd110
testq %rbp, %rbp
movq %rbp, 0x10(%rsp)
je 0xf170
leaq 0x142a6(%rip), %rdi     # 0x2340b
movl %ebp, %esi
xorl %eax, %eax
callq 0xd110
jmp 0xf17c
leaq 0x161a7(%rip), %rdi     # 0x2531e
callq 0xd0c0
testq %r15, %r15
movsd 0x20(%rsp), %xmm0
je 0xf1b9
movzbl (%r15), %eax
cmpl $0x2c, %eax
je 0xf1b9
cmpl $0x3d, %eax
jne 0xf1a2
leaq 0x1(%r15), %rsi
leaq 0x14287(%rip), %rdi     # 0x23427
jmp 0xf1ac
leaq 0x1429b(%rip), %rdi     # 0x23444
movq %r15, %rsi
xorl %eax, %eax
callq 0xd110
movsd 0x20(%rsp), %xmm0
ucomisd 0x111df(%rip), %xmm0    # 0x203a0
jne 0xf1c5
jnp 0xf1d3
leaq 0x14294(%rip), %rdi     # 0x23460
movb $0x1, %al
callq 0xd110
testb $0x1, %r12b
leaq 0x142c2(%rip), %rsi     # 0x234a0
leaq 0x16181(%rip), %rax     # 0x25366
cmovneq %rax, %rsi
leaq 0x14292(%rip), %rdi     # 0x23482
xorl %eax, %eax
callq 0xd110
testl %r13d, %r13d
movq 0x30(%rsp), %r12
je 0xf251
movsd 0x20(%rsp), %xmm1
ucomisd 0x11189(%rip), %xmm1    # 0x20398
jne 0xf213
jnp 0xf240
ucomisd 0x11185(%rip), %xmm1    # 0x203a0
jne 0xf21f
jnp 0xf240
xorps %xmm0, %xmm0
cvtsi2sd %r13d, %xmm0
mulsd %xmm0, %xmm1
cvttsd2si %xmm1, %rsi
leaq 0x1428d(%rip), %rdi     # 0x234c4
xorl %eax, %eax
callq 0xd110
jmp 0xf251
leaq 0x1425f(%rip), %rdi     # 0x234a6
movl %r13d, %esi
xorl %eax, %eax
callq 0xd110
testb $0x1, 0xe(%rsp)
je 0xf264
leaq 0x160e0(%rip), %rdi     # 0x2533f
callq 0xd0c0
testq %r12, %r12
je 0xf38f
decl %ebx
cmpl $0x3, %ebx
ja 0xf38f
leaq 0x11129(%rip), %rcx     # 0x203a8
movslq (%rcx,%rbx,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x14254(%rip), %rdi     # 0x234e3
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
testq %r15, %r15
je 0xf2aa
cmpb $0x3d, (%r15)
je 0xf38f
movq $-0x1, %rsi
movq 0x10(%rsp), %rcx
shlq %cl, %rsi
notq %rsi
leaq 0x14243(%rip), %rdi     # 0x23506
xorl %eax, %eax
callq 0xd110
leaq 0x1ed(%rip), %rdi       # 0xf4be
jmp 0xf38c
leaq 0x14275(%rip), %rdi     # 0x23552
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
leaq 0x14288(%rip), %rdi     # 0x23578
movq 0x10(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
leaq 0x1e6(%rip), %rdi       # 0xf4e9
jmp 0xf38c
leaq 0x141d4(%rip), %rdi     # 0x234e3
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
testq %r15, %r15
je 0xf326
cmpb $0x3d, (%r15)
je 0xf38f
movq $-0x1, %rsi
movq 0x10(%rsp), %rcx
shlq %cl, %rsi
notq %rsi
leaq 0x141c7(%rip), %rdi     # 0x23506
xorl %eax, %eax
callq 0xd110
leaq 0x1b0(%rip), %rdi       # 0xf4fd
jmp 0xf38c
movq $-0x1, %r15
movq 0x10(%rsp), %rcx
shlq %cl, %r15
notq %r15
leaq 0x141bf(%rip), %rdi     # 0x23527
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0xd110
leaq 0x1418b(%rip), %rdi     # 0x23506
movq %r15, %rsi
xorl %eax, %eax
callq 0xd110
leaq 0x146(%rip), %rdi       # 0xf4d2
callq *%r12
addq $0xa8, %r14
movl 0x2c(%rsp), %esi
incl %esi
cmpq $0x1630, %r14           # imm = 0x1630
leaq 0x70(%rsp), %rdi
leaq 0x13fef(%rip), %r9      # 0x2339e
jne 0xf09c
leaq 0x13fe1(%rip), %rdi     # 0x2339d
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xd0c0