|
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
View previous topic :: View next topic |
Author |
Message |
Coldbird
Joined: 08 Feb 2007 Posts: 155
|
Posted: Wed Mar 17, 2010 9:46 am Post subject: Debug Code - Works in Kernel Mode, but not in user? |
|
|
Code: | #include <pspiofilemgr.h>
#include <pspsdk.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "debug.h"
#include "snprintf.h"
int debuglog(const char * format, ...)
{
//written bytes
int written = 0;
//increase permission level
unsigned int k1 = pspSdkSetK1(0);
//first flag
static int first = 1;
//internal buffer
char buffer[512];
//argument list
va_list args;
//activate argument handler
va_start(args, format);
//fill buffer
vsnprintf(buffer, 512, format, args);
//kill argument handler
va_end(args);
//write new file
if(first) { written = writeBufferToFile(LOGFILE, buffer, strlen(buffer)); first = 0; }
//append buffer to file
else written = appendBufferToFile(LOGFILE, buffer, strlen(buffer));
//restore permission level
pspSdkSetK1(k1);
//return written bytes
return written;
}
int _writeBufferToFile(const char * path, void * buffer, int buflen, int append)
{
//written bytes
int written = 0;
//file flags
unsigned int flags = PSP_O_CREAT | PSP_O_WRONLY;
//append flag
if(append) flags |= PSP_O_APPEND;
//wipe file
else flags |= PSP_O_TRUNC;
//open file for appending
SceUID file = sceIoOpen(path, flags, 0777);
//opened file
if(file >= 0)
{
//write buffer
written = sceIoWrite(file, buffer, buflen);
//close file
sceIoClose(file);
}
//return written bytes
return written;
}
int writeBufferToFile(const char * path, void * buffer, int buflen)
{
//written bytes
int written = 0;
//increase permission level
unsigned int k1 = pspSdkSetK1(0);
//write buffer
written = _writeBufferToFile(path, buffer, buflen, 0);
//restore permission level
pspSdkSetK1(k1);
//return written bytes
return written;
}
int appendBufferToFile(const char * path, void * buffer, int buflen)
{
//written bytes
int written = 0;
//increase permission level
unsigned int k1 = pspSdkSetK1(0);
//write buffer
written = _writeBufferToFile(path, buffer, buflen, 1);
//restore permission level
pspSdkSetK1(k1);
//return written bytes
return written;
}
|
Here's what I'm doing... I got a kernel module "coldbird.prx" - which uses the debug code i showed you guys above.
Works like a charm... prints whatever I tell debuglog to print into a file of my choice... brilliant.
But here's the thing... it won't work from a user prx module "pspnet_adhoc.prx" (my 1:1 clone of the flash0 module)...
I've tried many things... exporting it using 0x4001 flag in coldbird.prx and reimporting it on pspnet_adhoc.prx... I've copied the whole debug code into pspnet_adhoc.prx and compiled it so its included in there... didn't work either...
No logfile is produced... no text outputted...
Does anyone have a idea why? If so - please tell me as this annoys me badly. _________________ Been gone for some time. Now I'm back. Someone mind getting me up-2-date? |
|
Back to top |
|
|
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Fri Mar 19, 2010 3:07 am Post subject: |
|
|
I use the same kind of code but using libc fopen fwrite fclose etc .. and it work without problem.
Are you sure that this
unsigned int k1 = pspSdkSetK1(0);
is allowed in a user prx ?
Code: |
void log(char* pMessage, ...)
{
char Message[256];
va_list ArgPtr;
FILE* pFile;
va_start (ArgPtr, pMessage);
vsnprintf (Message, sizeof (Message), pMessage, ArgPtr);
va_end (ArgPtr);
#ifdef _DEBUG_STDOUT
printf (Message);
#endif
pFile = fopen ("log.txt", "a");
fwrite (Message, strlen (Message), 1, pFile);
fclose (pFile);
} |
|
|
Back to top |
|
|
Coldbird
Joined: 08 Feb 2007 Posts: 155
|
Posted: Sat Mar 20, 2010 11:48 pm Post subject: |
|
|
Yes it is allowed in a user module, and I can't get your sample to compile really...
Mind handing me a makefile of yours so I can see just which things you are linking too?
Ive tried newlib aswell as the minimal kernel lib but either way Im hitting a dead end.
EDIT: Nvm. compilation problems resolved.
EDIT2: No go here... waayy too bulky... Using newlib (which your code requires) the whole libc gets statically linked, which results in a 90+KB prx for every prx i have... this IS too bulky... I need a PSP specific solution using the firmware apis to maintain a normal executeable size. _________________ Been gone for some time. Now I'm back. Someone mind getting me up-2-date? |
|
Back to top |
|
|
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Mar 21, 2010 7:42 am Post subject: |
|
|
Ok here are a sample hello world with lthe log function and the makefile
you place the eboot.bpb in your ms at /psp/game/hello
you execute it. You quit the helloworld with the home key
the log is created in your ms at /psp/game/hello
Code: |
#include <pspkernel.h> //Déclarations des librairies
#include <pspdebug.h>
#include <stdarg.h>
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
PSP_MODULE_INFO("Helloworld", 0, 2, 1); // Nom+ numéro de version du programme
#define printf pspDebugScreenPrintf //simplifie l'écriture de la fonction pspDebugScreenPrintf en printf
void psplog(char* pMessage, ...)
{
char Message[256];
va_list ArgPtr;
FILE* pFile;
va_start (ArgPtr, pMessage);
vsnprintf (Message, sizeof (Message), pMessage, ArgPtr);
va_end (ArgPtr);
#ifdef _DEBUG_STDOUT
printf (Message);
#endif
pFile = fopen ("log.txt", "a");
fwrite (Message, strlen (Message), 1, pFile);
fclose (pFile);
}
int exit_callback(int arg1, int arg2, void *common) { //début des fonctions pour le fonctionnement de la touche home
sceKernelExitGame();
return 0;
}
int CallbackThread(SceSize args, void *argp) {
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
int SetupCallbacks(void) {
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0) {
sceKernelStartThread(thid, 0, 0);
}
return thid;
}//fin des fonctions pour le fonctionnement de la touche home
int main(void)
{
pspDebugScreenInit(); //Permet l'affichage du texte
SetupCallbacks(); //Permet la mise en marche de la touche home
psplog("%s from psp\n","HelloWorld !"); //Texte à afficher
sceKernelSleepThread(); //Mise en veille du kernel (sinon le programme plante)
return 0;
} |
and the makefile
Code: |
TARGET = hello-world
OBJS = helloworld.o
BUILD_PRX = 1
PSP_FW_VERSION=550
INCDIR =
CFLAGS = -G0 -Wall -O2
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS =
STDLIBS= -losl -lmikmod -lpng -ljpeg -lz \
-lpspsdk -lpspctrl -lpspumd -lpsprtc -lpsppower -lpspgu -lpspaudiolib -lpspaudio -lm \
-lpspmpeg -lpspaudiocodec -lpsphprm -lpspgum_vfpu -lpspvfpu -lpspgum
LIBS=$(STDLIBS)$(YOURLIBS)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello World
#PSP_EBOOT_ICON = ICON0.png
#PSP_EBOOT_PIC1= PIC1.png
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
|
|
|
Back to top |
|
|
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Mar 21, 2010 7:50 am Post subject: |
|
|
create your own sprintf and replace the fopen by the sce equivalent
so you have both the best world
here is a code sample of the sprintf.c
Code: |
00001 /**********************************************************************
00002
00003 sprintf.c -
00004
00005 $Author: akr $
00006 $Date: 2005/12/12 15:09:50 $
00007 created at: Fri Oct 15 10:39:26 JST 1993
00008
00009 Copyright (C) 1993-2003 Yukihiro Matsumoto
00010 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
00011 Copyright (C) 2000 Information-technology Promotion Agency, Japan
00012
00013 **********************************************************************/
00014
00015 #include "ruby.h"
00016 #include <ctype.h>
00017 #include <math.h>
00018
00019 #define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */
00020
00021 static void fmt_setup (char*,int,int,int,int);
00022
00023 static char*
00024 remove_sign_bits(str, base)
00025 char *str;
00026 int base;
00027 {
00028 char *s, *t;
00029
00030 s = t = str;
00031
00032 if (base == 16) {
00033 while (*t == 'f') {
00034 t++;
00035 }
00036 }
00037 else if (base == 8) {
00038 if (*t == '3') t++;
00039 while (*t == '7') {
00040 t++;
00041 }
00042 }
00043 else if (base == 2) {
00044 while (*t == '1') {
00045 t++;
00046 }
00047 }
00048 if (t > s) {
00049 while (*t) *s++ = *t++;
00050 *s = '\0';
00051 }
00052
00053 return str;
00054 }
00055
00056 static char
00057 sign_bits(base, p)
00058 int base;
00059 const char *p;
00060 {
00061 char c = '.';
00062
00063 switch (base) {
00064 case 16:
00065 if (*p == 'X') c = 'F';
00066 else c = 'f';
00067 break;
00068 case 8:
00069 c = '7'; break;
00070 case 2:
00071 c = '1'; break;
00072 }
00073 return c;
00074 }
00075
00076 #define FNONE 0
00077 #define FSHARP 1
00078 #define FMINUS 2
00079 #define FPLUS 4
00080 #define FZERO 8
00081 #define FSPACE 16
00082 #define FWIDTH 32
00083 #define FPREC 64
00084
00085 #define CHECK(l) do {\
00086 while (blen + (l) >= bsiz) {\
00087 bsiz*=2;\
00088 }\
00089 rb_str_resize(result, bsiz);\
00090 buf = RSTRING(result)->ptr;\
00091 } while (0)
00092
00093 #define PUSH(s, l) do { \
00094 CHECK(l);\
00095 memcpy(&buf[blen], s, l);\
00096 blen += (l);\
00097 } while (0)
00098
00099 #define GETARG() (nextvalue != Qundef ? nextvalue : \
00100 posarg < 0 ? \
00101 (rb_raise(rb_eArgError, "unnumbered(%d) mixed with numbered", nextarg), 0) : \
00102 (posarg = nextarg++, GETNTHARG(posarg)))
00103
00104 #define GETPOSARG(n) (posarg > 0 ? \
00105 (rb_raise(rb_eArgError, "numbered(%d) after unnumbered(%d)", n, posarg), 0) : \
00106 ((n < 1) ? (rb_raise(rb_eArgError, "invalid index - %d$", n), 0) : \
00107 (posarg = -1, GETNTHARG(n))))
00108
00109 #define GETNTHARG(nth) \
00110 ((nth >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[nth])
00111
00112 #define GETASTER(val) do { \
00113 t = p++; \
00114 n = 0; \
00115 for (; p < end && ISDIGIT(*p); p++) { \
00116 int next_n = 10 * n + (*p - '0'); \
00117 if (next_n / 10 != n) {\
00118 rb_raise(rb_eArgError, #val " too big"); \
00119 } \
00120 n = next_n; \
00121 } \
00122 if (p >= end) { \
00123 rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \
00124 } \
00125 if (*p == '$') { \
00126 tmp = GETPOSARG(n); \
00127 } \
00128 else { \
00129 tmp = GETARG(); \
00130 p = t; \
00131 } \
00132 val = NUM2INT(tmp); \
00133 } while (0)
00134
00135
00136 /*
00137 * call-seq:
00138 * format(format_string [, arguments...] ) => string
00139 * sprintf(format_string [, arguments...] ) => string
00140 *
00141 * Returns the string resulting from applying <i>format_string</i> to
00142 * any additional arguments. Within the format string, any characters
00143 * other than format sequences are copied to the result. A format
00144 * sequence consists of a percent sign, followed by optional flags,
00145 * width, and precision indicators, then terminated with a field type
00146 * character. The field type controls how the corresponding
00147 * <code>sprintf</code> argument is to be interpreted, while the flags
00148 * modify that interpretation. The field type characters are listed
00149 * in the table at the end of this section. The flag characters are:
00150 *
00151 * Flag | Applies to | Meaning
00152 * ---------+--------------+-----------------------------------------
00153 * space | bdeEfgGiouxX | Leave a space at the start of
00154 * | | positive numbers.
00155 * ---------+--------------+-----------------------------------------
00156 * (digit)$ | all | Specifies the absolute argument number
00157 * | | for this field. Absolute and relative
00158 * | | argument numbers cannot be mixed in a
00159 * | | sprintf string.
00160 * ---------+--------------+-----------------------------------------
00161 * # | beEfgGoxX | Use an alternative format. For the
00162 * | | conversions `o', `x', `X', and `b',
00163 * | | prefix the result with ``0'', ``0x'', ``0X'',
00164 * | | and ``0b'', respectively. For `e',
00165 * | | `E', `f', `g', and 'G', force a decimal
00166 * | | point to be added, even if no digits follow.
00167 * | | For `g' and 'G', do not remove trailing zeros.
00168 * ---------+--------------+-----------------------------------------
00169 * + | bdeEfgGiouxX | Add a leading plus sign to positive numbers.
00170 * ---------+--------------+-----------------------------------------
00171 * - | all | Left-justify the result of this conversion.
00172 * ---------+--------------+-----------------------------------------
00173 * 0 (zero) | bdeEfgGiouxX | Pad with zeros, not spaces.
00174 * ---------+--------------+-----------------------------------------
00175 * * | all | Use the next argument as the field width.
00176 * | | If negative, left-justify the result. If the
00177 * | | asterisk is followed by a number and a dollar
00178 * | | sign, use the indicated argument as the width.
00179 *
00180 *
00181 * The field width is an optional integer, followed optionally by a
00182 * period and a precision. The width specifies the minimum number of
00183 * characters that will be written to the result for this field. For
00184 * numeric fields, the precision controls the number of decimal places
00185 * displayed. For string fields, the precision determines the maximum
00186 * number of characters to be copied from the string. (Thus, the format
00187 * sequence <code>%10.10s</code> will always contribute exactly ten
00188 * characters to the result.)
00189 *
00190 * The field types are:
00191 *
00192 * Field | Conversion
00193 * ------+--------------------------------------------------------------
00194 * b | Convert argument as a binary number.
00195 * c | Argument is the numeric code for a single character.
00196 * d | Convert argument as a decimal number.
00197 * E | Equivalent to `e', but uses an uppercase E to indicate
00198 * | the exponent.
00199 * e | Convert floating point argument into exponential notation
00200 * | with one digit before the decimal point. The precision
00201 * | determines the number of fractional digits (defaulting to six).
00202 * f | Convert floating point argument as [-]ddd.ddd,
00203 * | where the precision determines the number of digits after
00204 * | the decimal point.
00205 * G | Equivalent to `g', but use an uppercase `E' in exponent form.
00206 * g | Convert a floating point number using exponential form
00207 * | if the exponent is less than -4 or greater than or
00208 * | equal to the precision, or in d.dddd form otherwise.
00209 * i | Identical to `d'.
00210 * o | Convert argument as an octal number.
00211 * p | The valuing of argument.inspect.
00212 * s | Argument is a string to be substituted. If the format
00213 * | sequence contains a precision, at most that many characters
00214 * | will be copied.
00215 * u | Treat argument as an unsigned decimal number.
00216 * X | Convert argument as a hexadecimal number using uppercase
00217 * | letters. Negative numbers will be displayed with two
00218 * | leading periods (representing an infinite string of
00219 * | leading 'FF's.
00220 * x | Convert argument as a hexadecimal number.
00221 * | Negative numbers will be displayed with two
00222 * | leading periods (representing an infinite string of
00223 * | leading 'ff's.
00224 *
00225 * Examples:
00226 *
00227 * sprintf("%d %04x", 123, 123) #=> "123 007b"
00228 * sprintf("%08b '%4s'", 123, 123) #=> "01111011 ' 123'"
00229 * sprintf("%1$*2$s %2$d %1$s", "hello", 8) #=> " hello 8 hello"
00230 * sprintf("%1$*2$s %2$d", "hello", -8) #=> "hello -8"
00231 * sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23) #=> "+1.23: 1.23:1.23"
00232 */
00233
00234 VALUE
00235 rb_f_sprintf(argc, argv)
00236 int argc;
00237 VALUE *argv;
00238 {
00239 VALUE fmt;
00240 const char *p, *end;
00241 char *buf;
00242 int blen, bsiz;
00243 VALUE result;
00244
00245 int width, prec, flags = FNONE;
00246 int nextarg = 1;
00247 int posarg = 0;
00248 int tainted = 0;
00249 VALUE nextvalue;
00250 VALUE tmp;
00251 VALUE str;
00252
00253 fmt = GETNTHARG(0);
00254 if (OBJ_TAINTED(fmt)) tainted = 1;
00255 StringValue(fmt);
00256 fmt = rb_str_new4(fmt);
00257 p = RSTRING(fmt)->ptr;
00258 end = p + RSTRING(fmt)->len;
00259 blen = 0;
00260 bsiz = 120;
00261 result = rb_str_buf_new(bsiz);
00262 buf = RSTRING(result)->ptr;
00263
00264 for (; p < end; p++) {
00265 const char *t;
00266 int n;
00267
00268 for (t = p; t < end && *t != '%'; t++) ;
00269 PUSH(p, t - p);
00270 if (t >= end) {
00271 /* end of fmt string */
00272 goto sprint_exit;
00273 }
00274 p = t + 1; /* skip `%' */
00275
00276 width = prec = -1;
00277 nextvalue = Qundef;
00278 retry:
00279 switch (*p) {
00280 default:
00281 if (ISPRINT(*p))
00282 rb_raise(rb_eArgError, "malformed format string - %%%c", *p);
00283 else
00284 rb_raise(rb_eArgError, "malformed format string");
00285 break;
00286
00287 case ' ':
00288 flags |= FSPACE;
00289 p++;
00290 goto retry;
00291
00292 case '#':
00293 flags |= FSHARP;
00294 p++;
00295 goto retry;
00296
00297 case '+':
00298 flags |= FPLUS;
00299 p++;
00300 goto retry;
00301
00302 case '-':
00303 flags |= FMINUS;
00304 p++;
00305 goto retry;
00306
00307 case '0':
00308 flags |= FZERO;
00309 p++;
00310 goto retry;
00311
00312 case '1': case '2': case '3': case '4':
00313 case '5': case '6': case '7': case '8': case '9':
00314 n = 0;
00315 for (; p < end && ISDIGIT(*p); p++) {
00316 int next_n = 10 * n + (*p - '0');
00317 if (next_n / 10 != n) {
00318 rb_raise(rb_eArgError, "width too big");
00319 }
00320 n = 10 * n + (*p - '0');
00321 }
00322 if (p >= end) {
00323 rb_raise(rb_eArgError, "malformed format string - %%[0-9]");
00324 }
00325 if (*p == '$') {
00326 if (nextvalue != Qundef) {
00327 rb_raise(rb_eArgError, "value given twice - %d$", n);
00328 }
00329 nextvalue = GETPOSARG(n);
00330 p++;
00331 goto retry;
00332 }
00333 width = n;
00334 flags |= FWIDTH;
00335 goto retry;
00336
00337 case '*':
00338 if (flags & FWIDTH) {
00339 rb_raise(rb_eArgError, "width given twice");
00340 }
00341
00342 flags |= FWIDTH;
00343 GETASTER(width);
00344 if (width < 0) {
00345 flags |= FMINUS;
00346 width = -width;
00347 }
00348 p++;
00349 goto retry;
00350
00351 case '.':
00352 if (flags & FPREC) {
00353 rb_raise(rb_eArgError, "precision given twice");
00354 }
00355 flags |= FPREC;
00356
00357 prec = 0;
00358 p++;
00359 if (*p == '*') {
00360 GETASTER(prec);
00361 if (prec < 0) { /* ignore negative precision */
00362 flags &= ~FPREC;
00363 }
00364 p++;
00365 goto retry;
00366 }
00367
00368 for (; p < end && ISDIGIT(*p); p++) {
00369 prec = 10 * prec + (*p - '0');
00370 }
00371 if (p >= end) {
00372 rb_raise(rb_eArgError, "malformed format string - %%.[0-9]");
00373 }
00374 goto retry;
00375
00376 case '\n':
00377 p--;
00378 case '\0':
00379 case '%':
00380 if (flags != FNONE) {
00381 rb_raise(rb_eArgError, "illegal format character - %%");
00382 }
00383 PUSH("%", 1);
00384 break;
00385
00386 case 'c':
00387 {
00388 VALUE val = GETARG();
00389 char c;
00390
00391 if (!(flags & FMINUS))
00392 while (--width > 0)
00393 PUSH(" ", 1);
00394 c = NUM2INT(val) & 0xff;
00395 PUSH(&c, 1);
00396 while (--width > 0)
00397 PUSH(" ", 1);
00398 }
00399 break;
00400
00401 case 's':
00402 case 'p':
00403 {
00404 VALUE arg = GETARG();
00405 long len;
00406
00407 if (*p == 'p') arg = rb_inspect(arg);
00408 str = rb_obj_as_string(arg);
00409 if (OBJ_TAINTED(str)) tainted = 1;
00410 len = RSTRING(str)->len;
00411 if (flags&FPREC) {
00412 if (prec < len) {
00413 len = prec;
00414 }
00415 }
00416 if (flags&FWIDTH) {
00417 if (width > len) {
00418 CHECK(width);
00419 width -= len;
00420 if (!(flags&FMINUS)) {
00421 while (width--) {
00422 buf[blen++] = ' ';
00423 }
00424 }
00425 memcpy(&buf[blen], RSTRING(str)->ptr, len);
00426 blen += len;
00427 if (flags&FMINUS) {
00428 while (width--) {
00429 buf[blen++] = ' ';
00430 }
00431 }
00432 break;
00433 }
00434 }
00435 PUSH(RSTRING(str)->ptr, len);
00436 }
00437 break;
00438
00439 case 'd':
00440 case 'i':
00441 case 'o':
00442 case 'x':
00443 case 'X':
00444 case 'b':
00445 case 'B':
00446 case 'u':
00447 {
00448 volatile VALUE val = GETARG();
00449 char fbuf[32], nbuf[64], *s, *t;
00450 char *prefix = 0;
00451 int sign = 0;
00452 char sc = 0;
00453 long v = 0;
00454 int base, bignum = 0;
00455 int len, pos;
00456 VALUE tmp;
00457 volatile VALUE tmp1;
00458
00459 switch (*p) {
00460 case 'd':
00461 case 'i':
00462 sign = 1; break;
00463 case 'o':
00464 case 'x':
00465 case 'X':
00466 case 'b':
00467 case 'B':
00468 case 'u':
00469 default:
00470 if (flags&(FPLUS|FSPACE)) sign = 1;
00471 break;
00472 }
00473 if (flags & FSHARP) {
00474 switch (*p) {
00475 case 'o':
00476 prefix = "0"; break;
00477 case 'x':
00478 prefix = "0x"; break;
00479 case 'X':
00480 prefix = "0X"; break;
00481 case 'b':
00482 prefix = "0b"; break;
00483 case 'B':
00484 prefix = "0B"; break;
00485 }
00486 if (prefix) {
00487 width -= strlen(prefix);
00488 }
00489 }
00490
00491 bin_retry:
00492 switch (TYPE(val)) {
00493 case T_FLOAT:
00494 val = rb_dbl2big(RFLOAT(val)->value);
00495 if (FIXNUM_P(val)) goto bin_retry;
00496 bignum = 1;
00497 break;
00498 case T_STRING:
00499 val = rb_str_to_inum(val, 0, Qtrue);
00500 goto bin_retry;
00501 case T_BIGNUM:
00502 bignum = 1;
00503 break;
00504 case T_FIXNUM:
00505 v = FIX2LONG(val);
00506 break;
00507 default:
00508 val = rb_Integer(val);
00509 goto bin_retry;
00510 }
00511
00512 switch (*p) {
00513 case 'o':
00514 base = 8; break;
00515 case 'x':
00516 case 'X':
00517 base = 16; break;
00518 case 'b':
00519 case 'B':
00520 base = 2; break;
00521 case 'u':
00522 case 'd':
00523 case 'i':
00524 default:
00525 base = 10; break;
00526 }
00527 if (!bignum) {
00528 if (base == 2) {
00529 val = rb_int2big(v);
00530 goto bin_retry;
00531 }
00532 if (sign) {
00533 char c = *p;
00534 if (c == 'i') c = 'd'; /* %d and %i are identical */
00535 if (v < 0) {
00536 v = -v;
00537 sc = '-';
00538 width--;
00539 }
00540 else if (flags & FPLUS) {
00541 sc = '+';
00542 width--;
00543 }
00544 else if (flags & FSPACE) {
00545 sc = ' ';
00546 width--;
00547 }
00548 sprintf(fbuf, "%%l%c", c);
00549 sprintf(nbuf, fbuf, v);
00550 s = nbuf;
00551 goto format_integer;
00552 }
00553 s = nbuf;
00554 if (v < 0) {
00555 if (base == 10) {
00556 rb_warning("negative number for %%u specifier");
00557 }
00558 if (!(flags&(FPREC|FZERO))) {
00559 strcpy(s, "..");
00560 s += 2;
00561 }
00562 }
00563 sprintf(fbuf, "%%l%c", *p == 'X' ? 'x' : *p);
00564 sprintf(s, fbuf, v);
00565 if (v < 0) {
00566 char d = 0;
00567
00568 remove_sign_bits(s, base);
00569 switch (base) {
00570 case 16:
00571 d = 'f'; break;
00572 case 8:
00573 d = '7'; break;
00574 }
00575 if (d && *s != d) {
00576 memmove(s+1, s, strlen(s)+1);
00577 *s = d;
00578 }
00579 }
00580 s = nbuf;
00581 goto format_integer;
00582 }
00583
00584 if (sign) {
00585 tmp = rb_big2str(val, base);
00586 s = RSTRING(tmp)->ptr;
00587 if (s[0] == '-') {
00588 s++;
00589 sc = '-';
00590 width--;
00591 }
00592 else if (flags & FPLUS) {
00593 sc = '+';
00594 width--;
00595 }
00596 else if (flags & FSPACE) {
00597 sc = ' ';
00598 width--;
00599 }
00600 goto format_integer;
00601 }
00602 if (!RBIGNUM(val)->sign) {
00603 val = rb_big_clone(val);
00604 rb_big_2comp(val);
00605 }
00606 tmp1 = tmp = rb_big2str(val, base);
00607 s = RSTRING(tmp)->ptr;
00608 if (*s == '-') {
00609 if (base == 10) {
00610 rb_warning("negative number for %%u specifier");
00611 s++;
00612 }
00613 else {
00614 remove_sign_bits(++s, base);
00615 tmp = rb_str_new(0, 3+strlen(s));
00616 t = RSTRING(tmp)->ptr;
00617 if (!(flags&(FPREC|FZERO))) {
00618 strcpy(t, "..");
00619 t += 2;
00620 }
00621 switch (base) {
00622 case 16:
00623 if (s[0] != 'f') strcpy(t++, "f"); break;
00624 case 8:
00625 if (s[0] != '7') strcpy(t++, "7"); break;
00626 case 2:
00627 if (s[0] != '1') strcpy(t++, "1"); break;
00628 }
00629 strcpy(t, s);
00630 bignum = 2;
00631 }
00632 }
00633 s = RSTRING(tmp)->ptr;
00634
00635 format_integer:
00636 pos = -1;
00637 len = strlen(s);
00638
00639 if (*p == 'X') {
00640 char *pp = s;
00641 while (*pp) {
00642 *pp = toupper(*pp);
00643 pp++;
00644 }
00645 }
00646 if ((flags&(FZERO|FPREC)) == FZERO) {
00647 prec = width;
00648 width = 0;
00649 }
00650 else {
00651 if (prec < len) prec = len;
00652 width -= prec;
00653 }
00654 if (!(flags&FMINUS)) {
00655 CHECK(width);
00656 while (width-- > 0) {
00657 buf[blen++] = ' ';
00658 }
00659 }
00660 if (sc) PUSH(&sc, 1);
00661 if (prefix) {
00662 int plen = strlen(prefix);
00663 PUSH(prefix, plen);
00664 }
00665 CHECK(prec - len);
00666 if (!bignum && v < 0) {
00667 char c = sign_bits(base, p);
00668 while (len < prec--) {
00669 buf[blen++] = c;
00670 }
00671 }
00672 else {
00673 char c;
00674
00675 if (bignum && !RBIGNUM(val)->sign)
00676 c = sign_bits(base, p);
00677 else
00678 c = '0';
00679 while (len < prec--) {
00680 buf[blen++] = c;
00681 }
00682 }
00683 PUSH(s, len);
00684 CHECK(width);
00685 while (width-- > 0) {
00686 buf[blen++] = ' ';
00687 }
00688 }
00689 break;
00690
00691 case 'f':
00692 case 'g':
00693 case 'G':
00694 case 'e':
00695 case 'E':
00696 {
00697 VALUE val = GETARG();
00698 double fval;
00699 int i, need = 6;
00700 char fbuf[32];
00701
00702 fval = RFLOAT(rb_Float(val))->value;
00703 #if defined(_WIN32) && !defined(__BORLANDC__)
00704 if (isnan(fval) || isinf(fval)) {
00705 char *expr;
00706
00707 if (isnan(fval)) {
00708 expr = "NaN";
00709 }
00710 else {
00711 expr = "Inf";
00712 }
00713 need = strlen(expr);
00714 if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
00715 need++;
00716 if ((flags & FWIDTH) && need < width)
00717 need = width;
00718
00719 CHECK(need);
00720 sprintf(&buf[blen], "%*s", need, "");
00721 if (flags & FMINUS) {
00722 if (!isnan(fval) && fval < 0.0)
00723 buf[blen++] = '-';
00724 else if (flags & FPLUS)
00725 buf[blen++] = '+';
00726 else if (flags & FSPACE)
00727 blen++;
00728 strncpy(&buf[blen], expr, strlen(expr));
00729 }
00730 else if (flags & FZERO) {
00731 if (!isnan(fval) && fval < 0.0) {
00732 buf[blen++] = '-';
00733 need--;
00734 }
00735 else if (flags & FPLUS) {
00736 buf[blen++] = '+';
00737 need--;
00738 }
00739 else if (flags & FSPACE) {
00740 blen++;
00741 need--;
00742 }
00743 while (need-- - strlen(expr) > 0) {
00744 buf[blen++] = '0';
00745 }
00746 strncpy(&buf[blen], expr, strlen(expr));
00747 }
00748 else {
00749 if (!isnan(fval) && fval < 0.0)
00750 buf[blen + need - strlen(expr) - 1] = '-';
00751 else if (flags & FPLUS)
00752 buf[blen + need - strlen(expr) - 1] = '+';
00753 strncpy(&buf[blen + need - strlen(expr)], expr,
00754 strlen(expr));
00755 }
00756 blen += strlen(&buf[blen]);
00757 break;
00758 }
00759 #endif /* defined(_WIN32) && !defined(__BORLANDC__) */
00760 fmt_setup(fbuf, *p, flags, width, prec);
00761 need = 0;
00762 if (*p != 'e' && *p != 'E') {
00763 i = INT_MIN;
00764 frexp(fval, &i);
00765 if (i > 0)
00766 need = BIT_DIGITS(i);
00767 }
00768 need += (flags&FPREC) ? prec : 6;
00769 if ((flags&FWIDTH) && need < width)
00770 need = width;
00771 need += 20;
00772
00773 CHECK(need);
00774 sprintf(&buf[blen], fbuf, fval);
00775 blen += strlen(&buf[blen]);
00776 }
00777 break;
00778 }
00779 flags = FNONE;
00780 }
00781
00782 sprint_exit:
00783 /* XXX - We cannot validiate the number of arguments if (digit)$ style used.
00784 */
00785 if (posarg >= 0 && nextarg < argc) {
00786 const char *mesg = "too many arguments for format string";
00787 if (RTEST(ruby_debug)) rb_raise(rb_eArgError, mesg);
00788 if (RTEST(ruby_verbose)) rb_warn(mesg);
00789 }
00790 rb_str_resize(result, blen);
00791
00792 if (tainted) OBJ_TAINT(result);
00793 return result;
00794 }
00795
00796 static void
00797 fmt_setup(buf, c, flags, width, prec)
00798 char *buf;
00799 int c;
00800 int flags, width, prec;
00801 {
00802 *buf++ = '%';
00803 if (flags & FSHARP) *buf++ = '#';
00804 if (flags & FPLUS) *buf++ = '+';
00805 if (flags & FMINUS) *buf++ = '-';
00806 if (flags & FZERO) *buf++ = '0';
00807 if (flags & FSPACE) *buf++ = ' ';
00808
00809 if (flags & FWIDTH) {
00810 sprintf(buf, "%d", width);
00811 buf += strlen(buf);
00812 }
00813
00814 if (flags & FPREC) {
00815 sprintf(buf, ".%d", prec);
00816 buf += strlen(buf);
00817 }
00818
00819 *buf++ = c;
00820 *buf = '\0';
00821 }
|
|
|
Back to top |
|
|
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Mar 21, 2010 7:57 am Post subject: |
|
|
another hint loaddynamically a prx containing your loggin function and in every of your prx
you dynamically find the function and called it so all your prx haven't 30K overhead due to the libc just one the module that have the logging function. |
|
Back to top |
|
|
Davee
Joined: 22 Jun 2009 Posts: 59
|
Posted: Sun Mar 21, 2010 10:22 am Post subject: |
|
|
Is coldbird.prx loaded before your clone? |
|
Back to top |
|
|
Coldbird
Joined: 08 Feb 2007 Posts: 155
|
Posted: Mon Mar 22, 2010 11:20 pm Post subject: |
|
|
Yes it is and I already solved the problem... as in fact it was no problem.
About my own snprintf... yes - I've been doing this from the very start since I couldn't live with the libc overhead.
My kernel module exports all the necessary functions (coldbird.prx), and the other dummy modules import it...
In fact everything was fine... and I did a lot more debugging to figure out the problem... as it wasn't a import / call problem but in fact a memory problem...
To see the real cause, check my thread "Allocating Userspace from within Kernel".
Thanks for all the help guys, this forums and its user never leave me hanging.
See this case as solved. ^_^ _________________ Been gone for some time. Now I'm back. Someone mind getting me up-2-date? |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|