text:
package am.widget.floatingactionmode.impl;

import android.content.Context;
import android.view.View;

import java.util.ArrayList;

import am.widget.floatingactionmode.FloatingMenuItem;
import am.widget.floatingactionmode.FloatingSubMenu;

/**
 * 常规次级菜单实现
 * Created by Alex on 2018/11/21.
 */
final class FloatingSubMenuCommonImpl implements FloatingSubMenu {

    private final Context mContext;
    private CharSequence mTitle;
    private final ArrayList<FloatingMenuItem> mItems = new ArrayList<>();

    FloatingSubMenuCommonImpl(Context context, CharSequence title) {
        mContext = context;
        mTitle = title;
    }

    @Override
    public FloatingSubMenu setTitle(CharSequence title) {
        mTitle = title;
        return this;
    }

    @Override
    public FloatingSubMenu setTitle(int title) {
        mTitle = mContext.getString(title);
        return this;
    }

    @Override
    public CharSequence getTitle() {
        return mTitle;
    }

    @Override
    public FloatingMenuItem add(CharSequence title) {
        final FloatingMenuItem item = new FloatingSubMenuItemImpl(mContext).setTitle(title);
        mItems.add(item);
        return item;
    }

    @Override
    public FloatingMenuItem add(int title) {
        final FloatingMenuItem item = new FloatingSubMenuItemImpl(mContext).setTitle(title);
        mItems.add(item);
        return item;
    }

    @Override
    public FloatingMenuItem add(int id, int order, CharSequence title) {
        final FloatingMenuItem item = new FloatingSubMenuItemImpl(mContext, id, order);
        mItems.add(item.setTitle(title));
        return item;
    }

    @Override
    public FloatingMenuItem add(int id, int order, int title) {
        final FloatingMenuItem item = new FloatingSubMenuItemImpl(mContext, id, order);
        mItems.add(item.setTitle(title));
        return item;
    }

    @Override
    public void removeItem(int id) {
        int count = mItems.size();
        for (int i = 0; i < count; i++) {
            final FloatingMenuItem item = mItems.get(i);
            if (item.getId() == id)
                mItems.remove(i);
            i--;
            count = mItems.size();
        }
    }

    @Override
    public void clear() {
        mItems.clear();
    }

    @Override
    public FloatingMenuItem findItem(int id) {
        for (FloatingMenuItem item : mItems) {
            if (item.getId() == id)
                return item;
        }
        return null;
    }

    @Override
    public int size() {
        return mItems.size();
    }

    @Override
    public FloatingMenuItem getItem(int index) {
        return mItems.get(index);
    }

    @Override
    public boolean isCustom() {
        return false;
    }

    @Override
    public FloatingSubMenu setCustomView(View view) {
        throw new UnsupportedOperationException("Common sub menu not support set custom view.");
    }

    @Override
    public View getCustomView() {
        throw new UnsupportedOperationException("Common sub menu not support get custom view.");
    }
}


text:
All definitions have been removed and replaced with custom resources.
As a result we are now providing the default assigned names:

- apache_mod --> apache2_mod
- apache_conf --> apache2_conf
- apache_site --> apache2_site

This helps as resource behaviours have been significantly changed to remove magic where possible.

## apache_module

Having a module disabled is now an action on the resource:

```ruby
# Old Style
apache_module "disabled_module" do
  enable false
end
```

```ruby
# New Style
apache2_module "disabled_module" do
  action :disable
end
```

## Where did the apache2 recipes go

Recipes are now modules, so your cookbook pattern will go from

```ruby
include_recipe 'apache2'
include_recipe 'apache2::mod_proxy'
include_recipe 'apache2::mod_proxy_http'
include_recipe 'apache2::mod_ssl'
```

to

```ruby
apache2_install 'default_install'
apache2_module 'headers'
apache2_module 'proxy'
apache2_module 'proxy_http'
apache2_module 'rewrite'
apache2_module 'ssl'
```

## What happened to all my attributes

In custom resources having & using a global variable like attributes makes the cookbook brittle and hard to test.

These have been removed in favour of tunable properties on each resource. Please see the documentation directory for all tunables.

## What happened to apache2_web_app

The `apache2_web_app` resource was a wrapper around the template resource and `apache2_site` that provided little value, and restricted the the users ability to provide all the variables possible.

It is recommended that you manage your template and call the `apache2_site` resource directly.

This leads to a simpler system, and you get more control over the variables and values you pass to the template.

Here are the modifications you will need to make:

```ruby
web_app 'ssl_redirect' do
  server_name node['hostname']
  server_port '80'
  docroot '/var/www/'
  template 'ssl_redirect.conf.erb'
  notifies :restart, 'service[apache2]', :delayed
end
```

to

```ruby
apache2_default_site 'ssl_redirect' do
  default_site_name 'ssl_redirect'
  cookbook 'my_cookbook'
  port '80'
  template_source 'ssl_redirect.conf.erb'
  action :enable
end
```

A further example of this behaviour can be seen in the `apache2_default_site` resource.

## The service resource

whilst `service['apache2']` is defined in the `apache2_install` resource, due to the notification system of nested resources, we are unable to notify or subscribe directly to it.

To work around this issue, define the following helper in your cookbook:

```ruby
service 'apache2' do
  service_name lazy { apache_platform_service_name }
  supports restart: true, status: true, reload: true
  action :nothing
end
```

redpajama_set_name: RedPajamaGithub


text:
using Gem.Engine.AI.BehaviorTree;
using Gem.Engine.AI.BehaviorTree.Composites;
using Gem.Engine.AI.BehaviorTree.Decorators;
using Gem.Engine.AI.BehaviorTree.Leaves;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;

namespace Gem.Engine.Tests.AI
{
    [TestClass]
    public class BehaviorTreeTests
    {

        [TestMethod]
        public void WalkAndUnlockDoorBehaviorTest()
        {
            using (var sw = File.CreateText("WalkAndUnlockDoorBehaviorTest.info"))
            {
                int step = 0;

                var walk = new Behavior<AIContext>(
                context => CheckTarget(step = context.InitialStep, context.Target, sw.WriteLine),
                context => CheckTarget(++step, context.Target, sw.WriteLine))
                .TraceAs("Walk Action", sw.WriteLine);

                var unlockDoor = new Behavior<AIContext>(
                context => context.CanUnlock ? BehaviorResult.Success : BehaviorResult.Failure)
                .TraceAs("Unlock Door Action", sw.WriteLine);

                var breakDoor = new Behavior<AIContext>(
               context => BehaviorResult.Success)
               .TraceAs("Break Door Action", sw.WriteLine);

                var closeDoor = new Behavior<AIContext>(
                context => BehaviorResult.Failure)
                .TraceAs("Close Door Action", sw.WriteLine);

                var openDoor = new Selector<AIContext>(new[] { unlockDoor, breakDoor.TraceAs("BreakDoor") })
                .TraceAs("Open Door Composite", sw.WriteLine);

                var goToRoom = new Sequence<AIContext>(new[] { walk, openDoor, DecorateFor.AlwaysSucceeding(closeDoor) })
                .TraceAs("Go To Room Composite", sw.WriteLine);

                var aiContext = new AIContext();

                for (int tick = 0; tick < 50; tick++)
                {
                    goToRoom.Behave(aiContext);
                }
            }
        }

        internal class AIContext
        {
            public int InitialStep { get; } = 1;
            public int Target { get; set; } = 10;
            public bool CanUnlock { get; } = true;
        }

        private BehaviorResult CheckTarget(int currentStep, int target, Action<string> debugInfo)
        {
            if (currentStep >= target)
            {
                return BehaviorResult.Success;
            }
            debugInfo(currentStep.ToString());
            return BehaviorResult.Running;
        }

        [TestMethod]
        public void FluentTreeBuilderTest()
        {
            var behaviorBuilder = new BehaviorTreeBuilder<AIContext>();
            var tree =
                    behaviorBuilder
                    .Selector
                       .Behavior(context => BehaviorResult.Success)
                       .Sequence
                            .Behavior(context => BehaviorResult.Success)
                       .End
                       .Sequence
                            .Decorate(DecorateFor.AlwaysSucceeding)
                            .Behavior(context => BehaviorResult.Success)
                            .Sequence
                               .Behavior(context => BehaviorResult.Success)
                            .End
                           .Question(context => 1 == 1)
                       .End
                    .End
                    .Tree;
        }

    }
}


text:
'use strict';

var gulp = require('gulp');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var envify = require('envify/custom');
var partialify = require('partialify');
var sourcemaps = require('gulp-sourcemaps');
var less = require('gulp-less');
var autoprefixer = require('gulp-autoprefixer');
var rimraf = require('gulp-rimraf');
var notify = require('gulp-notify');
var browserSync = require('browser-sync');

// default task /////////////////////////////////////////////////
gulp.task('default', ['build', 'browser-sync', 'watch']);

gulp.task('clean', function() {
    return gulp.src(['build/**/*'], {
        read: false
    }).pipe(rimraf());
});

// build tasks //////////////////////////////////////////////////
gulp.task('build', ['css', 'html', 'images', 'browserify']);

gulp.task('browserify', function() {
    var environ = {
        NODE_ENV: process.env.NODE_ENV
    };
    return browserify('./public/main.js')
        .transform(envify(environ))
        .transform(partialify)
        .bundle({
            debug: process.env.NODE_ENV != 'production'
        })
        .on('error', function(err) {
            notify.onError('Error: <%= error.message %>')(err);
            this.end();
        })
        .pipe(source('index.js'))
        .pipe(gulp.dest('build/'));
});

// assets //////////////////////////////////////////////////////
gulp.task('html', function() {
    return gulp.src('./public/**/*.html')
        .pipe(gulp.dest('build/'))
});

gulp.task('css', function() {
    return gulp.src('public/**/*.css')
        .pipe(autoprefixer('last 1 version'))
        .pipe(gulp.dest('./build'))
});

gulp.task('less', function() {
    var less_transform = less();
    less_transform.on('error', function(err) {
        notify.onError('<%= error.message %>')(err);
        this.end();
    });
    return gulp.src('./public/**/*.less')
        .pipe(sourcemaps.init())
        .pipe(less_transform)
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('./build'));
});

gulp.task('images', ['favicon'], function() {
    return gulp.src('public/img/**/*')
        .pipe(gulp.dest('build/img'));
});

gulp.task('favicon', function() {
    return gulp.src('public/img/favicon.ico')
        .pipe(gulp.dest('build/'));
});

// file watching & rebuild/reload on change ////////////////////
gulp.task('watch', function() {
    gulp.watch('public/**/*.js', ['browserify']);
    gulp.watch('public/**/*.html', ['html']);
    gulp.watch('public/**/*.css', ['css']);
    gulp.watch('public/**/*.less', ['less']);
    gulp.watch('public/img/**/*', ['images']);
});

gulp.task('browser-sync', function() {
    browserSync({
        tunnel: true,
        open: 'local',
        ghostMode: false,
        files: './build/**/*',
        server: {
            baseDir: './build',
        },
    });
});


text:
from django.apps import AppConfig

class SpiritTopicAdminConfig(AppConfig):

    name = 'spirit.topic.admin'
    verbose_name = "Spirit Topic Admin"
    label = 'spirit_topic_admin'


text:
interface KnockoutStatic {
    track(obj: any, propertyNames?: Array<string>): any;
    untrack(obj: any, propertyNames?: Array<string>): any;
    defineProperty(obj: any, propertyName: string, evaluator: Function): any;
    defineProperty(obj: any, propertyName: string, options: KnockoutDefinePropertyOptions): any;
    getObservable(obj: any, propertyName: string): KnockoutObservable<any>;
    valueHasMutated(obj: any, propertyName: string): void;
}

interface KnockoutDefinePropertyOptions {
	get(): any;
	set?(value: any): void;
}

interface Array<T> {
	remove(item: T): T[];
	removeAll(items: T[]): T[];
	removeAll(): T[];

	destroy(item: T): void;
	destroyAll(items: T[]): void;
	destroyAll(): void;
}


text:
            <form class="form-horizontal" th:action="@{/question/{qId}/answer/delete/{id}(id=${answer.id},qId=${qId})}" method="POST">
                <fieldset>
                    <legend>Delete Answer</legend>

                        Content

                            <textarea class="form-control" rows="6" id="answer_content" name="content" th:field="${answer.content}" disabled="disabled"></textarea>

                            Cancel
                            <input type="submit" class="btn btn-danger" value="Delete"/>

                </fieldset>
            </form>


text:
<?php

namespace Jaxxes\SeleccionProcesBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * QuestionbyProcessSelection
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class QuestionbyProcessSelection
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
    * @ORM\ManyToOne(targetEntity="Jaxxes\SeleccionProcesBundle\Entity\NivelbySelectionProcess")
    */
    protected $nivelbySelectionProcess;

    /**
    * @ORM\ManyToOne(targetEntity="Jaxxes\ResumeBundle\Entity\QuestionbySection")
    */
    protected $questionbySection;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    public function __toString()
    {
        return $this->getNivelbySelectionProcess()->__toString();
    }

    /**
     * Set nivelbySelectionProcess
     *
     * @param Jaxxes\SeleccionProcesBundle\Entity\NivelbySelectionProcess $nivelbySelectionProcess
     */
    public function setNivelbySelectionProcess(\Jaxxes\SeleccionProcesBundle\Entity\NivelbySelectionProcess $nivelbySelectionProcess)
    {
        $this->nivelbySelectionProcess = $nivelbySelectionProcess;
    }

    /**
     * Get nivelbySelectionProcess
     *
     * @return Jaxxes\SeleccionProcesBundle\Entity\NivelbySelectionProcess
     */
    public function getNivelbySelectionProcess()
    {
        return $this->nivelbySelectionProcess;
    }

    /**
     * Set questionbySection
     *
     * @param Jaxxes\ResumeBundle\Entity\QuestionbySection $questionbySection
     */
    public function setQuestionbySection(\Jaxxes\ResumeBundle\Entity\QuestionbySection $questionbySection)
    {
        $this->questionbySection = $questionbySection;
    }

    /**
     * Get questionbySection
     *
     * @return Jaxxes\ResumeBundle\Entity\QuestionbySection
     */
    public function getQuestionbySection()
    {
        return $this->questionbySection;
    }
}


text:
import { merge } from 'lodash';
import * as papaparse from 'papaparse';
const defaultOptions = {
    skipEmptyLines: true,
};
export class ParserUtils {
    /**
     * parses the given csv file/blob using PapaParse
     * @param data
     * @param options additional options
     * @return {Promise<R>|Promise}
     */
    static parseCSV(data, options = {}) {
        return new Promise((resolve, reject) => {
            papaparse.parse(data, merge({
                complete: (result) => resolve({ data: result.data, meta: result.meta }),
                error: (error) => reject(error),
            }, defaultOptions, options));
        });
    }
    static streamCSV(data, chunk, options = {}) {
        return new Promise((resolve, reject) => {
            papaparse.parse(data, merge({
                complete: (result) => resolve(null),
                chunk: (result) => chunk({ data: result.data, meta: result.meta }),
                error: (error) => reject(error),
            }, defaultOptions, options));
        });
    }
}
//# sourceMappingURL=parser.js.map


text:
require 'rails_helper'

feature 'Issue Sidebar' do
  include MobileHelpers

  let(:group) { create(:group, :nested) }
  let(:project) { create(:project, :public, namespace: group) }
  let(:issue) { create(:issue, project: project) }
  let!(:user) { create(:user)}
  let!(:label) { create(:label, project: project, title: 'bug') }

  before do
    sign_in(user)
  end

  context 'assignee', js: true do
    let(:user2) { create(:user) }
    let(:issue2) { create(:issue, project: project, author: user2) }

    before do
      project.team << [user, :developer]
      visit_issue(project, issue2)

      find('.block.assignee .edit-link').click

      wait_for_requests
    end

    it 'shows author in assignee dropdown' do
      page.within '.dropdown-menu-user' do
        expect(page).to have_content(user2.name)
      end
    end

    it 'shows author when filtering assignee dropdown' do
      page.within '.dropdown-menu-user' do
        find('.dropdown-input-field').native.send_keys user2.name
        sleep 1 # Required to wait for end of input delay

        wait_for_requests

        expect(page).to have_content(user2.name)
      end
    end

    it 'assigns yourself' do
      find('.block.assignee .dropdown-menu-toggle').click

      click_button 'assign yourself'

      wait_for_requests

      find('.block.assignee .edit-link').click

      page.within '.dropdown-menu-user' do
        expect(page.find('.dropdown-header')).to be_visible
        expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name)
      end
    end

    it 'keeps your filtered term after filtering and dismissing the dropdown' do
      find('.dropdown-input-field').native.send_keys user2.name

      wait_for_requests

      page.within '.dropdown-menu-user' do
        expect(page).not_to have_content 'Unassigned'
        click_link user2.name
      end

      find('.js-right-sidebar').click
      find('.block.assignee .edit-link').click

      expect(page.all('.dropdown-menu-user li').length).to eq(1)
      expect(find('.dropdown-input-field').value).to eq(user2.name)
    end
  end

  context 'as a allowed user' do
    before do
      project.team << [user, :developer]
      visit_issue(project, issue)
    end

    context 'sidebar', js: true do
      it 'changes size when the screen size is smaller' do
        sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
        # Resize the window
        resize_screen_sm
        # Make sure the sidebar is collapsed
        find(sidebar_selector)
        expect(page).to have_css(sidebar_selector)
        # Once is collapsed let's open the sidebard and reload
        open_issue_sidebar
        refresh
        find(sidebar_selector)
        expect(page).to have_css(sidebar_selector)
        # Restore the window size as it was including the sidebar
        restore_window_size
        open_issue_sidebar
      end
    end

    context 'editing issue labels', js: true do
      before do
        page.within('.block.labels') do
          find('.edit-link').click
        end
      end

      it 'shows option to create a new label' do
        page.within('.block.labels') do
          expect(page).to have_content 'Create new'
        end
      end

      context 'creating a new label', js: true do
        before do
          page.within('.block.labels') do
            click_link 'Create new'
          end
        end

        it 'shows dropdown switches to "create label" section' do
          page.within('.block.labels') do
            expect(page).to have_content 'Create new label'
          end
        end

        it 'adds new label' do
          page.within('.block.labels') do
            fill_in 'new_label_name', with: 'wontfix'
            page.find('.suggest-colors a', match: :first).trigger('click')
            page.find('button', text: 'Create').trigger('click')

            page.within('.dropdown-page-one') do
              expect(page).to have_content 'wontfix'
            end
          end
        end

        it 'shows error message if label title is taken' do
          page.within('.block.labels') do
            fill_in 'new_label_name', with: label.title
            page.find('.suggest-colors a', match: :first).trigger('click')
            page.find('button', text: 'Create').trigger('click')

            page.within('.dropdown-page-two') do
              expect(page).to have_content 'Title has already been taken'
            end
          end
        end
      end
    end
  end

  context 'as a guest' do
    before do
      project.team << [user, :guest]
      visit_issue(project, issue)
    end

    it 'does not have a option to edit labels' do
      expect(page).not_to have_selector('.block.labels .edit-link')
    end
  end

  def visit_issue(project, issue)
    visit project_issue_path(project, issue)
  end

  def open_issue_sidebar
    find('aside.right-sidebar.right-sidebar-collapsed .js-sidebar-toggle').trigger('click')
    find('aside.right-sidebar.right-sidebar-expanded')
  end
end


text:
<?php

namespace ForkCMS\Modules\MediaLibrary\Domain\MediaItem;

use ForkCMS\Modules\MediaLibrary\Domain\Manager\FileManager;
use ForkCMS\Modules\MediaLibrary\Domain\MediaItem\MediaItem;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use SimpleBus\Message\Bus\MessageBus;

/**
 * MediaItem Subscriber
 */
final class MediaItemSubscriber implements EventSubscriber
{
    /** @var CacheManager */
    protected $cacheManager;

    /** @var MessageBus */
    protected $commandBus;

    /** @var FileManager */
    protected $fileManager;

    public function __construct(
        FileManager $fileManager,
        CacheManager $cacheManager,
        MessageBus $commandBus
    ) {
        $this->fileManager = $fileManager;
        $this->cacheManager = $cacheManager;
        $this->commandBus = $commandBus;
    }

    public function getSubscribedEvents(): array
    {
        return [
            Events::postPersist,
            Events::postRemove,
        ];
    }

    private function deleteSource(MediaItem $mediaItem): void
    {
        $this->fileManager->deleteFile($mediaItem->getAbsolutePath());
    }

    private function deleteThumbnails(MediaItem $mediaItem): void
    {
        // We have an image, so we have thumbnails to delete
        if ($mediaItem->getType()->isImage()) {
            // Delete all thumbnails
            $this->cacheManager->remove($mediaItem->getWebPath());
        }
    }

    private function generateThumbnails(MediaItem $mediaItem): void
    {
        // We have an image, so we have a backend thumbnail to generate
        if ($mediaItem->getType()->isImage()) {
            // Generate Backend thumbnail
            $this->cacheManager->getBrowserPath($mediaItem->getWebPath(), 'media_library_backend_thumbnail');
        }
    }

    public function postPersist(LifecycleEventArgs $eventArgs): void
    {
        $entity = $eventArgs->getObject();
        if (!$entity instanceof MediaItem) {
            return;
        }

        $this->generateThumbnails($entity);
    }

    public function postRemove(LifecycleEventArgs $eventArgs): void
    {
        $entity = $eventArgs->getObject();
        if (!$entity instanceof MediaItem) {
            return;
        }

        $this->deleteSource($entity);
        $this->deleteThumbnails($entity);
    }
}


text:
#include "cache.h"
#include "blob.h"
#include "tree.h"
#include "commit.h"
#include "tag.h"
#include "tree-walk.h"
#include "builtin.h"
#include "parse-options.h"
#include "string-list.h"
#include "run-command.h"
#include "userdiff.h"
#include "grep.h"
#include "quote.h"
#include "dir.h"
#include "thread-utils.h"

static char const * const grep_usage[] = {
	"git grep [options] [-e] <pattern> [<rev>...] [[--] <path>...]",
	NULL
};

static int use_threads = 1;

#ifndef NO_PTHREADS
#define THREADS 8
static pthread_t threads[THREADS];

static void *load_sha1(const unsigned char *sha1, unsigned long *size,
		       const char *name);
static void *load_file(const char *filename, size_t *sz);

enum work_type {WORK_SHA1, WORK_FILE};

/* We use one producer thread and THREADS consumer
 * threads. The producer adds struct work_items to 'todo' and the
 * consumers pick work items from the same array.
 */
struct work_item {
	enum work_type type;
	char *name;

	/* if type == WORK_SHA1, then 'identifier' is a SHA1,
	 * otherwise type == WORK_FILE, and 'identifier' is a NUL
	 * terminated filename.
	 */
	void *identifier;
	char done;
	struct strbuf out;
};

/* In the range [todo_done, todo_start) in 'todo' we have work_items
 * that have been or are processed by a consumer thread. We haven't
 * written the result for these to stdout yet.
 *
 * The work_items in [todo_start, todo_end) are waiting to be picked
 * up by a consumer thread.
 *
 * The ranges are modulo TODO_SIZE.
 */
#define TODO_SIZE 128
static struct work_item todo[TODO_SIZE];
static int todo_start;
static int todo_end;
static int todo_done;

/* Has all work items been added? */
static int all_work_added;

/* This lock protects all the variables above. */
static pthread_mutex_t grep_mutex;

/* Used to serialize calls to read_sha1_file. */
static pthread_mutex_t read_sha1_mutex;

#define grep_lock() pthread_mutex_lock(&grep_mutex)
#define grep_unlock() pthread_mutex_unlock(&grep_mutex)
#define read_sha1_lock() pthread_mutex_lock(&read_sha1_mutex)
#define read_sha1_unlock() pthread_mutex_unlock(&read_sha1_mutex)

/* Signalled when a new work_item is added to todo. */
static pthread_cond_t cond_add;

/* Signalled when the result from one work_item is written to
 * stdout.
 */
static pthread_cond_t cond_write;

/* Signalled when we are finished with everything. */
static pthread_cond_t cond_result;

static int print_hunk_marks_between_files;
static int printed_something;

static void add_work(enum work_type type, char *name, void *id)
{
	grep_lock();

	while ((todo_end+1) % ARRAY_SIZE(todo) == todo_done) {
		pthread_cond_wait(&cond_write, &grep_mutex);
	}

	todo[todo_end].type = type;
	todo[todo_end].name = name;
	todo[todo_end].identifier = id;
	todo[todo_end].done = 0;
	strbuf_reset(&todo[todo_end].out);
	todo_end = (todo_end + 1) % ARRAY_SIZE(todo);

	pthread_cond_signal(&cond_add);
	grep_unlock();
}

static struct work_item *get_work(void)
{
	struct work_item *ret;

	grep_lock();
	while (todo_start == todo_end && !all_work_added) {
		pthread_cond_wait(&cond_add, &grep_mutex);
	}

	if (todo_start == todo_end && all_work_added) {
		ret = NULL;
	} else {
		ret = &todo[todo_start];
		todo_start = (todo_start + 1) % ARRAY_SIZE(todo);
	}
	grep_unlock();
	return ret;
}

static void grep_sha1_async(struct grep_opt *opt, char *name,
			    const unsigned char *sha1)
{
	unsigned char *s;
	s = xmalloc(20);
	memcpy(s, sha1, 20);
	add_work(WORK_SHA1, name, s);
}

static void grep_file_async(struct grep_opt *opt, char *name,
			    const char *filename)
{
	add_work(WORK_FILE, name, xstrdup(filename));
}

static void work_done(struct work_item *w)
{
	int old_done;

	grep_lock();
	w->done = 1;
	old_done = todo_done;
	for(; todo[todo_done].done && todo_done != todo_start;
	    todo_done = (todo_done+1) % ARRAY_SIZE(todo)) {
		w = &todo[todo_done];
		if (w->out.len) {
			if (print_hunk_marks_between_files && printed_something)
				write_or_die(1, "--\n", 3);
			write_or_die(1, w->out.buf, w->out.len);
			printed_something = 1;
		}
		free(w->name);
		free(w->identifier);
	}

	if (old_done != todo_done)
		pthread_cond_signal(&cond_write);

	if (all_work_added && todo_done == todo_end)
		pthread_cond_signal(&cond_result);

	grep_unlock();
}

static void *run(void *arg)
{
	int hit = 0;
	struct grep_opt *opt = arg;

	while (1) {
		struct work_item *w = get_work();
		if (!w)
			break;

		opt->output_priv = w;
		if (w->type == WORK_SHA1) {
			unsigned long sz;
			void* data = load_sha1(w->identifier, &sz, w->name);

			if (data) {
				hit |= grep_buffer(opt, w->name, data, sz);
				free(data);
			}
		} else if (w->type == WORK_FILE) {
			size_t sz;
			void* data = load_file(w->identifier, &sz);
			if (data) {
				hit |= grep_buffer(opt, w->name, data, sz);
				free(data);
			}
		} else {
			assert(0);
		}

		work_done(w);
	}
	free_grep_patterns(arg);
	free(arg);

	return (void*) (intptr_t) hit;
}

static void strbuf_out(struct grep_opt *opt, const void *buf, size_t size)
{
	struct work_item *w = opt->output_priv;
	strbuf_add(&w->out, buf, size);
}

static void start_threads(struct grep_opt *opt)
{
	int i;

	pthread_mutex_init(&grep_mutex, NULL);
	pthread_mutex_init(&read_sha1_mutex, NULL);
	pthread_cond_init(&cond_add, NULL);
	pthread_cond_init(&cond_write, NULL);
	pthread_cond_init(&cond_result, NULL);

	for (i = 0; i < ARRAY_SIZE(todo); i++) {
		strbuf_init(&todo[i].out, 0);
	}

	for (i = 0; i < ARRAY_SIZE(threads); i++) {
		int err;
		struct grep_opt *o = grep_opt_dup(opt);
		o->output = strbuf_out;
		compile_grep_patterns(o);
		err = pthread_create(&threads[i], NULL, run, o);

		if (err)
			die(_("grep: failed to create thread: %s"),
			    strerror(err));
	}
}

static int wait_all(void)
{
	int hit = 0;
	int i;

	grep_lock();
	all_work_added = 1;

	/* Wait until all work is done. */
	while (todo_done != todo_end)
		pthread_cond_wait(&cond_result, &grep_mutex);

	/* Wake up all the consumer threads so they can see that there
	 * is no more work to do.
	 */
	pthread_cond_broadcast(&cond_add);
	grep_unlock();

	for (i = 0; i < ARRAY_SIZE(threads); i++) {
		void *h;
		pthread_join(threads[i], &h);
		hit |= (int) (intptr_t) h;
	}

	pthread_mutex_destroy(&grep_mutex);
	pthread_mutex_destroy(&read_sha1_mutex);
	pthread_cond_destroy(&cond_add);
	pthread_cond_destroy(&cond_write);
	pthread_cond_destroy(&cond_result);

	return hit;
}
#else /* !NO_PTHREADS */
#define read_sha1_lock()
#define read_sha1_unlock()

static int wait_all(void)
{
	return 0;
}
#endif

static int grep_config(const char *var, const char *value, void *cb)
{
	struct grep_opt *opt = cb;
	char *color = NULL;

	switch (userdiff_config(var, value)) {
	case 0: break;
	case -1: return -1;
	default: return 0;
	}

	if (!strcmp(var, "grep.extendedregexp")) {
		if (git_config_bool(var, value))
			opt->regflags |= REG_EXTENDED;
		else
			opt->regflags &= ~REG_EXTENDED;
		return 0;
	}

	if (!strcmp(var, "grep.linenumber")) {
		opt->linenum = git_config_bool(var, value);
		return 0;
	}

	if (!strcmp(var, "color.grep"))
		opt->color = git_config_colorbool(var, value, -1);
	else if (!strcmp(var, "color.grep.context"))
		color = opt->color_context;
	else if (!strcmp(var, "color.grep.filename"))
		color = opt->color_filename;
	else if (!strcmp(var, "color.grep.function"))
		color = opt->color_function;
	else if (!strcmp(var, "color.grep.linenumber"))
		color = opt->color_lineno;
	else if (!strcmp(var, "color.grep.match"))
		color = opt->color_match;
	else if (!strcmp(var, "color.grep.selected"))
		color = opt->color_selected;
	else if (!strcmp(var, "color.grep.separator"))
		color = opt->color_sep;
	else
		return git_color_default_config(var, value, cb);
	if (color) {
		if (!value)
			return config_error_nonbool(var);
		color_parse(value, var, color);
	}
	return 0;
}

static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
{
	void *data;

	if (use_threads) {
		read_sha1_lock();
		data = read_sha1_file(sha1, type, size);
		read_sha1_unlock();
	} else {
		data = read_sha1_file(sha1, type, size);
	}
	return data;
}

static void *load_sha1(const unsigned char *sha1, unsigned long *size,
		       const char *name)
{
	enum object_type type;
	void *data = lock_and_read_sha1_file(sha1, &type, size);

	if (!data)
		error(_("'%s': unable to read %s"), name, sha1_to_hex(sha1));

	return data;
}

static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
		     const char *filename, int tree_name_len)
{
	struct strbuf pathbuf = STRBUF_INIT;
	char *name;

	if (opt->relative && opt->prefix_length) {
		quote_path_relative(filename + tree_name_len, -1, &pathbuf,
				    opt->prefix);
		strbuf_insert(&pathbuf, 0, filename, tree_name_len);
	} else {
		strbuf_addstr(&pathbuf, filename);
	}

	name = strbuf_detach(&pathbuf, NULL);

#ifndef NO_PTHREADS
	if (use_threads) {
		grep_sha1_async(opt, name, sha1);
		return 0;
	} else
#endif
	{
		int hit;
		unsigned long sz;
		void *data = load_sha1(sha1, &sz, name);
		if (!data)
			hit = 0;
		else
			hit = grep_buffer(opt, name, data, sz);

		free(data);
		free(name);
		return hit;
	}
}

static void *load_file(const char *filename, size_t *sz)
{
	struct stat st;
	char *data;
	int i;

	if (lstat(filename, &st) < 0) {
	err_ret:
		if (errno != ENOENT)
			error(_("'%s': %s"), filename, strerror(errno));
		return NULL;
	}
	if (!S_ISREG(st.st_mode))
		return NULL;
	*sz = xsize_t(st.st_size);
	i = open(filename, O_RDONLY);
	if (i < 0)
		goto err_ret;
	data = xmalloc(*sz + 1);
	if (st.st_size != read_in_full(i, data, *sz)) {
		error(_("'%s': short read %s"), filename, strerror(errno));
		close(i);
		free(data);
		return NULL;
	}
	close(i);
	data[*sz] = 0;
	return data;
}

static int grep_file(struct grep_opt *opt, const char *filename)
{
	struct strbuf buf = STRBUF_INIT;
	char *name;

	if (opt->relative && opt->prefix_length)
		quote_path_relative(filename, -1, &buf, opt->prefix);
	else
		strbuf_addstr(&buf, filename);
	name = strbuf_detach(&buf, NULL);

#ifndef NO_PTHREADS
	if (use_threads) {
		grep_file_async(opt, name, filename);
		return 0;
	} else
#endif
	{
		int hit;
		size_t sz;
		void *data = load_file(filename, &sz);
		if (!data)
			hit = 0;
		else
			hit = grep_buffer(opt, name, data, sz);

		free(data);
		free(name);
		return hit;
	}
}

static void append_path(struct grep_opt *opt, const void *data, size_t len)
{
	struct string_list *path_list = opt->output_priv;

	if (len == 1 && *(const char *)data == '\0')
		return;
	string_list_append(path_list, xstrndup(data, len));
}

static void run_pager(struct grep_opt *opt, const char *prefix)
{
	struct string_list *path_list = opt->output_priv;
	const char **argv = xmalloc(sizeof(const char *) * (path_list->nr + 1));
	int i, status;

	for (i = 0; i < path_list->nr; i++)
		argv[i] = path_list->items[i].string;
	argv[path_list->nr] = NULL;

	if (prefix && chdir(prefix))
		die(_("Failed to chdir: %s"), prefix);
	status = run_command_v_opt(argv, RUN_USING_SHELL);
	if (status)
		exit(status);
	free(argv);
}

static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int cached)
{
	int hit = 0;
	int nr;
	read_cache();

	for (nr = 0; nr < active_nr; nr++) {
		struct cache_entry *ce = active_cache[nr];
		if (!S_ISREG(ce->ce_mode))
			continue;
		if (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))
			continue;
		/*
		 * If CE_VALID is on, we assume worktree file and its cache entry
		 * are identical, even if worktree file has been modified, so use
		 * cache version instead
		 */
		if (cached || (ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) {
			if (ce_stage(ce))
				continue;
			hit |= grep_sha1(opt, ce->sha1, ce->name, 0);
		}
		else
			hit |= grep_file(opt, ce->name);
		if (ce_stage(ce)) {
			do {
				nr++;
			} while (nr < active_nr &&
				 !strcmp(ce->name, active_cache[nr]->name));
			nr--; /* compensate for loop control */
		}
		if (hit && opt->status_only)
			break;
	}
	return hit;
}

static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
		     struct tree_desc *tree, struct strbuf *base, int tn_len)
{
	int hit = 0, match = 0;
	struct name_entry entry;
	int old_baselen = base->len;

	while (tree_entry(tree, &entry)) {
		int te_len = tree_entry_len(entry.path, entry.sha1);

		if (match != 2) {
			match = tree_entry_interesting(&entry, base, tn_len, pathspec);
			if (match < 0)
				break;
			if (match == 0)
				continue;
		}

		strbuf_add(base, entry.path, te_len);

		if (S_ISREG(entry.mode)) {
			hit |= grep_sha1(opt, entry.sha1, base->buf, tn_len);
		}
		else if (S_ISDIR(entry.mode)) {
			enum object_type type;
			struct tree_desc sub;
			void *data;
			unsigned long size;

			data = lock_and_read_sha1_file(entry.sha1, &type, &size);
			if (!data)
				die(_("unable to read tree (%s)"),
				    sha1_to_hex(entry.sha1));

			strbuf_addch(base, '/');
			init_tree_desc(&sub, data, size);
			hit |= grep_tree(opt, pathspec, &sub, base, tn_len);
			free(data);
		}
		strbuf_setlen(base, old_baselen);

		if (hit && opt->status_only)
			break;
	}
	return hit;
}

static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
		       struct object *obj, const char *name)
{
	if (obj->type == OBJ_BLOB)
		return grep_sha1(opt, obj->sha1, name, 0);
	if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
		struct tree_desc tree;
		void *data;
		unsigned long size;
		struct strbuf base;
		int hit, len;

		data = read_object_with_reference(obj->sha1, tree_type,
						  &size, NULL);
		if (!data)
			die(_("unable to read tree (%s)"), sha1_to_hex(obj->sha1));

		len = name ? strlen(name) : 0;
		strbuf_init(&base, PATH_MAX + len + 1);
		if (len) {
			strbuf_add(&base, name, len);
			strbuf_addch(&base, ':');
		}
		init_tree_desc(&tree, data, size);
		hit = grep_tree(opt, pathspec, &tree, &base, base.len);
		strbuf_release(&base);
		free(data);
		return hit;
	}
	die(_("unable to grep from object of type %s"), typename(obj->type));
}

static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
			const struct object_array *list)
{
	unsigned int i;
	int hit = 0;
	const unsigned int nr = list->nr;

	for (i = 0; i < nr; i++) {
		struct object *real_obj;
		real_obj = deref_tag(list->objects[i].item, NULL, 0);
		if (grep_object(opt, pathspec, real_obj, list->objects[i].name)) {
			hit = 1;
			if (opt->status_only)
				break;
		}
	}
	return hit;
}

static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec)
{
	struct dir_struct dir;
	int i, hit = 0;

	memset(&dir, 0, sizeof(dir));
	setup_standard_excludes(&dir);

	fill_directory(&dir, pathspec->raw);
	for (i = 0; i < dir.nr; i++) {
		const char *name = dir.entries[i]->name;
		int namelen = strlen(name);
		if (!match_pathspec_depth(pathspec, name, namelen, 0, NULL))
			continue;
		hit |= grep_file(opt, dir.entries[i]->name);
		if (hit && opt->status_only)
			break;
	}
	return hit;
}

static int context_callback(const struct option *opt, const char *arg,
			    int unset)
{
	struct grep_opt *grep_opt = opt->value;
	int value;
	const char *endp;

	if (unset) {
		grep_opt->pre_context = grep_opt->post_context = 0;
		return 0;
	}
	value = strtol(arg, (char **)&endp, 10);
	if (*endp) {
		return error(_("switch `%c' expects a numerical value"),
			     opt->short_name);
	}
	grep_opt->pre_context = grep_opt->post_context = value;
	return 0;
}

static int file_callback(const struct option *opt, const char *arg, int unset)
{
	struct grep_opt *grep_opt = opt->value;
	int from_stdin = !strcmp(arg, "-");
	FILE *patterns;
	int lno = 0;
	struct strbuf sb = STRBUF_INIT;

	patterns = from_stdin ? stdin : fopen(arg, "r");
	if (!patterns)
		die_errno(_("cannot open '%s'"), arg);
	while (strbuf_getline(&sb, patterns, '\n') == 0) {
		char *s;
		size_t len;

		/* ignore empty line like grep does */
		if (sb.len == 0)
			continue;

		s = strbuf_detach(&sb, &len);
		append_grep_pat(grep_opt, s, len, arg, ++lno, GREP_PATTERN);
	}
	if (!from_stdin)
		fclose(patterns);
	strbuf_release(&sb);
	return 0;
}

static int not_callback(const struct option *opt, const char *arg, int unset)
{
	struct grep_opt *grep_opt = opt->value;
	append_grep_pattern(grep_opt, "--not", "command line", 0, GREP_NOT);
	return 0;
}

static int and_callback(const struct option *opt, const char *arg, int unset)
{
	struct grep_opt *grep_opt = opt->value;
	append_grep_pattern(grep_opt, "--and", "command line", 0, GREP_AND);
	return 0;
}

static int open_callback(const struct option *opt, const char *arg, int unset)
{
	struct grep_opt *grep_opt = opt->value;
	append_grep_pattern(grep_opt, "(", "command line", 0, GREP_OPEN_PAREN);
	return 0;
}

static int close_callback(const struct option *opt, const char *arg, int unset)
{
	struct grep_opt *grep_opt = opt->value;
	append_grep_pattern(grep_opt, ")", "command line", 0, GREP_CLOSE_PAREN);
	return 0;
}

static int pattern_callback(const struct option *opt, const char *arg,
			    int unset)
{
	struct grep_opt *grep_opt = opt->value;
	append_grep_pattern(grep_opt, arg, "-e option", 0, GREP_PATTERN);
	return 0;
}

static int help_callback(const struct option *opt, const char *arg, int unset)
{
	return -1;
}

int cmd_grep(int argc, const char **argv, const char *prefix)
{
	int hit = 0;
	int cached = 0;
	int seen_dashdash = 0;
	int external_grep_allowed__ignored;
	const char *show_in_pager = NULL, *default_pager = "dummy";
	struct grep_opt opt;
	struct object_array list = OBJECT_ARRAY_INIT;
	const char **paths = NULL;
	struct pathspec pathspec;
	struct string_list path_list = STRING_LIST_INIT_NODUP;
	int i;
	int dummy;
	int use_index = 1;
	enum {
		pattern_type_unspecified = 0,
		pattern_type_bre,
		pattern_type_ere,
		pattern_type_fixed,
		pattern_type_pcre,
	};
	int pattern_type = pattern_type_unspecified;

	struct option options[] = {
		OPT_BOOLEAN(0, "cached", &cached,
			"search in index instead of in the work tree"),
		OPT_BOOLEAN(0, "index", &use_index,
			"--no-index finds in contents not managed by git"),
		OPT_GROUP(""),
		OPT_BOOLEAN('v', "invert-match", &opt.invert,
			"show non-matching lines"),
		OPT_BOOLEAN('i', "ignore-case", &opt.ignore_case,
			"case insensitive matching"),
		OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp,
			"match patterns only at word boundaries"),
		OPT_SET_INT('a', "text", &opt.binary,
			"process binary files as text", GREP_BINARY_TEXT),
		OPT_SET_INT('I', NULL, &opt.binary,
			"don't match patterns in binary files",
			GREP_BINARY_NOMATCH),
		{ OPTION_INTEGER, 0, "max-depth", &opt.max_depth, "depth",
			"descend at most <depth> levels", PARSE_OPT_NONEG,
			NULL, 1 },
		OPT_GROUP(""),
		OPT_SET_INT('E', "extended-regexp", &pattern_type,
			    "use extended POSIX regular expressions",
			    pattern_type_ere),
		OPT_SET_INT('G', "basic-regexp", &pattern_type,
			    "use basic POSIX regular expressions (default)",
			    pattern_type_bre),
		OPT_SET_INT('F', "fixed-strings", &pattern_type,
			    "interpret patterns as fixed strings",
			    pattern_type_fixed),
		OPT_SET_INT('P', "perl-regexp", &pattern_type,
			    "use Perl-compatible regular expressions",
			    pattern_type_pcre),
		OPT_GROUP(""),
		OPT_BOOLEAN('n', "line-number", &opt.linenum, "show line numbers"),
		OPT_NEGBIT('h', NULL, &opt.pathname, "don't show filenames", 1),
		OPT_BIT('H', NULL, &opt.pathname, "show filenames", 1),
		OPT_NEGBIT(0, "full-name", &opt.relative,
			"show filenames relative to top directory", 1),
		OPT_BOOLEAN('l', "files-with-matches", &opt.name_only,
			"show only filenames instead of matching lines"),
		OPT_BOOLEAN(0, "name-only", &opt.name_only,
			"synonym for --files-with-matches"),
		OPT_BOOLEAN('L', "files-without-match",
			&opt.unmatch_name_only,
			"show only the names of files without match"),
		OPT_BOOLEAN('z', "null", &opt.null_following_name,
			"print NUL after filenames"),
		OPT_BOOLEAN('c', "count", &opt.count,
			"show the number of matches instead of matching lines"),
		OPT__COLOR(&opt.color, "highlight matches"),
		OPT_GROUP(""),
		OPT_CALLBACK('C', NULL, &opt, "n",
			"show <n> context lines before and after matches",
			context_callback),
		OPT_INTEGER('B', NULL, &opt.pre_context,
			"show <n> context lines before matches"),
		OPT_INTEGER('A', NULL, &opt.post_context,
			"show <n> context lines after matches"),
		OPT_NUMBER_CALLBACK(&opt, "shortcut for -C NUM",
			context_callback),
		OPT_BOOLEAN('p', "show-function", &opt.funcname,
			"show a line with the function name before matches"),
		OPT_GROUP(""),
		OPT_CALLBACK('f', NULL, &opt, "file",
			"read patterns from file", file_callback),
		{ OPTION_CALLBACK, 'e', NULL, &opt, "pattern",
			"match <pattern>", PARSE_OPT_NONEG, pattern_callback },
		{ OPTION_CALLBACK, 0, "and", &opt, NULL,
		  "combine patterns specified with -e",
		  PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback },
		OPT_BOOLEAN(0, "or", &dummy, ""),
		{ OPTION_CALLBACK, 0, "not", &opt, NULL, "",
		  PARSE_OPT_NOARG | PARSE_OPT_NONEG, not_callback },
		{ OPTION_CALLBACK, '(', NULL, &opt, NULL, "",
		  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
		  open_callback },
		{ OPTION_CALLBACK, ')', NULL, &opt, NULL, "",
		  PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
		  close_callback },
		OPT__QUIET(&opt.status_only,
			   "indicate hit with exit status without output"),
		OPT_BOOLEAN(0, "all-match", &opt.all_match,
			"show only matches from files that match all patterns"),
		OPT_GROUP(""),
		{ OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
			"pager", "show matching files in the pager",
			PARSE_OPT_OPTARG, NULL, (intptr_t)default_pager },
		OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed__ignored,
			    "allow calling of grep(1) (ignored by this build)"),
		{ OPTION_CALLBACK, 0, "help-all", &options, NULL, "show usage",
		  PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback },
		OPT_END()
	};

	/*
	 * 'git grep -h', unlike 'git grep -h <pattern>', is a request
	 * to show usage information and exit.
	 */
	if (argc == 2 && !strcmp(argv[1], "-h"))
		usage_with_options(grep_usage, options);

	memset(&opt, 0, sizeof(opt));
	opt.prefix = prefix;
	opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
	opt.relative = 1;
	opt.pathname = 1;
	opt.pattern_tail = &opt.pattern_list;
	opt.header_tail = &opt.header_list;
	opt.regflags = REG_NEWLINE;
	opt.max_depth = -1;

	strcpy(opt.color_context, "");
	strcpy(opt.color_filename, "");
	strcpy(opt.color_function, "");
	strcpy(opt.color_lineno, "");
	strcpy(opt.color_match, GIT_COLOR_BOLD_RED);
	strcpy(opt.color_selected, "");
	strcpy(opt.color_sep, GIT_COLOR_CYAN);
	opt.color = -1;
	git_config(grep_config, &opt);
	if (opt.color == -1)
		opt.color = git_use_color_default;

	/*
	 * If there is no -- then the paths must exist in the working
	 * tree.  If there is no explicit pattern specified with -e or
	 * -f, we take the first unrecognized non option to be the
	 * pattern, but then what follows it must be zero or more
	 * valid refs up to the -- (if exists), and then existing
	 * paths.  If there is an explicit pattern, then the first
	 * unrecognized non option is the beginning of the refs list
	 * that continues up to the -- (if exists), and then paths.
	 */
	argc = parse_options(argc, argv, prefix, options, grep_usage,
			     PARSE_OPT_KEEP_DASHDASH |
			     PARSE_OPT_STOP_AT_NON_OPTION |
			     PARSE_OPT_NO_INTERNAL_HELP);
	switch (pattern_type) {
	case pattern_type_fixed:
		opt.fixed = 1;
		opt.pcre = 0;
		break;
	case pattern_type_bre:
		opt.fixed = 0;
		opt.pcre = 0;
		opt.regflags &= ~REG_EXTENDED;
		break;
	case pattern_type_ere:
		opt.fixed = 0;
		opt.pcre = 0;
		opt.regflags |= REG_EXTENDED;
		break;
	case pattern_type_pcre:
		opt.fixed = 0;
		opt.pcre = 1;
		break;
	default:
		break; /* nothing */
	}

	if (use_index && !startup_info->have_repository)
		/* die the same way as if we did it at the beginning */
		setup_git_directory();

	/*
	 * skip a -- separator; we know it cannot be
	 * separating revisions from pathnames if
	 * we haven't even had any patterns yet
	 */
	if (argc > 0 && !opt.pattern_list && !strcmp(argv[0], "--")) {
		argv++;
		argc--;
	}

	/* First unrecognized non-option token */
	if (argc > 0 && !opt.pattern_list) {
		append_grep_pattern(&opt, argv[0], "command line", 0,
				    GREP_PATTERN);
		argv++;
		argc--;
	}

	if (show_in_pager == default_pager)
		show_in_pager = git_pager(1);
	if (show_in_pager) {
		opt.color = 0;
		opt.name_only = 1;
		opt.null_following_name = 1;
		opt.output_priv = &path_list;
		opt.output = append_path;
		string_list_append(&path_list, show_in_pager);
		use_threads = 0;
	}

	if (!opt.pattern_list)
		die(_("no pattern given."));
	if (!opt.fixed && opt.ignore_case)
		opt.regflags |= REG_ICASE;

#ifndef NO_PTHREADS
	if (online_cpus() == 1 || !grep_threads_ok(&opt))
		use_threads = 0;

	if (use_threads) {
		if (opt.pre_context || opt.post_context)
			print_hunk_marks_between_files = 1;
		start_threads(&opt);
	}
#else
	use_threads = 0;
#endif

	compile_grep_patterns(&opt);

	/* Check revs and then paths */
	for (i = 0; i < argc; i++) {
		const char *arg = argv[i];
		unsigned char sha1[20];
		/* Is it a rev? */
		if (!get_sha1(arg, sha1)) {
			struct object *object = parse_object(sha1);
			if (!object)
				die(_("bad object %s"), arg);
			add_object_array(object, arg, &list);
			continue;
		}
		if (!strcmp(arg, "--")) {
			i++;
			seen_dashdash = 1;
		}
		break;
	}

	/* The rest are paths */
	if (!seen_dashdash) {
		int j;
		for (j = i; j < argc; j++)
			verify_filename(prefix, argv[j]);
	}

	paths = get_pathspec(prefix, argv + i);
	init_pathspec(&pathspec, paths);
	pathspec.max_depth = opt.max_depth;
	pathspec.recursive = 1;

	if (show_in_pager && (cached || list.nr))
		die(_("--open-files-in-pager only works on the worktree"));

	if (show_in_pager && opt.pattern_list && !opt.pattern_list->next) {
		const char *pager = path_list.items[0].string;
		int len = strlen(pager);

		if (len > 4 && is_dir_sep(pager[len - 5]))
			pager += len - 4;

		if (!strcmp("less", pager) || !strcmp("vi", pager)) {
			struct strbuf buf = STRBUF_INIT;
			strbuf_addf(&buf, "+/%s%s",
					strcmp("less", pager) ? "" : "*",
					opt.pattern_list->pattern);
			string_list_append(&path_list, buf.buf);
			strbuf_detach(&buf, NULL);
		}
	}

	if (!show_in_pager)
		setup_pager();

	if (!use_index) {
		if (cached)
			die(_("--cached cannot be used with --no-index."));
		if (list.nr)
			die(_("--no-index cannot be used with revs."));
		hit = grep_directory(&opt, &pathspec);
	} else if (!list.nr) {
		if (!cached)
			setup_work_tree();

		hit = grep_cache(&opt, &pathspec, cached);
	} else {
		if (cached)
			die(_("both --cached and trees are given."));
		hit = grep_objects(&opt, &pathspec, &list);
	}

	if (use_threads)
		hit |= wait_all();
	if (hit && show_in_pager)
		run_pager(&opt, prefix);
	free_grep_patterns(&opt);
	return !hit;
}


text:
#include "LocationUpdateInformation.h"

namespace WFAPI {

LocationUpdateInformation::LocationUpdateInformation()
   : m_altitude(0),
     m_heading(0),
     m_gpsQuality(QUALITY_MISSING),
     m_speed(0),
     m_routeHeading(0)
{

}

LocationUpdateInformation::LocationUpdateInformation(
   const WGS84Coordinate& position,
   wf_int32 altitude,
   wf_uint16 heading,
   GpsQualityEnum gpsQuality,
   wf_uint16 speed,
   const WGS84Coordinate& routePosition,
   wf_uint16 routeHeading)
   : m_altitude(altitude), m_heading(heading),
     m_gpsQuality(gpsQuality), m_position(position), m_speed(speed),
     m_routePosition(routePosition), m_routeHeading(routeHeading)
{
}

LocationUpdateInformation::LocationUpdateInformation(
   const LocationUpdateInformation& locationUpdateInformation)
   : m_altitude(locationUpdateInformation.m_altitude),
     m_heading(locationUpdateInformation.m_heading),
     m_gpsQuality(locationUpdateInformation.m_gpsQuality),
     m_position(locationUpdateInformation.m_position),
     m_speed(locationUpdateInformation.m_speed),
     m_routePosition(locationUpdateInformation.m_routePosition),
     m_routeHeading(locationUpdateInformation.m_routeHeading)
{
}

LocationUpdateInformation::~LocationUpdateInformation()
{
}

LocationUpdateInformation&
LocationUpdateInformation::operator=(const LocationUpdateInformation& rhs)
{
   if (this == &rhs) {
      // Handle self assignment
      return *this;
   }

   m_altitude = rhs.m_altitude;
   m_heading = rhs.m_heading;
   m_gpsQuality = rhs.m_gpsQuality;
   m_position = rhs.m_position;
   m_speed = rhs.m_speed;
   m_routePosition = rhs.m_routePosition;
   m_routeHeading = rhs.m_routeHeading;

   return *this;
}

wf_int32
LocationUpdateInformation::getAltitude() const
{
   return m_altitude;
}

wf_uint16
LocationUpdateInformation::getHeading() const
{
   return m_heading;
}

GpsQualityEnum
LocationUpdateInformation::getGpsQuality() const
{
   return m_gpsQuality;
}

WGS84Coordinate
LocationUpdateInformation::getPosition() const
{
   return m_position;
}

wf_uint16
LocationUpdateInformation::getSpeed() const
{
   return m_speed;
}

WGS84Coordinate
LocationUpdateInformation::getRoutePosition() const
{
   return m_routePosition;
}

wf_uint16
LocationUpdateInformation::getRouteHeading() const
{
   return m_routeHeading;
}

} // End namespace WFAPI


text:
/* -*-C++-*-
 */
/*
 * Copyright 2016 EU Project ASAP 619706.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

#ifndef INCLUDED_ASAP_ARFF_H
#define INCLUDED_ASAP_ARFF_H

#include <stdexcept>
#include <cctype>
#include <cstdlib>
#include <array>

#include "asap/memory.h"
#include "asap/traits.h"
#include "asap/data_set.h"
#include "asap/word_count.h"

namespace asap {

struct NZDelim {
    bool operator () ( char c ) const {
	return ( c == ',' ) | ( c == ')' );
    }
};

struct IsAlnum {
    bool operator () ( char c ) const {
	return std::isalnum(c);
    }
};

struct NewLine {
    bool operator () ( char c ) const {
	return c == '\n';
    }
};

struct NonBlank {
    bool operator () ( char c ) const {
	return !std::isspace(c);
    }
};

namespace array {

// Skip all white-space (blank lines) as well as lines with comments
#if 1
void skip_blank_lines( char * & p, char * end ) {
    while( std::isspace(*p) )
	++p;
    while( *p == '%' ) {
	++p;
	while( *p != '\n' )
	    if( *p++ == '\0' )
		return;
	while( std::isspace(*p) )
	    ++p;
    }
}
#else
void skip_blank_lines( char * & p, char * end ) {
    if( (p = std::find_if( p, end, NonBlank() )) == end )
	return;
    while( *p == '%' ) {
	++p;
	if( (p = std::find_if( p, end, NewLine() )) == end )
	    return;
	++p;
	if( (p=std::find_if( p, end, NonBlank() )) == end )
	    return;
    }
}
#endif

// Update dense_vector
template<typename vector_type, typename = void>
class record_value {
    vector_type & vector;
    typename vector_type::index_type nexti;
public:
    record_value( vector_type & vector_ ) : vector( vector_ ), nexti( 0 ) { }

    void operator () ( typename vector_type::value_type v ) {
	assert( nexti < vector.length() ); // throw
	vector[nexti++] = v;
    }
    void operator () ( typename vector_type::index_type i,
		       typename vector_type::value_type v ) {
	assert( 0 <= i && i < vector.length() ); // throw
	vector[i] = v;
    }
};

// Update sparse_vector
template<typename vector_type>
class record_value<vector_type,
		   typename std::enable_if<is_sparse_vector<vector_type>::value>::type> {
    vector_type & vector;
    typename vector_type::index_type pos, idx;
public:
    record_value( vector_type & vector_ ) : vector( vector_ ), pos( 0 ), idx( 0 ) { }

    void operator () ( typename vector_type::value_type v ) {
	assert( pos < vector.length() ); // throw
	if( v > 0 )
	    vector.set( pos++, v, idx );
	++idx;
    }
    void operator () ( typename vector_type::index_type i,
		       typename vector_type::value_type v ) {
	assert( 0 <= i && i < vector.length() ); // throw
	if( v > 0 )
	    vector.set( pos++, v, i );
    }
};

template<typename vector_type>
bool
read_dense_vector( char *& p, char * end, vector_type & vector ) {
#define ADVANCE(pp) do { if( *(pp) == '\0' ) { return false; } ++pp; } while( 0 )
    // assert( *p != '[' );
    while( *p != '[' )
        ADVANCE( p );
    ADVANCE( p );
    record_value<vector_type> recorder( vector );
    do {
	while( std::isspace( *p ) )
	    ADVANCE( p );
	if( *p == '?' )
	    fatal( "missing data not supported" );
	typename vector_type::value_type v = 0;
#if REAL_IS_INT
	v = std::strtoul( p, &p, 10 );
#else
	v = std::strtod( p, &p );
#endif
	recorder( v );
	// while( std::isspace( *p ) && *p != '\n' )
	while( ( std::isspace( *p ) || *p == ',' || *p == ']' || *p == ')' ) && (*p != '\n') )
	    ADVANCE( p );
	while( std::isspace( *p ) && *p != '\n' )
	    ADVANCE( p );
    } while( *p != '\n' );
    return true;
#undef ADVANCE
}

template<typename vector_type>
bool
read_sparse_vector( char *& pref, char * end, vector_type & vector ) {
    // We will only be overwriting a few elements, so clear everything first
    if( is_dense_vector<vector_type>::value )
	vector.clear();

    record_value<vector_type> recorder( vector );

    char * p = pref;

    while( *p != '[' )
        ++p;

    assert( *p == '[' );
    ++p;
    while( std::isspace( *p ) )
	++p;
    do {
	typename vector_type::index_type i = std::strtoul( p, &p, 10 );
	while( std::isspace( *p ) || *p == ':' )
	    ++p;
	if( *p == ']' )
	    break;
	if( *p == '?' )
	    fatal( "missing data not supported" );
	typename vector_type::value_type vv = 0;
#if REAL_IS_INT
	vv = std::strtoul( p, &p, 10 );
#else
	vv = std::strtod( p, &p );
#endif
	// vector[i] = vv;
	recorder( i, vv );

	if( (p = std::find_if( p, end, NZDelim() )) == end ) {
	    pref = p;
	    return false;
	}
	if( *p == ')' )
	    break;
	++p;
	while( std::isspace( *p ) )
	    ++p;
    } while( *p != ')' ); // && *p != '\n' );
    ++p;
    pref = p;
    return true;
}

template<typename vector_type>
bool read_vector( char *& p, char * end, vector_type & vector ) {
    if( *p == '{' )
	return read_sparse_vector( p, end, vector );
    else
	return read_dense_vector( p, end, vector );
}

template<typename WordBankTy>
const char * read_relation( char *& p, WordBankTy & idx ) {
    while( std::isspace(*p) && *p != '\n' )
	++p;
    char * relation = p;
    if( *p == '\'' ) { // scan until closing quote
	++p;
	while( *p != '\'' ) {
	    if( *p == '\\' ) // skip next character
		++p;
	    if( *p == '\0' )
		return 0;
	    ++p;
	}
	// Skip closing quote
	++p;
    } else { // scan until space
	while( !std::isspace( *p ) ) {
	    if( *p == '\0' )
		return 0;
	    ++p;
	}
    }
    const char * stored
	= idx.memorize( relation, p-relation ); // Store relation, not indexed
    ++p; // delimiter replaced by '\0'
    return stored;
}

template<typename WordBankTy>
const char * read_attribute( char *& p, WordBankTy & idx ) {
    // Isolate token
    while( std::isspace( *p ) )
	++p;
    char * name = p;
    while( !std::isspace( *p ) )
	if( *p++ == '\0' )
	    return 0;
    const char * stored = idx.index( name, p-name ); // Store name in index
    ++p; // space replaced by '\0'

    // Isolate type
    while( std::isspace( *p ) )
	++p;
    char * type = p;
    while( !std::isspace( *p ) )
	if( *p++ == '\0' )
	    return 0;
    // Delineate end of data type by overwriting space
    *p++ = '\0';
    if( strcmp( type, "numeric" ) ) {
	std::cerr << "Warning: treating non-numeric attribute '"
		  << stored << "' of type '" << type << "' as numeric\n";
    }

    return stored; // ignoring type as we only consider numeric types ...
}
template<typename WordBankTy>
const char * read_column_header( char *& p, WordBankTy & idx ) {
    char * name = p;
    const char * stored = idx.index( name, p-name ); // Store name in index
    return stored; // ignoring type as we only consider numeric types ...
}

}

size_t count_lines( const char * p ) {
    size_t nlines = 0;
    while( *p ) {
	if( *p == '\n' )
	    ++nlines;
	++p;
    }
    return nlines;
}

size_t count_nonzeros( const char * p, const char * end ) {
    size_t nvalues = 0;
    ++p; // skip opening {
    const char * prevp = p;
    while( (p = std::find_if( p, end, NZDelim() )) != end ) {
	if( *p == ']' )
	    break;
	++p;
	++nvalues;
	prevp = p;
    }
    if( std::find_if( prevp, p, IsAlnum() ) != p )
	++nvalues;
    return nvalues;
}

size_t count_nonzeros_filtered( char * p, char * end ) {
    size_t nvalues = 0;

    while( *p != '[' )
        ++p;

    assert( *p == '[' );
    ++p;
    while( std::isspace( *p ) )
	++p;
    do {
	if( *p == ']' )
	    break;
#if REAL_IS_INT
	if( std::strtoul( p, &p, 10 ) )
	    ++nvalues;
#else
	if( std::strtod( p, &p ) )
	    ++nvalues;
#endif
	if( *p == ')' )
	    break;
	++p;
	while( std::isspace( *p ) )
	    ++p;
    } while( *p != ')' ); // && *p != '\n' );
    return nvalues;
}

std::pair<size_t,size_t> count_values( const char * p, const char * end ) {
    size_t npoints = 0;
    size_t nvalues = 0;

    const char * prevp = p;
    while( (p=std::find_if( p, end, NZDelim() )) != end ) {
	if( *p == ',' ) {
	    ++nvalues;
	}
	else if( *p == ']' ) {
	    ++npoints;
	    if( std::find_if( prevp, p, IsAlnum() ) != p )
		++nvalues;
	}
	++p;
	prevp = p;
    }

    return std::make_pair( npoints, nvalues );
}

template<typename VectorTy, typename Container>
typename std::enable_if<is_dense_vector<VectorTy>::value>::type
create_vector( Container & container, const char * p, const char * end,
	       size_t ndim ) {
    container.emplace_back( ndim );
}

template<typename VectorTy, typename Container>
typename std::enable_if<is_sparse_vector<VectorTy>::value>::type
create_vector( Container & container, const char * p, const char * end,
	       size_t ndim ) {
    container.emplace_back( ndim, count_nonzeros_filtered( (char *)p, (char *)end ) );
}

template<typename VectorTy, typename Container>
typename std::enable_if<is_dense_vector<VectorTy>::value>::type
init_vector( Container & container, const char * p, const char * end,
	     size_t ndim ) {
}

template<typename VectorTy, typename Container>
typename std::enable_if<is_sparse_vector<VectorTy>::value>::type
init_vector( Container & container, const char * p, const char * end,
	     size_t ndim ) {
    container.emplace_back( ndim, count_nonzeros_filtered( (char *)p, (char *)end ) );
}

// Basic implementation where vectors are individually allocated
template<typename DataSetTy>
typename std::enable_if<
    std::is_same<typename DataSetTy::vector_type::memory_mgmt_type, mm_ownership_policy>::value,
    DataSetTy>::type
array_read( const std::string & filename, bool &is_stored_sparse ) {
    typedef DataSetTy data_set_type;
    typedef typename data_set_type::vector_type vector_type;
    typedef typename data_set_type::index_list_type index_list_type;
    typedef typename vector_type::index_type index_type;
    typedef typename vector_type::value_type value_type;
    typedef index_list_type word_container_type;

    std::shared_ptr<index_list_type> idx = std::make_shared<index_list_type>();

    word_container_type &                 m_container = *idx;

    word_container_file_builder<index_list_type> idx_builder( filename, *idx );

    std::shared_ptr<std::vector<vector_type>> vec_ptr
	= std::make_shared<std::vector<vector_type>>();
    std::vector<vector_type> & vec = *vec_ptr;

    const char * relation = "undefined";
    bool is_sparse = false;

    // Now parse the data
    char * p = idx_builder.get_buffer();
    char * end = idx_builder.get_buffer_end();

    // Fudge fake id's as we don't care about them for ASAP workflow
    char labels[24][10];
    for(int i = 0; i < 24; ++i)
    {
        sprintf(labels[i],"%d",i+1);
    }
    for(auto text : labels) {   // Range-for!
       const char * stored = (*idx).index( text, strlen(text)+1 ); // Store name in index
    }
#define ADVANCE(pp) do { if( *(pp) == '\0' ) goto END_OF_FILE; ++pp; } while( 0 )
    do {
        array::skip_blank_lines( p, end );
        while( *p != '(' )
            ADVANCE( p );
        ADVANCE( p );

#ifdef IMR
            int ndim = 24;
#else
            int ndim = idx_builder.size();
#endif
            p += 4;

	    array::skip_blank_lines( p, end );

	    do {
		is_sparse |= *p == '{';
		// Create vector speculatively...
		create_vector<vector_type>( vec, p, end, ndim );
		if( !array::read_vector( p, end, vec.back() ) ) {
		    // Oops, no vector after all...
		    // This should happen at most once per file
		    vec.pop_back();
		}
		array::skip_blank_lines( p, end );
	    } while( *p != '\0' );
    } while( 1 );
#undef ADVANCE

END_OF_FILE:

    is_stored_sparse = is_sparse;
    return data_set_type( relation, idx, vec_ptr );

    is_stored_sparse = is_sparse;
    return data_set_type( relation, idx, vec_ptr );
}

#ifndef IMR
// Specialization for dense vectors without ownership. Ownership of the
// vector contents are referred to the data_set for efficiency reasons.
template<typename DataSetTy>
typename std::enable_if<
    std::is_same<typename DataSetTy::vector_type::memory_mgmt_type, mm_no_ownership_policy>::value,
    DataSetTy>::type
arff_read( const std::string & filename, bool &is_stored_sparse ) {
    typedef DataSetTy data_set_type;
    typedef typename data_set_type::vector_type vector_type;
    typedef typename data_set_type::index_list_type index_list_type;
    typedef typename vector_type::index_type index_type;
    typedef typename vector_type::value_type value_type;
    typedef typename data_set_type::vector_list_type vector_set_type;

    std::shared_ptr<index_list_type> idx = std::make_shared<index_list_type>();
    word_container_file_builder<index_list_type> idx_builder( filename, *idx );

    const char * relation = "undefined";
    bool is_sparse = false;

    // Now parse the data
    char * p = idx_builder.get_buffer();
    char * end = idx_builder.get_buffer_end();
#define ADVANCE(pp) do { if( *(pp) == '\0' ) goto END_OF_FILE; ++pp; } while( 0 )
    size_t num_points;
    do {
	arff::skip_blank_lines( p, end );
	while( *p != '@' )
	    ADVANCE( p );
	ADVANCE( p );
	if( !strncasecmp( p, "relation ", 9 ) ) {
	    p += 9;
	    if( !(relation = arff::read_relation( p, idx_builder.get_word_list() )) )
		fatal( "Incomplete relation specifier in input file '",
		       filename, "'" );
	} else if( !strncasecmp( p, "attribute ", 10 ) ) {
	    p += 10;
	    if( !arff::read_attribute( p, idx_builder.get_word_list() ) )
		fatal( "Incomplete attribute specifier in input file '",
		       filename, "'" );
	} else if( !strncasecmp( p, "data", 4 ) ) {
	    // From now on everything is data
	    int ndim = idx_builder.size();
	    p += 4;

	    arff::skip_blank_lines( p, end );

	    return [&]() -> data_set_type {
		// Estimate upper bound on space needed to store all vectors.
		// Assumptions:
		//   + At most one vector per line
		//   + Dense vectors, so fixed vector size
		std::pair<size_t,size_t> info = count_values(p, end);
		// size_t max_points = count_lines(p);
		size_t max_points = info.first;
		size_t max_values = info.second;
		std::shared_ptr<vector_set_type> dvs_ptr
		    = std::make_shared<vector_set_type>(
			max_points, is_sparse_vector<vector_type>::value ?
			max_values : ndim );
		vector_set_type & dvs = *dvs_ptr;
		dvs.clear(); // zero-init

		if( !max_points )
		    goto END_OF_FILE;

		num_points = 0;

		do {
		    is_sparse |= *p == '(';

		    assert( num_points < max_points );
		    init_vector<vector_type>( dvs, p, end, ndim );
		    if( !arff::read_vector( p, end, dvs[num_points++] ) ) {
			// Oops, no vector after all...
			// This should happen at most once per file.
			--num_points;
		    }
		    arff::skip_blank_lines( p, end );
		} while( *p != '\0' );
	    END_OF_FILE:
		dvs.trim_number( num_points );
		is_stored_sparse = is_sparse;
		return data_set_type( relation, idx, dvs_ptr );
	    }();
	}
    } while( 1 );
#undef ADVANCE

END_OF_FILE:

    is_stored_sparse = is_sparse;
    return data_set_type( relation, idx, std::make_shared<vector_set_type>( 0, 0 ) );
}
#endif

// Version for IMR input format to k-means, basic array format
// Specialization for dense vectors without ownership. Ownership of the
// vector contents are referred to the data_set for efficiency reasons.
template<typename DataSetTy>
typename std::enable_if<
    std::is_same<typename DataSetTy::vector_type::memory_mgmt_type, mm_no_ownership_policy>::value,
    DataSetTy>::type
array_read( std::string & filename, bool &is_stored_sparse ) {
    typedef DataSetTy data_set_type;
    typedef typename data_set_type::vector_type vector_type;
    typedef typename data_set_type::index_list_type index_list_type;
    typedef typename vector_type::index_type index_type;
    typedef typename vector_type::value_type value_type;
    typedef typename data_set_type::vector_list_type vector_set_type;

    std::shared_ptr<index_list_type> idx = std::make_shared<index_list_type>();
    word_container_file_builder<index_list_type> idx_builder( filename, *idx );

    const char * relation = "undefined";
    bool is_sparse = false;

    // Now parse the data
    char * p = idx_builder.get_buffer();
    char * end = idx_builder.get_buffer_end();
#define ADVANCE(pp) do { if( *(pp) == '\0' ) goto END_OF_FILE; ++pp; } while( 0 )
    size_t num_points;
    do {
	array::skip_blank_lines( p, end );
	while( *p != '(' )
	    ADVANCE( p );
	ADVANCE( p );
	    int ndim = idx_builder.size();
	    p += 4;

	    // array::skip_blank_lines( p, end );

	    return [&]() -> data_set_type {
		// Estimate upper bound on space needed to store all vectors.
		// Assumptions:
		//   + At most one vector per line
		//   + Dense vectors, so fixed vector size
		std::pair<size_t,size_t> info = count_values(p, end);
		// size_t max_points = count_lines(p);
		size_t max_points = info.first;
		size_t max_values = info.second;
		std::shared_ptr<vector_set_type> dvs_ptr
		    = std::make_shared<vector_set_type>(
			max_points, is_sparse_vector<vector_type>::value ?
			max_values : ndim );
		vector_set_type & dvs = *dvs_ptr;
		dvs.clear(); // zero-init

		if( !max_points )
		    goto END_OF_FILE;

		num_points = 0;

		do {
		    is_sparse |= *p == '(';

		    assert( num_points < max_points );
		    init_vector<vector_type>( dvs, p, end, ndim );
		    if( !array::read_vector( p, end, dvs[num_points++] ) ) {
			// Oops, no vector after all...
			// This should happen at most once per file.
			--num_points;
		    }
		    array::skip_blank_lines( p, end );
		} while( *p != '\0' );
	    END_OF_FILE:
		dvs.trim_number( num_points );
		is_stored_sparse = is_sparse;
		return data_set_type( relation, idx, dvs_ptr );
	    }();
    } while( 1 );
#undef ADVANCE

END_OF_FILE:

    is_stored_sparse = is_sparse;
    return data_set_type( relation, idx, std::make_shared<vector_set_type>( 0, 0 ) );
}

namespace arff {

template<typename Type>
const char * as_word( const Type & val ) {
    return val;
}

template<typename Type1, typename Type2>
const char * as_word( const std::pair<Type1,Type2> & val ) {
    return val.first;
}

template<typename Type>
const char * get_value( const Type & val ) {
    return "";
}

template<typename Type1, typename Type2>
const Type2 & get_value( const std::pair<Type1,Type2> & val ) {
    return val.second;
}

template<typename Type1, typename Type2>
std::ostream &
operator << ( std::ostream & os, const std::pair<Type1,Type2> & val ) {
    return os << as_word( val );
}

template<size_t N, typename Type2>
std::ostream &
operator << ( std::ostream & os,
	      const std::pair<asap::text::ngram<N>,Type2> & val ) {
    for( size_t i=0; i < N; ++i ) {
	os << as_word( val.first[i] );
	if( i < N-1 )
	    os << '#';
    }
    return os;
}

template<typename VectorIter, typename ColNameIter, typename RowNameIter>
void arff_write( std::ostream & of,
		 const char * const relation_name,
		 VectorIter vI, VectorIter vE,
		 ColNameIter cI, ColNameIter cE,
		 RowNameIter rI, RowNameIter rE ) {
    of << "@relation " << relation_name;

    for( auto I=cI; I != cE; ++I )
	of << "\n\t@attribute " << *I
	   << " numeric % value=" << get_value(*I);

    of << "\n\n@data";

    for( auto I=vI; I != vE; ++I, ++rI )
	of << "\n\t" << *I << " % " << *rI;

    of << std::endl;
}

};

template<typename DataSetTy>
void arff_write( std::ostream & os,
		 const DataSetTy & data_set ) {
    if( data_set.transpose() ) {
	arff::arff_write( os, data_set.get_relation(),
			  data_set.vector_cbegin(), data_set.vector_cend(),
			  data_set.index2_cbegin(), data_set.index2_cend(),
			  data_set.index_cbegin(), data_set.index_cend() );
    } else {
	arff::arff_write( os, data_set.get_relation(),
			  data_set.vector_cbegin(), data_set.vector_cend(),
			  data_set.index_cbegin(), data_set.index_cend(),
			  data_set.index2_cbegin(), data_set.index2_cend() );
    }
}

template<typename DataSetTy>
void arff_write( const std::string & filename,
		 const DataSetTy & data_set ) {
    if( !strcmp( filename.c_str(), "-" ) )
	arff_write( std::cout, data_set );
    else {
	std::ofstream of( filename, std::ios_base::out );
	arff_write( of, data_set );
	of.close();
    }
}

}

#endif // INCLUDED_ASAP_ARFF_H


text:
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

func main() {
	// runes are numbers
	letter := 'A'
	fmt.Println(letter)
	fmt.Printf("%T \n", letter)

	// string to rune conversion
	letter2 := rune("A"[0])
	fmt.Println(letter2)

	// string index access
	word := "Hello"
	letter3 := rune(word[0])
	fmt.Println(letter3)

	// remainder bucket selection
	for i := 65; i <= 122; i++ {
		fmt.Println(i, "-", string(i), "-", i%12)
	}

	// Hash Function
	n := HashBucket("Go", 12)
	fmt.Println(n)

	// Get Moby Dick
	res, err := http.Get("http://www.gutenberg.org/files/2701/old/moby10b.txt")
	if err != nil {
		log.Fatal(err)
	}

	page, err := ioutil.ReadAll(res.Body)
	res.Body.Close()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", page)
}

// HashBucket function for calculating hash of word
func HashBucket(word string, buckets int) int {
	letter := int(word[0])
	bucket := letter % buckets
	return bucket
}


text:
using FluentAssertions;
using ModelGenerator.Generator;
using ModelGenerator.Model;
using Ploeh.AutoFixture;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

namespace ModelGenerator.Tests
{
    public class TypescriptClassGeneratorTests
    {
        private readonly Fixture _fixture = new Fixture();

        [Theory]
        [InlineData(OutputMode.Details), InlineData(OutputMode.Create), InlineData(OutputMode.Summary), InlineData(OutputMode.Update), InlineData(OutputMode.Model)]
        public void ModelShouldCreateClass(OutputMode mode)
        {
            var versionNumber = typeof(Generator.Typescript.ClassGenerator).Assembly.GetName().Version.ToString(3);
            var generator = new Generator.Typescript.ClassGenerator(mode);

            var testModel = new Class
            {
                Name = _fixture.Create<string>(),
                Properties = new List<Property>()
            };

            var output = new StringBuilder();

            generator.CreateClass(testModel, output);

            var result = output.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
                .Select(s => s.Trim()).ToList();

            result.Should().Contain($"export interface I{HelperClasses.GetName(testModel.Name, mode)} {{");
            result.Should().Contain($"// Model Generator v{versionNumber}");
        }
    }
}


text:
from datetime import datetime, timedelta
from deap import algorithms
from deap import base
from deap import creator
from deap import tools
from tabulate import tabulate

import random
import numpy

# Hard coded probabilities and generations
CXPB, MUTPB, NGEN = 0.5, 0.2, 50

# Create your models here.
class extGenOptimizer():
    def __init__(self):
        random.seed(128)
        numpy.random.seed(128)

        # Constant variables
        self.examSubjectDuration = timedelta(hours=1) # hour
        # 1 Hour per subject, will be a variable in the future
        # Kept constant initially for simplicity

        # Initializing optimizer
        creator.create("FitnessMax", base.Fitness, weights=(1.0,))
        creator.create("Individual", numpy.ndarray, fitness=creator.FitnessMax)

        self.toolbox = base.Toolbox()

        self.toolbox.register("individual", self.initExamTimetableGenome)
        self.toolbox.register(
            "population", tools.initRepeat, list, self.toolbox.individual)

        self.toolbox.register("evaluate", self.evalExamTimetableGenome)
        self.toolbox.register("mate", self.mateExamTimetableGenome)
        self.toolbox.register(
            "mutate", self.mutateExamTimetableGenome, indpb=0.05)
        self.toolbox.register("select", tools.selTournament, tournsize=3)

    # Exam Timetable Genome format: Numpy 2D array
    # Column 0: TimeTable order. Length = Number of subjects
    # Column 1: Rest revision after that subject
    # Last subject exam always have zero revision time as exams are done
    def initExamTimetableGenome(self):
        examTimetableGenome = numpy.zeros([self.subjectLookUpLen, 2])
        examTimetableGenome[:, 0] = range(len(self.subjectLookUp))
        totalRevisionTime = 0
        for idx in range(self.subjectLookUpLen-1):
            tmpRestTime = random.randint(0, self.maxRevisionTime)
            totalRevisionTime = totalRevisionTime + tmpRestTime
            if totalRevisionTime < self.maxRevisionTime:
                examTimetableGenome[idx, 1] = tmpRestTime
            elif totalRevisionTime == self.maxRevisionTime:
                examTimetableGenome[idx, 1] = tmpRestTime
                break
            else:
                examTimetableGenome[idx, 1] = \
                    self.maxRevisionTime - (totalRevisionTime - tmpRestTime)
                break
        if totalRevisionTime < self.maxRevisionTime:
            examTimetableGenome[self.subjectLookUpLen - 2, 1] = \
                examTimetableGenome[self.subjectLookUpLen - 2, 1] + \
                self.maxRevisionTime - totalRevisionTime
        numpy.random.shuffle(examTimetableGenome[:, 0])
        individual = creator.Individual(examTimetableGenome)
        return individual

    # Gets each subject's start time and end time base on revision time
    # Schedule format:
    # idx = 0: subject name
    # idx = 1: start time
    # idx = 2: end time
    # Fixed duration (i.e 1 hour) (self.examSubjectDuration)
    def getSchedule(self, individual):
        schedule = []
        timeSlotCounter = 0
        for idx in range(0, self.subjectLookUpLen):
            if idx == 0:
                startTime = self.timeSlots[0][0]
            else:
                revisionTime = timedelta(hours=individual[idx-1][1])
                startTime = lastEndTime + revisionTime
            endTime = startTime + self.examSubjectDuration

            if endTime > self.timeSlots[timeSlotCounter][1]:
                extraRevisionTime = startTime - \
                    self.timeSlots[timeSlotCounter][1]
                while True:
                    timeSlotCounter = timeSlotCounter + 1
                    timeSlotStart = self.timeSlots[timeSlotCounter][0]
                    timeSlotEnd = self.timeSlots[timeSlotCounter][1]
                    timeSlotDuration = timeSlotEnd - timeSlotStart
                    if timeSlotDuration <= extraRevisionTime:
                        if timeSlotCounter >= len(self.timeSlots):
                            print 'fail'
                            return 0 # Punishment
                        else:
                            extraRevisionTime = extraRevisionTime - \
                                timeSlotDuration
                    else:
                        startTime = timeSlotStart + extraRevisionTime
                        endTime = startTime + self.examSubjectDuration
                        break
            lastEndTime = endTime
            schedule.append([
                    self.subjectLookUp[int(individual[idx][0])],
                    startTime,
                    endTime
                    ])
        return schedule

    # Gets all the revision time based on the student's examination list
    # and the exam schedule generated
    def getRevisionTimeFromSchedule(self, record, schedule):
        revisionTimeArray = []
        firstSubjectExamined = False
        studentSubjectList = record[1:]
        for idx in range(0, self.subjectLookUpLen):
            if self.subjectLookUp[idx] in studentSubjectList:
                if firstSubjectExamined:
                    revisionTimeArray.append(
                        (schedule[idx][1] - lastEndTime).total_seconds()
                        / 3600)
                    lastEndTime = schedule[idx][2]
                else:
                    firstSubjectExamined = True
                    lastEndTime = schedule[idx][2]
        if len(revisionTimeArray) == 0:
            return [float('inf')]
        else:
            return revisionTimeArray

    # Generate schedule base on order and revision time
    # For each student, sum up their revision time
    # Average all student's revision time
    def evalExamTimetableGenome(self, individual):
        schedule = self.getSchedule(individual)
        minRevisionTime = float('inf')
        for student in self.studentRecord:
            tmpRevisionTime = self.getRevisionTimeFromSchedule(student,
                                                               schedule)
            if min(tmpRevisionTime) < minRevisionTime:
                minRevisionTime = min(tmpRevisionTime)
        return minRevisionTime, # Comma is important

    # Copy child 1 and 2 as individual 1 and 2
    # Take two points
    # Extract a section from individual1
    # Remove the elements from in the section from child 2
    # and add section at beginning of child 2
    # Same procedure for individual 2 and child 1
    def mateExamTimetableGenome(self, individual1, individual2):
        child1 = individual1
        child2 = individual2

        cxpoint1 = random.randint(0, self.subjectLookUpLen-1)
        cxpoint2 = random.randint(0, self.subjectLookUpLen-1)

        if cxpoint1 == cxpoint2:
            return (child1, child2)
        elif cxpoint1 > cxpoint2:
            tmp = cxpoint1
            cxpoint1 = cxpoint2
            cxpoint2 = tmp

        tmpList1 = list(individual1[:, 0])
        tmpSection1 = list(individual1[cxpoint1: cxpoint2, 0])

        tmpList2 = list(individual2[:, 0])
        tmpSection2 = list(individual2[cxpoint1: cxpoint2, 0])

        for item in tmpSection2:
            tmpList1.remove(item)
        child1[:, 0] = tmpSection2 + tmpList1

        for item in tmpSection1:
            tmpList2.remove(item)
        child2[:, 0] = tmpSection1 + tmpList2

        return (child1, child2)

    # Find two random indices and swap two subjects
    # Find two random indices and swap two revision times, last one is fixed
    def mutateExamTimetableGenome(self, individual, indpb):
        # Swap two subjects
        cxpoint1 = random.randint(0, self.subjectLookUpLen-1)
        cxpoint2 = random.randint(0, self.subjectLookUpLen-1)

        tmp = individual[cxpoint1, 0]
        individual[cxpoint1, 0] = individual[cxpoint2, 0]
        individual[cxpoint1, 0] = tmp

        # Swap two revision time, last one fixed, not allowed for swapping
        cxpoint1 = random.randint(0, self.subjectLookUpLen-2)
        cxpoint2 = random.randint(0, self.subjectLookUpLen-2)

        tmp = individual[cxpoint1, 1]
        individual[cxpoint1, 1] = individual[cxpoint2, 1]
        individual[cxpoint1, 1] = tmp

        # For the two rest times, mutate their times by +/- 1
        if individual[cxpoint1, 1] > 0:
            individual[cxpoint1, 1] = individual[cxpoint1, 1] - 1
            individual[cxpoint2, 1] = individual[cxpoint2, 1] + 1
        elif individual[cxpoint2, 1] > 0:
            individual[cxpoint2, 1] = individual[cxpoint2, 1] - 1
            individual[cxpoint1, 1] = individual[cxpoint1, 1] + 1

        return individual

    # Print results including all information
    def printResult(self, individual):
        result = [['Subject', 'Revision Time', 'Start Time', 'End Time'],
                  ['-'*20] * 4]
        schedule = self.getSchedule(individual)
        for idx in range(self.subjectLookUpLen):
            tmp = []
            tmp.append(self.subjectLookUp[int(individual[idx][0])])
            if idx < self.subjectLookUpLen -1:
                tmp.append((schedule[idx+1][1]-schedule[idx][2])
                           .total_seconds() / 3600)
            else:
                tmp.append(0)
            tmp.append(schedule[idx][1])
            tmp.append(schedule[idx][2])
            result.append(tmp)
        print tabulate(result)
        obj1 = self.evalExamTimetableGenome(individual)
        print "Min Revision Time = %f" % (obj1)

    # Run otpimizer
    def run(self, verbose = False):
        # Data validation

        # Data formation
        # All subjects are assumed to last for an hour for simplicity
        # This constraint will be opened up later on
        self.subjectLookUp = []
        for student in self.studentRecord:
            for subject in student[1:]:
                if subject not in self.subjectLookUp:
                    self.subjectLookUp.append(subject)
        self.subjectLookUpLen = len(self.subjectLookUp)
        # Calculate total number of hours
        self.totalNumHours = 0
        for ts in self.timeSlots:
            # Integer division, rounded down
            self.totalNumHours += (ts[1] - ts[0]).seconds / 3600
        self.maxRevisionTime = self.totalNumHours - len(self.subjectLookUp) * 1

        pop = self.toolbox.population(n=300)

        if verbose:
            print("Start of evolution")

        # Evaluate the entire population
        fitnesses = list(map(self.toolbox.evaluate, pop))
        for ind, fit in zip(pop, fitnesses):
            ind.fitness.values = fit

        if verbose:
            print("  Evaluated %i individuals" % len(pop))

        # Begin the evolution
        for g in range(NGEN):
            if verbose:
                print("-- Generation %i --" % g)

            # Select the next generation individuals
            offspring = self.toolbox.select(pop, len(pop))
            # Clone the selected individuals
            offspring = list(map(self.toolbox.clone, offspring))

            # Apply crossover and mutation on the offspring
            for child1, child2 in zip(offspring[::2], offspring[1::2]):
                if random.random() < CXPB:
                    self.toolbox.mate(child1, child2)
                    del child1.fitness.values
                    del child2.fitness.values

            for mutant in offspring:
                if random.random() < MUTPB:
                    self.toolbox.mutate(mutant)
                    del mutant.fitness.values

            # Evaluate the individuals with an invalid fitness
            invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
            fitnesses = map(self.toolbox.evaluate, invalid_ind)
            for ind, fit in zip(invalid_ind, fitnesses):
                ind.fitness.values = fit

            if verbose:
                print("  Evaluated %i individuals" % len(invalid_ind))

            # The population is entirely replaced by the offspring
            pop[:] = offspring

            if verbose:
                # Gather all the fitnesses in one list and print the stats
                fits = [ind.fitness.values[0] for ind in pop]

                length = len(pop)
                mean = sum(fits) / length
                sum2 = sum(x*x for x in fits)
                std = abs(sum2 / length - mean**2)**0.5

                print("  Min %s" % min(fits))
                print("  Max %s" % max(fits))
                print("  Avg %s" % mean)
                print("  Std %s" % std)

                print("-- End of (successful) evolution --")

        self.best_ind = tools.selBest(pop, 1)[0]
        if verbose:
            self.printResult(self.best_ind)
        return self.getSchedule(self.best_ind)

if __name__ == "__main__":
    t = extGenOptimizer()
    t.timeSlots = [
        [datetime(2015, 11, 11, 9), datetime(2015, 11, 11, 12)],
        [datetime(2015, 11, 12, 9), datetime(2015, 11, 12, 12)],
        [datetime(2015, 11, 14, 9), datetime(2015, 11, 14, 12)],
        ]
    t.studentRecord = [
        ["A", "Chinese", "English"],
        ["B", "Chinese", "English", "Math"],
        ["C", "Chinese", "English", "Math"],
        ]
    t.run(verbose=True)


text:
package org.elasticsearch.xpack.core.security.action.rolemapping;

import org.elasticsearch.Version;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.xpack.core.security.authc.support.mapper.ExpressionRoleMapping;
import org.elasticsearch.xpack.core.security.authc.support.mapper.TemplateRoleName;
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.ExpressionParser;
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.RoleMapperExpression;
import org.elasticsearch.xpack.core.security.support.MetadataUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.action.ValidateActions.addValidationError;

/**
 * Request object for adding/updating a role-mapping to the native store
 *
 * see org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore
 */
public class PutRoleMappingRequest extends ActionRequest implements WriteRequest<PutRoleMappingRequest> {

    private String name = null;
    private boolean enabled = true;
    private List<String> roles = Collections.emptyList();
    private List<TemplateRoleName> roleTemplates = Collections.emptyList();
    private RoleMapperExpression rules = null;
    private Map<String, Object> metadata = Collections.emptyMap();
    private RefreshPolicy refreshPolicy = RefreshPolicy.IMMEDIATE;

    public PutRoleMappingRequest(StreamInput in) throws IOException {
        super(in);
        this.name = in.readString();
        this.enabled = in.readBoolean();
        this.roles = in.readStringList();
        if (in.getVersion().onOrAfter(Version.V_7_2_0)) {
            this.roleTemplates = in.readList(TemplateRoleName::new);
        }
        this.rules = ExpressionParser.readExpression(in);
        this.metadata = in.readMap();
        this.refreshPolicy = RefreshPolicy.readFrom(in);
    }

    public PutRoleMappingRequest() {}

    @Override
    public ActionRequestValidationException validate() {
        ActionRequestValidationException validationException = null;
        if (name == null) {
            validationException = addValidationError("role-mapping name is missing", validationException);
        }
        if (roles.isEmpty() && roleTemplates.isEmpty()) {
            validationException = addValidationError("role-mapping roles or role-templates are missing", validationException);
        }
        if (roles.size() > 0 && roleTemplates.size() > 0) {
            validationException = addValidationError("role-mapping cannot have both roles and role-templates", validationException);
        }
        if (rules == null) {
            validationException = addValidationError("role-mapping rules are missing", validationException);
        }
        if (MetadataUtils.containsReservedMetadata(metadata)) {
            validationException = addValidationError(
                "metadata keys may not start with [" + MetadataUtils.RESERVED_PREFIX + "]",
                validationException
            );
        }
        return validationException;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public List<String> getRoles() {
        return Collections.unmodifiableList(roles);
    }

    public List<TemplateRoleName> getRoleTemplates() {
        return Collections.unmodifiableList(roleTemplates);
    }

    public void setRoles(List<String> roles) {
        this.roles = new ArrayList<>(roles);
    }

    public void setRoleTemplates(List<TemplateRoleName> templates) {
        this.roleTemplates = new ArrayList<>(templates);
    }

    public RoleMapperExpression getRules() {
        return rules;
    }

    public void setRules(RoleMapperExpression expression) {
        this.rules = expression;
    }

    @Override
    public PutRoleMappingRequest setRefreshPolicy(RefreshPolicy refreshPolicy) {
        this.refreshPolicy = refreshPolicy;
        return this;
    }

    /**
     * Should this request trigger a refresh ({@linkplain RefreshPolicy#IMMEDIATE}, the default),
     * wait for a refresh ({@linkplain RefreshPolicy#WAIT_UNTIL}), or proceed ignore refreshes
     * entirely ({@linkplain RefreshPolicy#NONE}).
     */
    @Override
    public RefreshPolicy getRefreshPolicy() {
        return refreshPolicy;
    }

    public void setMetadata(Map<String, Object> metadata) {
        this.metadata = Objects.requireNonNull(metadata);
    }

    public Map<String, Object> getMetadata() {
        return metadata;
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        super.writeTo(out);
        out.writeString(name);
        out.writeBoolean(enabled);
        out.writeStringCollection(roles);
        if (out.getVersion().onOrAfter(Version.V_7_2_0)) {
            out.writeList(roleTemplates);
        }
        ExpressionParser.writeExpression(rules, out);
        out.writeMap(metadata);
        refreshPolicy.writeTo(out);
    }

    public ExpressionRoleMapping getMapping() {
        return new ExpressionRoleMapping(name, rules, roles, roleTemplates, metadata, enabled);
    }
}