示例#1
0
/**
 * List program lines to a player
 *
 * This is used by the debugger for listing lines and for backtraces.
 * Uses the editor's list_program under the hood.
 *
 * @see list_program
 *
 * @param player the player to send the listing to
 * @param program the program to list
 * @param fr the running program frame
 * @param start the start line
 * @param end the end line
 */
void
list_proglines(dbref player, dbref program, struct frame *fr, int start,
               int end)
{
    int range[2];
    int argc;

    if (start == end || end == 0) {
        range[0] = start;
        range[1] = start;
        argc = 1;
    } else {
        range[0] = start;
        range[1] = end;
        argc = 2;
    }

    /* Make sure we have the lines of code loaded for display */
    if (!fr->brkpt.proglines || program != fr->brkpt.lastproglisted) {
        free_prog_text(fr->brkpt.proglines);
        fr->brkpt.proglines = (struct line *) read_program(program);
        fr->brkpt.lastproglisted = program;
    }

    {
        /*
         * We have to change the program position in order to do the
         * listing, so we use this tmpline so we can reset it when
         * we are done.
         */
        struct line *tmpline = PROGRAM_FIRST(program);

        PROGRAM_SET_FIRST(program, fr->brkpt.proglines);

        {
            int tmpflg = (FLAGS(player) & INTERNAL);

            FLAGS(player) |= INTERNAL;

            list_program(player, program, range, argc, 0);

            if (!tmpflg) {
                FLAGS(player) &= ~INTERNAL;
            }
        }

        PROGRAM_SET_FIRST(program, tmpline);
    }

    return;
}
示例#2
0
/*
 * Interactive debugger
 */
static void Debugger2(GLenum target, GLvoid *data)
{
   static GLuint skipCount = 0;
   const GLubyte *ln;
   GLint pos, line, column;
   GLint id;
   int progType;
   GLint len;
   GLubyte *program;
   GLboolean stop;
   int i;

   /* Sigh, GL_VERTEX_PROGRAM_ARB == GL_VERTEX_PROGRAM_NV so it's a bit
    * hard to distinguish between them.
    */
   if (target == GL_FRAGMENT_PROGRAM_ARB)
      progType = ARB_FRAGMENT_PROGRAM;
   else if (target == GL_FRAGMENT_PROGRAM_NV)
      progType = NV_FRAGMENT_PROGRAM;
   else
      progType = NV_VERTEX_PROGRAM;         

   /* Until we hit zero, continue rendering */
   if (skipCount > 0) {
      skipCount--;
      return;
   }

   /* Get id of the program and current position */
   switch (progType) {
   case ARB_FRAGMENT_PROGRAM:
      glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &id);
      glGetIntegerv(GL_FRAGMENT_PROGRAM_POSITION_MESA, &pos);
      break;
   case NV_FRAGMENT_PROGRAM:
      glGetIntegerv(GL_FRAGMENT_PROGRAM_BINDING_NV, &id);
      glGetIntegerv(GL_FRAGMENT_PROGRAM_POSITION_MESA, &pos);
      break;
   case ARB_VERTEX_PROGRAM:
      glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &id);
      glGetIntegerv(GL_VERTEX_PROGRAM_POSITION_MESA, &pos);
      break;
   case NV_VERTEX_PROGRAM:
      glGetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &id);
      glGetIntegerv(GL_VERTEX_PROGRAM_POSITION_MESA, &pos);
      break;
   default:
      abort();
   }

   /* get program string */
   if (progType == ARB_VERTEX_PROGRAM ||
       progType == ARB_FRAGMENT_PROGRAM)
      glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &len);
   else
      glGetProgramivNV(id, GL_PROGRAM_LENGTH_NV, &len);
   program = malloc(len + 1);
   if (progType == ARB_VERTEX_PROGRAM ||
       progType == ARB_FRAGMENT_PROGRAM)
      glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, program);
   else
      glGetProgramStringNV(id, GL_PROGRAM_STRING_NV, program);


   /* Get current line number, column, line string */
   ln = find_line_column(program, program + pos, &line, &column);

   /* test breakpoints */   
   if (NumBreakpoints > 0)
      stop = GL_FALSE;
   else
      stop = GL_TRUE;
   for (i = 0; i < NumBreakpoints; i++) {
      if (Breakpoints[i].enabled) {
         switch (Breakpoints[i].type) {
            case PIXEL:
               if (progType == ARB_FRAGMENT_PROGRAM) {

               }
               else if (progType == NV_FRAGMENT_PROGRAM) {
                  GLfloat pos[4];
                  int px, py;
                  glGetProgramRegisterfvMESA(GL_FRAGMENT_PROGRAM_NV,
                                             6, (GLubyte *) "f[WPOS]", pos);
                  px = (int) pos[0];
                  py = (int) pos[1];
                  printf("%d, %d\n", px, py);
                  if (px == Breakpoints[i].x &&
                      py == Breakpoints[i].y) {
                     printf("Break at pixel (%d, %d)\n", px, py);
                     stop = GL_TRUE;
                  }
               }
               break;
            case LINE:
               if (line == Breakpoints[i].line) {
                  /* hit a breakpoint! */
                  printf("Break at line %d\n", line);
                  stop = GL_TRUE;
               }
               break;
         }
      }
   }
   if (!stop) {
      free(program);
      return;
   }

   printf("%d: %s\n", line, ln);

   /* get commands from stdin */
   while (1) {
      char command[1000], *cmd;

      /* print prompt and get command */
      printf("(%s %d) ", (target == GL_VERTEX_PROGRAM_ARB ? "vert" : "frag"),
             line);
      fgets(command, 999, stdin);

      /* skip leading whitespace */
      for (cmd = command; cmd[0] == ' '; cmd++)
         ;

      if (!cmd[0])
         /* nothing (repeat the previous cmd?) */
         continue;

      switch (cmd[0]) {
         case 's':
            /* skip N instructions */
            i = atoi(cmd + 2);
            skipCount = i;
            printf("Skipping %d instructions\n", i);
            return;
         case 'n':
            /* next */
            return;
         case 'c':
            return;
         case 'd':
            /* dump machine state */
            if (progType == NV_FRAGMENT_PROGRAM) {
               static const char *inRegs[] = {
                  "f[WPOS]", "f[COL0]", "f[COL1]", "f[FOGC]",
                  "f[TEX0]", "f[TEX1]", "f[TEX2]", "f[TEX3]",
                  NULL
               };
               static const char *outRegs[] = {
                  "o[COLR]", "o[COLH]", "o[DEPR]", NULL
               };
               GLfloat v[4];
               int i;
               printf("Fragment input attributes:\n");
               for (i = 0; inRegs[i]; i++) {
                  glGetProgramRegisterfvMESA(GL_FRAGMENT_PROGRAM_NV,
                                             strlen(inRegs[i]),
                                             (const GLubyte *) inRegs[i], v);
                  printf("  %s: %g, %g, %g, %g\n", inRegs[i],
                         v[0], v[1], v[2], v[3]);
               }
               printf("Fragment output attributes:\n");
               for (i = 0; outRegs[i]; i++) {
                  glGetProgramRegisterfvMESA(GL_FRAGMENT_PROGRAM_NV,
                                             strlen(outRegs[i]),
                                             (const GLubyte *) outRegs[i], v);
                  printf("  %s: %g, %g, %g, %g\n", outRegs[i],
                         v[0], v[1], v[2], v[3]);
               }
               printf("Temporaries:\n");
               for (i = 0; i < 4; i++) {
                  char temp[100];
                  GLfloat v[4];
                  sprintf(temp, "R%d", i);
                  glGetProgramRegisterfvMESA(GL_FRAGMENT_PROGRAM_NV,
                                             strlen(temp),
                                             (const GLubyte *) temp, v);
                  printf("  %s: %g, %g, %g, %g\n", temp, v[0],v[1],v[2],v[3]);
               }
            }
            else if (progType == NV_VERTEX_PROGRAM) {
               GLfloat v[4];
               int i;
               static const char *inRegs[] = {
                  "v[OPOS]", "v[WGHT]", "v[NRML]", "v[COL0]",
                  "v[COL1]", "v[FOGC]", "v[6]", "v[7]",
                  "v[TEX0]", "v[TEX1]", "v[TEX2]", "v[TEX3]",
                  "v[TEX4]", "v[TEX5]", "v[TEX6]", "v[TEX7]",
                  NULL
               };
               static const char *outRegs[] = {
                  "o[HPOS]", "o[COL0]", "o[COL1]", "o[BFC0]",
                  "o[BFC1]", "o[FOGC]", "o[PSIZ]",
                  "o[TEX0]", "o[TEX1]", "o[TEX2]", "o[TEX3]",
                  "o[TEX4]", "o[TEX5]", "o[TEX6]", "o[TEX7]",
                  NULL
               };
               printf("Vertex input attributes:\n");
               for (i = 0; inRegs[i]; i++) {
                  glGetProgramRegisterfvMESA(GL_VERTEX_PROGRAM_NV,
                                             strlen(inRegs[i]),
                                             (const GLubyte *) inRegs[i], v);
                  printf("  %s: %g, %g, %g, %g\n", inRegs[i],
                         v[0], v[1], v[2], v[3]);
               }
               printf("Vertex output attributes:\n");
               for (i = 0; outRegs[i]; i++) {
                  glGetProgramRegisterfvMESA(GL_VERTEX_PROGRAM_NV,
                                             strlen(outRegs[i]),
                                             (const GLubyte *) outRegs[i], v);
                  printf("  %s: %g, %g, %g, %g\n", outRegs[i],
                         v[0], v[1], v[2], v[3]);
               }
               printf("Temporaries:\n");
               for (i = 0; i < 4; i++) {
                  char temp[100];
                  GLfloat v[4];
                  sprintf(temp, "R%d", i);
                  glGetProgramRegisterfvMESA(GL_VERTEX_PROGRAM_NV,
                                             strlen(temp),
                                             (const GLubyte *) temp, v);
                  printf("  %s: %g, %g, %g, %g\n", temp, v[0],v[1],v[2],v[3]);
               }
            }
            break;
         case 'l':
            /* list */
            list_program(program, len);
            break;
         case 'p':
            /* print */
            {
               GLfloat v[4];
               char *c;
               cmd++;
               while (*cmd == ' ')
                  cmd++;
               c = cmd;
               while (*c) {
                  if (*c == '\n' || *c == '\r')
                     *c = 0;
                  else
                     c++;
               }
               glGetProgramRegisterfvMESA(target, strlen(cmd),
                                          (const GLubyte *) cmd, v);
               if (glGetError() == GL_NO_ERROR)
                  printf("%s = %g, %g, %g, %g\n", cmd, v[0], v[1], v[2], v[3]);
               else
                  printf("Invalid expression\n");
            }
            break;
         case 'b':
            if (cmd[1] == ' ' && isdigit(cmd[2])) {
               char *comma = strchr(cmd, ',');
               if (comma) {
                  /* break at pixel */
                  int x = atoi(cmd + 2);
                  int y = atoi(comma + 1);
                  if (NumBreakpoints < MAX_BREAKPOINTS) {
                     Breakpoints[NumBreakpoints].type = PIXEL;
                     Breakpoints[NumBreakpoints].x = x;
                     Breakpoints[NumBreakpoints].y = y;
                     Breakpoints[NumBreakpoints].enabled = GL_TRUE;
                     NumBreakpoints++;
                     printf("Breakpoint %d: break at pixel (%d, %d)\n",
                            NumBreakpoints, x, y);
                  }
               }
               else {
                  /* break at line */
                  int l = atoi(cmd + 2);
                  if (l && NumBreakpoints < MAX_BREAKPOINTS) {
                     Breakpoints[NumBreakpoints].type = LINE;
                     Breakpoints[NumBreakpoints].line = l;
                     Breakpoints[NumBreakpoints].enabled = GL_TRUE;
                     NumBreakpoints++;
                     printf("Breakpoint %d: break at line %d\n",
                            NumBreakpoints, l);
                  }
               }
            }
            else {
               /* list breakpoints */
               printf("Breakpoints:\n");
               for (i = 0; i < NumBreakpoints; i++) {
                  switch (Breakpoints[i].type) {
                  case LINE:
                     printf("  %d: break at line %d\n",
                            i + 1, Breakpoints[i].line);
                     break;
                  case PIXEL:
                     printf("  %d: break at pixel (%d, %d)\n",
                            i + 1, Breakpoints[i].x, Breakpoints[i].y);
                     break;
                  }
               }
            }
            break;
         case 'h':
            /* help */
            printf("Debugger commands:\n");
            printf("  b      list breakpoints\n");
            printf("  b N    break at line N\n");
            printf("  b x,y  break at pixel x,y\n");
            printf("  c      continue execution\n");
            printf("  d      display register values\n");
            printf("  h      help\n");
            printf("  l      list program\n");
            printf("  n      next instruction\n");
            printf("  p V    print value V\n");
            printf("  s N    skip N instructions\n");
            break;
         default:
            printf("Unknown command: %c\n", cmd[0]);
      }
   }
}