//*****************************************************************************
//
// The "setproxy" command allows the user to change their proxy behavior
//
//*****************************************************************************
int
Cmd_setproxy(int argc, char *argv[])
{
    char pcProxyPort[10];

    //
    // Check the number of arguments.
    //
    if((argc == 2) && (ustrcmp("off",argv[1]) == 0 ))
    {
        g_bUseProxy = false;
        g_pcProxyAddress[0] = 0;
        g_ui16ProxyPort = 0;

        UARTprintf("Attempting to re-establish link with Exosite.\n\n");
        g_bOnline = LocateValidCIK();
    }
    else if(argc == 3)
    {
        //
        // Otherwise, copy the user-defined location into the global variable.
        //
        ustrncpy(g_pcProxyAddress, argv[1], 49);
        ustrncpy(pcProxyPort, argv[2], 9);

        //
        // Make sure that the global string remains terminated with a zero.
        //
        g_pcProxyAddress[49] = 0;
        pcProxyPort[9] = 0;
        g_ui16ProxyPort = ustrtoul(pcProxyPort, NULL, 0);
        g_bUseProxy = true;

        UARTprintf("New Proxy Address: %s\n", g_pcProxyAddress);
        UARTprintf("New Proxy Port: %d\n\n", g_ui16ProxyPort);

        UARTprintf("Attempting to re-establish link with Exosite.\n\n");
        g_bOnline = LocateValidCIK();

    }
    else
    {
        UARTprintf("\nProxy configuration help:\n");
        UARTprintf("    The setproxy command changes the proxy behavior of"
                   "this board.\n");
        UARTprintf("    To disable the proxy, type:\n\n");
        UARTprintf("    setproxy off\n\n");
        UARTprintf("    To enable the proxy with a specific proxy name and "
                   "port, type\n");
        UARTprintf("    setproxy <proxyaddress> <portnumber>. For "
                   "example:\n\n");
        UARTprintf("    setproxy your.proxy.address 80\n\n");
    }

    return 0;
}
Exemplo n.º 2
0
//*****************************************************************************
//
// The alert command allows the user to send an alert message to the saved
// email address.
//
//*****************************************************************************
int
Cmd_alert(int argc, char *argv[])
{
    uint32_t ui32Index;

    //
    // Check the number of arguments.
    //
    if(argc < 2) {
        //
        // If there was no second term, prompt the user to enter one next time.
        //
        UARTprintf("Please specify the alert you want to send:\n");
        for(ui32Index = 0; ui32Index < NUM_ALERTS; ui32Index++) {
            //
            // Print a list of the available alert messages.
            //
            UARTprintf("alert %d: %s\n", ui32Index,
                       g_ppcAlertMessages[ui32Index]);
        }
    } else {
        ui32Index = ustrtoul(argv[1], NULL, 0);
        ustrncpy(g_pcAlert, g_ppcAlertMessages[ui32Index], 140);
        g_sAlert.eReadWriteType = READ_WRITE;

        UARTprintf("Alert message set. Sending to the server "
                   "on the next sync operation.");
    }

    return 0;
}
Exemplo n.º 3
0
//*****************************************************************************
//
// The setemail command allows the user to set a contact email address to be
// used for alert messages.
//
//*****************************************************************************
int
Cmd_setemail(int argc, char *argv[])
{
    //
    // Check the number of arguments.
    //
    if(argc < 2) {
        //
        // If there was no second term, prompt the user to enter one next time.
        //
        UARTprintf("Not enough arguments. Please enter an email address.\n");
        UARTprintf("For example \"setemail [email protected]\"");
    } else {
        //
        // Otherwise, copy the user-defined location into the global variable.
        //
        ustrncpy(g_pcContactEmail, argv[1], 100);

        //
        // Make sure that the global string remains terminated with a zero.
        //
        g_pcContactEmail[99] = 0;

        //
        // Mark the location as READ_WRITE, so it will get uploaded to the
        // server on the next sync.
        //
        g_sContactEmail.eReadWriteType = READ_WRITE;

        UARTprintf("Email set to: %s\n\n", g_pcContactEmail);
    }

    return 0;
}
Exemplo n.º 4
0
/* This is an internal wrapper around the user thread function. Its
 * purpose is to handle all the necessary housekeeping stuff so that the
 * user function needs not to be aware of the threading calls. The user
 * function call has just "normal", non-threading semantics.
 * rgerhards, 2007-12-17
 */
static void* thrdStarter(void *arg)
{
    DEFiRet;
    thrdInfo_t *pThis = (thrdInfo_t*) arg;
#	if HAVE_PRCTL && defined PR_SET_NAME
    uchar thrdName[32] = "in:";
#	endif

    assert(pThis != NULL);
    assert(pThis->pUsrThrdMain != NULL);

    ustrncpy(thrdName+3, pThis->name, 20);
    dbgOutputTID((char*)thrdName);

#	if HAVE_PRCTL && defined PR_SET_NAME
    /* set thread name - we ignore if the call fails, has no harsh consequences... */
    if(prctl(PR_SET_NAME, thrdName, 0, 0, 0) != 0) {
        DBGPRINTF("prctl failed, not setting thread name for '%s'\n", pThis->name);
    } else {
        DBGPRINTF("set thread name to '%s'\n", thrdName);
    }
#	endif

    /* block all signals */
    sigset_t sigSet;
    sigfillset(&sigSet);
    pthread_sigmask(SIG_BLOCK, &sigSet, NULL);

    /* but ignore SIGTTN, which we (ab)use to signal the thread to shutdown -- rgerhards, 2009-07-20 */
    sigemptyset(&sigSet);
    sigaddset(&sigSet, SIGTTIN);
    pthread_sigmask(SIG_UNBLOCK, &sigSet, NULL);

    /* setup complete, we are now ready to execute the user code. We will not
     * regain control until the user code is finished, in which case we terminate
     * the thread.
     */
    iRet = pThis->pUsrThrdMain(pThis);

    dbgprintf("thrdStarter: usrThrdMain %s - 0x%lx returned with iRet %d, exiting now.\n",
              pThis->name, (unsigned long) pThis->thrdID, iRet);

    /* signal master control that we exit (we do the mutex lock mostly to
     * keep the thread debugger happer, it would not really be necessary with
     * the logic we employ...)
     */
    d_pthread_mutex_lock(&pThis->mutThrd);
    pThis->bIsActive = 0;
    pthread_cond_signal(&pThis->condThrdTerm);
    d_pthread_mutex_unlock(&pThis->mutThrd);

    ENDfunc
    pthread_exit(0);
}
Exemplo n.º 5
0
void lcd_print_dir_entry(uint16_t i) {
  char filename[16 + 1];

  if      (ep[i]->flags & E_DIR)   lcd_puts_P(PSTR("DIR "));
  else if (ep[i]->flags & E_IMAGE) lcd_puts_P(PSTR("IMG "));
  else lcd_printf("%3u ", ep[i]->filesize);
  memset (filename, 0, sizeof(filename));
  ustrncpy(filename, ep[i]->filename,
           (LCD_COLS - 4) > 16 ? 16 : LCD_COLS - 4);
  pet2asc((uint8_t *) filename);
  lcd_puts(filename);
}
Exemplo n.º 6
0
//*****************************************************************************
//
// Sets the value of a tStat structure based on a formatted string input.
//
//*****************************************************************************
void
StatSetVal(tStat *psStat, char *pcInputValue)
{
    if((psStat->eValueType) == STRING)
    {
        ustrncpy(StatStringVal(*psStat), pcInputValue, MAX_STAT_STRING);
    }
    else if((psStat->eValueType == INT) ||
            (psStat->eValueType == HEX))
    {
        StatIntVal(*psStat) = ustrtoul(pcInputValue, NULL, 0);
    }
}
Exemplo n.º 7
0
uTCHAR *js_to_name(const DBWORD val, const _js_element *list, const DBWORD length) {
	BYTE index;
	static uTCHAR str[20];

	umemset(str, 0x00, usizeof(str));

	for (index = 0; index < length; index++) {
		if (val == list[index].value) {
			ustrncpy(str, list[index].name, usizeof(str));
			return ((uTCHAR *) str);
		}
	}
	return ((uTCHAR *) list[0].name);
}
Exemplo n.º 8
0
uTCHAR *js_name_device(int dev) {
	static uTCHAR name[128];
	uTCHAR path_dev[30];
	int fd;

	umemset(name, 0x00, usizeof(name));

	usnprintf(path_dev, usizeof(path_dev), uL("" JS_DEV_PATH "%d"), dev);
	fd = uopen(path_dev, O_RDONLY | O_NONBLOCK);

	if (uioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0) {
		ustrncpy(name, uL("Not connected"), usizeof(name));
	}

	close(fd);

	return((uTCHAR *) name);
}
Exemplo n.º 9
0
/* Initialize the Signature Object */
void CSigScan::Init(unsigned char *sig, char *mask, size_t len) {
	is_set = 0;

	sig_len = len;
	sig_str = new unsigned char[sig_len];
	ustrncpy(sig_str, sig, sig_len);

	sig_mask = new char[sig_len+2]; //Original line was "sig_mask = new char[sig_len+1];", but made my module fail with "invalid access to memory" (translated error message into English) @aVoN
	strncpy(sig_mask, mask, sig_len);
	sig_mask[sig_len+1] = 0;

	if(!base_addr)
		return ; // GetDllMemInfo() Failed

	if((sig_addr = FindSignature()) == NULL)
		return ; // FindSignature() Failed

	is_set = 1;
	// SigScan Successful!
}
Exemplo n.º 10
0
/* Initialize the Signature Object */
void CSigScan::Init(unsigned char *sig, char *mask, size_t len) {
    is_set = 0;
 
    sig_len = len;
    sig_str = new unsigned char[sig_len];
    ustrncpy(sig_str, sig, sig_len);
 
    sig_mask = new char[sig_len+1];
    strncpy(sig_mask, mask, sig_len);
    sig_mask[sig_len+1] = 0;
 
    if(!base_addr)
        return ; // GetDllMemInfo() Failed
 
    if((sig_addr = FindSignature()) == NULL)
        return ; // FindSignature() Failed
 
    is_set = 1;
    // SigScan Successful!
}
Exemplo n.º 11
0
int usubstitute_env(char *line, int max_len)
{

  char *tmp_line;
  char *env_cpy;
  char *dollar_bracket;
  char *closing_bracket;
  char *pre_str;
  char *env_str;
  char *env_val;
  char *post_str;

  int pre_len, env_len, post_len, tot_len;

  tmp_line = (char *) umalloc(max_len);
  env_cpy = (char *) umalloc(max_len);

  memset(env_cpy, 0, max_len);

  /*
   * look for opening '$(' sequence
   */

  while ((dollar_bracket = ustrstr(line, "$(")) != NULL) {

    pre_str = line;
    env_str = dollar_bracket + 2;

    if ((closing_bracket = strchr(env_str, ')')) == NULL) {

      /*
       * no closing bracket
       */

      fprintf(stderr, "WARNING - uparams_read:substitute_env\n");
      fprintf(stderr, "No closing bracket for env variable\n");
      fprintf(stderr, "Reading '%s'", line);
      ufree(tmp_line);
      ufree(env_cpy);
      return (-1);

    } /* if ((closing_bracket = ... */

    post_str = closing_bracket + 1;
    
    /*
     * load up env string and null terminate
     */

    env_len = (int) (closing_bracket - env_str);
    strncpy(env_cpy, env_str, env_len );
    env_cpy[env_len] = '\0';

    /*
     * get env val
     */

    if ((env_val = getenv(env_cpy)) == NULL) {

      /*
       * no env variable set 
       */

      fprintf(stderr, "WARNING - uparams_read:substitute_env\n");
      fprintf(stderr, "Env variable '%s' not set\n", env_cpy);
      ufree(tmp_line);
      ufree(env_cpy);
      return (-1);

    }

    /*
     * compute total length after substitution
     */

    pre_len = (int) (dollar_bracket - pre_str);
    env_len = strlen(env_val);
    post_len = strlen(post_str);

    tot_len = pre_len + env_len + post_len + 1;

    if (tot_len > max_len) {

      /*
       * substituted string too long
       */

      fprintf(stderr, "WARNING - uparams_read:substitute_env\n");
      fprintf(stderr, "Env str too long.\n");
      fprintf(stderr, "Reading '%s'", line);
      
      ufree(tmp_line);
      ufree(env_cpy);
      return (-1);

    } /* if (tot_len > max_len) */

    /*
     * set tmp line and copy over
     */

    *dollar_bracket = '\0';
    sprintf(tmp_line, "%s%s%s", pre_str, env_val, post_str);
    ustrncpy(line, tmp_line, max_len);

  } /* while */

  ufree(tmp_line);
  ufree(env_cpy);
  return (0);

}
Exemplo n.º 12
0
//*****************************************************************************
//
// Send Data to the Screen starting at line index
// default to start at line 2
//
//*****************************************************************************
void
ScreenPayloadWrite(uint8_t * source, uint32_t length, uint32_t index)
{
    uint32_t x=0;

    switch(index) {
        case 1: {
            if((length-x) < SCREEN_LINELENGTH) {
                ustrncpy(g_pcPayloadLine1,(char *)source+x, length-x);
                return;
            } else {
                ustrncpy(g_pcPayloadLine1,(char *)source+x,
                         SCREEN_LINELENGTH);
            }
            x=x+SCREEN_LINELENGTH;
        }
        default:
        case 2: {
            if((length-x) < SCREEN_LINELENGTH) {
                ustrncpy(g_pcPayloadLine2,(char *)source+x, length-x);
                return;
            } else {
                ustrncpy(g_pcPayloadLine2,(char *)source+x,
                         SCREEN_LINELENGTH);
            }
            x=x+SCREEN_LINELENGTH;
        }
        case 3: {
            if((length-x) < SCREEN_LINELENGTH) {
                ustrncpy(g_pcPayloadLine3,(char *)source+x, length-x);
                return;
            } else {
                ustrncpy(g_pcPayloadLine3,(char *)source+x,
                         SCREEN_LINELENGTH);
            }
            x=x+SCREEN_LINELENGTH;
        }
        case 4: {
            if((length-x) < SCREEN_LINELENGTH) {
                ustrncpy(g_pcPayloadLine4,(char *)source+x, length-x);
                return;
            } else {
                ustrncpy(g_pcPayloadLine4,(char *)source+x,
                         SCREEN_LINELENGTH);
            }
            x=x+SCREEN_LINELENGTH;
        }
        case 5: {
            if((length-x) < SCREEN_LINELENGTH) {
                ustrncpy(g_pcPayloadLine5,(char *)source+x, length-x);
                return;
            } else {
                ustrncpy(g_pcPayloadLine5,(char *)source+x,
                         SCREEN_LINELENGTH);
            }
            x=x+SCREEN_LINELENGTH;
        }
        case 6: {
            if((length-x) < SCREEN_LINELENGTH) {
                ustrncpy(g_pcPayloadLine6,(char *)source+x, length-x);
                return;
            } else {
                ustrncpy(g_pcPayloadLine6,(char *)source+x,
                         SCREEN_LINELENGTH);
            }
            x=x+SCREEN_LINELENGTH;
        }
        case 7: {
            if((length-x) < SCREEN_LINELENGTH) {
                ustrncpy(g_pcPayloadLine7,(char *)source+x, length-x);
                return;
            } else {
                ustrncpy(g_pcPayloadLine7,(char *)source+x,
                         SCREEN_LINELENGTH);
            }
            x=x+SCREEN_LINELENGTH;
        }
        case 8: {
            if((length-x) < SCREEN_LINELENGTH) {
                ustrncpy(g_pcPayloadLine8,(char *)source+x, length-x);
                return;
            } else {
                ustrncpy(g_pcPayloadLine8,(char *)source+x,
                         SCREEN_LINELENGTH);
            }
        }
    }
    return;
}
Exemplo n.º 13
0
/**
 * file_open - open a file on given secondary
 * @secondary: secondary address used in OPEN call
 *
 * This function opens the file named in command_buffer on the given
 * secondary address. All special names and prefixes/suffixed are handled
 * here, e.g. $/#/@/,S,W
 */
void file_open(uint8_t secondary) {
  buffer_t *buf;
  uint8_t i = 0;
  uint8_t recordlen = 0;

  /* If the secondary is already in use, close the existing buffer */
  buf = find_buffer(secondary);
  if (buf != NULL) {
    /* FIXME: What should we do if an error occurs? */
    cleanup_and_free_buffer(buf);
  }

  /* Assume everything will go well unless proven otherwise */
  set_error(ERROR_OK);

  /* Strip 0x0d characters from end of name (C2BD-C2CA) */
  if (command_length > 1) {
    if (command_buffer[command_length-1] == 0x0d)
      command_length -= 1;
    else if (command_buffer[command_length-2] == 0x0d)
      command_length -= 2;
  }

  /* Clear the remainder of the command buffer, simplifies parsing */
  memset(command_buffer+command_length, 0, sizeof(command_buffer)-command_length);

  uart_trace(command_buffer,0,command_length);

  /* Direct access? */
  if (command_buffer[0] == '#') {
    open_buffer(secondary);
    return;
  }

  /* Parse type+mode suffixes */
  uint8_t *ptr = command_buffer;
  enum open_modes mode = OPEN_READ;
  uint8_t filetype = TYPE_DEL;

  while(i++ < 2 && *ptr && (ptr = ustrchr(ptr, ','))) {
    *ptr = 0;
    ptr++;
    switch (*ptr) {
    case 0:
      break;

    case 'R': /* Read */
      mode = OPEN_READ;
      break;

    case 'W': /* Write */
      mode = OPEN_WRITE;
      break;

    case 'A': /* Append */
      mode = OPEN_APPEND;
      break;

    case 'M': /* Modify */
      mode = OPEN_MODIFY;
      break;

    case 'D': /* DEL */
      filetype = TYPE_DEL;
      break;

    case 'S': /* SEQ */
      filetype = TYPE_SEQ;
      break;

    case 'P': /* PRG */
      filetype = TYPE_PRG;
      break;

    case 'U': /* USR */
      filetype = TYPE_USR;
      break;

    case 'L': /* REL */
      filetype = TYPE_REL;
      mode = OPEN_WRITE;
      if((ptr = ustrchr(ptr, ',')))
        recordlen = *(++ptr);
      i = 2;  // stop the scan
      break;
    }
  }

  /* Load directory? */
  if (command_buffer[0] == '$') {
    load_directory(secondary);
    return;
  }

  /* Parse path+partition numbers */
  uint8_t *fname;
  int8_t res;
  cbmdirent_t dent;
  path_t path;

  /* Parse path and file name */
  if (parse_path(command_buffer, &path, &fname, 0))
      return;

#ifdef CONFIG_M2I
  /* For M2I only: Remove trailing spaces from name */
  if (partition[path.part].fop == &m2iops) {
    res = ustrlen(fname);
    while (--res && fname[res] == ' ')
      fname[res] = 0;
  }
#endif

  /* Filename matching */
  if (opendir(&matchdh, &path))
    return;

  do {
    res = next_match(&matchdh, fname, NULL, NULL, FLAG_HIDDEN, &dent);
    if (res > 0)
      /* Error, abort */
      return;

    /* Don't match on DEL or DIR */
    if ((dent.typeflags & TYPE_MASK) != TYPE_DEL &&
        (dent.typeflags & TYPE_MASK) != TYPE_DIR)
      break;

    /* But do match if it's for writing */
    if (mode == OPEN_WRITE || secondary == 1)
      break;
  } while (res == 0);

  if(res && filetype == TYPE_REL && !recordlen) {
    set_error(ERROR_SYNTAX_UNABLE);
    return;
  }

  /* If match found is a REL... */
  if(!res && (dent.typeflags & TYPE_MASK) == TYPE_REL) {
    /* requested type must be REL or DEL */
    if(filetype != TYPE_REL && filetype != TYPE_DEL) {
      set_error(ERROR_FILE_TYPE_MISMATCH);
      return;
    }
    filetype = TYPE_REL;
    mode = OPEN_MODIFY;
  }

  /* Force mode+type for secondaries 0/1 */
  switch (secondary) {
  case 0:
    mode = OPEN_READ;
    if (filetype == TYPE_DEL)
      filetype = TYPE_PRG;
    break;

  case 1:
    mode = OPEN_WRITE;
    if (filetype == TYPE_DEL)
      filetype = TYPE_PRG;
    break;

  default:
    if (filetype == TYPE_DEL)
      filetype = TYPE_SEQ;
  }

  if (mode == OPEN_WRITE) {
    if (res == 0) {
      /* Match found */
      if (command_buffer[0] == '@') {
        /* Make sure there is a free buffer to open the new file later */
        if (!check_free_buffers()) {
          set_error(ERROR_NO_CHANNEL);
          return;
        }

        /* Copy dent because file_delete may change it */
        cbmdirent_t dentcopy = dent;

        /* Rewrite existing file: Delete the old one */
        if (file_delete(&path, &dentcopy) == 255)
          return;

        /* Force fatops to create a new name based on the (long) CBM- */
        /* name instead of creating one with the old SFN and no LFN.  */
        if (dent.opstype == OPSTYPE_FAT || dent.opstype == OPSTYPE_FAT_X00)
          dent.pvt.fat.realname[0] = 0;
      } else {
        /* Write existing file without replacement: Raise error */
        set_error(ERROR_FILE_EXISTS);
        return;
      }
    } else {
      /* Normal write or non-existing rewrite */
      /* Doesn't exist: Copy name to dent */
      memset(&dent, 0, sizeof(dent));
      ustrncpy(dent.name, fname, CBM_NAME_LENGTH);
      set_error(ERROR_OK); // because first_match has set FNF
    }
  } else if (res != 0) {
    /* File not found */
    set_error(ERROR_FILE_NOT_FOUND);
    return;
  }

  /* Grab a buffer */
  buf = alloc_buffer();
  if (!buf)
    return;

  buf->secondary = secondary;

  if(filetype == TYPE_REL) {
    display_filename_write(path.part,CBM_NAME_LENGTH,dent.name);
    open_rel(&path, &dent, buf, recordlen, (mode == OPEN_MODIFY));
    return;
  }

  switch (mode) {
  case OPEN_MODIFY:
  case OPEN_READ:
    /* Modify is the same as read, but allows reading *ed files.        */
    /* FAT doesn't have anything equivalent, so both are mapped to READ */
    display_filename_read(path.part,CBM_NAME_LENGTH,dent.name);
    open_read(&path, &dent, buf);
    break;

  case OPEN_WRITE:
  case OPEN_APPEND:
    display_filename_write(path.part,CBM_NAME_LENGTH,dent.name);
    open_write(&path, &dent, filetype, buf, (mode == OPEN_APPEND));
    break;
  }
}
Exemplo n.º 14
0
//*****************************************************************************
//
// Given a pointer to a tStat and a destination string, this function will
// print the value of the tStat to the string.
//
//*****************************************************************************
void
StatPrintValue(tStat *psStat, char *pcValueString)
{
    char *pcSourceString;
    char pcPercentString[3];
    uint32_t ui32CharValue;
    uint8_t ui8Index;
    //
    // Check the type of data that is stored in this psStat variable.
    //
    if((psStat->eValueType) == STRING)
    {
        //
        // If this is a string, perform a little processing to remove
        // percent-encoded characters. First, copy the original string pointer
        // for ease of use.
        //
        pcSourceString = StatStringVal(*psStat);


        //
        // Loop through the characters in the string one by one.
        //
        ui8Index = 0;
        while(*pcSourceString != 0)
        {
            //
            // If the character is a percent sign, calculate the correct
            // percent-encoding substitution.
            //
            if(*pcSourceString == '%')
            {
                //
                // The next two characters should be a hexadecimal
                // representation of the actual character that should be
                // printed. Convert them to an integer here.
                //
                ustrncpy(pcPercentString, (pcSourceString + 1), 2);

                pcPercentString[2] = 0;

                ui32CharValue = ustrtoul((pcPercentString), NULL, 16);

                //
                // Increment the source pointer past the escaped characters.
                //
                pcSourceString = pcSourceString + 3;

                //
                // Copy the converted value into the destination string.
                //
                pcValueString[ui8Index] = ui32CharValue;

            }
            else
            {
                //
                // If the character was not a percent sign, it can be copied
                // directly.
                //
                pcValueString[ui8Index] = *pcSourceString;
                pcSourceString++;
            }

            //
            // Increment the index.
            //
            ui8Index++;
        }
        
        pcValueString[ui8Index] = 0;
    }
    else if((psStat->eValueType) == INT)
    {
        //
        // If this is an integer value, just print the value as text into the
        // destination string.
        //
        usprintf(pcValueString, "%d", StatIntVal(*psStat));
    }
}
Exemplo n.º 15
0
//*****************************************************************************
//
// Print a string to the screen and save it to the screen buffer.
//
//*****************************************************************************
void
WriteString(const char *pcString)
{
    uint32_t ui32Size, ui32StrSize;
    char *pcCurLine;
    int32_t i32Idx;

    ui32StrSize = ustrlen(pcString);

    //
    // Check if the string requires scrolling the text in order to print.
    //
    if((g_ui32Line >= MAX_LINES) && (g_ui32Column == 0))
    {
        //
        // Start redrawing at line 0.
        //
        g_ui32Line = 0;

        //
        // Print lines from the current position down first.
        //
        for(i32Idx = g_ui32CurrentLine + 1; i32Idx < MAX_LINES; i32Idx++)
        {
            GrStringDraw(&g_sContext, g_pcLines + (MAX_COLUMNS * i32Idx),
                         ustrlen(g_pcLines + (MAX_COLUMNS * i32Idx)),
                         DISPLAY_TEXT_BORDER_H,
                         DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER +
                         (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1);

            g_ui32Line++;
        }

        //
        // If not already at the top then print the lines starting at the
        // top of the buffer.
        //
        if(g_ui32CurrentLine != 0)
        {
            for(i32Idx = 0; i32Idx < g_ui32CurrentLine; i32Idx++)
            {
                GrStringDraw(&g_sContext, g_pcLines + (MAX_COLUMNS * i32Idx),
                             ustrlen(g_pcLines + (MAX_COLUMNS * i32Idx)),
                             DISPLAY_TEXT_BORDER_H,
                             DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER +
                             (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)),
                             1);

                g_ui32Line++;
            }
        }
    }

    //
    // Save the current line pointer to use in references below.
    //
    pcCurLine = g_pcLines + (MAX_COLUMNS * g_ui32CurrentLine);

    if(g_ui32Column + ui32StrSize >= MAX_COLUMNS - 1)
    {
        ui32Size = MAX_COLUMNS - g_ui32Column - 1;
    }
    else
    {
        ui32Size = ui32StrSize;
    }

    //
    // Handle the case where the string has a new line at the end.
    //
    if(pcString[ui32StrSize-1] == '\n')
    {
        //
        // Make sure that this is not a single new line.
        //
        if(ui32Size > 0 )
        {
            //
            // Copy the string into the screen buffer.
            //
            ustrncpy(pcCurLine + g_ui32Column, pcString, ui32Size - 1);
        }

        //
        // If this is the start of a new line then clear out the rest of the
        // line by writing spaces to the end of the line.
        //
        if(g_ui32Column == 0)
        {
            //
            // Clear out the string with spaces to overwrite any existing
            // characters with spaces.
            //
            for(i32Idx = ui32Size - 1; i32Idx < MAX_COLUMNS; i32Idx++)
            {
                pcCurLine[i32Idx] = ' ';
            }
        }

        //
        // Null terminate the string.
        //
        pcCurLine[g_ui32Column + MAX_COLUMNS - 1] = 0;

        //
        // Draw the new string.
        //
        GrStringDraw(&g_sContext, pcCurLine + g_ui32Column, ui32Size - 1,
                     DISPLAY_TEXT_BORDER_H +
                     (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column),
                     DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER +
                     (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1);

        //
        // Increment the line values and reset the column to 0.
        //
        g_ui32Line++;
        g_ui32CurrentLine++;

        if(g_ui32CurrentLine >= MAX_LINES)
        {
            g_ui32CurrentLine = 0;
        }
        g_ui32Column = 0;
    }
    else
    {
        //
        // Copy the string into the screen buffer.
        //
        ustrncpy(pcCurLine + g_ui32Column, pcString, ui32Size);

        //
        // See if this was the first string draw on this line.
        //
        if(g_ui32Column == 0)
        {
            //
            // Pad the rest of the string with spaces to overwrite any existing
            // characters with spaces.
            //
            for(i32Idx = ui32Size; i32Idx < MAX_COLUMNS - 1; i32Idx++)
            {
                pcCurLine[i32Idx] = ' ';
            }

            //
            // Draw the new string.
            //
            GrStringDraw(&g_sContext,
                         pcCurLine + g_ui32Column, MAX_COLUMNS - 1,
                         DISPLAY_TEXT_BORDER_H +
                         (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column),
                         DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER +
                         (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1);
        }
        else
        {
            //
            // Draw the new string.
            //
            GrStringDraw(&g_sContext, pcCurLine + g_ui32Column,
                         g_ui32Column + ui32Size,
                         DISPLAY_TEXT_BORDER_H +
                         (GrFontMaxWidthGet(g_psFontFixed6x8) * g_ui32Column),
                         DISPLAY_BANNER_HEIGHT + DISPLAY_TEXT_BORDER +
                         (g_ui32Line * GrFontHeightGet(g_psFontFixed6x8)), 1);
        }

        //
        // Update the current column.
        //
        g_ui32Column += ui32Size;
    }
}
Exemplo n.º 16
0
void cmd_line_parse(int argc, uTCHAR **argv) {
	QStringList splitted;
	QString arg, key, skey, value, exe = QFileInfo(uQString(argv[0])).baseName();
	int opt = 0;

	for (int a = 1; a < argc; a++) {
		arg = uQString(argv[a]);
		splitted = arg.split("=");
		key = QString(splitted.at(0));

		if (key.startsWith("--") || key.startsWith("-")) {
			key = key.replace("-", "");

			for (unsigned int b = 0; b < LENGTH(opt_long); b++) {
				if ((opt_long[b].lopt == key) || (opt_long[b].sopt == key)) {
					skey = opt_long[b].sopt;
					if (opt_long[b].ra == req_arg) {
						if (splitted.count() > 1) {
							value = QString(splitted.at(1));
						} else {
							if ((a + 1) >= argc) {
								QMessageBox::warning(0,
									"Error",
									QString("%1: the option needs an arguments -- \"%2\"").arg(exe, key));
								usage(exe);
							} else {
								value = uQString(argv[++a]);
							}
						}
					}
					opt = (*((char *) skey.toLatin1().constData()));
				}
			}
		} else {
			umemset(info.rom_file, 0x00, usizeof(info.rom_file));
			ustrncpy(info.rom_file, uQStringCD(key), usizeof(info.rom_file) - 1);
			continue;
		}

		switch (opt) {
			case 0:
				// long options
				if (key == "swap-duty") {
					set_int(cfg_from_file.swap_duty, SET_SWAP_DUTY);
				} else if (key == "swap-emphasis") {
					set_int(cfg_from_file.disable_swap_emphasis_pal, SET_SWAP_EMPHASIS_PAL);
				} else if (key == "portable") {
					// l'ho gia' controllato quindi qui non faccio niente
				} else if (key == "txt-on-screen") {
					set_int(cfg_from_file.txt_on_screen, SET_TEXT_ON_SCREEN);
				} else if (key == "input-display") {
					set_int(cfg_from_file.input_display, SET_INPUT_DISPLAY);
				} else if (key == "disable-tv-noise") {
					set_int(cfg_from_file.disable_tv_noise, SET_DISABLE_TV_NOISE);
				} else if (key == "disable-sepia") {
					set_int(cfg_from_file.disable_sepia_color, SET_DISABLE_SEPIA_PAUSE);
#if defined (WITH_OPENGL)
				} else if (key == "disable-srgb-fbo") {
					set_int(cfg_from_file.disable_srgb_fbo, SET_DISABLE_SRGB_FBO);
#endif
				} else if (key == "overscan-brd-ntsc") {
					set_oscan(SET_OVERSCAN_BRD_NTSC, 0);
				} else if (key == "overscan-brd-pal") {
					set_oscan(SET_OVERSCAN_BRD_PAL, 1);
				} else if (key == "par-soft-stretch") {
					set_int(cfg_from_file.PAR_soft_stretch, SET_PAR_SOFT_STRETCH);
				} else if (key == "hide-sprites") {
					set_int(cfg_from_file.hide_sprites, SET_HIDE_SPRITES);
				} else if (key == "hide-background") {
					set_int(cfg_from_file.hide_background, SET_HIDE_BACKGROUND);
				} else if (key == "unlimited-sprites") {
					set_int(cfg_from_file.unlimited_sprites, SET_UNLIMITED_SPRITES);
				} else if (key == "save-battery-ram-file") {
					set_int(cfg_from_file.save_battery_ram_file, SET_BATTERY_RAM_FILE_EVEY_TOT);
				} else if (key == "background-pause") {
					set_int(cfg_from_file.bck_pause, SET_BCK_PAUSE);
				} else if (key == "language") {
					set_int(cfg_from_file.language, SET_GUI_LANGUAGE);
				} else if (key == "disable-new-menu") {
					set_int(cfg_from_file.disable_new_menu, SET_GUI_DISABLE_NEW_MENU);
				}
				break;
			case 'a':
				set_int(cfg_from_file.apu.channel[APU_MASTER], SET_AUDIO);
				break;
			case 'b':
				set_int(cfg_from_file.audio_buffer_factor, SET_AUDIO_BUFFER_FACTOR);
				break;
			case 'c':
				set_int(cfg_from_file.channels_mode, SET_CHANNELS);
				break;
			case 'd':
				cfg_from_file.stereo_delay = set_double(5);
				break;
			case 'f':
				set_int(cfg_from_file.fps, SET_FPS);
				break;
			case 'g':
				set_int(cfg_from_file.cheat_mode, SET_CHEAT_MODE);
				break;
			case 'h':
			case '?':
				usage(exe);
				break;
			case 'V': {
				if (!info.portable) {
					fprintf(stdout, "%s %s\n", NAME, VERSION);
				} else {
					fprintf(stdout, "Portable %s %s\n", NAME, VERSION);
				}
				emu_quit(EXIT_SUCCESS);
				break;
			}
			case 'k':
				set_int(cfg_from_file.frameskip, SET_FRAMESKIP);
				break;
			case 'i':
				set_int(cfg_from_file.filter, SET_FILTER);
				break;
			case 'l':
				set_int(cfg_from_file.samplerate, SET_SAMPLERATE);
				break;
			case 'm':
				set_int(cfg_from_file.mode, SET_MODE);
				break;
			case 'n':
				set_int(cfg_from_file.ntsc_format, SET_NTSC_FORMAT);
				break;
			case 'o':
				set_int(cfg_from_file.oscan, SET_OVERSCAN_DEFAULT);
				break;
			case 'p':
				set_int(cfg_from_file.palette, SET_PALETTE);
				break;
			case 'q':
				set_int(cfg_from_file.audio_quality, SET_AUDIO_QUALITY);
				break;
#if defined (WITH_OPENGL)
			case 'r':
				set_int(cfg_from_file.render, SET_RENDERING);
				gfx_set_render(cfg_from_file.render);
				break;
#endif
			case 's':
				set_int(cfg_from_file.scale, SET_SCALE);
				gfx.scale_before_fscreen = cfg_from_file.scale;
				break;
			case 't':
				{
					int rc = settings_val_to_int(SET_STRETCH_FULLSCREEN, oarg);

					if (rc >= 0) {
						cfg_from_file.scale = !rc;
					}
				}
				break;
			case 'u':
				set_int(cfg_from_file.fullscreen, SET_FULLSCREEN);
				break;
			case 'v':
				set_int(cfg_from_file.vsync, SET_VSYNC);
				break;
			case 'e':
				set_int(cfg_from_file.pixel_aspect_ratio, SET_PAR);
				break;
			case 'j':
				set_int(cfg_from_file.interpolation, SET_INTERPOLATION);
				break;
			default:
				break;
		}
	}
}
Exemplo n.º 17
0
static rsRetVal
dynstats_addBucketMetrics(dynstats_buckets_t *bkts, dynstats_bucket_t *b, const uchar* name) {
	uchar *metric_name_buff, *metric_suffix;
	const uchar *suffix_litteral;
	int name_len;
	DEFiRet;

	name_len = ustrlen(name);
	CHKmalloc(metric_name_buff = malloc((name_len + DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH + 1) * sizeof(uchar)));

	ustrncpy(metric_name_buff, name, name_len);
	metric_suffix = metric_name_buff + name_len;
	*metric_suffix = DYNSTATS_METRIC_NAME_SEPARATOR;
	metric_suffix++;

	suffix_litteral = UCHAR_CONSTANT("ops_overflow");
	ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH);
	STATSCOUNTER_INIT(b->ctrOpsOverflow, b->mutCtrOpsOverflow);
	CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr,
									   CTR_FLAG_RESETTABLE,
										&(b->ctrOpsOverflow),
										&b->pOpsOverflowCtr, 1));

	suffix_litteral = UCHAR_CONSTANT("new_metric_add");
	ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH);
	STATSCOUNTER_INIT(b->ctrNewMetricAdd, b->mutCtrNewMetricAdd);
	CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr,
									   CTR_FLAG_RESETTABLE,
										&(b->ctrNewMetricAdd),
										&b->pNewMetricAddCtr, 1));

	suffix_litteral = UCHAR_CONSTANT("no_metric");
	ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH);
	STATSCOUNTER_INIT(b->ctrNoMetric, b->mutCtrNoMetric);
	CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr,
									   CTR_FLAG_RESETTABLE,
										&(b->ctrNoMetric),
										&b->pNoMetricCtr, 1));

	suffix_litteral = UCHAR_CONSTANT("metrics_purged");
	ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH);
	STATSCOUNTER_INIT(b->ctrMetricsPurged, b->mutCtrMetricsPurged);
	CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr,
									   CTR_FLAG_RESETTABLE,
										&(b->ctrMetricsPurged),
										&b->pMetricsPurgedCtr, 1));

	suffix_litteral = UCHAR_CONSTANT("ops_ignored");
	ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH);
	STATSCOUNTER_INIT(b->ctrOpsIgnored, b->mutCtrOpsIgnored);
	CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr,
									   CTR_FLAG_RESETTABLE,
										&(b->ctrOpsIgnored),
										&b->pOpsIgnoredCtr, 1));

	suffix_litteral = UCHAR_CONSTANT("purge_triggered");
	ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH);
	STATSCOUNTER_INIT(b->ctrPurgeTriggered, b->mutCtrPurgeTriggered);
	CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr,
									   CTR_FLAG_RESETTABLE,
										&(b->ctrPurgeTriggered),
										&b->pPurgeTriggeredCtr, 1));

finalize_it:
	free(metric_name_buff);
	if (iRet != RS_RET_OK) {
		if (b->pOpsOverflowCtr != NULL) {
			statsobj.DestructCounter(bkts->global_stats, b->pOpsOverflowCtr);
		}
		if (b->pNewMetricAddCtr != NULL) {
			statsobj.DestructCounter(bkts->global_stats, b->pNewMetricAddCtr);
		}
		if (b->pNoMetricCtr != NULL) {
			statsobj.DestructCounter(bkts->global_stats, b->pNoMetricCtr);
		}
		if (b->pMetricsPurgedCtr != NULL) {
			statsobj.DestructCounter(bkts->global_stats, b->pMetricsPurgedCtr);
		}
		if (b->pOpsIgnoredCtr != NULL) {
			statsobj.DestructCounter(bkts->global_stats, b->pOpsIgnoredCtr);
		}
		if (b->pPurgeTriggeredCtr != NULL) {
			statsobj.DestructCounter(bkts->global_stats, b->pPurgeTriggeredCtr);
		}
	}
	RETiRet;
}
Exemplo n.º 18
0
//*****************************************************************************
//
//! A simple vsnprintf function supporting \%c, \%d, \%p, \%s, \%u, \%x, and
//! \%X.
//!
//! \param pcBuf points to the buffer where the converted string is stored.
//! \param ulSize is the size of the buffer.
//! \param pcString is the format string.
//! \param vaArgP is the list of optional arguments, which depend on the
//! contents of the format string.
//!
//! This function is very similar to the C library <tt>vsnprintf()</tt>
//! function.  Only the following formatting characters are supported:
//!
//! - \%c to print a character
//! - \%d or \%i to print a decimal value
//! - \%s to print a string
//! - \%u to print an unsigned decimal value
//! - \%x to print a hexadecimal value using lower case letters
//! - \%X to print a hexadecimal value using lower case letters (not upper case
//! letters as would typically be used)
//! - \%p to print a pointer as a hexadecimal value
//! - \%\% to print out a \% character
//!
//! For \%d, \%i, \%p, \%s, \%u, \%x, and \%X, an optional number may reside
//! between the \% and the format character, which specifies the minimum number
//! of characters to use for that value; if preceded by a 0 then the extra
//! characters will be filled with zeros instead of spaces.  For example,
//! ``\%8d'' will use eight characters to print the decimal value with spaces
//! added to reach eight; ``\%08d'' will use eight characters as well but will
//! add zeroes instead of spaces.
//!
//! The type of the arguments after \e pcString must match the requirements of
//! the format string.  For example, if an integer was passed where a string
//! was expected, an error of some kind will most likely occur.
//!
//! The \e ulSize parameter limits the number of characters that will be stored
//! in the buffer pointed to by \e pcBuf to prevent the possibility of a buffer
//! overflow.  The buffer size should be large enough to hold the expected
//! converted output string, including the null termination character.
//!
//! The function will return the number of characters that would be converted
//! as if there were no limit on the buffer size.  Therefore it is possible for
//! the function to return a count that is greater than the specified buffer
//! size.  If this happens, it means that the output was truncated.
//!
//! \return Returns the number of characters that were to be stored, not
//! including the NULL termination character, regardless of space in the
//! buffer.
//
//*****************************************************************************
int
uvsnprintf(char *pcBuf, unsigned long ulSize, const char *pcString,
           va_list vaArgP)
{
    unsigned long ulIdx, ulValue, ulCount, ulBase, ulNeg;
    char *pcStr, cFill;
    int iConvertCount = 0;

    //
    // Check the arguments.
    //
    ASSERT(pcString != 0);
    ASSERT(pcBuf != 0);
    ASSERT(ulSize != 0);

    //
    // Adjust buffer size limit to allow one space for null termination.
    //
    if(ulSize)
    {
        ulSize--;
    }

    //
    // Initialize the count of characters converted.
    //
    iConvertCount = 0;

    //
    // Loop while there are more characters in the format string.
    //
    while(*pcString)
    {
        //
        // Find the first non-% character, or the end of the string.
        //
        for(ulIdx = 0; (pcString[ulIdx] != '%') && (pcString[ulIdx] != '\0');
            ulIdx++)
        {
        }

        //
        // Write this portion of the string to the output buffer.  If there are
        // more characters to write than there is space in the buffer, then
        // only write as much as will fit in the buffer.
        //
        if(ulIdx > ulSize)
        {
            ustrncpy(pcBuf, pcString, ulSize);
            pcBuf += ulSize;
            ulSize = 0;
        }
        else
        {
            ustrncpy(pcBuf, pcString, ulIdx);
            pcBuf += ulIdx;
            ulSize -= ulIdx;
        }

        //
        // Update the conversion count.  This will be the number of characters
        // that should have been written, even if there was not room in the
        // buffer.
        //
        iConvertCount += ulIdx;

        //
        // Skip the portion of the format string that was written.
        //
        pcString += ulIdx;

        //
        // See if the next character is a %.
        //
        if(*pcString == '%')
        {
            //
            // Skip the %.
            //
            pcString++;

            //
            // Set the digit count to zero, and the fill character to space
            // (that is, to the defaults).
            //
            ulCount = 0;
            cFill = ' ';

            //
            // It may be necessary to get back here to process more characters.
            // Goto's aren't pretty, but effective.  I feel extremely dirty for
            // using not one but two of the beasts.
            //
again:

            //
            // Determine how to handle the next character.
            //
            switch(*pcString++)
            {
                //
                // Handle the digit characters.
                //
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                {
                    //
                    // If this is a zero, and it is the first digit, then the
                    // fill character is a zero instead of a space.
                    //
                    if((pcString[-1] == '0') && (ulCount == 0))
                    {
                        cFill = '0';
                    }

                    //
                    // Update the digit count.
                    //
                    ulCount *= 10;
                    ulCount += pcString[-1] - '0';

                    //
                    // Get the next character.
                    //
                    goto again;
                }

                //
                // Handle the %c command.
                //
                case 'c':
                {
                    //
                    // Get the value from the varargs.
                    //
                    ulValue = va_arg(vaArgP, unsigned long);

                    //
                    // Copy the character to the output buffer, if there is
                    // room.  Update the buffer size remaining.
                    //
                    if(ulSize != 0)
                    {
                        *pcBuf++ = (char)ulValue;
                        ulSize--;
                    }

                    //
                    // Update the conversion count.
                    //
                    iConvertCount++;

                    //
                    // This command has been handled.
                    //
                    break;
                }

                //
                // Handle the %d and %i commands.
                //
                case 'd':
                case 'i':
                {
                    //
                    // Get the value from the varargs.
                    //
                    ulValue = va_arg(vaArgP, unsigned long);

                    //
                    // If the value is negative, make it positive and indicate
                    // that a minus sign is needed.
                    //
                    if((long)ulValue < 0)
                    {
                        //
                        // Make the value positive.
                        //
                        ulValue = -(long)ulValue;

                        //
                        // Indicate that the value is negative.
                        //
                        ulNeg = 1;
                    }
                    else
                    {
                        //
                        // Indicate that the value is positive so that a
                        // negative sign isn't inserted.
                        //
                        ulNeg = 0;
                    }

                    //
                    // Set the base to 10.
                    //
                    ulBase = 10;

                    //
                    // Convert the value to ASCII.
                    //
                    goto convert;
                }

                //
                // Handle the %s command.
                //
                case 's':
                {
                    //
                    // Get the string pointer from the varargs.
                    //
                    pcStr = va_arg(vaArgP, char *);

                    //
                    // Determine the length of the string.
                    //
                    for(ulIdx = 0; pcStr[ulIdx] != '\0'; ulIdx++)
                    {
                    }

                    //
                    // Update the convert count to include any padding that
                    // should be necessary (regardless of whether we have space
                    // to write it or not).
                    //
                    if(ulCount > ulIdx)
                    {
                        iConvertCount += (ulCount - ulIdx);
                    }

                    //
                    // Copy the string to the output buffer.  Only copy as much
                    // as will fit in the buffer.  Update the output buffer
                    // pointer and the space remaining.
                    //
                    if(ulIdx > ulSize)
                    {
                        ustrncpy(pcBuf, pcStr, ulSize);
                        pcBuf += ulSize;
                        ulSize = 0;
                    }
                    else
                    {
                        ustrncpy(pcBuf, pcStr, ulIdx);
                        pcBuf += ulIdx;
                        ulSize -= ulIdx;

                        //
                        // Write any required padding spaces assuming there is
                        // still space in the buffer.
                        //
                        if(ulCount > ulIdx)
                        {
                            ulCount -= ulIdx;
                            if(ulCount > ulSize)
                            {
                                ulCount = ulSize;
                            }
                            ulSize =- ulCount;

                            while(ulCount--)
                            {
                                *pcBuf++ = ' ';
                            }
                        }
                    }

                    //
                    // Update the conversion count.  This will be the number of
                    // characters that should have been written, even if there
                    // was not room in the buffer.
                    //
                    iConvertCount += ulIdx;

                    //
                    // This command has been handled.
                    //
                    break;
                }

                //
                // Handle the %u command.
                //
                case 'u':
                {
                    //
                    // Get the value from the varargs.
                    //
                    ulValue = va_arg(vaArgP, unsigned long);

                    //
                    // Set the base to 10.
                    //
                    ulBase = 10;

                    //
                    // Indicate that the value is positive so that a minus sign
                    // isn't inserted.
                    //
                    ulNeg = 0;

                    //
                    // Convert the value to ASCII.
                    //
                    goto convert;
                }

                //
                // Handle the %x and %X commands.  Note that they are treated
                // identically; that is, %X will use lower case letters for a-f
                // instead of the upper case letters is should use.  We also
                // alias %p to %x.
                //
                case 'x':
                case 'X':
                case 'p':
                {
                    //
                    // Get the value from the varargs.
                    //
                    ulValue = va_arg(vaArgP, unsigned long);

                    //
                    // Set the base to 16.
                    //
                    ulBase = 16;

                    //
                    // Indicate that the value is positive so that a minus sign
                    // isn't inserted.
                    //
                    ulNeg = 0;

                    //
                    // Determine the number of digits in the string version of
                    // the value.
                    //
convert:
                    for(ulIdx = 1;
                        (((ulIdx * ulBase) <= ulValue) &&
                         (((ulIdx * ulBase) / ulBase) == ulIdx));
                        ulIdx *= ulBase, ulCount--)
                    {
                    }

                    //
                    // If the value is negative, reduce the count of padding
                    // characters needed.
                    //
                    if(ulNeg)
                    {
                        ulCount--;
                    }

                    //
                    // If the value is negative and the value is padded with
                    // zeros, then place the minus sign before the padding.
                    //
                    if(ulNeg && (ulSize != 0) && (cFill == '0'))
                    {
                        //
                        // Place the minus sign in the output buffer.
                        //
                        *pcBuf++ = '-';
                        ulSize--;

                        //
                        // Update the conversion count.
                        //
                        iConvertCount++;

                        //
                        // The minus sign has been placed, so turn off the
                        // negative flag.
                        //
                        ulNeg = 0;
                    }

                    //
                    // See if there are more characters in the specified field
                    // width than there are in the conversion of this value.
                    //
                    if((ulCount > 1) && (ulCount < 65536))
                    {
                        //
                        // Loop through the required padding characters.
                        //
                        for(ulCount--; ulCount; ulCount--)
                        {
                            //
                            // Copy the character to the output buffer if there
                            // is room.
                            //
                            if(ulSize != 0)
                            {
                                *pcBuf++ = cFill;
                                ulSize--;
                            }

                            //
                            // Update the conversion count.
                            //
                            iConvertCount++;
                        }
                    }

                    //
                    // If the value is negative, then place the minus sign
                    // before the number.
                    //
                    if(ulNeg && (ulSize != 0))
                    {
                        //
                        // Place the minus sign in the output buffer.
                        //
                        *pcBuf++ = '-';
                        ulSize--;

                        //
                        // Update the conversion count.
                        //
                        iConvertCount++;
                    }

                    //
                    // Convert the value into a string.
                    //
                    for(; ulIdx; ulIdx /= ulBase)
                    {
                        //
                        // Copy the character to the output buffer if there is
                        // room.
                        //
                        if(ulSize != 0)
                        {
                            *pcBuf++ = g_pcHex[(ulValue / ulIdx) % ulBase];
                            ulSize--;
                        }

                        //
                        // Update the conversion count.
                        //
                        iConvertCount++;
                    }

                    //
                    // This command has been handled.
                    //
                    break;
                }

                //
                // Handle the %% command.
                //
                case '%':
                {
                    //
                    // Simply write a single %.
                    //
                    if(ulSize != 0)
                    {
                        *pcBuf++ = pcString[-1];
                        ulSize--;
                    }

                    //
                    // Update the conversion count.
                    //
                    iConvertCount++;

                    //
                    // This command has been handled.
                    //
                    break;
                }

                //
                // Handle all other commands.
                //
                default:
                {
                    //
                    // Indicate an error.
                    //
                    if(ulSize >= 5)
                    {
                        ustrncpy(pcBuf, "ERROR", 5);
                        pcBuf += 5;
                        ulSize -= 5;
                    }
                    else
                    {
                        ustrncpy(pcBuf, "ERROR", ulSize);
                        pcBuf += ulSize;
                        ulSize = 0;
                    }

                    //
                    // Update the conversion count.
                    //
                    iConvertCount += 5;

                    //
                    // This command has been handled.
                    //
                    break;
                }
            }
        }
    }
Exemplo n.º 19
0
void menu_browse_files(void) {
  buffer_t *buf;
  buffer_t *buf_tbl;
  buffer_t *buf_cur;
  buffer_t *first_buf;
  path_t path;
  cbmdirent_t dent;
  uint16_t entries;
  uint8_t entry_num;
  bool fat_filesystem;
  uint8_t i;
  uint8_t my;
  uint16_t mp;
  bool action;
  uint16_t stack_mp[MAX_LASTPOS];
  uint8_t stack_my[MAX_LASTPOS];
  uint8_t pos_stack;
  uint8_t save_active_buffers;

  pos_stack = 0;
  memset(stack_mp, 0, sizeof(stack_mp));
  memset(stack_my, 0, sizeof(stack_my));
  save_active_buffers = active_buffers;

start:
  lcd_clear();
  lcd_puts_P(PSTR("Reading..."));

  buf = buf_tbl = buf_cur = first_buf = NULL;
  entries = entry_num = mp = 0;
  fat_filesystem = false;

  // Allocate one buffer, used to read a single directory entry
  if ((buf = alloc_system_buffer()) == NULL) return;

  // Allocate buffers with continuous data segments
  // Stores pointers to directory entries for qsort
  if ((buf_tbl = alloc_linked_buffers(CONFIG_DIR_BUFFERS)) == NULL) return;

  // Buffers to store the actual diretory entries.
  // Whilst the directory grows, new buffers get allocated and linked
  if ((buf_cur = alloc_system_buffer()) == NULL) return;
  first_buf = buf_cur;

  // Allocating buffers affects the LEDs
  set_busy_led(false); set_dirty_led(true);

  path.part = current_part;
  path.dir  = partition[path.part].current_dir;
  uart_trace(&path.dir, 0, sizeof(dir_t));
  uart_putcrlf();
  uart_flush();
  if (opendir(&buf->pvt.dir.dh, &path)) return;

  for (;;) {
    if (next_match(&buf->pvt.dir.dh,
                    buf->pvt.dir.matchstr,
                    buf->pvt.dir.match_start,
                    buf->pvt.dir.match_end,
                    buf->pvt.dir.filetype,
                    &dent) == 0)
    {
      uint8_t e_flags = 0;
      if (dent.opstype == OPSTYPE_FAT) {
        fat_filesystem = true;
        if (check_imageext(dent.pvt.fat.realname) != IMG_UNKNOWN)
          e_flags |= E_IMAGE;
      }
      // Current block full?
      if (entry_num == ENTRIES_PER_BLOCK) {
        entry_num = 0;
        buffer_t *old_buf = buf_cur;
        if ((buf_cur = alloc_system_buffer()) == NULL) {
          printf("alloc buf_cur failed, %d entries", entries);
          goto cleanup;
        }
        set_busy_led(false); set_dirty_led(true);
        buf_cur->pvt.buffer.next = NULL;
        old_buf->pvt.buffer.next = buf_cur;
      }

      // Store entry
      ep[entries] = (entry_t *) (buf_cur->data + entry_num * sizeof(entry_t));
      ustrncpy(ep[entries]->filename, dent.name, 16);
      ep[entries]->filesize = dent.blocksize;
      if ((dent.typeflags & EXT_TYPE_MASK) == TYPE_DIR)
        e_flags |= E_DIR;
      ep[entries]->flags = e_flags;
      entries++;
      entry_num++;
    } else {
      // No more directory entries to read
      break;
    }
  }
  printf("%d entries\r\n", entries);

  if (fat_filesystem)
    qsort(ep, entries, sizeof(entry_t*), compare);

  for (uint16_t i = 0; i < entries; i++) {
    printf("%3u: ", i);
    if (ep[i]->flags & E_DIR)
      uart_puts_P(PSTR(" DIR "));
    else if (ep[i]->flags & E_IMAGE)
      uart_puts_P(PSTR(" IMG "));
    else
      printf("%4u ", ep[i]->filesize);
    uint8_t filename[16 + 1];
    ustrncpy(filename, ep[i]->filename, 16);
    filename[16] = '\0';
    pet2asc(filename);
    printf("%s\r\n", filename);
    uart_flush();
  }
  uart_putcrlf();

#define DIRNAV_OFFSET   2
#define NAV_ABORT       0
#define NAV_PARENT      1

  mp = stack_mp[pos_stack];
  my = stack_my[pos_stack];
  printf("mp set to %d\r\n", mp);
  if (mp < (LCD_LINES - 1))
    my = mp;
  else
    my = 0;
  action = false;

  for (i=0; i < MAX_LASTPOS; i++) {
    if (pos_stack == i) uart_putc('>');
    printf("%d ", stack_mp[i]);
  }
  uart_putcrlf();

  for (;;) {
    lcd_clear();
    for (i = 0; i < LCD_LINES; i++) {
      lcd_locate(0, i);
      int8_t y = mp - my + i;
      if (y < 0) return; // should not happen!
      if (y < DIRNAV_OFFSET) {
        rom_menu_browse(y);
      } else {
        y -= DIRNAV_OFFSET;
        if (y >= entries) {
          lcd_puts_P(PSTR("-- End of dir --"));
          break;
        } else {
          lcd_print_dir_entry(y);
        }
      }
    }

    lcd_cursor(true);
    for (;;) {
      lcd_locate(0, my);
      //printf("mp: %u   my: %u\r\n", mp, my);
      //while (!get_key_state(KEY_ANY));
      if (get_key_autorepeat(KEY_PREV)) {
        if (mp > 0) {
          --mp;
          if (my > 0) --my;
          else {
            my = LCD_LINES - 1;
            if (mp < LCD_LINES) {
              while ((mp - my) >= DIRNAV_OFFSET) {
                --my;
                // TODO: is this really necessary?
                uart_puts_P(PSTR("my fixed\r\n"));
              }
            }
            break;
          }
        } else {
          my = LCD_LINES - 2;
          mp = entries + DIRNAV_OFFSET - 1;
          break;
        }
      }
      if (get_key_autorepeat(KEY_NEXT)) {
        if (mp < (entries -1 + DIRNAV_OFFSET)) {
          ++mp;
          if (my < (LCD_LINES - 1))  ++my;
          else {
            my = 0;
            break;
          }
        } else {
          mp = 0;
          my = 0;
          break;
        }
      }
      if (get_key_press(KEY_SEL)) {
        action = true;
        break;
      }
    }
    lcd_cursor(false);
    if (!action) continue;
    if (mp == NAV_ABORT) goto cleanup;
    if (mp == NAV_PARENT) {
      uart_puts_P(PSTR("CD_\r\n"));
      ustrcpy_P(command_buffer, PSTR("CD_"));
      command_length = 3;
      parse_doscommand();
      clear_command_buffer();
      stack_mp[pos_stack] = 0;
      stack_my[pos_stack] = 0;
      if (pos_stack > 0) --pos_stack;
      printf("pos_stack set to %d\r\n", pos_stack);
      if (current_error != ERROR_OK) goto cleanup;
      goto reread;
    }
    if (ep[mp - DIRNAV_OFFSET]->flags & E_DIR ||
        ep[mp - DIRNAV_OFFSET]->flags & E_IMAGE)
    {
      clear_command_buffer();
      ustrcpy_P(command_buffer, PSTR("CD:"));
      ustrncpy(command_buffer + 3, ep[mp - DIRNAV_OFFSET]->filename, 16);
      command_length = ustrlen(command_buffer);
      parse_doscommand();
      clear_command_buffer();
      if (current_error != ERROR_OK) goto cleanup;
      if (pos_stack < MAX_LASTPOS) {
        stack_mp[pos_stack]   = mp;
        stack_my[pos_stack++] = my;
        printf("pos_stack set to %d\r\n", pos_stack);
      }
      goto reread;
    }
  }

reread:
  free_buffer(buf);

  buffer_t *p = buf_tbl;
  do {
    p->allocated = 0;
    p = p->pvt.buffer.next;
  } while (p != NULL);

  p = first_buf;
  if (p != NULL) do {
    p->allocated = 0;
    p = p->pvt.buffer.next;
  } while (p != NULL);

  set_busy_led(false); set_dirty_led(true);
  active_buffers = save_active_buffers;
  if (mp == NAV_ABORT) return;
  goto start;

cleanup:
  mp = NAV_ABORT;
  goto reread;
}