mov esi, [esp+0x20+8]
mov [esi], eax
; Undo the pusha
- add esp, 0x20
+ popa
mov eax, .newTask
ret
.newTask:
return newThread->TID;
}
+#if 0
+tPID Proc_NewProcess(Uint Flags, void (*Fcn)(void*), size_t SaveSize, const void *Data)
+{
+ tThread *newThread = Threads_CloneTCB(CLONE_VM);
+ return 0;
+}
+#endif
+
/**
* \fn int Proc_Clone(Uint *Err, Uint Flags)
* \brief Clone the current process
tThread *cur = Proc_GetCurThread();
Uint eip;
+ Log_Warning("Proc", "Proc_Clone is deprecated");
// Sanity, please
if( !(Flags & CLONE_VM) ) {
Log_Error("Proc", "Proc_Clone: Don't leave CLONE_VM unset, use Proc_NewKThread instead");
// New thread
newThread = Threads_CloneTCB(Flags);
if(!newThread) return -1;
+ ASSERT(newThread->Process);
+ //ASSERT(CheckMem(newThread->Process, sizeof(tProcess)));
+ //LOG("newThread->Process = %p", newThread->Process);
newThread->KernelStack = cur->KernelStack;
if( eip == 0 ) {
return 0;
}
+ //ASSERT(newThread->Process);
+ //ASSERT(CheckMem(newThread->Process, sizeof(tProcess)));
+ //LOG("newThread->Process = %p", newThread->Process);
newThread->SavedState.EIP = eip;
newThread->SavedState.SSE = NULL;
newThread->SavedState.bSSEModified = 0;
mov [rsp+0x10], rdi ; Arg1
mov [rsp+0x18], rsi ; Arg2
mov [rsp+0x20], rdx ; Arg3
- mov [rsp+0x28], r10 ; Arg4
+ mov [rsp+0x28], r10 ; Arg4 (r10 used in place of rcx)
mov [rsp+0x30], r8 ; Arg5
mov [rsp+0x38], r9 ; Arg6
void *ret;
// Sanity Check
- if(MaxBits < 12 || !PhysAddr) return 0;
+ ASSERTCR(MaxBits, >=, 12, NULL);
// Fast Allocate
if(Pages == 1 && MaxBits >= PHYS_BITS)
{
phys = MM_AllocPhys();
- *PhysAddr = phys;
ret = MM_MapHWPages(phys, 1);
MM_DerefPhys(phys);
+ if(PhysAddr)
+ *PhysAddr = phys;
return ret;
}
// Allocated successfully, now map
ret = MM_MapHWPages(phys, Pages);
- *PhysAddr = phys;
+ if(PhysAddr)
+ *PhysAddr = phys;
// MapHWPages references the pages, so deref them back down to 1
for(;Pages--;phys+=0x1000)
MM_DerefPhys(phys);
{
const int max_slots = (MM_TMPMAP_END - MM_TMPMAP_BASE) / PAGE_SIZE;
tVAddr ret = MM_TMPMAP_BASE;
- int i;
- for( i = 0; i < max_slots; i ++, ret += PAGE_SIZE )
+ for( int i = 0; i < max_slots; i ++, ret += PAGE_SIZE )
{
tPAddr *ent;
if( MM_GetPageEntryPtr( ret, 0, 1, 0, &ent) < 0 ) {
HEAP_VALIDATE();
+ // TODO: Schedule a delayed screen update
+
//LEAVE('-');
}
* drv/vterm_vt100.c
* - Virtual Terminal - VT100 (Kinda) Emulation
*/
-#define DEBUG 0
+#define DEBUG 1
#include "vterm.h"
#define sTerminal sVTerm
LOG("(%i)", CountDown);
VT_int_UpdateScreen(Term, 0);
if( Term->Flags & VT_FLAG_ALTBUF )
- VT_int_ScrollText(Term, CountDown);
+ VT_int_ScrollText(Term, -CountDown);
else
{
if(Term->ViewTopRow + CountDown < 0)
// Allocate card array
gaE1000_Cards = calloc(sizeof(tCard), card_count);
if( !gaE1000_Cards ) {
+ Log_Warning("E1000", "Allocation of %i card structures failed", card_count);
return MODULE_ERR_MALLOC;
}
Log_Debug("E1000", "Card %i: %P IRQ %i", card_idx, card->MMIOBasePhys, card->IRQ);
if( E1000_int_InitialiseCard(card) ) {
+ Log_Warning("E1000", "Initialisation of card #%i failed", card_idx);
return MODULE_ERR_MALLOC;
}
ifneq ($(_OBJPREFIX),)
@mkdir -p $(dir $@)
endif
- $V$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
- $V$(CC) -M -MP -MT $@ $(CPPFLAGS) $< -o $(_OBJPREFIX)$*.dep
+ $V$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ -MQ $@ -MP -MD -MF $(_OBJPREFIX)$*.dep
$(_OBJPREFIX)%.o: %.cpp
@echo [CXX] -o $@
# include <assert.h>
# include <stdlib.h> // malloc/free
+# define ASSERTC(a, r, b) assert(a r b)
+
static inline int MIN(int a, int b)
{
return a < b ? a : b;
if( ret <= old_inc_len ) {
_SysDebug("Term_HandleVT100: ret(%i) <= old_inc_len(%i), inc_len=%i, '%*C'",
ret, old_inc_len, st->cache_len, st->cache_len, st->cache);
- assert(ret > old_inc_len);
+ ASSERTC(ret, >, old_inc_len);
}
st->cache_len = 0;
//_SysDebug("%i bytes of escape code '%.*s' (return %i)",
Display_MoveCursor(Term, 0, -(args[0] != 0 ? args[0] : 1));
break;
case 'H':
- if( argc != 2 ) {
+ if( argc == 0 ) {
+ Display_SetCursor(Term, 0, 0);
}
- else {
+ else if( argc == 1 ) {
+ Display_SetCursor(Term, args[0]-1, 0);
+ }
+ else if( argc == 2 ) {
// Adjust 1-based cursor position to 0-based
Display_SetCursor(Term, args[0]-1, args[1]-1);
}
break;
// Set scrolling region
case 'r':
- Display_SetScrollArea(Term, args[0], (args[1] - args[0]));
+ Display_SetScrollArea(Term, args[0]-1, (args[1] - args[0])+1);
break;
case 's':
}
free(cmd);
// Prompt
- SetCursorPos(giTerminal_Height-1, 1);
+ SetCursorPos(giTerminal_Height, 1);
printf("\x1B[2K"); // Clear line
- printf("[%s]", Window_GetName(NULL));
+ int prompt_len = printf("[%s] ", Window_GetName(NULL));
+ SetCursorPos(giTerminal_Height, prompt_len+1);
+ fflush(stdout);
}
}
}
}
}
+void Cmd_me(char *ArgString)
+{
+ tServer *srv = Window_GetServer(NULL);
+ if( srv && Window_IsChat(NULL) ) {
+ Window_AppendMessage(NULL, MSG_CLASS_ACTION, Server_GetNick(srv), "%s", ArgString);
+ Server_SendCommand(srv, "PRIVMSG %s :\1ACTION %s\1\n", Window_GetName(NULL), ArgString);
+ }
+}
+
const struct {
const char *Name;
void (*Fcn)(char *ArgString);
#include <string.h>
#include <net.h>
#include <stdarg.h>
+#include <acess/devices/pty.h>
#include "common.h"
#include "input.h"
{
printf("\x1B[?1047l");
printf("Quit: %s\n", gsExitReason);
+
+ // stty +echo,canon
+ struct ptymode mode = {.InputMode = 0, .OutputMode = 0};
+ mode.InputMode = PTYIMODE_CANON|PTYIMODE_ECHO;
+ _SysIOCtl(0, PTY_IOCTL_SETMODE, &mode);
}
void Exit(const char *Reason)
ACurses_Init();
printf("\x1B[?1047h");
- printf("\x1B[%i;%ir", 1, giTerminal_Height-1);
-
- SetCursorPos(giTerminal_Height-1, 1);
- printf("[(status)] ");
+ printf("\x1B[%i;%ir", 2, giTerminal_Height-2);
// HACK: Static server entry
// UCC (University [of Western Australia] Computer Club) IRC Server
- tServer *starting_server = Server_Connect( "UCC", "130.95.13.18", 6667 );
+// tServer *starting_server = Server_Connect( "UCC", "130.95.13.18", 6667 );
// Freenode (#osdev)
-// gWindow_Status.Server = Server_Connect( "Freenode", "89.16.176.16", 6667 );
+ tServer *starting_server = Server_Connect( "Freenode", "84.240.3.129", 6667 );
// Local servers
// gWindow_Status.Server = Server_Connect( "VMHost", "10.0.2.2", 6667 );
// gWindow_Status.Server = Server_Connect( "BitlBee", "192.168.1.39", 6667 );
- if( !starting_server )
- return -1;
-
Windows_SetStatusServer(starting_server);
+ Windows_RepaintCurrent();
+ SetCursorPos(giTerminal_Height-1, 1);
+ printf("[(status)] ");
MainLoop();
int MainLoop(void)
{
- SetCursorPos(giTerminal_Height-1, 1);
+ SetCursorPos(giTerminal_Height, 1);
printf("[(status)] ");
fflush(stdout);
+ // stty -echo,canon
+ struct ptymode mode = {.InputMode = 0, .OutputMode = 0};
+ _SysIOCtl(0, PTY_IOCTL_SETMODE, &mode);
+
for( ;; )
{
fd_set readfds, errorfds;
void Redraw_Screen(void)
{
printf("\x1B[2J"); // Clear screen
- printf("\x1B[0;0H"); // Reset cursor
+ printf("\x1B[H"); // Reset cursor
Windows_RepaintCurrent();
}
// === GLOBALS ===
const char *gsUsername = "user";
const char *gsHostname = "acess";
-const char *gsRealName = "Acess2 IRC Client";
+const char *gsRealName = "An Acess User";
const char *gsNickname = "acess";
+const char *gsVersionResponse = "Acess2 IRC Client / Running on some VM probably";
tServer *gpServers;
// === CODE ===
const char *Server_GetNick(const tServer *Server)
{
- return Server->Nick;
+ return Server ? Server->Nick : "NULL";
+}
+const char *Server_GetName(const tServer *Server)
+{
+ return Server ? Server->Name : "NULL";
}
void Server_SendCommand(tServer *Server, const char *Format, ...)
{
tWindow *win;
if( strcmp(Dest, Server->Nick) == 0 ) {
- win = Windows_GetByName(Server, Src);
- if(!win)
- win = Window_Create(Server, Src);
+ win = Windows_GetByNameOrCreate(Server, Src);
}
else {
- win = Windows_GetByName(Server, Dest);
- if(!win)
- win = Window_Create(Server, Dest);
+ win = Windows_GetByNameOrCreate(Server, Dest);
+ }
+
+ // Detect CTCP
+ if( Message[0] == '\1' && Message[strlen(Message)-1] == '\1' )
+ {
+ Message += 1;
+ // message is a CTCP command
+ if( strcmp(Message, "VERSION\1") == 0 )
+ {
+ // Put a message in the status window, and reply
+ Window_AppendMessage(WINDOW_STATUS, MSG_CLASS_CLIENT, Server->Name, "CTCP VERSION request from %s", Src);
+ // - Always reply via NOTICE
+ Server_SendCommand(Server, "NOTICE %s :\1VERSION %s\1", Src, gsVersionResponse);
+ }
+ else if( strncmp(Message, "ACTION ", 7) == 0 )
+ {
+ Message += 7;
+ // Put a message in the status window, and reply
+ Window_AppendMessage(win, MSG_CLASS_ACTION, Src, "%.*s", (int)(strlen(Message)-1), Message);
+ }
+ else
+ {
+ Window_AppendMessage(WINDOW_STATUS, MSG_CLASS_CLIENT, Server->Name, "Unknown CTCP '%s' from %s",
+ Message, Src);
+ }
+ }
+ else
+ {
+ Window_AppendMessage(win, MSG_CLASS_MESSAGE, Src, "%s", Message);
}
- Window_AppendMessage(win, MSG_CLASS_MESSAGE, Src, "%s", Message);
}
/**
Window_AppendMsg_TopicTime( Windows_GetByNameOrCreate(Server, user), message, timestamp );
break;
case 353: // /NAMES list
+ // TODO: Parse the /names list and store it locally, dump to window when end is seen
// <user> = <channel> :list
// '=' was eaten in and set to message
user = GetValue(Line, &pos); // Actually channel
message = Line + pos + 1; // List
- // TODO: parse and store
Window_AppendMessage( Windows_GetByNameOrCreate(Server, user), MSG_CLASS_CLIENT, "NAMES", message );
break;
case 366: // end of /NAMES list
// <user> <channel> :msg
// - Ignored
break;
+
+ case 1: // welcome
+ case 2: // host name and version (text)
+ case 3: // host uptime
+ case 4: // host name, version, and signature
+ case 5: // parameters
+
+ case 250: // Highest connection count
+ case 251: // user count (network)
+ case 252: // Operator count
+ case 253: // Unidentified connections
+ case 254: // Channel count
+ case 255: // Server's stats
+ case 265: // Local users -- min max :Text representation
+ case 266: // Global users (same as above)
+
case 372: // MOTD Data
case 375: // MOTD Start
case 376: // MOTD End
+ Window_AppendMessage( WINDOW_STATUS, MSG_CLASS_WALL, Server->Name, "%s", message);
+ break;
default:
//printf("[%s] %i %s\n", Server->Name, num, message);
if( strcmp(cmd, "NOTICE") == 0 )
{
const char *class = GetValue(Line, &pos);
- _SysDebug("NOTICE class='%s'", class);
-
const char *message = (Line[pos] == ':') ? Line + pos + 1 : GetValue(Line, &pos);
+ _SysDebug("NOTICE class='%s'", class);
- //printf("[%s] NOTICE %s: %s\n", Server->Name, ident, message);
char *ident_bang = strchr(ident, '!');
if( ident_bang ) {
*ident_bang = '\0';
Window_AppendMsg_Part( Windows_GetByNameOrCreate(Server, channel), ident, "" );
}
+ else if( strcmp(cmd, "MODE" ) == 0 )
+ {
+ // ident MODE channel flags nick[ nick...]
+ const char *channel = GetValue(Line, &pos);
+ const char *flags = GetValue(Line, &pos);
+ const char *args = Line + pos;
+
+ Window_AppendMsg_Mode( Windows_GetByNameOrCreate(Server, channel), ident, flags, args );
+ }
+ else if( strcmp(cmd, "KICK" ) == 0 )
+ {
+ // ident KICK channel nick :reason
+ const char *channel = GetValue(Line, &pos);
+ const char *nick = GetValue(Line, &pos);
+ const char *message = Line + pos + 1;
+
+ Window_AppendMsg_Kick( Windows_GetByNameOrCreate(Server, channel), ident, nick, message );
+ if( strcmp(nick, Server->Nick) == 0 ) {
+ // Oh, that was me :(
+ // - what do?
+ }
+ }
else
{
Window_AppendMessage( WINDOW_STATUS, MSG_CLASS_BARE, Server->Name, "Unknown command '%s' %s", cmd, Line);
extern int Server_HandleIncoming(tServer *Server);
extern const char *Server_GetNick(const tServer *Server);
+extern const char *Server_GetName(const tServer *Server);
extern void Server_SendCommand(tServer *Server, const char *Format, ...) __attribute__((format(__printf__,2,3)));
#include <stdio.h> // TODO: replace with calls into ACurses_*
#include <stdlib.h>
#include <assert.h>
+#include "server.h"
+#include <ctype.h>
struct sMessage
{
time_t Timestamp;
enum eMessageClass Class;
char *Source; // Pointer to the end of `Data`
+ size_t PrefixLen;
char Data[];
};
// === PROTOTYPES ===
void Windows_RepaintCurrent(void);
+size_t WordBreak(const char *Line, size_t avail);
+size_t Windows_int_PaintMessagePrefix(const tMessage *Message, bool EnablePrint);
+size_t Windows_int_PaintMessageLine(const tMessage *Message, size_t Offset, bool EnablePrint);
+ int Windows_int_GetMessageLines(const tMessage *Message);
int Windows_int_PaintMessage(tMessage *Message);
// === GLOBALS ===
tWindow gWindow_Status = {
NULL, NULL, NULL, // No next, empty list, no server
- 0, {""} // No activity, empty name (rendered as status)
+ 0, {"(status)"} // No activity, empty name (rendered as status)
};
tWindow *gpWindows = &gWindow_Status;
tWindow *gpCurrentWindow = &gWindow_Status;
// === CODE ===
void Windows_RepaintCurrent(void)
{
- tMessage *msg = gpCurrentWindow->Messages;
-
// TODO: Title bar?
+ SetCursorPos(1, 1);
+ printf("\x1b[37;44m\x1b[2K%s\x1b[0m\n", gpCurrentWindow->Name);
+
+ int avail_rows = giTerminal_Height - 3;
// Note: This renders from the bottom up
- for( int y = giTerminal_Height - 1; y -- && msg; msg = msg->Next)
+ tMessage *msg = gpCurrentWindow->Messages;
+ for( int y = avail_rows; msg && y > 0; )
{
- y -= Windows_int_PaintMessage(msg);
+ int lines = Windows_int_GetMessageLines(msg);
+ y -= lines;
+ size_t ofs = 0;
+ size_t len;
+ int i = 0;
+ do {
+ SetCursorPos(2 + y+i, 1);
+ len = Windows_int_PaintMessageLine(msg, ofs, (y+i >= 0));
+ ofs += len;
+ i ++;
+ } while( len > 0 );
+ msg = msg->Next;
}
+ // Status line is our department
+ SetCursorPos(giTerminal_Height-1, 1);
+ printf("\x1b[37;44m\x1b[2K[%s] [%s/%s]\x1b[0m", Server_GetNick(gpCurrentWindow->Server),
+ Server_GetName(gpCurrentWindow->Server), gpCurrentWindow->Name);
+ fflush(stdout);
// Bottom line is rendered by the prompt
+}
+
+size_t WordBreak(const char *Line, size_t avail)
+{
+ // If sufficient space, don't need to break on a word
+ if( strlen(Line) < avail )
+ return strlen(Line);
+
+ // Search backwards from end of space for a non-alpha-numeric character
+ size_t ret = avail-1;
+ while( ret > 0 && isalnum(Line[ret]) )
+ ret --;
+
+ // if one wasn't found in a sane area, just split
+ if( ret < avail-20 || ret == 0 )
+ return avail;
+ return ret;
}
-int Windows_int_PaintMessage(tMessage *Message)
+size_t Windows_int_PaintMessagePrefix(const tMessage *Message, bool EnablePrint)
{
- printf("\33[T"); // Scroll down 1 (free space below)
- SetCursorPos(giTerminal_Height-2, 1);
+ size_t len = 0;
+
+ unsigned long seconds_today = Message->Timestamp/1000 % (24 * 3600);
+ if(EnablePrint)
+ printf("%02i:%02i:%02i ", seconds_today/3600, (seconds_today/60)%60, seconds_today%60);
+ else
+ len += snprintf(NULL, 0, "%02i:%02i:%02i ", seconds_today/3600, (seconds_today/60)%60, seconds_today%60);
- size_t prefixlen = 0;
- prefixlen += printf("%02i:%02i:%02i ", (Message->Timestamp/3600)%24, (Message->Timestamp/60)%60, Message->Timestamp%60);
+ const char *format;
switch(Message->Class)
{
- case MSG_CLASS_BARE: break;
+ case MSG_CLASS_BARE:
+ format = "";
+ break;
case MSG_CLASS_CLIENT:
if(Message->Source)
- prefixlen += printf("[%s] ", Message->Source);
- prefixlen += printf("-!- ");
+ format = "[%s] -!- ";
+ else
+ format = "-!- ";
break;
case MSG_CLASS_WALL:
- prefixlen += printf("[%s] ", Message->Source);
+ format = "[%s] ";
break;
case MSG_CLASS_MESSAGE:
- prefixlen += printf("<%s> ", Message->Source);
+ format = "<%s> ";
break;
case MSG_CLASS_ACTION:
- prefixlen += printf("* %s ", Message->Source);
+ format = "* %s ";
break;
}
- int avail = giTerminal_Width - prefixlen;
- int msglen = strlen(Message->Data);
-
- int nLines = 1;
- printf("%.*s", avail, Message);
- while( msglen > avail ) {
- msglen -= avail;
- Message += avail;
- printf("\33[T");
- SetCursorPos(giTerminal_Height-2, prefixlen+1);
- printf("%.*s", avail, Message);
- nLines ++;
+
+ if( EnablePrint )
+ len += printf(format, Message->Source);
+ else
+ len += snprintf(NULL, 0, format, Message->Source);
+
+ return len;
+}
+
+size_t Windows_int_PaintMessageLine(const tMessage *Message, size_t Offset, bool EnablePrint)
+{
+ if( Message->Data[Offset] == '\0' ) {
+ return 0;
}
+ size_t avail = giTerminal_Width - Message->PrefixLen;
+ const char *msg_data = Message->Data + Offset;
+ int used = WordBreak(msg_data+Offset, avail);
+
+ if( EnablePrint )
+ {
+ if( Offset == 0 )
+ Windows_int_PaintMessagePrefix(Message, true);
+ else
+ printf("\x1b[%iC", Message->PrefixLen);
+ printf("%.*s", used, msg_data);
+ }
+
+ if( msg_data[used] == '\0' )
+ return 0;
+
+ return Offset + used;
+}
+
+int Windows_int_GetMessageLines(const tMessage *Message)
+{
+ assert(Message->PrefixLen);
+ const size_t avail = giTerminal_Height - Message->PrefixLen;
+ const size_t msglen = strlen(Message->Data);
+ size_t offset = 0;
+ int nLines = 0;
+ do {
+ offset += WordBreak(Message->Data+offset, avail);
+ nLines ++;
+ } while(offset < msglen);
return nLines;
}
msg->Class = Class;
msg->Source = (Source ? msg->Data + len+1 : NULL);
+ msg->Timestamp = _SysTimestamp();
+
va_start(args, Message);
vsnprintf(msg->Data, len+1, Message, args);
va_end(args);
+ if( Source ) {
+ strcpy(msg->Source, Source);
+ }
+
+ msg->PrefixLen = Windows_int_PaintMessagePrefix(msg, false);
+
msg->Next = Window->Messages;
Window->Messages = msg;
// Scroll if needed, and redraw?
// - Lazy option of draw at bottom of screen
printf("\33[s"); // Save cursor
- Windows_int_PaintMessage(msg);
- printf("\x1b[u"); // Restore cursor
+ size_t offset = 0, len;
+ do {
+ printf("\33[T"); // Scroll down 1 (free space below)
+ SetCursorPos(giTerminal_Height-2, 1);
+ len = Windows_int_PaintMessageLine(Message, offset, true);
+ offset += len;
+ } while( len > 0 );
+ printf("\33[u"); // Restore cursor
+ fflush(stdout);
}
}
{
Window_AppendMessage(Window, MSG_CLASS_CLIENT, NULL, "Topic set by %s at %s", User, Timestamp);
}
+void Window_AppendMsg_Kick(tWindow *Window, const char *Operator, const char *Nick, const char *Reason)
+{
+ Window_AppendMessage(Window, MSG_CLASS_CLIENT, NULL, "%s was kicked from %s by %s [%s]",
+ Nick, Window->Name, Operator, Reason);
+}
+void Window_AppendMsg_Mode(tWindow *Window, const char *Operator, const char *Flags, const char *Args)
+{
+ Window_AppendMessage(Window, MSG_CLASS_CLIENT, NULL, "mode/%s [%s %s] by %s",
+ Window->Name, Flags, Args, Operator);
+}
extern void Window_AppendMsg_Join(tWindow *Window, const char *Usermask);
extern void Window_AppendMsg_Quit(tWindow *Window, const char *Usermask, const char *Reason);
extern void Window_AppendMsg_Part(tWindow *Window, const char *Usermask, const char *Reason);
+extern void Window_AppendMsg_Kick(tWindow *Window, const char *Operator, const char *Nick, const char *Reason);
+extern void Window_AppendMsg_Mode(tWindow *Window, const char *Operator, const char *Flags, const char *Args);
extern void Window_AppendMsg_Topic(tWindow *Window, const char *Topic);
extern void Window_AppendMsg_TopicTime(tWindow *Window, const char *User, const char *Timestmap);
*/
#include <net.h>
#include <stdint.h>
-#include <stdio.h>
+//#include <stdio.h>
+#include <stdlib.h>
#define DEBUG 0
static inline uint32_t htonl(uint32_t v)
*/
static int Net_ParseIPv4Addr(const char *String, uint8_t *Addr)
{
- int i = 0;
int j;
- int val;
+ const char *pos = String;
- for( j = 0; String[i] && j < 4; j ++ )
+ for( j = 0; *pos && j < 4; j ++ )
{
- val = 0;
- for( ; String[i] && String[i] != '.'; i++ )
- {
- if('0' > String[i] || String[i] > '9') {
- #if DEBUG
- printf("0<c<9 expected, '%c' found\n", String[i]);
- #endif
- return 0;
- }
- val = val*10 + String[i] - '0';
+ char *end;
+ unsigned long val = strtoul(pos, &end, 10);
+ if( *end && *end != '.' ) {
+ #if DEBUG
+ _SysDebug("%s: Unexpected character, '%c' found", __func__, *end);
+ #endif
+ return 0;
+ }
+ if( *pos == '.' ) {
+ #if DEBUG
+ _SysDebug("%s: Two dots in a row", __func__);
+ #endif
+ return 0;
}
if(val > 255) {
#if DEBUG
- printf("val > 255 (%i)\n", val);
+ _SysDebug("%s: val > 255 (%i)", __func__, val);
#endif
return 0;
}
+ #if DEBUG
+ _SysDebug("%s: Comp '%.*s' = %lu", __func__, end - pos, pos, val);
+ #endif
Addr[j] = val;
- if(String[i] == '.')
- i ++;
+ pos = end;
+
+ if(*pos == '.')
+ pos ++;
}
if( j != 4 ) {
#if DEBUG
- printf("4 parts expected, %i found\n", j);
+ _SysDebug("%s: 4 parts expected, %i found", __func__, j);
#endif
return 0;
}
- if(String[i] != '\0') {
+ if(*pos != '\0') {
#if DEBUG
- printf("EOS != '\\0', '%c'\n", String[i]);
+ _SysDebug("%s: EOS != '\\0', '%c'", __func__, *pos);
#endif
return 0;
}