// File: /workspace/github_cpp_makefile_star2_O2/jaudoux[P]countTags/src/optionparser.h
// Function: option::PrintUsageImplementation::printUsage(option::PrintUsageImplementation::IStringWriter&, option::Descriptor const*, int, int, int)
static void printUsage(IStringWriter& write, const Descriptor usage[], int width = 80, //
                         int last_column_min_percent = 50, int last_column_own_line_max_percent = 75)
  {
    if (width < 1) // protect against nonsense values
      width = 80;

    if (width > 10000) // protect against overflow in the following computation
      width = 10000;

    int last_column_min_width = ((width * last_column_min_percent) + 50) / 100;
    int last_column_own_line_max_width = ((width * last_column_own_line_max_percent) + 50) / 100;
    if (last_column_own_line_max_width == 0)
      last_column_own_line_max_width = 1;

    LinePartIterator part(usage);
    while (part.nextTable())
    {

      /***************** Determine column widths *******************************/

      const int maxcolumns = 8; // 8 columns are enough for everyone
      int col_width[maxcolumns];
      int lastcolumn;
      int leftwidth;
      int overlong_column_threshold = 10000;
      do
      {
        lastcolumn = 0;
        for (int i = 0; i < maxcolumns; ++i)
          col_width[i] = 0;

        part.restartTable();
        while (part.nextRow())
        {
          while (part.next())
          {
            if (part.column() < maxcolumns)
            {
              upmax(lastcolumn, part.column());
              if (part.screenLength() < overlong_column_threshold)
                // We don't let rows that don't use table separators (\t or \v) influence
                // the width of column 0. This allows the user to interject section headers
                // or explanatory paragraphs that do not participate in the table layout.
                if (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
                    || part.data()[part.length()] == '\v')
                  upmax(col_width[part.column()], part.screenLength());
            }
          }
        }

        /*
         * If the last column doesn't fit on the same
         * line as the other columns, we can fix that by starting it on its own line.
         * However we can't do this for any of the columns 0..lastcolumn-1.
         * If their sum exceeds the maximum width we try to fix this by iteratively
         * ignoring the widest line parts in the width determination until
         * we arrive at a series of column widths that fit into one line.
         * The result is a layout where everything is nicely formatted
         * except for a few overlong fragments.
         * */

        leftwidth = 0;
        overlong_column_threshold = 0;
        for (int i = 0; i < lastcolumn; ++i)
        {
          leftwidth += col_width[i];
          upmax(overlong_column_threshold, col_width[i]);
        }

      } while (leftwidth > width);

      /**************** Determine tab stops and last column handling **********************/

      int tabstop[maxcolumns];
      tabstop[0] = 0;
      for (int i = 1; i < maxcolumns; ++i)
        tabstop[i] = tabstop[i - 1] + col_width[i - 1];

      int rightwidth = width - tabstop[lastcolumn];
      bool print_last_column_on_own_line = false;
      if (rightwidth < last_column_min_width && rightwidth < col_width[lastcolumn])
      {
        print_last_column_on_own_line = true;
        rightwidth = last_column_own_line_max_width;
      }

      // If lastcolumn == 0 we must disable print_last_column_on_own_line because
      // otherwise 2 copies of the last (and only) column would be output.
      // Actually this is just defensive programming. It is currently not
      // possible that lastcolumn==0 and print_last_column_on_own_line==true
      // at the same time, because lastcolumn==0 => tabstop[lastcolumn] == 0 =>
      // rightwidth==width => rightwidth>=last_column_min_width  (unless someone passes
      // a bullshit value >100 for last_column_min_percent) => the above if condition
      // is false => print_last_column_on_own_line==false
      if (lastcolumn == 0)
        print_last_column_on_own_line = false;

      LineWrapper lastColumnLineWrapper(width - rightwidth, width);
      LineWrapper interjectionLineWrapper(0, width);

      part.restartTable();

      /***************** Print out all rows of the table *************************************/

      while (part.nextRow())
      {
        int x = -1;
        while (part.next())
        {
          if (part.column() > lastcolumn)
            continue; // drop excess columns (can happen if lastcolumn == maxcolumns-1)

          if (part.column() == 0)
          {
            if (x >= 0)
              write("\n", 1);
            x = 0;
          }

          indent(write, x, tabstop[part.column()]);

          if ((part.column() < lastcolumn)
              && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
                  || part.data()[part.length()] == '\v'))
          {
            write(part.data(), part.length());
            x += part.screenLength();
          }
          else // either part.column() == lastcolumn or we are in the special case of
               // an interjection that doesn't contain \v or \t
          {
            // NOTE: This code block is not necessarily executed for
            // each line, because some rows may have fewer columns.

            LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;

            if (!print_last_column_on_own_line)
              lineWrapper.process(write, part.data(), part.length());
          }
        } // while

        if (print_last_column_on_own_line)
        {
          part.restartRow();
          while (part.next())
          {
            if (part.column() == lastcolumn)
            {
              write("\n", 1);
              int _ = 0;
              indent(write, _, width - rightwidth);
              lastColumnLineWrapper.process(write, part.data(), part.length());
            }
          }
        }

        write("\n", 1);
        lastColumnLineWrapper.flush(write);
        interjectionLineWrapper.flush(write);
      }
    }
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x258, %rsp            # imm = 0x258
movq %rdi, %rbx
movl $0x2710, %eax           # imm = 0x2710
cmpl %eax, %edx
cmovbl %edx, %eax
testl %edx, %edx
pushq $0x50
popq %r15
cmovgl %eax, %r15d
imull %r15d, %ecx
leal 0x32(%rcx), %eax
pushq $0x64
popq %rcx
cltd
idivl %ecx
movl %eax, 0x58(%rsp)
imull %r15d, %r8d
leal 0x32(%r8), %eax
cltd
idivl %ecx
addl $0x95, %r8d
cmpl $0xc7, %r8d
pushq $0x1
popq %rcx
cmovbl %ecx, %eax
movl %eax, 0x54(%rsp)
leaq 0x34(%rsp), %rcx
movq %rsi, -0x24(%rcx)
xorps %xmm0, %xmm0
movups %xmm0, -0x1c(%rcx)
andq $0x0, -0xc(%rcx)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, -0x4(%rcx)
andq $0x0, 0x8(%rcx)
andl $0x0, 0x10(%rcx)
movb $0x1, 0x14(%rcx)
leaq 0x10(%rsp), %r12
leaq 0x8(%rsp), %r14
movl %r15d, 0xc(%rsp)
movq %r12, %rdi
callq 0x4154
testb %al, %al
je 0x4135
movl $0x2710, %ebp           # imm = 0x2710
xorl %eax, %eax
cmpq $0x8, %rax
je 0x3e1f
andl $0x0, 0x60(%rsp,%rax,4)
incq %rax
jmp 0x3e0f
movq 0x10(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x20(%rax), %rax
movq %rax, 0x20(%rsp)
andq $0x0, 0x28(%rsp)
xorl %r13d, %r13d
movq %r12, %rdi
callq 0x41aa
testb %al, %al
jne 0x3e91
jmp 0x3e9f
movslq 0x30(%rsp), %rax
cmpq $0x7, %rax
jg 0x3e91
cmpl %eax, %r13d
cmovlel %eax, %r13d
movl 0x38(%rsp), %ecx
cmpl %ebp, %ecx
jge 0x3e91
testl %eax, %eax
jg 0x3e84
cmpl $0x0, 0x44(%rsp)
jg 0x3e84
movq 0x28(%rsp), %rdx
movslq 0x34(%rsp), %rsi
movzbl (%rdx,%rsi), %edx
orl $0x2, %edx
cmpl $0xb, %edx
jne 0x3e91
movl 0x60(%rsp,%rax,4), %edx
cmpl %ecx, %edx
cmovgl %edx, %ecx
movl %ecx, 0x60(%rsp,%rax,4)
movq %r12, %rdi
callq 0x4222
testb %al, %al
jne 0x3e49
jmp 0x3e3b
xorl %eax, %eax
testl %r13d, %r13d
movl $0x0, %ecx
cmovgl %r13d, %ecx
xorl %ebp, %ebp
xorl %edx, %edx
cmpq %rax, %rcx
je 0x3ec6
movl 0x60(%rsp,%rax,4), %esi
addl %esi, %edx
cmpl %esi, %ebp
cmovlel %esi, %ebp
incq %rax
jmp 0x3eb1
cmpl %r15d, %edx
jg 0x3e0d
andl $0x0, 0x80(%rsp)
xorl %eax, %eax
pushq $0x1
popq %rcx
cmpq $0x8, %rcx
je 0x3ef2
addl 0x5c(%rsp,%rcx,4), %eax
movl %eax, 0x80(%rsp,%rcx,4)
incq %rcx
jmp 0x3edc
movl %r13d, %eax
movl %r15d, %ecx
subl 0x80(%rsp,%rax,4), %ecx
cmpl 0x58(%rsp), %ecx
jge 0x3f13
cmpl 0x60(%rsp,%rax,4), %ecx
setl %al
cmovll 0x54(%rsp), %ecx
jmp 0x3f15
xorl %eax, %eax
subl %ecx, %r15d
movl %r15d, 0x168(%rsp)
movl %ecx, 0x16c(%rsp)
movabsq $0xf00000000, %rdx      # imm = 0xF00000000
movq %rdx, 0x170(%rsp)
cmpl $0x1, %ecx
jg 0x3f49
movl $0x2, 0x16c(%rsp)
andl $0x0, 0x240(%rsp)
movl 0xc(%rsp), %ecx
movl %ecx, 0x244(%rsp)
movq %rdx, 0x248(%rsp)
cmpl $0x1, %ecx
ja 0x3f74
movl $0x2, 0x244(%rsp)
testl %r13d, %r13d
setne %bpl
movq 0x10(%rsp), %rcx
movq %rcx, 0x18(%rsp)
movq 0x20(%rcx), %rcx
movq %rcx, 0x20(%rsp)
andq $0x0, 0x28(%rsp)
andb %al, %bpl
movq %r12, %rdi
callq 0x41aa
testb %al, %al
je 0x412b
orl $-0x1, 0x8(%rsp)
movq %r12, %rdi
callq 0x4222
testb %al, %al
je 0x4077
movl 0x30(%rsp), %eax
cmpl %r13d, %eax
jg 0x3fac
testl %eax, %eax
jne 0x3fef
cmpl $0x0, 0x8(%rsp)
js 0x3fe8
movq (%rbx), %rax
movq %rbx, %rdi
leaq 0x22d7(%rip), %rsi      # 0x62b4
pushq $0x1
popq %rdx
callq *(%rax)
movl 0x30(%rsp), %eax
jmp 0x3fea
xorl %eax, %eax
andl $0x0, 0x8(%rsp)
cltq
movl 0x80(%rsp,%rax,4), %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x431a
movl 0x30(%rsp), %eax
cmpl %r13d, %eax
jge 0x4042
movq 0x28(%rsp), %rsi
movslq 0x34(%rsp), %rdx
testl %eax, %eax
jg 0x402d
cmpl $0x0, 0x44(%rsp)
jg 0x402d
movzbl (%rsi,%rdx), %ecx
orl $0x2, %ecx
cmpl $0xb, %ecx
jne 0x4042
movq (%rbx), %rax
movq %rbx, %rdi
callq *(%rax)
movl 0x38(%rsp), %eax
addl %eax, 0x8(%rsp)
jmp 0x3fac
testb %bpl, %bpl
jne 0x3fac
testl %eax, %eax
leaq 0xa8(%rsp), %rdi
leaq 0x180(%rsp), %rax
cmoveq %rax, %rdi
movq 0x28(%rsp), %rdx
movl 0x34(%rsp), %ecx
movq %rbx, %rsi
callq 0x4384
jmp 0x3fac
testb %bpl, %bpl
je 0x40f4
movq 0x20(%rsp), %rax
movq %rax, 0x28(%rsp)
orl $-0x1, 0x30(%rsp)
leaq 0x34(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
andl $0x0, 0x10(%rax)
movb $0x1, 0x48(%rsp)
movq %r12, %rdi
callq 0x4222
testb %al, %al
je 0x40f4
cmpl %r13d, 0x30(%rsp)
jne 0x409f
movq (%rbx), %rax
movq %rbx, %rdi
leaq 0x21f5(%rip), %rsi      # 0x62b4
pushq $0x1
popq %rdx
callq *(%rax)
andl $0x0, 0x5c(%rsp)
movq %rbx, %rdi
leaq 0x5c(%rsp), %rsi
movl %r15d, %edx
callq 0x431a
movq 0x28(%rsp), %rdx
movl 0x34(%rsp), %ecx
leaq 0xa8(%rsp), %rdi
movq %rbx, %rsi
callq 0x4384
jmp 0x409f
movq (%rbx), %rax
movq %rbx, %rdi
leaq 0x21b3(%rip), %rsi      # 0x62b4
pushq $0x1
popq %rdx
callq *(%rax)
leaq 0xa8(%rsp), %rdi
movq %rbx, %rsi
callq 0x450c
leaq 0x180(%rsp), %rdi
movq %rbx, %rsi
callq 0x450c
jmp 0x3f97
movl 0xc(%rsp), %r15d
jmp 0x3df8
addq $0x258, %rsp            # imm = 0x258
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop