mirror of
https://github.com/suloku/savegame-manager.git
synced 2026-09-09 19:55:07 -05:00
The source for the 0.2.0 release (12-30-2010).
This commit is contained in:
@@ -40,7 +40,7 @@ LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lfat -lnds9
|
||||
LIBS := -lfat -ldswifi9 -lnds9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
#include "auxspi_core.cpp"
|
||||
#include "hardware.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using std::max;
|
||||
|
||||
extern u8 data[0x8000];
|
||||
|
||||
|
||||
// ========================================================
|
||||
// local functions
|
||||
@@ -265,9 +271,13 @@ void auxspi_erase()
|
||||
auxspi_wait_busy();
|
||||
auxspi_close();
|
||||
}
|
||||
} else {
|
||||
int8 size = 1 << max(0, (auxspi_save_size_log_2() - 15));
|
||||
memset(data, 0, 0x8000);
|
||||
for (int i = 0; i < size; i++) {
|
||||
auxspi_write_data(i << 15, data, 0x8000, type);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: do something for other types as well!
|
||||
}
|
||||
|
||||
void auxspi_wait_wip()
|
||||
|
||||
@@ -55,7 +55,7 @@ void displayInit()
|
||||
consoleInit(&lowerScreen, 3,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
|
||||
|
||||
consoleSelect(&upperScreen);
|
||||
displayMessage("DS savegame manager\nVersion 0.1.1 Beta\nBy Pokedoc");
|
||||
iprintf("\n\n\n\n\nDS savegame manager\nVersion 0.2 Beta\nBy Pokedoc");
|
||||
|
||||
displayPrintState("Press (B) to continue");
|
||||
while (!(keysCurrent() & KEY_B));
|
||||
@@ -63,6 +63,11 @@ void displayInit()
|
||||
|
||||
void displayPrintUpper()
|
||||
{
|
||||
extern uint32 ezflash;
|
||||
extern bool gba;
|
||||
extern uint32 dstype;
|
||||
extern bool slot2;
|
||||
|
||||
// print upper screen (background)
|
||||
consoleSelect(&upperScreen);
|
||||
consoleSetWindow(&upperScreen, 0, 0, 32, 24);
|
||||
@@ -73,16 +78,20 @@ void displayPrintUpper()
|
||||
iprintf("Game name:\n");
|
||||
iprintf("Game save:\n");
|
||||
iprintf("Special :\n");
|
||||
#if 0
|
||||
iprintf("--- SLOT 2 ---------------------");
|
||||
iprintf("Game ID :\n");
|
||||
iprintf("Game name:\n");
|
||||
iprintf("Game save:\n");
|
||||
iprintf("Special :\n");
|
||||
#endif
|
||||
if (dstype > 0)
|
||||
iprintf("This device has no Slot-2");
|
||||
else {
|
||||
iprintf("Game ID :\n");
|
||||
iprintf("Game name:\n");
|
||||
iprintf("Game save:\n");
|
||||
iprintf("Special :\n");
|
||||
}
|
||||
|
||||
// print upper screen
|
||||
consoleSetWindow(&upperScreen, 10, 2, 12, 4);
|
||||
consoleSetWindow(&upperScreen, 10, 2, 22, 4);
|
||||
consoleClear();
|
||||
consoleSetWindow(&upperScreen, 10, 7, 22, 4);
|
||||
consoleClear();
|
||||
|
||||
// fetch cartridge header (maybe, calling "cardReadHeader" on a FC messes with libfat!)
|
||||
@@ -108,12 +117,15 @@ void displayPrintUpper()
|
||||
case 3:
|
||||
sprintf(&name[0], "DSi/SD");
|
||||
break;
|
||||
case 4:
|
||||
sprintf(&name[0], "Slot 2");
|
||||
break;
|
||||
}
|
||||
consoleClear();
|
||||
iprintf("%s", name);
|
||||
|
||||
// 1) The cart id.
|
||||
consoleSetWindow(&upperScreen, 10, 2, 20, 1);
|
||||
consoleSetWindow(&upperScreen, 10, 2, 22, 1);
|
||||
sprintf(&name[0], "----");
|
||||
if (flash_card) {
|
||||
sprintf(&name[0], "Flash Card");
|
||||
@@ -125,7 +137,7 @@ void displayPrintUpper()
|
||||
iprintf("%s", name);
|
||||
|
||||
// 2) The cart name.
|
||||
consoleSetWindow(&upperScreen, 10, 3, 20, 1);
|
||||
consoleSetWindow(&upperScreen, 10, 3, 22, 1);
|
||||
sprintf(&name[0], "----");
|
||||
if (flash_card) {
|
||||
sprintf(&name[0], "Flash Card");
|
||||
@@ -137,7 +149,7 @@ void displayPrintUpper()
|
||||
iprintf("%s", name);
|
||||
|
||||
// 3) The save type
|
||||
consoleSetWindow(&upperScreen, 10, 4, 20, 1);
|
||||
consoleSetWindow(&upperScreen, 10, 4, 22, 1);
|
||||
sprintf(&name[0], "----");
|
||||
if (flash_card) {
|
||||
sprintf(&name[0], "Flash Card");
|
||||
@@ -146,10 +158,10 @@ void displayPrintUpper()
|
||||
uint32 size = auxspi_save_size();
|
||||
switch (type) {
|
||||
case 1:
|
||||
sprintf(&name[0], "Type 1 (%i Bytes)", size);
|
||||
sprintf(&name[0], "Eeprom (%i Bytes)", size);
|
||||
break;
|
||||
case 2:
|
||||
sprintf(&name[0], "Type 2 (%i kB)", size >> 10);
|
||||
sprintf(&name[0], "FRAM (%i kB)", size >> 10);
|
||||
break;
|
||||
case 3:
|
||||
sprintf(&name[0], "Flash (%i kB)", size >> 10);
|
||||
@@ -163,17 +175,81 @@ void displayPrintUpper()
|
||||
iprintf("%s", name);
|
||||
|
||||
// 4) Special properties (infrared device...)
|
||||
consoleSetWindow(&upperScreen, 10, 5, 24, 1);
|
||||
consoleSetWindow(&upperScreen, 10, 5, 22, 1);
|
||||
consoleClear();
|
||||
memset(&name[0], 0, MAXPATHLEN);
|
||||
//if (auxspi_has_infrared()) {
|
||||
if (ir) {
|
||||
sprintf(&name[0], "Infrared");
|
||||
} else {
|
||||
sprintf(&name[0], "---");
|
||||
sprintf(&name[0], "----");
|
||||
}
|
||||
iprintf("%s", name);
|
||||
|
||||
// Slot 2 status
|
||||
// 5) GBA game id
|
||||
consoleSetWindow(&upperScreen, 10, 7, 22, 1);
|
||||
consoleClear();
|
||||
memset(&name[0], 0, MAXPATHLEN);
|
||||
if (ezflash) {
|
||||
if (ezflash == 0x89168916)
|
||||
sprintf(name, "3in1 (512M)");
|
||||
else
|
||||
sprintf(name, "3in1 (256M)");
|
||||
} else if (gba)
|
||||
sprintf(name, "%.4s", (char*)0x080000ac);
|
||||
else if (slot2)
|
||||
sprintf(name, "Flash Card");
|
||||
else if (dstype == 0)
|
||||
sprintf(name, "----");
|
||||
if (dstype == 0)
|
||||
iprintf("%s", name);
|
||||
|
||||
// 6) GBA game name
|
||||
consoleSetWindow(&upperScreen, 10, 8, 22, 1);
|
||||
consoleClear();
|
||||
memset(&name[0], 0, MAXPATHLEN);
|
||||
if (ezflash)
|
||||
sprintf(name, "3in1");
|
||||
else if (gba)
|
||||
sprintf(name, "%.12s", (char*)0x080000a0);
|
||||
else if (slot2)
|
||||
sprintf(name, "Flash Card");
|
||||
else if (dstype == 0)
|
||||
sprintf(name, "----");
|
||||
if (dstype == 0)
|
||||
iprintf(name);
|
||||
|
||||
// 7) GBA save size
|
||||
consoleSetWindow(&upperScreen, 10, 9, 22, 1);
|
||||
consoleClear();
|
||||
memset(&name[0], 0, MAXPATHLEN);
|
||||
if (ezflash)
|
||||
sprintf(name, "SRAM");
|
||||
else if (gba)
|
||||
sprintf(name, "(unsupported)");
|
||||
else if (slot2)
|
||||
sprintf(name, "Flash Card");
|
||||
else if (dstype == 0)
|
||||
sprintf(name, "----");
|
||||
if (dstype == 0)
|
||||
iprintf(name);
|
||||
|
||||
// 8) GBA special stuff
|
||||
consoleSetWindow(&upperScreen, 10, 10, 22, 1);
|
||||
consoleClear();
|
||||
memset(&name[0], 0, MAXPATHLEN);
|
||||
if (ezflash)
|
||||
sprintf(name, "NOR + PSRAM");
|
||||
else if (gba)
|
||||
sprintf(name, "(unsupported)");
|
||||
else if (slot2)
|
||||
sprintf(name, "----");
|
||||
else if (dstype == 0)
|
||||
sprintf(name, "----");
|
||||
if (dstype == 0)
|
||||
iprintf(name);
|
||||
|
||||
#if 0
|
||||
// hack: some tests to debug new hardware.
|
||||
uint8 data[512];
|
||||
|
||||
@@ -33,25 +33,84 @@
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "display.h"
|
||||
|
||||
char fnames[256][256];
|
||||
#include "fileselect.h"
|
||||
|
||||
|
||||
extern u8 data[0x8000];
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
void ftpGetFileList(const char *dir, netbuf *ctrl, uint32 &num)
|
||||
{
|
||||
char *buf = (char*)data;
|
||||
memset(buf, 0, 0x8000);
|
||||
FtpDirBuf((char*)data, 0x8000, "/", ctrl);
|
||||
//FtpDir("/dir.txt", "/", ctrl);
|
||||
char *ptr = buf; // scan pointer
|
||||
char *ptr2 = buf; // write pointer
|
||||
// count number of entries and condense them for further use
|
||||
char *begin = 0, *end;
|
||||
while ((end = strchr(ptr, '\n')) != NULL) {
|
||||
char c;
|
||||
char fname[512];
|
||||
if (!strlen(ptr))
|
||||
break;
|
||||
sscanf(ptr, "%c%*s %*s %*s %*s %*s %*s %*s %*s %[^\n]", &c, fname); // gets 'd' or 'f' - dir or file
|
||||
begin = strstr(ptr, fname);
|
||||
if (!begin)
|
||||
break;
|
||||
int flen = end - begin + 1;
|
||||
if (flen <= 1)
|
||||
break; // some FTP servers send an empty line at the end, so prevent an integer overflow
|
||||
if (c == 'd')
|
||||
*ptr2 = 'd';
|
||||
else
|
||||
*ptr2 = 'f';
|
||||
ptr2++;
|
||||
memcpy(ptr2, begin, flen);
|
||||
ptr = end + 1;
|
||||
ptr2 += flen;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
void fileGetFileList(const char *dir, uint32 &num)
|
||||
{
|
||||
char *buf = (char*)data;
|
||||
int idx = 0;
|
||||
memset(buf, 0, 0x8000);
|
||||
|
||||
DIR *pdir;
|
||||
struct dirent *pent;
|
||||
num = 0;
|
||||
|
||||
pdir=opendir(dir);
|
||||
|
||||
char name[128];
|
||||
if (pdir) {
|
||||
while ((pent=readdir(pdir)) !=NULL) {
|
||||
sprintf(&fnames[num][0], "%s", pent->d_name);
|
||||
num++;
|
||||
if (num == 256)
|
||||
char fullname[256];
|
||||
sprintf(fullname, "%s/%s", dir, pent->d_name);
|
||||
struct stat statbuf;
|
||||
stat(fullname, &statbuf);
|
||||
|
||||
// TODO: check for buffer overflow!
|
||||
if (idx + strlen(pent->d_name) < 0x8000-2) {
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
int len = sprintf(buf, "d%s\n", pent->d_name);
|
||||
buf += len;
|
||||
idx += len;
|
||||
} else {
|
||||
int len = sprintf(buf, "f%s\n", pent->d_name);
|
||||
buf += len;
|
||||
idx += len;
|
||||
}
|
||||
num++;
|
||||
} else {
|
||||
// buffer overflow imminent
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pdir)
|
||||
@@ -67,45 +126,65 @@ void filePrintFileList(const char *dir, uint32 first, uint32 select, uint32 coun
|
||||
consoleSetWindow(&lowerScreen, 0, 0, 32, 19);
|
||||
consoleClear();
|
||||
|
||||
for (uint32 i = first; (i < first + 18) && (i < count); i++) {
|
||||
struct stat statbuf;
|
||||
char fullpath[512];
|
||||
sprintf(fullpath, "%s/%s", dir, fnames[i]);
|
||||
stat(fullpath, &statbuf);
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
if (i != select)
|
||||
iprintf("[%.29s]\n", fnames[i]);
|
||||
else
|
||||
iprintf("-->[%.26s]\n", fnames[i]);
|
||||
} else {
|
||||
if (i != select)
|
||||
iprintf("%.31s\n", fnames[i]);
|
||||
else
|
||||
iprintf("-->%.28s\n", fnames[i]);
|
||||
}
|
||||
char *buf = (char*)data;
|
||||
int idx = 0;
|
||||
int len = strlen(buf);
|
||||
for (int i = 0; i < first; i++) {
|
||||
buf = strchr(buf, '\n') + 1;
|
||||
}
|
||||
|
||||
for (uint32 i = first; (i < first + 18) && (i < count); i++) {
|
||||
struct stat statbuf;
|
||||
char dir;
|
||||
u32 size;
|
||||
char fname[128];
|
||||
char fname2[128];
|
||||
char *newline = strchr(buf, '\n');
|
||||
int linelen = newline - buf;
|
||||
|
||||
*newline = 0;
|
||||
if (*buf == 'd') {
|
||||
if (i != select)
|
||||
iprintf("[%.29s]\n", buf+1);
|
||||
else
|
||||
iprintf("-->[%.26s]\n", buf+1);
|
||||
} else {
|
||||
if (i != select)
|
||||
iprintf("%.31s\n", buf+1);
|
||||
else
|
||||
iprintf("-->%.28s\n", buf+1);
|
||||
}
|
||||
*newline = '\n';
|
||||
buf += linelen+1;
|
||||
}
|
||||
|
||||
consoleSelect(&lowerScreen);
|
||||
consoleSetWindow(&lowerScreen, 0, 18, 32, 6);
|
||||
consoleClear();
|
||||
iprintf("================================");
|
||||
iprintf("Please select a .sav file\n");
|
||||
iprintf(" (A) Select\n");
|
||||
iprintf(" (B) One directory up\n");
|
||||
if (cancel)
|
||||
iprintf(" (B) cancel");
|
||||
iprintf(" (L+R) cancel (new file)");
|
||||
}
|
||||
|
||||
// ========================***************************==============================
|
||||
void fileSelect(const char *startdir, char *out_dir, char *out_fname, bool allow_cancel)
|
||||
void fileSelect(const char *startdir, char *out_dir, char *out_fname, netbuf *buf,
|
||||
bool allow_cancel, bool allow_up)
|
||||
{
|
||||
bool select = false;
|
||||
static int size_list = 18;
|
||||
|
||||
uint32 num_files = 0;
|
||||
uint32 sel_file = 0;
|
||||
uint32 first_file = 0;
|
||||
|
||||
// get list of files in current dir
|
||||
fileGetFileList(startdir, num_files);
|
||||
if (buf)
|
||||
ftpGetFileList("/", buf, num_files);
|
||||
else
|
||||
fileGetFileList(startdir, num_files);
|
||||
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
|
||||
|
||||
while (!select) {
|
||||
@@ -116,49 +195,82 @@ void fileSelect(const char *startdir, char *out_dir, char *out_fname, bool allow
|
||||
if (keys & KEY_DOWN) {
|
||||
if (sel_file < num_files-1) {
|
||||
sel_file++;
|
||||
if (sel_file >= first_file + size_list - 1)
|
||||
first_file = sel_file - (size_list - 1);
|
||||
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
|
||||
if (sel_file > first_file + 18)
|
||||
first_file = sel_file - 18;
|
||||
}
|
||||
} else if (keys & KEY_UP) {
|
||||
if (sel_file > 0) {
|
||||
sel_file--;
|
||||
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
|
||||
if (sel_file < first_file)
|
||||
first_file = sel_file;
|
||||
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
|
||||
}
|
||||
} else if (keys & KEY_A) {
|
||||
// TODO: Okay, my first attempt at implementing a fuill file browser
|
||||
// failed, so I am disabling changing directory for now. If anybody
|
||||
// feels inclined to fix it, go ahead.
|
||||
if (stricmp(fnames[sel_file], ".") == 0)
|
||||
continue;
|
||||
if (stricmp(fnames[sel_file], "..") == 0)
|
||||
//return;
|
||||
// get selected file name
|
||||
char *buf2 = (char*)data;
|
||||
int idx = 0;
|
||||
int len = strlen(buf2);
|
||||
char fname[128];
|
||||
for (int i = 0; i < sel_file; i++) {
|
||||
buf2 = strchr(buf2, '\n') + 1;
|
||||
}
|
||||
char c;
|
||||
sscanf(buf2, "%c%[^\n]", &c, fname); // gets 'd' or 'f' - dir or file
|
||||
// special cases
|
||||
if (stricmp(fname, ".") == 0)
|
||||
// don't do anything
|
||||
continue;
|
||||
if (stricmp(fname, "..") == 0) {
|
||||
// return to parent function (usually results in "back to higher level")
|
||||
while (keysCurrent() & (KEY_A | KEY_B));
|
||||
if (!allow_up)
|
||||
continue;
|
||||
if (buf)
|
||||
FtpChdir("..", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
// get selected file properties
|
||||
char fullname[512];
|
||||
sprintf(fullname, "%s/%s", startdir, fnames[sel_file]);
|
||||
sprintf(fullname, "%s%s", startdir, fname);
|
||||
struct stat statbuf;
|
||||
stat(fullname, &statbuf);
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
/*
|
||||
if (c == 'd') {
|
||||
char fullpath[512];
|
||||
sprintf(fullpath, "%s/%s", startdir, fnames[sel_file]);
|
||||
fileSelect(fullpath, out_dir, out_fname, allow_cancel);
|
||||
for (int i = 0; i < 5; i++)
|
||||
swiWaitForVBlank();
|
||||
sprintf(fullpath, "%s%s/", startdir, fname);
|
||||
if (buf)
|
||||
FtpChdir(fname, buf);
|
||||
fileSelect(fullpath, out_dir, out_fname, buf, allow_cancel, true);
|
||||
if ((keysCurrent() & (KEY_L | KEY_R)) && allow_cancel)
|
||||
return;
|
||||
while (keysCurrent() & (KEY_A | KEY_B));
|
||||
|
||||
// did we select a file? if so, keep returning to parent calling function
|
||||
if (strlen(out_fname))
|
||||
return;
|
||||
*/
|
||||
|
||||
// we did not select anything, so regenerate the old list
|
||||
num_files = 0;
|
||||
if (buf)
|
||||
ftpGetFileList("/", buf, num_files);
|
||||
else
|
||||
fileGetFileList(startdir, num_files);
|
||||
filePrintFileList(startdir, first_file, sel_file, num_files, allow_cancel);
|
||||
continue;
|
||||
} else {
|
||||
sprintf(out_dir, "%s", startdir);
|
||||
sprintf(out_fname, "%s", fnames[sel_file]);
|
||||
sprintf(out_fname, "%s", fname);
|
||||
while (keysCurrent() & (KEY_A | KEY_B));
|
||||
return;
|
||||
}
|
||||
select = true;
|
||||
|
||||
} else if (keys & KEY_B) {
|
||||
if (!allow_up)
|
||||
continue;
|
||||
if (buf)
|
||||
FtpChdir("..", buf);
|
||||
return;
|
||||
} else if (keys & (KEY_L | KEY_R)) {
|
||||
if (allow_cancel) {
|
||||
sprintf(out_dir, "%s", startdir);
|
||||
out_fname[0] = 0;
|
||||
|
||||
@@ -33,8 +33,28 @@
|
||||
|
||||
#define MAX_CUSTOM_LIST 8192
|
||||
|
||||
#include <unistd.h>
|
||||
//#endif
|
||||
//#if defined(_WIN32)
|
||||
//#include <windows.h>
|
||||
//#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
//#if defined(__unix__)
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
void fileSelect(const char *startdir, char *out_dir, char *out_fname, bool allow_cancel = false);
|
||||
#include "ftplib.h"
|
||||
|
||||
|
||||
void fileSelect(const char *startdir, char *out_dir, char *out_fname, netbuf *buf = 0,
|
||||
bool allow_cancel = false, bool allow_up = true);
|
||||
|
||||
bool fileExists(const char *fname);
|
||||
uint32 fileSize(const char *fname);
|
||||
|
||||
1452
arm9/source/ftplib.c
Normal file
1452
arm9/source/ftplib.c
Normal file
File diff suppressed because it is too large
Load Diff
139
arm9/source/ftplib.h
Normal file
139
arm9/source/ftplib.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/***************************************************************************/
|
||||
/* */
|
||||
/* ftplib.h - header file for callable ftp access routines */
|
||||
/* Copyright (C) 1996, 1997 Thomas Pfau, pfau@cnj.digex.net */
|
||||
/* 73 Catherine Street, South Bound Brook, NJ, 08880 */
|
||||
/* */
|
||||
/* This library is free software; you can redistribute it and/or */
|
||||
/* modify it under the terms of the GNU Library General Public */
|
||||
/* License as published by the Free Software Foundation; either */
|
||||
/* version 2 of the License, or (at your option) any later version. */
|
||||
/* */
|
||||
/* This library is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
|
||||
/* Library General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU Library General Public */
|
||||
/* License along with this progam; if not, write to the */
|
||||
/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
|
||||
/* Boston, MA 02111-1307, USA. */
|
||||
/* */
|
||||
/***************************************************************************/
|
||||
|
||||
#if !defined(__FTPLIB_H)
|
||||
#define __FTPLIB_H
|
||||
|
||||
//#define __unix__
|
||||
|
||||
/*
|
||||
#if defined(__unix__) || defined(VMS)
|
||||
#define GLOBALDEF
|
||||
#define GLOBALREF extern
|
||||
#elif defined(_WIN32)
|
||||
#if defined BUILDING_LIBRARY
|
||||
#define GLOBALDEF __declspec(dllexport)
|
||||
#define GLOBALREF __declspec(dllexport)
|
||||
#else
|
||||
#define GLOBALREF __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
|
||||
#define GLOBALDEF
|
||||
#define GLOBALREF
|
||||
|
||||
/* FtpAccess() type codes */
|
||||
#define FTPLIB_DIR 1
|
||||
#define FTPLIB_DIR_VERBOSE 2
|
||||
#define FTPLIB_FILE_READ 3
|
||||
#define FTPLIB_FILE_WRITE 4
|
||||
|
||||
/* FtpAccess() mode codes */
|
||||
#define FTPLIB_ASCII 'A'
|
||||
#define FTPLIB_IMAGE 'I'
|
||||
#define FTPLIB_TEXT FTPLIB_ASCII
|
||||
#define FTPLIB_BINARY FTPLIB_IMAGE
|
||||
|
||||
/* connection modes */
|
||||
#define FTPLIB_PASSIVE 1
|
||||
#define FTPLIB_PORT 2
|
||||
|
||||
/* connection option names */
|
||||
#define FTPLIB_CONNMODE 1
|
||||
#define FTPLIB_CALLBACK 2
|
||||
#define FTPLIB_IDLETIME 3
|
||||
#define FTPLIB_CALLBACKARG 4
|
||||
#define FTPLIB_CALLBACKBYTES 5
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct NetBuf netbuf;
|
||||
typedef int (*FtpCallback)(netbuf *nControl, int xfered, void *arg);
|
||||
|
||||
/* v1 compatibility stuff */
|
||||
#define _FTPLIB_NO_COMPAT
|
||||
#if !defined(_FTPLIB_NO_COMPAT)
|
||||
extern netbuf *DefaultNetbuf;
|
||||
|
||||
#define ftplib_lastresp FtpLastResponse(DefaultNetbuf)
|
||||
#define ftpInit FtpInit
|
||||
#define ftpOpen(x) FtpConnect(x, &DefaultNetbuf)
|
||||
#define ftpLogin(x,y) FtpLogin(x, y, DefaultNetbuf)
|
||||
#define ftpSite(x) FtpSite(x, DefaultNetbuf)
|
||||
#define ftpMkdir(x) FtpMkdir(x, DefaultNetbuf)
|
||||
#define ftpChdir(x) FtpChdir(x, DefaultNetbuf)
|
||||
#define ftpRmdir(x) FtpRmdir(x, DefaultNetbuf)
|
||||
#define ftpNlst(x, y) FtpNlst(x, y, DefaultNetbuf)
|
||||
#define ftpDir(x, y) FtpDir(x, y, DefaultNetbuf)
|
||||
#define ftpGet(x, y, z) FtpGet(x, y, z, DefaultNetbuf)
|
||||
#define ftpPut(x, y, z) FtpPut(x, y, z, DefaultNetbuf)
|
||||
#define ftpRename(x, y) FtpRename(x, y, DefaultNetbuf)
|
||||
#define ftpDelete(x) FtpDelete(x, DefaultNetbuf)
|
||||
#define ftpQuit() FtpQuit(DefaultNetbuf)
|
||||
#endif /* (_FTPLIB_NO_COMPAT) */
|
||||
/* end v1 compatibility stuff */
|
||||
|
||||
extern int ftplib_debug;
|
||||
GLOBALREF void FtpInit(void);
|
||||
GLOBALREF char *FtpLastResponse(netbuf *nControl);
|
||||
GLOBALREF int FtpConnect(const char *host, netbuf **nControl);
|
||||
GLOBALREF int FtpOptions(int opt, long val, netbuf *nControl);
|
||||
GLOBALREF int FtpLogin(const char *user, const char *pass, netbuf *nControl);
|
||||
GLOBALREF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl,
|
||||
netbuf **nData);
|
||||
GLOBALREF int FtpRead(void *buf, int max, netbuf *nData);
|
||||
GLOBALREF int FtpWrite(void *buf, int len, netbuf *nData);
|
||||
GLOBALREF int FtpClose(netbuf *nData);
|
||||
GLOBALREF int FtpSite(const char *cmd, netbuf *nControl);
|
||||
GLOBALREF int FtpSysType(char *buf, int max, netbuf *nControl);
|
||||
GLOBALREF int FtpMkdir(const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpChdir(const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpCDUp(netbuf *nControl);
|
||||
GLOBALREF int FtpRmdir(const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpPwd(char *path, int max, netbuf *nControl);
|
||||
GLOBALREF int FtpNlst(const char *output, const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpDir(const char *output, const char *path, netbuf *nControl);
|
||||
GLOBALREF int FtpSize(const char *path, int *size, char mode, netbuf *nControl);
|
||||
GLOBALREF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl);
|
||||
GLOBALREF int FtpGet(const char *output, const char *path, char mode,
|
||||
netbuf *nControl);
|
||||
GLOBALREF int FtpPut(const char *input, const char *path, char mode,
|
||||
netbuf *nControl);
|
||||
GLOBALREF int FtpRename(const char *src, const char *dst, netbuf *nControl);
|
||||
GLOBALREF int FtpDelete(const char *fnm, netbuf *nControl);
|
||||
GLOBALREF void FtpQuit(netbuf *nControl);
|
||||
|
||||
static int FtpSendCmd(const char *cmd, char expresp, netbuf *nControl);
|
||||
|
||||
GLOBALREF int FtpAccessBuf(const char *path, int typ, int mode, netbuf *nControl,
|
||||
netbuf **nData);
|
||||
GLOBALREF int FtpDirBuf(char *buf, int size, const char *path, netbuf *nControl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* __FTPLIB_H */
|
||||
@@ -29,12 +29,14 @@
|
||||
#include <nds/arm9/console.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <dswifi9.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "display.h"
|
||||
#include "dsCard.h"
|
||||
#include "ftplib.h"
|
||||
#include "gba.h"
|
||||
|
||||
#include "hardware.h"
|
||||
@@ -50,6 +52,11 @@ uint32 boot;
|
||||
bool flash_card = true; // the homebrew will always start with a FC inserted
|
||||
bool with_infrared = false; // ... which does not have an IR device
|
||||
|
||||
extern char ftp_ip[16];
|
||||
extern char ftp_user[64];
|
||||
extern char ftp_pass[64];
|
||||
extern int ftp_port;
|
||||
|
||||
u8 data[0x8000];
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
@@ -134,6 +141,7 @@ void hwBackup3in1()
|
||||
// Dump save and write it to NOR
|
||||
chip_reset();
|
||||
OpenNorWrite();
|
||||
SetSerialMode();
|
||||
displayPrintState("Writing save to NOR");
|
||||
if (size < 15)
|
||||
size_blocks = 1;
|
||||
@@ -159,8 +167,6 @@ void hwBackup3in1()
|
||||
WriteSram(0x0a000000, (u8*)&data2, sizeof(data2));
|
||||
char txt[128];
|
||||
sprintf(txt, "%.12s", &nds.gameTitle[0]);
|
||||
//memcpy(&txt[0], &nds.gameTitle[0], 12);
|
||||
//displayPrintState(txt);
|
||||
|
||||
displayMessage("Save has been written to 3in1.\nPlease power off and restart\nthis tool.");
|
||||
|
||||
@@ -175,8 +181,8 @@ void hwDump3in1(uint32 size, const char *gamename)
|
||||
|
||||
char path[256];
|
||||
char fname[256] = "";
|
||||
//fileSelect("/", path, fname/*, true*/);
|
||||
//if (!fname[0]) {
|
||||
fileSelect("/", path, fname, 0, true, false);
|
||||
if (!fname[0]) {
|
||||
uint32 cnt = 0;
|
||||
sprintf(fname, "/%s.%i.sav", gamename, cnt);
|
||||
while (fileExists(fname)) {
|
||||
@@ -188,14 +194,14 @@ void hwDump3in1(uint32 size, const char *gamename)
|
||||
}
|
||||
sprintf(fname, "/%s.%i.sav", gamename, cnt);
|
||||
}
|
||||
//}
|
||||
}
|
||||
char fullpath[512];
|
||||
//sprintf(fullpath, "%s/%s", path, fname);
|
||||
sprintf(fullpath, "%s", fname);
|
||||
displayMessage(fullpath);
|
||||
|
||||
sprintf(fullpath, "%s/%s", path, fname);
|
||||
//sprintf(fullpath, "%s", fname);
|
||||
displayMessage(fname);
|
||||
|
||||
// TODO: add support for smaller files!
|
||||
FILE *file = fopen(fullpath, "wb");
|
||||
//u8 *data = (u8*)malloc(0x8000);
|
||||
if (size < 15)
|
||||
size_blocks = 1;
|
||||
else
|
||||
@@ -205,8 +211,6 @@ void hwDump3in1(uint32 size, const char *gamename)
|
||||
u32 LEN = 0x8000;
|
||||
ReadNorFlash(data, i << 15, LEN);
|
||||
fwrite(data, 1, LEN, file);
|
||||
//if (j != LEN)
|
||||
//iprintf ("WRITE ERROR %i\n", errno);
|
||||
}
|
||||
//free(data);
|
||||
fclose(file);
|
||||
@@ -219,8 +223,9 @@ void hwRestore3in1()
|
||||
{
|
||||
char path[256];
|
||||
char fname[256];
|
||||
memset(fname, 0, 256);
|
||||
displayMessage("Please select a .sav file.");
|
||||
fileSelect("/", path, fname);
|
||||
fileSelect("/", path, fname, 0, false, false);
|
||||
displayMessage("");
|
||||
char msg[256];
|
||||
sprintf(msg, "%s%s", path, fname);
|
||||
@@ -310,11 +315,9 @@ void hwRestore3in1_b(uint32 size_file)
|
||||
}
|
||||
LEN = 1 << shift;
|
||||
num_blocks = 1 << (size - shift);
|
||||
//data = (u8*)malloc(LEN);
|
||||
|
||||
chip_reset();
|
||||
OpenNorWrite();
|
||||
SetSerialMode();
|
||||
for (unsigned int i = 0; i < num_blocks; i++) {
|
||||
if (i % (num_blocks >> 6) == 0)
|
||||
displayProgressBar(i+1, num_blocks);
|
||||
@@ -330,13 +333,224 @@ void hwRestore3in1_b(uint32 size_file)
|
||||
while (1) {};
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
void hwErase()
|
||||
{
|
||||
displayMessage("This will WIPE OUT your entire\nsave! ARE YOU SURE?\n\nPress R+up+Y to confim!");
|
||||
while (!(keysCurrent() & (KEY_UP | KEY_R | KEY_Y))) {};
|
||||
auxspi_erase();
|
||||
displayMessage("Done! Your save is gone!");
|
||||
while(0);
|
||||
while(1);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
void hwBackupFTP()
|
||||
{
|
||||
netbuf *buf, *ndata;
|
||||
int j;
|
||||
static int jmax = 10;
|
||||
|
||||
// Dump save and write it to FTP server
|
||||
// First: swap card
|
||||
swap_cart();
|
||||
displayPrintUpper();
|
||||
uint8 size = auxspi_save_size_log_2();
|
||||
int size_blocks = 1 << max(0, (int8(size) - 18)); // ... in units of 0x40000 bytes - that's 256 kB
|
||||
uint8 type = auxspi_save_type();
|
||||
if (size < 15)
|
||||
size_blocks = 1;
|
||||
else
|
||||
size_blocks = 1 << (uint8(size) - 15);
|
||||
|
||||
// Second: connect to FTP server
|
||||
displayPrintState("FTP: connecting to AP");
|
||||
if (!Wifi_InitDefault(true)) {
|
||||
displayPrintState("FTP: ERROR: AP not found");
|
||||
while(1);
|
||||
}
|
||||
displayPrintState("FTP: connecting to FTP server");
|
||||
char fullname[512];
|
||||
sprintf(fullname, "%s:%i", ftp_ip, ftp_port);
|
||||
j = 0;
|
||||
while (!FtpConnect(fullname, &buf)) {
|
||||
j++;
|
||||
if (j >= jmax) {
|
||||
displayPrintState("FTP: ERROR: FTP server missing");
|
||||
while(1);
|
||||
}
|
||||
swiDelay(10000);
|
||||
}
|
||||
displayPrintState("FTP: login");
|
||||
j = 0;
|
||||
while (!FtpLogin(ftp_user, ftp_pass, buf)) {
|
||||
j++;
|
||||
if (j >= jmax) {
|
||||
displayPrintState("FTP: ERROR: login failed");
|
||||
while(1);
|
||||
}
|
||||
swiDelay(10000);
|
||||
}
|
||||
|
||||
char fdir[256] = "";
|
||||
char fname[256] ="";
|
||||
memset(fname, 0, 256);
|
||||
displayMessage("Please select a file name to\noverwrite, or press L+R in a\nfolder to create a new file.");
|
||||
displayPrintState("FTP: dir");
|
||||
fileSelect("/", fdir, fname, buf, true, false);
|
||||
bool newfile;
|
||||
if (!fname[0])
|
||||
newfile = true;
|
||||
else
|
||||
newfile = false;
|
||||
|
||||
// Third: get a new target filename
|
||||
FtpChdir(fdir, buf);
|
||||
if (!fname[0]) {
|
||||
displayMessage("Looking for an unused filename");
|
||||
sNDSHeader nds;
|
||||
cardReadHeader((u8*)&nds);
|
||||
uint32 cnt = 0;
|
||||
int tsize = 0;
|
||||
sprintf(fname, "%.12s.%i.sav", nds.gameTitle, cnt);
|
||||
while (FtpSize(fname, &tsize, FTPLIB_IMAGE, buf) != 0) {
|
||||
if (cnt < 65536)
|
||||
cnt++;
|
||||
else {
|
||||
displayMessage("Unable to get a filename!\nThis means that you have more\nthan 65536 saves! (wow!)\nOops!");
|
||||
while(1);
|
||||
}
|
||||
sprintf(fname, "%.12s.%i.sav", nds.gameTitle, cnt);
|
||||
displayPrintState(fname);
|
||||
}
|
||||
}
|
||||
|
||||
// Fourth: dump save
|
||||
displayPrintState("");
|
||||
sprintf(fullname, "Writing file:\n%s%s", fdir, fname);
|
||||
displayMessage(fullname);
|
||||
FtpAccess(fname, FTPLIB_FILE_WRITE, FTPLIB_IMAGE, buf, &ndata);
|
||||
u32 length = 0x200;
|
||||
if (size < 9)
|
||||
length = 1 << size;
|
||||
for (int i = 0; i < (1 << (size - 9)); i++) {
|
||||
displayProgressBar(i+1, (size_blocks << 6));
|
||||
auxspi_read_data(i << 9, (u8*)&data[0], length, type);
|
||||
int out;
|
||||
if ((out = FtpWrite((u8*)&data[0], length, ndata)) < length) {
|
||||
char dings[512];
|
||||
sprintf(dings, "Error: wrote %i, got %i", length, out);
|
||||
displayPrintState(dings);
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
FtpClose(ndata);
|
||||
FtpQuit(ndata);
|
||||
|
||||
Wifi_DisconnectAP();
|
||||
|
||||
displayMessage("Done! Please turn off your DS.");
|
||||
while(1);
|
||||
}
|
||||
|
||||
void hwRestoreFTP()
|
||||
{
|
||||
netbuf *buf, *ndata;
|
||||
int j;
|
||||
static int jmax = 10;
|
||||
|
||||
// Dump save and write it to FTP server
|
||||
// First: connect to FTP server
|
||||
displayPrintState("FTP: connecting to AP");
|
||||
if (!Wifi_InitDefault(true)) {
|
||||
displayPrintState("FTP: ERROR: AP not found");
|
||||
while(1);
|
||||
}
|
||||
displayPrintState("FTP: connecting to FTP server");
|
||||
char fullname[512];
|
||||
sprintf(fullname, "%s:%i", ftp_ip, ftp_port);
|
||||
j = 0;
|
||||
while (!FtpConnect(fullname, &buf)) {
|
||||
j++;
|
||||
if (j >= jmax) {
|
||||
displayPrintState("FTP: ERROR: FTP server missing");
|
||||
while(1);
|
||||
}
|
||||
swiDelay(10000);
|
||||
}
|
||||
displayPrintState("FTP: login");
|
||||
j = 0;
|
||||
while (!FtpLogin(ftp_user, ftp_pass, buf)) {
|
||||
j++;
|
||||
if (j >= jmax) {
|
||||
displayPrintState("FTP: ERROR: login failed");
|
||||
while(1);
|
||||
}
|
||||
swiDelay(10000);
|
||||
}
|
||||
|
||||
// Second: select a filename
|
||||
char fdir[256] = "";
|
||||
char fname[256] ="";
|
||||
memset(fname, 0, 256);
|
||||
displayMessage("Please select a file name to\nrestore.");
|
||||
displayPrintState("FTP: dir");
|
||||
fileSelect("/", fdir, fname, buf, true, false);
|
||||
/*char fn[512];
|
||||
displayMessage(fname);
|
||||
while(1);*/
|
||||
|
||||
// Third: swap card
|
||||
swap_cart();
|
||||
displayPrintUpper();
|
||||
uint8 size = auxspi_save_size_log_2();
|
||||
int size_blocks = 1 << (size - 9); // ... in units of 512 bytes
|
||||
uint8 type = auxspi_save_type();
|
||||
if (type == 3) {
|
||||
displayPrintState("Formating Flash chip");
|
||||
auxspi_erase();
|
||||
}
|
||||
|
||||
displayPrintState("");
|
||||
FtpChdir(fdir, buf);
|
||||
sprintf(fullname, "Reading file:\n%s%s", fdir, fname);
|
||||
displayMessage(fullname);
|
||||
FtpAccess(fname, FTPLIB_FILE_READ, FTPLIB_IMAGE, buf, &ndata);
|
||||
u32 LEN = 0, num_blocks = 0, shift = 0;
|
||||
switch (type) {
|
||||
case 1:
|
||||
shift = 4; // 16 bytes
|
||||
break;
|
||||
case 2:
|
||||
shift = 5; // 32 bytes
|
||||
break;
|
||||
case 3:
|
||||
shift = 8; // 256 bytes
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
LEN = 1 << shift;
|
||||
int num_blocks_ftp = 1 << (size - 9);
|
||||
num_blocks = 1 << (size - shift);
|
||||
for (int i = 0; i < num_blocks_ftp; i++) {
|
||||
displayProgressBar(i+1, num_blocks_ftp);
|
||||
int out;
|
||||
if ((out = FtpRead((u8*)data, 512, ndata)) < 512) {
|
||||
char dings[512];
|
||||
sprintf(dings, "Error: requested 512, got %i", out);
|
||||
while(1);
|
||||
}
|
||||
for (int j = 0; j < 1 << (9-shift); j++) {
|
||||
auxspi_write_data((i << 9)+(j << shift), ((u8*)data)+(j<<shift), LEN, type);
|
||||
}
|
||||
}
|
||||
FtpClose(ndata);
|
||||
FtpQuit(ndata);
|
||||
|
||||
Wifi_DisconnectAP();
|
||||
|
||||
displayMessage("Done! Please turn off your DS.");
|
||||
while(1);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
@@ -54,6 +54,9 @@ void hwRestore3in1();
|
||||
void hwRestore3in1_b(uint32 size_file);
|
||||
void hwErase();
|
||||
|
||||
void hwBackupFTP();
|
||||
void hwRestoreFTP();
|
||||
|
||||
void hwBackupGBA();
|
||||
void hwRestoreGBA();
|
||||
void hwEraseGBA();
|
||||
|
||||
394
arm9/source/headings.i
Normal file
394
arm9/source/headings.i
Normal file
@@ -0,0 +1,394 @@
|
||||
/***************************************************************************
|
||||
headings.i - Section Heading Manipulation Functions
|
||||
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "iniheadings.h"
|
||||
|
||||
#if defined(HAVE_STRINGS_H)
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
# define strcasecmp stricmp
|
||||
#endif
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_addHeading
|
||||
* Parameters : ini - pointer to ini file database. heading - heading name
|
||||
* Returns : Pointer to new heading.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Adds a new heading to the ini file database and updates the temporary workfile
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
struct section_tag *__ini_addHeading (ini_t *ini, char *heading)
|
||||
{
|
||||
struct section_tag *section;
|
||||
size_t length;
|
||||
long pos;
|
||||
|
||||
// Format heading for storing
|
||||
__ini_strtrim (heading);
|
||||
|
||||
/* Create a backup of the file we are about to edit */
|
||||
if (ini->heading == heading)
|
||||
return __ini_locateHeading (ini, heading);
|
||||
|
||||
// Add new heading to work file and read it in
|
||||
// using file add
|
||||
fseek (ini->ftmp, 0, SEEK_END);
|
||||
fputs ("\n[", ini->ftmp);
|
||||
pos = ftell (ini->ftmp);
|
||||
fputs (heading, ini->ftmp);
|
||||
length = (size_t) (ftell (ini->ftmp) - pos);
|
||||
section = __ini_faddHeading (ini, ini->ftmp, pos, length);
|
||||
fseek (ini->ftmp, 0, SEEK_END);
|
||||
fputs ("]\n", ini->ftmp);
|
||||
ini->heading = section->heading;
|
||||
if (section)
|
||||
ini->flags |= INI_MODIFIED;
|
||||
return section;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_faddheading
|
||||
* Parameters : ini - pointer to ini file database, file - ini file to read heading from
|
||||
* : pos - heading position in file, length - heading length
|
||||
* Returns : Pointer to new heading.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Adds a new heading to the ini file database from the input file.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
struct section_tag *__ini_faddHeading (ini_t *ini, FILE *file, long pos, size_t length)
|
||||
{
|
||||
struct section_tag *section;
|
||||
char *str;
|
||||
|
||||
if (length)
|
||||
{
|
||||
length++;
|
||||
str = (char *) malloc (sizeof(char) * length);
|
||||
assert (str);
|
||||
fseek (file, pos, SEEK_SET);
|
||||
fgets (str, (int) length, file);
|
||||
__ini_strtrim (str);
|
||||
}
|
||||
else
|
||||
{
|
||||
str = (char *) malloc (sizeof(char));
|
||||
assert (str);
|
||||
*str = '\0';
|
||||
}
|
||||
|
||||
section = __ini_createHeading (ini, str);
|
||||
// Make sure heading was created
|
||||
if (!section)
|
||||
{
|
||||
free (str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_createHeading
|
||||
* Parameters : ini - pointer to ini file database. heading - heading name
|
||||
* Returns : Pointer to new heading.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Adds an entry into the heading linked list ready for formating by the addHeading commands
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
struct section_tag *__ini_createHeading (ini_t *ini, char *heading)
|
||||
{
|
||||
struct section_tag *pNew;
|
||||
|
||||
pNew = __ini_locateHeading (ini, heading);
|
||||
// Check to see if heading already exists
|
||||
if (pNew)
|
||||
free (heading);
|
||||
else
|
||||
{ // Create a new heading as dosen't exist
|
||||
pNew = (struct section_tag *) malloc (sizeof (struct section_tag));
|
||||
if (!pNew)
|
||||
return NULL;
|
||||
memset (pNew, 0, sizeof (struct section_tag));
|
||||
pNew->heading = heading;
|
||||
|
||||
if (*heading)
|
||||
{ // Found a named heading
|
||||
pNew->pPrev = ini->last;
|
||||
ini->last = pNew;
|
||||
if (pNew->pPrev)
|
||||
pNew->pPrev->pNext = pNew;
|
||||
else
|
||||
ini->first = pNew;
|
||||
}
|
||||
else
|
||||
{ // Anonymous heading (special case),
|
||||
// always comes first
|
||||
pNew->pNext = ini->first;
|
||||
ini->first = pNew;
|
||||
if (pNew->pNext)
|
||||
pNew->pNext->pPrev = pNew;
|
||||
else
|
||||
ini->last = pNew;
|
||||
}
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
{ // Rev 1.3 - Added
|
||||
struct section_tag *pOld;
|
||||
unsigned long crc32;
|
||||
unsigned char accel;
|
||||
|
||||
crc32 = __ini_createCrc32 (heading, (ini->flags & INI_CASE) != 0);
|
||||
pNew->crc = crc32;
|
||||
// Rev 1.3 - Add accelerator list
|
||||
accel = (unsigned char) crc32 & 0x0FF;
|
||||
pNew->pPrev_Acc = NULL;
|
||||
pOld = ini->sections[accel];
|
||||
ini->sections[accel] = pNew;
|
||||
if (pOld) pOld->pPrev_Acc = pNew;
|
||||
pNew->pNext_Acc = pOld;
|
||||
}
|
||||
#endif // INI_USE_HASH_TABLE
|
||||
}
|
||||
|
||||
ini->selected = pNew;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_deleteHeading
|
||||
* Parameters : ini - pointer to ini file database. heading - heading name
|
||||
* Returns :
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Removes a heading from the database only.
|
||||
* : This change does not occur in the file until ini_close is called.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
void __ini_deleteHeading (ini_t *ini)
|
||||
{
|
||||
struct section_tag *current_h;
|
||||
|
||||
// Delete Heading
|
||||
current_h = ini->selected;
|
||||
if (current_h)
|
||||
{ // Delete Keys
|
||||
while (current_h->first)
|
||||
{
|
||||
current_h->selected = current_h->first;
|
||||
__ini_deleteKey (ini);
|
||||
}
|
||||
|
||||
// Tidy up all users of this heading
|
||||
ini->selected = NULL;
|
||||
if (ini->last == current_h)
|
||||
ini->last = current_h->pPrev;
|
||||
|
||||
// Break heading out of list
|
||||
if (!current_h->pPrev)
|
||||
ini->first = current_h->pNext;
|
||||
else
|
||||
current_h->pPrev->pNext = current_h->pNext;
|
||||
if (current_h->pNext)
|
||||
current_h->pNext->pPrev = current_h->pPrev;
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
// Rev 1.3 - Take member out of accelerator list
|
||||
if (!current_h->pPrev_Acc)
|
||||
ini->sections[(unsigned char) current_h->crc & 0x0FF] = current_h->pNext_Acc;
|
||||
else
|
||||
current_h->pPrev_Acc->pNext_Acc = current_h->pNext_Acc;
|
||||
if (current_h->pNext_Acc)
|
||||
current_h->pNext_Acc->pPrev_Acc = current_h->pPrev_Acc;
|
||||
#endif // INI_USE_HASH_TABLE
|
||||
|
||||
// Delete Heading
|
||||
free (current_h->heading);
|
||||
free (current_h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_locateHeading
|
||||
* Parameters : ini - pointer to ini file database. heading - heading name
|
||||
* Returns : Pointer to heading.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Locates a heading entry in the database.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
struct section_tag *__ini_locateHeading (ini_t *ini, const char *heading)
|
||||
{
|
||||
struct section_tag *current_h;
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
// Rev 1.3 - Revised to use new accelerator
|
||||
unsigned long crc32;
|
||||
crc32 = __ini_createCrc32 (heading, (ini->flags & INI_CASE) != 0);
|
||||
|
||||
// Search for heading
|
||||
for (current_h = ini->sections[(unsigned char) crc32 & 0x0FF]; current_h; current_h = current_h->pNext_Acc)
|
||||
{
|
||||
if (current_h->crc == crc32)
|
||||
{
|
||||
if (ini->flags & INI_CASE)
|
||||
{
|
||||
if (!strcmp (current_h->heading, heading))
|
||||
break;
|
||||
}
|
||||
else if (!strcasecmp (current_h->heading, heading))
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Search for heading
|
||||
for (current_h = ini->first; current_h; current_h = current_h->pNext)
|
||||
{
|
||||
if (ini->flags & INI_CASE)
|
||||
{
|
||||
if (!strcmp (current_h->heading, heading))
|
||||
break;
|
||||
}
|
||||
else if (!strcasecmp (current_h->heading, heading))
|
||||
break;
|
||||
}
|
||||
#endif // INI_USE_HASH_TABLE
|
||||
|
||||
ini->selected = current_h;
|
||||
return current_h;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : (public) ini_deleteHeading
|
||||
* Parameters : ini - pointer to ini file descriptor
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Equivalent Microsoft write string API call where both data & key are set to NULL.
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_deleteHeading (ini_fd_t fd)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
if (!ini->selected)
|
||||
return -1;
|
||||
// Is file read only?
|
||||
if (ini->mode == INI_READ)
|
||||
return -1;
|
||||
// Can't delete a temporary section
|
||||
if (ini->selected == &(ini->tmpSection))
|
||||
return -1;
|
||||
__ini_deleteHeading (ini);
|
||||
ini->flags |= INI_MODIFIED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : (public) ini_locateHeading
|
||||
* Parameters : fd - pointer to ini file descriptor
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Equivalent Microsoft write string API call where both data & key are set to NULL.
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_locateHeading (ini_fd_t fd, const char *heading)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct section_tag *section;
|
||||
|
||||
if (!heading)
|
||||
return -1;
|
||||
|
||||
section = __ini_locateHeading (ini, heading);
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
// Rev 1.1 - Remove buffered list
|
||||
if (ini->list)
|
||||
{
|
||||
free (ini->list);
|
||||
ini->list = NULL;
|
||||
}
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
|
||||
if (section)
|
||||
{
|
||||
section->selected = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ok no section was found, but maybe the user is wanting to create a
|
||||
// new one so create it temporarily and see what actually happens later
|
||||
{ // Remove old heading
|
||||
section = &(ini->tmpSection);
|
||||
if (section->heading)
|
||||
free (section->heading);
|
||||
|
||||
// Add new heading
|
||||
section->heading = strdup (heading);
|
||||
if (!section->heading)
|
||||
return -1;
|
||||
section->selected = NULL;
|
||||
ini->selected = section;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : (public) ini_currentHeading
|
||||
* Parameters : fd - pointer to ini file descriptor
|
||||
* Returns : NULL for Error and on success pointer to heading
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Returns currently selected heading
|
||||
********************************************************************************************************************/
|
||||
const char * INI_LINKAGE ini_currentHeading (ini_fd_t fd)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct section_tag *section;
|
||||
|
||||
if (!ini)
|
||||
return NULL;
|
||||
section = ini->selected;
|
||||
if (!section)
|
||||
return NULL;
|
||||
return section->heading;
|
||||
}
|
||||
1165
arm9/source/ini.cpp
Normal file
1165
arm9/source/ini.cpp
Normal file
File diff suppressed because it is too large
Load Diff
76
arm9/source/ini.h
Normal file
76
arm9/source/ini.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/***************************************************************************
|
||||
ini.h - Ini database definition
|
||||
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _ini_h_
|
||||
#define _ini_h_
|
||||
|
||||
#define INI_USE_HASH_TABLE
|
||||
|
||||
#include "libini.h"
|
||||
#include "inikeys.h"
|
||||
#include "iniheadings.h"
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
# include "inilist.h"
|
||||
#endif
|
||||
|
||||
typedef enum {INI_NEW, INI_EXIST, INI_READ} ini_mode_t;
|
||||
|
||||
enum
|
||||
{
|
||||
INI_NONE = 0,
|
||||
INI_MODIFIED = 1 << 0,
|
||||
INI_NEWFILE = 1 << 1,
|
||||
INI_BACKUP = 1 << 2, // Create backup file
|
||||
INI_CASE = 1 << 3 // Case sensitive
|
||||
};
|
||||
|
||||
// Database containing all information about an ini file.
|
||||
typedef struct ini_t
|
||||
{
|
||||
char *filename;
|
||||
FILE *ftmp; // Temporary work file
|
||||
ini_mode_t mode; // Access mode
|
||||
int flags;
|
||||
|
||||
struct section_tag *first;
|
||||
struct section_tag *last;
|
||||
struct section_tag *selected;
|
||||
char *heading; // Last written section in tmp file.
|
||||
struct section_tag tmpSection;
|
||||
struct key_tag tmpKey;
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
struct section_tag *sections[256];
|
||||
#endif
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
// Rev 1.1 Added - New for list accessing
|
||||
char *list; // Accelerator for accessing same list (When all list read, will be freed)
|
||||
char *listDelims; // list sperators
|
||||
char *listIndexPtr; // current element we wish to access (will auto increment)
|
||||
unsigned int listLength;
|
||||
unsigned int listIndex;
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
} ini_t;
|
||||
|
||||
static void __ini_strtrim (char *str);
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
static unsigned long __ini_createCrc32 (const char *str, bool strcase);
|
||||
#endif
|
||||
|
||||
#endif // _ini_h_
|
||||
59
arm9/source/iniconfig.h
Normal file
59
arm9/source/iniconfig.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* include/config.h. Generated by configure. */
|
||||
/* include/config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define if you have the strcasecmp function. */
|
||||
#define HAVE_STRCASECMP
|
||||
|
||||
/* Define if you have the <strings.h> header file. */
|
||||
//#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "libini"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION ""
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.1.10"
|
||||
55
arm9/source/iniheadings.h
Normal file
55
arm9/source/iniheadings.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/***************************************************************************
|
||||
headings.h - Section Heading Manipulation Functions
|
||||
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _headings_h_
|
||||
#define _headings_h_
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ini.h"
|
||||
|
||||
//*******************************************************************************************************************
|
||||
// Data structure definitions
|
||||
//*******************************************************************************************************************
|
||||
struct keys_tag;
|
||||
struct ini_t;
|
||||
|
||||
// Linked list structure for holding section/heading information.
|
||||
struct section_tag
|
||||
{
|
||||
char *heading;
|
||||
struct key_tag *first;
|
||||
struct key_tag *last;
|
||||
struct key_tag *selected;
|
||||
struct section_tag *pNext;
|
||||
struct section_tag *pPrev;
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
unsigned long crc;
|
||||
struct key_tag *keys[256];
|
||||
struct section_tag *pNext_Acc;
|
||||
struct section_tag *pPrev_Acc;
|
||||
#endif // INI_USE_HASH_TABLE
|
||||
};
|
||||
|
||||
static struct section_tag *__ini_addHeading (struct ini_t *ini, char *heading);
|
||||
static struct section_tag *__ini_faddHeading (struct ini_t *ini, FILE *file, long pos, size_t length);
|
||||
static struct section_tag *__ini_createHeading (struct ini_t *ini, char *heading);
|
||||
static void __ini_deleteHeading (struct ini_t *ini);
|
||||
static struct section_tag *__ini_locateHeading (struct ini_t *ini, const char *heading);
|
||||
|
||||
#endif // _headings_h_
|
||||
54
arm9/source/inikeys.h
Normal file
54
arm9/source/inikeys.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/***************************************************************************
|
||||
keys.h - Key Manipulation Functions
|
||||
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _keys_h_
|
||||
#define _keys_h_
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ini.h"
|
||||
|
||||
//*******************************************************************************************************************
|
||||
// Data structure definitions
|
||||
//*******************************************************************************************************************
|
||||
struct ini_t;
|
||||
struct section_tag;
|
||||
|
||||
// Linked list structure for holding key information.
|
||||
struct key_tag
|
||||
{
|
||||
char *key;
|
||||
long pos;
|
||||
size_t length;
|
||||
struct key_tag *pNext;
|
||||
struct key_tag *pPrev;
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
unsigned long crc;
|
||||
struct key_tag *pNext_Acc;
|
||||
struct key_tag *pPrev_Acc;
|
||||
#endif // INI_USE_HASH_TABLE
|
||||
};
|
||||
|
||||
static struct key_tag *__ini_addKey (struct ini_t *ini, char *key);
|
||||
static struct key_tag *__ini_faddKey (struct ini_t *ini, FILE *file, long pos, size_t length);
|
||||
static struct key_tag *__ini_createKey (struct ini_t *ini, char *key);
|
||||
static void __ini_deleteKey (struct ini_t *ini);
|
||||
static struct key_tag *__ini_locateKey (struct ini_t *ini, const char *key);
|
||||
static size_t __ini_averageLengthKey (struct section_tag *current_h);
|
||||
|
||||
#endif // _keys_h_
|
||||
32
arm9/source/inilist.h
Normal file
32
arm9/source/inilist.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/***************************************************************************
|
||||
list.h - Adds list support to ini files
|
||||
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _list_h_
|
||||
#define _list_h_
|
||||
|
||||
#include "ini.h"
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
|
||||
struct ini_t;
|
||||
static int __ini_listEval (struct ini_t *ini);
|
||||
static char *__ini_listRead (struct ini_t *ini);
|
||||
static int __ini_listIndexLength (struct ini_t *ini);
|
||||
static int __ini_listDelims (struct ini_t *ini, const char *delims);
|
||||
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
#endif // _list_h_
|
||||
438
arm9/source/keys.i
Normal file
438
arm9/source/keys.i
Normal file
@@ -0,0 +1,438 @@
|
||||
/***************************************************************************
|
||||
keys.i - Key Manipulation Functions
|
||||
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "inikeys.h"
|
||||
|
||||
#define INI_EQUALS_ALIGN 10
|
||||
|
||||
#if defined(HAVE_STRINGS_H)
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
# define strcasecmp stricmp
|
||||
#endif
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_addKey
|
||||
* Parameters : ini - pointer to ini file database. key - key name
|
||||
* Returns : Pointer to key.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Adds a new key to the ini file database and updates the temporary workfile.
|
||||
* : A heading operation must be called before this function.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
struct key_tag *__ini_addKey (ini_t *ini, char *key)
|
||||
{
|
||||
struct key_tag *_key;
|
||||
size_t length;
|
||||
long pos;
|
||||
|
||||
// Format heading for storing
|
||||
__ini_strtrim (key);
|
||||
if (!*key)
|
||||
return NULL;
|
||||
|
||||
// Add new key to work file and read it in
|
||||
// using file add
|
||||
fseek (ini->ftmp, 0, SEEK_END);
|
||||
pos = ftell (ini->ftmp);
|
||||
fputs (key, ini->ftmp);
|
||||
length = (size_t) (ftell (ini->ftmp) - pos);
|
||||
_key = __ini_faddKey (ini, ini->ftmp, pos, length);
|
||||
fseek (ini->ftmp, 0, SEEK_END);
|
||||
fputc ('=', ini->ftmp);
|
||||
if (_key)
|
||||
ini->flags |= INI_MODIFIED;
|
||||
return _key;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_averageLengthKey
|
||||
* Parameters : current_h - pointer to current header.
|
||||
* Returns : Returns the average key length
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Finds average key length for aligning equals.
|
||||
********************************************************************************************************************/
|
||||
size_t __ini_averageLengthKey (struct section_tag *current_h)
|
||||
{
|
||||
#ifdef INI_EQUALS_ALIGN
|
||||
size_t equal_pos, equal_max, keylength;
|
||||
size_t average = 0, count = 0;
|
||||
struct key_tag *current_k;
|
||||
|
||||
// Rev 1.1 Added - Line up equals characters for keys
|
||||
// Calculate Average
|
||||
current_k = current_h->first;
|
||||
while (current_k)
|
||||
{
|
||||
count++;
|
||||
average += strlen (current_k->key);
|
||||
current_k = current_k->pNext;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
average /= count;
|
||||
equal_pos = (equal_max = average);
|
||||
|
||||
#if INI_EQUALS_ALIGN > 0
|
||||
// Work out the longest key in that range
|
||||
current_k = current_h->first;
|
||||
while (current_k)
|
||||
{
|
||||
keylength = strlen (current_k->key);
|
||||
equal_max = average + INI_EQUALS_ALIGN;
|
||||
|
||||
if ((equal_max > keylength) && (keylength > equal_pos))
|
||||
equal_pos = keylength;
|
||||
current_k = current_k->pNext;
|
||||
}
|
||||
#endif // INI_EQUALS_ALIGN > 0
|
||||
return equal_pos;
|
||||
#else
|
||||
return 0;
|
||||
#endif // INI_EQUALS_ALIGN
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_faddKey
|
||||
* Parameters : ini - pointer to ini file database, file - ini file to read key from
|
||||
* : pos - key position in file, length - key length
|
||||
* Returns : Pointer to key.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Adds a new key to the ini file database from the input file.
|
||||
* : A heading operation must be called before this function.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
struct key_tag *__ini_faddKey (ini_t *ini, FILE *file, long pos, size_t length)
|
||||
{
|
||||
struct key_tag *_key;
|
||||
char *str;
|
||||
|
||||
length++;
|
||||
str = (char *) malloc (sizeof(char) * length);
|
||||
assert (str);
|
||||
fseek (file, pos, SEEK_SET);
|
||||
fgets (str, (int) length, file);
|
||||
__ini_strtrim (str);
|
||||
|
||||
_key = __ini_createKey (ini, str);
|
||||
if (!_key)
|
||||
{ free (str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_key->pos = pos + (long) length;
|
||||
return _key;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_createKey
|
||||
* Parameters : ini - pointer to ini file database. key - key name
|
||||
* Returns : Pointer to key.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Adds an entry into the key linked list ready for formating by the addKey commands
|
||||
* : A heading operation must be called before this function.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
struct key_tag *__ini_createKey (ini_t *ini, char *key)
|
||||
{
|
||||
struct section_tag *section;
|
||||
struct key_tag *pNew;
|
||||
long pos;
|
||||
|
||||
if (!*key)
|
||||
return NULL;
|
||||
|
||||
section = ini->selected;
|
||||
pNew = __ini_locateKey (ini, key);
|
||||
if (pNew)
|
||||
{ // Reset details of existing key
|
||||
free (pNew->key);
|
||||
pNew->key = key;
|
||||
pos = 0;
|
||||
}
|
||||
else
|
||||
{ // Create a new key and add at end;
|
||||
pNew = (struct key_tag *) malloc (sizeof (struct key_tag));
|
||||
if (!pNew)
|
||||
return NULL;
|
||||
memset (pNew, 0, sizeof (struct key_tag));
|
||||
pNew->key = key;
|
||||
|
||||
if (!section->first)
|
||||
section->first = pNew;
|
||||
else
|
||||
section->last->pNext = pNew;
|
||||
|
||||
pNew->pPrev = section->last;
|
||||
section->last = pNew;
|
||||
section->selected = pNew;
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
{ // Rev 1.3 - Added
|
||||
struct key_tag *pOld;
|
||||
unsigned long crc32;
|
||||
unsigned char accel;
|
||||
|
||||
crc32 = __ini_createCrc32 (key, (ini->flags & INI_CASE) != 0);
|
||||
pNew->crc = crc32;
|
||||
// Rev 1.3 - Add accelerator list
|
||||
accel = (unsigned char) crc32 & 0x0FF;
|
||||
pNew->pPrev_Acc = NULL;
|
||||
pOld = section->keys[accel];
|
||||
section->keys[accel] = pNew;
|
||||
if (pOld) pOld->pPrev_Acc = pNew;
|
||||
pNew->pNext_Acc = pOld;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
section->selected = pNew;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_deleteKey
|
||||
* Parameters : ini - pointer to ini file database. key - key name
|
||||
* Returns :
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Removes a key from the database only.
|
||||
* : This change does not occur in the file until ini_close is called.
|
||||
* : A heading operation must be called before this function.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
void __ini_deleteKey (ini_t *ini)
|
||||
{
|
||||
struct key_tag *current_k;
|
||||
struct section_tag *section = ini->selected;
|
||||
|
||||
current_k = section->selected;
|
||||
if (current_k)
|
||||
{
|
||||
// Tidy up all users of this key
|
||||
section->selected = NULL;
|
||||
if (section->last == current_k)
|
||||
section->last = current_k->pPrev;
|
||||
|
||||
// Check to see if all keys were removed
|
||||
if (!current_k->pPrev)
|
||||
section->first = current_k->pNext;
|
||||
else
|
||||
current_k->pPrev->pNext = current_k->pNext;
|
||||
if (current_k->pNext)
|
||||
current_k->pNext->pPrev = current_k->pPrev;
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
// Rev 1.3 - Take member out of accelerator list
|
||||
if (!current_k->pPrev_Acc)
|
||||
section->keys[(unsigned char) current_k->crc & 0x0FF] = current_k->pNext_Acc;
|
||||
else
|
||||
current_k->pPrev_Acc->pNext_Acc = current_k->pNext_Acc;
|
||||
if (current_k->pNext_Acc)
|
||||
current_k->pNext_Acc->pPrev_Acc = current_k->pPrev_Acc;
|
||||
#endif // INI_USE_HASH_TABLE
|
||||
|
||||
// Delete Key
|
||||
free (current_k->key);
|
||||
free (current_k);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_locateKey
|
||||
* Parameters : ini - pointer to ini file database. key - key name
|
||||
* Returns : Pointer to key.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Locates a key entry in the database.
|
||||
* : A heading operation must be called before this function.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
struct key_tag *__ini_locateKey (ini_t *ini, const char *key)
|
||||
{
|
||||
struct key_tag *current_k;
|
||||
struct section_tag *section;
|
||||
section = ini->selected;
|
||||
|
||||
#ifdef INI_USE_HASH_TABLE
|
||||
{ // Rev 1.3 - Added
|
||||
unsigned long crc32;
|
||||
crc32 = __ini_createCrc32 (key, (ini->flags & INI_CASE) != 0);
|
||||
|
||||
// Search for key
|
||||
for (current_k = section->keys[(unsigned char) crc32 & 0x0FF]; current_k; current_k = current_k->pNext_Acc)
|
||||
{
|
||||
if (current_k->crc == crc32)
|
||||
{
|
||||
if (ini->flags & INI_CASE)
|
||||
{
|
||||
if (!strcmp (current_k->key, key))
|
||||
break;
|
||||
}
|
||||
else if (!strcasecmp (current_k->key, key))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
{ // Search for key
|
||||
for (current_k = section->first; current_k; current_k = current_k->pNext)
|
||||
{
|
||||
if (ini->flags & INI_CASE)
|
||||
{
|
||||
if (!strcmp (current_k->key, key))
|
||||
break;
|
||||
}
|
||||
else if (!strcasecmp (current_k->key, key))
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // INI_USE_HASH_TABLE
|
||||
|
||||
section->selected = current_k;
|
||||
return current_k;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : (public) ini_deleteKey
|
||||
* Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Equivalent Microsoft write string API call where data set to NULL
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_deleteKey (ini_fd_t fd)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
if (!ini->selected || !ini->selected->selected)
|
||||
return -1;
|
||||
// Can't delete a temporary key
|
||||
if (ini->selected->selected == &(ini->tmpKey))
|
||||
return -1;
|
||||
// Is file read only?
|
||||
if (ini->mode == INI_READ)
|
||||
return -1;
|
||||
__ini_deleteKey (ini);
|
||||
ini->flags |= INI_MODIFIED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : (public) ini_locateKey
|
||||
* Parameters : fd - pointer to ini file descriptor
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description :
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_locateKey (ini_fd_t fd, const char *key)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct key_tag *_key = NULL;
|
||||
|
||||
if (!key)
|
||||
return -1;
|
||||
if (!ini->selected)
|
||||
return -1;
|
||||
|
||||
// Can't search for a key in a temporary heading
|
||||
if (ini->selected != &(ini->tmpSection))
|
||||
_key = __ini_locateKey (ini, key);
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
// Rev 1.1 - Remove buffered list
|
||||
if (ini->list)
|
||||
{
|
||||
free (ini->list);
|
||||
ini->list = NULL;
|
||||
}
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
|
||||
if (_key)
|
||||
return 0;
|
||||
|
||||
// Ok no key was found, but maybe the user is wanting to create a
|
||||
// new one so create it temporarily and see what actually happens later
|
||||
{ // Remove all key
|
||||
_key = &(ini->tmpKey);
|
||||
if (_key->key)
|
||||
free (_key->key);
|
||||
|
||||
// Add new key
|
||||
_key->key = strdup (key);
|
||||
if (!_key)
|
||||
return -1;
|
||||
ini->selected->selected = _key;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : (public) ini_currentKey
|
||||
* Parameters : fd - pointer to ini file descriptor
|
||||
* Returns : NULL for Error and on success pointer to key
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description :
|
||||
********************************************************************************************************************/
|
||||
const char * INI_LINKAGE ini_currentKey (ini_fd_t fd)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct section_tag *section;
|
||||
struct key_tag *key;
|
||||
|
||||
if (!ini)
|
||||
return NULL;
|
||||
section = ini->selected;
|
||||
if (!section)
|
||||
return NULL;
|
||||
key = section->selected;
|
||||
if (!key)
|
||||
return NULL;
|
||||
return key->key;
|
||||
}
|
||||
219
arm9/source/libini.h
Normal file
219
arm9/source/libini.h
Normal file
@@ -0,0 +1,219 @@
|
||||
/***************************************************************************
|
||||
libini.h - Header file of functions to
|
||||
manipulate an ini file.
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _libini_h_
|
||||
#define _libini_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define INI_ADD_EXTRAS
|
||||
#define INI_ADD_LIST_SUPPORT
|
||||
|
||||
#ifdef SWIG
|
||||
%ignore ini_readString;
|
||||
%include typemaps.i
|
||||
%apply int *INOUT { int *value };
|
||||
%apply long *INOUT { long *value };
|
||||
%apply double *INOUT { double *value };
|
||||
%rename (ini_readString) ini_readFileToBuffer;
|
||||
#define INI_EXTERN
|
||||
#define INI_STATIC
|
||||
#endif /* SWIG */
|
||||
|
||||
#ifdef _WINDOWS
|
||||
# define INI_LINKAGE __stdcall
|
||||
#else
|
||||
# define INI_LINKAGE
|
||||
#endif
|
||||
|
||||
/* DLL building support on win32 hosts */
|
||||
#ifndef INI_EXTERN
|
||||
# ifdef DLL_EXPORT /* defined by libtool (if required) */
|
||||
# define INI_EXTERN __declspec(dllexport)
|
||||
# endif
|
||||
# ifdef LIBINI_DLL_IMPORT /* define if linking with this dll */
|
||||
# define INI_EXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# ifndef INI_EXTERN /* static linking or !_WIN32 */
|
||||
# define INI_EXTERN extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef INI_ADD_EXTRAS
|
||||
#undef INI_ADD_LIST_SUPPORT
|
||||
#endif
|
||||
|
||||
/* Compatibility with future C++ code */
|
||||
#ifndef ini_fd_t
|
||||
#define ini_fd_t ini_fd_t
|
||||
typedef void* ini_fd_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* Rev 1.2 Added new fuction */
|
||||
INI_EXTERN ini_fd_t INI_LINKAGE ini_open (const char *name, const char *mode,
|
||||
const char *comment);
|
||||
INI_EXTERN int INI_LINKAGE ini_close (ini_fd_t fd);
|
||||
INI_EXTERN int INI_LINKAGE ini_flush (ini_fd_t fd);
|
||||
INI_EXTERN int INI_LINKAGE ini_delete (ini_fd_t fd);
|
||||
|
||||
/* Rev 1.2 Added these functions to make life a bit easier, can still be implemented
|
||||
* through ini_writeString though. */
|
||||
INI_EXTERN int INI_LINKAGE ini_locateKey (ini_fd_t fd, const char *key);
|
||||
INI_EXTERN int INI_LINKAGE ini_locateHeading (ini_fd_t fd, const char *heading);
|
||||
INI_EXTERN int INI_LINKAGE ini_deleteKey (ini_fd_t fd);
|
||||
INI_EXTERN int INI_LINKAGE ini_deleteHeading (ini_fd_t fd);
|
||||
|
||||
INI_EXTERN const char * INI_LINKAGE ini_currentKey (ini_fd_t fd);
|
||||
INI_EXTERN const char * INI_LINKAGE ini_currentHeading (ini_fd_t fd);
|
||||
|
||||
/* Returns the number of bytes required to be able to read the key as a
|
||||
* string from the file. (1 should be added to this length to account
|
||||
* for a NULL character). If delimiters are used, returns the length
|
||||
* of the next data element in the key to be read */
|
||||
INI_EXTERN int INI_LINKAGE ini_dataLength (ini_fd_t fd);
|
||||
|
||||
/* Default Data Type Operations
|
||||
* Arrays implemented to help with reading, for writing you should format the
|
||||
* complete array as a string and perform an ini_writeString. */
|
||||
INI_EXTERN int INI_LINKAGE ini_readString (ini_fd_t fd, char *str, size_t size);
|
||||
INI_EXTERN int INI_LINKAGE ini_writeString (ini_fd_t fd, const char *str);
|
||||
INI_EXTERN int INI_LINKAGE ini_readInt (ini_fd_t fd, int *value);
|
||||
|
||||
|
||||
#ifdef INI_ADD_EXTRAS
|
||||
/* Read Operations */
|
||||
INI_EXTERN int INI_LINKAGE ini_readLong (ini_fd_t fd, long *value);
|
||||
INI_EXTERN int INI_LINKAGE ini_readDouble (ini_fd_t fd, double *value);
|
||||
INI_EXTERN int INI_LINKAGE ini_readBool (ini_fd_t fd, int *value);
|
||||
|
||||
/* Write Operations */
|
||||
INI_EXTERN int INI_LINKAGE ini_writeInt (ini_fd_t fd, int value);
|
||||
INI_EXTERN int INI_LINKAGE ini_writeLong (ini_fd_t fd, long value);
|
||||
INI_EXTERN int INI_LINKAGE ini_writeDouble (ini_fd_t fd, double value);
|
||||
INI_EXTERN int INI_LINKAGE ini_writeBool (ini_fd_t fd, int value);
|
||||
|
||||
/* Extra Functions */
|
||||
INI_EXTERN int INI_LINKAGE ini_append (ini_fd_t fddst, ini_fd_t fdsrc);
|
||||
#endif /* INI_ADD_EXTRAS */
|
||||
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
/* Rev 1.1 Added - List Operations (Used for read operations only)
|
||||
* Be warned, once delimiters are set, every key that is read will be checked for the
|
||||
* presence of sub strings. This will incure a speed hit and therefore once a line
|
||||
* has been read and list/array functionality is not required, set delimiters
|
||||
* back to NULL.
|
||||
*/
|
||||
|
||||
/* Returns the number of elements in an list being seperated by the provided delimiters */
|
||||
INI_EXTERN int INI_LINKAGE ini_listLength (ini_fd_t fd);
|
||||
/* Change delimiters, default "" */
|
||||
INI_EXTERN int INI_LINKAGE ini_listDelims (ini_fd_t fd, const char *delims);
|
||||
/* Set index to access in a list. When read the index will automatically increment */
|
||||
INI_EXTERN int INI_LINKAGE ini_listIndex (ini_fd_t fd, unsigned long index);
|
||||
#endif /* INI_ADD_LIST_SUPPORT */
|
||||
|
||||
|
||||
#ifdef SWIG
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include <libini.h>
|
||||
#define INI_STATIC static
|
||||
typedef struct
|
||||
{
|
||||
char *buffer;
|
||||
size_t size;
|
||||
} ini_buffer_t;
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
/*************************************************************
|
||||
* SWIG helper functions to create C compatible string buffers
|
||||
*************************************************************/
|
||||
INI_STATIC ini_buffer_t *ini_createBuffer (unsigned int size)
|
||||
{
|
||||
ini_buffer_t *b;
|
||||
/* Allocate memory to structure */
|
||||
if (size == ( ((unsigned) -1 << 1) >> 1 ))
|
||||
return 0; /* Size is too big */
|
||||
b = malloc (sizeof (ini_buffer_t));
|
||||
if (!b)
|
||||
return 0;
|
||||
|
||||
/* Allocate memory to buffer */
|
||||
b->buffer = malloc (sizeof (char) * (size + 1));
|
||||
if (!b->buffer)
|
||||
{
|
||||
free (b);
|
||||
return 0;
|
||||
}
|
||||
b->size = size;
|
||||
b->buffer[0] = '\0';
|
||||
|
||||
/* Returns address to tcl */
|
||||
return b;
|
||||
}
|
||||
|
||||
INI_STATIC void ini_deleteBuffer (ini_buffer_t *buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return;
|
||||
free (buffer->buffer);
|
||||
free (buffer);
|
||||
}
|
||||
|
||||
INI_STATIC int ini_readFileToBuffer (ini_fd_t fd, ini_buffer_t *buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return -1;
|
||||
return ini_readString (fd, buffer->buffer, buffer->size + 1);
|
||||
}
|
||||
|
||||
INI_STATIC char *ini_getBuffer (ini_buffer_t *buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return "";
|
||||
return buffer->buffer;
|
||||
}
|
||||
|
||||
INI_STATIC int ini_setBuffer (ini_buffer_t *buffer, const char *str)
|
||||
{
|
||||
size_t len;
|
||||
if (!buffer)
|
||||
return -1;
|
||||
len = strlen (str);
|
||||
if (len > buffer->size)
|
||||
len = buffer->size;
|
||||
|
||||
memcpy (buffer->buffer, str, len);
|
||||
buffer->buffer[len] = '\0';
|
||||
return len;
|
||||
}
|
||||
%}
|
||||
#endif /* SWIG */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _libini_h_ */
|
||||
332
arm9/source/list.i
Normal file
332
arm9/source/list.i
Normal file
@@ -0,0 +1,332 @@
|
||||
/***************************************************************************
|
||||
list.i - Adds list support to ini files
|
||||
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "inilist.h"
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_listEval
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* Returns : -1 for Error or the numbers of list items found
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Uses the currently specified delimiters to calculate the number of eliments in a list
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int __ini_listEval (ini_t *ini)
|
||||
{
|
||||
int length, count, i, ret;
|
||||
int ldelim;
|
||||
char ch;
|
||||
|
||||
// Remove old list
|
||||
if (ini->list)
|
||||
{
|
||||
free (ini->list);
|
||||
ini->list = NULL;
|
||||
}
|
||||
|
||||
// Re-evaluate with new settings
|
||||
length = ini->selected->selected->length;
|
||||
if (length < 0)
|
||||
return -1;
|
||||
if (!length)
|
||||
{
|
||||
ini->listIndex = 0;
|
||||
ini->listLength = 0;
|
||||
if (ini->selected->selected == &ini->tmpKey)
|
||||
return -1; // Can't read tmpKey
|
||||
return 0;
|
||||
}
|
||||
|
||||
// See if there are any chars which can be used to split the string into sub ones
|
||||
if (!ini->listDelims)
|
||||
return -1;
|
||||
ldelim = (int) strlen (ini->listDelims);
|
||||
|
||||
// Buffer string for faster access
|
||||
ini->list = (char *) malloc (length + 1);
|
||||
if (!ini->list)
|
||||
return -1;
|
||||
|
||||
{ // Backup up delims to avoid causing problems with readString
|
||||
char *delims = ini->listDelims;
|
||||
ini->listDelims = NULL;
|
||||
ret = ini_readString ((ini_fd_t) ini, ini->list, length + 1);
|
||||
ini->listDelims = delims;
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Process buffer string to find number of sub strings
|
||||
{
|
||||
char lastch = '\0';
|
||||
count = 1;
|
||||
while (length)
|
||||
{
|
||||
length--;
|
||||
ch = ini->list[length];
|
||||
for (i = 0; i < ldelim; i++)
|
||||
{
|
||||
if ((char) ch == ini->listDelims[i])
|
||||
{ // Prevent lots of NULL strings on multiple
|
||||
// whitespace
|
||||
if (lastch == '\0')
|
||||
{
|
||||
if (isspace (ch))
|
||||
{
|
||||
ch = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Seperate strings
|
||||
ini->list[length] = (ch = '\0');
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastch = ch;
|
||||
}
|
||||
}
|
||||
|
||||
ini->listLength = count;
|
||||
ini->listIndexPtr = ini->list;
|
||||
ini->listIndex = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_listRead
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* Returns : NULL for error, string point otherwise
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Reads the indexed parameter from the list and auto
|
||||
* : increments
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
char *__ini_listRead (ini_t *ini)
|
||||
{
|
||||
char *p;
|
||||
|
||||
// we must read an element from the list
|
||||
// Rev 1.2 Changed order of these two ifs as test was performed
|
||||
// sometimes before anything was read
|
||||
if (!ini->list)
|
||||
{
|
||||
if (__ini_listEval (ini) < 0)
|
||||
return NULL;
|
||||
// Handle an empty list
|
||||
if (!ini->listLength)
|
||||
return "";
|
||||
}
|
||||
|
||||
// Check to see if we are trying to get a value beyond the end of the list
|
||||
if (ini->listIndex >= ini->listLength)
|
||||
return NULL;
|
||||
p = ini->listIndexPtr;
|
||||
// Auto increment pointers to next index
|
||||
ini->listIndexPtr += (strlen (ini->listIndexPtr) + 1);
|
||||
ini->listIndex++;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_listLength
|
||||
* Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
|
||||
* Returns : -1 for Error or the numbers of list items found
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Uses the currently specified delimiters to calculate the number of eliments in a list
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_listLength (ini_fd_t fd)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
|
||||
// Check to make sure a section/key has
|
||||
// been asked for by the user
|
||||
if (!ini->selected)
|
||||
return -1;
|
||||
if (!ini->selected->selected)
|
||||
return -1;
|
||||
|
||||
// Check to see if we have moved to a new key
|
||||
if (!ini->list)
|
||||
return __ini_listEval (ini);
|
||||
|
||||
return ini->listLength;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_listDelims
|
||||
* Parameters : ini - pointer to ini file database. delims - string of delimitor chars
|
||||
* Returns : -1 for Error or 0 for success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Sets the delimiters used for list accessing, (default delim is NULL)
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int __ini_listDelims (struct ini_t *ini, const char *delims)
|
||||
{
|
||||
if (ini->listDelims)
|
||||
free (ini->listDelims);
|
||||
ini->listDelims = NULL;
|
||||
|
||||
// Make sure we have something to copy
|
||||
if (delims)
|
||||
{
|
||||
if (*delims)
|
||||
{ // Store delims for later use
|
||||
ini->listDelims = strdup (delims);
|
||||
if (!ini->listDelims)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// List will need recalculating at some point
|
||||
if (ini->list)
|
||||
{
|
||||
free (ini->list);
|
||||
ini->list = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_listDelims
|
||||
* Parameters : fd - pointer to ini file database. delims - string of delimitor chars
|
||||
* Returns : -1 for Error or 0 for success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Sets the delimiters used for list accessing, (default delim is NULL)
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_listDelims (ini_fd_t fd, const char *delims)
|
||||
{
|
||||
return __ini_listDelims ((ini_t *) fd, delims);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_listIndex
|
||||
* Parameters : ini - pointer to ini file database. delims - string of delimitor chars
|
||||
* Returns :
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Sets the index that the next call to any of the read function will obtain (default 0)
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_listIndex (ini_fd_t fd, unsigned long index)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
unsigned int count;
|
||||
char *p;
|
||||
|
||||
// Check to make sure a section/key has
|
||||
// been asked for by the user
|
||||
if (!ini->selected)
|
||||
return -1;
|
||||
if (!ini->selected->selected)
|
||||
return -1;
|
||||
|
||||
// Pull in new list
|
||||
if (!ini->list)
|
||||
{
|
||||
if (__ini_listEval (ini) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now scroll through to required index
|
||||
if (!ini->listLength)
|
||||
return -1;
|
||||
if (index == ini->listIndex)
|
||||
return 0;
|
||||
|
||||
if (index > ini->listIndex)
|
||||
{ // Continue search from the from current position
|
||||
count = ini->listIndex;
|
||||
p = ini->listIndexPtr;
|
||||
}
|
||||
else
|
||||
{ // Reset list and search from beginning
|
||||
count = 0;
|
||||
p = ini->list;
|
||||
}
|
||||
|
||||
while (count != index)
|
||||
{
|
||||
count++;
|
||||
if (count >= ini->listLength)
|
||||
return -1;
|
||||
// Jump to next sub string
|
||||
p += (strlen (p) + 1);
|
||||
}
|
||||
|
||||
ini->listIndex = count;
|
||||
ini->listIndexPtr = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_listIndexLength
|
||||
* Parameters : ini - pointer to ini file database
|
||||
* Returns :
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Returns the length the indexed sub string
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int __ini_listIndexLength (ini_t *ini)
|
||||
{
|
||||
if (!ini->list)
|
||||
{ // No list yet. So try to get one
|
||||
if (__ini_listEval (ini) < 0)
|
||||
return -1;
|
||||
if (!ini->listLength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Now return length
|
||||
return strlen (ini->listIndexPtr);
|
||||
}
|
||||
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
@@ -42,13 +42,22 @@
|
||||
#include "hardware.h"
|
||||
#include "fileselect.h"
|
||||
|
||||
#include "libini.h"
|
||||
|
||||
|
||||
|
||||
uint32 ezflash = 0;
|
||||
uint32 dstype = 0;
|
||||
bool gba = 0;
|
||||
uint32 mode = 0;
|
||||
bool slot2 = false;
|
||||
|
||||
char ftp_ip[16] = "ftp_ip";
|
||||
char ftp_user[64] = "ftp_user";
|
||||
char ftp_pass[64] = "ftp_pass";
|
||||
int ftp_port = 0;
|
||||
|
||||
char bootdir[256] = "/";
|
||||
|
||||
|
||||
// ============================================================================
|
||||
@@ -59,9 +68,45 @@ void mode_dsi()
|
||||
while (1);
|
||||
}
|
||||
|
||||
void mode_slot2()
|
||||
{
|
||||
// use slot2 DLDI device to store data
|
||||
displayPrintState("");
|
||||
displayPrintUpper();
|
||||
displayPrintLower();
|
||||
|
||||
displayMessage("This mode is DISABLED.\nPlease remove Slot-2 module\nand restart this tool.");
|
||||
while(1);
|
||||
|
||||
touchPosition touchXY;
|
||||
while(1) {
|
||||
swiWaitForVBlank();
|
||||
touchRead(&touchXY);
|
||||
|
||||
// backup
|
||||
if ((touchXY.py > 8*0) && (touchXY.py < 8*8)) {
|
||||
//displayPrintUpper();
|
||||
//hwBackupGBA();
|
||||
}
|
||||
|
||||
// restore
|
||||
if ((touchXY.py > 8*8) && (touchXY.py < 8*16)) {
|
||||
//displayPrintUpper();
|
||||
//hwRestoreGBA();
|
||||
}
|
||||
|
||||
// erase
|
||||
if ((touchXY.py > 8*16) && (touchXY.py < 8*24)) {
|
||||
//displayPrintUpper();
|
||||
//hwEraseGBA();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mode_3in1()
|
||||
{
|
||||
displayPrintUpper();
|
||||
displayPrintLower();
|
||||
|
||||
dsCardData data2;
|
||||
ReadSram(0x0a000000, (u8*)&data2, sizeof(data2));
|
||||
@@ -83,11 +128,6 @@ void mode_3in1()
|
||||
hwRestore3in1_b(size);
|
||||
}
|
||||
|
||||
// use 3in1 to buffer data
|
||||
displayPrintState("3in1 mode");
|
||||
displayPrintUpper();
|
||||
displayPrintLower();
|
||||
|
||||
touchPosition touchXY;
|
||||
while(1) {
|
||||
swiWaitForVBlank();
|
||||
@@ -117,7 +157,44 @@ void mode_3in1()
|
||||
void mode_gba()
|
||||
{
|
||||
// use 3in1 to buffer data
|
||||
displayPrintState("gba mode");
|
||||
displayPrintState("");
|
||||
displayPrintUpper();
|
||||
displayPrintLower();
|
||||
|
||||
displayMessage("This mode is DISABLED.\nPlease remove Slot-2 module\nand restart this tool.");
|
||||
while(1);
|
||||
|
||||
touchPosition touchXY;
|
||||
while(1) {
|
||||
swiWaitForVBlank();
|
||||
touchRead(&touchXY);
|
||||
|
||||
// backup
|
||||
if ((touchXY.py > 8*0) && (touchXY.py < 8*8)) {
|
||||
//displayPrintUpper();
|
||||
//hwBackupGBA();
|
||||
}
|
||||
|
||||
// restore
|
||||
if ((touchXY.py > 8*8) && (touchXY.py < 8*16)) {
|
||||
//displayPrintUpper();
|
||||
//hwRestoreGBA();
|
||||
}
|
||||
|
||||
// erase
|
||||
if ((touchXY.py > 8*16) && (touchXY.py < 8*24)) {
|
||||
//displayPrintUpper();
|
||||
//hwEraseGBA();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mode_wifi()
|
||||
{
|
||||
displayPrintUpper();
|
||||
|
||||
// use 3in1 to buffer data
|
||||
displayPrintState("");
|
||||
displayPrintUpper();
|
||||
displayPrintLower();
|
||||
|
||||
@@ -128,33 +205,24 @@ void mode_gba()
|
||||
|
||||
// backup
|
||||
if ((touchXY.py > 8*0) && (touchXY.py < 8*8)) {
|
||||
displayPrintUpper();
|
||||
hwBackupGBA();
|
||||
//hwBackup3in1();
|
||||
hwBackupFTP();
|
||||
}
|
||||
|
||||
// restore
|
||||
if ((touchXY.py > 8*8) && (touchXY.py < 8*16)) {
|
||||
displayPrintUpper();
|
||||
hwRestoreGBA();
|
||||
hwRestoreFTP();
|
||||
}
|
||||
|
||||
// erase
|
||||
if ((touchXY.py > 8*16) && (touchXY.py < 8*24)) {
|
||||
swap_cart();
|
||||
displayPrintUpper();
|
||||
hwEraseGBA();
|
||||
hwErase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mode_wifi()
|
||||
{
|
||||
// read/write to ftp server, does nothing at the moment
|
||||
displayPrintState("FTP mode - unsupported!");
|
||||
while (1);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
sysSetBusOwners(true, true);
|
||||
|
||||
@@ -168,20 +236,73 @@ int main(void)
|
||||
while (1) {};
|
||||
}
|
||||
|
||||
// TODO: load ini file...
|
||||
// load ini file...
|
||||
ini_fd_t ini = 0;
|
||||
char inipath[256];
|
||||
if (argv[0]) {
|
||||
char *last = strrchr(argv[0], '/');
|
||||
int len = (last - argv[0])+1;
|
||||
strncpy(bootdir, argv[0], len);
|
||||
sprintf(inipath, "%s/savegame_manager.ini", bootdir);
|
||||
if (fileExists(inipath))
|
||||
ini = ini_open(inipath, "r", "");
|
||||
}
|
||||
if (!ini) {
|
||||
sprintf(inipath, "/savegame_manager.ini");
|
||||
if (fileExists(inipath))
|
||||
ini = ini_open(inipath, "r", "");
|
||||
}
|
||||
if (!ini) {
|
||||
displayMessage("Unable to open ini file!\nPlease make sure that it is\n1. in this apps folder, or"
|
||||
"\n2. in the root folder\nIf 1. does not work, use 2.");
|
||||
while (1);
|
||||
}
|
||||
|
||||
ini_locateHeading(ini, "");
|
||||
ini_locateKey(ini, "ftp_ip");
|
||||
ini_readString(ini, ftp_ip, 16);
|
||||
ini_locateKey(ini, "ftp_user");
|
||||
ini_readString(ini, ftp_user, 64);
|
||||
ini_locateKey(ini, "ftp_pass");
|
||||
ini_readString(ini, ftp_pass, 64);
|
||||
ini_locateKey(ini, "ftp_port");
|
||||
ini_readInt(ini, &ftp_port);
|
||||
ini_close(ini);
|
||||
//displayPrintState(ftp_user);
|
||||
//while (1);
|
||||
|
||||
// Identify hardware and branch to corresponding mode
|
||||
displayPrintState("Identifying hardware...");
|
||||
chip_reset();
|
||||
OpenNorWrite();
|
||||
ezflash = ReadNorFlashID();
|
||||
CloseNorWrite();
|
||||
dstype = 0; // DS/DSL, no idea how to identify DSi etc.
|
||||
gba = gbaIsGame();
|
||||
|
||||
// Try to identify slot-2 device. Try opening slot-2 root directory
|
||||
// Nope, does not work: CyclopsDS mounts itself on fat1, fat2, fat3,... (didn't test more)
|
||||
/*
|
||||
DIR* pdir = opendir("fat2:/");
|
||||
struct dirent *pent;
|
||||
if (pdir) {
|
||||
pent=readdir(pdir);
|
||||
if (pent)
|
||||
//char fullname[256];
|
||||
displayMessage(pent->d_name);
|
||||
//slot2=true;
|
||||
}
|
||||
*/
|
||||
if (argv[0][3] == '2')
|
||||
slot2 = true;
|
||||
|
||||
if (dstype == 1) {
|
||||
// DSi/DSiXL, will branch to SD-card mode when cracked.
|
||||
mode = 3;
|
||||
mode_dsi();
|
||||
} else if (slot2) {
|
||||
mode = 4;
|
||||
mode_slot2();
|
||||
} else if (ezflash != 0) {
|
||||
// DS with EZFlash found -> branch to 3in1 mode
|
||||
mode = 2;
|
||||
|
||||
530
arm9/source/types.i
Normal file
530
arm9/source/types.i
Normal file
@@ -0,0 +1,530 @@
|
||||
/***************************************************************************
|
||||
types.i - Libini supported data types
|
||||
Use readString for others
|
||||
|
||||
-------------------
|
||||
begin : Fri Apr 21 2000
|
||||
copyright : (C) 2000 by Simon White
|
||||
email : s_a_white@email.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ini.h"
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_read
|
||||
* Parameters : ini - pointer to ini file database, size - key length returned here
|
||||
* Returns : -1 for Error and 0 on success.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Common read functionality
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
static int __ini_read (ini_t *ini, size_t *size)
|
||||
{
|
||||
struct key_tag *_key;
|
||||
|
||||
if (!ini->selected)
|
||||
return -1;
|
||||
// Locate and read keys value
|
||||
_key = ini->selected->selected;
|
||||
if (!_key)
|
||||
return -1;
|
||||
|
||||
if (_key->length)
|
||||
{ // Locate and read back keys data
|
||||
fseek (ini->ftmp, _key->pos, SEEK_SET);
|
||||
}
|
||||
else if (_key == &ini->tmpKey)
|
||||
return -1; // Can't read tmpKey
|
||||
*size = _key->length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_readList
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* Returns : Pointer to buffer holding data.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Common read functionality from a list
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
static char *__ini_readList (ini_t *ini)
|
||||
{
|
||||
if (!ini->selected)
|
||||
return NULL;
|
||||
// Locate and read keys value
|
||||
if (!ini->selected->selected)
|
||||
return NULL;
|
||||
return __ini_listRead (ini);
|
||||
}
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : __ini_write
|
||||
* Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
|
||||
* Returns : Pointer to new key.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Make calls to add a new key and appends a description of changes in the backup file
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
static struct key_tag *__ini_write (ini_t *ini)
|
||||
{
|
||||
struct section_tag *section;
|
||||
struct key_tag *key;
|
||||
|
||||
// Is file read only?
|
||||
if (ini->mode == INI_READ)
|
||||
return NULL;
|
||||
|
||||
// Check to make sure a section/key has
|
||||
// been asked for by the user
|
||||
section = ini->selected;
|
||||
if (!section)
|
||||
return NULL;
|
||||
key = section->selected;
|
||||
if (!key)
|
||||
return NULL;
|
||||
|
||||
// Add or replace key
|
||||
if (!__ini_addHeading (ini, section->heading))
|
||||
return NULL;
|
||||
return __ini_addKey (ini, key->key);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_readString
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for error or the number of chars read.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Reads data part from a key and returns it as a string
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_readString (ini_fd_t fd, char *str, size_t size)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
|
||||
// Check size and reserve space for NULL
|
||||
if (size-- <= 0)
|
||||
return -1;
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
if (ini->listDelims)
|
||||
{
|
||||
char *data = __ini_readList (ini);
|
||||
if (!data)
|
||||
return -1;
|
||||
strncpy (str, data, size);
|
||||
}
|
||||
else
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
{ // Locate and read back keys data (Index ignored)
|
||||
// Check to make sure size is correct
|
||||
size_t length;
|
||||
if (__ini_read (ini, &length) < 0)
|
||||
return -1;
|
||||
if (size > length)
|
||||
size = length;
|
||||
size = fread (str, sizeof(char), size, ini->ftmp);
|
||||
}
|
||||
|
||||
str[size] = '\0';
|
||||
__ini_strtrim (str);
|
||||
return (int) size;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_writeString
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Writes data part to a key.
|
||||
* : Conforms to Microsoft API call. E.g. use NULLS to remove headings/keys
|
||||
* : Headings and keys will be created as necessary
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_writeString (ini_fd_t fd, const char *str)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct key_tag *_key;
|
||||
|
||||
_key = __ini_write (ini);
|
||||
if (!_key)
|
||||
return -1;
|
||||
|
||||
// Write data to bottom of backup file
|
||||
_key->length = strlen (str);
|
||||
fprintf (ini->ftmp, "%s\n", str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_readInt
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for error or the number of values read.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Reads data part from a key and returns it as a int
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_readInt (ini_fd_t fd, int *value)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
int ret = 0;
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
if (ini->listDelims)
|
||||
{
|
||||
char *data = __ini_readList (ini);
|
||||
if (data)
|
||||
sscanf (data, "%d", value);
|
||||
}
|
||||
else
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
{
|
||||
size_t length;
|
||||
if (__ini_read (ini, &length) >= 0)
|
||||
{
|
||||
if (length > 0)
|
||||
ret = fscanf (ini->ftmp, "%d", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 1)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef INI_ADD_EXTRAS
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_readLong
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for error or the number of values read.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Reads data part from a key and returns it as a long
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_readLong (ini_fd_t fd, long *value)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
int ret = 0;
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
if (ini->listDelims)
|
||||
{
|
||||
char *data = __ini_readList (ini);
|
||||
if (data)
|
||||
ret = sscanf (data, "%ld", value);
|
||||
}
|
||||
else
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
{
|
||||
size_t length;
|
||||
if (__ini_read (ini, &length) >= 0)
|
||||
{
|
||||
if (length > 0)
|
||||
ret = fscanf (ini->ftmp, "%ld", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 1)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_readDouble
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for error or the number of values read.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Reads data part from a key and returns it as a double (real)
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_readDouble (ini_fd_t fd, double *value)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
int ret = 0;
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
if (ini->listDelims)
|
||||
{
|
||||
char *data = __ini_readList (ini);
|
||||
if (data)
|
||||
ret = sscanf (data, "%lf", value);
|
||||
}
|
||||
else
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
{
|
||||
size_t length;
|
||||
if (__ini_read (ini, &length) >= 0)
|
||||
{
|
||||
if (length > 0)
|
||||
ret = fscanf (ini->ftmp, "%lf", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 1)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_readBool
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for error or the number of values read.
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Reads data part from a key and returns it as a int. Supported bool strings are 0, 1, true
|
||||
* : false.
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_readBool (ini_fd_t fd, int *value)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
char buffer[6] = "";
|
||||
|
||||
#ifdef INI_ADD_LIST_SUPPORT
|
||||
if (ini->listDelims)
|
||||
{
|
||||
char *data = __ini_readList (ini);
|
||||
if (!data)
|
||||
return -1;
|
||||
sscanf (data, "%5s", buffer);
|
||||
}
|
||||
else
|
||||
#endif // INI_ADD_LIST_SUPPORT
|
||||
{
|
||||
size_t length;
|
||||
if (__ini_read (ini, &length) < 0)
|
||||
return -1;
|
||||
if (length > 0)
|
||||
fscanf (ini->ftmp, "%5s", buffer);
|
||||
}
|
||||
|
||||
{ // Convert string to lower case
|
||||
char *p = buffer;
|
||||
while (*p != '\0')
|
||||
{
|
||||
*p = (char) tolower (*p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
// Decode supported bool types
|
||||
switch (*buffer)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
if (buffer[1] != '\0')
|
||||
return -1;
|
||||
*value = *buffer - '0';
|
||||
break;
|
||||
default:
|
||||
if (!strcasecmp (buffer, "true"))
|
||||
*value = 1;
|
||||
else if (!strcasecmp (buffer, "false"))
|
||||
*value = 0;
|
||||
else if (!strcasecmp (buffer, "on"))
|
||||
*value = 1;
|
||||
else if (!strcasecmp (buffer, "off"))
|
||||
*value = 0;
|
||||
else if (!strcasecmp (buffer, "yes"))
|
||||
*value = 1;
|
||||
else if (!strcasecmp (buffer, "no"))
|
||||
*value = 0;
|
||||
else // No match
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_writeInt
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Writes data part to a key.
|
||||
* : Headings and keys will be created as necessary
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_writeInt (ini_fd_t fd, int value)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct key_tag *_key;
|
||||
long pos;
|
||||
|
||||
_key = __ini_write (ini);
|
||||
if (!_key)
|
||||
return -1;
|
||||
|
||||
// Write data to bottom of backup file
|
||||
fprintf (ini->ftmp, "%d", value);
|
||||
pos = ftell (ini->ftmp);
|
||||
_key->length = (size_t) (pos - _key->pos);
|
||||
fprintf (ini->ftmp, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_writeLong
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Writes data part to a key.
|
||||
* : Headings and keys will be created as necessary
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_writeLong (ini_fd_t fd, long value)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct key_tag *_key;
|
||||
long pos;
|
||||
|
||||
_key = __ini_write (ini);
|
||||
if (!_key)
|
||||
return -1;
|
||||
|
||||
// Write data to bottom of backup file
|
||||
fprintf (ini->ftmp, "%ld", value);
|
||||
pos = ftell (ini->ftmp);
|
||||
_key->length = (size_t) (pos - _key->pos);
|
||||
fprintf (ini->ftmp, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_writeDouble
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Writes data part to a key.
|
||||
* : Headings and keys will be created as necessary
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_writeDouble (ini_fd_t fd, double value)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct key_tag *_key;
|
||||
long pos;
|
||||
|
||||
_key = __ini_write (ini);
|
||||
if (!_key)
|
||||
return -1;
|
||||
|
||||
// Write data to bottom of backup file
|
||||
fprintf (ini->ftmp, "%f", value);
|
||||
pos = ftell (ini->ftmp);
|
||||
_key->length = (size_t) (pos - _key->pos);
|
||||
fprintf (ini->ftmp, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************************************
|
||||
* Function : ini_writeBool
|
||||
* Parameters : ini - pointer to ini file database.
|
||||
* : value - keys data
|
||||
* Returns : -1 for Error and 0 on success
|
||||
* Globals Used :
|
||||
* Globals Modified :
|
||||
* Description : Writes data part to a key.
|
||||
* : Headings and keys will be created as necessary
|
||||
********************************************************************************************************************
|
||||
* Rev | Date | By | Comment
|
||||
* ----------------------------------------------------------------------------------------------------------------
|
||||
********************************************************************************************************************/
|
||||
int INI_LINKAGE ini_writeBool (ini_fd_t fd, int value)
|
||||
{
|
||||
ini_t *ini = (ini_t *) fd;
|
||||
struct key_tag *_key;
|
||||
long pos;
|
||||
|
||||
// Check if value is legal
|
||||
if ((value < 0) || (value > 1))
|
||||
return -1;
|
||||
|
||||
_key = __ini_write (ini);
|
||||
if (!_key)
|
||||
return -1;
|
||||
|
||||
// Write data to bottom of backup file
|
||||
if (value)
|
||||
fprintf (ini->ftmp, "true");
|
||||
else
|
||||
fprintf (ini->ftmp, "false");
|
||||
pos = ftell (ini->ftmp);
|
||||
_key->length = (size_t) (pos - _key->pos);
|
||||
fprintf (ini->ftmp, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // INI_ADD_EXTRAS
|
||||
@@ -1 +1 @@
|
||||
<Project name="Savegame Manager"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="arm9" path="arm9\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="source" path="source\"><File path="auxspi.cpp"></File><File path="auxspi.h"></File><File path="auxspi_core.cpp"></File><File path="display.cpp"></File><File path="display.h"></File><File path="dsCard.cpp"></File><File path="dsCard.h"></File><File path="fileselect.cpp"></File><File path="fileselect.h"></File><File path="gba.cpp"></File><File path="gba.h"></File><File path="hardware.cpp"></File><File path="hardware.h"></File><File path="main.cpp"></File></MagicFolder><File path="Makefile"></File></MagicFolder><File path="Makefile"></File></Project>
|
||||
<Project name="Savegame Manager"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="arm9" path="arm9\"><MagicFolder excludeFolders="CVS;.svn" filter="*" name="build" path="build\"><File path=".map"></File><File path="auxspi.d"></File><File path="auxspi.o"></File><File path="auxspi_core.d"></File><File path="auxspi_core.o"></File><File path="display.d"></File><File path="display.o"></File><File path="dsCard.d"></File><File path="dsCard.o"></File><File path="fileselect.d"></File><File path="fileselect.o"></File><File path="ftplib.d"></File><File path="ftplib.o"></File><File path="gba.d"></File><File path="gba.o"></File><File path="hardware.d"></File><File path="hardware.o"></File><File path="ini.d"></File><File path="ini.o"></File><File path="main.d"></File><File path="main.o"></File></MagicFolder><MagicFolder excludeFolders="CVS;.svn" filter="*" name="source" path="source\"><File path="auxspi.cpp"></File><File path="auxspi.h"></File><File path="auxspi_core.cpp"></File><File path="display.cpp"></File><File path="display.h"></File><File path="dsCard.cpp"></File><File path="dsCard.h"></File><File path="fileselect.cpp"></File><File path="fileselect.h"></File><File path="ftplib.c"></File><File path="ftplib.h"></File><File path="gba.cpp"></File><File path="gba.h"></File><File path="hardware.cpp"></File><File path="hardware.h"></File><File path="headings.i"></File><File path="ini.cpp"></File><File path="ini.h"></File><File path="iniconfig.h"></File><File path="iniheadings.h"></File><File path="inikeys.h"></File><File path="inilist.h"></File><File path="keys.i"></File><File path="libini.h"></File><File path="list.i"></File><File path="main.cpp"></File><File path="types.i"></File></MagicFolder><File path="Makefile"></File><File path="savegame_manager.arm9.elf"></File></MagicFolder><File path="Makefile"></File></Project>
|
||||
@@ -1 +1 @@
|
||||
<pd><ViewState><e p="Savegame Manager" x="true"></e><e p="Savegame Manager\arm9" x="true"></e><e p="Savegame Manager\arm9\source" x="true"></e></ViewState></pd>
|
||||
<pd><ViewState><e p="Savegame Manager" x="true"></e><e p="Savegame Manager\arm9" x="true"></e><e p="Savegame Manager\arm9\build" x="false"></e><e p="Savegame Manager\arm9\source" x="true"></e></ViewState></pd>
|
||||
Reference in New Issue
Block a user