<commit_before>#include "condor_common.h"
#include "_condor_fix_resource.h"
#include <iostream.h>
#include <time.h>

#ifndef WIN32
#include <netinet/in.h>
#include <sys/param.h>
#endif  // ifndef WIN32

#include "condor_classad.h"
#include "condor_parser.h"
#include "sched.h"
#include "condor_status.h"
#include "manager.h"
#include "condor_debug.h"
#include "condor_config.h"
#include "condor_network.h"
#include "internet.h"
#include "fdprintf.h"
#include "condor_io.h"
#include "condor_attributes.h"

#include "../condor_daemon_core.V6/condor_daemon_core.h"

#include "condor_collector.h"
#include "collector_engine.h"
#include "HashTable.h"
#include "hashkey.h"

#include "condor_uid.h"

// about self
static char *_FileName_ = __FILE__;		// used by EXCEPT
char* mySubSystem = "COLLECTOR";		// used by Daemon Core

// variables from the config file
char *Log;
char *CollectorLog;
char *CondorAdministrator;
char *CondorDevelopers;
int   MaxCollectorLog;
int   ClientTimeout;
int   QueryTimeout;
int   MachineUpdateInterval;
int	  MasterCheckInterval;

// the heart of the collector ...
CollectorEngine collector;

// misc functions
#ifndef WIN32
extern	   void initializeReporter (void);
#endif
extern "C" int  SetSyscalls () {return 0;}
extern     void initializeParams();

// misc external variables
extern int errno;

// internal function prototypes
void houseKeeper(void);
int receive_update(Service*, int, Stream*);
int receive_query(Service*, int, Stream*);
void process_query(AdTypes, ClassAd &, Stream *);
int sigint_handler(Service*, int);
int sighup_handler(Service*, int);
#ifndef WIN32
void sigpipe_handler();
void unixsigint_handler();
void unixsighup_handler();
#endif

void usage(char* name)
{
	dprintf(D_ALWAYS,"Usage: %s [-f] [-b] [-t] [-p <port>]\n",name );
	exit( 1 );
}

// main initialization code... the real main() is in DaemonCore
main_init(int argc, char *argv[])
{
	char** ptr;

	// handle collector-specific command line args
	if(argc > 1)
	{
		usage(argv[0]);
	}
	for(ptr = argv + 1; *ptr; ptr++)
	{
		if(ptr[0][0] != '-')
		{
			usage(argv[0]);
		}
		switch(ptr[0][1])
		{
		// place collector-specific command line args here
		default:
			usage(argv[0]);
		}
	}

	// read in various parameters from condor_config
    initializeParams ();

    // install signal handlers
	daemonCore->Register_Signal(DC_SIGINT,"SIGINT",(SignalHandler)sigint_handler,"sigint_handler()");

#ifndef WIN32
	install_sig_handler (SIGINT, unixsigint_handler);
#endif	// of ifndef WIN32

#ifndef WIN32
	// setup routine to report to condor developers
	initializeReporter ();
#endif

	// install command handlers for queries
	daemonCore->Register_Command(QUERY_STARTD_ADS,"QUERY_STARTD_ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);
	daemonCore->Register_Command(QUERY_SCHEDD_ADS,"QUERY_SCHEDD_ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);
	daemonCore->Register_Command(QUERY_MASTER_ADS,"QUERY_MASTER_ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);
	daemonCore->Register_Command(QUERY_CKPT_SRVR_ADS,"QUERY_CKPT_SRVR_ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);

	// install command handlers for updates
	daemonCore->Register_Command(UPDATE_STARTD_AD,"UPDATE_STARTD_AD",
		(CommandHandler)receive_update,"receive_update",NULL,WRITE);
	daemonCore->Register_Command(UPDATE_SCHEDD_AD,"UPDATE_SCHEDD_AD",
		(CommandHandler)receive_update,"receive_update",NULL,WRITE);
	daemonCore->Register_Command(UPDATE_MASTER_AD,"UPDATE_MASTER_AD",
		(CommandHandler)receive_update,"receive_update",NULL,WRITE);
	daemonCore->Register_Command(UPDATE_CKPT_SRVR_AD,"UPDATE_CKPT_SRVR_AD",
		(CommandHandler)receive_update,"receive_update",NULL,WRITE);

	// set up housekeeper
	if (!collector.scheduleHousekeeper(MachineUpdateInterval))
	{
		EXCEPT ("Could not initialize housekeeper");
	}

	// set up routine to check on masters
	if (!collector.scheduleDownMasterCheck (MasterCheckInterval))
	{
		EXCEPT ("Could not initialize master check routine");
	}

	// set up so that private ads from startds are collected as well
	collector.wantStartdPrivateAds (true);

	return TRUE;
}

int
receive_query(Service* s, int command, Stream* sock)
{
    struct sockaddr_in *from;
	AdTypes whichAds;
	ClassAd ad;

	from = sock->endpoint();

	sock->decode();
	sock->timeout(ClientTimeout);
    if (!ad.get((Stream &)*sock) || !sock->eom())
    {
        dprintf(D_ALWAYS,"Failed to receive query on TCP: aborting\n");
        return FALSE;
    }

    // cancel timeout --- collector engine sets up its own timeout for
    // collecting further information
    sock->timeout(0);

    switch (command)
    {
	  case QUERY_STARTD_ADS:
		dprintf (D_ALWAYS, "Got QUERY_STARTD_ADS\n");
		whichAds = STARTD_AD;
		break;

	  case QUERY_SCHEDD_ADS:
		dprintf (D_ALWAYS, "Got QUERY_SCHEDD_ADS\n");
		whichAds = SCHEDD_AD;
		break;

	  case QUERY_MASTER_ADS:
		dprintf (D_ALWAYS, "Got QUERY_MASTER_ADS\n");
		whichAds = MASTER_AD;
		break;

	  case QUERY_CKPT_SRVR_ADS:
		dprintf (D_ALWAYS, "Got QUERY_CKPT_SRVR_ADS\n");
		whichAds = CKPT_SRVR_AD;
		break;

	  case QUERY_STARTD_PVT_ADS:
		dprintf (D_ALWAYS, "Got QUERY_STARTD_PVT_ADS\n");
		whichAds = STARTD_PVT_AD;
		break;

	  default:
		dprintf(D_ALWAYS,"Unknown command %d in process_query()\n", command);
		whichAds = (AdTypes) -1;
    }

    if (whichAds != (AdTypes) -1)
		process_query (whichAds, ad, sock);

    // all done; let daemon core will clean up connection
	return TRUE;
}

int
receive_update(Service *s, int command, Stream* sock)
{
    int	insert;
	sockaddr_in *from;
	ClassAd *ad;

	// TCP commands should not allow for classad updates.  In fact the collector
	// will not collect on TCP to discourage use of TCP for classad updates.
	if ( sock->type() == Stream::reli_sock ) {
		// update via tcp; sorry buddy, use udp or you're outa here!
		dprintf(D_ALWAYS,"Received UPDATE command via TCP; ignored\n");
		// let daemon core clean up the socket
		return TRUE;
	}

	// get endpoint
	from = sock->endpoint();

    // process the given command
	if (!(ad = collector.collect (command,(Sock*)sock,from,insert)))
	{
		if (insert == -2)
		{
			// this should never happen assuming we never register QUERY
			// commands with daemon core, but it cannot hurt to check...
			dprintf (D_ALWAYS,"Got QUERY command (%d); not supported for UDP\n",
						command);
		}
	}

	// let daemon core clean up the socket
	return TRUE;
}

static ClassAd *__query__;
static Stream *__sock__;
static int __numAds__;
static int __failed__;

int
query_scanFunc (ClassAd *ad)
{
    int more = 1;

    if ((*ad) >= (*__query__))
    {
        if (!__sock__->code(more) || !ad->put(*__sock__))
        {
            dprintf (D_ALWAYS,
                    "Error sending query result to client -- aborting\n");
            return 0;
        }
        __numAds__++;
    }

    return 1;
}

void
process_query (AdTypes whichAds, ClassAd &query, Stream *sock)
{
	int		more;

	// here we set up a network timeout of a longer duration
	sock->timeout(QueryTimeout);

	// set up for hashtable scan
	__query__ = &query;
	__numAds__ = 0;
	__sock__ = sock;
	sock->encode();
	if (!collector.walkHashTable (whichAds, query_scanFunc))
	{
		dprintf (D_ALWAYS, "Error sending query response\n");
	}

	// end of query response ...
	more = 0;
	if (!sock->code(more))
	{
		dprintf (D_ALWAYS, "Error sending EndOfResponse (0) to client\n");
	}

	// flush the output
	if (!sock->end_of_message())
	{
		dprintf (D_ALWAYS, "Error flushing CEDAR socket\n");
	}

	dprintf (D_ALWAYS, "(Sent %d ads in response to query)\n", __numAds__);
}

#ifndef WIN32
int 	__mailer__;

int
reportScanFunc (ClassAd *ad)
{
	char buffer[2048];
	int	 x;

	if (!ad->LookupString (ATTR_NAME, buffer)) return 0;
	fdprintf (__mailer__, "%15s", buffer);

	if (!ad->LookupString (ATTR_ARCH, buffer)) return 0;
	fdprintf (__mailer__, "%8s", buffer);

	if (!ad->LookupString (ATTR_OPSYS, buffer)) return 0;
	fdprintf (__mailer__, "%14s", buffer);

	if (!ad->LookupInteger (ATTR_MIPS, x)) x = -1;
	fdprintf (__mailer__, "%4d", x);

	if (!ad->LookupInteger (ATTR_KFLOPS, x)) x = -1;
	fdprintf (__mailer__, "%7d", x);

	if (!ad->LookupString (ATTR_STATE, buffer)) return 0;
	fdprintf (__mailer__, "%10s\n", buffer);

	return 1;
}

void
reportToDevelopers (void)
{
	char	whoami[128];
	char	buffer[128];

	if (get_machine_name (whoami) == -1) {
		dprintf (D_ALWAYS, "Unable to get_machine_name()\n");
		return;
	}

	sprintf (buffer, "Condor Collector (%s):  Monthly report\n", whoami);
	if ((__mailer__ = email (buffer, CondorDevelopers)) < 0) {
		dprintf (D_ALWAYS, "Didn't send monthly report (couldn't open url)\n");
		return;
	}

	if (!collector.walkHashTable (STARTD_AD, reportScanFunc)) {
		dprintf (D_ALWAYS, "Error sending monthly report\n");
	}

	close (__mailer__);
	return;
}
#endif  // of ifndef WIN32

// signal handlers ...
int
sigint_handler (Service *s, int sig)
{
    dprintf (D_ALWAYS, "Killed by SIGINT\n");
    exit(0);
	return FALSE;	// never will get here; just to satisfy c++
}

#ifndef WIN32
void
unixsigint_handler ()
{
    dprintf (D_ALWAYS, "Killed by SIGINT\n");
    exit(0);
	return;	// never will get here; just to satisfy c++
}

#endif	// of ifndef WIN32

int
main_config()
{
    initializeParams();
	return TRUE;
}

int
main_shutdown_fast()
{
	exit(0);
	return TRUE;	// to satisfy c++
}

int
main_shutdown_graceful()
{
	exit(0);
	return TRUE;	// to satisfy c++
}

<commit_msg>Registered command to query startd private ads<commit_after>#include "condor_common.h"
#include "_condor_fix_resource.h"
#include <iostream.h>
#include <time.h>

#ifndef WIN32
#include <netinet/in.h>
#include <sys/param.h>
#endif  // ifndef WIN32

#include "condor_classad.h"
#include "condor_parser.h"
#include "sched.h"
#include "condor_status.h"
#include "manager.h"
#include "condor_debug.h"
#include "condor_config.h"
#include "condor_network.h"
#include "internet.h"
#include "fdprintf.h"
#include "condor_io.h"
#include "condor_attributes.h"

#include "../condor_daemon_core.V6/condor_daemon_core.h"

#include "condor_collector.h"
#include "collector_engine.h"
#include "HashTable.h"
#include "hashkey.h"

#include "condor_uid.h"

// about self
static char *_FileName_ = __FILE__;		// used by EXCEPT
char* mySubSystem = "COLLECTOR";		// used by Daemon Core

// variables from the config file
char *Log;
char *CollectorLog;
char *CondorAdministrator;
char *CondorDevelopers;
int   MaxCollectorLog;
int   ClientTimeout;
int   QueryTimeout;
int   MachineUpdateInterval;
int	  MasterCheckInterval;

// the heart of the collector ...
CollectorEngine collector;

// misc functions
#ifndef WIN32
extern	   void initializeReporter (void);
#endif
extern "C" int  SetSyscalls () {return 0;}
extern     void initializeParams();

// misc external variables
extern int errno;

// internal function prototypes
void houseKeeper(void);
int receive_update(Service*, int, Stream*);
int receive_query(Service*, int, Stream*);
void process_query(AdTypes, ClassAd &, Stream *);
int sigint_handler(Service*, int);
int sighup_handler(Service*, int);
#ifndef WIN32
void sigpipe_handler();
void unixsigint_handler();
void unixsighup_handler();
#endif

void usage(char* name)
{
	dprintf(D_ALWAYS,"Usage: %s [-f] [-b] [-t] [-p <port>]\n",name );
	exit( 1 );
}

// main initialization code... the real main() is in DaemonCore
main_init(int argc, char *argv[])
{
	char** ptr;

	// handle collector-specific command line args
	if(argc > 1)
	{
		usage(argv[0]);
	}
	for(ptr = argv + 1; *ptr; ptr++)
	{
		if(ptr[0][0] != '-')
		{
			usage(argv[0]);
		}
		switch(ptr[0][1])
		{
		// place collector-specific command line args here
		default:
			usage(argv[0]);
		}
	}

	// read in various parameters from condor_config
    initializeParams ();

    // install signal handlers
	daemonCore->Register_Signal(DC_SIGINT,"SIGINT",(SignalHandler)sigint_handler,"sigint_handler()");

#ifndef WIN32
	install_sig_handler (SIGINT, unixsigint_handler);
#endif	// of ifndef WIN32

#ifndef WIN32
	// setup routine to report to condor developers
	initializeReporter ();
#endif

	// install command handlers for queries
	daemonCore->Register_Command(QUERY_STARTD_ADS,"QUERY_STARTD_ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);
	daemonCore->Register_Command(QUERY_STARTD_ADS,"QUERY_STARTD_PVT__ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);
	daemonCore->Register_Command(QUERY_SCHEDD_ADS,"QUERY_SCHEDD_ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);
	daemonCore->Register_Command(QUERY_MASTER_ADS,"QUERY_MASTER_ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);
	daemonCore->Register_Command(QUERY_CKPT_SRVR_ADS,"QUERY_CKPT_SRVR_ADS",
		(CommandHandler)receive_query,"receive_query",NULL,READ);

	// install command handlers for updates
	daemonCore->Register_Command(UPDATE_STARTD_AD,"UPDATE_STARTD_AD",
		(CommandHandler)receive_update,"receive_update",NULL,WRITE);
	daemonCore->Register_Command(UPDATE_SCHEDD_AD,"UPDATE_SCHEDD_AD",
		(CommandHandler)receive_update,"receive_update",NULL,WRITE);
	daemonCore->Register_Command(UPDATE_MASTER_AD,"UPDATE_MASTER_AD",
		(CommandHandler)receive_update,"receive_update",NULL,WRITE);
	daemonCore->Register_Command(UPDATE_CKPT_SRVR_AD,"UPDATE_CKPT_SRVR_AD",
		(CommandHandler)receive_update,"receive_update",NULL,WRITE);

	// set up housekeeper
	if (!collector.scheduleHousekeeper(MachineUpdateInterval))
	{
		EXCEPT ("Could not initialize housekeeper");
	}

	// set up routine to check on masters
	if (!collector.scheduleDownMasterCheck (MasterCheckInterval))
	{
		EXCEPT ("Could not initialize master check routine");
	}

	// set up so that private ads from startds are collected as well
	collector.wantStartdPrivateAds (true);

	return TRUE;
}

int
receive_query(Service* s, int command, Stream* sock)
{
    struct sockaddr_in *from;
	AdTypes whichAds;
	ClassAd ad;

	from = sock->endpoint();

	sock->decode();
	sock->timeout(ClientTimeout);
    if (!ad.get((Stream &)*sock) || !sock->eom())
    {
        dprintf(D_ALWAYS,"Failed to receive query on TCP: aborting\n");
        return FALSE;
    }

    // cancel timeout --- collector engine sets up its own timeout for
    // collecting further information
    sock->timeout(0);

    switch (command)
    {
	  case QUERY_STARTD_ADS:
		dprintf (D_ALWAYS, "Got QUERY_STARTD_ADS\n");
		whichAds = STARTD_AD;
		break;

	  case QUERY_SCHEDD_ADS:
		dprintf (D_ALWAYS, "Got QUERY_SCHEDD_ADS\n");
		whichAds = SCHEDD_AD;
		break;

	  case QUERY_MASTER_ADS:
		dprintf (D_ALWAYS, "Got QUERY_MASTER_ADS\n");
		whichAds = MASTER_AD;
		break;

	  case QUERY_CKPT_SRVR_ADS:
		dprintf (D_ALWAYS, "Got QUERY_CKPT_SRVR_ADS\n");
		whichAds = CKPT_SRVR_AD;
		break;

	  case QUERY_STARTD_PVT_ADS:
		dprintf (D_ALWAYS, "Got QUERY_STARTD_PVT_ADS\n");
		whichAds = STARTD_PVT_AD;
		break;

	  default:
		dprintf(D_ALWAYS,"Unknown command %d in process_query()\n", command);
		whichAds = (AdTypes) -1;
    }

    if (whichAds != (AdTypes) -1)
		process_query (whichAds, ad, sock);

    // all done; let daemon core will clean up connection
	return TRUE;
}

int
receive_update(Service *s, int command, Stream* sock)
{
    int	insert;
	sockaddr_in *from;
	ClassAd *ad;

	// TCP commands should not allow for classad updates.  In fact the collector
	// will not collect on TCP to discourage use of TCP for classad updates.
	if ( sock->type() == Stream::reli_sock ) {
		// update via tcp; sorry buddy, use udp or you're outa here!
		dprintf(D_ALWAYS,"Received UPDATE command via TCP; ignored\n");
		// let daemon core clean up the socket
		return TRUE;
	}

	// get endpoint
	from = sock->endpoint();

    // process the given command
	if (!(ad = collector.collect (command,(Sock*)sock,from,insert)))
	{
		if (insert == -2)
		{
			// this should never happen assuming we never register QUERY
			// commands with daemon core, but it cannot hurt to check...
			dprintf (D_ALWAYS,"Got QUERY command (%d); not supported for UDP\n",
						command);
		}
	}

	// let daemon core clean up the socket
	return TRUE;
}

static ClassAd *__query__;
static Stream *__sock__;
static int __numAds__;
static int __failed__;

int
query_scanFunc (ClassAd *ad)
{
    int more = 1;

    if ((*ad) >= (*__query__))
    {
        if (!__sock__->code(more) || !ad->put(*__sock__))
        {
            dprintf (D_ALWAYS,
                    "Error sending query result to client -- aborting\n");
            return 0;
        }
        __numAds__++;
    }

    return 1;
}

void
process_query (AdTypes whichAds, ClassAd &query, Stream *sock)
{
	int		more;

	// here we set up a network timeout of a longer duration
	sock->timeout(QueryTimeout);

	// set up for hashtable scan
	__query__ = &query;
	__numAds__ = 0;
	__sock__ = sock;
	sock->encode();
	if (!collector.walkHashTable (whichAds, query_scanFunc))
	{
		dprintf (D_ALWAYS, "Error sending query response\n");
	}

	// end of query response ...
	more = 0;
	if (!sock->code(more))
	{
		dprintf (D_ALWAYS, "Error sending EndOfResponse (0) to client\n");
	}

	// flush the output
	if (!sock->end_of_message())
	{
		dprintf (D_ALWAYS, "Error flushing CEDAR socket\n");
	}

	dprintf (D_ALWAYS, "(Sent %d ads in response to query)\n", __numAds__);
}

#ifndef WIN32
int 	__mailer__;

int
reportScanFunc (ClassAd *ad)
{
	char buffer[2048];
	int	 x;

	if (!ad->LookupString (ATTR_NAME, buffer)) return 0;
	fdprintf (__mailer__, "%15s", buffer);

	if (!ad->LookupString (ATTR_ARCH, buffer)) return 0;
	fdprintf (__mailer__, "%8s", buffer);

	if (!ad->LookupString (ATTR_OPSYS, buffer)) return 0;
	fdprintf (__mailer__, "%14s", buffer);

	if (!ad->LookupInteger (ATTR_MIPS, x)) x = -1;
	fdprintf (__mailer__, "%4d", x);

	if (!ad->LookupInteger (ATTR_KFLOPS, x)) x = -1;
	fdprintf (__mailer__, "%7d", x);

	if (!ad->LookupString (ATTR_STATE, buffer)) return 0;
	fdprintf (__mailer__, "%10s\n", buffer);

	return 1;
}

void
reportToDevelopers (void)
{
	char	whoami[128];
	char	buffer[128];

	if (get_machine_name (whoami) == -1) {
		dprintf (D_ALWAYS, "Unable to get_machine_name()\n");
		return;
	}

	sprintf (buffer, "Condor Collector (%s):  Monthly report\n", whoami);
	if ((__mailer__ = email (buffer, CondorDevelopers)) < 0) {
		dprintf (D_ALWAYS, "Didn't send monthly report (couldn't open url)\n");
		return;
	}

	if (!collector.walkHashTable (STARTD_AD, reportScanFunc)) {
		dprintf (D_ALWAYS, "Error sending monthly report\n");
	}

	close (__mailer__);
	return;
}
#endif  // of ifndef WIN32

// signal handlers ...
int
sigint_handler (Service *s, int sig)
{
    dprintf (D_ALWAYS, "Killed by SIGINT\n");
    exit(0);
	return FALSE;	// never will get here; just to satisfy c++
}

#ifndef WIN32
void
unixsigint_handler ()
{
    dprintf (D_ALWAYS, "Killed by SIGINT\n");
    exit(0);
	return;	// never will get here; just to satisfy c++
}

#endif	// of ifndef WIN32

int
main_config()
{
    initializeParams();
	return TRUE;
}

int
main_shutdown_fast()
{
	exit(0);
	return TRUE;	// to satisfy c++
}

int
main_shutdown_graceful()
{
	exit(0);
	return TRUE;	// to satisfy c++
}

<|endoftext|>


<commit_before>f89d751e-ad58-11e7-b62f-ac87a332f658<commit_msg>Nope, didn't work, now it does<commit_after>fa0e3af0-ad58-11e7-8db2-ac87a332f658<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: testjavavm.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: jl $ $Date: 2002-07-05 09:48:04 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <jni.h>

//#include <iostream>
#include <stdio.h>
#include <rtl/process.h>

#include <vos/dynload.hxx>

#include <cppuhelper/servicefactory.hxx>
#include <cppuhelper/weak.hxx>
#include <cppuhelper/bootstrap.hxx>

#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/java/XJavaVM.hpp>
#include <com/sun/star/registry/XImplementationRegistration.hpp>
#include <com/sun/star/java/XJavaThreadRegister_11.hpp>

//#include <cppuhelper/implbase1.hxx>

using namespace std;
using namespace rtl;
using namespace cppu;
using namespace vos;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
//using namespace com::sun::star::reflection;
using namespace com::sun::star::lang;
using namespace com::sun::star::registry;
using namespace com::sun::star::java;

#if defined(W32)
#define LIBJEN    "jen.dll"
#elif defined(UNX)
#define LIBJEN    "libjen.so"
#endif

sal_Bool testJavaVM(const Reference< XMultiServiceFactory > & xMgr )
{

      OUString sVMService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.java.JavaVirtualMachine"));
    Reference<XInterface> xXInt= xMgr->createInstance(sVMService);
    if( ! xXInt.is())
        return sal_False;
    Reference<XJavaVM> xVM( xXInt, UNO_QUERY);
    if( ! xVM.is())
        return sal_False;
    Reference<XJavaThreadRegister_11> xreg11(xVM, UNO_QUERY);
    if( ! xreg11.is())
        return sal_False;

    sal_Int8 arId[16];
    rtl_getGlobalProcessId((sal_uInt8*) arId);
    Any anyVM = xVM->getJavaVM( Sequence<sal_Int8>(arId, 16));

    sal_Bool b= xreg11->isThreadAttached();
    xreg11->registerThread();
    b= xreg11->isThreadAttached();
    xreg11->revokeThread();
    b= xreg11->isThreadAttached();

    b= xVM->isVMEnabled();
    b= xVM->isVMStarted();

    b= xVM->isVMEnabled();
    b= xVM->isVMStarted();

    JavaVM* _jvm= *(JavaVM**) anyVM.getValue();
    JNIEnv *p_env;
    if( _jvm->AttachCurrentThread((void**) &p_env, 0))
        return sal_False;

//  jclass aJProg = p_env->FindClass("TestJavaVM");
//  if( p_env->ExceptionOccurred()){
//      p_env->ExceptionDescribe();
//      p_env->ExceptionClear();
//  }
//
//  jmethodID mid= p_env->GetStaticMethodID( aJProg,"main", "([Ljava/lang/String;)V");

    jclass cls = p_env->FindClass( "TestJavaVM");
    if (cls == 0) {
        OSL_TRACE( "Can't find Prog class\n");
        exit(1);
    }

//   jmethodID methid = p_env->GetStaticMethodID( cls, "main", "([Ljava/lang/String;)V");
//    if (methid == 0) {
//        OSL_TRACE("Can't find Prog.main\n");
//        exit(1);
//    }

//    jstring jstr = p_env->NewStringUTF(" from C!");
//    if (jstr == 0) {
//        OSL_TRACE("Out of memory\n");
//        exit(1);
//    }
//    jobjectArray args = p_env->NewObjectArray( 1,
//                        p_env->FindClass("java/lang/String"), jstr);
//    if (args == 0) {
//        OSL_TRACE( "Out of memory\n");
//        exit(1);
//    }
//    p_env->CallStaticVoidMethod( cls, methid, args);

    jmethodID id = p_env->GetStaticMethodID( cls, "getInt", "()I");
    if( id)
    {
        jint _i= p_env->CallStaticIntMethod(cls, id);
    }

    if( p_env->ExceptionOccurred()){
        p_env->ExceptionDescribe();
        p_env->ExceptionClear();
    }

    _jvm->DetachCurrentThread();
    return sal_True;
}

extern
#if (defined UNX) || (defined OS2)
int main( int argc, char * argv[] )
#else
int __cdecl main( int argc, char * argv[] )
#endif
{
    Reference<XSimpleRegistry> xreg= createSimpleRegistry();
    xreg->open( OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")),
                               sal_False, sal_False );

    Reference< XComponentContext > context= bootstrap_InitialComponentContext(xreg);
    Reference<XMultiComponentFactory> fac= context->getServiceManager();
    Reference<XMultiServiceFactory> xMgr( fac, UNO_QUERY);

    sal_Bool bSucc = sal_False;
    try
    {
        OUString sImplReg(RTL_CONSTASCII_USTRINGPARAM(
            "com.sun.star.registry.ImplementationRegistration"));
        Reference<com::sun::star::registry::XImplementationRegistration> xImplReg(
            xMgr->createInstance( sImplReg ), UNO_QUERY );
        OSL_ENSURE( xImplReg.is(), "### no impl reg!" );

        OUString sLibLoader( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary"));
        OUString sJenLib( RTL_CONSTASCII_USTRINGPARAM( LIBJEN ));
        xImplReg->registerImplementation(
            sLibLoader, sJenLib, Reference< XSimpleRegistry >() );

        bSucc = testJavaVM( xMgr );
    }
    catch (Exception & rExc)
    {
        OSL_ENSURE( sal_False, "### exception occured!" );
        OString aMsg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) );
        OSL_TRACE( "### exception occured: " );
        OSL_TRACE( aMsg.getStr() );
        OSL_TRACE( "\n" );
    }

    Reference< XComponent > xCompContext( context, UNO_QUERY );
    xCompContext->dispose();
    printf("javavm %s", bSucc ? "succeeded" : "failed");
//  cout << "javavm " << (bSucc ? "succeeded" : "failed") << " !" << endl;
    return (bSucc ? 0 : -1);
}

<commit_msg>INTEGRATION: CWS uno2 (1.4.42); FILE MERGED 2003/04/08 13:56:34 dbo 1.4.42.2: #107991# UNO shared library component renaming 2003/04/08 10:46:57 jl 1.4.42.1: #i12929#<commit_after>/*************************************************************************
 *
 *  $RCSfile: testjavavm.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2003-04-23 16:15:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <jni.h>

//#include <iostream>
#include <stdio.h>
#include <rtl/process.h>

#include <vos/dynload.hxx>

#include <cppuhelper/servicefactory.hxx>
#include <cppuhelper/weak.hxx>
#include <cppuhelper/bootstrap.hxx>

#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/java/XJavaVM.hpp>
#include <com/sun/star/registry/XImplementationRegistration.hpp>
#include <com/sun/star/java/XJavaThreadRegister_11.hpp>

//#include <cppuhelper/implbase1.hxx>

using namespace std;
using namespace rtl;
using namespace cppu;
using namespace vos;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
//using namespace com::sun::star::reflection;
using namespace com::sun::star::lang;
using namespace com::sun::star::registry;
using namespace com::sun::star::java;

sal_Bool testJavaVM(const Reference< XMultiServiceFactory > & xMgr )
{

      OUString sVMService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.java.JavaVirtualMachine"));
    Reference<XInterface> xXInt= xMgr->createInstance(sVMService);
    if( ! xXInt.is())
        return sal_False;
    Reference<XJavaVM> xVM( xXInt, UNO_QUERY);
    if( ! xVM.is())
        return sal_False;
    Reference<XJavaThreadRegister_11> xreg11(xVM, UNO_QUERY);
    if( ! xreg11.is())
        return sal_False;

    sal_Int8 arId[16];
    rtl_getGlobalProcessId((sal_uInt8*) arId);
    Any anyVM = xVM->getJavaVM( Sequence<sal_Int8>(arId, 16));
    if ( ! anyVM.hasValue())
    {
        OSL_ENSURE(0,"could not get Java VM");
        return sal_False;
    }

    sal_Bool b= xreg11->isThreadAttached();
    xreg11->registerThread();
    b= xreg11->isThreadAttached();
    xreg11->revokeThread();
    b= xreg11->isThreadAttached();

    b= xVM->isVMEnabled();
    b= xVM->isVMStarted();

    b= xVM->isVMEnabled();
    b= xVM->isVMStarted();

    JavaVM* _jvm= *(JavaVM**) anyVM.getValue();
    JNIEnv *p_env;
    if( _jvm->AttachCurrentThread((void**) &p_env, 0))
        return sal_False;

//  jclass aJProg = p_env->FindClass("TestJavaVM");
//  if( p_env->ExceptionOccurred()){
//      p_env->ExceptionDescribe();
//      p_env->ExceptionClear();
//  }
//
//  jmethodID mid= p_env->GetStaticMethodID( aJProg,"main", "([Ljava/lang/String;)V");

    jclass cls = p_env->FindClass( "TestJavaVM");
    if (cls == 0) {
        OSL_TRACE( "Can't find Prog class\n");
        exit(1);
    }

//   jmethodID methid = p_env->GetStaticMethodID( cls, "main", "([Ljava/lang/String;)V");
//    if (methid == 0) {
//        OSL_TRACE("Can't find Prog.main\n");
//        exit(1);
//    }

//    jstring jstr = p_env->NewStringUTF(" from C!");
//    if (jstr == 0) {
//        OSL_TRACE("Out of memory\n");
//        exit(1);
//    }
//    jobjectArray args = p_env->NewObjectArray( 1,
//                        p_env->FindClass("java/lang/String"), jstr);
//    if (args == 0) {
//        OSL_TRACE( "Out of memory\n");
//        exit(1);
//    }
//    p_env->CallStaticVoidMethod( cls, methid, args);

    jmethodID id = p_env->GetStaticMethodID( cls, "getInt", "()I");
    if( id)
    {
        jint _i= p_env->CallStaticIntMethod(cls, id);
    }

    if( p_env->ExceptionOccurred()){
        p_env->ExceptionDescribe();
        p_env->ExceptionClear();
    }

    _jvm->DetachCurrentThread();
    return sal_True;
}

extern
#if (defined UNX) || (defined OS2)
int main( int argc, char * argv[] )
#else
int __cdecl main( int argc, char * argv[] )
#endif
{
    Reference<XSimpleRegistry> xreg= createSimpleRegistry();
    xreg->open( OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")),
                               sal_False, sal_False );

    Reference< XComponentContext > context= bootstrap_InitialComponentContext(xreg);
    Reference<XMultiComponentFactory> fac= context->getServiceManager();
    Reference<XMultiServiceFactory> xMgr( fac, UNO_QUERY);

    sal_Bool bSucc = sal_False;
    try
    {
        OUString sImplReg(RTL_CONSTASCII_USTRINGPARAM(
            "com.sun.star.registry.ImplementationRegistration"));
        Reference<com::sun::star::registry::XImplementationRegistration> xImplReg(
            xMgr->createInstance( sImplReg ), UNO_QUERY );
        OSL_ENSURE( xImplReg.is(), "### no impl reg!" );

        OUString sLibLoader( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary"));
        OUString sJenLib(
            RTL_CONSTASCII_USTRINGPARAM( "javavm.uno" SAL_DLLEXTENSION ) );
        xImplReg->registerImplementation(
            sLibLoader, sJenLib, Reference< XSimpleRegistry >() );

        bSucc = testJavaVM( xMgr );
    }
    catch (Exception & rExc)
    {
        OSL_ENSURE( sal_False, "### exception occured!" );
        OString aMsg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) );
        OSL_TRACE( "### exception occured: " );
        OSL_TRACE( aMsg.getStr() );
        OSL_TRACE( "\n" );
    }

    Reference< XComponent > xCompContext( context, UNO_QUERY );
    xCompContext->dispose();
    printf("javavm %s", bSucc ? "succeeded" : "failed");
//  cout << "javavm " << (bSucc ? "succeeded" : "failed") << " !" << endl;
    return (bSucc ? 0 : -1);
}

<|endoftext|>


<commit_before>#include "condor_common.h"
#include "condor_netaddr.h"
#include "internet.h"

condor_netaddr::condor_netaddr() : maskbit_((unsigned int)-1) {
}

condor_netaddr::condor_netaddr(const condor_sockaddr& base,
		unsigned int maskbit)
: base_(base), maskbit_(maskbit) {
}

bool condor_netaddr::match(const condor_sockaddr& target) const {
	if (maskbit_ == (unsigned int)-1) {
		return false; // uninitialized
	}

	// check if address type is same
	//
	// what is correct policy for matching between IPv4 address and
	// IPv4-mapped-IPv6 address?
	if (base_.get_aftype() != target.get_aftype()) {
		return false;
	}

	const uint32_t* baseaddr = base_.get_address();
	const uint32_t* targetaddr = target.get_address();

	if (!baseaddr || !targetaddr) {
		return false;
	}
	int addr_len = base_.get_address_len();

	int curmaskbit = maskbit_;
	for (int i = 0; i < addr_len; ++i) {
		if (curmaskbit <= 0) { break; }
		uint32_t mask;
		if (curmaskbit > 32) {
			mask = 0xffffffff;
		} else {
			mask = htonl(~(0xffffffff >> curmaskbit));
		}

		if ((*baseaddr & mask) != (*targetaddr & mask)) {
			return false;
		}

		curmaskbit -= 32;
		baseaddr++;
		targetaddr++;
	}

	return true;
}

static int convert_maskaddr_to_maskbit(uint32_t mask_value) {
	int maskbit = 0;

	// get rid of 0's from the right-most side
	while (mask_value > 0 && (mask_value & 1) == 0)
		mask_value >>= 1;

	while (mask_value > 0 && (mask_value & 1) == 1) {
		maskbit++;
		mask_value >>= 1;
	}

	if (mask_value != 0) {
		// the mask address is not well formed
		// e.g. 255.129.0.0, ill-formed mask
		// 1111 1111 | 1000 0001 | 0000 0000 | 0000 0000
		return -1;
	}

	return maskbit;
}

bool condor_netaddr::from_net_string(const char* net) {
	const char* slash = strchr(net, '/');
	const char* net_end = net + strlen(net);
	if (slash) {
		std::string base(net, slash - net);
		if (!base_.from_ip_string(base.c_str()))
			return false;

		// check whether secondary part is number
		char* end_ptr = NULL;
		unsigned long int maskbit = strtoul(slash + 1, &end_ptr, 10);

		// if end_ptr == net_end, the entire secondary part is a number,
		// which means it is the mask bit.
		if (end_ptr == net_end) {
			maskbit_ = maskbit;
		} else {
			// only IPv4 allows secondary part to be address form
			// e.g. 128.105.0.0/255.255.0.0
			if (base_.is_ipv4()) {
				std::string mask(slash + 1, net_end - slash - 1);
				condor_sockaddr maskaddr;

				// convert to numerical representation
				if (!maskaddr.from_ip_string(mask.c_str()) ||
						!maskaddr.is_ipv4())
					return false;

				// convert to mask bit
				const uint32_t* maskaddr_array = maskaddr.get_address();
				maskbit_ = convert_maskaddr_to_maskbit(*maskaddr_array);
				if (maskbit_ == (unsigned int)-1)
					return false;
			}
		}
	} else {
		// if there is no slash ('/'), it should be IPv4 and
		// wildcard format
		//
		// e.g. 128.105.*

		in_addr base;
		in_addr mask;
		if (!is_ipv4_addr_implementation(net, &base, &mask, 1))
			return false;

		base_ = condor_sockaddr(base, 0);
		maskbit_ = convert_maskaddr_to_maskbit(*(uint32_t*)&mask);
		if (maskbit_ == -1)
			return false;
	}
	return true;
}
<commit_msg>Math didn't work for 32-bit bit mask. #2527<commit_after>#include "condor_common.h"
#include "condor_netaddr.h"
#include "internet.h"

condor_netaddr::condor_netaddr() : maskbit_((unsigned int)-1) {
}

condor_netaddr::condor_netaddr(const condor_sockaddr& base,
		unsigned int maskbit)
: base_(base), maskbit_(maskbit) {
}

bool condor_netaddr::match(const condor_sockaddr& target) const {
	if (maskbit_ == (unsigned int)-1) {
		return false; // uninitialized
	}

	// check if address type is same
	//
	// what is correct policy for matching between IPv4 address and
	// IPv4-mapped-IPv6 address?
	if (base_.get_aftype() != target.get_aftype()) {
		return false;
	}

	const uint32_t* baseaddr = base_.get_address();
	const uint32_t* targetaddr = target.get_address();

	if (!baseaddr || !targetaddr) {
		return false;
	}
	int addr_len = base_.get_address_len();

	int curmaskbit = maskbit_;
	for (int i = 0; i < addr_len; ++i) {
		if (curmaskbit <= 0) { break; }
		uint32_t mask;
		if (curmaskbit >= 32) {
			mask = 0xffffffff;
		} else {
			mask = htonl(~(0xffffffff >> curmaskbit));
		}

		if ((*baseaddr & mask) != (*targetaddr & mask)) {
			return false;
		}

		curmaskbit -= 32;
		baseaddr++;
		targetaddr++;
	}

	return true;
}

static int convert_maskaddr_to_maskbit(uint32_t mask_value) {
	int maskbit = 0;

	// get rid of 0's from the right-most side
	while (mask_value > 0 && (mask_value & 1) == 0)
		mask_value >>= 1;

	while (mask_value > 0 && (mask_value & 1) == 1) {
		maskbit++;
		mask_value >>= 1;
	}

	if (mask_value != 0) {
		// the mask address is not well formed
		// e.g. 255.129.0.0, ill-formed mask
		// 1111 1111 | 1000 0001 | 0000 0000 | 0000 0000
		return -1;
	}

	return maskbit;
}

bool condor_netaddr::from_net_string(const char* net) {
	const char* slash = strchr(net, '/');
	const char* net_end = net + strlen(net);
	if (slash) {
		std::string base(net, slash - net);
		if (!base_.from_ip_string(base.c_str()))
			return false;

		// check whether secondary part is number
		char* end_ptr = NULL;
		unsigned long int maskbit = strtoul(slash + 1, &end_ptr, 10);

		// if end_ptr == net_end, the entire secondary part is a number,
		// which means it is the mask bit.
		if (end_ptr == net_end) {
			maskbit_ = maskbit;
		} else {
			// only IPv4 allows secondary part to be address form
			// e.g. 128.105.0.0/255.255.0.0
			if (base_.is_ipv4()) {
				std::string mask(slash + 1, net_end - slash - 1);
				condor_sockaddr maskaddr;

				// convert to numerical representation
				if (!maskaddr.from_ip_string(mask.c_str()) ||
						!maskaddr.is_ipv4())
					return false;

				// convert to mask bit
				const uint32_t* maskaddr_array = maskaddr.get_address();
				maskbit_ = convert_maskaddr_to_maskbit(*maskaddr_array);
				if (maskbit_ == (unsigned int)-1)
					return false;
			}
		}
	} else {
		// if there is no slash ('/'), it should be IPv4 and
		// wildcard format
		//
		// e.g. 128.105.*

		in_addr base;
		in_addr mask;
		if (!is_ipv4_addr_implementation(net, &base, &mask, 1))
			return false;

		base_ = condor_sockaddr(base, 0);
		maskbit_ = convert_maskaddr_to_maskbit(*(uint32_t*)&mask);
		if (maskbit_ == -1)
			return false;
	}
	return true;
}
<|endoftext|>


<commit_before>// Scintilla source code edit control
/**
 * @file LexMagik.cxx
 * Lexer for GE(r) Smallworld(tm) MagikSF
 */
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

/**
 * Is it a core character (C isalpha(), exclamation and question mark)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlphaCore(int ch) {
    return (isalpha(ch) || ch == '!' || ch == '?');
}

/**
 * Is it a character (IsAlphaCore() and underscore)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlpha(int ch) {
    return (IsAlphaCore(ch) || ch == '_');
}

/**
 * Is it a symbolic character (IsAlpha() and colon)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlphaSym(int ch) {
    return (IsAlpha(ch) || ch == ':');
}

/**
 * Is it a numerical character (IsAlpha() and 0 - 9)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlNum(int ch) {
    return ((ch >= '0' && ch < '9') || IsAlpha(ch));
}

/**
 * Is it a symbolic numerical character (IsAlNum() and colon)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlNumSym(int ch) {
    return (IsAlNum(ch) || ch == ':');
}

/**
 * The lexer function
 *
 * \param  startPos Where to start scanning
 * \param  length Where to scan to
 * \param  initStyle The style at the initial point, not used in this folder
 * \param  keywordslists The keywordslists, currently, number 5 is used
 * \param  styler The styler
 */
static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler) {
    styler.StartAt(startPos);

    WordList &keywords = *keywordlists[0];
    WordList &pragmatics = *keywordlists[1];
    WordList &containers = *keywordlists[2];
    WordList &flow = *keywordlists[3];
    WordList &characters = *keywordlists[4];

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

    repeat:

        if(sc.ch == '#') {
            if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT);
            else sc.SetState(SCE_MAGIK_COMMENT);
            for(; sc.More() && !(sc.atLineEnd); sc.Forward());
            sc.SetState(SCE_MAGIK_DEFAULT);
            goto repeat;
        }

        if(sc.ch == '"') {
            sc.SetState(SCE_MAGIK_STRING);

            if(sc.More())
            {
                sc.Forward();
                for(; sc.More() && sc.ch != '"'; sc.Forward());
            }

            sc.ForwardSetState(SCE_MAGIK_DEFAULT);
            goto repeat;
        }

	    // The default state
	    if(sc.state == SCE_MAGIK_DEFAULT) {

	        // A certain keyword has been detected
	        if (sc.ch == '_' && (
                    sc.currentPos == 0 || !IsAlNum(sc.chPrev))) {
	            char keyword[50];
	            memset(keyword, '\0', 50);

	            for(
                    int scanPosition = 0;
                    scanPosition < 50;
                    scanPosition++) {
	                char keywordChar = static_cast<char>(
                        tolower(styler.SafeGetCharAt(
                            scanPosition +
                                static_cast<int>(sc.currentPos+1), ' ')));
                    if(IsAlpha(keywordChar)) {
                        keyword[scanPosition] = keywordChar;
                    } else {
                        break;
                    }
	            }

                // It is a pragma
	            if(pragmatics.InList(keyword)) {
	                sc.SetState(SCE_MAGIK_PRAGMA);
	            }

	            // it is a normal keyword like _local, _self, etc.
	            else if(keywords.InList(keyword)) {
	                sc.SetState(SCE_MAGIK_KEYWORD);
	            }

                // It is a container keyword, such as _method, _proc, etc.
	            else if(containers.InList(keyword)) {
	                sc.SetState(SCE_MAGIK_CONTAINER);
	            }

	            // It is a flow keyword, such as _for, _if, _try, etc.
	            else if(flow.InList(keyword)) {
	                sc.SetState(SCE_MAGIK_FLOW);
	            }

	            // Interpret as unknown keyword
	            else {
	                sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD);
	            }
	        }

            // Symbolic expression
	        else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) {
	            sc.SetState(SCE_MAGIK_SYMBOL);
	            bool firstTrip = true;
	            for(sc.Forward(); sc.More(); sc.Forward()) {
	                if(firstTrip && IsAlphaSym(sc.ch));
	                else if(!firstTrip && IsAlNumSym(sc.ch));
	                else if(sc.ch == '|') {
	                    for(sc.Forward();
                            sc.More() && sc.ch != '|';
                            sc.Forward());
	                }
	                else break;

	                firstTrip = false;
	            }
	            sc.SetState(SCE_MAGIK_DEFAULT);
	            goto repeat;
	        }

            // Identifier (label) expression
	        else if(sc.ch == '@') {
	            sc.SetState(SCE_MAGIK_IDENTIFIER);
	            bool firstTrip = true;
	            for(sc.Forward(); sc.More(); sc.Forward()) {
	                if(firstTrip && IsAlphaCore(sc.ch)) {
	                    firstTrip = false;
	                }
	                else if(!firstTrip && IsAlpha(sc.ch));
	                else break;
	            }
	            sc.SetState(SCE_MAGIK_DEFAULT);
	            goto repeat;
	        }

	        // Start of a character
            else if(sc.ch == '%') {
                sc.SetState(SCE_MAGIK_CHARACTER);
                sc.Forward();
                char keyword[50];
	            memset(keyword, '\0', 50);

	            for(
                    int scanPosition = 0;
                    scanPosition < 50;
                    scanPosition++) {
	                char keywordChar = static_cast<char>(
                        tolower(styler.SafeGetCharAt(
                            scanPosition +
                                static_cast<int>(sc.currentPos), ' ')));
                    if(IsAlpha(keywordChar)) {
                        keyword[scanPosition] = keywordChar;
                    } else {
                        break;
                    }
	            }

	            if(characters.InList(keyword)) {
	                sc.Forward(strlen(keyword));
	            } else {
	                sc.Forward();
	            }

                sc.SetState(SCE_MAGIK_DEFAULT);
                goto repeat;
            }

            // Operators
	        else if(
                sc.ch == '>' ||
                sc.ch == '<' ||
                sc.ch == '.' ||
                sc.ch == ',' ||
                sc.ch == '+' ||
                sc.ch == '-' ||
                sc.ch == '/' ||
                sc.ch == '*' ||
                sc.ch == '~' ||
                sc.ch == '$' ||
                sc.ch == '=') {
                sc.SetState(SCE_MAGIK_OPERATOR);
            }

            // Braces
            else if(sc.ch == '(' || sc.ch == ')') {
                sc.SetState(SCE_MAGIK_BRACE_BLOCK);
            }

            // Brackets
            else if(sc.ch == '{' || sc.ch == '}') {
                sc.SetState(SCE_MAGIK_BRACKET_BLOCK);
            }

            // Square Brackets
            else if(sc.ch == '[' || sc.ch == ']') {
                sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK);
            }

	    }

	    // It is an operator
	    else if(
            sc.state == SCE_MAGIK_OPERATOR ||
            sc.state == SCE_MAGIK_BRACE_BLOCK ||
            sc.state == SCE_MAGIK_BRACKET_BLOCK ||
            sc.state == SCE_MAGIK_SQBRACKET_BLOCK) {
	        sc.SetState(SCE_MAGIK_DEFAULT);
	        goto repeat;
	    }

	    // It is the pragma state
	    else if(sc.state == SCE_MAGIK_PRAGMA) {
	        if(!IsAlpha(sc.ch)) {
	            sc.SetState(SCE_MAGIK_DEFAULT);
                goto repeat;
	        }
	    }

	    // It is the keyword state
	    else if(
            sc.state == SCE_MAGIK_KEYWORD ||
            sc.state == SCE_MAGIK_CONTAINER ||
            sc.state == SCE_MAGIK_FLOW ||
            sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) {
	        if(!IsAlpha(sc.ch)) {
	            sc.SetState(SCE_MAGIK_DEFAULT);
	            goto repeat;
	        }
	    }
	}

	sc.Complete();
}

/**
 * The word list description
 */
static const char * const magikWordListDesc[] = {
    "Accessors (local, global, self, super, thisthread)",
    "Pragmatic (pragma, private)",
    "Containers (method, block, proc)",
    "Flow (if, then, elif, else)",
    "Characters (space, tab, newline, return)",
    "Fold Containers (method, proc, block, if, loop)",
    0};

/**
 * This function detects keywords which are able to have a body. Note that it
 * uses the Fold Containers word description, not the containers description. It
 * only works when the style at that particular position is set on Containers
 * or Flow (number 3 or 4).
 *
 * \param  keywordslist The list of keywords that are scanned, they should only
 *         contain the start keywords, not the end keywords
 * \param  The actual keyword
 * \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword
 *         0 otherwise
 */
static inline int IsFoldingContainer(WordList &keywordslist, char * keyword) {
    if(
        strlen(keyword) > 3 &&
        keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') {
        if (keywordslist.InList(keyword + 3)) {
            return -1;
        }

    } else {
        if(keywordslist.InList(keyword)) {
            return 1;
        }
    }

    return 0;
}

/**
 * The folding function
 *
 * \param  startPos Where to start scanning
 * \param  length Where to scan to
 * \param  keywordslists The keywordslists, currently, number 5 is used
 * \param  styler The styler
 */
static void FoldMagikDoc(unsigned int startPos, int length, int,
    WordList *keywordslists[], Accessor &styler) {

    bool compact = styler.GetPropertyInt("fold.compact") != 0;

    WordList &foldingElements = *keywordslists[5];
    int endPos = startPos + length;
    int line = styler.GetLine(startPos);
    int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
    int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;

    for(
        int currentPos = startPos;
        currentPos < endPos;
        currentPos++) {
            char currentState = styler.StyleAt(currentPos);
            char c = styler.SafeGetCharAt(currentPos, ' ');
            int prevLine = styler.GetLine(currentPos - 1);
            line = styler.GetLine(currentPos);

            // Default situation
            if(prevLine < line) {
                styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG);
                flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
            }

            if(
                (
                    currentState == SCE_MAGIK_CONTAINER ||
                    currentState == SCE_MAGIK_FLOW
                ) &&
                c == '_') {

                char keyword[50];
                memset(keyword, '\0', 50);

                for(
                    int scanPosition = 0;
                    scanPosition < 50;
                    scanPosition++) {
                    char keywordChar = static_cast<char>(
                        tolower(styler.SafeGetCharAt(
                            scanPosition +
                                currentPos + 1, ' ')));
                    if(IsAlpha(keywordChar)) {
                        keyword[scanPosition] = keywordChar;
                    } else {
                        break;
                    }
                }

                if(IsFoldingContainer(foldingElements, keyword) > 0) {
                    styler.SetLevel(
                        line,
                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
                    level++;
                } else if(IsFoldingContainer(foldingElements, keyword) < 0) {
                    styler.SetLevel(line, styler.LevelAt(line));
                    level--;
                }
            }

            if(
                compact && (
                    currentState == SCE_MAGIK_BRACE_BLOCK ||
                    currentState == SCE_MAGIK_BRACKET_BLOCK ||
                    currentState == SCE_MAGIK_SQBRACKET_BLOCK)) {
                if(c == '{' || c == '[' || c == '(') {
                    styler.SetLevel(
                        line,
                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
                    level++;
                } else if(c == '}' || c == ']' || c == ')') {
                    styler.SetLevel(line, styler.LevelAt(line));
                    level--;
                }
            }
        }

}

/**
 * Injecting the module
 */
LexerModule lmMagikSF(
    SCLEX_MAGIK, ColouriseMagikDoc, "magiksf", FoldMagikDoc, magikWordListDesc);

<commit_msg>Better fix to recognising numbers.<commit_after>// Scintilla source code edit control
/**
 * @file LexMagik.cxx
 * Lexer for GE(r) Smallworld(tm) MagikSF
 */
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

/**
 * Is it a core character (C isalpha(), exclamation and question mark)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlphaCore(int ch) {
    return (isalpha(ch) || ch == '!' || ch == '?');
}

/**
 * Is it a character (IsAlphaCore() and underscore)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlpha(int ch) {
    return (IsAlphaCore(ch) || ch == '_');
}

/**
 * Is it a symbolic character (IsAlpha() and colon)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlphaSym(int ch) {
    return (IsAlpha(ch) || ch == ':');
}

/**
 * Is it a numerical character (IsAlpha() and 0 - 9)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlNum(int ch) {
    return ((ch >= '0' && ch <= '9') || IsAlpha(ch));
}

/**
 * Is it a symbolic numerical character (IsAlNum() and colon)
 *
 * \param  ch The character
 * \return True if ch is a character, False otherwise
 */
static inline bool IsAlNumSym(int ch) {
    return (IsAlNum(ch) || ch == ':');
}

/**
 * The lexer function
 *
 * \param  startPos Where to start scanning
 * \param  length Where to scan to
 * \param  initStyle The style at the initial point, not used in this folder
 * \param  keywordslists The keywordslists, currently, number 5 is used
 * \param  styler The styler
 */
static void ColouriseMagikDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler) {
    styler.StartAt(startPos);

    WordList &keywords = *keywordlists[0];
    WordList &pragmatics = *keywordlists[1];
    WordList &containers = *keywordlists[2];
    WordList &flow = *keywordlists[3];
    WordList &characters = *keywordlists[4];

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

    repeat:

        if(sc.ch == '#') {
            if (sc.chNext == '#') sc.SetState(SCE_MAGIK_HYPER_COMMENT);
            else sc.SetState(SCE_MAGIK_COMMENT);
            for(; sc.More() && !(sc.atLineEnd); sc.Forward());
            sc.SetState(SCE_MAGIK_DEFAULT);
            goto repeat;
        }

        if(sc.ch == '"') {
            sc.SetState(SCE_MAGIK_STRING);

            if(sc.More())
            {
                sc.Forward();
                for(; sc.More() && sc.ch != '"'; sc.Forward());
            }

            sc.ForwardSetState(SCE_MAGIK_DEFAULT);
            goto repeat;
        }

	    // The default state
	    if(sc.state == SCE_MAGIK_DEFAULT) {

	        // A certain keyword has been detected
	        if (sc.ch == '_' && (
                    sc.currentPos == 0 || !IsAlNum(sc.chPrev))) {
	            char keyword[50];
	            memset(keyword, '\0', 50);

	            for(
                    int scanPosition = 0;
                    scanPosition < 50;
                    scanPosition++) {
	                char keywordChar = static_cast<char>(
                        tolower(styler.SafeGetCharAt(
                            scanPosition +
                                static_cast<int>(sc.currentPos+1), ' ')));
                    if(IsAlpha(keywordChar)) {
                        keyword[scanPosition] = keywordChar;
                    } else {
                        break;
                    }
	            }

                // It is a pragma
	            if(pragmatics.InList(keyword)) {
	                sc.SetState(SCE_MAGIK_PRAGMA);
	            }

	            // it is a normal keyword like _local, _self, etc.
	            else if(keywords.InList(keyword)) {
	                sc.SetState(SCE_MAGIK_KEYWORD);
	            }

                // It is a container keyword, such as _method, _proc, etc.
	            else if(containers.InList(keyword)) {
	                sc.SetState(SCE_MAGIK_CONTAINER);
	            }

	            // It is a flow keyword, such as _for, _if, _try, etc.
	            else if(flow.InList(keyword)) {
	                sc.SetState(SCE_MAGIK_FLOW);
	            }

	            // Interpret as unknown keyword
	            else {
	                sc.SetState(SCE_MAGIK_UNKNOWN_KEYWORD);
	            }
	        }

            // Symbolic expression
	        else if(sc.ch == ':' && !IsAlNum(sc.chPrev)) {
	            sc.SetState(SCE_MAGIK_SYMBOL);
	            bool firstTrip = true;
	            for(sc.Forward(); sc.More(); sc.Forward()) {
	                if(firstTrip && IsAlphaSym(sc.ch));
	                else if(!firstTrip && IsAlNumSym(sc.ch));
	                else if(sc.ch == '|') {
	                    for(sc.Forward();
                            sc.More() && sc.ch != '|';
                            sc.Forward());
	                }
	                else break;

	                firstTrip = false;
	            }
	            sc.SetState(SCE_MAGIK_DEFAULT);
	            goto repeat;
	        }

            // Identifier (label) expression
	        else if(sc.ch == '@') {
	            sc.SetState(SCE_MAGIK_IDENTIFIER);
	            bool firstTrip = true;
	            for(sc.Forward(); sc.More(); sc.Forward()) {
	                if(firstTrip && IsAlphaCore(sc.ch)) {
	                    firstTrip = false;
	                }
	                else if(!firstTrip && IsAlpha(sc.ch));
	                else break;
	            }
	            sc.SetState(SCE_MAGIK_DEFAULT);
	            goto repeat;
	        }

	        // Start of a character
            else if(sc.ch == '%') {
                sc.SetState(SCE_MAGIK_CHARACTER);
                sc.Forward();
                char keyword[50];
	            memset(keyword, '\0', 50);

	            for(
                    int scanPosition = 0;
                    scanPosition < 50;
                    scanPosition++) {
	                char keywordChar = static_cast<char>(
                        tolower(styler.SafeGetCharAt(
                            scanPosition +
                                static_cast<int>(sc.currentPos), ' ')));
                    if(IsAlpha(keywordChar)) {
                        keyword[scanPosition] = keywordChar;
                    } else {
                        break;
                    }
	            }

	            if(characters.InList(keyword)) {
	                sc.Forward(strlen(keyword));
	            } else {
	                sc.Forward();
	            }

                sc.SetState(SCE_MAGIK_DEFAULT);
                goto repeat;
            }

            // Operators
	        else if(
                sc.ch == '>' ||
                sc.ch == '<' ||
                sc.ch == '.' ||
                sc.ch == ',' ||
                sc.ch == '+' ||
                sc.ch == '-' ||
                sc.ch == '/' ||
                sc.ch == '*' ||
                sc.ch == '~' ||
                sc.ch == '$' ||
                sc.ch == '=') {
                sc.SetState(SCE_MAGIK_OPERATOR);
            }

            // Braces
            else if(sc.ch == '(' || sc.ch == ')') {
                sc.SetState(SCE_MAGIK_BRACE_BLOCK);
            }

            // Brackets
            else if(sc.ch == '{' || sc.ch == '}') {
                sc.SetState(SCE_MAGIK_BRACKET_BLOCK);
            }

            // Square Brackets
            else if(sc.ch == '[' || sc.ch == ']') {
                sc.SetState(SCE_MAGIK_SQBRACKET_BLOCK);
            }

	    }

	    // It is an operator
	    else if(
            sc.state == SCE_MAGIK_OPERATOR ||
            sc.state == SCE_MAGIK_BRACE_BLOCK ||
            sc.state == SCE_MAGIK_BRACKET_BLOCK ||
            sc.state == SCE_MAGIK_SQBRACKET_BLOCK) {
	        sc.SetState(SCE_MAGIK_DEFAULT);
	        goto repeat;
	    }

	    // It is the pragma state
	    else if(sc.state == SCE_MAGIK_PRAGMA) {
	        if(!IsAlpha(sc.ch)) {
	            sc.SetState(SCE_MAGIK_DEFAULT);
                goto repeat;
	        }
	    }

	    // It is the keyword state
	    else if(
            sc.state == SCE_MAGIK_KEYWORD ||
            sc.state == SCE_MAGIK_CONTAINER ||
            sc.state == SCE_MAGIK_FLOW ||
            sc.state == SCE_MAGIK_UNKNOWN_KEYWORD) {
	        if(!IsAlpha(sc.ch)) {
	            sc.SetState(SCE_MAGIK_DEFAULT);
	            goto repeat;
	        }
	    }
	}

	sc.Complete();
}

/**
 * The word list description
 */
static const char * const magikWordListDesc[] = {
    "Accessors (local, global, self, super, thisthread)",
    "Pragmatic (pragma, private)",
    "Containers (method, block, proc)",
    "Flow (if, then, elif, else)",
    "Characters (space, tab, newline, return)",
    "Fold Containers (method, proc, block, if, loop)",
    0};

/**
 * This function detects keywords which are able to have a body. Note that it
 * uses the Fold Containers word description, not the containers description. It
 * only works when the style at that particular position is set on Containers
 * or Flow (number 3 or 4).
 *
 * \param  keywordslist The list of keywords that are scanned, they should only
 *         contain the start keywords, not the end keywords
 * \param  The actual keyword
 * \return 1 if it is a folding start-keyword, -1 if it is a folding end-keyword
 *         0 otherwise
 */
static inline int IsFoldingContainer(WordList &keywordslist, char * keyword) {
    if(
        strlen(keyword) > 3 &&
        keyword[0] == 'e' && keyword[1] == 'n' && keyword[2] == 'd') {
        if (keywordslist.InList(keyword + 3)) {
            return -1;
        }

    } else {
        if(keywordslist.InList(keyword)) {
            return 1;
        }
    }

    return 0;
}

/**
 * The folding function
 *
 * \param  startPos Where to start scanning
 * \param  length Where to scan to
 * \param  keywordslists The keywordslists, currently, number 5 is used
 * \param  styler The styler
 */
static void FoldMagikDoc(unsigned int startPos, int length, int,
    WordList *keywordslists[], Accessor &styler) {

    bool compact = styler.GetPropertyInt("fold.compact") != 0;

    WordList &foldingElements = *keywordslists[5];
    int endPos = startPos + length;
    int line = styler.GetLine(startPos);
    int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;
    int flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;

    for(
        int currentPos = startPos;
        currentPos < endPos;
        currentPos++) {
            char currentState = styler.StyleAt(currentPos);
            char c = styler.SafeGetCharAt(currentPos, ' ');
            int prevLine = styler.GetLine(currentPos - 1);
            line = styler.GetLine(currentPos);

            // Default situation
            if(prevLine < line) {
                styler.SetLevel(line, (level|flags) & ~SC_FOLDLEVELHEADERFLAG);
                flags = styler.LevelAt(line) & ~SC_FOLDLEVELNUMBERMASK;
            }

            if(
                (
                    currentState == SCE_MAGIK_CONTAINER ||
                    currentState == SCE_MAGIK_FLOW
                ) &&
                c == '_') {

                char keyword[50];
                memset(keyword, '\0', 50);

                for(
                    int scanPosition = 0;
                    scanPosition < 50;
                    scanPosition++) {
                    char keywordChar = static_cast<char>(
                        tolower(styler.SafeGetCharAt(
                            scanPosition +
                                currentPos + 1, ' ')));
                    if(IsAlpha(keywordChar)) {
                        keyword[scanPosition] = keywordChar;
                    } else {
                        break;
                    }
                }

                if(IsFoldingContainer(foldingElements, keyword) > 0) {
                    styler.SetLevel(
                        line,
                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
                    level++;
                } else if(IsFoldingContainer(foldingElements, keyword) < 0) {
                    styler.SetLevel(line, styler.LevelAt(line));
                    level--;
                }
            }

            if(
                compact && (
                    currentState == SCE_MAGIK_BRACE_BLOCK ||
                    currentState == SCE_MAGIK_BRACKET_BLOCK ||
                    currentState == SCE_MAGIK_SQBRACKET_BLOCK)) {
                if(c == '{' || c == '[' || c == '(') {
                    styler.SetLevel(
                        line,
                        styler.LevelAt(line) | SC_FOLDLEVELHEADERFLAG);
                    level++;
                } else if(c == '}' || c == ']' || c == ')') {
                    styler.SetLevel(line, styler.LevelAt(line));
                    level--;
                }
            }
        }

}

/**
 * Injecting the module
 */
LexerModule lmMagikSF(
    SCLEX_MAGIK, ColouriseMagikDoc, "magiksf", FoldMagikDoc, magikWordListDesc);

<|endoftext|>


<commit_before>/*Published under The MIT License (MIT)
See LICENSE*/

// Christopher Hernandez

#include <iostream>
#include <cstdlib>
#include <string.h>
#include <mpi.h>

#include "colony.h"
#include "my_timer.h"
#include "my_mpi_header.h"

int _length;
int _width;
int _n;
int _gens;

double calculateAvgTime(double* times) {
  double total = 0;
 	for(int i = 0; i < _n; i++)
    total += times[i]; // add up all times

  return total / _n; // sum / n = avg
}

int main(int argc, char** argv) {
  // Init MPI
  callMPI( MPI_Init(&argc, &argv) );

  myTimer_t t0 = getTimeStamp();

  _length = atoi(argv[1]);
  _width = atoi(argv[2]);
  _n = _length * _width
  _gens = atoi(argv[3]);
  bool print = true;
  if (argv[4]) { // if 4th parameter exists don't print
    if (strncmp(argv[4],"--no-print", 10) == 0) {
      print = false;
    }
  }

  // Defining Node's Rank and Size
  int rank, size;
  callMPI( MPI_Comm_rank(MPI_COMM_WORLD, &rank) );
  callMPI( MPI_Comm_size(MPI_COMM_WORLD, &size) );

  // Create colony
  Colony c(_length, _width, _gens);

  for (int i = 0; i < _gens; i++) {
    if (print) {
      if(system("clear") == NULL)
        std::cerr << "could not clear console";
      if (rank == 0) { // only 1 output
        c.printGrid();
      }
      c.evolve();
    } else {
      c.evolve();
    }
  }

  double t1 =  getElapsedTime(t0, getTimeStamp()); // end time
  if (rank == 0) {
    std::cout << "Average timestep: " << calculateAvgTime(c.getTimes()) << " ms" << std::endl;
    std::cout << "Total Time: " << t1 << " ms" << std::endl;
  }
  // End MPI
  callMPI( MPI_Finalize() );
  return 0;
}
<commit_msg>forgot semicolon<commit_after>/*Published under The MIT License (MIT)
See LICENSE*/

// Christopher Hernandez

#include <iostream>
#include <cstdlib>
#include <string.h>
#include <mpi.h>

#include "colony.h"
#include "my_timer.h"
#include "my_mpi_header.h"

int _length;
int _width;
int _n;
int _gens;

double calculateAvgTime(double* times) {
  double total = 0;
 	for(int i = 0; i < _n; i++)
    total += times[i]; // add up all times

  return total / _n; // sum / n = avg
}

int main(int argc, char** argv) {
  // Init MPI
  callMPI( MPI_Init(&argc, &argv) );

  myTimer_t t0 = getTimeStamp();

  _length = atoi(argv[1]);
  _width = atoi(argv[2]);
  _n = _length * _width;
  _gens = atoi(argv[3]);
  bool print = true;
  if (argv[4]) { // if 4th parameter exists don't print
    if (strncmp(argv[4],"--no-print", 10) == 0) {
      print = false;
    }
  }

  // Defining Node's Rank and Size
  int rank, size;
  callMPI( MPI_Comm_rank(MPI_COMM_WORLD, &rank) );
  callMPI( MPI_Comm_size(MPI_COMM_WORLD, &size) );

  // Create colony
  Colony c(_length, _width, _gens);

  for (int i = 0; i < _gens; i++) {
    if (print) {
      if(system("clear"))
      if (rank == 0) { // only 1 output
        c.printGrid();
      }
      c.evolve();
    } else {
      c.evolve();
    }
  }

  double t1 =  getElapsedTime(t0, getTimeStamp()); // end time
  if (rank == 0) {
    std::cout << "Average timestep: " << calculateAvgTime(c.getTimes()) << " ms" << std::endl;
    std::cout << "Total Time: " << t1 << " ms" << std::endl;
  }
  // End MPI
  callMPI( MPI_Finalize() );
  return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <memory>
#include <algorithm>
#include <cstring>
#include <unordered_map>

using namespace std;

vector<string> split(const string& str) {
  string buf; // Have a buffer string
  stringstream ss(str); // Insert the string into a stream
  vector<string> tokens; // Create vector to hold our words

  while (ss >> buf)
    tokens.push_back(buf);

  return tokens;
}

using RoomID = int;

struct RoomObject
{
  vector<string> names;
  string description;
  bool visible;
};

struct Map
{
  static const int max_width = 100, max_height = 100;
  static const int player_start_x = 50, player_start_y = 50;
  enum Location
  {
    UNKNOWN,
    GRAVEYARD,
    GRAVEYARD_GATES,
    KHATHARRS_MOMS_HOUSE,
  };
  Location map_location[max_width][max_height];
  int x, y;
  Map()
  {
    memset(map_location, UNKNOWN, sizeof(map_location));
    x = 50;
    y = 50;
    map_location[50][50] = GRAVEYARD;
    map_location[50][51] = GRAVEYARD_GATES;
    map_location[50][52] = KHATHARRS_MOMS_HOUSE;
  }
};

struct Entity
{
  Entity(string name, int maxHealth) : name(name), health(maxHealth) {}

  void heal(int points)
  {
    health = min(100, health + points);
    cout << name << " healed to " << health << " health" << endl;
  }

  void damage(int points)
  {
    health = max(0, health - points);
    cout << name << " damaged to " << health << "health" << endl;
  }

  int getHealth() const { return health; }

  // Return false if the entity didn't know the command
  virtual bool act(vector<string> commands) = 0;

  string name;
  Map map;

private:
  int health;
};

struct Shogun : public Entity {
  Shogun() : Entity("Shogibear", 100) {}
};

struct Item
{
  virtual void apply(Entity* entity) = 0;
  virtual string identify() const = 0;
};

struct HealthItem : public Item
{
  HealthItem(int healPower) : healPower(healPower) {}

  void apply(Entity* entity) override
  {
    entity->heal(healPower);
  }

  string identify() const override
  {
    stringstream ss;
    ss << "Health Potion (" << healPower << ")";
    return ss.str();
  }

private:
  int healPower;
};
struct BlessedSword : public Item
{
  BlessedSword(int Weapon) : Weapon(Weapon){}
  void apply(Entity* entity) override{entity->damage(Weapon);}string identify() const override{stringstream ss; ss << "Hit (" << Weapon << ")";}
private: int Weapon;};//will add this to entity on my next commit. <.<

                      /*
                      struct ReallyFastSword : public Item
                      struct TheFastcall : public Entity
                      {
                      TheFastcall() : Entity("The Fastcall", 22) {}
                      virtual bool act(vector<string> commands) override
                      {
                      }
                      };
                      */

struct Player : public Entity
{
  Player(string name, int health) : Entity(name, health) {}

  virtual bool act(vector<string> commands) override
  {
    auto& cmd = commands[0];
    if(cmd == "n") { commands = vector<string>{"go","north"}; }
    if(cmd == "s") { commands = vector<string>{"go","south"}; }
    if(cmd == "e") { commands = vector<string>{"go","east"}; }
    if(cmd == "w") { commands = vector<string>{"go","west"}; }

    if (commands.size() >= 1 && commands[0] == "look")
    {
      look();
      return true;
    }
    else if (commands.size() >= 2 && (commands[0] == "examine" || commands[0] == "x"))
    {
    }
    else if (commands.size() >= 2 && commands[0] == "go")
    {
      if (travel(commands[1]) == true)
      {
        look();
      } else {
        cout << "Can't travel " << commands[1] << endl;
      }
      return true;
    }
    else if (commands.size() >= 1 && commands[0] == "items")
    {
      showItems();
      return true;
    }
    else if (commands.size() >= 2 && commands[0] == "use")
    {
      int index = stoi(commands[1]);
      useItem(index);
      return true;
    }

    return false;
  }

  bool travel(string direction)
  {
    if ((map.x <= 0 && direction == "west") || (map.x >= (map.max_width - 1) && direction == "east"))
      return false;
    if ((map.y <= 0 && direction == "south") || (map.y >= (map.max_width - 1) && direction == "north"))
      return false;
    if(direction=="north"&&map.map_location[map.x][map.y+1]==Map::UNKNOWN)return false;if(direction=="south"&&map.map_location[map.x][map.y-1]==Map::UNKNOWN)return false;if(direction=="east"&&map.map_location[map.x+1][map.y]==Map::UNKNOWN)return false
      ;if(direction=="west"&&map.map_location[map.x-1][map.y]==Map::UNKNOWN)return false;if(direction=="north")map.y++;if(direction=="south")map.y--;if(direction=="east")map.x++;if(direction=="west")map.x--;
    return true;/*
                switch (map.map_location[map.x][map.y])
                {
                case Map::GRAVEYARD:
                if (direction == "north")
                {
                map.y++;
                return true;
                }
                break;
                case Map::GRAVEYARD_GATES:
                if (direction == "south")
                {
                map.y--;
                return true;
                }
                if (direction == "north")
                {
                map.y++;
                return true;
                }
                break;
                }

                cout << "Can't travel " << direction << endl;
                return false;*/
  }

  void look()
  {
    switch (map.map_location[map.x][map.y])
    {
    case Map::GRAVEYARD:
      cout << "A thick layer of fog covers the graveyard soil. Tombstones jut out here and there and an eerie willow tree looms over your head, obstructing the full moon partially. Off in the distance you see the northern gates -- the only entrance into this forsaken place." << endl;
      break;
    case Map::GRAVEYARD_GATES:
      cout << "For many centuries these gates have stood the test of time. The gateway to the afterlife. Inside the graveyard small hills stretch endlessly, littered with thousands of tombstones. You see a willow tree south of the gates. Outisde, north, you see a very large house." << endl;
      break;
    case Map::KHATHARRS_MOMS_HOUSE:
      cout << "The house is gigantic! What could possibly require such volume, such mass, such density? The house appears to not have any doors, but due to the strain from whatever is present inside, cracks have formed. You see a crack you might just fit into east." << endl;
      break;
    }
  }

  void giveItem(shared_ptr<Item> item)
  {
    inventory.push_back(item);
  }

  void showItems()
  {
    if (inventory.size() == 0)
      cout << "You have no items." << endl;
    int i = 1;
    for (auto item : inventory)
    {
      cout << "  " << i++ << ". " << item->identify() << std::endl;
    }
  }

  void useItem(size_t index)
  {
    if (index > inventory.size())
    {
      cout << "Invalid index" << endl;
      return;
    }

    inventory[index-1]->apply(this);
    inventory.erase(inventory.begin() + index - 1);
  }

private:
  vector<shared_ptr<Item>> inventory;
};

struct Room {
  string describe() {
    stringstream ss;
    return ss.str(); //description << list entites, list items, list exits
  }
  string description;
  vector<unique_ptr<Entity>> entities;
  vector<RoomObject> objects;
  unordered_map<string, RoomID> exits;
};

class Adventure
{
public:
  void begin()
  {
    string command;
    cout << "Welcome, brave soul. Pray tell, what is thy name?" << endl;
    cout << "> ";
    getline(cin, command);

    Player player(command, 100);
    player.giveItem(make_shared<HealthItem>(20));

    cout << player.name << "! Your presence defiles these sacred grounds. Beware the soil upon which you step, for it will claim you sooner rather than later." << endl;
    player.look();

    while (player.getHealth() > 0)
    {
      cout << "> ";
      getline(cin, command);
      if (player.act(split(command)) == false)
        cout << "Unknown command" << endl;
    }

    cout << "You died. Game over." << endl;
  }
};

int main()
{
  Adventure adventure;
  adventure.begin();
  return 0;
}
<commit_msg>Revert "Update main.cpp"<commit_after>#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <memory>
#include <algorithm>
#include <cstring>
#include <unordered_map>

using namespace std;

vector<string> split(const string& str) {
    string buf; // Have a buffer string
    stringstream ss(str); // Insert the string into a stream
    vector<string> tokens; // Create vector to hold our words

    while (ss >> buf)
        tokens.push_back(buf);

    return tokens;
}

using RoomID = int;

struct RoomObject
{
	vector<string> names;
	string description;
	bool visible;
};

struct Map
{
	static const int max_width = 100, max_height = 100;
	static const int player_start_x = 50, player_start_y = 50;
    enum Location
    {
        UNKNOWN,
        GRAVEYARD,
        GRAVEYARD_GATES,
        KHATHARRS_MOMS_HOUSE,
    };
	Location map_location[max_width][max_height];
	int x, y;
	Map()
	{
        memset(map_location, UNKNOWN, sizeof(map_location));
		x = 50;
		y = 50;
		map_location[50][50] = GRAVEYARD;
		map_location[50][51] = GRAVEYARD_GATES;
		map_location[50][52] = KHATHARRS_MOMS_HOUSE;
	}
};

struct Entity
{
    Entity(string name, int maxHealth) : name(name), health(maxHealth) {}

    void heal(int points)
    {
        health = min(100, health + points);
        cout << name << " healed to " << health << " health" << endl;
    }

    void damage(int points)
    {
        health = max(0, health - points);
        cout << name << " damaged to " << health << "health" << endl;
    }

    int getHealth() const { return health; }

    // Return false if the entity didn't know the command
    virtual bool act(vector<string> commands) = 0;

    string name;
    Map map;

private:
    int health;
};

struct Shogun : public Entity {
  Shogun() : Entity("Shogibear", 100) {}
};

struct Item
{
    virtual void apply(Entity* entity) = 0;
    virtual string identify() const = 0;
};

struct HealthItem : public Item
{
    HealthItem(int healPower) : healPower(healPower) {}

    void apply(Entity* entity) override
    {
        entity->heal(healPower);
    }

    string identify() const override
    {
        stringstream ss;
        ss << "Health Potion (" << healPower << ")";
        return ss.str();
    }

private:
    int healPower;
};
struct BlessedSword : public Item
{
    BlessedSword(int Weapon) : Weapon(Weapon){}
void apply(Entity* entity) override{entity->damage(Weapon);}string identify() const override{stringstream ss; ss << "Hit (" << Weapon << ")";}
private: int Weapon;};//will add this to entity on my next commit. <.<

/*
struct ReallyFastSword : public Item
struct TheFastcall : public Entity
{
    TheFastcall() : Entity("The Fastcall", 22) {}
    virtual bool act(vector<string> commands) override
    {
    }
};
*/

struct Player : public Entity
{
    Player(string name, int health) : Entity(name, health) {}

    virtual bool act(vector<string> commands) override
    {
        auto& cmd = commands[0];
        if(cmd == "n") { commands = vector<string>{"go","north"}; }
        if(cmd == "s") { commands = vector<string>{"go","south"}; }
        if(cmd == "e") { commands = vector<string>{"go","east"}; }
        if(cmd == "w") { commands = vector<string>{"go","west"}; }

        if (commands.size() >= 1 && commands[0] == "look")
        {
            look();
            return true;
        }
        else if (commands.size() >= 2 && (commands[0] == "examine" || commands[0] == "x"))
        {
        }
        else if (commands.size() >= 2 && commands[0] == "go")
        {
            if (travel(commands[1]) == true)
            {
                look();
            } else {
                cout << "Can't travel " << commands[1] << endl;
            }
            return true;
        }
        else if (commands.size() >= 1 && commands[0] == "items")
        {
            showItems();
            return true;
        }
        else if (commands.size() >= 2 && commands[0] == "use")
        {
            int index = stoi(commands[1]);
            useItem(index);
            return true;
        }

        return false;
    }

    bool travel(string direction)
    {
		if ((map.x <= 0 && direction == "west") || (map.x >= (map.max_width - 1) && direction == "east"))
			return false;
		if ((map.y <= 0 && direction == "south") || (map.y >= (map.max_width - 1) && direction == "north"))
			return false;
        if(direction=="north"&&map.map_location[map.x][map.y+1]==Map::UNKNOWN)return false;if(direction=="south"&&map.map_location[map.x][map.y-1]==Map::UNKNOWN)return false;if(direction=="east"&&map.map_location[map.x+1][map.y]==Map::UNKNOWN)return false
        ;if(direction=="west"&&map.map_location[map.x-1][map.y]==Map::UNKNOWN)return false;if(direction=="north")map.y++;if(direction=="south")map.y--;if(direction=="east")map.x++;if(direction=="west")map.x--;
        return true;/*
        switch (map.map_location[map.x][map.y])
        {
            case Map::GRAVEYARD:
                if (direction == "north")
                {
					map.y++;
                    return true;
                }
                break;
            case Map::GRAVEYARD_GATES:
                if (direction == "south")
                {
					map.y--;
                    return true;
                }
                if (direction == "north")
                {
                    map.y++;
                    return true;
                }
                break;
        }

        cout << "Can't travel " << direction << endl;
        return false;*/
    }

    void look()
    {
        switch (map.map_location[map.x][map.y])
        {
            case Map::GRAVEYARD:
                cout << "A thick layer of fog covers the graveyard soil. Tombstones jut out here and there and an eerie willow tree looms over your head, obstructing the full moon partially. Off in the distance you see the northern gates -- the only entrance into this forsaken place." << endl;
                break;
            case Map::GRAVEYARD_GATES:
                cout << "For many centuries these gates have stood the test of time. The gateway to the afterlife. Inside the graveyard small hills stretch endlessly, littered with thousands of tombstones. You see a willow tree south of the gates. Outisde, north, you see a very large house." << endl;
                break;
            case Map::KHATHARRS_MOMS_HOUSE:
                cout << "The house is gigantic! What could possibly require such volume, such mass, such density? The house appears to not have any doors, but due to the strain from whatever is present inside, cracks have formed. You see a crack you might just fit into east." << endl;
                break;
        }
    }

    void giveItem(shared_ptr<Item> item)
    {
        inventory.push_back(item);
    }

    void showItems()
    {
        if (inventory.size() == 0)
            cout << "You have no items." << endl;
        int i = 1;
        for (auto item : inventory)
        {
            cout << "  " << i++ << ". " << item->identify() << std::endl;
        }
    }

    void useItem(size_t index)
    {
        if (index > inventory.size())
        {
            cout << "Invalid index" << endl;
            return;
        }

        inventory[index-1]->apply(this);
        inventory.erase(inventory.begin() + index - 1);
    }

private:
    vector<shared_ptr<Item>> inventory;
};

struct Room {
	string describe() {
		return ""; //description << list entites, list items, list exits
	}
	string description;
	vector<Entity> entities;
	vector<RoomObject> objects;
	unordered_map<string, RoomID> exits;
};

class Adventure
{
public:
    void begin()
    {
        string command;
        cout << "Welcome, brave soul. Pray tell, what is thy name?" << endl;
        cout << "> ";
        getline(cin, command);

        Player player(command, 100);
        player.giveItem(make_shared<HealthItem>(20));

        cout << player.name << "! Your presence defiles these sacred grounds. Beware the soil upon which you step, for it will claim you sooner rather than later." << endl;
        player.look();

        while (player.getHealth() > 0)
        {
            cout << "> ";
            getline(cin, command);
            if (player.act(split(command)) == false)
                cout << "Unknown command" << endl;
        }

        cout << "You died. Game over." << endl;
    }
};

int main()
{
    Adventure adventure;
    adventure.begin();
    return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <mpi.h>
#include <math.h>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <algorithm>

int g_world_size;
int g_mpi_rank;
int start_id;
int end_id;
int g_max_id = 125000000;
MPI_Offset file_start;
MPI_Offset file_end;
std::map<int, std::set<int>> g_adj_list;
std::map<int, std::set<int>> g_bonus_list;

void parse_file();
void listen();
void add_to_adjlist(std::string line);
int id_to_rank(int id);

int main(int argc, char** argv) {
  // Initialize the MPI environment
  MPI_Init(&argc, &argv);

  // Get the number of processes
  MPI_Comm_size(MPI_COMM_WORLD, &g_world_size);

  // Get the rank of the process
  MPI_Comm_rank(MPI_COMM_WORLD, &g_mpi_rank);

  start_id = g_mpi_rank*(g_max_id / g_world_size);
  end_id = (g_mpi_rank+1)*(g_max_id / g_world_size);
  if (g_mpi_rank == g_world_size-1){
    end_id = g_max_id;
  }

  //printf("Rank %d: start_id: %d end_id: %d\n", g_mpi_rank, start_id, end_id);

  // Print off a hello world message
  parse_file();
  printf("Rank: %d    g_adj_list.size(): %lu    g_bonus_list.size(): %lu\n", g_mpi_rank, g_adj_list.size(), g_bonus_list.size());
  if (g_mpi_rank == 0){
   // parse_file();
    //printf("Rank: %d    g_adj_list.size(): %lu\n", g_mpi_rank, g_adj_list.size());
  }

  // Finalize the MPI environment.
  MPI_Finalize();

  return 0;
}

void parse_file(){
  char filename[70];
  //sprintf(filename, "com-friendster.ungraph.txt");
  sprintf(filename, "/gpfs/u/home/PCP5/PCP5stns/scratch-shared/com-friendster.ungraph.txt");

  MPI_File infile;
  MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &infile);
  MPI_Offset filesize = 0;
  MPI_File_get_size(infile, &filesize);

  file_start = (g_mpi_rank)*(filesize/g_world_size);
  if (g_mpi_rank == 0){
    file_start = 124;
  }else{
    file_start -= 50; // allow some overlap to catch newlines
  }
  file_end = (g_mpi_rank+1)*(filesize/g_world_size);
  if (g_mpi_rank == g_world_size-1){
    file_end = filesize;
  }
  /*if (g_mpi_rank != 0){
   MPI_File_close(&infile);
   return;
  }*/
  MPI_Offset offset = file_start;
  char * buffer;
  std::string chunk = "";
  unsigned int buffer_size = 100000;

  bool skip = (g_mpi_rank != 0);

  while (offset < file_end){
   // printf("Rank: %d offset: %lld, file_end: %lld, remaining: %lld  size of adj_list: %lu\n", g_mpi_rank, offset, file_end, file_end-offset, g_adj_list.size());
    buffer = (char *)malloc( (buffer_size + 1)*sizeof(char));
    MPI_File_read_at(infile, offset, buffer, buffer_size, MPI_CHAR, MPI_STATUS_IGNORE);
    offset += buffer_size;
    // end the string
    buffer[buffer_size] = '\0';
    std::string new_string(buffer);
    free(buffer);
    chunk += new_string;

    if (skip){
      // skip up to the first newline to remove any broken lines from starting in the middle of the file
      chunk = chunk.substr(chunk.find('\n')+1);
    }else{
      skip = true;
    }

    int found_nl = chunk.find('\n');
    while (found_nl < chunk.size()){
      std::string line = chunk.substr(0, found_nl);
      add_to_adjlist(line);

      chunk = chunk.substr(found_nl+1);
      found_nl = chunk.find('\n');
    }
  }
  printf("Rank %d: finished read in of own portion of file    %lu\n", g_mpi_rank, g_adj_list.size());
  //MPI_Barrier(MPI_COMM_WORLD);
  MPI_File_close(&infile);
}

int id_to_rank(int id){
  int max_id=0;
  for (int i=0; i<g_world_size; i++){
    max_id += g_max_id / g_world_size;
    if (id < max_id){
      return i;
    }
  }
  return g_world_size-1;
}

void add_to_adjlist(std::string line){

  int tab_pos = line.find("\t");
  int one = atoi(line.substr(0, tab_pos).c_str());
  int two = atoi(line.substr(tab_pos+1).c_str());

  if (one >= start_id && one < end_id){
    g_adj_list[one].insert(two);
    if (two >= start_id && two < end_id){
      g_adj_list[two].insert(one);
    }else{
      g_bonus_list[two].insert(one);
    }
  }else{
    g_bonus_list[one].insert(two);
    g_bonus_list[two].insert(one);
  }
}
<commit_msg>read in from 125 files<commit_after>#include <stdio.h>
#include <mpi.h>
#include <math.h>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
#include <sstream>

int g_world_size;
int g_mpi_rank;
int start_id;
int end_id;
int g_max_id = 125000000;
MPI_Offset file_start;
MPI_Offset file_end;
std::map<int, std::set<int>> g_adj_list;
std::map<int, std::set<int>> g_bonus_list;

void parse_file_one_rank();
void parse_file();
void listen();
void add_to_adjlist(std::string line);
int id_to_rank(int id);

int main(int argc, char** argv) {
  // Initialize the MPI environment
  MPI_Init(&argc, &argv);

  // Get the number of processes
  MPI_Comm_size(MPI_COMM_WORLD, &g_world_size);

  // Get the rank of the process
  MPI_Comm_rank(MPI_COMM_WORLD, &g_mpi_rank);

  start_id = g_mpi_rank*(g_max_id / g_world_size);
  end_id = (g_mpi_rank+1)*(g_max_id / g_world_size);
  if (g_mpi_rank == g_world_size-1){
    end_id = g_max_id;
  }

  //printf("Rank %d: start_id: %d end_id: %d\n", g_mpi_rank, start_id, end_id);

  // Print off a hello world message
  if(g_mpi_rank == 0 || g_mpi_rank==1){
    parse_file();
  }
  // if(g_mpi_rank==0){
  //   parse_file_one_rank();
  // }
  MPI_Barrier(MPI_COMM_WORLD);
  printf("Rank: %d    g_adj_list.size(): %lu    g_bonus_list.size(): %lu\n", g_mpi_rank, g_adj_list.size(), g_bonus_list.size());
  //if (g_mpi_rank == 0){
   // parse_file();
    //printf("Rank: %d    g_adj_list.size(): %lu\n", g_mpi_rank, g_adj_list.size());
  }

  // Finalize the MPI environment.
  MPI_Finalize();

  return 0;
}

void parse_file_one_rank(){
  std::string line;
  int count = 0;
  std::ifstream infile("com-friendster.ungraph.txt");
  for(int i =0; i<4; i++){
    std::getline(infile, line);
  }
  std::vector<std::ofstream*> streams;
  for(int i=0;i<125;i++) {
    std::stringstream sstm;
    sstm<<"./Friendster/users_"<<i<<".txt";
    std::string fileName = sstm.str();
    streams.push_back(new std::ofstream(fileName.c_str(), std::ofstream::out));
  }
  while(std::getline(infile,line)){
    count++;
    int tab_pos = line.find("\t");
    int one = atoi(line.substr(0, tab_pos).c_str());
    int two = atoi(line.substr(tab_pos+1).c_str());
    int oneFile = floor((double)one/1000000);
    int twoFile = floor((double)two/1000000);
    std::stringstream sstm;
    sstm<<one<<"\t"<<two<<"\n";
    std::string lineOne = sstm.str();
    sstm.str(std::string());
    sstm.clear();
    sstm<<two<<"\t"<<one<<"\n";
    std::string lineTwo = sstm.str();

    *streams[oneFile]<<lineOne;
    *streams[twoFile]<<lineTwo;
    if(count%500000==0){
      double percent = one/(double)g_max_id*100;
      std::cout<<percent<<"%"<<std::endl;
    }
  }
}

void parse_file(){
  char filename[70];
  int lowFile = floor((double)start_id/1000000);
  int highFile = floor((double)end_id/1000000);
  for (int i=0; i<highFile-lowFile+1; i++){
    sprintf(filename, "/gpfs/u/home/PCP5/PCP5bhgw/scratch/users_%d.txt", lowFile);
    MPI_File infile;
    MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &infile);
    MPI_Offset filesize = 0;
    MPI_File_get_size(infile, &filesize);

    file_start = (g_mpi_rank)*(filesize/g_world_size);
    if (g_mpi_rank == 0){
      file_start = 124;
    }else{
      file_start -= 50; // allow some overlap to catch newlines
    }
    file_end = (g_mpi_rank+1)*(filesize/g_world_size);
    if (g_mpi_rank == g_world_size-1){
      file_end = filesize;
    }
    // if (g_mpi_rank != 0){
    // MPI_File_close(&infile);
    // return;
    // }
    MPI_Offset offset = file_start;
    char * buffer;
    std::string chunk = "";
    unsigned int buffer_size = 10000;

    bool skip = (g_mpi_rank != 0);

    while (offset < file_end){
     // printf("Rank: %d offset: %lld, file_end: %lld, remaining: %lld  size of adj_list: %lu\n", g_mpi_rank, offset, file_end, file_end-offset, g_adj_list.size());
      buffer = (char *)malloc( (buffer_size + 1)*sizeof(char));
      MPI_File_read_at(infile, offset, buffer, buffer_size, MPI_CHAR, MPI_STATUS_IGNORE);
      offset += buffer_size;
      // end the string
      buffer[buffer_size] = '\0';
      std::string new_string(buffer);
      free(buffer);
      chunk += new_string;

      if (skip){
        // skip up to the first newline to remove any broken lines from starting in the middle of the file
        chunk = chunk.substr(chunk.find('\n')+1);
      }else{
        skip = true;
      }

      int found_nl = chunk.find('\n');
      while (found_nl < chunk.size()){
        std::string line = chunk.substr(0, found_nl);
        add_to_adjlist(line);

        chunk = chunk.substr(found_nl+1);
        found_nl = chunk.find('\n');
      }
    }
    //MPI_Barrier(MPI_COMM_WORLD);
    MPI_File_close(&infile);
    lowFile++;
    memset(&filename[0], 0, sizeof(filename));
  }
  printf("Rank %d: finished read in of own portion of file    %lu\n", g_mpi_rank, g_adj_list.size());
    //sprintf(filename, "com-friendster.ungraph.txt");
}

int id_to_rank(int id){
  int max_id=0;
  for (int i=0; i<g_world_size; i++){
    max_id += g_max_id / g_world_size;
    if (id < max_id){
      return i;
    }
  }
  return g_world_size-1;
}

void add_to_adjlist(std::string line){
  int tab_pos = line.find("\t");
  int one = atoi(line.substr(0, tab_pos).c_str());
  int two = atoi(line.substr(tab_pos+1).c_str());
  if (one >= start_id && one < end_id){
    g_adj_list[one].insert(two);
  }
}
<|endoftext|>