text:
/* Why don't we use the SD controllers' carddetect feature?
 *
 * From the AU1100 MMC application guide:
 * If the Au1100-based design is intended to support both MultiMediaCards
 * and 1- or 4-data bit SecureDigital cards, then the solution is to
 * connect a weak (560KOhm) pull-up resistor to connector pin 1.
 * In doing so, a MMC card never enters SPI-mode communications,
 * but now the SecureDigital card-detect feature of CD/DAT3 is ineffective
 * (the low to high transition will not occur).
 */

#include <linux/clk.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/leds.h>
#include <linux/mmc/host.h>
#include <linux/slab.h>

#include <asm/io.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1100_mmc.h>

#define DRIVER_NAME "au1xxx-mmc"

/* Set this to enable special debugging macros */
/* #define DEBUG */

#ifdef DEBUG
#define DBG(fmt, idx, args...)	\
	pr_debug("au1xmmc(%d): DEBUG: " fmt, idx, ##args)
#else
#define DBG(fmt, idx, args...) do {} while (0)
#endif

/* Hardware definitions */
#define AU1XMMC_DESCRIPTOR_COUNT 1

/* max DMA seg size: 64KB on Au1100, 4MB on Au1200 */
#define AU1100_MMC_DESCRIPTOR_SIZE 0x0000ffff
#define AU1200_MMC_DESCRIPTOR_SIZE 0x003fffff

#define AU1XMMC_OCR (MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \
		     MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \
		     MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36)

/* This gives us a hard value for the stop command that we can write directly
 * to the command register.
 */
#define STOP_CMD	\
	(SD_CMD_RT_1B | SD_CMD_CT_7 | (0xC << SD_CMD_CI_SHIFT) | SD_CMD_GO)

/* This is the set of interrupts that we configure by default. */
#define AU1XMMC_INTERRUPTS 				\
	(SD_CONFIG_SC | SD_CONFIG_DT | SD_CONFIG_RAT |	\
	 SD_CONFIG_CR | SD_CONFIG_I)

/* The poll event (looking for insert/remove events runs twice a second. */
#define AU1XMMC_DETECT_TIMEOUT (HZ/2)

struct au1xmmc_host {
	struct mmc_host *mmc;
	struct mmc_request *mrq;

	u32 flags;
	void __iomem *iobase;
	u32 clock;
	u32 bus_width;
	u32 power_mode;

	int status;

	struct {
		int len;
		int dir;
	} dma;

	struct {
		int index;
		int offset;
		int len;
	} pio;

	u32 tx_chan;
	u32 rx_chan;

	int irq;

	struct tasklet_struct finish_task;
	struct tasklet_struct data_task;
	struct au1xmmc_platform_data *platdata;
	struct platform_device *pdev;
	struct resource *ioarea;
	struct clk *clk;
};

/* Status flags used by the host structure */
#define HOST_F_XMIT	0x0001
#define HOST_F_RECV	0x0002
#define HOST_F_DMA	0x0010
#define HOST_F_DBDMA	0x0020
#define HOST_F_ACTIVE	0x0100
#define HOST_F_STOP	0x1000

#define HOST_S_IDLE	0x0001
#define HOST_S_CMD	0x0002
#define HOST_S_DATA	0x0003
#define HOST_S_STOP	0x0004

/* Easy access macros */
#define HOST_STATUS(h)	((h)->iobase + SD_STATUS)
#define HOST_CONFIG(h)	((h)->iobase + SD_CONFIG)
#define HOST_ENABLE(h)	((h)->iobase + SD_ENABLE)
#define HOST_TXPORT(h)	((h)->iobase + SD_TXPORT)
#define HOST_RXPORT(h)	((h)->iobase + SD_RXPORT)
#define HOST_CMDARG(h)	((h)->iobase + SD_CMDARG)
#define HOST_BLKSIZE(h)	((h)->iobase + SD_BLKSIZE)
#define HOST_CMD(h)	((h)->iobase + SD_CMD)
#define HOST_CONFIG2(h)	((h)->iobase + SD_CONFIG2)
#define HOST_TIMEOUT(h)	((h)->iobase + SD_TIMEOUT)
#define HOST_DEBUG(h)	((h)->iobase + SD_DEBUG)

#define DMA_CHANNEL(h)	\
	(((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan)

static inline int has_dbdma(void)
{
	switch (alchemy_get_cputype()) {
	case ALCHEMY_CPU_AU1200:
	case ALCHEMY_CPU_AU1300:
		return 1;
	default:
		return 0;
	}
}

static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask)
{
	u32 val = __raw_readl(HOST_CONFIG(host));
	val |= mask;
	__raw_writel(val, HOST_CONFIG(host));
	wmb(); /* drain writebuffer */
}

static inline void FLUSH_FIFO(struct au1xmmc_host *host)
{
	u32 val = __raw_readl(HOST_CONFIG2(host));

	__raw_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host));
	wmb(); /* drain writebuffer */
	mdelay(1);

	/* SEND_STOP will turn off clock control - this re-enables it */
	val &= ~SD_CONFIG2_DF;

	__raw_writel(val, HOST_CONFIG2(host));
	wmb(); /* drain writebuffer */
}

static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask)
{
	u32 val = __raw_readl(HOST_CONFIG(host));
	val &= ~mask;
	__raw_writel(val, HOST_CONFIG(host));
	wmb(); /* drain writebuffer */
}

static inline void SEND_STOP(struct au1xmmc_host *host)
{
	u32 config2;

	WARN_ON(host->status != HOST_S_DATA);
	host->status = HOST_S_STOP;

	config2 = __raw_readl(HOST_CONFIG2(host));
	__raw_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host));
	wmb(); /* drain writebuffer */

	/* Send the stop command */
	__raw_writel(STOP_CMD, HOST_CMD(host));
	wmb(); /* drain writebuffer */
}

static void au1xmmc_set_power(struct au1xmmc_host *host, int state)
{
	if (host->platdata && host->platdata->set_power)
		host->platdata->set_power(host->mmc, state);
}

static int au1xmmc_card_inserted(struct mmc_host *mmc)
{
	struct au1xmmc_host *host = mmc_priv(mmc);

	if (host->platdata && host->platdata->card_inserted)
		return !!host->platdata->card_inserted(host->mmc);

	return -ENOSYS;
}

static int au1xmmc_card_readonly(struct mmc_host *mmc)
{
	struct au1xmmc_host *host = mmc_priv(mmc);

	if (host->platdata && host->platdata->card_readonly)
		return !!host->platdata->card_readonly(mmc);

	return -ENOSYS;
}

static void au1xmmc_finish_request(struct au1xmmc_host *host)
{
	struct mmc_request *mrq = host->mrq;

	host->mrq = NULL;
	host->flags &= HOST_F_ACTIVE | HOST_F_DMA;

	host->dma.len = 0;
	host->dma.dir = 0;

	host->pio.index  = 0;
	host->pio.offset = 0;
	host->pio.len = 0;

	host->status = HOST_S_IDLE;

	mmc_request_done(host->mmc, mrq);
}

static void au1xmmc_tasklet_finish(unsigned long param)
{
	struct au1xmmc_host *host = (struct au1xmmc_host *) param;
	au1xmmc_finish_request(host);
}

static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
				struct mmc_command *cmd, struct mmc_data *data)
{
	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);

	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		break;
	case MMC_RSP_R1:
		mmccmd |= SD_CMD_RT_1;
		break;
	case MMC_RSP_R1B:
		mmccmd |= SD_CMD_RT_1B;
		break;
	case MMC_RSP_R2:
		mmccmd |= SD_CMD_RT_2;
		break;
	case MMC_RSP_R3:
		mmccmd |= SD_CMD_RT_3;
		break;
	default:
		pr_info("au1xmmc: unhandled response type %02x\n",
			mmc_resp_type(cmd));
		return -EINVAL;
	}

	if (data) {
		if (data->flags & MMC_DATA_READ) {
			if (data->blocks > 1)
				mmccmd |= SD_CMD_CT_4;
			else
				mmccmd |= SD_CMD_CT_2;
		} else if (data->flags & MMC_DATA_WRITE) {
			if (data->blocks > 1)
				mmccmd |= SD_CMD_CT_3;
			else
				mmccmd |= SD_CMD_CT_1;
		}
	}

	__raw_writel(cmd->arg, HOST_CMDARG(host));
	wmb(); /* drain writebuffer */

	if (wait)
		IRQ_OFF(host, SD_CONFIG_CR);

	__raw_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
	wmb(); /* drain writebuffer */

	/* Wait for the command to go on the line */
	while (__raw_readl(HOST_CMD(host)) & SD_CMD_GO)
		/* nop */;

	/* Wait for the command to come back */
	if (wait) {
		u32 status = __raw_readl(HOST_STATUS(host));

		while (!(status & SD_STATUS_CR))
			status = __raw_readl(HOST_STATUS(host));

		/* Clear the CR status */
		__raw_writel(SD_STATUS_CR, HOST_STATUS(host));

		IRQ_ON(host, SD_CONFIG_CR);
	}

	return 0;
}

static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
{
	struct mmc_request *mrq = host->mrq;
	struct mmc_data *data;
	u32 crc;

	WARN_ON((host->status != HOST_S_DATA) && (host->status != HOST_S_STOP));

	if (host->mrq == NULL)
		return;

	data = mrq->cmd->data;

	if (status == 0)
		status = __raw_readl(HOST_STATUS(host));

	/* The transaction is really over when the SD_STATUS_DB bit is clear */
	while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
		status = __raw_readl(HOST_STATUS(host));

	data->error = 0;
	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);

        /* Process any errors */
	crc = (status & (SD_STATUS_WC | SD_STATUS_RC));
	if (host->flags & HOST_F_XMIT)
		crc |= ((status & 0x07) == 0x02) ? 0 : 1;

	if (crc)
		data->error = -EILSEQ;

	/* Clear the CRC bits */
	__raw_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));

	data->bytes_xfered = 0;

	if (!data->error) {
		if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) {
			u32 chan = DMA_CHANNEL(host);

			chan_tab_t *c = *((chan_tab_t **)chan);
			au1x_dma_chan_t *cp = c->chan_ptr;
			data->bytes_xfered = cp->ddma_bytecnt;
		} else
			data->bytes_xfered =
				(data->blocks * data->blksz) - host->pio.len;
	}

	au1xmmc_finish_request(host);
}

static void au1xmmc_tasklet_data(unsigned long param)
{
	struct au1xmmc_host *host = (struct au1xmmc_host *)param;

	u32 status = __raw_readl(HOST_STATUS(host));
	au1xmmc_data_complete(host, status);
}

#define AU1XMMC_MAX_TRANSFER 8

static void au1xmmc_send_pio(struct au1xmmc_host *host)
{
	struct mmc_data *data;
	int sg_len, max, count;
	unsigned char *sg_ptr, val;
	u32 status;
	struct scatterlist *sg;

	data = host->mrq->data;

	if (!(host->flags & HOST_F_XMIT))
		return;

	/* This is the pointer to the data buffer */
	sg = &data->sg[host->pio.index];
	sg_ptr = sg_virt(sg) + host->pio.offset;

	/* This is the space left inside the buffer */
	sg_len = data->sg[host->pio.index].length - host->pio.offset;

	/* Check if we need less than the size of the sg_buffer */
	max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
	if (max > AU1XMMC_MAX_TRANSFER)
		max = AU1XMMC_MAX_TRANSFER;

	for (count = 0; count < max; count++) {
		status = __raw_readl(HOST_STATUS(host));

		if (!(status & SD_STATUS_TH))
			break;

		val = *sg_ptr++;

		__raw_writel((unsigned long)val, HOST_TXPORT(host));
		wmb(); /* drain writebuffer */
	}

	host->pio.len -= count;
	host->pio.offset += count;

	if (count == sg_len) {
		host->pio.index++;
		host->pio.offset = 0;
	}

	if (host->pio.len == 0) {
		IRQ_OFF(host, SD_CONFIG_TH);

		if (host->flags & HOST_F_STOP)
			SEND_STOP(host);

		tasklet_schedule(&host->data_task);
	}
}

static void au1xmmc_receive_pio(struct au1xmmc_host *host)
{
	struct mmc_data *data;
	int max, count, sg_len = 0;
	unsigned char *sg_ptr = NULL;
	u32 status, val;
	struct scatterlist *sg;

	data = host->mrq->data;

	if (!(host->flags & HOST_F_RECV))
		return;

	max = host->pio.len;

	if (host->pio.index < host->dma.len) {
		sg = &data->sg[host->pio.index];
		sg_ptr = sg_virt(sg) + host->pio.offset;

		/* This is the space left inside the buffer */
		sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;

		/* Check if we need less than the size of the sg_buffer */
		if (sg_len < max)
			max = sg_len;
	}

	if (max > AU1XMMC_MAX_TRANSFER)
		max = AU1XMMC_MAX_TRANSFER;

	for (count = 0; count < max; count++) {
		status = __raw_readl(HOST_STATUS(host));

		if (!(status & SD_STATUS_NE))
			break;

		if (status & SD_STATUS_RC) {
			DBG("RX CRC Error [%d + %d].\n", host->pdev->id,
					host->pio.len, count);
			break;
		}

		if (status & SD_STATUS_RO) {
			DBG("RX Overrun [%d + %d]\n", host->pdev->id,
					host->pio.len, count);
			break;
		}
		else if (status & SD_STATUS_RU) {
			DBG("RX Underrun [%d + %d]\n", host->pdev->id,
					host->pio.len,	count);
			break;
		}

		val = __raw_readl(HOST_RXPORT(host));

		if (sg_ptr)
			*sg_ptr++ = (unsigned char)(val & 0xFF);
	}

	host->pio.len -= count;
	host->pio.offset += count;

	if (sg_len && count == sg_len) {
		host->pio.index++;
		host->pio.offset = 0;
	}

	if (host->pio.len == 0) {
		/* IRQ_OFF(host, SD_CONFIG_RA | SD_CONFIG_RF); */
		IRQ_OFF(host, SD_CONFIG_NE);

		if (host->flags & HOST_F_STOP)
			SEND_STOP(host);

		tasklet_schedule(&host->data_task);
	}
}

/* This is called when a command has been completed - grab the response
 * and check for errors.  Then start the data transfer if it is indicated.
 */
static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
{
	struct mmc_request *mrq = host->mrq;
	struct mmc_command *cmd;
	u32 r[4];
	int i, trans;

	if (!host->mrq)
		return;

	cmd = mrq->cmd;
	cmd->error = 0;

	if (cmd->flags & MMC_RSP_PRESENT) {
		if (cmd->flags & MMC_RSP_136) {
			r[0] = __raw_readl(host->iobase + SD_RESP3);
			r[1] = __raw_readl(host->iobase + SD_RESP2);
			r[2] = __raw_readl(host->iobase + SD_RESP1);
			r[3] = __raw_readl(host->iobase + SD_RESP0);

			/* The CRC is omitted from the response, so really
			 * we only got 120 bytes, but the engine expects
			 * 128 bits, so we have to shift things up.
			 */
			for (i = 0; i < 4; i++) {
				cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
				if (i != 3)
					cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24;
			}
		} else {
			/* Techincally, we should be getting all 48 bits of
			 * the response (SD_RESP1 + SD_RESP2), but because
			 * our response omits the CRC, our data ends up
			 * being shifted 8 bits to the right.  In this case,
			 * that means that the OSR data starts at bit 31,
			 * so we can just read RESP0 and return that.
			 */
			cmd->resp[0] = __raw_readl(host->iobase + SD_RESP0);
		}
	}

        /* Figure out errors */
	if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC))
		cmd->error = -EILSEQ;

	trans = host->flags & (HOST_F_XMIT | HOST_F_RECV);

	if (!trans || cmd->error) {
		IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA | SD_CONFIG_RF);
		tasklet_schedule(&host->finish_task);
		return;
	}

	host->status = HOST_S_DATA;

	if ((host->flags & (HOST_F_DMA | HOST_F_DBDMA))) {
		u32 channel = DMA_CHANNEL(host);

		/* Start the DBDMA as soon as the buffer gets something in it */

		if (host->flags & HOST_F_RECV) {
			u32 mask = SD_STATUS_DB | SD_STATUS_NE;

			while((status & mask) != mask)
				status = __raw_readl(HOST_STATUS(host));
		}

		au1xxx_dbdma_start(channel);
	}
}

static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate)
{
	unsigned int pbus = clk_get_rate(host->clk);
	unsigned int divisor = ((pbus / rate) / 2) - 1;
	u32 config;

	config = __raw_readl(HOST_CONFIG(host));

	config &= ~(SD_CONFIG_DIV);
	config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE;

	__raw_writel(config, HOST_CONFIG(host));
	wmb(); /* drain writebuffer */
}

static int au1xmmc_prepare_data(struct au1xmmc_host *host,
				struct mmc_data *data)
{
	int datalen = data->blocks * data->blksz;

	if (data->flags & MMC_DATA_READ)
		host->flags |= HOST_F_RECV;
	else
		host->flags |= HOST_F_XMIT;

	if (host->mrq->stop)
		host->flags |= HOST_F_STOP;

	host->dma.dir = DMA_BIDIRECTIONAL;

	host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg,
				   data->sg_len, host->dma.dir);

	if (host->dma.len == 0)
		return -ETIMEDOUT;

	__raw_writel(data->blksz - 1, HOST_BLKSIZE(host));

	if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) {
		int i;
		u32 channel = DMA_CHANNEL(host);

		au1xxx_dbdma_stop(channel);

		for (i = 0; i < host->dma.len; i++) {
			u32 ret = 0, flags = DDMA_FLAGS_NOIE;
			struct scatterlist *sg = &data->sg[i];
			int sg_len = sg->length;

			int len = (datalen > sg_len) ? sg_len : datalen;

			if (i == host->dma.len - 1)
				flags = DDMA_FLAGS_IE;

			if (host->flags & HOST_F_XMIT) {
				ret = au1xxx_dbdma_put_source(channel,
					sg_phys(sg), len, flags);
			} else {
				ret = au1xxx_dbdma_put_dest(channel,
					sg_phys(sg), len, flags);
			}

			if (!ret)
				goto dataerr;

			datalen -= len;
		}
	} else {
		host->pio.index = 0;
		host->pio.offset = 0;
		host->pio.len = datalen;

		if (host->flags & HOST_F_XMIT)
			IRQ_ON(host, SD_CONFIG_TH);
		else
			IRQ_ON(host, SD_CONFIG_NE);
			/* IRQ_ON(host, SD_CONFIG_RA | SD_CONFIG_RF); */
	}

	return 0;

dataerr:
	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
			host->dma.dir);
	return -ETIMEDOUT;
}

/* This actually starts a command or data transaction */
static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
{
	struct au1xmmc_host *host = mmc_priv(mmc);
	int ret = 0;

	WARN_ON(irqs_disabled());
	WARN_ON(host->status != HOST_S_IDLE);

	host->mrq = mrq;
	host->status = HOST_S_CMD;

	/* fail request immediately if no card is present */
	if (0 == au1xmmc_card_inserted(mmc)) {
		mrq->cmd->error = -ENOMEDIUM;
		au1xmmc_finish_request(host);
		return;
	}

	if (mrq->data) {
		FLUSH_FIFO(host);
		ret = au1xmmc_prepare_data(host, mrq->data);
	}

	if (!ret)
		ret = au1xmmc_send_command(host, 0, mrq->cmd, mrq->data);

	if (ret) {
		mrq->cmd->error = ret;
		au1xmmc_finish_request(host);
	}
}

static void au1xmmc_reset_controller(struct au1xmmc_host *host)
{
	/* Apply the clock */
	__raw_writel(SD_ENABLE_CE, HOST_ENABLE(host));
	wmb(); /* drain writebuffer */
	mdelay(1);

	__raw_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host));
	wmb(); /* drain writebuffer */
	mdelay(5);

	__raw_writel(~0, HOST_STATUS(host));
	wmb(); /* drain writebuffer */

	__raw_writel(0, HOST_BLKSIZE(host));
	__raw_writel(0x001fffff, HOST_TIMEOUT(host));
	wmb(); /* drain writebuffer */

	__raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
	wmb(); /* drain writebuffer */

	__raw_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host));
	wmb(); /* drain writebuffer */
	mdelay(1);

	__raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host));
	wmb(); /* drain writebuffer */

	/* Configure interrupts */
	__raw_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host));
	wmb(); /* drain writebuffer */
}

static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct au1xmmc_host *host = mmc_priv(mmc);
	u32 config2;

	if (ios->power_mode == MMC_POWER_OFF)
		au1xmmc_set_power(host, 0);
	else if (ios->power_mode == MMC_POWER_ON) {
		au1xmmc_set_power(host, 1);
	}

	if (ios->clock && ios->clock != host->clock) {
		au1xmmc_set_clock(host, ios->clock);
		host->clock = ios->clock;
	}

	config2 = __raw_readl(HOST_CONFIG2(host));
	switch (ios->bus_width) {
	case MMC_BUS_WIDTH_8:
		config2 |= SD_CONFIG2_BB;
		break;
	case MMC_BUS_WIDTH_4:
		config2 &= ~SD_CONFIG2_BB;
		config2 |= SD_CONFIG2_WB;
		break;
	case MMC_BUS_WIDTH_1:
		config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB);
		break;
	}
	__raw_writel(config2, HOST_CONFIG2(host));
	wmb(); /* drain writebuffer */
}

#define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT)
#define STATUS_DATA_IN  (SD_STATUS_NE)
#define STATUS_DATA_OUT (SD_STATUS_TH)

static irqreturn_t au1xmmc_irq(int irq, void *dev_id)
{
	struct au1xmmc_host *host = dev_id;
	u32 status;

	status = __raw_readl(HOST_STATUS(host));

	if (!(status & SD_STATUS_I))
		return IRQ_NONE;	/* not ours */

	if (status & SD_STATUS_SI)	/* SDIO */
		mmc_signal_sdio_irq(host->mmc);

	if (host->mrq && (status & STATUS_TIMEOUT)) {
		if (status & SD_STATUS_RAT)
			host->mrq->cmd->error = -ETIMEDOUT;
		else if (status & SD_STATUS_DT)
			host->mrq->data->error = -ETIMEDOUT;

		/* In PIO mode, interrupts might still be enabled */
		IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);

		/* IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA | SD_CONFIG_RF); */
		tasklet_schedule(&host->finish_task);
	}
#if 0
	else if (status & SD_STATUS_DD) {
		/* Sometimes we get a DD before a NE in PIO mode */
		if (!(host->flags & HOST_F_DMA) && (status & SD_STATUS_NE))
			au1xmmc_receive_pio(host);
		else {
			au1xmmc_data_complete(host, status);
			/* tasklet_schedule(&host->data_task); */
		}
	}
#endif
	else if (status & SD_STATUS_CR) {
		if (host->status == HOST_S_CMD)
			au1xmmc_cmd_complete(host, status);

	} else if (!(host->flags & HOST_F_DMA)) {
		if ((host->flags & HOST_F_XMIT) && (status & STATUS_DATA_OUT))
			au1xmmc_send_pio(host);
		else if ((host->flags & HOST_F_RECV) && (status & STATUS_DATA_IN))
			au1xmmc_receive_pio(host);

	} else if (status & 0x203F3C70) {
			DBG("Unhandled status %8.8x\n", host->pdev->id,
				status);
	}

	__raw_writel(status, HOST_STATUS(host));
	wmb(); /* drain writebuffer */

	return IRQ_HANDLED;
}

/* 8bit memory DMA device */
static dbdev_tab_t au1xmmc_mem_dbdev = {
	.dev_id		= DSCR_CMD0_ALWAYS,
	.dev_flags	= DEV_FLAGS_ANYUSE,
	.dev_tsize	= 0,
	.dev_devwidth	= 8,
	.dev_physaddr	= 0x00000000,
	.dev_intlevel	= 0,
	.dev_intpolarity = 0,
};
static int memid;

static void au1xmmc_dbdma_callback(int irq, void *dev_id)
{
	struct au1xmmc_host *host = (struct au1xmmc_host *)dev_id;

	/* Avoid spurious interrupts */
	if (!host->mrq)
		return;

	if (host->flags & HOST_F_STOP)
		SEND_STOP(host);

	tasklet_schedule(&host->data_task);
}

static int au1xmmc_dbdma_init(struct au1xmmc_host *host)
{
	struct resource *res;
	int txid, rxid;

	res = platform_get_resource(host->pdev, IORESOURCE_DMA, 0);
	if (!res)
		return -ENODEV;
	txid = res->start;

	res = platform_get_resource(host->pdev, IORESOURCE_DMA, 1);
	if (!res)
		return -ENODEV;
	rxid = res->start;

	if (!memid)
		return -ENODEV;

	host->tx_chan = au1xxx_dbdma_chan_alloc(memid, txid,
				au1xmmc_dbdma_callback, (void *)host);
	if (!host->tx_chan) {
		dev_err(&host->pdev->dev, "cannot allocate TX DMA\n");
		return -ENODEV;
	}

	host->rx_chan = au1xxx_dbdma_chan_alloc(rxid, memid,
				au1xmmc_dbdma_callback, (void *)host);
	if (!host->rx_chan) {
		dev_err(&host->pdev->dev, "cannot allocate RX DMA\n");
		au1xxx_dbdma_chan_free(host->tx_chan);
		return -ENODEV;
	}

	au1xxx_dbdma_set_devwidth(host->tx_chan, 8);
	au1xxx_dbdma_set_devwidth(host->rx_chan, 8);

	au1xxx_dbdma_ring_alloc(host->tx_chan, AU1XMMC_DESCRIPTOR_COUNT);
	au1xxx_dbdma_ring_alloc(host->rx_chan, AU1XMMC_DESCRIPTOR_COUNT);

	/* DBDMA is good to go */
	host->flags |= HOST_F_DMA | HOST_F_DBDMA;

	return 0;
}

static void au1xmmc_dbdma_shutdown(struct au1xmmc_host *host)
{
	if (host->flags & HOST_F_DMA) {
		host->flags &= ~HOST_F_DMA;
		au1xxx_dbdma_chan_free(host->tx_chan);
		au1xxx_dbdma_chan_free(host->rx_chan);
	}
}

static void au1xmmc_enable_sdio_irq(struct mmc_host *mmc, int en)
{
	struct au1xmmc_host *host = mmc_priv(mmc);

	if (en)
		IRQ_ON(host, SD_CONFIG_SI);
	else
		IRQ_OFF(host, SD_CONFIG_SI);
}

static const struct mmc_host_ops au1xmmc_ops = {
	.request	= au1xmmc_request,
	.set_ios	= au1xmmc_set_ios,
	.get_ro		= au1xmmc_card_readonly,
	.get_cd		= au1xmmc_card_inserted,
	.enable_sdio_irq = au1xmmc_enable_sdio_irq,
};

static int au1xmmc_probe(struct platform_device *pdev)
{
	struct mmc_host *mmc;
	struct au1xmmc_host *host;
	struct resource *r;
	int ret, iflag;

	mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev);
	if (!mmc) {
		dev_err(&pdev->dev, "no memory for mmc_host\n");
		ret = -ENOMEM;
		goto out0;
	}

	host = mmc_priv(mmc);
	host->mmc = mmc;
	host->platdata = pdev->dev.platform_data;
	host->pdev = pdev;

	ret = -ENODEV;
	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "no mmio defined\n");
		goto out1;
	}

	host->ioarea = request_mem_region(r->start, resource_size(r),
					   pdev->name);
	if (!host->ioarea) {
		dev_err(&pdev->dev, "mmio already in use\n");
		goto out1;
	}

	host->iobase = ioremap(r->start, 0x3c);
	if (!host->iobase) {
		dev_err(&pdev->dev, "cannot remap mmio\n");
		goto out2;
	}

	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!r) {
		dev_err(&pdev->dev, "no IRQ defined\n");
		goto out3;
	}
	host->irq = r->start;

	mmc->ops = &au1xmmc_ops;

	mmc->f_min =   450000;
	mmc->f_max = 24000000;

	mmc->max_blk_size = 2048;
	mmc->max_blk_count = 512;

	mmc->ocr_avail = AU1XMMC_OCR;
	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
	mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT;

	iflag = IRQF_SHARED;	/* Au1100/Au1200: one int for both ctrls */

	switch (alchemy_get_cputype()) {
	case ALCHEMY_CPU_AU1100:
		mmc->max_seg_size = AU1100_MMC_DESCRIPTOR_SIZE;
		break;
	case ALCHEMY_CPU_AU1200:
		mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE;
		break;
	case ALCHEMY_CPU_AU1300:
		iflag = 0;	/* nothing is shared */
		mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE;
		mmc->f_max = 52000000;
		if (host->ioarea->start == AU1100_SD0_PHYS_ADDR)
			mmc->caps |= MMC_CAP_8_BIT_DATA;
		break;
	}

	ret = request_irq(host->irq, au1xmmc_irq, iflag, DRIVER_NAME, host);
	if (ret) {
		dev_err(&pdev->dev, "cannot grab IRQ\n");
		goto out3;
	}

	host->clk = clk_get(&pdev->dev, ALCHEMY_PERIPH_CLK);
	if (IS_ERR(host->clk)) {
		dev_err(&pdev->dev, "cannot find clock\n");
		ret = PTR_ERR(host->clk);
		goto out_irq;
	}

	ret = clk_prepare_enable(host->clk);
	if (ret) {
		dev_err(&pdev->dev, "cannot enable clock\n");
		goto out_clk;
	}

	host->status = HOST_S_IDLE;

	/* board-specific carddetect setup, if any */
	if (host->platdata && host->platdata->cd_setup) {
		ret = host->platdata->cd_setup(mmc, 1);
		if (ret) {
			dev_warn(&pdev->dev, "board CD setup failed\n");
			mmc->caps |= MMC_CAP_NEEDS_POLL;
		}
	} else
		mmc->caps |= MMC_CAP_NEEDS_POLL;

	/* platform may not be able to use all advertised caps */
	if (host->platdata)
		mmc->caps &= ~(host->platdata->mask_host_caps);

	tasklet_init(&host->data_task, au1xmmc_tasklet_data,
			(unsigned long)host);

	tasklet_init(&host->finish_task, au1xmmc_tasklet_finish,
			(unsigned long)host);

	if (has_dbdma()) {
		ret = au1xmmc_dbdma_init(host);
		if (ret)
			pr_info(DRIVER_NAME ": DBDMA init failed; using PIO\n");
	}

#ifdef CONFIG_LEDS_CLASS
	if (host->platdata && host->platdata->led) {
		struct led_classdev *led = host->platdata->led;
		led->name = mmc_hostname(mmc);
		led->brightness = LED_OFF;
		led->default_trigger = mmc_hostname(mmc);
		ret = led_classdev_register(mmc_dev(mmc), led);
		if (ret)
			goto out5;
	}
#endif

	au1xmmc_reset_controller(host);

	ret = mmc_add_host(mmc);
	if (ret) {
		dev_err(&pdev->dev, "cannot add mmc host\n");
		goto out6;
	}

	platform_set_drvdata(pdev, host);

	pr_info(DRIVER_NAME ": MMC Controller %d set up at %p"
		" (mode=%s)\n", pdev->id, host->iobase,
		host->flags & HOST_F_DMA ? "dma" : "pio");

	return 0;	/* all ok */

out6:
#ifdef CONFIG_LEDS_CLASS
	if (host->platdata && host->platdata->led)
		led_classdev_unregister(host->platdata->led);
out5:
#endif
	__raw_writel(0, HOST_ENABLE(host));
	__raw_writel(0, HOST_CONFIG(host));
	__raw_writel(0, HOST_CONFIG2(host));
	wmb(); /* drain writebuffer */

	if (host->flags & HOST_F_DBDMA)
		au1xmmc_dbdma_shutdown(host);

	tasklet_kill(&host->data_task);
	tasklet_kill(&host->finish_task);

	if (host->platdata && host->platdata->cd_setup &&
	    !(mmc->caps & MMC_CAP_NEEDS_POLL))
		host->platdata->cd_setup(mmc, 0);
out_clk:
	clk_disable_unprepare(host->clk);
	clk_put(host->clk);
out_irq:
	free_irq(host->irq, host);
out3:
	iounmap((void *)host->iobase);
out2:
	release_resource(host->ioarea);
	kfree(host->ioarea);
out1:
	mmc_free_host(mmc);
out0:
	return ret;
}

static int au1xmmc_remove(struct platform_device *pdev)
{
	struct au1xmmc_host *host = platform_get_drvdata(pdev);

	if (host) {
		mmc_remove_host(host->mmc);

#ifdef CONFIG_LEDS_CLASS
		if (host->platdata && host->platdata->led)
			led_classdev_unregister(host->platdata->led);
#endif

		if (host->platdata && host->platdata->cd_setup &&
		    !(host->mmc->caps & MMC_CAP_NEEDS_POLL))
			host->platdata->cd_setup(host->mmc, 0);

		__raw_writel(0, HOST_ENABLE(host));
		__raw_writel(0, HOST_CONFIG(host));
		__raw_writel(0, HOST_CONFIG2(host));
		wmb(); /* drain writebuffer */

		tasklet_kill(&host->data_task);
		tasklet_kill(&host->finish_task);

		if (host->flags & HOST_F_DBDMA)
			au1xmmc_dbdma_shutdown(host);

		au1xmmc_set_power(host, 0);

		clk_disable_unprepare(host->clk);
		clk_put(host->clk);

		free_irq(host->irq, host);
		iounmap((void *)host->iobase);
		release_resource(host->ioarea);
		kfree(host->ioarea);

		mmc_free_host(host->mmc);
	}
	return 0;
}

#ifdef CONFIG_PM
static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct au1xmmc_host *host = platform_get_drvdata(pdev);

	__raw_writel(0, HOST_CONFIG2(host));
	__raw_writel(0, HOST_CONFIG(host));
	__raw_writel(0xffffffff, HOST_STATUS(host));
	__raw_writel(0, HOST_ENABLE(host));
	wmb(); /* drain writebuffer */

	return 0;
}

static int au1xmmc_resume(struct platform_device *pdev)
{
	struct au1xmmc_host *host = platform_get_drvdata(pdev);

	au1xmmc_reset_controller(host);

	return 0;
}
#else
#define au1xmmc_suspend NULL
#define au1xmmc_resume NULL
#endif

static struct platform_driver au1xmmc_driver = {
	.probe         = au1xmmc_probe,
	.remove        = au1xmmc_remove,
	.suspend       = au1xmmc_suspend,
	.resume        = au1xmmc_resume,
	.driver        = {
		.name  = DRIVER_NAME,
	},
};

static int __init au1xmmc_init(void)
{
	if (has_dbdma()) {
		/* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride
		* of 8 bits.  And since devices are shared, we need to create
		* our own to avoid freaking out other devices.
		*/
		memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
		if (!memid)
			pr_err("au1xmmc: cannot add memory dbdma\n");
	}
	return platform_driver_register(&au1xmmc_driver);
}

static void __exit au1xmmc_exit(void)
{
	if (has_dbdma() && memid)
		au1xxx_ddma_del_device(memid);

	platform_driver_unregister(&au1xmmc_driver);
}

module_init(au1xmmc_init);
module_exit(au1xmmc_exit);

MODULE_AUTHOR("Advanced Micro Devices, Inc");
MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:au1xxx-mmc");


text:
"""Constants shared between gateware and C++"""

import argparse
import sys

class Constants:
    ###########################################################################
    # Funct3 codes - used to route CFU to instructions
    INS_SET = 0
    INS_GET = 1
    INS_POOL = 2
    INS_PING = 7

    # Registers
    REG_VERIFY = 0

    # Write any value to start or reset to trigger accelerator start or reset
    REG_ACCELERATOR_START = 1
    REG_ACCELERATOR_RESET = 2

    # Write data to filter store at address
    # in0 = (store << 16 | addr), in1  = data
    REG_FILTER_WRITE = 3

    # Configuration values
    # See ACCELERATOR_CONFIGURATION_LAYOUT in accelerator.py
    REG_MODE = 4
    REG_INPUT_OFFSET = 5
    REG_NUM_FILTER_WORDS = 6
    REG_OUTPUT_OFFSET = 7
    REG_OUTPUT_ACTIVATION_MIN = 8
    REG_OUTPUT_ACTIVATION_MAX = 9
    REG_INPUT_BASE_ADDR = 10
    REG_NUM_PIXELS_X = 11
    REG_PIXEL_ADVANCE_X = 12
    REG_PIXEL_ADVANCE_Y = 13
    REG_INPUT_CHANNEL_DEPTH = 14
    REG_OUTPUT_CHANNEL_DEPTH = 15
    REG_NUM_OUTPUT_VALUES = 16

    # For post process parameters. Writing multiplier sends all values
    REG_POST_PROCESS_BIAS = 17
    REG_POST_PROCESS_SHIFT = 18
    REG_POST_PROCESS_MULTIPLIER = 19

    # Gets the output value
    REG_OUTPUT_WORD = 20

    # Number of items in FIFO
    REG_FIFO_ITEMS = 21

    # Maximum number of 8-bit channels per pixel
    MAX_CHANNEL_DEPTH = 512

    # Height (A dimension, aka activation values, aka inputs)
    # Must be a power of 2. Only tested with value 4
    SYS_ARRAY_HEIGHT = 4

    # Width (B dimension, aka filter values) of the Systolic array
    # Must be a power of 2. Only tested with value 2
    SYS_ARRAY_WIDTH = 2

    # Total Number of MACC blocks in Systolic array
    SYS_ARRAY_MACC_BLOCKS = SYS_ARRAY_HEIGHT * SYS_ARRAY_WIDTH

    # Total number of separate store
    NUM_FILTER_STORES = SYS_ARRAY_WIDTH

    # Depth of filter storage, per store
    FILTER_WORDS_PER_STORE = 512

    # Number of words in the output queue
    OUTPUT_FIFO_DEPTH = 1024

    # Accelerator Mode
    MODE_0 = 0  # For input layers
    MODE_1 = 1  # For other layers

CC_FILE_HEADER = """// Generated file
// Shared constants generated from gen2/gateware/constants.py
#ifndef _GATEWARE_CONSTANTS_H
#define _GATEWARE_CONSTANTS_H
"""

CC_FILE_TAIL = """#endif"""

def main():
    parser = argparse.ArgumentParser(
        description='Write C header file with constants')
    'outfile',
    parser.add_argument('output', metavar='FILE', nargs='?',
                        type=argparse.FileType('w'), default=sys.stdout,
                        help='Where to send output')
    args = parser.parse_args()

    with args.output as f:
        print(CC_FILE_HEADER, file=f)
        for name, value in vars(Constants).items():
            if not name.startswith('_'):
                print(f"#define {name} {value}", file=f)
        print(CC_FILE_TAIL, file=f)

if __name__ == "__main__":
    main()

redpajama_set_name: RedPajamaGithub


text:
package main

import (
	"bufio"
	"errors"
	"fmt"
	"net"
)

func main() {
	listen()
}

func listen() {
	listener, err := net.Listen("tcp", ":1026")
	if err != nil {
		fmt.Println("Failed to open port on 1026")
		return
	}
	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("Error accepting connection")
			continue
		}

		go handle(conn)
	}
}

func handle(conn net.Conn) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("Fatal error: %s", err)
		}
		conn.Close()
	}()
	reader := bufio.NewReader(conn)

	data, err := reader.ReadBytes('\n')
	if err != nil {
		fmt.Println("Failed to read from socket.")
	}

	response(data, conn)
}

func response(data []byte, conn net.Conn) {
	conn.Write(data)
	panic(errors.New("Pretend I'm a real error"))
}


text:
BASEDIR=`dirname $0`

mkdir -p "$1/usr/lib/qrlogin/bin"
mkdir -p "$1/usr/lib/qrlogin/www"
mkdir -p "$1/usr/lib/qrlogin/log"
mkdir -p "$1/usr/lib/qrlogin/conf"

cp -vr "$BASEDIR/bin" "$1/usr/lib/qrlogin"
cp -vr "$BASEDIR/conf" "$1/usr/lib/qrlogin"
cp -vr "$BASEDIR/www" "$1/usr/lib/qrlogin"

mkdir -p "$1/etc/init.d"

INITSCRIPT="$1/etc/init.d/qrlogin"

echo "#!/bin/sh" > $INITSCRIPT
echo "" >> $INITSCRIPT
echo "/usr/lib/qrlogin/bin/qrlogind /run/qrlogin.pid \$1" >> $INITSCRIPT

chmod +x $INITSCRIPT

mkdir -p "$1/etc/logrotate.d"

LOGROTATE="$1/etc/logrotate.d/qrlogin"

echo "/usr/lib/qrlogin/log/logfile {" > $LOGROTATE
echo "	daily" >> $LOGROTATE
echo "	rotate 7" >> $LOGROTATE
echo "	maxage 7" >> $LOGROTATE
echo "	dateext" >> $LOGROTATE
echo "	compress" >> $LOGROTATE
echo "	delaycompress" >> $LOGROTATE
echo "	notifempty" >> $LOGROTATE
echo "	missingok" >> $LOGROTATE
echo "	nocreate" >> $LOGROTATE
echo "	postrotate" >> $LOGROTATE
echo "		service qrlogin logrotate" >> $LOGROTATE
echo "	endscript" >> $LOGROTATE
echo "}" >> $LOGROTATE

update-rc.d qrlogin defaults

USERGROUP=`grep -E "^setusergroup=.*$" "$1/usr/lib/qrlogin/conf/qrlogind.conf" | cut -d= -f 2`

if [ "$USERGROUP" != "" ]; then

    USERNAME=`echo $USERGROUP | cut -d: -f 1`
    GROUPNAME=`echo $USERGROUP | cut -d: -f 2`

    groupadd $GROUPNAME
    useradd -NM $USERNAME

    chown $USERGROUP "$1/usr/lib/qrlogin/log"
fi

service qrlogin start


text:
class AddIsLeafToStandardStatements < ActiveRecord::Migration[5.1]
  def change
    add_column :standard_statements, :is_leaf, :boolean
  end
end


text:
<?php
namespace Concrete\Core\Console\Command;

use Concrete\Core\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Concrete\Core\Service\ServiceInterface;
use Concrete\Core\Service\Rule\RuleInterface;
use Concrete\Core\Service\Rule\ConfigurableRuleInterface;
use Core;
use Exception;

final class ServiceCommand extends Command
{
    protected function configure()
    {
        $errExitCode = static::RETURN_CODE_ON_FAILURE;
        $serviceHandles = [];
        $help = '';
        $manager = Core::make('Concrete\Core\Service\Manager\ServiceManager');
        /* @var \Concrete\Core\Service\Manager\ServiceManager $manager */
        foreach ($manager->getAllServices() as $serviceHandle => $service) {
            $serviceHandles[] = $serviceHandle;
            foreach ($service->getGenerator()->getRules() as $ruleHandle => $rule) {
                if ($rule instanceof ConfigurableRuleInterface) {
                    /* @var ConfigurableRuleInterface $rule */
                    foreach ($rule->getOptions() as $optionHandle => $option) {
                        $help .= "Rule option for service $serviceHandle, rule $ruleHandle:\n";
                        $help .= "  - $optionHandle: " . $option->getDescription();
                        if ($option->isRequired()) {
                            $help .= ' [required]';
                        } else {
                            $help .= ' [optional]';
                        }
                        $help .= "\n";
                    }
                }
            }
        }
        $help .= <<<EOT

Return codes for the check operation:
  0 operation completed successfully
  $errExitCode errors occurred
  2 web server configuration is not aligned

Return codes for the update operation:
  0 operation completed successfully
  $errExitCode errors occurred

More info at http://documentation.concrete5.org/developers/appendix/cli-commands#c5-service
EOT
        ;
        $this
            ->setName('c5:service')
            ->setDescription('Check or update the web server configuration')
            ->addEnvOption()
            ->addOption('service-version', 'r', InputOption::VALUE_REQUIRED, 'The specific version of the web server software', '')
            ->addArgument('service', InputArgument::REQUIRED, 'The web server to use (' . implode('|', $serviceHandles) . ')')
            ->addArgument('operation', InputArgument::REQUIRED, 'The operation to perform (check|update)')
            ->addArgument('rule-options', InputArgument::IS_ARRAY, 'List of key-value pairs to pass to the rules (example: foo=bar baz=foo)')
            ->setHelp(trim($help))
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $rc = 0;
        $manager = Core::make('Concrete\Core\Service\Manager\ServiceManager');
        /* @var \Concrete\Core\Service\Manager\ServiceManager $manager */
        $service = $manager->getService($input->getArgument('service'), $input->getOption('service-version'));
        if ($service === null) {
            $msg = 'Unknown web server handle: ' . $input->getArgument('service');
            $msg .= PHP_EOL;
            $msg .= 'Valid handles: ' . implode(', ', $manager->getExtensions());
            throw new Exception($msg);
        }
        $operation = $input->getArgument('operation');
        $ruleOptions = $this->parseRuleOptions($input);
        switch ($operation) {
            case 'check':
                if ($this->checkConfiguration($service, $ruleOptions, $output) === false) {
                    $rc = 2;
                }
                break;
            case 'update':
                $this->updateConfiguration($service, $ruleOptions, $output);
                break;
            default:
                throw new Exception('Invalid value of the operation argument (valid values: check or update');
        }

        return $rc;
    }

    public function checkConfiguration(ServiceInterface $service, array $ruleOptions, OutputInterface $output)
    {
        $storage = $service->getStorage();
        if (!$storage->canRead()) {
            throw new Exception('Unable to read current server configuration for ' . $service->getFullName());
        }
        $configuration = $storage->read();
        $generator = $service->getGenerator();
        $configurator = $service->getConfigurator();
        $allOk = true;
        foreach ($generator->getRules() as $ruleHandle => $rule) {
            $this->configureRule($rule, $ruleOptions);
            $shouldHave = $rule->isEnabled();
            if ($shouldHave !== null) {
                if ($shouldHave) {
                    $output->write("Checking presence of rule $ruleHandle... ");
                    if ($configurator->hasRule($configuration, $rule)) {
                        $output->writeln('<info>found (ok).</info>');
                    } else {
                        $output->writeln('<error>NOT FOUND!</error>');
                    }
                } else {
                    $output->write("Checking absence of rule $ruleHandle... ");
                    if ($configurator->hasRule($configuration, $rule)) {
                        $output->writeln('<error>FOUND!</error>');
                    } else {
                        $output->writeln('<info>not found (ok).</info>');
                    }
                }
            }
        }

        return $allOk;
    }

    public function updateConfiguration(ServiceInterface $service, array $ruleOptions, OutputInterface $output)
    {
        // Initialize some variable
        $storage = $service->getStorage();
        if (!$storage->canRead()) {
            throw new Exception('Unable to read the current server configuration for ' . $service->getFullName());
        }
        $configuration = $storage->read();
        $generator = $service->getGenerator();
        $configurator = $service->getConfigurator();
        $configurationUpdated = false;

        // Let's check every defined rule
        foreach ($generator->getRules() as $ruleHandle => $rule) {
            $this->configureRule($rule, $ruleOptions);

            // Let's see if this rule should be present or not in the configuration
            $shouldHave = $rule->isEnabled();

            if ($shouldHave === true) {
                // This rule should be present in the configuration
                $output->write("Checking presence of rule $ruleHandle... ");
                if ($configurator->hasRule($configuration, $rule)) {
                    // The rule is already in the configuration
                    $output->writeln("<info>already present.</info>");
                } else {
                    // The rule is not in the configuration: let's add it
                    $output->write("not found. Adding it... ");
                    $configuration = $configurator->addRule($configuration, $rule);
                    $output->writeln("<info>done.</info>");
                    $configurationUpdated = true;
                }
            } elseif ($shouldHave === false) {
                // This rule should not be present in the configuration
                $output->write("Checking absence of rule $ruleHandle... ");
                if ($configurator->hasRule($configuration, $rule)) {
                    // The rule is in the configuration: let's remove it
                    $output->write("found. Removing it... ");
                    $configuration = $configurator->removeRule($configuration, $rule);
                    $output->writeln("<info>done.</info>");
                    $configurationUpdated = true;
                } else {
                    // The rule is not in the configuration
                    $output->writeln("<info>already absent.</info>");
                }
            }
        }

        if ($configurationUpdated) {
            // Some rule has been added or removed from the configuration: let's save it
            $output->write("Persisting new configuration... ");
            if (!$storage->canWrite()) {
                throw new Exception('Unable to write the current server configuration for ' . $service->getFullName());
            }
            $storage->write($configuration);
            $output->writeln("<info>done.</info>");
        }
    }

    /**
     * Parse the rule-options input argument.
     *
     * @param InputInterface $input
     *
     * @throws Exception
     *
     * @return array
     */
    protected function parseRuleOptions(InputInterface $input)
    {
        $ruleOptions = [];
        foreach ($input->getArgument('rule-options') as $keyValuePair) {
            list($key, $value) = explode('=', $keyValuePair, 2);
            $key = trim($key);
            if (substr($key, -2) === '[]') {
                $isArray = true;
                $key = rtrim(substr($key, 0, -2));
            } else {
                $isArray = false;
            }
            if ($key === '' || !isset($value)) {
                throw new Exception(sprintf("Unable to parse the rule option '%s': it must be in the form of key=value", $keyValuePair));
            }
            if (isset($ruleOptions[$key])) {
                if (!($isArray && is_array($ruleOptions[$key]))) {
                    throw new Exception(sprintf("Duplicated rule option '%s'", $key));
                }
                $ruleOptions[$key][] = $value;
            } else {
                $ruleOptions[$key] = $isArray ? ((array) $value) : $value;
            }
        }

        return $ruleOptions;
    }

    protected function configureRule(RuleInterface $rule, array $options)
    {
        if ($rule instanceof ConfigurableRuleInterface) {
            foreach ($rule->getOptions() as $optionHandle => $optionValue) {
                if (isset($options[$optionHandle])) {
                    $optionValue->setValue($options[$optionHandle]);
                }
            }
        }
    }
}


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.analytics.synapse.artifacts.models;

import com.azure.core.annotation.Fluent;
import com.fasterxml.jackson.annotation.JsonProperty;

/** Parameters of a script block. */
@Fluent
public final class ScriptActivityParameter {
    /*
     * The name of the parameter. Type: string (or Expression with resultType string).
     */
    @JsonProperty(value = "name")
    private Object name;

    /*
     * The type of the parameter.
     */
    @JsonProperty(value = "type")
    private ScriptActivityParameterType type;

    /*
     * The value of the parameter.
     */
    @JsonProperty(value = "value")
    private Object value;

    /*
     * The direction of the parameter.
     */
    @JsonProperty(value = "direction")
    private ScriptActivityParameterDirection direction;

    /*
     * The size of the output direction parameter.
     */
    @JsonProperty(value = "size")
    private Integer size;

    /**
     * Get the name property: The name of the parameter. Type: string (or Expression with resultType string).
     *
     * @return the name value.
     */
    public Object getName() {
        return this.name;
    }

    /**
     * Set the name property: The name of the parameter. Type: string (or Expression with resultType string).
     *
     * @param name the name value to set.
     * @return the ScriptActivityParameter object itself.
     */
    public ScriptActivityParameter setName(Object name) {
        this.name = name;
        return this;
    }

    /**
     * Get the type property: The type of the parameter.
     *
     * @return the type value.
     */
    public ScriptActivityParameterType getType() {
        return this.type;
    }

    /**
     * Set the type property: The type of the parameter.
     *
     * @param type the type value to set.
     * @return the ScriptActivityParameter object itself.
     */
    public ScriptActivityParameter setType(ScriptActivityParameterType type) {
        this.type = type;
        return this;
    }

    /**
     * Get the value property: The value of the parameter.
     *
     * @return the value value.
     */
    public Object getValue() {
        return this.value;
    }

    /**
     * Set the value property: The value of the parameter.
     *
     * @param value the value value to set.
     * @return the ScriptActivityParameter object itself.
     */
    public ScriptActivityParameter setValue(Object value) {
        this.value = value;
        return this;
    }

    /**
     * Get the direction property: The direction of the parameter.
     *
     * @return the direction value.
     */
    public ScriptActivityParameterDirection getDirection() {
        return this.direction;
    }

    /**
     * Set the direction property: The direction of the parameter.
     *
     * @param direction the direction value to set.
     * @return the ScriptActivityParameter object itself.
     */
    public ScriptActivityParameter setDirection(ScriptActivityParameterDirection direction) {
        this.direction = direction;
        return this;
    }

    /**
     * Get the size property: The size of the output direction parameter.
     *
     * @return the size value.
     */
    public Integer getSize() {
        return this.size;
    }

    /**
     * Set the size property: The size of the output direction parameter.
     *
     * @param size the size value to set.
     * @return the ScriptActivityParameter object itself.
     */
    public ScriptActivityParameter setSize(Integer size) {
        this.size = size;
        return this;
    }
}


text:
import sys, os, glob, string,math, time
from math import log
from optparse import OptionParser
from subprocess import call
POOLSIZE= 2;
INCLUDE_STRAND_AMBIG = 0;
CORES =1;
WINDOW =0;
PARSIMONY =1;
HWE_CHECK = 0;

##################################################################################################################################

def output_GLL_inputfile(afmatrixfile,outfile):
	File1 = open(outfile,'w');
	File = open(afmatrixfile);
	for line in File:
		if line[0] != '#':
			snp = line.strip().split();
			print >>File1, 'SNP',snp[0].strip('chr'),snp[1],snp[3],snp[4],snp[3] + '/' + snp[4],100;
	File.close();
	File1.close();

def make_ancestry_inputfile_simple(afmatrixfile,GLLfile,outfile):
	File1 = open(outfile,'w');
	File = open(GLLfile);  GLLs = {};
	for line in File: snp= line.strip().split(); GLLs[(snp[POOLSIZE+1].strip('chr'),int(snp[POOLSIZE+2]))] = ' '.join(snp[0:POOLSIZE+1]);
	File.close();

	File = open(afmatrixfile);
	for line in File:
		snp = line.strip().split();
		if line[0] == '#':
			print >>File1, '#GLL',
			for i in xrange(5,len(snp)): print >>File1, snp[i],
			print >>File1, '\n',
		else:
			try:
				ll =  GLLs[(snp[0].strip('chr'),int(snp[1]))];
				print >>File1, ll,
				for i in xrange(5,len(snp)): print >>File1, snp[i],
				print >>File1, '\n',
			except KeyError: pass;
	File.close();
	File1.close();

## function that processed bam file for ancestry calculation
def ancestry_pipeline_bam(matrixfile,bamfile,outfile,executable_dir_path):

	## the python I/O can be removed in C

	print >>sys.stderr, "making input file for getting genotype likelihoods";
	output_GLL_inputfile(matrixfile,outfile+'.forGLL');
	#python ../runancestry.py hapmap3.allchroms.shared.matrix.hg19  > hapmap3.allchroms.shared.matrix.hg19.forhapcut

	print >>sys.stderr, "calculating genotype likelihoods for bam file",bamfile,"poolsize is: ",POOLSIZE
	call([ executable_dir_path + "/calculateGLL -p " + `POOLSIZE` + " --bam " + bamfile + " --variants " + outfile +".forGLL" + " --mmq 30 > " + outfile + ".GLL" ],shell=True)
	# ../../hapCUT/calculateGLL --bam DM00231.bwamem.MD.bam --variants hapmap3.allchroms.shared.matrix.hg19.forhapcut --mmq 30 > DM00231.bwamem.MD.GLL

	print >>sys.stderr, "making input file for ancestry calculations";
	make_ancestry_inputfile_simple(matrixfile,outfile + ".GLL",outfile + ".ancestry.input");
	#python runancestry.py ancestry-data/hapmap3.allchroms.shared.matrix.hg19 ancestry-data/DM00231.bwamem.MD.GLL > ancestry-data/DM00231.bwamem.MD.input
	print >>sys.stderr, "ancestry admixture calculations for",bamfile,"poolsize is ",POOLSIZE;
	call(["time " + executable_dir_path + "/ANCESTRY -p " + `POOLSIZE` + " --pr 1 -i " + outfile + ".ancestry.input > " + outfile + '.ancestry.out'],shell=True);
	#call(["rm -f " + bamfile + ".GLL"],shell=True);
	#call(["rm -f " + bamfile + ".forGLL"],shell=True);
	#call(["rm -f " + bamfile + ".ancestry.input"],shell=True);
	#./ANCESTRY ancestry-data/DM00231.bwamem.MD.input

##################################################################################################################################

## add support for plink ped files for multiple samples or processing a file with list of bamfile names
## function that reads in PLINK ped and map files and determines ancestry for each individual in ped file
def make_ancestry_inputfile_plink(pedfile,mapfile,afmatrixfile,outfile,executable_dir_path,modulo_CORE):

	RC = {}; RC['A'] = 'T'; RC['T'] = 'A'; RC['C'] = 'G'; RC['G'] = 'C';
	gll_low = -4; gll_high = 0; gll_equal = -0.477121;

	## read the allele frequency matrix file into a hashtable once for all samples
	print >>sys.stderr, "reading allele frequency file",afmatrixfile;
	File = open(afmatrixfile);lines =0; AFtable = {}; headerline = [];
	for line in File:
		snp = line.strip().split();
		if line[0] == '#' or lines ==0: headerline = snp;
		elif INCLUDE_STRAND_AMBIG ==1: AFtable[snp[2]] = snp;
		elif snp[3] == 'A' and snp[4] == 'T': continue;
		elif snp[3] == 'T' and snp[4] == 'A': continue;
		elif snp[3] == 'C' and snp[4] == 'G': continue;
		elif snp[3] == 'G' and snp[4] == 'C': continue;
		else: AFtable[snp[2]] = snp;
		lines +=1;
	File.close()

	## read the map file once so that we have SNP rsid for each SNP
	print >>sys.stderr, "reading mapfile",mapfile;
	try: File = open(mapfile,'r');
	except IOError: print >>sys.stderr, "map file",mapfile,"not found"; return -1;
	SNPlist = [];
	for line in File:
		snp = line.strip().split();
		if snp[0][0] == '#': continue; ## BUG if first line has '# chrom', make sure the lines match up to ped file... 10/04/2014
		SNPlist.append([snp[1],snp[0],snp[2]]);
	File.close();
	#######

	#### read the ped file line by line and calculate ancestry for each individual
	File = open(pedfile,'r'); samples = 0;
	for line in File:
		if CORES > 1 and samples%CORES != modulo_CORE: samples +=1; continue;
		GLLs = {};
		genotypes = line.strip().split();
		sampleid = genotypes[1]; outfilename = outfile+'.'+sampleid + '.input';
		File1 = open(outfilename,'w');

		# Family ID      Individual ID   FatherID MotherID Sex  phenotype #SIM_1 SIM_1 0 0 1 -9 C C C C A

		print >>File1, '#GLL',
		for i in xrange(5,len(headerline)): print >>File1, headerline[i],
		print >>File1, '\n',

		overlapping_markers =0; missing_markers = 0;
		for i in xrange(6,len(genotypes),2):
			s = i-6; s /=2;
			try:
				snp = AFtable[SNPlist[s][0]]; flag = 0;
				if genotypes[i] == snp[3] and genotypes[i+1] == snp[3]: print >>File1, gll_high,gll_low,gll_low,
				elif genotypes[i] == snp[4] and genotypes[i+1] == snp[4]: print >>File1, gll_low,gll_low,gll_high,
				elif genotypes[i] == snp[3] and genotypes[i+1] == snp[4]: print >>File1, gll_low,gll_high,gll_low,
				elif genotypes[i+1] == snp[3] and genotypes[i] == snp[4]: print >>File1, gll_low,gll_high,gll_low,
				elif genotypes[i+1] == RC[snp[3]] and genotypes[i] == RC[snp[4]]: print >>File1, gll_low,gll_high,gll_low,
				elif genotypes[i] == RC[snp[3]] and genotypes[i+1] == RC[snp[4]]: print >>File1, gll_low,gll_high,gll_low,
				elif genotypes[i] == RC[snp[4]] and genotypes[i+1] == RC[snp[4]]: print >>File1, gll_low,gll_low,gll_high,
				elif genotypes[i] == RC[snp[3]] and genotypes[i+1] == RC[snp[3]]: print >>File1, gll_high,gll_low,gll_low,
				else:
					flag = 1; missing_markers +=1;
					#print i,'missing',snp,SNPlist[s],genotypes[i],genotypes[i+1]
				if flag ==0:
					for j in xrange(5,len(snp)): print >>File1, snp[j],
					print >>File1, '\n',
					overlapping_markers +=1;
			except KeyError:
				#print >>sys.stderr, 'variant not found',SNPlist[s][0];
				pass;

		File1.close();
		print >>sys.stderr, "\n\nancestry admixture calculations for individual:",samples+1,sampleid,'using',overlapping_markers,'markers';
		#print >>sys.stderr, "missing",missing_markers,len(genotypes)/2;

		if WINDOW ==0: call(["" + executable_dir_path + "/ANCESTRY -p 2 --pr " + `PARSIMONY` + " --HWE " + `HWE_CHECK` + " -i " + outfilename +  " > " + outfilename + ".ancestry"],shell=True);
		else:
			print >>sys.stderr, "calling BFGS method in windows";
			call(["time " + executable_dir_path + "/ANCESTRY.1 -p 2 --pr " + `PARSIMONY` + " -i " + outfilename  + " > " + outfilename + ".ancestry"],shell=True);
		#call(["rm -f " + outfilename],shell=True);
		#call(["rm -f " + outfilename +  " " + outfilename + ".ancestry"],shell=True);
		samples +=1;
		#sys.exit();
		"""
		"""
	File.close();

####################################################################################################################################################

## genotype file is rsid AG pairs
def make_ancestry_inputfile_rsid(afmatrixfile,GLLfile,outfile):

	RC = {}; RC['A'] = 'T'; RC['T'] = 'A'; RC['C'] = 'G'; RC['G'] = 'C';
	#gll_low = -3.602; gll_high = -0.000021715; gll_equal = -0.477121255; ## assuming error rate = 1/20000 or 50 errors per million genotypes
	gll_low = -4; gll_high = -0.000086868; gll_equal = -0.477121;
	#gll_low = -9; gll_high = 0.00000; gll_equal = -0.477121;
	column =1;

	## read genotype file and store genotypes in hashtable
	File1 = open(outfile,'w');
	GLLs = {};
	File = open(GLLfile);
	for line in File:
		snp= line.strip().split();
		if snp[column] == 'NN' or snp[column] == 'N/N' or snp[column] == 'NoCall' or snp[column] == '--': continue;
		if snp[column][1] == '/': genotype = snp[column][0] + snp[column][2];
		else: genotype = snp[column];
		GLLs[snp[0]] = genotype;

	File.close();

	lines = 0; valid_snps = 0;
	File = open(afmatrixfile);
	for line in File:
		snp = line.strip().split();
		if line[0] == '#' or lines ==0:
			print >>File1, '#GLL',
			for i in xrange(5,len(snp)): print >>File1, snp[i],
			print >>File1, '\n',
		## ignore A/T and C/G snps that are strand ambiguous
		elif INCLUDE_STRAND_AMBIG ==0 and snp[3] == 'A' and snp[4] == 'T': continue;
		elif INCLUDE_STRAND_AMBIG ==0 and snp[3] == 'T' and snp[4] == 'A': continue;
		elif INCLUDE_STRAND_AMBIG ==0 and snp[3] == 'C' and snp[4] == 'G': continue;
		elif INCLUDE_STRAND_AMBIG ==0 and snp[3] == 'G' and snp[4] == 'C': continue;
		elif snp[3] in RC and snp[4] in RC: ## the two alleles are [ACTG], ignore indel D/I alleles
			try:
				GENOTYPE = GLLs[snp[2]];  flag =0;
				if GENOTYPE[0] == snp[3] and GENOTYPE[1] == snp[3]: print >>File1, gll_high,gll_low,gll_low,
				elif GENOTYPE[0] == snp[4] and GENOTYPE[1] == snp[4]: print >>File1, gll_low,gll_low,gll_high,
				elif GENOTYPE[0] == snp[3] and GENOTYPE[1] == snp[4]: print >>File1, gll_low,gll_high,gll_low,
				elif GENOTYPE[1] == snp[3] and GENOTYPE[0] == snp[4]: print >>File1, gll_low,gll_high,gll_low,
				elif GENOTYPE[1] == RC[snp[3]] and GENOTYPE[0] == RC[snp[4]]: print >>File1, gll_low,gll_high,gll_low,
				elif GENOTYPE[0] == RC[snp[3]] and GENOTYPE[1] == RC[snp[4]]: print >>File1, gll_low,gll_high,gll_low,
				elif GENOTYPE[0] == RC[snp[4]] and GENOTYPE[1] == RC[snp[4]]: print >>File1, gll_low,gll_low,gll_high,
				elif GENOTYPE[0] == RC[snp[3]] and GENOTYPE[1] == RC[snp[3]]: print >>File1, gll_high,gll_low,gll_low,
				else:
					#print >>File1, gll_equal,gll_equal,gll_equal,
					#print >>sys.stderr, GENOTYPE,snp;
					flag = 1;
				if flag ==0:
					for i in xrange(5,len(snp)): print >>File1, snp[i],
					print >>File1, '\n',
					valid_snps +=1;
					#print >>sys.stderr, snp[2];
			except KeyError: pass;
		lines +=1;
	print >>sys.stderr, "ancestry genotype file has",valid_snps,"markers";
	File.close();
	File1.close();

def ancestry_pipeline_genotypes(matrixfile,genotype_file,outfile,executable_dir_path):
	print >>sys.stderr, "making input file for ancestry calculations";
	make_ancestry_inputfile_rsid(matrixfile,genotype_file,genotype_file + ".ancestry.input");
	print >>sys.stderr, "ancestry admixture calculations",genotype_file
	if WINDOW ==0: call(["time " + executable_dir_path + "/ANCESTRY --LRT 7.68 -p 2 --pr 1 -i " + genotype_file + ".ancestry.input > " + outfile],shell=True);
	else:
		print >>sys.stderr, "calling BFGS method in windows";
		call(["time " + executable_dir_path + "/ANCESTRY.1 -p 2 --pr 1 -i " + genotype_file + ".ancestry.input > " + outfile],shell=True);
	#call(["time " + executable_dir_path + "/ANCESTRY -p 2 --pr 1 -i " + genotype_file + ".ancestry.input > " + outfile],shell=True);
	#call(["time ./ANCESTRY --ea 1 -p 2 --pr 1 -i " + bamfile + ".ancestry.input > " + outfile],shell=True);
	#call(["rm -f " + bamfile + ".ancestry.input"],shell=True);

###########################################################################################################################

parser = OptionParser();
#parser.add_option("--type",dest="type",type="string",help="type of input file: bam/geno/genotype/VCF/ped",default="");
parser.add_option("-b","--bam",dest="BAMfile",type="string",help="input bam file name",default="");
parser.add_option("--geno",dest="genofile",type="string",help="input file name for simple genotype file: rsid AG on each line",default="");
parser.add_option("--vcf","--VCF",dest="vcffile",type="string",help="input file name for VCF file",default="");
parser.add_option("--plink",dest="pedfile",type="string",help="input file name for plink file in ped/map format (provide prefix of ped file name without the .ped)",default="");
parser.add_option("-f","--freq",dest="AFfile",type="string",help="allele frequency file",default="");
parser.add_option("-o","--out",dest="outfile",type="string",help="prefix of output file names",default="iADMIX.out");
parser.add_option("-p","--poolsize",dest="POOLSIZE",type="int",help="pool size for non-diploid samples, default = 2",default=2);
parser.add_option("--pr","--parsimony",dest="pr",type="int",help="parsimonious ancestry estimation 0/1, default = 1",default=1);
parser.add_option("--hwe","--HWE",dest="HWE",type="int",help="HWE deviation estimation 0/1, default = 0",default=0);
parser.add_option("--strand",dest="include_strand_ambiguous",type="int",help="<0/1> include SNPs that are strand ambiguous (A/T, C/G): default = 0 (not included)",default=0);
parser.add_option("--path",dest="path",type="string",help="path to directory with executables ANCESTRY and calculateGLL",default=".");
parser.add_option("-c","--cores",dest="CORES",type="int",help="number of cores for processing in parallel",default=1);
parser.add_option("-m","--modcore",dest="MOD_CORE",type="int",help="0/1/2/3..../CORES-1",default=0);
parser.add_option("-w","--windows",dest="WINDOW",type="int",help="0/1",default=0);
(options,args) = parser.parse_args(); POOLSIZE = options.POOLSIZE;  CORES = options.CORES; HWE_CHECK = options.HWE;
WINDOW = options.WINDOW;
INCLUDE_STRAND_AMBIG = options.include_strand_ambiguous
PARSIMONY = options.pr;

#file = open(sys.argv[1],'rb'); while True: byte = file.read(1); print ord(byte); sys.exit();

if (options.BAMfile == "" and options.genofile == "" and options.pedfile == "") or options.AFfile == "":

	print >>sys.stderr,"\n####program iAdmix for estimation of ancestry using population allele frequencies###\n";
	print >>sys.stderr, "python runancestry.py --bam sample.bam --geno sample.genotypes --freq allelefrequency_file --out outputfile --poolsize 2";
	print >>sys.stderr, "\nExample: python runancestry.py --freq hapmap3.allchroms.shared.matrix --geno HGDP01254.genotypes --out HGDP12054.ancestry";
	print >>sys.stderr, "Example: python runancestry.py --freq hapmap3.allchroms.shared.matrix --bam HGDP01254.sorted.bam --out HGDP12054.ancestry";
	print >>sys.stderr, "Example: python runancestry.py --freq hapmap3.allchroms.shared.matrix --plink HGDP01254.genotypes (ped/map) --out HGDP12054.ancestry\n\n";
	parser.print_help()
	sys.exit();
elif options.pedfile != "":
	make_ancestry_inputfile_plink(options.pedfile+'.ped',options.pedfile+'.map',options.AFfile,options.outfile,options.path,options.MOD_CORE);

elif options.BAMfile != "":
	if not os.path.exists(options.path + "/ANCESTRY"): print >>sys.stderr, "ANCESTRY executable does not exist, please specify correct path with the executable using --path option\n"; sys.exit();
	if not os.path.exists(options.path + "/calculateGLL"): print >>sys.stderr, "calculateGLL executable does not exist, please specify correct path with the executable using --path option\n"; sys.exit();
	ancestry_pipeline_bam(options.AFfile,options.BAMfile,options.outfile,options.path);
elif options.genofile != "":
	if not os.path.exists(options.path + "/ANCESTRY"): print >>sys.stderr, "ANCESTRY executable does not exist, please specify correct path with the executable using --path option\n"; sys.exit();
	ancestry_pipeline_genotypes(options.AFfile,options.genofile,options.outfile,options.path);

########################################################################################################################################


text:
using IntergrationTest.Constants;
using Propeller.Mvc.Core.Mapping;
using Sitecore.Data;

namespace IntergrationTest.Models.Maps
{
    public class MovieModelMap : ConfigurationMap<MovieModel>
    {
        public MovieModelMap()
        {
            SetProperty(p => p.Title).Map(new ID(ConstantsMovieModel.Fields.TitleField)).Include();
            SetProperty(p => p.ReleaseDate).Map(new ID(ConstantsMovieModel.Fields.ReleaseDateField)).Include();
        }
    }
}


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
    <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
    <meta name=viewport content="width=device-width, initial-scale=1">
    <title>What changes should Snapchat make to its Discover feature that would significantly increase the product's relevance as a news source? – Borker dot co</title>
    <meta name="description" content="Still important, though">
    <meta name="keywords" content="design">
    <link rel="canonical" href="http://borker.co/snapchat-discover/">

    <meta name="twitter:title" content="What changes should Snapchat make to its Discover feature that would significantly increase the product's relevance as a news source?">
    <meta name="twitter:description" content="Still important, though">
    <meta name="twitter:site" content="@borker">
    <meta name="twitter:creator" content="@borker">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:image" content="http://borker.co/assets/img/logo-new.png">

    <meta property="og:locale" content="en_US">
    <meta property="og:type" content="article">
    <meta property="og:title" content="What changes should Snapchat make to its Discover feature that would significantly increase the product's relevance as a news source?">
    <meta property="og:description" content="Still important, though">
    <meta property="og:url" content="http://borker.co/snapchat-discover/">
    <meta property="og:site_name" content="Borker dot co">
    <meta property="og:image" content="http://borker.co/assets/img/logo-new.png">

    <meta name="HandheldFriendly" content="True">
    <meta name="MobileOptimized" content="320">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="apple-touch-icon-precomposed" sizes="57x57" href="http://borker.co/assets/img/favicon/apple-touch-icon-57x57.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://borker.co/assets/img/favicon/apple-touch-icon-114x114.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://borker.co/assets/img/favicon/apple-touch-icon-72x72.png">
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="http://borker.co/assets/img/favicon/apple-touch-icon-144x144.png">
    <link rel="icon" type="image/png" href="http://borker.co/assets/img/favicon/favicon.png">
    <link rel="shortcut icon" href="http://borker.co/assets/img/favicon/favicon.ico">

    <link rel="alternate" type="application/rss+xml" title="Borker dot co" href="http://borker.co/feed.xml" />

    <link rel="stylesheet" type="text/css" href="http://borker.co/assets/css/main.css">

Home

Projects

About

Writing

Thoughts

Design

What changes should Snapchat make to its Discover feature that would significantly increase the product's relevance as a news source?

23 Aug 2016

Answer originally written on Quora, where it won a knowledge prize.

There's some evidence and a strong hypothesis that Snapchat will just remove the Discover feature. However, some ideas for keeping the 'Discover' feature relevant:

Use it for vertically focused e-commerce (specifically clothes, food, movies)

Make it hyper local (eg what pokemon are around, funniest faces at the Yankees game)

Turn it into a snap version of Instagram explore

There's a lot at stake, since some major publishers (BuzzFeed, Cosmo) generate a significant portion of their traffic now through Snapchat. Cosmo generates as many views through Snapchat as it does on its main site. BuzzFeed gets 20% of its traffic. [1] Snapchat now has more users than Twitter by the way [2] .

WHERE IS DISCOVER NOW?

Let's first look at the UI to see what clues we can draw from it. You can often understand where a feature is going if you look at where it is, and the changes the company has put into it.

Here's the current Discover screen (8/30/16):

A discovery!

Here's the current Stories screen (8/30/16):

A likely story!

Notice anything?

Discover stories have already migrated to the stories stream. The stories there focus on 2 use cases:

1) Additional content: you already watched all of your friends' snaps and you want more. Here's some click-baity stuff for you to look at.

2) "Live": live is 'in' right now. YouNow follows Facebook Live follows Periscope, etc. People love looking into other people's more interesting experiences from the comfort of their own home.

These are the same types of content you find on Discover page.

QUICK HISTORY: WHAT HAPPENED TO DISCOVER?

Detective work

Discover used to be the bubbles from publishers, putting their name out their first, but the new shift focuses even more on the individual piece of news.

Snapchat's new update of Discover offers a subscribe button at the bottom of each piece, I suspect pushes the content to the top of your feed and also provides a metric that Snapchat can use to show brands how effective maintaining a Snapchat presence is.

DO YOU EVEN NEED DISCOVER?

Discover right now is a source of revenue for Snapchat: brands pay Snapchat a percentage of their ad revenues to remain on the page [3]. They can (or could at one point) also pay to take-over a publisher's Discover channel, to the order of $50,000. [4] Not cheap.

But not everyone has seen value in Discover. Very high quality brands, like the NFL and the Onion, no longer seem to post on Discover, and some brands (eg Yahoo) have been kicked off the platform for not posting content.

Given how Snapchat is growing, it's no surprise that Snapchat's much bigger opportunity is providing ads in between Snaps, something that will generate $1B in revenue for them or more if they have it their way [5] . I suspect that makes the revenue generated by Discover seem like chump change.

It does matter to some brands though,

FUTURE OF DISCOVER:

I've written before that Snapchat has a great forum for short form news, because it captures attention very well, especially from young people (see: Is Snapchat really a good place to read and discover news?)

Discover offers, at its core, a reason to stay on the platform after you've consumed all of your friends' snaps. That's important for Snapchat, whose sole business model is sucking up your attention and turning it into money.

I believe Discover's 'platform' based news delivery will eventually be phased out in favor of a 'feed' based delivery, similar to the way the stories and live tiles are being used now. Why? People ultimately don't care about the publisher, just the content.

I believe Snapchat will ultimately phase out the Discover tab as an idea, but how could it make it more relevant to a news source, or as a product:

Using Discover for vertically focused e-commerce:

'But Ryan, commerce isn't news.' Sure it is. If Kylie's hairstyle is news, the launch of a new product or a sale can be news. We don't even need to argue on this one.

Snapchat recently bought Vurb, and I suspect a large reason they did so was to build out Snapchat's integrations across other apps.

The idea here would be that certain kinds of e-commerce lend themselves incredibly well to Snapchat's platform.

Imagine fashion bloggers showing off their looks on Snapchat with a purchase link. You can only view it once and buy it, afterward it's gone.

Imagine a happy hour filter that could steer you to a nearby restaurant with cheap drink prices if you post to your story

Imagine previews of movies on the platform that unlock a special filter you can use in your snaps (eg watch the trailer and unlock the Incredible Hulk filter)

Totally doable, monetizable, etc.

Making Discover hyper-local:

They could change the core part of Discover to what's happening around you right now:

"Super cute cat stuck in tree"
Watch Live: "Skateboarding in your local park"
Meet now: "Rare Pokemon at the convenience store"
This will be hard due to the amount of content required, but there's certainly a possibility of making it happen, especially if they can find a way to reward users creating the content.

Instagram 'Explore' for Snapchat

The explore tab on Instagram has a similar reason for existing as the Discover tab: keep you engaged after you've gone through your feed.

Snapchat could basically pull the same trick off: start ordering Snaps that you'd like from the past 7 days that you can only see through the discover tab.

Since most news on Snapchat lasts 1 day, the ability to go further into the past could actually be a hook for people in the product.

CONCLUSION:

Discover was an initial test by Snapchat to see how successful publishers would be on their platform. The test has gone well.

However, Snapchat will now focus on between Snap ads, which will become their largest money maker—this opens up some more speculative uses for the Discover page and feature.

The focus and deep attention provides some exciting possibilities for the platform.

Footnotes

1 Snapchat Discover One Year Later: How 23 Media Companies Are Building Stories For Evan Spiegel

2 Three questions publishers have about Snapchat Discover

[3] Ibid.

4 Snapchat's ad rates drop as brands find problems

5 Snapchat Launches a Colossal Expansion of Its Advertising, Ushering in a New Era for the App

        Borker dot co © 2019


text:
* Proposal: [SDL-0196](0196-sdlartwork-static-icons.md)
* Author: [Joel Fischer](https://github.com/joeljfischer)
* Status: **Accepted**
* Impacted Platforms: [iOS / Android]

## Introduction

Make additions to `SDLArtwork` and `SDLScreenManager` to make using static icons as easy as using uploaded artworks.

## Motivation

Currently we have `SDLArtwork`, `SDLScreenManager`, and the [static icon enum](https://github.com/smartdevicelink/sdl_evolution/blob/master/proposals/0159-Static-SDL-Icon-Names-Enum.md), however, these don't currently play well together. You need to use a raw `Image` RPC to use the static icon enum. We should allow the use of static icons in `SDLSoftButtonObject`, `SDLChoiceCell`, etc.

## Proposed solution

The proposed solution is to make API additions to the `SDLArtwork` RPC and internal changes to `SDLScreenManager` subclasses to account for static icons.

### SDLArtwork Changes

```objc
// New Additions
@property (assign, nonatomic, readonly) BOOL isStaticIcon;

- (instancetype)initWithStaticIcon:(SDLStaticIconName)staticIcon;
+ (instancetype)artworkWithStaticIcon:(SDLStaticIconName)staticIcon;
```

The `name` and `data` parameters will both return the hex data to which the static icon name enum corresponds.

### SDLScreenManager Changes
Screen Manager sub-managers, including the Text and Graphic, Soft Button, Menu, and Choice Set managers will need to watch for `isStaticIcon`, skip the upload, and use the static icon in the `SDLImage` RPC that is created.

### SDLFileManager Changes
In order to prevent manual upload by the developer of an `SDLArtwork` with a static icon through the `SDLFileManager`, the `SDLFileManager` will have to return a success automatically if the `SDLArtwork` is a static icon.

### Android
Android will need to make similar changes to their (currently in-progress) managers.

## Potential downsides

`SDLArtwork` and the managers will become somewhat more complex in their handling of artwork as they will have to check for static icon usage.

## Impact on existing code

This will be a minor version change.

## Alternatives considered

1. The `SDLScreenManager` could also add APIs to receive a `SDLStaticIconName` enum in place of an `SDLArtwork`. This would better encapsulate what's going on, as `SDLArtwork` doesn't perfectly make sense to encapsulate a static icon as a subclass of `SDLFile`.

However, this alternative was discarded due to the extensive increase in API surface required to implement this alternative. Every artwork-related API in the `SDLScreenManager`, including `SDLChoice`, `SDLMenuCell`, and `SDLScreenManager` itself, would need to be doubled to account for a static icon. In addition, properties on `SDLScreenManager` like `primaryGraphic` would need to be replicated to account for the static icon. This is simply too complex.


text:
#include "util/MessageQueue.h"

void MessageQueue::enqueue(QueueItem item)
{
    std::unique_lock<std::mutex> lock(mutex_);
    queue_.push(item);
    lock.unlock();
    cond_push_.notify_one();
}

// should block until a message is waiting in the queue,
// so it should be okay to put this in a while loop or something.
const QueueItem MessageQueue::dequeue()
{
    std::unique_lock<std::mutex> lock(mutex_);

    while(queue_.empty()) {
        cond_push_.wait(lock);
    }

    auto item = queue_.front();
    queue_.pop();
    return item;
}


text:
import helper
from helper import Command

def start(args, logfile, errfile):
  helper.set_database_host(args)
  command = Command("rvm jruby-1.7.8 do bundle exec trinidad --config config/trinidad.yml", False)
  return helper.run([command], logfile, errfile, args.troot)

def stop(logfile, errfile):
  return helper.stop('trinidad', logfile, errfile)


text:
package org.apache.camel.utils.cassandra;

import com.datastax.oss.driver.api.core.ConsistencyLevel;
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
import com.datastax.oss.driver.api.querybuilder.QueryBuilder;
import com.datastax.oss.driver.api.querybuilder.delete.Delete;
import com.datastax.oss.driver.api.querybuilder.delete.DeleteSelection;
import com.datastax.oss.driver.api.querybuilder.insert.Insert;
import com.datastax.oss.driver.api.querybuilder.insert.InsertInto;
import com.datastax.oss.driver.api.querybuilder.insert.RegularInsert;
import com.datastax.oss.driver.api.querybuilder.select.Select;
import com.datastax.oss.driver.api.querybuilder.select.SelectFrom;
import com.datastax.oss.driver.api.querybuilder.truncate.Truncate;

import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.bindMarker;
import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.insertInto;
import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom;

public final class CassandraUtils {

    private CassandraUtils() {
    }

    /**
     * Test if the array is null or empty.
     */
    public static boolean isEmpty(Object[] array) {
        return array == null || array.length == 0;
    }

    /**
     * Concatenate 2 arrays.
     */
    public static Object[] concat(Object[] array1, Object[] array2) {
        if (isEmpty(array1)) {
            return array2;
        }
        if (isEmpty(array2)) {
            return array1;
        }
        Object[] array = new Object[array1.length + array2.length];
        System.arraycopy(array1, 0, array, 0, array1.length);
        System.arraycopy(array2, 0, array, array1.length, array2.length);
        return array;
    }

    private static int size(String[] array) {
        return array == null ? 0 : array.length;
    }

    private static boolean isEmpty(String[] array) {
        return size(array) == 0;
    }

    /**
     * Concatenate 2 arrays.
     */
    public static String[] concat(String[] array1, String[] array2) {
        if (isEmpty(array1)) {
            return array2;
        }
        if (isEmpty(array2)) {
            return array1;
        }
        String[] array = new String[array1.length + array2.length];
        System.arraycopy(array1, 0, array, 0, array1.length);
        System.arraycopy(array2, 0, array, array1.length, array2.length);
        return array;
    }

    /**
     * Append values to given array.
     */
    public static Object[] append(Object[] array1, Object... array2) {
        return concat(array1, array2);
    }

    /**
     * Append values to given array.
     */
    public static String[] append(String[] array1, String... array2) {
        return concat(array1, array2);
    }

    /**
     * Generate Insert CQL.
     */
    public static Insert generateInsert(String table, String[] columns, boolean ifNotExists, Integer ttl) {
        InsertInto into = insertInto(table);
        RegularInsert regularInsert = null;
        Insert insert = null;
        for (String column : columns) {
            regularInsert = (regularInsert != null ? regularInsert : into).value(column, bindMarker());
        }
        if (ifNotExists) {
            insert = regularInsert.ifNotExists();
        }
        if (ttl != null) {
            insert = (insert != null ? insert : regularInsert).usingTtl(ttl);
        }
        return insert != null ? insert : regularInsert;
    }

    /**
     * Generate select where columns = ? CQL.
     */
    public static Select generateSelect(String table, String[] selectColumns, String[] whereColumns) {
        return generateSelect(table, selectColumns, whereColumns, size(whereColumns));
    }

    /**
     * Generate select where columns = ? CQL.
     */
    public static Select generateSelect(String table, String[] selectColumns, String[] whereColumns, int whereColumnsMaxIndex) {
        SelectFrom from = selectFrom(table);
        Select select = null;
        for (String column : selectColumns) {
            select = (select != null ? select : from).column(column);
        }
        if (select == null) {
            select = from.all();
        }
        if (isWhereClause(whereColumns, whereColumnsMaxIndex)) {
            for (int i = 0; i < whereColumns.length && i < whereColumnsMaxIndex; i++) {
                select = select.whereColumn(whereColumns[i]).isEqualTo(bindMarker());
            }
        }
        return select;
    }

    /**
     * Generate delete where columns = ? CQL.
     */
    public static Delete generateDelete(String table, String[] whereColumns, boolean ifExists) {
        return generateDelete(table, whereColumns, size(whereColumns), ifExists);
    }

    /**
     * Generate delete where columns = ? CQL.
     */
    public static Delete generateDelete(String table, String[] whereColumns, int whereColumnsMaxIndex, boolean ifExists) {
        DeleteSelection deleteSelection = QueryBuilder.deleteFrom(table);
        Delete delete = null;

        if (isWhereClause(whereColumns, whereColumnsMaxIndex)) {
            for (int i = 0; i < whereColumns.length && i < whereColumnsMaxIndex; i++) {
                delete = (delete != null ? delete : deleteSelection).whereColumn(whereColumns[i]).isEqualTo(bindMarker());
            }
        } else {
            // Once there is at least one relation, the statement can be built
            //(see https://docs.datastax.com/en/developer/java-driver/4.6/manual/query_builder/delete/#relations)
            throw new IllegalArgumentException(
                    "Invalid delete statement. There has to be at least one relation. "
                                               + "To delete all records, use Truncate");
        }

        if (ifExists) {
            delete = delete.ifExists();
        }
        return delete;
    }

    private static boolean isWhereClause(String[] whereColumns, int whereColumnsMaxIndex) {
        return !isEmpty(whereColumns) && whereColumnsMaxIndex > 0;
    }

    /**
     * Generate delete where columns = ? CQL.
     */
    public static Truncate generateTruncate(String table) {
        Truncate truncate = QueryBuilder.truncate(table);
        return truncate;
    }

    /**
     * Apply consistency level if provided, else leave default.
     */
    public static <T extends SimpleStatement> T applyConsistencyLevel(T statement, ConsistencyLevel consistencyLevel) {
        if (consistencyLevel != null) {
            statement.setConsistencyLevel(consistencyLevel);
        }
        return statement;
    }
}


text:
layout: index
title: SetObjectFlagOn
---

    SetObjectFlagOff (object, string flag name)

Turns the object flag on - an object flag is simply a [boolean](../../types/boolean.html) attribute, so:

     SetObjectFlagOn(myobject, "myflag")

is equivalent to

     myobject.myflag = true

See also [SetObjectFlagOff](setobjectflagoff.html)


text:
import java.util.*;
import java.io.*;

public class A4 {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        System.out.println((n>2 && n%2 == 0)? "YES" : "NO");
    }
}


text:
            {{Username}}

                {{#Explicit}}
                NSFW
                {{/Explicit}}
                {{#Verified}}
                ✓ Verified
                {{/Verified}}

        {{Description}}

        {{Location}}

        {{FollowerCount}} followers

        following {{FollowingCount}}

        {{LoopCount}} loops


text:
def to_freud(sentence):
    return ' '.join('sex' for _ in sentence.split())


text:
import CHIP_IO.GPIO as GPIO
from datetime import timedelta
from time import sleep
import subprocess
import datetime
import serial
import random
import psutil
import sys
import os

GPIO.cleanup()
sing_channel = "XIO-P1"
record_channel = "XIO-P7"

GPIO.setup(record_channel, GPIO.IN)
GPIO.setup(sing_channel, GPIO.IN)

GPIO.add_event_detect(record_channel, GPIO.RISING)
GPIO.add_event_detect(sing_channel, GPIO.RISING)

# hardcoded file locations
codeLoc = "/home/chip/mewsician/"
audioLoc = "/home/chip/audio/"
queue = audioLoc + "queue"

# auth passed in from (../start)
authentication = sys.argv[1]
recording = False
listening = False
singing = False
play_pid = None
fname = None
bname = None
mpid = None

# trigger playback of audio file
def playback():
    global play_pid
    print("Starting playback...")

    # get a random audio clip to play from the audio folder
    music_files = [f for f in os.listdir(audioLoc) if f.endswith('.mp3')]
    if len(music_files) > 0:
        m_index = random.randint(0, len(music_files)-1)
        print 'm_index is', m_index
        music_path = audioLoc + music_files[m_index]
        playback_fname = music_path

        args = ['mplayer', playback_fname]
        playproc = subprocess.Popen(args)
        play_pid = psutil.Process(playproc.pid)
    else:
        print 'no playable music...'

# code that runs once when the script is starting.
def startup():
    print "\n<||||| - mewsician . commences - |||||>\n"
    try: # reupload and files that previously failed
        for file in open(queue, 'r'):
            retryUpload(file)
    except: # no uploads || !file exists yet || upload err
        args = ['touch', queue]
        subprocess.Popen(args)
        print sys.exc_info()[0]

# trigger external recording and create a new subprocess for this
# combine current time and uid for the filename to be uploaded
def record():
    global fname, bname, mpid
    print("Starting recording...")

    bname = datetime.datetime.now().strftime("%Y-%m-%d @ %H:%M:%S")
    fname =  bname + '.wav'

    # starting the recording
    args = ['arecord', '-f', 'cd', fname]
    musicproc = subprocess.Popen(args)
    mpid = psutil.Process(musicproc.pid)
    print(fname)
    print(mpid)
    print("""  ...meow, edge detected!
  |\      _,,,---,,_
  /,`.-'`'    -.  ;-;;,_
 |,4-  ) )-,_..;\ (  `'-'
'---''(_/--'  `-'\_)
        """) # =^_^=

def retryUpload(file):
    # TODO implement
    print(file)

# stop current recording, compress file format
# trigger external uploading if connected to the network
def upload():
    global mname
    print("\nStopping recording...")
    mpid.terminate() # from record()
    mname = bname + ".mp3"

    # stopped recording, update arduino lights
    send_serial('u')

    print("Compressing audio...")
    subprocess.call(['sudo', 'chown', 'chip:chip', fname])
    subprocess.call(['lame', '-V2', fname, mname]) # convert
    subprocess.call(['sudo', 'chown', 'chip:chip', mname])

    print("Uploading music...")
    auth = 'auth=' + authentication # upload
    path =  os.getcwd() + '/' + mname
    upload = 'file=@' + path

    args = ['curl', '--form', upload, '--form', auth, 'http://mewsician.win/upload']
    try: # if upload fails (no network connection), write it to a queue
        print(subprocess.check_output(args))
        print("Cleaning up...")
        subprocess.call(['mv', '-v', mname, audioLoc])
        subprocess.call(['rm', '-v', fname])
        print("Complete.")
    except subprocess.CalledProcessError as e:
        with open(audioLoc + "queue", "a") as q:
            q.write(mname)
        print(e.output)

def trigger_record():
    print 'trigger record'
    if recording:
        end_recording()
        send_serial('d')
    else:
        start_recording()

def start_recording():
    global recording
    global listening
    global singing
    recording = True
    listening = False
    singing = False

    # global hunger
    # hunger = 0

    # write_time_to_file()
    send_serial('r')
    record()

def end_recording():
    send_serial('e')
    upload()
    global recording
    recording = False

def write_time_to_file():
    with open('last_time_practiced.txt', 'w+') as f:
        f.write(datetime.datetime.now().isoformat())

def start_singing():
    global listening
    global singing
    singing = True
    listening = False

    send_serial('s')
    playback()

def end_singing():
    global singing
    global play_pid

    singing = False
    send_serial('d')
    # if still playing, kill the playback process
    if pid_active(play_pid):
        p = psutil.Process(play_pid)
        p.terminate()
    print "playback ending."
    play_pid = None

def trigger_listen():
    if listening:
        end_listening()
    else:
        start_listening()

def start_listening():
    global recording
    global listening
    global singing
    listening = True
    recording = False
    singing = False
    send_serial('l')

def end_listening():
    global listening
    listening = False
    send_serial('d')

def send_serial(ch):
    # d, r, s, c
    for i in range(0,2):
        try:
            ser.write(ch)
        except:
            print "failed to send '", ch, "'... try again"

def pid_active(pid):
    return pid in psutil.pids()

def calc_hunger():
    # get last time entered listen or record state
    try:
        with open('last_time_practiced.txt', 'r+') as f:
            # process last date
            lastdatestr = f.readline()
            if lastdatestr:
                lastdate = datetime.datetime.strptime(lastdatestr, "%Y-%m-%dT%H:%M:%S.%f")
                now = datetime.datetime.now()
                difference = now - lastdate
                days = difference.days
            else:
                days = 0
            send_serial('h')
            sleep(3)
            send_serial(bytes([days]))
            print "it's been ", days, " since you practiced"
            return days
    except:
        print "oh no file error"
        return 0

last_time = -1

ser = serial.Serial('/dev/ttyS0')
sleep(1) # wait for channel to open
# hunger = calc_hunger()

# initialize as dreaming
send_serial('d')

startup() # setting up code to initialize the board/uploads

while True: # continually in this state, check if channel HI
    # print(GPIO.input(record_channel))
    # record ing
    if GPIO.event_detected(record_channel) and not GPIO.input(record_channel):
        trigger_record() # on button press, trigger callback
        sleep(10) # wait 10 secs for debouncing, bad but works.
        # THIS MEANS RECORD FOR AT LEAST 10 seconds please:

    # start sing
    if not recording:
        if not singing and not GPIO.input(sing_channel):
            if last_time is -1:
                last_time = datetime.datetime.now()
            else:
                if datetime.datetime.now() - last_time > timedelta(0, 0, 250):
                    last_time = -1
                    print "singing..."
                    start_singing()
                    sleep(3) # wait 3 secs for debouncing, bad but works.

        # # end sing
        if singing and GPIO.input(sing_channel):
            print "stop singing..."
            end_singing()
            sleep(3) # wait 3 secs for debouncing, bad but works.


text:
Forms

 Basic Form Elements

                        <form role="form">

Text Input <input class="form-control">

Example block-level help text here.

Text Input with Placeholder <input
                                    class="form-control" placeholder="Enter text">

Static Control

email@example.com

File input <input type="file">

Text area <textarea class="form-control"
                                                                                rows="3"></textarea>

Checkboxes

 <input type="checkbox" value="">Checkbox 1

 <input type="checkbox" value="">Checkbox 2

 <input type="checkbox" value="">Checkbox 3

Inline Checkboxes
                                <input type="checkbox">1   <input
                                    type="checkbox">2   <input type="checkbox">3

Radio Buttons

 <input type="radio" name="optionsRadios" id="optionsRadios1"
                                                                  value="option1" checked>Radio 1

 <input type="radio" name="optionsRadios" id="optionsRadios2"
                                                                  value="option2">Radio 2

 <input type="radio" name="optionsRadios" id="optionsRadios3"
                                                                  value="option3">Radio 3

Inline Radio Buttons
                                <input type="radio" name="optionsRadiosInline" id="optionsRadiosInline1" value="option1"
                                       checked>1   <input type="radio"
                                                                                name="optionsRadiosInline"
                                                                                id="optionsRadiosInline2"
                                                                                value="option2">2
                                 <input type="radio" name="optionsRadiosInline"
                                                                    id="optionsRadiosInline3" value="option3">3

Selects <select class="form-control">
                                <option>1
                                <option>2
                                <option>3
                                <option>4
                                <option>5
                            </select>

Multiple Selects <select multiple
                                                                                class="form-control">
                                <option>1
                                <option>2
                                <option>3
                                <option>4
                                <option>5
                            </select>

                            <button type="submit" class="btn btn-default">Submit Button</button>
                            <button type="reset" class="btn btn-default">Reset Button</button>
                        </form>

Disabled Form States

                        <form role="form">
                            <fieldset disabled>

Disabled input <input
                                        class="form-control" id="disabledInput" type="text" placeholder="Disabled input"
                                        disabled>

Disabled select menu <select
                                        id="disabledSelect" class="form-control">
                                    <option>Disabled select
                                </select>

 <input type="checkbox">Disabled Checkbox

                                <button type="submit" class="btn btn-primary">Disabled Button</button>
                            </fieldset>
                        </form>

Form Validation States

                        <form role="form">

Input
                                with success <input type="text" class="form-control" id="inputSuccess">

Input
                                with warning <input type="text" class="form-control" id="inputWarning">

Input with
                                error <input type="text" class="form-control" id="inputError">

                        </form>

Input Groups

                        <form role="form">

@ <input
                                    type="text" class="form-control" placeholder="Username">

<input type="text" class="form-control"> .00

  <input type="text" class="form-control"
                                                                          placeholder="Font Awesome Icon">

$ <input
                                    type="text" class="form-control"> .00

<input type="text" class="form-control">  <button class="btn btn-default" type="button"></button>

                        </form>


text:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>geomesa-convert_2.11</artifactId>
        <groupId>org.locationtech.geomesa</groupId>
        <version>2.4.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>geomesa-convert-fixedwidth_2.11</artifactId>
    <name>GeoMesa Convert Fixed Width</name>

    <dependencies>
        <dependency>
            <groupId>org.locationtech.geomesa</groupId>
            <artifactId>geomesa-convert-common_${scala.binary.version}</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.specs2</groupId>
            <artifactId>specs2-core_${scala.binary.version}</artifactId>
        </dependency>
        <dependency>
            <groupId>org.specs2</groupId>
            <artifactId>specs2-junit_${scala.binary.version}</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>