// File: /workspace/github_c_makefile_star2_O1/GregorR[P]lstg/source/lst_primitives.c
// Function: primitive
struct object  *primitive(int primitiveNumber, struct object *args,
                          int *failed)
{
  struct object  *returnedValue = nilObject;
  int             i,
                  j;
  FILE           *fp;
  unsigned char  *p;
  struct byteObject *stringReturn;
  char            nameBuffer[80],
                  modeBuffer[80];

  *failed = 0;
  switch (primitiveNumber)
  {
    case 100:                  /* open a file */
      lstGetString(nameBuffer, 80, args->data[0]);
      lstGetString(modeBuffer, 10, args->data[1]);
      fp = fopen(nameBuffer, modeBuffer);
      if(fp != NULL)
      {
        for(i = 0; i < LST_FILEMAX; ++i)
        {
          if(filePointers[i] == NULL)
          {
            break;
          }
        }
        if(i >= LST_FILEMAX)
        {
          sysError("too many open files", 0);
          fclose(fp);
          *failed = 1;
        }
        else
        {
          returnedValue = newInteger(i);
          filePointers[i] = fp;
        }
      }
      else
      {
        *failed = 1;
      }
      break;

    case 101:                  /* read a single character from a file */
      i = integerValue(args->data[0]);
      if((i < 0) || (i >= LST_FILEMAX) || !(fp = filePointers[i]))
      {
        *failed = 1;
        break;
      }
      i = fgetc(fp);
      if(i != EOF)
      {
        returnedValue = newInteger(i);
      }
      break;

    case 102:                  /* write a single character to a file */
      i = integerValue(args->data[0]);
      if((i < 0) || (i >= LST_FILEMAX) || !(fp = filePointers[i]))
      {
        *failed = 1;
        break;
      }
      fputc(integerValue(args->data[1]), fp);
      break;

    case 103:                  /* close file */
      i = integerValue(args->data[0]);
      if((i < 0) || (i >= LST_FILEMAX) || !(fp = filePointers[i]))
      {
        *failed = 1;
        break;
      }
      fclose(fp);
      filePointers[i] = NULL;
      break;

    case 104:                  /* file out image */
      i = integerValue(args->data[0]);
      if((i < 0) || (i >= LST_FILEMAX) || !(fp = filePointers[i]))
      {
        *failed = 1;
        break;
      }
      fileOut(fp);
      break;

    case 105:                  /* edit a string */
      {
        struct stat buf;
        /*
        first get the name of a temp file 
        */
        sprintf(nameBuffer, "%s/lsteditXXXXXX", lstTmpDir);
        mkstemp(nameBuffer);
        /*
        copy string to file.
        write the string in text mode - so even notepad can visualize it without problems.
        */
        fp = fopen(nameBuffer, "w");
        if(fp == NULL)
          sysError("cannot open temp edit file", 0);
        j = SIZE(args->data[0]);
        p = ((struct byteObject *) args->data[0])->bytes;
        for(i = 0; i < j; i++)
          fputc(*p++, fp);
        fputc('\n', fp);
        fclose(fp);
        /*
        edit string 
        */
        strcpy(modeBuffer, defaultEditor);
        strcat(modeBuffer, nameBuffer);
        system(modeBuffer);
        /*
        copy back to new string.
        read the file in binary mode - otherwise we would try to read too many bytes on Windows...
        */
        /*
          get length of file 
        */
        stat(nameBuffer, &buf);
        j = buf.st_size;
        stringReturn = (struct byteObject *)gcialloc(j);
        returnedValue = (struct object *) stringReturn;
        returnedValue->class = args->data[0]->class;

        fp = fopen(nameBuffer, "rb");
        if(fp == NULL)
          sysError("cannot open temp edit file", 0);
        /*
        reset to beginning, and read values 
        */
        for(i = 0; i < j; i++)
          stringReturn->bytes[i] = (unsigned char)fgetc(fp);
        /*
        now clean up files 
        */
        fclose(fp);
        unlink(nameBuffer);
      }
      break;

    case 106:                  /* Read into ByteArray */
      /*
         File descriptor 
       */
      i = integerValue(args->data[0]);
      if((i < 0) || (i >= LST_FILEMAX) || !(fp = filePointers[i]))
      {
        *failed = 1;
        break;
      }

      /*
         Make sure we're populating an array of bytes 
       */
      returnedValue = args->data[1];
      if((returnedValue->size & FLAG_BIN) == 0)
      {
        *failed = 1;
        break;
      }

      /*
         Sanity check on I/O count 
       */
      i = integerValue(args->data[2]);
      if((LstUInt)i > SIZE(returnedValue))
      {
        *failed = 1;
        break;
      }

      /*
         Do the I/O 
       */
      i = fread(bytePtr(returnedValue), sizeof(char), i, fp);
      if(i < 0)
      {
        *failed = 1;
        break;
      }
      returnedValue = newInteger(i);
      break;

    case 107:                  /* Write from ByteArray */
      /*
         File descriptor 
       */
      i = integerValue(args->data[0]);
      if((i < 0) || (i >= LST_FILEMAX) || !(fp = filePointers[i]))
      {
        *failed = 1;
        break;
      }

      /*
         Make sure we're writing an array of bytes 
       */
      returnedValue = args->data[1];
      if((returnedValue->size & FLAG_BIN) == 0)
      {
        *failed = 1;
        break;
      }

      /*
         Sanity check on I/O count 
       */
      i = integerValue(args->data[2]);
      if((LstUInt)i > SIZE(returnedValue))
      {
        *failed = 1;
        break;
      }

      /*
         Do the I/O 
       */
      i = fwrite(bytePtr(returnedValue), sizeof(char), i, fp);
      if(i < 0)
      {
        *failed = 1;
        break;
      }
      returnedValue = newInteger(i);
      break;

    case 108:                  /* Seek to file position */
      /*
         File descriptor 
       */
      i = integerValue(args->data[0]);
      if((i < 0) || (i >= LST_FILEMAX) || !(fp = filePointers[i]))
      {
        *failed = 1;
        break;
      }

      /*
         File position 
       */
      i = integerValue(args->data[1]);
      if((i < 0) || ((i = fseek(fp, i, SEEK_SET)) < 0))
      {
        *failed = 1;
        break;
      }

      /*
         Return position as our value 
       */
      returnedValue = newInteger(i);
      break;

    case 109:  /* Return the name of the current operating system */
        returnedValue = lstNewString(lstOsName);
      break;

    case 110: /* Sleep */
      Sleep(integerValue(args->data[0]));
      break;

    case 111: /* argc */
      returnedValue = newInteger(lstArgc);
      break;

    case 112: /* argv[i] */
      returnedValue = lstNewString(lstArgv[integerValue(args->data[0])]);
      break;

    case 113: /* next arg */
      if (lstArgi + 1 >= lstArgc)
      {
        /* We already passed all the arguments! */
        returnedValue = nilObject;
      } else {
        returnedValue = lstNewString(lstArgv[++lstArgi]);
      }
      break;

    case 114: /* System version */
      returnedValue = lstNewString(LITTLE_SMALLTALK_VERSION);
      break;

    case 115: /* Debugging? */
      returnedValue = lstDebugging ? trueObject : falseObject;
      break;

    case 116: /* read entire file */
    {
      char *buf;
      size_t sz;
      ssize_t used, rd;
      i = integerValue(args->data[0]);
      if((i < 0) || (i >= LST_FILEMAX) || !(fp = filePointers[i]))
      {
        *failed = 1;
        break;
      }
      buf = malloc(4096);
      if (!buf)
      {
        perror("malloc");
        exit(1);
      }
      sz = 4096;
      used = 0;
      while ((rd = fread(buf + used, 1, sz - used, fp)) > 0)
      {
        used += rd;
        if (used >= sz - 1)
        {
          sz *= 2;
          buf = realloc(buf, sz);
          if (!buf)
          {
            perror("realloc");
            exit(1);
          }
        }
      }
      if (used == 0)
      {
        returnedValue = nilObject;
      } else {
        buf[used] = 0;
        returnedValue = lstNewString(buf);
      }
      free(buf);
      break;
    }

#if defined(LST_USE_FFI)
      /* FFI (Foreign Function Interface) primitives */
    case 230:
    case 231:
    case 232:
    case 233:
    case 234:
    case 235:
    case 236:
    case 237:
    case 238:
    case 239:
    case 240:   /* getInt */
    case 241:   /* setInt */
        returnedValue = lstFfiPrimitive(primitiveNumber, args);
        break;
#endif

#if defined(LST_USE_SOCKET)
    case 250: /* Socket */
        returnedValue = lstSocketPrimitive(primitiveNumber, args, failed);
        break;
    case 251: /* Inet */
        returnedValue = lstInetPrimitive(primitiveNumber, args, failed);
        break;
#endif

    default:
	    sysError("unknown primitive", (void *)(INT_PTR)primitiveNumber);
  }
  return (returnedValue);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
leaq 0x4019e(%rip), %rbp     # 0x45938
movq (%rbp), %rbx
movl $0x0, (%rdx)
leal -0x64(%rdi), %eax
cmpl $0x10, %eax
ja 0x5aa3
movq %rdx, %r14
movq %rsi, %r15
leaq 0x1d33(%rip), %rcx      # 0x74f0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x10(%r15), %rdx
leaq 0x10(%rsp), %r12
movq %r12, %rdi
movl $0x50, %esi
callq 0x565e
movq 0x18(%r15), %rdx
leaq 0x60(%rsp), %r15
movq %r15, %rdi
movl $0xa, %esi
callq 0x565e
movq %r12, %rdi
movq %r15, %rsi
callq 0x22a0
testq %rax, %rax
je 0x5ce3
movq %rax, %r15
leaq 0x41390(%rip), %rcx     # 0x46ba0
xorl %eax, %eax
cmpq $0x0, (%rcx)
je 0x582a
incq %rax
addq $0x8, %rcx
cmpq $0x14, %rax
jne 0x5812
movl $0x14, %eax
cmpl $0x14, %eax
jb 0x5d0b
leaq 0x1cfa(%rip), %rdi      # 0x7534
xorl %esi, %esi
callq 0x4340
movq %r15, %rdi
callq 0x20e0
jmp 0x5ce3
movq 0x10(%r15), %rax
shrq %rax
cmpl $0x13, %eax
ja 0x5ce3
andl $0x1f, %eax
leaq 0x41338(%rip), %rcx     # 0x46ba0
movq (%rcx,%rax,8), %r15
testq %r15, %r15
je 0x5ce3
movl $0x1000, %edi           # imm = 0x1000
callq 0x2220
testq %rax, %rax
je 0x5d52
movq %rax, %r14
movl $0x1000, %ebx           # imm = 0x1000
movl $0x1, %esi
movl $0x1000, %edx           # imm = 0x1000
movq %rax, %rdi
movq %r15, %rcx
callq 0x20c0
testq %rax, %rax
movq %rax, 0x8(%rsp)
jle 0x5d22
xorl %r12d, %r12d
movq %r12, %rcx
movq %rax, %r12
addq %rcx, %r12
leaq -0x1(%rbx), %rax
cmpq %rax, %r12
jb 0x58e2
addq %rbx, %rbx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2270
movq %rax, %r14
testq %rax, %rax
je 0x5d4d
leaq (%r14,%r12), %r13
movq %rbx, %rdx
subq %r12, %rdx
movl $0x1, %esi
movq %r13, %rdi
movq %r15, %rcx
callq 0x20c0
testq %rax, %rax
jg 0x58b6
jmp 0x5d25
leaq 0x1c6e(%rip), %rdi      # 0x757b
jmp 0x5c1c
movslq 0x41327(%rip), %rax     # 0x46c40
leaq 0x1(,%rax,2), %rbx
jmp 0x5cea
movq 0x10(%r15), %rax
shrq %rax
cmpl $0x13, %eax
ja 0x5ce3
andl $0x1f, %eax
leaq 0x41260(%rip), %rcx     # 0x46ba0
movq (%rcx,%rax,8), %rdi
testq %rdi, %rdi
je 0x5ce3
callq 0x510e
jmp 0x5cea
movq 0x412ea(%rip), %rax     # 0x46c48
movq 0x10(%r15), %rcx
andq $-0x2, %rcx
movq (%rax,%rcx,4), %rdi
jmp 0x5c1c
leaq 0x1c00(%rip), %rdi      # 0x7576
jmp 0x5c1c
movq 0x10(%r15), %rax
shrq %rax
cmpl $0x13, %eax
ja 0x5ce3
andl $0x1f, %eax
leaq 0x4120b(%rip), %rcx     # 0x46ba0
movq (%rcx,%rax,8), %rsi
testq %rsi, %rsi
je 0x5ce3
movq 0x18(%r15), %rdi
shrq %rdi
callq 0x2180
jmp 0x5cea
cmpl $0x0, 0x4129a(%rip)     # 0x46c54
jne 0x5cff
leaq 0x3ff81(%rip), %rax     # 0x45948
jmp 0x5d06
movq 0x10(%r15), %r15
shrq %r15
cmpl $0x13, %r15d
ja 0x5ce3
andl $0x1f, %r15d
movl %r15d, %eax
leaq 0x411b5(%rip), %r12     # 0x46ba0
movq (%r12,%rax,8), %rdi
testq %rdi, %rdi
je 0x5ce3
callq 0x20e0
movq $0x0, (%r12,%r15,8)
jmp 0x5cea
movq 0x10(%r15), %rax
shrq %rax
cmpl $0x13, %eax
ja 0x5ce3
andl $0x1f, %eax
leaq 0x4117c(%rip), %rcx     # 0x46ba0
movq (%rcx,%rax,8), %rcx
testq %rcx, %rcx
je 0x5ce3
movq 0x18(%r15), %rbx
movl (%rbx), %edx
testb $0x2, %dl
je 0x5ce3
movq 0x20(%r15), %rax
shrq %rax
shrl $0x2, %edx
cmpl %eax, %edx
jb 0x5ce3
leaq 0x10(%rbx), %rdi
movl %eax, %edx
movl $0x1, %esi
callq 0x2340
jmp 0x5c82
movq 0x10(%r15), %rax
shrq %rax
cmpl $0x13, %eax
ja 0x5ce3
andl $0x1f, %eax
leaq 0x4111f(%rip), %rcx     # 0x46ba0
movq (%rcx,%rax,8), %rdi
testq %rdi, %rdi
je 0x5ce3
callq 0x2160
cmpl $-0x1, %eax
je 0x5cea
cltq
jmp 0x5919
movslq %edi, %rsi
leaq 0x1afd(%rip), %rdi      # 0x75aa
callq 0x4340
jmp 0x5cea
leaq 0x3bc72(%rip), %rax     # 0x41730
movq (%rax), %rdx
leaq 0x1a80(%rip), %rsi      # 0x7548
leaq 0x10(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2310
movq %rbx, %rdi
callq 0x2250
leaq 0x1a73(%rip), %rsi      # 0x7559
movq %rbx, %rdi
callq 0x22a0
movq %rax, %rbx
testq %rax, %rax
jne 0x5b04
leaq 0x1a5e(%rip), %rdi      # 0x755b
xorl %esi, %esi
callq 0x4340
movq 0x10(%r15), %r14
movl (%r14), %r12d
cmpq $0x4, %r12
jb 0x5b2e
shrl $0x2, %r12d
xorl %r13d, %r13d
movzbl 0x10(%r14,%r13), %edi
movq %rbx, %rsi
callq 0x2180
incq %r13
cmpl %r13d, %r12d
jne 0x5b18
movl $0xa, %edi
movq %rbx, %rsi
callq 0x2180
movq %rbx, %rdi
callq 0x20e0
leaq 0x60(%rsp), %rbx
movl $0x206976, (%rbx)       # imm = 0x206976
leaq 0x10(%rsp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2300
movq %rbx, %rdi
callq 0x2110
leaq 0xb8(%rsp), %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x21e0
movq 0x30(%rbx), %r14
movl %r14d, %edi
callq 0x4ddd
movq %rax, %rbx
movq 0x10(%r15), %rax
movq 0x8(%rax), %rax
movq %rax, 0x8(%rbx)
leaq 0x168e(%rip), %rsi      # 0x7229
movq %r12, %rdi
callq 0x22a0
movq %rax, %r15
testq %rax, %rax
jne 0x5bb9
leaq 0x19a9(%rip), %rdi      # 0x755b
xorl %esi, %esi
callq 0x4340
testl %r14d, %r14d
jle 0x5bdd
andl $0x7fffffff, %r14d      # imm = 0x7FFFFFFF
xorl %r12d, %r12d
movq %r15, %rdi
callq 0x2160
movb %al, 0x10(%rbx,%r12)
incq %r12
cmpq %r12, %r14
jne 0x5bc8
movq %r15, %rdi
callq 0x20e0
leaq 0x10(%rsp), %rdi
callq 0x2090
jmp 0x5cea
movslq 0x41055(%rip), %rax     # 0x46c50
leal 0x1(%rax), %ecx
cmpl 0x4103c(%rip), %ecx     # 0x46c40
jge 0x5cea
movq 0x41037(%rip), %rdx     # 0x46c48
movl %ecx, 0x41039(%rip)     # 0x46c50
movq 0x8(%rdx,%rax,8), %rdi
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x5616
movq 0x10(%r15), %rax
shrq %rax
cmpl $0x13, %eax
ja 0x5ce3
andl $0x1f, %eax
leaq 0x40f54(%rip), %rcx     # 0x46ba0
movq (%rcx,%rax,8), %rcx
testq %rcx, %rcx
je 0x5ce3
movq 0x18(%r15), %rbx
movl (%rbx), %edx
testb $0x2, %dl
je 0x5ce3
movq 0x20(%r15), %rax
shrq %rax
shrl $0x2, %edx
cmpl %eax, %edx
jb 0x5ce3
leaq 0x10(%rbx), %rdi
movl %eax, %edx
movl $0x1, %esi
callq 0x20c0
testl %eax, %eax
js 0x5ce3
addl %eax, %eax
incq %rax
movq %rax, %rbx
jmp 0x5cea
movl 0x10(%r15), %eax
shrl %eax
imull $0x3e8, %eax, %edi      # imm = 0x3E8
callq 0x2370
jmp 0x5cea
movq 0x10(%r15), %rax
shrq %rax
cmpl $0x13, %eax
ja 0x5ce3
andl $0x1f, %eax
leaq 0x40ee7(%rip), %rcx     # 0x46ba0
movq (%rcx,%rax,8), %rdi
testq %rdi, %rdi
je 0x5ce3
movq 0x18(%r15), %rsi
btq $0x20, %rsi
jb 0x5ce3
shrl %esi
xorl %edx, %edx
callq 0x2260
testl %eax, %eax
js 0x5ce3
leal 0x1(,%rax,2), %ebx
jmp 0x5cea
movl $0x1, (%r14)
movq %rbx, %rax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3fc3a(%rip), %rax     # 0x45940
movq (%rax), %rbx
jmp 0x5cea
movl %eax, %eax
leaq 0x1(,%rax,2), %rbx
leaq 0x40e84(%rip), %rcx     # 0x46ba0
movq %r15, (%rcx,%rax,8)
jmp 0x5cea
movq %r14, %r13
cmpq $0x0, 0x8(%rsp)
jle 0x5d3f
movb $0x0, (%r13)
movq %r14, %rdi
callq 0x5616
movq %rax, %rbx
jmp 0x5d43
movq (%rbp), %rbx
movq %r14, %rdi
callq 0x2060
jmp 0x5cea
callq 0x23c4
callq 0x23d9
nop