summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/games/minesweep/minefield.cpp4
-rw-r--r--noncore/net/opieirc/ircsession.cpp8
-rw-r--r--noncore/todayplugins/stockticker/libstocks/csv.c3
3 files changed, 10 insertions, 5 deletions
diff --git a/noncore/games/minesweep/minefield.cpp b/noncore/games/minesweep/minefield.cpp
index 72c05b0..1987ea5 100644
--- a/noncore/games/minesweep/minefield.cpp
+++ b/noncore/games/minesweep/minefield.cpp
@@ -323,425 +323,427 @@ void MineField::setState( State st )
}
void MineField::setup( int level )
{
lev = level;
setState( Waiting );
//viewport()->setUpdatesEnabled( FALSE );
int i;
for ( i = 0; i < numCols*numRows; i++ )
delete mines[i];
delete[] mines;
switch( lev ) {
case 1:
numRows = 9 ;
numCols = 9 ;
minecount = 12;
break;
case 2:
numRows = 13;
numCols = 13;
minecount = 33;
break;
case 3:
numCols = 18;
numRows = 18;
minecount = 66 ;
break;
}
mines = new Mine* [numRows*numCols];
for ( i = 0; i < numCols*numRows; i++ )
mines[i] = new Mine( this );
nonminecount = numRows*numCols - minecount;
mineguess = minecount;
emit mineCount( mineguess );
Mine::paletteChange();
if ( availableRect.isValid() )
setCellSize(findCellSize());
// viewport()->setUpdatesEnabled( TRUE );
//viewport()->repaint( TRUE );
updateContents( 0, 0, numCols*cellSize, numRows*cellSize );
updateGeometry();
}
void MineField::drawContents( QPainter * p, int clipx, int clipy, int clipw, int cliph )
{
int c1 = clipx / cellSize;
int c2 = ( clipx + clipw - 1 ) / cellSize;
int r1 = clipy / cellSize;
int r2 = ( clipy + cliph - 1 ) / cellSize;
for ( int c = c1; c <= c2 ; c++ ) {
for ( int r = r1; r <= r2 ; r++ ) {
int x = c * cellSize;
int y = r * cellSize;
Mine *m = mine( r, c );
if ( m )
m->paint( p, colorGroup(), QRect(x, y, cellSize, cellSize ) );
}
}
}
// Chicken and egg problem: We need to know how big the parent is
// before we can decide how big to make the table.
void MineField::setAvailableRect( const QRect &r )
{
availableRect = r;
int newCellSize = findCellSize();
if ( newCellSize == cellSize ) {
setCellSize( cellSize );
} else {
viewport()->setUpdatesEnabled( FALSE );
setCellSize( newCellSize );
viewport()->setUpdatesEnabled( TRUE );
viewport()->repaint( TRUE );
}
}
int MineField::findCellSize()
{
int w = availableRect.width() - 2;
int h = availableRect.height() - 2;
int cellsize;
cellsize = QMIN( w/numCols, h/numRows );
cellsize = QMIN( QMAX( cellsize, minGrid ), maxGrid );
return cellsize;
}
void MineField::setCellSize( int cellsize )
{
int b = 2;
int w2 = cellsize*numCols;
int h2 = cellsize*numRows;
int w = QMIN( availableRect.width(), w2+b );
int h = QMIN( availableRect.height(), h2+b );
//
// Don't rely on the change in cellsize to force a resize,
// as it's possible to have the same size cells when going
// from a large play area to a small one.
//
resizeContents(w2, h2);
if ( availableRect.height() < h2 &&
availableRect.width() - w > style().scrollBarExtent().width() ) {
w += style().scrollBarExtent().width();
}
setGeometry( availableRect.x() + (availableRect.width()-w)/2,
availableRect.y() + (availableRect.height()-h)/2, w, h );
cellSize = cellsize;
}
void MineField::placeMines()
{
int mines = minecount;
while ( mines ) {
int col = int((double(rand()) / double(RAND_MAX)) * numCols);
int row = int((double(rand()) / double(RAND_MAX)) * numRows);
Mine* m = mine( row, col );
if ( m && !m->isMined() && m->state() == Mine::Hidden ) {
m->setMined( TRUE );
mines--;
}
}
}
void MineField::updateCell( int r, int c )
{
updateContents( c*cellSize, r*cellSize, cellSize, cellSize );
}
void MineField::contentsMousePressEvent( QMouseEvent* e )
{
int c = e->pos().x() / cellSize;
int r = e->pos().y() / cellSize;
if ( onBoard( r, c ) )
cellPressed( r, c );
else
currCol = currRow = -1;
}
void MineField::contentsMouseReleaseEvent( QMouseEvent* e )
{
int c = e->pos().x() / cellSize;
int r = e->pos().y() / cellSize;
if ( onBoard( r, c ) && c == currCol && r == currRow )
cellClicked( r, c );
if ( flagAction == FlagNext ) {
flagAction = NoAction;
}
}
/*
state == Waiting means no "hold"
*/
void MineField::cellPressed( int row, int col )
{
if ( state() == GameOver )
return;
currRow = row;
currCol = col;
if ( state() == Playing )
holdTimer->start( 150, TRUE );
}
void MineField::held()
{
flagAction = FlagNext;
updateMine( currRow, currCol );
ignoreClick = TRUE;
}
void MineField::keyPressEvent( QKeyEvent* e )
{
#if defined(Q_WS_QWS) || defined(_WS_QWS_)
flagAction = ( e->key() == Key_Up ) ? FlagOn : NoAction;
#else
flagAction = ( ( e->state() & ShiftButton ) == ShiftButton ) ? FlagOn : NoAction;
#endif
}
void MineField::keyReleaseEvent( QKeyEvent* )
{
flagAction = NoAction;
}
int MineField::getHint( int row, int col )
{
int hint = 0;
for ( int c = col-1; c <= col+1; c++ )
for ( int r = row-1; r <= row+1; r++ ) {
Mine* m = mine( r, c );
if ( m && m->isMined() )
hint++;
}
return hint;
}
void MineField::setHint( int row, int col )
{
Mine *m = mine( row, col );
if ( !m )
return;
int hint = getHint( row, col );
if ( !hint ) {
for ( int c = col-1; c <= col+1; c++ )
for ( int r = row-1; r <= row+1; r++ ) {
Mine* m = mine( r, c );
if ( m && m->state() == Mine::Hidden ) {
m->activate( TRUE );
nonminecount--;
setHint( r, c );
updateCell( r, c );
}
}
}
m->setHint( hint );
updateCell( row, col );
}
/*
Only place mines after first click, since it is pointless to
kill the player before the game has started.
*/
void MineField::cellClicked( int row, int col )
{
if ( state() == GameOver )
return;
if ( state() == Waiting ) {
Mine* m = mine( row, col );
if ( !m )
return;
m->setState( Mine::Empty );
nonminecount--;
placeMines();
setState( Playing );
emit gameStarted();
updateMine( row, col );
} else { // state() == Playing
holdTimer->stop();
if ( ignoreClick )
ignoreClick = FALSE;
else
updateMine( row, col );
}
}
void MineField::updateMine( int row, int col )
{
Mine* m = mine( row, col );
if ( !m )
return;
bool wasFlagged = m->state() == Mine::Flagged;
bool wasEmpty = m->state() == Mine::Empty;
m->activate( flagAction == NoAction );
if ( m->state() == Mine::Exploded ) {
emit gameOver( FALSE );
setState( GameOver );
return;
} else if ( m->state() == Mine::Empty ) {
setHint( row, col );
if ( !wasEmpty )
nonminecount--;
}
if ( flagAction != NoAction ) {
if ( m->state() == Mine::Flagged ) {
if (mineguess > 0) {
--mineguess;
emit mineCount( mineguess );
if ( m->isMined() )
--minecount;
} else {
m->setState(Mine::Hidden);
}
} else if ( wasFlagged ) {
++mineguess;
emit mineCount( mineguess );
if ( m->isMined() )
++minecount;
}
}
updateCell( row, col );
if ( !minecount && !mineguess || !nonminecount ) {
emit gameOver( TRUE );
setState( GameOver );
}
}
void MineField::showMines()
{
for ( int c = 0; c < numCols; c++ )
for ( int r = 0; r < numRows; r++ ) {
Mine* m = mine( r, c );
if ( !m )
continue;
if ( m->isMined() && m->state() == Mine::Hidden )
m->setState( Mine::Mined );
if ( !m->isMined() && m->state() == Mine::Flagged )
m->setState( Mine::Wrong );
updateCell( r, c );
}
}
void MineField::paletteChange( const QPalette &o )
{
Mine::paletteChange();
QScrollView::paletteChange( o );
}
void MineField::writeConfig(Config& cfg) const
{
cfg.setGroup("Field");
cfg.writeEntry("Level",lev);
QString grid="";
if ( stat == Playing ) {
for ( int x = 0; x < numCols; x++ )
for ( int y = 0; y < numRows; y++ ) {
char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat
const Mine* m = mine( y, x );
int st = (int)m->state(); if ( m->isMined() ) st+=5;
grid += code + st;
}
}
cfg.writeEntry("Grid",grid);
}
void MineField::readConfig(Config& cfg)
{
cfg.setGroup("Field");
lev = cfg.readNumEntry("Level",1);
setup(lev);
flagAction = NoAction;
ignoreClick = FALSE;
currRow = currCol = 0;
QString grid = cfg.readEntry("Grid");
int x;
if ( !grid.isEmpty() ) {
int i=0;
minecount=0;
mineguess=0;
for ( x = 0; x < numCols; x++ ) {
for ( int y = 0; y < numRows; y++ ) {
char code='A'+(x*17+y*101)%21; // Reduce the urge to cheat
int st = (char)(QChar)grid[i++]-code;
Mine* m = mine( y, x );
+ if (!m)
+ continue;
if ( st >= 5 ) {
st-=5;
m->setMined(TRUE);
minecount++;
mineguess++;
}
m->setState((Mine::MineState)st);
switch ( m->state() ) {
case Mine::Flagged:
if (m->isMined())
minecount--;
mineguess--;
break;
case Mine::Empty:
--nonminecount;
break;
default:
break;
}
}
}
for ( x = 0; x < numCols; x++ ) {
for ( int y = 0; y < numRows; y++ ) {
Mine* m = mine( y, x );
- if ( m->state() == Mine::Empty )
+ if ( m && m->state() == Mine::Empty )
m->setHint(getHint(y,x));
}
}
}
setState( Playing );
emit mineCount( mineguess );
}
QSize MineField::sizeHint() const
{
if ( qApp->desktop()->width() >= 240 )
return QSize(200,200);
else
return QSize(160, 160);
}
diff --git a/noncore/net/opieirc/ircsession.cpp b/noncore/net/opieirc/ircsession.cpp
index c8d7869..d87ff80 100644
--- a/noncore/net/opieirc/ircsession.cpp
+++ b/noncore/net/opieirc/ircsession.cpp
@@ -1,216 +1,218 @@
#include "ircsession.h"
#include "ircmessageparser.h"
#include "ircchannelperson.h"
#include "ircversion.h"
IRCSession::IRCSession(QObject *parent, IRCServer *server)
: QObject(parent)
{
m_server = server;
m_connection = new IRCConnection(m_server);
m_parser = new IRCMessageParser(this);
connect(m_connection, SIGNAL(messageArrived(IRCMessage*)), this, SLOT(handleMessage(IRCMessage*)));
connect(m_parser, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput)));
connect(m_connection, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput)));
}
IRCSession::~IRCSession() {
/* We want this to get deleted automatically */
m_channels.setAutoDelete(TRUE);
m_people.setAutoDelete(TRUE);
delete m_parser;
delete m_connection;
}
void IRCSession::beginSession() {
m_connection->doConnect();
}
void IRCSession::join(QString channelname) {
m_connection->sendLine("JOIN " + channelname);
}
void IRCSession::quit(){
m_connection->sendLine("QUIT :[OI] I'm too good to need a reason");
}
void IRCSession::quit(QString message){
m_connection->sendLine("QUIT :" + message);
}
void IRCSession::topic(IRCChannel *channel, QString message){
m_connection->sendLine("TOPIC :" + channel->channelname() + " " + message);
}
void IRCSession::mode(IRCChannel *channel, QString message){
m_connection->sendLine("MODE " + channel->channelname() + " " + message);
}
void IRCSession::mode(IRCPerson *person, QString message){
m_connection->sendLine("MODE " + person->nick() + " " + message);
}
void IRCSession::mode(QString message){
m_connection->sendLine("MODE " + message);
}
void IRCSession::raw(QString message){
m_connection->sendLine(message);
}
void IRCSession::kick(IRCChannel *channel, IRCPerson *person) {
m_connection->sendLine("KICK " + channel->channelname() + " " + person->nick() +" :0wn3d - no reason");
}
void IRCSession::op(IRCChannel *channel, IRCPerson *person) {
m_connection->sendLine("MODE " + channel->channelname() + " +ooo " + person->nick());
}
void IRCSession::kick(IRCChannel *channel, IRCPerson *person, QString message) {
m_connection->sendLine("KICK " + channel->channelname() + " " + person->nick() +" :" + message);
}
void IRCSession::sendMessage(IRCPerson *person, QString message) {
m_connection->sendLine("PRIVMSG " + person->nick() + " :" + message);
}
void IRCSession::sendMessage(IRCChannel *channel, QString message) {
m_connection->sendLine("PRIVMSG " + channel->channelname() + " :" + message);
}
void IRCSession::sendAction(IRCChannel *channel, QString message) {
m_connection->sendLine("PRIVMSG " + channel->channelname() + " :\001ACTION " + message + "\001");
}
void IRCSession::sendAction(IRCPerson *person, QString message) {
m_connection->sendLine("PRIVMSG " + person->nick() + " :\001ACTION " + message + "\001");
}
bool IRCSession::isSessionActive() {
return m_connection->isConnected();
}
bool IRCSession::isLoggedIn() {
return m_connection->isLoggedIn();
}
void IRCSession::endSession() {
if (m_connection->isLoggedIn())
quit(APP_VERSION);
else
m_connection->close();
}
void IRCSession::part(IRCChannel *channel) {
m_connection->sendLine("PART " + channel->channelname() + " :" + APP_VERSION);
}
void IRCSession::setValidUsermodes(const QString &modes) {
m_validUsermodes = modes;
}
void IRCSession::setValidChannelmodes(const QString &modes) {
m_validChannelmodes = modes;
}
void IRCSession::updateNickname(const QString &oldNickname, const QString &newNickname) {
QList<IRCChannel> channels;
IRCOutput output;
if (oldNickname == m_server->nick()) {
m_server->setNick(newNickname);
output = IRCOutput(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg(newNickname));
channels = m_channels;
}
else {
IRCPerson *person = getPerson(oldNickname);
if(!person) {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person")));
return;
}
getChannelsByPerson(person, channels);
output = IRCOutput(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg(oldNickname).arg(newNickname));
}
QListIterator<IRCChannel> it(channels);
for (;it.current(); ++it) {
IRCChannelPerson *chanperson = it.current()->getPerson(oldNickname);
- it.current()->removePerson(chanperson);
- chanperson->setNick(newNickname);
- it.current()->addPerson(chanperson);
+ if (chanperson) {
+ it.current()->removePerson(chanperson);
+ chanperson->setNick(newNickname);
+ it.current()->addPerson(chanperson);
+ }
}
emit updateChannels();
output.addParam(new QString(newNickname));
emit outputReady(output);
}
IRCChannel *IRCSession::getChannel(QString channelname) {
QListIterator<IRCChannel> it(m_channels);
for (; it.current(); ++it) {
if (it.current()->channelname() == channelname) {
return it.current();
}
}
return 0;
}
IRCPerson *IRCSession::getPerson(QString nickname) {
QListIterator<IRCPerson> it(m_people);
for (; it.current(); ++it) {
if (it.current()->nick() == nickname) {
return it.current();
}
}
return 0;
}
void IRCSession::getChannelsByPerson(IRCPerson *person, QList<IRCChannel> &channels) {
QListIterator<IRCChannel> it(m_channels);
for (; it.current(); ++it) {
if (it.current()->getPerson(person->nick()) != 0) {
channels.append(it.current());
}
}
}
void IRCSession::addPerson(IRCPerson *person) {
m_people.append(person);
}
void IRCSession::addChannel(IRCChannel *channel) {
m_channels.append(channel);
}
void IRCSession::removeChannel(IRCChannel *channel) {
m_channels.remove(channel);
}
void IRCSession::removePerson(IRCPerson *person) {
m_people.remove(person);
}
void IRCSession::handleMessage(IRCMessage *message) {
m_parser->parse(message);
}
void IRCSession::whois(const QString &nickname) {
m_connection->whois(nickname);
}
void IRCSession::sendCTCPPing(const QString &nickname) {
m_connection->sendCTCPPing(nickname);
}
void IRCSession::sendCTCPRequest(const QString &nickname, const QString &type, const QString &args) {
m_connection->sendCTCPRequest(nickname, type, args);
}
void IRCSession::sendCTCPReply(const QString &nickname, const QString &type, const QString &args) {
m_connection->sendCTCPReply(nickname, type, args);
}
diff --git a/noncore/todayplugins/stockticker/libstocks/csv.c b/noncore/todayplugins/stockticker/libstocks/csv.c
index 6170bed..86d8607 100644
--- a/noncore/todayplugins/stockticker/libstocks/csv.c
+++ b/noncore/todayplugins/stockticker/libstocks/csv.c
@@ -1,405 +1,406 @@
/* libstocks - Library to get current stock quotes from Yahoo Finance
*
* Copyright (C) 2000 Eric Laeuffer
*
* 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#define __CSV_C__
#ifndef __UNIX__
#define __UNIX__
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef __WINDOWS__
#include <mbstring.h>
#endif
#include "csv.h"
#include "stocks.h"
#include "lists.h"
#define DATE_LENGTH 7 /*YYMMDD*/
const char *months[12]=
{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
/*****************************************************************************/
/* Replacement of the strtok function. This one forgets "delim" when it is */
/* between two commas. */
/* Thanks to Julio Lucas who has told me the bug and has proposed me a patch */
/*****************************************************************************/
char *csv_strtok(char *s, char *delim)
{
static char *next=NULL;
char *temp, *first;
int comma=0;
if (s!=NULL) first=s;
else first=next;
temp=first;
if (*temp=='\0') return NULL;
while (*temp!='\0' && ((*temp!=*delim) || comma))
{
if (*temp=='"') comma ^= 1;
temp++;
}
if (*temp=='\0') next=temp;
else
{
*temp='\0';
next=temp+1;
}
return first;
}
/*****************************************************************************/
/* Parses the csv file and return a list of stocks structure. */
/* *csv points on the csv file in memory */
/* count defines the country, because csv depends on the country */
/*****************************************************************************/
stock *parse_csv_file(char *csv)
{
char *line;
char *end_line;
char *ptr;
char *date;
char *time;
char *name;
char *symbol;
stock *StockPtr=NULL;
stock *LastStockPtr=NULL;
/* Used to return the pointer to the list */
stock *FirstStockPtr=NULL;
/* used to see if symbol is valid */
int valid;
char *test;
line = csv;
end_line = csv;
while ((end_line = strstr(line, "\n")))
{
*end_line = 0;
/* Check if symbol valid */
/* if 1 "N/A" then ok because Indices have N/A for volume */
/* if 4 "N/A" then ok because Mutual funds have */
/* if 5 "N/A" then ok because currencies have */
/* So if >5 then stock not valid */
test = line;
valid = 0;
while ( (test = strstr(test, "N/A")) )
{
valid ++;
test = test +3;
}
if (valid < 6)
{
/* This Symbol is valid */
StockPtr = malloc_stock();
ptr = csv_strtok(line, ",");
if (!ptr) return 0;
symbol = (char *)malloc(strlen(ptr)+1);
if (symbol==NULL)
{
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
strcpy((char *)(symbol), ptr);
StockPtr->Symbol = symbol;
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
name = (char *)malloc(strlen(ptr)+1);
if (name==NULL)
{
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
strcpy((char *)(name), ptr);
StockPtr->Name = name;
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->CurrentPrice));
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
date = (char *)malloc(strlen(ptr)+1);
if (date==NULL)
{
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
strcpy((char *)(date), ptr);
StockPtr->Date = date;
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
time = (char *)malloc(strlen(ptr)+1);
if (time==NULL)
{
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
strcpy((char *)(time), ptr);
StockPtr->Time = time;
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->Variation));
StockPtr->Pourcentage = 100 * StockPtr->Variation /
(StockPtr->CurrentPrice - StockPtr->Variation);
StockPtr->LastPrice = StockPtr->CurrentPrice - StockPtr->Variation;
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->OpenPrice));
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->MaxPrice));
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->MinPrice));
ptr = csv_strtok(NULL, ",");
if (!ptr) return 0;
StockPtr->Volume = atoi(ptr);
if( !FirstStockPtr )
{
FirstStockPtr = StockPtr;
StockPtr->PreviousStock = 0;
}
StockPtr->NextStock = 0;
if (LastStockPtr)
{
LastStockPtr->NextStock = StockPtr;
StockPtr->PreviousStock = LastStockPtr;
}
LastStockPtr = StockPtr;
}
else
{
/* this symbol is not valid */
/* Set the stock struct just with Symbol, all other are NULL */
/* This can be used to see if the symbol has been reached are not */
StockPtr = malloc_stock();
ptr = csv_strtok(line, ",");
if (!ptr) return 0;
symbol = (char *)malloc(strlen(ptr)+1);
if (symbol==NULL)
{
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
strcpy((char *)(symbol), ptr);
StockPtr->Symbol = symbol;
if( !FirstStockPtr )
{
FirstStockPtr = StockPtr;
StockPtr->PreviousStock = 0;
}
StockPtr->NextStock = 0;
if (LastStockPtr)
{
LastStockPtr->NextStock = StockPtr;
StockPtr->PreviousStock = LastStockPtr;
}
LastStockPtr = StockPtr;
}
end_line++;
line = end_line;
}
return (FirstStockPtr);
}
/*****************************************************************************/
/* Parses the history quotes file and return a stock structure list. */
/*****************************************************************************/
stock *parse_csv_history_file(char *csv_file)
{
char *line;
char *end_line;
char *ptr;
int day;
char smonth[10];
int month;
int year;
char *date;
int i;
int test;
stock *StockPtr=NULL;
stock *LastStockPtr=NULL;
/* Used to return the pointer to the list */
stock *FirstStockPtr=NULL;
line = csv_file;
end_line = csv_file;
/* do not use the first line */
- end_line = strstr(line, "\n");
+ if (!(end_line = strstr(line, "\n")))
+ return 0;
*end_line = 0;
end_line++;
line = end_line;
while ((end_line = strstr(line, "\n")))
{
*end_line = 0;
StockPtr = malloc_stock();
/* Date */
ptr = strtok(line, ",");
if (!ptr) return 0;
sscanf(ptr,"%d-%3s-%d",&day,smonth,&year);
i=0;
#ifdef __UNIX__
while((test=strcasecmp(months[i], smonth))) i++;
#elif __WINDOWS__
while(test=_mbsnbicmp(months[i], smonth, strlen(months[i]))) i++;
#endif
month = i+1;
date = (char *)malloc(DATE_LENGTH);
if (date==NULL)
{
fprintf(stderr,"Memory allocating error (%s line %d)\n"
,__FILE__, __LINE__);
exit(1);
}
sprintf(date,"%.2d%.2d%.2d", year, month, day);
StockPtr->Date = date;
/* Open */
ptr = strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->OpenPrice));
/* High */
ptr = strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->MaxPrice));
/* Low */
ptr = strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->MinPrice));
/* Close */
ptr = strtok(NULL, ",");
if (!ptr) return 0;
sscanf(ptr,"%f",&(StockPtr->LastPrice));
/* Volume */
ptr = strtok(NULL, ",");
if (!ptr)
/* It seems to be an indice */
/* No volume for indices */
StockPtr->Volume = 0;
else
StockPtr->Volume = atoi(ptr);
if( !FirstStockPtr )
{
FirstStockPtr = StockPtr;
StockPtr->PreviousStock = 0;
}
StockPtr->NextStock = 0;
if (LastStockPtr)
{
LastStockPtr->NextStock = StockPtr;
StockPtr->PreviousStock = LastStockPtr;
}
LastStockPtr = StockPtr;
end_line++;
line = end_line;
}
return (FirstStockPtr);
}