/*-*-c++-*-
 * $Id: qlcrashdoc.h,v 1.1 2002/01/28 15:38:33 holzheu Exp $
 *
 * This file is part of qlcrash, a GUI for the dump-analysis tool lcrash.
 *
 * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *
 * Authors:
 * Michael Geselbracht (let@users.sourceforge.net)
 * Fritz Elfert (elfert@de.ibm.com)
 * Michael Holzheu (holzheu@de.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version. See the file COPYING for more
 * information.
 */
#ifndef QLCRASHDOC_H
#define QLCRASHDOC_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

// include files for QT
#include <qobject.h>
#include <qdict.h>
#include <qvaluelist.h>
#include <qstringlist.h>

// STL
#include <utility>

#include "crashtypes.h"
#include "cnconsole.h"
#include "cdisassemble.h"
#include "ctraceitem.h"
#include "ctaskitem.h"
#include "csymtabitem.h"

class QListViewItemIterator;
class QTimer;
template<class T> class QCache;

// forward declaration of the QLcrash classes and structs
class QLcrashView;
class CParser;
class CChildManager;
class CConfigManager;
class StructViewItem;
class CListView;
struct TreeNode;

typedef QValueList<std::pair<QString, QStringList> > CLowcoreList;

class QLcrashDoc : public QObject
{
	Q_OBJECT

public:
	QLcrashDoc(CConfigManager* cm, QObject* parent, const char* name=0);
	~QLcrashDoc();

	void setLCrashPath(QString);

	// extract type from print expression
	QString getTypeFromExpression(const QString& expr) const;
	
	// extrace address from print expression
	QString getAddressFromExpression(const QString& expr) const;

	// prepare different views for CMainWin
	CListView* getTree(const QString& name, const QString& addr, const QString& type);
	CListView* getArray(const QString& addr, const QString& type, int number);
	CListView* getWalk(const QString& member, const QString& addr, const QString& type);

	// get and return a piece of dump data
	const unsigned char* getDump(const QString& addr);
	
	// return the disassembled code of a function
	QValueList<CDisassemble> getDisassemble(const QString& fkt);
	
	// return a stack trace for a task (the `trace' command). the first item contains
	// only the task name (as function())
	QValueList<CTraceItem> getTrace(const QString& addr);
	
	// return a task list with task name and address
	QValueList<CTaskItem> getTaskList();
	
	// return a list containing all global symbols
	QValueList<CSymtabItem> getGlobalSymbols();

	// print type info on main console
	void printTypeInfo(const QString& type, const QString& name);

	// display whatis-output on main console
	void printWhatis(const QString& type, const QString& name);

	// print stack trace for given task struct address
	void printTrace(const QString& addr);

	// print a message to the main console
	void print(const QString& str);

	// print an error message to the main console
	void printErr(const QString& str);

	// returns if lcrash is still in its initialization phase
	inline bool waitForInit() const {
		return oWaitForInit;
	}

	inline CConfigManager* configManager() {
		return oConfigManager;
	}

	// used for future >>cross dump<< feature
	inline int targetWordSize() const {
		return sizeof(long);
	}
	bool targetLittleEndian() const;

	// the source of the help page for qlcrash
	QString helpHomeURL();

	// return the directory where the last file has been saved
	QString lastSaveDir() const;

	// set the directory of the last recently saved file
	void setLastSaveDir(const QString& lsd);

	/* return format options for the lcrash print command
	*/
	QString printFormat() const;

	void loadConfig();
	void runCrash();
	
	/* return lcrash help text
	*/
	QString getLcrashHelp();
	
	// S/390 specific
	QStringList* s390AvailableLogs();
	QStringList* s390AvailableViews(const QString& log);
	QString s390dbfText(const QString& log, const QString& view);
	bool haveDebugFeature();
	void s390dbfSaveToFile(const QString& log, const QString& view, const QString& file);
	CLowcoreList getTraceLowcore(const QString& addr);

signals:
	void sigToConsole(CNConsole*, QString);
	void sigErrToConsole(CNConsole*, QString);
	void sigNewGraph(CListView*);
	void sigTaskList(TaskListType*);
	void sigExit(bool);
	void sigLCrashReady();
	void sigBusy(bool);
	void sigSetup();
	
public slots:
	void slotFromConsole(CNConsole*, QString);
	void slotRestart();
	void slotSetup();
	
protected slots:
	void slotChildDied();
	void slotStdoutFromChild(QString);
	void slotStderrFromChild(QString);
	void slotInitialTimeout();
	
protected:
	void createTree(CNConsole*, QString typeHint=QString::null);
	void createTreeTraverse(TreeNode* root, CListView* rootItem, QString typeHint=QString::null);
	void createTreeTraverse(TreeNode* parentNode, StructViewItem* parentItem, QDict<QString>* map, StructViewItem** after, const QString& type);
	
	/* create a walk using list_head member of a struct
	*/
	CListView* getListHead(const QString& name, const QString& addr, const QString& type);
	
	/* return size info for the specified type. it also acts as a workaround for
	   the 'sizeof "unsigned long"' problem of lcrash.
	   if an error occurs, 0 is returned.
	*/
	int sizeinfo(const QString& type, const QString& name=QString::null);
	
	/* returns a map of members for structure s */
	QDict<QString>* structInfo(QString s);
	
	/* get a token from a trace output */
	int getTraceLowcoreToken(const char* str, QString&);
	
private:
	CParser* oParser;
	CChildManager* oChildManager;
	CConfigManager* oConfigManager;
	bool oGraph;
	QDict<QDict<QString> > oTypeMap;
	bool oWaitForInit;
	bool oQuitAfterChildExit;
	bool lcrashIsReady;
	QTimer* oInitialTimer;
	QCache<unsigned char>* oDumpCache;
	signed char oS390dbf;
	QString oLastSaveDir;
};

#endif // QLCRASHDOC_H
