// File: /workspace/github_cpp_makefile_star2_O1/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
movl %ecx, %ebp
movl $0x2710, %eax           # imm = 0x2710
cmpl %eax, %edx
cmovbl %edx, %eax
testl %edx, %edx
movl $0x50, %r13d
cmovgl %eax, %r13d
imull %r13d, %r8d
leal 0x32(%r8), %eax
cltq
imulq $0x51eb851f, %rax, %rax # imm = 0x51EB851F
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x25, %rax
addl %ecx, %eax
addl $0x95, %r8d
cmpl $0xc7, %r8d
movl $0x1, %ecx
cmovael %eax, %ecx
movl %ecx, 0x50(%rsp)
movq %rdi, %rbx
leaq 0x8(%rsp), %rdi
movq %rsi, (%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rdi)
xorl %eax, %eax
movq %rax, 0x18(%rdi)
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movq %rcx, 0x20(%rdi)
movq %rax, 0x2c(%rdi)
movl $0x0, 0x34(%rdi)
movb $0x1, 0x38(%rdi)
callq 0x47a0
testb %al, %al
je 0x4782
imull %r13d, %ebp
addl $0x32, %ebp
movslq %ebp, %rax
imulq $0x51eb851f, %rax, %rcx # imm = 0x51EB851F
movq %rcx, %rax
shrq $0x3f, %rax
sarq $0x25, %rcx
addl %eax, %ecx
movq %rcx, 0x58(%rsp)
leaq 0x2c(%rsp), %r15
leaq 0x8(%rsp), %r14
movl %r13d, 0x4c(%rsp)
movl $0x2710, %r12d          # imm = 0x2710
xorps %xmm0, %xmm0
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x60(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x20(%rax), %rax
movq %rax, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
xorl %ebp, %ebp
movq 0x20(%rsp), %rax
testq %rax, %rax
je 0x436a
incq %rax
movzbl -0x1(%rax), %ecx
testl %ecx, %ecx
je 0x439e
cmpl $0xa, %ecx
je 0x43b9
movq %rax, 0x20(%rsp)
jmp 0x4353
movq 0x18(%rsp), %rax
movq %rax, 0x20(%rsp)
movl $0xffffffff, 0x28(%rsp) # imm = 0xFFFFFFFF
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
movl $0x0, 0x10(%r15)
movb $0x1, 0x40(%rsp)
testq %rax, %rax
jne 0x4428
jmp 0x4439
movq 0x10(%rsp), %rcx
movq 0x48(%rcx), %rax
testq %rax, %rax
je 0x4439
addq $0x28, %rcx
movq %rcx, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movl $0xffffffff, 0x28(%rsp) # imm = 0xFFFFFFFF
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
movl $0x0, 0x10(%r15)
movb $0x1, 0x40(%rsp)
jmp 0x4428
movslq 0x28(%rsp), %rax
cmpq $0x7, %rax
jg 0x4428
cmpl %eax, %ebp
cmovlel %eax, %ebp
movl 0x30(%rsp), %ecx
cmpl %r12d, %ecx
jge 0x4428
testl %eax, %eax
jg 0x441b
cmpl $0x0, 0x3c(%rsp)
jg 0x441b
movq 0x20(%rsp), %rdx
movslq 0x2c(%rsp), %rsi
movzbl (%rdx,%rsi), %edx
orl $0x2, %edx
cmpl $0xb, %edx
jne 0x4428
movl 0x60(%rsp,%rax,4), %edx
cmpl %ecx, %edx
cmovgl %edx, %ecx
movl %ecx, 0x60(%rsp,%rax,4)
movq %r14, %rdi
callq 0x4816
testb %al, %al
jne 0x43e1
jmp 0x4349
testl %ebp, %ebp
jle 0x4461
movl %ebp, %eax
xorl %edx, %edx
xorl %ecx, %ecx
xorl %esi, %esi
movl 0x60(%rsp,%rdx,4), %r12d
addl %r12d, %ecx
cmpl %r12d, %esi
cmovgl %esi, %r12d
incq %rdx
movl %r12d, %esi
cmpq %rdx, %rax
jne 0x4445
jmp 0x4466
xorl %r12d, %r12d
xorl %ecx, %ecx
cmpl %r13d, %ecx
jg 0x431e
movl $0x0, 0x80(%rsp)
movl $0x1, %eax
xorl %ecx, %ecx
addl 0x5c(%rsp,%rax,4), %ecx
movl %ecx, 0x80(%rsp,%rax,4)
incq %rax
cmpq $0x8, %rax
jne 0x4481
movslq %ebp, %rcx
movl %r13d, %eax
subl 0x80(%rsp,%rcx,4), %eax
cmpl 0x58(%rsp), %eax
jge 0x44b6
cmpl 0x60(%rsp,%rcx,4), %eax
setl %cl
cmovll 0x50(%rsp), %eax
jmp 0x44b8
xorl %ecx, %ecx
testl %ebp, %ebp
movzbl %cl, %r12d
cmovel %ebp, %r12d
subl %eax, %r13d
movl %r13d, 0x168(%rsp)
movl %eax, 0x16c(%rsp)
movabsq $0xf00000000, %rcx      # imm = 0xF00000000
movq %rcx, 0x170(%rsp)
cmpl $0x1, %eax
jg 0x44f6
movl $0x2, 0x16c(%rsp)
movl $0x0, 0x240(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0x244(%rsp)
movq %rcx, 0x248(%rsp)
cmpl $0x1, %eax
ja 0x4524
movl $0x2, 0x244(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x20(%rax), %rax
movq %rax, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
movq 0x20(%rsp), %rax
testq %rax, %rax
je 0x4561
incq %rax
movzbl -0x1(%rax), %ecx
testl %ecx, %ecx
je 0x4591
cmpl $0xa, %ecx
je 0x45ac
movq %rax, 0x20(%rsp)
jmp 0x454a
movq 0x18(%rsp), %rax
movq %rax, 0x20(%rsp)
movl $0xffffffff, 0x28(%rsp) # imm = 0xFFFFFFFF
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
movl $0x0, 0x10(%r15)
movb $0x1, 0x40(%rsp)
testq %rax, %rax
jne 0x45d2
jmp 0x476d
movq 0x10(%rsp), %rcx
movq 0x48(%rcx), %rax
testq %rax, %rax
je 0x476d
addq $0x28, %rcx
movq %rcx, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movl $0xffffffff, 0x28(%rsp) # imm = 0xFFFFFFFF
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
movl $0x0, 0x10(%r15)
movb $0x1, 0x40(%rsp)
movl $0xffffffff, 0x4(%rsp)  # imm = 0xFFFFFFFF
movq %r14, %rdi
callq 0x4816
testb %al, %al
je 0x46af
movl 0x28(%rsp), %eax
cmpl %ebp, %eax
jg 0x45da
testl %eax, %eax
jne 0x4619
cmpl $0x0, 0x4(%rsp)
js 0x4611
movq (%rbx), %rax
movq %rbx, %rdi
leaq 0x2c5a(%rip), %rsi      # 0x7264
movl $0x1, %edx
callq *(%rax)
movl $0x0, 0x4(%rsp)
movslq 0x28(%rsp), %rax
movl 0x80(%rsp,%rax,4), %edx
movq %rbx, %rdi
leaq 0x4(%rsp), %rsi
callq 0x4916
movl 0x28(%rsp), %eax
cmpl %ebp, %eax
jge 0x4679
testl %eax, %eax
jg 0x465b
cmpl $0x0, 0x3c(%rsp)
jg 0x465b
movq 0x20(%rsp), %rcx
movslq 0x2c(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
orl $0x2, %ecx
cmpl $0xb, %ecx
jne 0x4679
movq 0x20(%rsp), %rsi
movl 0x2c(%rsp), %edx
movq (%rbx), %rax
movq %rbx, %rdi
callq *(%rax)
movl 0x30(%rsp), %eax
addl %eax, 0x4(%rsp)
jmp 0x45da
testb $0x1, %r12b
jne 0x45da
testl %eax, %eax
leaq 0xa8(%rsp), %rdi
leaq 0x180(%rsp), %rax
cmoveq %rax, %rdi
movq 0x20(%rsp), %rdx
movl 0x2c(%rsp), %ecx
movq %rbx, %rsi
callq 0x4978
jmp 0x45da
testb $0x1, %r12b
je 0x4734
movq 0x18(%rsp), %rax
movq %rax, 0x20(%rsp)
movl $0xffffffff, 0x28(%rsp) # imm = 0xFFFFFFFF
xorps %xmm0, %xmm0
movups %xmm0, (%r15)
movl $0x0, 0x10(%r15)
movb $0x1, 0x40(%rsp)
movq %r14, %rdi
callq 0x4816
testb %al, %al
je 0x4734
cmpl %ebp, 0x28(%rsp)
jne 0x46db
movq (%rbx), %rax
movq %rbx, %rdi
leaq 0x2b6a(%rip), %rsi      # 0x7264
movl $0x1, %edx
callq *(%rax)
movl $0x0, 0x54(%rsp)
movq %rbx, %rdi
leaq 0x54(%rsp), %rsi
movl %r13d, %edx
callq 0x4916
movq 0x20(%rsp), %rdx
movl 0x2c(%rsp), %ecx
leaq 0xa8(%rsp), %rdi
movq %rbx, %rsi
callq 0x4978
jmp 0x46db
movq (%rbx), %rax
movq %rbx, %rdi
leaq 0x2b23(%rip), %rsi      # 0x7264
movl $0x1, %edx
callq *(%rax)
leaq 0xa8(%rsp), %rdi
movq %rbx, %rsi
callq 0x4c26
leaq 0x180(%rsp), %rdi
movq %rbx, %rsi
callq 0x4c26
jmp 0x4540
movq %r14, %rdi
callq 0x47a0
testb %al, %al
movl 0x4c(%rsp), %r13d
jne 0x4318
addq $0x258, %rsp            # imm = 0x258
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq