<commit_before>#include <async>

#include <memory>

#define likely(x)       __builtin_expect(!!(x), 1)
#define unlikely(x)     __builtin_expect(!!(x), 0)

void Async::upload_file(
    Disk          disk,
    const Dirent& ent,
    Connection    conn,
    on_after_func callback,
    const size_t  CHUNK_SIZE)
{
  disk_transfer(disk, ent,
  [conn, callback, CHUNK_SIZE] (fs::buffer_t buffer,
                                size_t       length,
                                next_func    next)
  {
    // write chunk to TCP connection
    conn->write(buffer.get(), length,
    [callback, CHUNK_SIZE, next] (size_t n) {

      // if all data written, go to next chunk
      next(n == CHUNK_SIZE);

    }, true);

  }, callback, CHUNK_SIZE);
}

void Async::disk_transfer(
    Disk          disk,
    const Dirent& ent,
    on_write_func write_func,
    on_after_func callback,
    const size_t  CHUNK_SIZE)
{
  typedef std::function<void(size_t)> next_func_t;
  auto next = std::make_shared<next_func_t> ();

  *next =
  [next, disk, ent, write_func, callback, CHUNK_SIZE] (size_t pos) {

    // number of write calls necessary
    const size_t writes = ent.size() / CHUNK_SIZE;

    // done condition
    if (pos >= writes) {
      callback(fs::no_error, true);
      return;
    }

    // read chunk from file
    disk->fs().read(ent, pos * CHUNK_SIZE, CHUNK_SIZE,
    [next, pos, write_func, callback, CHUNK_SIZE] (
        fs::error_t  err,
        fs::buffer_t buffer,
        uint64_t     length)
    {
      if (err) {
        printf("%s\n", err.to_string().c_str());
        callback(err, false);
        return;
      }

      // call write callback with data
      write_func(buffer, length,
      [next, pos, callback] (bool good) {
        // if the write succeeded, call next
        if (likely(good))
          (*next)(pos+1);
        else
          // otherwise, fail
          callback(fs::no_error, false);
      });
    });

  };
  // start async loop
  (*next)(0);
}
<commit_msg>async: Fix missing error for write failed<commit_after>#include <async>

#include <memory>

#define likely(x)       __builtin_expect(!!(x), 1)
#define unlikely(x)     __builtin_expect(!!(x), 0)

void Async::upload_file(
    Disk          disk,
    const Dirent& ent,
    Connection    conn,
    on_after_func callback,
    const size_t  CHUNK_SIZE)
{
  disk_transfer(disk, ent,
  [conn, CHUNK_SIZE] (fs::buffer_t buffer,
                      size_t       length,
                      next_func    next)
  {
    // write chunk to TCP connection
    conn->write(buffer.get(), length,
    [CHUNK_SIZE, next] (size_t n) {

      // if all data written, go to next chunk
      next(n == CHUNK_SIZE);

    }, true);

  }, callback, CHUNK_SIZE);
}

void Async::disk_transfer(
    Disk          disk,
    const Dirent& ent,
    on_write_func write_func,
    on_after_func callback,
    const size_t  CHUNK_SIZE)
{
  typedef std::function<void(size_t)> next_func_t;
  auto next = std::make_shared<next_func_t> ();

  *next =
  [next, disk, ent, write_func, callback, CHUNK_SIZE] (size_t pos) {

    // number of write calls necessary
    const size_t writes = ent.size() / CHUNK_SIZE;

    // done condition
    if (pos >= writes) {
      callback(fs::no_error, true);
      return;
    }

    // read chunk from file
    disk->fs().read(ent, pos * CHUNK_SIZE, CHUNK_SIZE,
    [next, pos, write_func, callback, CHUNK_SIZE] (
        fs::error_t  err,
        fs::buffer_t buffer,
        uint64_t     length)
    {
      if (err) {
        printf("%s\n", err.to_string().c_str());
        callback(err, false);
        return;
      }

      // call write callback with data
      write_func(buffer, length,
      [next, pos, callback] (bool good) {
        // if the write succeeded, call next
        if (likely(good))
          (*next)(pos+1);
        else
          // otherwise, fail
          callback({fs::error_t::E_IO, "Write failed"}, false);
      });
    });

  };
  // start async loop
  (*next)(0);
}
<|endoftext|>


<commit_before>#include "TextRenderer.h"
#include "NonLeafTag.h"
#include <iostream>

TextRenderer::TextRenderer(SDL_Renderer *r, int w, int h)
{
	dx = 10;
	dy = 10;

	x_pos = dx;
	y_pos = dy;

	renderer = r;

	//SET Url bar params
	url_bar.x = 0;
	url_bar.y = 0;
	url_bar.w = screen_w;
	url_bar.h = screen_h  / 8;

	//SET links bar params

	int box_length = 200;

	links_bar.x = screen_w - box_length ;
	links_bar.y = screen_h - box_length ;
	links_bar.w = box_length;
	links_bar.h = box_length;

	surface_table = new std::vector<SmartTexture*>();
	first_words   = new std::vector<SmartTexture*>();

	int img_flags = IMG_INIT_PNG;

	if( !(IMG_Init(img_flags) & img_flags)){
		SDL_LogCritical(SDL_LOG_CATEGORY_ERROR , "Failed to initialize SDL Image: %s\n", SDL_GetError());
	} else{

		SDL_Log("Initialized SDL_Image\n");
	}

	if( TTF_Init() == -1){
		SDL_LogCritical( SDL_LOG_CATEGORY_ERROR , "Failed to initialize SDL TTF %s\n", SDL_GetError());
	} else{
		SDL_Log("Initialized SDL_TTF");
	}

	// Initialize fonts here
	font1 = TTF_OpenFont("OpenSans-Bold.ttf", font1_size);
	font2 = TTF_OpenFont("OpenSans-Bold.ttf", font2_size);
	if(font1 != NULL){
		SDL_Log("Font1 loaded");
	}
	if(font2 != NULL){
		SDL_Log("Font2 loaded");
	}

	// Set log file
	logfile.open("render-info.txt");

	// TEST
	//

	//color gets flipped
	SDL_Color black = {0x00, 0x00, 0x00};
	SDL_Color red   = {0xFF, 0x00, 0x00};

	SDL_Surface *textSurface = TTF_RenderText_Blended(font2, "Hello, World", col_green);

	SDL_Surface *textSurface2 = TTF_RenderText_Blended(font1, "here it is", red);
	if( textSurface == NULL ){

		SDL_Log( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() );
	}

	texture  = SDL_CreateTextureFromSurface( renderer, textSurface );
	texture2 = SDL_CreateTextureFromSurface( renderer, textSurface2);
	img_w = textSurface->w;
	img_h = textSurface->h;

	img_w2 = textSurface2->w;
	img_h2 = textSurface2->h;

}

/*
 * extract rendering information from the tree here
 */
void TextRenderer::walkTree(Tag *root)
{
	SDL_Surface *textSurface;
	SDL_Texture *curTexture;
	std::vector<Tag*> *children = root->getChildren();

	enum font_type{
		HEADING,
		REGULAR,
		LINK
	};

	int cur_w;
	int cur_h;

	font_type cur_type;

	/*
	 * Loop invariant: text holds the current internal node's
	 * text children
	 */
	for(std::vector<Tag*>::iterator it = children->begin();
			it != children->end();
			++it){
		NonLeafTag *cur = (NonLeafTag *)*it;
		std::vector<std::string> text = cur->getTextChildren();

		std::string cur_node_type = (*it)->getType();
		if(cur_node_type == "HEADING"){
			cur_type = HEADING;
		}

		else if(cur_node_type == "PARA"){
			cur_type = REGULAR;
		}

		else if(cur_node_type == "LINK"){
			cur_type = LINK;
		}
		else continue;

		for(std::vector<std::string>::iterator ut = text.begin();
				ut != text.end();
				++ut){
			std::string cur_text = *ut;
			cur_text.append(" ");
			if(cur_type == HEADING){
				textSurface = TTF_RenderText_Blended(font2, cur_text.c_str(), col_mag);
			}
			else if(cur_type == REGULAR){
				textSurface = TTF_RenderText_Blended(font1, cur_text.c_str(), col_green);
			}

			else{
				textSurface = TTF_RenderText_Blended(font1, cur_text.c_str(), col_blue);
			}

			cur_w = textSurface->w;
			cur_h = textSurface->h;

			curTexture = SDL_CreateTextureFromSurface(renderer , textSurface);
			surface_table->push_back(new SmartTexture(cur_w, cur_h, curTexture , false, cur_text ));
			}

		const char *blank = "BLANK TEXT\n";
		textSurface = TTF_RenderText_Blended(font2, blank, col_blank);
		curTexture= SDL_CreateTextureFromSurface(renderer, textSurface );
		cur_w = textSurface->w;
		cur_h = textSurface->h;

		surface_table->push_back(new SmartTexture(cur_w, cur_h, curTexture, true, "BLANK"));

	}

		/* Setup all the important stuff */
		int position = 0;

		setupDoc();
}

/*
 * This gets called when a page is first created.
 *
 *
 */
void TextRenderer::setupDoc()
{
	x_pos = dx;
	y_pos = dy;

	int cur_w ;
	int cur_h ;

	for(std::vector<SmartTexture*>::iterator it = surface_table->begin();
			it != surface_table->end();
			++it
			){
	if(x_pos == dx){
			first_words->push_back(*it);
		}

	if(!(*it)->is_break()){

			cur_w = (*it)->getWidth();
			cur_h = (*it)->getHeight();

			if(x_pos + cur_w  < screen_w - dx){

				log_render_info(*it, x_pos, y_pos);
				x_pos += cur_w;

			}
			else{
				x_pos = dx;
				y_pos += cur_h;

				log_render_info(*it, x_pos, y_pos);

				x_pos += cur_w;
			}

		}

		//new line
		else{
			cur_h = (*it)->getHeight();
			x_pos = dx;
			y_pos += dy + cur_h;

			log_render_info(*it, x_pos, y_pos);
		}

	}

	doc_head = first_words->begin();
}

void TextRenderer::log_render_info(SmartTexture *s, int x, int y)
{

	logfile << "Rendering " << s->getWord() << " at x: " << x << " , y: " << y << std::endl;
}

void TextRenderer::printFirstWords()
{
	for(std::vector<SmartTexture*>::iterator it = first_words->begin();
			it != first_words->end();
			++it){

		std::cout << (*it)->getWord() << std::endl;

	}

}

/*
 * Gets called ny main
 */
void TextRenderer::renderCall()
{

	if(cur_mode ==  LR_DEFAULT ){
		renderPage();
	}

	else if(cur_mode == LR_URL){
		SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0xFF, 0x00);
		SDL_RenderFillRect(renderer, &url_bar);
	}

	else if(cur_mode == LR_LINKS){
		SDL_SetRenderDrawColor(renderer, 0x00, 0x80, 0xFF, 0x00);
		SDL_RenderFillRect(renderer, &links_bar);

	}

}

void TextRenderer::renderPage()
{
	x_pos = dx;
	y_pos = dy;

	int cur_w ;
	int cur_h ;

	std::vector<SmartTexture*>::iterator it = surface_table->begin();
	for(;
			it != surface_table->end();
			++it){

		if(*it == *doc_head )
			break;

	}

	/*
	 * Need to do a search with the iterators
	 *
	 */

	for(;
			it != surface_table->end();
			++it
			){

	if(!(*it)->is_break()){

			cur_w = (*it)->getWidth();
			cur_h = (*it)->getHeight();

			if(x_pos + cur_w  < screen_w - dx){

				SDL_Rect curRect = {x_pos, y_pos, cur_w, cur_h};

				SDL_RenderCopyEx(renderer, (*it)->getTexture(), NULL, &curRect, 0.0, NULL, SDL_FLIP_NONE);

				x_pos += cur_w;

			}
			else{
				x_pos = dx;
				y_pos += cur_h;

				SDL_Rect curRect = {x_pos, y_pos, cur_w, cur_h};
				SDL_RenderCopyEx(renderer, (*it)->getTexture(), NULL, &curRect, 0.0, NULL, SDL_FLIP_NONE);

				x_pos += cur_w;
			}

		}

		//new line
		else{
			cur_h = (*it)->getHeight();
			x_pos = dx;
			y_pos += dy + cur_h;

			log_render_info(*it, x_pos, y_pos);
		}

	}
}

/*
 * TODO: check that these can't be crashed!
 *
 */
void TextRenderer::shiftDown()
{
	// check for valid position
	if(position + 1 < surface_table->size() - 1){
		position += 1;
		doc_head++;

	}
}

void TextRenderer::shiftUp()
{
	if(position - 1 >= 0){
		position -= 1;
		doc_head--;
	}
}

void TextRenderer::setMode(LR_MODE mode)
{
	cur_mode = mode;
}

<commit_msg>cant get rects to show<commit_after>#include "TextRenderer.h"
#include "NonLeafTag.h"
#include <iostream>

TextRenderer::TextRenderer(SDL_Renderer *r, int w, int h)
{
	dx = 10;
	dy = 10;

	x_pos = dx;
	y_pos = dy;

	renderer = r;

	//SET Url bar params
	url_bar.x = 0;
	url_bar.y = 0;
	url_bar.w = screen_w;
	url_bar.h = screen_h  / 8;

	//SET links bar params

	int box_length = 200;

	links_bar.x = screen_w - box_length ;
	links_bar.y = screen_h - box_length ;
	links_bar.w = box_length;
	links_bar.h = box_length;

	surface_table = new std::vector<SmartTexture*>();
	first_words   = new std::vector<SmartTexture*>();

	int img_flags = IMG_INIT_PNG;

	if( !(IMG_Init(img_flags) & img_flags)){
		SDL_LogCritical(SDL_LOG_CATEGORY_ERROR , "Failed to initialize SDL Image: %s\n", SDL_GetError());
	} else{

		SDL_Log("Initialized SDL_Image\n");
	}

	if( TTF_Init() == -1){
		SDL_LogCritical( SDL_LOG_CATEGORY_ERROR , "Failed to initialize SDL TTF %s\n", SDL_GetError());
	} else{
		SDL_Log("Initialized SDL_TTF");
	}

	// Initialize fonts here
	font1 = TTF_OpenFont("OpenSans-Bold.ttf", font1_size);
	font2 = TTF_OpenFont("OpenSans-Bold.ttf", font2_size);
	if(font1 != NULL){
		SDL_Log("Font1 loaded");
	}
	if(font2 != NULL){
		SDL_Log("Font2 loaded");
	}

	// Set log file
	logfile.open("render-info.txt");

	// TEST
	//

	//color gets flipped
	SDL_Color black = {0x00, 0x00, 0x00};
	SDL_Color red   = {0xFF, 0x00, 0x00};

	SDL_Surface *textSurface = TTF_RenderText_Blended(font2, "Hello, World", col_green);

	SDL_Surface *textSurface2 = TTF_RenderText_Blended(font1, "here it is", red);
	if( textSurface == NULL ){

		SDL_Log( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() );
	}

	texture  = SDL_CreateTextureFromSurface( renderer, textSurface );
	texture2 = SDL_CreateTextureFromSurface( renderer, textSurface2);
	img_w = textSurface->w;
	img_h = textSurface->h;

	img_w2 = textSurface2->w;
	img_h2 = textSurface2->h;

}

/*
 * extract rendering information from the tree here
 */
void TextRenderer::walkTree(Tag *root)
{
	SDL_Surface *textSurface;
	SDL_Texture *curTexture;
	std::vector<Tag*> *children = root->getChildren();

	enum font_type{
		HEADING,
		REGULAR,
		LINK
	};

	int cur_w;
	int cur_h;

	font_type cur_type;

	/*
	 * Loop invariant: text holds the current internal node's
	 * text children
	 */
	for(std::vector<Tag*>::iterator it = children->begin();
			it != children->end();
			++it){
		NonLeafTag *cur = (NonLeafTag *)*it;
		std::vector<std::string> text = cur->getTextChildren();

		std::string cur_node_type = (*it)->getType();
		if(cur_node_type == "HEADING"){
			cur_type = HEADING;
		}

		else if(cur_node_type == "PARA"){
			cur_type = REGULAR;
		}

		else if(cur_node_type == "LINK"){
			cur_type = LINK;
		}
		else continue;

		for(std::vector<std::string>::iterator ut = text.begin();
				ut != text.end();
				++ut){
			std::string cur_text = *ut;
			cur_text.append(" ");
			if(cur_type == HEADING){
				textSurface = TTF_RenderText_Blended(font2, cur_text.c_str(), col_mag);
			}
			else if(cur_type == REGULAR){
				textSurface = TTF_RenderText_Blended(font1, cur_text.c_str(), col_green);
			}

			else{
				textSurface = TTF_RenderText_Blended(font1, cur_text.c_str(), col_blue);
			}

			cur_w = textSurface->w;
			cur_h = textSurface->h;

			curTexture = SDL_CreateTextureFromSurface(renderer , textSurface);
			surface_table->push_back(new SmartTexture(cur_w, cur_h, curTexture , false, cur_text ));
			}

		const char *blank = "BLANK TEXT\n";
		textSurface = TTF_RenderText_Blended(font2, blank, col_blank);
		curTexture= SDL_CreateTextureFromSurface(renderer, textSurface );
		cur_w = textSurface->w;
		cur_h = textSurface->h;

		surface_table->push_back(new SmartTexture(cur_w, cur_h, curTexture, true, "BLANK"));

	}

		/* Setup all the important stuff */
		int position = 0;

		setupDoc();
}

/*
 * This gets called when a page is first created.
 *
 *
 */
void TextRenderer::setupDoc()
{
	x_pos = dx;
	y_pos = dy;

	int cur_w ;
	int cur_h ;

	for(std::vector<SmartTexture*>::iterator it = surface_table->begin();
			it != surface_table->end();
			++it
			){
	if(x_pos == dx){
			first_words->push_back(*it);
		}

	if(!(*it)->is_break()){

			cur_w = (*it)->getWidth();
			cur_h = (*it)->getHeight();

			if(x_pos + cur_w  < screen_w - dx){

				log_render_info(*it, x_pos, y_pos);
				x_pos += cur_w;

			}
			else{
				x_pos = dx;
				y_pos += cur_h;

				log_render_info(*it, x_pos, y_pos);

				x_pos += cur_w;
			}

		}

		//new line
		else{
			cur_h = (*it)->getHeight();
			x_pos = dx;
			y_pos += dy + cur_h;

			log_render_info(*it, x_pos, y_pos);
		}

	}

	doc_head = first_words->begin();
}

void TextRenderer::log_render_info(SmartTexture *s, int x, int y)
{

	logfile << "Rendering " << s->getWord() << " at x: " << x << " , y: " << y << std::endl;
}

void TextRenderer::printFirstWords()
{
	for(std::vector<SmartTexture*>::iterator it = first_words->begin();
			it != first_words->end();
			++it){

		std::cout << (*it)->getWord() << std::endl;

	}

}

/*
 * Gets called ny main
 */
void TextRenderer::renderCall()
{

	if(cur_mode ==  LR_DEFAULT ){
		renderPage();
	}

	else if(cur_mode == LR_URL){
		SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0x00);
		SDL_Surface *rectSurface = SDL_CreateRGBSurface(0,url_bar.w, url_bar.h, 0, 0xf000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
		SDL_Texture *text = SDL_CreateTextureFromSurface(renderer, rectSurface);
		SDL_RenderCopyEx(renderer,text, NULL, &url_bar, 0.0, NULL, SDL_FLIP_NONE);

	}

	else if(cur_mode == LR_LINKS){
		SDL_SetRenderDrawColor(renderer, 0x00, 0x80, 0xFF, 0x00);
		SDL_RenderFillRect(renderer, &links_bar);

	}

}

void TextRenderer::renderPage()
{
	x_pos = dx;
	y_pos = dy;

	int cur_w ;
	int cur_h ;

	std::vector<SmartTexture*>::iterator it = surface_table->begin();
	for(;
			it != surface_table->end();
			++it){

		if(*it == *doc_head )
			break;

	}

	/*
	 * Need to do a search with the iterators
	 *
	 */

	for(;
			it != surface_table->end();
			++it
			){

	if(!(*it)->is_break()){

			cur_w = (*it)->getWidth();
			cur_h = (*it)->getHeight();

			if(x_pos + cur_w  < screen_w - dx){

				SDL_Rect curRect = {x_pos, y_pos, cur_w, cur_h};

				SDL_RenderCopyEx(renderer, (*it)->getTexture(), NULL, &curRect, 0.0, NULL, SDL_FLIP_NONE);

				x_pos += cur_w;

			}
			else{
				x_pos = dx;
				y_pos += cur_h;

				SDL_Rect curRect = {x_pos, y_pos, cur_w, cur_h};
				SDL_RenderCopyEx(renderer, (*it)->getTexture(), NULL, &curRect, 0.0, NULL, SDL_FLIP_NONE);

				x_pos += cur_w;
			}

		}

		//new line
		else{
			cur_h = (*it)->getHeight();
			x_pos = dx;
			y_pos += dy + cur_h;

			log_render_info(*it, x_pos, y_pos);
		}

	}
}

/*
 * TODO: check that these can't be crashed!
 *
 */
void TextRenderer::shiftDown()
{
	// check for valid position
	if(position + 1 < surface_table->size() - 1){
		position += 1;
		doc_head++;

	}
}

void TextRenderer::shiftUp()
{
	if(position - 1 >= 0){
		position -= 1;
		doc_head--;
	}
}

void TextRenderer::setMode(LR_MODE mode)
{
	cur_mode = mode;
}

<|endoftext|>


<commit_before>
enum disir_status
basic_keyval(struct disir_mold **mold)
{
    enum disir_status status;
    struct disir_context *context;

    status = dc_mold_begin (&context);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_documentation (context, "test_doc", strlen ("test_doc"));
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_keyval_string (context, "key_string", "string_value", "k1value doc", NULL);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_keyval_integer (context, "key_integer", 42, "k2value doc", NULL);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_keyval_float (context, "key_float", 3.14, "k3value doc", NULL);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_mold_finalize (&context, mold);
    if (status != DISIR_STATUS_OK)
        goto error;

    return DISIR_STATUS_OK;
error:
    return status;
}

<commit_msg>test: update basic_keyval with key_boolean<commit_after>
enum disir_status
basic_keyval(struct disir_mold **mold)
{
    enum disir_status status;
    struct disir_context *context;

    status = dc_mold_begin (&context);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_documentation (context, "test_doc", strlen ("test_doc"));
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_keyval_string (context, "key_string", "string_value", "k1value doc", NULL);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_keyval_integer (context, "key_integer", 42, "k2value doc", NULL);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_keyval_float (context, "key_float", 3.14, "k3value doc", NULL);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_add_keyval_boolean (context, "key_boolean", 1, "key boolean doc", NULL);
    if (status != DISIR_STATUS_OK)
        goto error;

    status = dc_mold_finalize (&context, mold);
    if (status != DISIR_STATUS_OK)
        goto error;

    return DISIR_STATUS_OK;
error:
    return status;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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.
 */

#include <cstring>

#include "zorbaerrors/error_manager.h"
#include "zorbatypes/zorbatypesError.h"

#include "ascii_util.h"
#include "regex.h"
#include "stl_util.h"

using namespace std;
U_NAMESPACE_USE

#define bs_c "\\p{L}\\d.:\\p{M}-"       /* \c equivalent contents */
#define bs_i "\\p{L}_:"                 /* \i equivalent contents */

namespace zorba {

///////////////////////////////////////////////////////////////////////////////

typedef uint32_t icu_flags_t;

static icu_flags_t convert_xquery_flags( char const *xq_flags ) {
  icu_flags_t icu_flags = 0;
  if ( xq_flags ) {
    for ( char const *f = xq_flags; *f; ++f ) {
      switch ( *f ) {
        case 'i': icu_flags |= UREGEX_CASE_INSENSITIVE; break;
        case 'm': icu_flags |= UREGEX_MULTILINE       ; break;
        case 's': icu_flags |= UREGEX_DOTALL          ; break;
        case 'x': icu_flags |= UREGEX_COMMENTS        ; break;
        default:
          throw zorbatypesException( xq_flags, ZorbatypesError::FORX0001 );
      }
    }
  }
  return icu_flags;
}

void convert_xquery_re( zstring const &xq_re, zstring *icu_re,
                        char const *xq_flags ) {
  bool const x_flag = xq_flags ? ::strchr( xq_flags, 'x' ) : false;

  icu_re->clear();
  icu_re->reserve( xq_re.length() );    // approximate

  bool got_backslash = false;
  bool in_char_class = false;           // within [...]

  bool in_backref = false;              // \[0-9]+
  int backref_no = 0;
  int parens_open = 0, parens_close = 0;

  FOR_EACH( zstring, xq_c, xq_re ) {
    if ( got_backslash ) {
      if ( x_flag && !in_char_class && ascii::is_space( *xq_c ) ) {
        //
        // XQuery F&O: 7.6.1.1: If [the 'x' flag is] present, whitespace
        // characters ... in the regular expression are removed prior to
        // matching with one exception: whitespace characters within character
        // class expressions ... are not removed.
        //
        continue;
      }
      got_backslash = false;
      switch ( *xq_c ) {
        case 'c': // NameChar
          *icu_re += "[" bs_c "]";
          continue;
        case 'C': // ^\c
          *icu_re += "[^" bs_c "]";
          continue;
        case 'i': // initial NameChar
          *icu_re += "[" bs_i "]";
          continue;
        case 'I': // ^\i
          *icu_re += "[^" bs_i "]";
          continue;
        default:
          if ( ascii::is_digit( *xq_c ) ) {
            if ( in_char_class ) {
              //
              // XQuery F&O 7.6.1: Within a character class expression,
              // \ followed by a digit is invalid.
              //
              ZORBA_ERROR( FORX0002 );
            }
            in_backref = true;
            backref_no = *xq_c - '0';
          }
          *icu_re += '\\';
          break;
      }
    } else {
      if ( in_backref ) {
        //
        // XQuery F&O 7.6.1: The construct \N where N is a single digit is
        // always recognized as a back-reference; if this is followed by
        // further digits, these digits are taken to be part of the back-
        // reference if and only if the resulting number NN is such that the
        // back-reference is preceded by NN or more unescaped opening
        // parentheses.
        //
        if ( parens_open > 9 && ascii::is_digit( *xq_c ) )
          backref_no = backref_no * 10 + (*xq_c - '0');
        else
          in_backref = false;
        //
        // XQuery F&O 7.6.1: The regular expression is invalid if a back-
        // reference refers to a subexpression that does not exist or whose
        // closing right parenthesis occurs after the back-reference.
        //
        if ( backref_no > parens_close )
          ZORBA_ERROR( FORX0002 );
      }
      switch ( *xq_c ) {
        case '\\':
          got_backslash = true;
          continue;
        case '(':
          ++parens_open;
          break;
        case ')':
          ++parens_close;
          break;
        case '[':
          in_char_class = true;
          break;
        case ']':
          in_char_class = false;
          break;
        default:
          if ( x_flag && ascii::is_space( *xq_c ) ) {
            if ( !in_char_class )
              continue;
            //
            // This is similar to the above case for removing whitespace except
            // ICU removes *all* whitespace (even within character classes)
            // unless the whitespace is escaped; hence we have to escape it.
            //
            *icu_re += '\\';
          }
      }
    }
    *icu_re += *xq_c;
  } // FOR_EACH
}

///////////////////////////////////////////////////////////////////////////////

#ifndef ZORBA_NO_UNICODE

namespace unicode {

bool regex::compile( string const &pattern, char const *flags ) {
  UErrorCode status = U_ZERO_ERROR;
  delete matcher_;
  matcher_ = new RegexMatcher( pattern, convert_xquery_flags( flags ), status );
  if ( U_FAILURE( status ) ) {
    delete matcher_;
    matcher_ = 0;
    return false;
  }
  return true;
}

bool regex::match_part( string const &s ) {
  assert( matcher_ );
  matcher_->reset( s );
  return matcher_->find() != 0;
}

bool regex::match_whole( string const &s ) {
  assert( matcher_ );
  matcher_->reset( s );
  UErrorCode status = U_ZERO_ERROR;
  return matcher_->matches( status ) && U_SUCCESS( status );
}

bool regex::next( re_type_t re_type, string const &s, size_type *pos,
                  string *substring, bool *matched ) {
  assert( matcher_ );
  assert( pos );
  unicode::size_type const s_len = s.length();
  if ( *pos < s_len ) {
    matcher_->reset( s );
    UErrorCode status = U_ZERO_ERROR;
    if ( matcher_->find( *pos, status ) ) {
      size_type const end = matcher_->end( status );
      if ( substring ) {
        size_type const start = matcher_->start( status );
        switch ( re_type ) {
          case re_is_match:
            substring->setTo( s, start, end - start );
            break;
          case re_is_separator:
            substring->setTo( s, *pos, start - *pos );
            break;
        }
      }
      *pos = end;
      if ( matched )
        *matched = true;
      return true;
    }
    if ( re_type == re_is_separator ) {
      //
      // Special case: the RE did not match starting at pos, but there *is* a
      // last token.  For example, given the RE of "," and:
      //
      //    s   = "a,b,c"
      //    pos =  01234
      //
      // then calling next_token() with a pos of 4 will not match another ","
      // but we should return the final token after the last "," (the "c").
      //
      if ( substring )
        substring->setTo( s, *pos, s_len - *pos );
      *pos = s_len;
      if ( matched )
        *matched = false;
      return true;
    }
  }
  if ( matched )
    *matched = false;
  return false;
}

bool regex::replace_all( string const &in, string const &replacement,
                         string *out ) {
  assert( matcher_ );
  assert( out );
  matcher_->reset( in );
  UErrorCode status = U_ZERO_ERROR;
  *out = matcher_->replaceAll( replacement, status );
  return U_SUCCESS( status ) == TRUE;
}

bool regex::replace_all( char const *in, char const *replacement,
                         string *out ) {
  string u_in, u_replacement;
  return  to_string( in, &u_in ) &&
          to_string( replacement, &u_replacement ) &&
          replace_all( u_in, u_replacement, out );
}

} // namespace unicode

#endif /* ZORBA_NO_UNICODE */

///////////////////////////////////////////////////////////////////////////////

} // namespace zorba
/* vim:set et sw=2 ts=2: */
<commit_msg>Fixed K2-MatchesFunc-[56].<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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.
 */

#include <cstring>

#include "zorbaerrors/error_manager.h"
#include "zorbatypes/zorbatypesError.h"

#include "ascii_util.h"
#include "regex.h"
#include "stl_util.h"

using namespace std;
U_NAMESPACE_USE

#define bs_c "\\p{L}\\d.:\\p{M}-"       /* \c equivalent contents */
#define bs_i "\\p{L}_:"                 /* \i equivalent contents */

namespace zorba {

///////////////////////////////////////////////////////////////////////////////

typedef uint32_t icu_flags_t;

static icu_flags_t convert_xquery_flags( char const *xq_flags ) {
  icu_flags_t icu_flags = 0;
  if ( xq_flags ) {
    for ( char const *f = xq_flags; *f; ++f ) {
      switch ( *f ) {
        case 'i': icu_flags |= UREGEX_CASE_INSENSITIVE; break;
        case 'm': icu_flags |= UREGEX_MULTILINE       ; break;
        case 's': icu_flags |= UREGEX_DOTALL          ; break;
        case 'x': icu_flags |= UREGEX_COMMENTS        ; break;
        default:
          throw zorbatypesException( xq_flags, ZorbatypesError::FORX0001 );
      }
    }
  }
  return icu_flags;
}

void convert_xquery_re( zstring const &xq_re, zstring *icu_re,
                        char const *xq_flags ) {
  bool const x_flag = xq_flags ? ::strchr( xq_flags, 'x' ) : false;

  icu_re->clear();
  icu_re->reserve( xq_re.length() );    // approximate

  bool got_backslash = false;
  bool in_char_class = false;           // within [...]

  bool in_backref = false;              // \[0-9]+
  int backref_no = 0;
  int parens_open = 0, parens_close = 0;

  FOR_EACH( zstring, xq_c, xq_re ) {
    if ( got_backslash ) {
      if ( x_flag && !in_char_class && ascii::is_space( *xq_c ) ) {
        //
        // XQuery F&O: 7.6.1.1: If [the 'x' flag is] present, whitespace
        // characters ... in the regular expression are removed prior to
        // matching with one exception: whitespace characters within character
        // class expressions ... are not removed.
        //
        continue;
      }
      got_backslash = false;
      switch ( *xq_c ) {
        case 'c': // NameChar
          *icu_re += "[" bs_c "]";
          continue;
        case 'C': // ^\c
          *icu_re += "[^" bs_c "]";
          continue;
        case 'i': // initial NameChar
          *icu_re += "[" bs_i "]";
          continue;
        case 'I': // ^\i
          *icu_re += "[^" bs_i "]";
          continue;
        default:
          if ( ascii::is_digit( *xq_c ) ) {
            if ( in_char_class ) {
              //
              // XQuery F&O 7.6.1: Within a character class expression,
              // \ followed by a digit is invalid.
              //
              ZORBA_ERROR( FORX0002 );
            }
            in_backref = true;
            backref_no = *xq_c - '0';
          }
          *icu_re += '\\';
          break;
      }
    } else {
      if ( in_backref ) {
        //
        // XQuery F&O 7.6.1: The construct \N where N is a single digit is
        // always recognized as a back-reference; if this is followed by
        // further digits, these digits are taken to be part of the back-
        // reference if and only if the resulting number NN is such that the
        // back-reference is preceded by NN or more unescaped opening
        // parentheses.
        //
        if ( parens_open > 9 && ascii::is_digit( *xq_c ) )
          backref_no = backref_no * 10 + (*xq_c - '0');
        else
          in_backref = false;
        //
        // XQuery F&O 7.6.1: The regular expression is invalid if a back-
        // reference refers to a subexpression that does not exist or whose
        // closing right parenthesis occurs after the back-reference.
        //
        if ( backref_no > parens_close )
          ZORBA_ERROR( FORX0002 );
      }
      switch ( *xq_c ) {
        case '\\':
          got_backslash = true;
          continue;
        case '(':
          ++parens_open;
          break;
        case ')':
          ++parens_close;
          break;
        case '[':
          in_char_class = true;
          break;
        case ']':
          in_char_class = false;
          break;
        default:
          if ( x_flag && ascii::is_space( *xq_c ) ) {
            if ( !in_char_class )
              continue;
            //
            // This is similar to the above case for removing whitespace except
            // ICU removes *all* whitespace (even within character classes)
            // unless the whitespace is escaped; hence we have to escape it.
            //
            *icu_re += '\\';
          }
      }
    }
    *icu_re += *xq_c;
  } // FOR_EACH

  //
  // XML Schema Part 2 F.1.1: [Unicode Database] groups code points into a
  // number of blocks such as Basic Latin (i.e., ASCII), Latin-1 Supplement,
  // Hangul Jamo, CJK Compatibility, etc. The set containing all characters
  // that have block name X (with all white space stripped out), can be
  // identified with a block escape \p{IsX}.
  //
  // However, ICU uses \p{InX} rather than \p{IsX}.  Also note that the '5'
  // below is correct since "\\" represents a single '\'.
  //
  ascii::replace_all( *icu_re, "\\p{Is", 5, "\\p{In", 5 );
}

///////////////////////////////////////////////////////////////////////////////

#ifndef ZORBA_NO_UNICODE

namespace unicode {

bool regex::compile( string const &pattern, char const *flags ) {
  UErrorCode status = U_ZERO_ERROR;
  delete matcher_;
  matcher_ = new RegexMatcher( pattern, convert_xquery_flags( flags ), status );
  if ( U_FAILURE( status ) ) {
    delete matcher_;
    matcher_ = 0;
    return false;
  }
  return true;
}

bool regex::match_part( string const &s ) {
  assert( matcher_ );
  matcher_->reset( s );
  return matcher_->find() != 0;
}

bool regex::match_whole( string const &s ) {
  assert( matcher_ );
  matcher_->reset( s );
  UErrorCode status = U_ZERO_ERROR;
  return matcher_->matches( status ) && U_SUCCESS( status );
}

bool regex::next( re_type_t re_type, string const &s, size_type *pos,
                  string *substring, bool *matched ) {
  assert( matcher_ );
  assert( pos );
  unicode::size_type const s_len = s.length();
  if ( *pos < s_len ) {
    matcher_->reset( s );
    UErrorCode status = U_ZERO_ERROR;
    if ( matcher_->find( *pos, status ) ) {
      size_type const end = matcher_->end( status );
      if ( substring ) {
        size_type const start = matcher_->start( status );
        switch ( re_type ) {
          case re_is_match:
            substring->setTo( s, start, end - start );
            break;
          case re_is_separator:
            substring->setTo( s, *pos, start - *pos );
            break;
        }
      }
      *pos = end;
      if ( matched )
        *matched = true;
      return true;
    }
    if ( re_type == re_is_separator ) {
      //
      // Special case: the RE did not match starting at pos, but there *is* a
      // last token.  For example, given the RE of "," and:
      //
      //    s   = "a,b,c"
      //    pos =  01234
      //
      // then calling next_token() with a pos of 4 will not match another ","
      // but we should return the final token after the last "," (the "c").
      //
      if ( substring )
        substring->setTo( s, *pos, s_len - *pos );
      *pos = s_len;
      if ( matched )
        *matched = false;
      return true;
    }
  }
  if ( matched )
    *matched = false;
  return false;
}

bool regex::replace_all( string const &in, string const &replacement,
                         string *out ) {
  assert( matcher_ );
  assert( out );
  matcher_->reset( in );
  UErrorCode status = U_ZERO_ERROR;
  *out = matcher_->replaceAll( replacement, status );
  return U_SUCCESS( status ) == TRUE;
}

bool regex::replace_all( char const *in, char const *replacement,
                         string *out ) {
  string u_in, u_replacement;
  return  to_string( in, &u_in ) &&
          to_string( replacement, &u_replacement ) &&
          replace_all( u_in, u_replacement, out );
}

} // namespace unicode

#endif /* ZORBA_NO_UNICODE */

///////////////////////////////////////////////////////////////////////////////

} // namespace zorba
/* vim:set et sw=2 ts=2: */
<|endoftext|>


<commit_before>/*
gettable.cpp

  ⠡栬 ᨬ

*/

/* Revision: 1.01 11.07.2000 $ */

/*
Modify:
  11.07.2000 SVS
    !    樨  BC & VC
  25.06.2000 SVS
    ! ⮢ Master Copy
    ! 뤥  ⢥ ᠬ⥫쭮
*/

#include "headers.hpp"
#pragma hdrstop

/* $ 30.06.2000 IS
   ⠭
*/
#include "internalheaders.hpp"
/* IS $ */

#if defined(__BORLANDC__)
static unsigned long CalcDifference(int *SrcTable,int *CheckedTable,unsigned char *DecodeTable);
#else
static unsigned long CalcDifference(int *SrcTable,int *CheckedTable,char *DecodeTable);
#endif

int GetTable(struct CharTableSet *TableSet,int AnsiText,int &TableNum,
             int &UseUnicode)
{
  int I;

  if (AnsiText)
  {
    for (I=0;I<256;I++)
    {
      TableSet->DecodeTable[I]=TableSet->EncodeTable[I]=I;
      TableSet->LowerTable[I]=TableSet->UpperTable[I]=I;
    }
    for (I=0;I<256;I++)
    {
      char Str[1];
      Str[0]=I;
      CharToOemBuff(Str,Str,1);
      TableSet->DecodeTable[I]=Str[0];
      Str[0]=I;
      OemToCharBuff(Str,Str,1);
      TableSet->EncodeTable[I]=Str[0];
      TableSet->LowerTable[I]=(unsigned char)CharLower((LPTSTR)I);
      TableSet->UpperTable[I]=(unsigned char)CharUpper((LPTSTR)I);
    }
    strcpy(TableSet->TableName,"Win");
    return(TRUE);
  }

  VMenu TableList(MSG(MGetTableTitle),NULL,0,ScrY-4);
  TableList.SetFlags(MENU_WRAPMODE);
  TableList.SetPosition(-1,-1,0,0);

  struct MenuItem ListItem;
  ListItem.Checked=ListItem.Separator=*ListItem.UserData=ListItem.UserDataSize=0;

  ListItem.Selected=(TableNum==0);
  strcpy(ListItem.Name,MSG(MGetTableNormalText));
  TableList.AddItem(&ListItem);

  if (UseUnicode)
  {
    ListItem.Selected=(TableNum==1);
    strcpy(ListItem.Name,"Unicode");
    TableList.AddItem(&ListItem);
  }

  for (I=0;;I++)
  {
    char TableKey[512];
    if (!EnumRegKey("CodeTables",I,TableKey,sizeof(TableKey)))
      break;
    CharToOem(PointToName(TableKey),ListItem.Name);
    ListItem.Selected=(I+1+UseUnicode == TableNum);
    TableList.AddItem(&ListItem);
  }

  TableList.AssignHighlights(FALSE);
  TableList.Process();
  int Pos=TableList.GetExitCode();

  if (Pos>UseUnicode && !PrepareTable(TableSet,Pos-1-UseUnicode))
    return(FALSE);

  UseUnicode=UseUnicode && Pos==1;

  if (Pos==-1)
    return(-1);
  TableNum=Pos;

  return(Pos!=0);
}

void DecodeString(char *Str,unsigned char *DecodeTable,int Length)
{
  if (Length==-1)
    Length=strlen(Str);
  while (Length--)
  {
    *Str=DecodeTable[(unsigned int)*Str];
    Str++;
  }
}

void EncodeString(char *Str,unsigned char *EncodeTable,int Length)
{
  if (Length==-1)
    Length=strlen(Str);
  while (Length--)
  {
    *Str=EncodeTable[(unsigned int)*Str];
    Str++;
  }
}

int DetectTable(FILE *SrcFile,struct CharTableSet *TableSet,int &TableNum)
{
  unsigned char DistrTable[256],FileDistr[256],FileData[4096];
  int ReadSize;
  if (!GetRegKey("CodeTables","Distribution",(BYTE *)DistrTable,(BYTE *)NULL,sizeof(DistrTable)))
    return(FALSE);
  SaveFilePos SavePos(SrcFile);
  fseek(SrcFile,0,SEEK_SET);

  int ProcessedSize=0;
  memset(FileDistr,0,sizeof(FileDistr));
  for (int Attempt=0;;Attempt++)
  {
    if ((ReadSize=fread(FileData,1,sizeof(FileData),SrcFile))==0)
      break;
    int TextData=TRUE;
    for (int I=4;I<ReadSize;I++)
    {
      int Ch=FileData[I];
      if (DistrTable[Ch]==0xff)
        continue;
      if (Ch!=FileData[I-1])
      {
        ProcessedSize++;
        if (++FileDistr[Ch]==254)
          break;
      }
      else
        if (Ch>127 && Ch==FileData[I-2] && Ch==FileData[I-3])
        {
          fseek(SrcFile,I-ReadSize+256,SEEK_CUR);
          TextData=FALSE;
          break;
        }
    }
    if (ProcessedSize>1024 || TextData && Attempt>4 || !TextData && Attempt>8)
      break;
  }

  if (ProcessedSize<10)
    return(FALSE);

  int MaxDistr=0,MaxFileDistr=0,I;
  for (I=0;I<sizeof(DistrTable)/sizeof(DistrTable[0]);I++)
    if (DistrTable[I]!=0xff && DistrTable[I]>MaxDistr)
      MaxDistr=DistrTable[I];
  for (I=0;I<sizeof(FileDistr)/sizeof(FileDistr[0]);I++)
    if (FileDistr[I]!=0xff && FileDistr[I]>MaxFileDistr)
      MaxFileDistr=FileDistr[I];

  int SrcTable[256],CheckedTable[256];
  for (I=0;I<sizeof(DistrTable)/sizeof(DistrTable[0]);I++)
    if (DistrTable[I]==0xff)
      SrcTable[I]=-1;
    else
      SrcTable[I]=MaxFileDistr*DistrTable[I];
  for (I=0;I<sizeof(FileDistr)/sizeof(FileDistr[0]);I++)
    if (FileDistr[I]==0xff)
      CheckedTable[I]=-1;
    else
      CheckedTable[I]=MaxDistr*FileDistr[I];

  unsigned long BestValue=CalcDifference(SrcTable,CheckedTable,NULL);
  int BestTable=-1;
  for (I=0;;I++)
  {
    char TableKey[512];
    if (!EnumRegKey("CodeTables",I,TableKey,sizeof(TableKey)))
      break;
#if defined(__BORLANDC__)
    unsigned char DecodeTable[256];
#else
    char DecodeTable[256];
#endif
    if (!GetRegKey(TableKey,"Mapping",(BYTE *)DecodeTable,(BYTE *)NULL,sizeof(DecodeTable)))
      return(FALSE);
    unsigned long CurValue=CalcDifference(SrcTable,CheckedTable,DecodeTable);
    if (CurValue<(5*BestValue)/6 || CurValue<BestValue && BestTable!=-1)
    {
      BestValue=CurValue;
      BestTable=I;
    }
  }
  if (BestTable==-1)
  {
    TableNum=0;
    return(FALSE);
  }
  if (!PrepareTable(TableSet,BestTable))
    return(FALSE);
  TableNum=BestTable+1;
  return(TRUE);
}

#if defined(__BORLANDC__)
static unsigned long CalcDifference(int *SrcTable,int *CheckedTable,unsigned char *DecodeTable)
#else
static unsigned long CalcDifference(int *SrcTable,int *CheckedTable,char *DecodeTable)
#endif
{
  unsigned char EncodeTable[256];
  int CheckedTableProcessed[256];
  int I;
  for (I=0;I<256;I++)
  {
    EncodeTable[I]=I;
    CheckedTableProcessed[I]=FALSE;
  }
  if (DecodeTable!=NULL)
    for (I=0;I<256;I++)
      EncodeTable[DecodeTable[I]]=I;
  unsigned long Diff=0;
  for (I=0;I<256;I++)
    if (SrcTable[I]!=-1)
    {
      int N=EncodeTable[I];
      Diff+=abs(SrcTable[I]-CheckedTable[N]);
      CheckedTableProcessed[N]=TRUE;
    }
  for (I=0;I<256;I++)
    if (SrcTable[I]!=-1 && !CheckedTableProcessed[I])
      Diff+=CheckedTable[I];
  return(Diff);
}

int PrepareTable(struct CharTableSet *TableSet,int TableNum)
{
  int I;
  for (I=0;I<256;I++)
  {
    TableSet->DecodeTable[I]=TableSet->EncodeTable[I]=I;
    TableSet->LowerTable[I]=TableSet->UpperTable[I]=I;
  }
  char TableKey[512];
  if (!EnumRegKey("CodeTables",TableNum,TableKey,sizeof(TableKey)))
    return(FALSE);
  if (!GetRegKey(TableKey,"Mapping",(BYTE *)TableSet->DecodeTable,(BYTE *)NULL,sizeof(TableSet->DecodeTable)))
    return(FALSE);
  strncpy(TableSet->TableName,PointToName(TableKey),sizeof(TableSet->TableName)-1);

  int EncodeSet[256];
  memset(EncodeSet,0,sizeof(EncodeSet));
  for (I=0;I<256;I++)
  {
    int Ch=TableSet->DecodeTable[I];
    if (!EncodeSet[Ch] || Ch>=128)
    {
      TableSet->EncodeTable[Ch]=I;
      EncodeSet[Ch]=TRUE;
    }
  }
  for (I=0;I<256;I++)
  {
    int Ch=TableSet->DecodeTable[I];
    TableSet->LowerTable[I]=TableSet->EncodeTable[LocalLower(Ch)];
    TableSet->UpperTable[I]=TableSet->EncodeTable[LocalUpper(Ch)];
  }
  return(TRUE);
}

<commit_msg>FAR patch 00152.gettable Дата              : 28.08.2000 Сделал            : andrey tretjakov Описание          : GetTable меню - hotkeys по номерам Измененные файлы  : gettable.cpp Состав            : 00152.gettable.txt                     gettable.cpp.152.diff Основан на патче  : 141 Дополнение        :<commit_after>/*
gettable.cpp

  ⠡栬 ᨬ

*/

/* Revision: 1.02 27.08.2000 $ */

/*
Modify:
  27.08.2000 tran
    + hotkeys as numbers
  11.07.2000 SVS
    !    樨  BC & VC
  25.06.2000 SVS
    ! ⮢ Master Copy
    ! 뤥  ⢥ ᠬ⥫쭮
*/

#include "headers.hpp"
#pragma hdrstop

/* $ 30.06.2000 IS
   ⠭
*/
#include "internalheaders.hpp"
/* IS $ */

#if defined(__BORLANDC__)
static unsigned long CalcDifference(int *SrcTable,int *CheckedTable,unsigned char *DecodeTable);
#else
static unsigned long CalcDifference(int *SrcTable,int *CheckedTable,char *DecodeTable);
#endif

int GetTable(struct CharTableSet *TableSet,int AnsiText,int &TableNum,
             int &UseUnicode)
{
  int I;
  int mx=0;
  char ItemName[128],t[128];

  if (AnsiText)
  {
    for (I=0;I<256;I++)
    {
      TableSet->DecodeTable[I]=TableSet->EncodeTable[I]=I;
      TableSet->LowerTable[I]=TableSet->UpperTable[I]=I;
    }
    for (I=0;I<256;I++)
    {
      char Str[1];
      Str[0]=I;
      CharToOemBuff(Str,Str,1);
      TableSet->DecodeTable[I]=Str[0];
      Str[0]=I;
      OemToCharBuff(Str,Str,1);
      TableSet->EncodeTable[I]=Str[0];
      TableSet->LowerTable[I]=(unsigned char)CharLower((LPTSTR)I);
      TableSet->UpperTable[I]=(unsigned char)CharUpper((LPTSTR)I);
    }
    strcpy(TableSet->TableName,"Win");
    return(TRUE);
  }

  VMenu TableList(MSG(MGetTableTitle),NULL,0,ScrY-4);
  TableList.SetFlags(MENU_WRAPMODE);
  TableList.SetPosition(-1,-1,0,0);

  struct MenuItem ListItem;
  ListItem.Checked=ListItem.Separator=*ListItem.UserData=ListItem.UserDataSize=0;

  ListItem.Selected=(TableNum==0);
  strcpy(ItemName,MSG(MGetTableNormalText));
  sprintf(ListItem.Name,"&1 %s",ItemName);
  TableList.AddItem(&ListItem);

  if (UseUnicode)
  {
    ListItem.Selected=(TableNum==1);
    strcpy(ListItem.Name,"&2 Unicode");
    TableList.AddItem(&ListItem);
    mx=1;
  }

  for (I=0;;I++)
  {
    char TableKey[512];
    if (!EnumRegKey("CodeTables",I,TableKey,sizeof(TableKey)))
      break;
    CharToOem(PointToName(TableKey),ItemName);
    if ( I<8-mx )
        sprintf(ListItem.Name,"&%i %s",I+2+mx,ItemName);
    else
        sprintf(ListItem.Name,"   %s",ItemName);
    ListItem.Selected=(I+1+UseUnicode == TableNum);
    TableList.AddItem(&ListItem);
  }

  TableList.AssignHighlights(FALSE);
  TableList.Process();
  int Pos=TableList.GetExitCode();

  if (Pos>UseUnicode && !PrepareTable(TableSet,Pos-1-UseUnicode))
    return(FALSE);

  UseUnicode=UseUnicode && Pos==1;

  if (Pos==-1)
    return(-1);
  TableNum=Pos;

  return(Pos!=0);
}

void DecodeString(char *Str,unsigned char *DecodeTable,int Length)
{
  if (Length==-1)
    Length=strlen(Str);
  while (Length--)
  {
    *Str=DecodeTable[(unsigned int)*Str];
    Str++;
  }
}

void EncodeString(char *Str,unsigned char *EncodeTable,int Length)
{
  if (Length==-1)
    Length=strlen(Str);
  while (Length--)
  {
    *Str=EncodeTable[(unsigned int)*Str];
    Str++;
  }
}

int DetectTable(FILE *SrcFile,struct CharTableSet *TableSet,int &TableNum)
{
  unsigned char DistrTable[256],FileDistr[256],FileData[4096];
  int ReadSize;
  if (!GetRegKey("CodeTables","Distribution",(BYTE *)DistrTable,(BYTE *)NULL,sizeof(DistrTable)))
    return(FALSE);
  SaveFilePos SavePos(SrcFile);
  fseek(SrcFile,0,SEEK_SET);

  int ProcessedSize=0;
  memset(FileDistr,0,sizeof(FileDistr));
  for (int Attempt=0;;Attempt++)
  {
    if ((ReadSize=fread(FileData,1,sizeof(FileData),SrcFile))==0)
      break;
    int TextData=TRUE;
    for (int I=4;I<ReadSize;I++)
    {
      int Ch=FileData[I];
      if (DistrTable[Ch]==0xff)
        continue;
      if (Ch!=FileData[I-1])
      {
        ProcessedSize++;
        if (++FileDistr[Ch]==254)
          break;
      }
      else
        if (Ch>127 && Ch==FileData[I-2] && Ch==FileData[I-3])
        {
          fseek(SrcFile,I-ReadSize+256,SEEK_CUR);
          TextData=FALSE;
          break;
        }
    }
    if (ProcessedSize>1024 || TextData && Attempt>4 || !TextData && Attempt>8)
      break;
  }

  if (ProcessedSize<10)
    return(FALSE);

  int MaxDistr=0,MaxFileDistr=0,I;
  for (I=0;I<sizeof(DistrTable)/sizeof(DistrTable[0]);I++)
    if (DistrTable[I]!=0xff && DistrTable[I]>MaxDistr)
      MaxDistr=DistrTable[I];
  for (I=0;I<sizeof(FileDistr)/sizeof(FileDistr[0]);I++)
    if (FileDistr[I]!=0xff && FileDistr[I]>MaxFileDistr)
      MaxFileDistr=FileDistr[I];

  int SrcTable[256],CheckedTable[256];
  for (I=0;I<sizeof(DistrTable)/sizeof(DistrTable[0]);I++)
    if (DistrTable[I]==0xff)
      SrcTable[I]=-1;
    else
      SrcTable[I]=MaxFileDistr*DistrTable[I];
  for (I=0;I<sizeof(FileDistr)/sizeof(FileDistr[0]);I++)
    if (FileDistr[I]==0xff)
      CheckedTable[I]=-1;
    else
      CheckedTable[I]=MaxDistr*FileDistr[I];

  unsigned long BestValue=CalcDifference(SrcTable,CheckedTable,NULL);
  int BestTable=-1;
  for (I=0;;I++)
  {
    char TableKey[512];
    if (!EnumRegKey("CodeTables",I,TableKey,sizeof(TableKey)))
      break;
#if defined(__BORLANDC__)
    unsigned char DecodeTable[256];
#else
    char DecodeTable[256];
#endif
    if (!GetRegKey(TableKey,"Mapping",(BYTE *)DecodeTable,(BYTE *)NULL,sizeof(DecodeTable)))
      return(FALSE);
    unsigned long CurValue=CalcDifference(SrcTable,CheckedTable,DecodeTable);
    if (CurValue<(5*BestValue)/6 || CurValue<BestValue && BestTable!=-1)
    {
      BestValue=CurValue;
      BestTable=I;
    }
  }
  if (BestTable==-1)
  {
    TableNum=0;
    return(FALSE);
  }
  if (!PrepareTable(TableSet,BestTable))
    return(FALSE);
  TableNum=BestTable+1;
  return(TRUE);
}

#if defined(__BORLANDC__)
static unsigned long CalcDifference(int *SrcTable,int *CheckedTable,unsigned char *DecodeTable)
#else
static unsigned long CalcDifference(int *SrcTable,int *CheckedTable,char *DecodeTable)
#endif
{
  unsigned char EncodeTable[256];
  int CheckedTableProcessed[256];
  int I;
  for (I=0;I<256;I++)
  {
    EncodeTable[I]=I;
    CheckedTableProcessed[I]=FALSE;
  }
  if (DecodeTable!=NULL)
    for (I=0;I<256;I++)
      EncodeTable[DecodeTable[I]]=I;
  unsigned long Diff=0;
  for (I=0;I<256;I++)
    if (SrcTable[I]!=-1)
    {
      int N=EncodeTable[I];
      Diff+=abs(SrcTable[I]-CheckedTable[N]);
      CheckedTableProcessed[N]=TRUE;
    }
  for (I=0;I<256;I++)
    if (SrcTable[I]!=-1 && !CheckedTableProcessed[I])
      Diff+=CheckedTable[I];
  return(Diff);
}

int PrepareTable(struct CharTableSet *TableSet,int TableNum)
{
  int I;
  for (I=0;I<256;I++)
  {
    TableSet->DecodeTable[I]=TableSet->EncodeTable[I]=I;
    TableSet->LowerTable[I]=TableSet->UpperTable[I]=I;
  }
  char TableKey[512];
  if (!EnumRegKey("CodeTables",TableNum,TableKey,sizeof(TableKey)))
    return(FALSE);
  if (!GetRegKey(TableKey,"Mapping",(BYTE *)TableSet->DecodeTable,(BYTE *)NULL,sizeof(TableSet->DecodeTable)))
    return(FALSE);
  strncpy(TableSet->TableName,PointToName(TableKey),sizeof(TableSet->TableName)-1);

  int EncodeSet[256];
  memset(EncodeSet,0,sizeof(EncodeSet));
  for (I=0;I<256;I++)
  {
    int Ch=TableSet->DecodeTable[I];
    if (!EncodeSet[Ch] || Ch>=128)
    {
      TableSet->EncodeTable[Ch]=I;
      EncodeSet[Ch]=TRUE;
    }
  }
  for (I=0;I<256;I++)
  {
    int Ch=TableSet->DecodeTable[I];
    TableSet->LowerTable[I]=TableSet->EncodeTable[LocalLower(Ch)];
    TableSet->UpperTable[I]=TableSet->EncodeTable[LocalUpper(Ch)];
  }
  return(TRUE);
}

<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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.
 */

#include <cstring>
#include <vector>

#include "zorbaerrors/error_manager.h"
#include "zorbaerrors/dict.h"

#include "ascii_util.h"
#include "regex.h"
#include "stl_util.h"

using namespace std;
U_NAMESPACE_USE

#define bs_c "\\p{L}\\d.:\\p{M}-"       /* \c equivalent contents */
#define bs_i "\\p{L}_:"                 /* \i equivalent contents */

namespace zorba {

///////////////////////////////////////////////////////////////////////////////

typedef uint32_t icu_flags_t;

static icu_flags_t convert_xquery_flags( char const *xq_flags ) {
  icu_flags_t icu_flags = 0;
  if ( xq_flags ) {
    for ( char const *f = xq_flags; *f; ++f ) {
      switch ( *f ) {
        case 'i': icu_flags |= UREGEX_CASE_INSENSITIVE; break;
        case 'm': icu_flags |= UREGEX_MULTILINE       ; break;
        case 's': icu_flags |= UREGEX_DOTALL          ; break;
        case 'x': icu_flags |= UREGEX_COMMENTS        ; break;
        default:
          throw XQUERY_EXCEPTION( FORX0001, ERROR_PARAMS( *f ) );
      }
    }
  }
  return icu_flags;
}

#define INVALID_RE_EXCEPTION(ZED_KEY) \
  XQUERY_EXCEPTION( FORX0002, ERROR_PARAMS( ZED( ZED_KEY ) ) )

void convert_xquery_re( zstring const &xq_re, zstring *icu_re,
                        char const *xq_flags ) {
  icu_flags_t const icu_flags = convert_xquery_flags( xq_flags );
  bool const i_flag = icu_flags & UREGEX_CASE_INSENSITIVE;
  bool const x_flag = icu_flags & UREGEX_COMMENTS;

  icu_re->clear();
  icu_re->reserve( xq_re.length() );    // approximate

  bool got_backslash = false;
  bool in_char_class = false;           // within [...]

  bool in_backref = false;              // '\'[1-9][0-9]*
  unsigned backref_no = 0;
  vector<bool> cap_sub;                 // true = open; false = closed

  FOR_EACH( zstring, xq_c, xq_re ) {
    if ( got_backslash ) {
      if ( x_flag && !in_char_class && ascii::is_space( *xq_c ) ) {
        //
        // XQuery F&O: 7.6.1.1: If [the 'x' flag is] present, whitespace
        // characters ... in the regular expression are removed prior to
        // matching with one exception: whitespace characters within character
        // class expressions ... are not removed.
        //
        continue;
      }
      got_backslash = false;
      switch ( *xq_c ) {
        case 'c': // NameChar
          *icu_re += "[" bs_c "]";
          continue;
        case 'C': // ^\c
          *icu_re += "[^" bs_c "]";
          continue;
        case 'i': // initial NameChar
          *icu_re += "[" bs_i "]";
          continue;
        case 'I': // ^\i
          *icu_re += "[^" bs_i "]";
          continue;
        default:
          if ( ascii::is_digit( *xq_c ) ) {
            backref_no = *xq_c - '0';
            if ( !backref_no )          // \0 is illegal
              throw INVALID_RE_EXCEPTION( BackRef0Illegal );
            if ( in_char_class ) {
              //
              // XQuery F&O 7.6.1: Within a character class expression,
              // \ followed by a digit is invalid.
              //
              throw INVALID_RE_EXCEPTION( BackRefIllegalInCharClass );
            }
            in_backref = true;
          }
          *icu_re += '\\';
          break;
      }
    } else {
      if ( in_backref ) {
        //
        // XQuery F&O 7.6.1: The construct \N where N is a single digit is
        // always recognized as a back-reference; if this is followed by
        // further digits, these digits are taken to be part of the back-
        // reference if and only if the resulting number NN is such that the
        // back-reference is preceded by NN or more unescaped opening
        // parentheses.
        //
        if ( cap_sub.size() > 9 && ascii::is_digit( *xq_c ) )
          backref_no = backref_no * 10 + (*xq_c - '0');
        else
          in_backref = false;
        //
        // XQuery F&O 7.6.1: The regular expression is invalid if a back-
        // reference refers to a subexpression that does not exist or whose
        // closing right parenthesis occurs after the back-reference.
        //
        if ( backref_no > cap_sub.size() )
          throw INVALID_RE_EXCEPTION( NonexistantBackRef );
        if ( cap_sub[ backref_no - 1 ] )
          throw INVALID_RE_EXCEPTION( NonClosedBackRef );
      }
      switch ( *xq_c ) {
        case '\\':
          got_backslash = true;
          continue;
        case '(':
          cap_sub.push_back( true );
          break;
        case ')':
          if ( cap_sub.empty() )
            throw INVALID_RE_EXCEPTION( UnbalancedParen );
          if ( !cap_sub.back() )
            throw INVALID_RE_EXCEPTION( UnbalancedParen );
          cap_sub.back() = false;
          break;
        case '[':
          in_char_class = true;
          break;
        case ']':
          in_char_class = false;
          break;
        default:
          if ( x_flag && ascii::is_space( *xq_c ) ) {
            if ( !in_char_class )
              continue;
            //
            // This is similar to the above case for removing whitespace except
            // ICU removes *all* whitespace (even within character classes)
            // unless the whitespace is escaped; hence we have to escape it.
            //
            *icu_re += '\\';
          }
      }
    }
    *icu_re += *xq_c;
  } // FOR_EACH

  if ( i_flag ) {
    //
    // XQuery F&O 7.6.1.1: All other constructs are unaffected by the "i" flag.
    // For example, "\p{Lu}" continues to match upper-case letters only.
    //
    // However, ICU lower-cases everything for the 'i' flag; hence we have to
    // turn off the 'i' flag for just the \p{Lu}.
    //
    // Note that the "6" and "12" below are correct since "\\" represents a
    // single '\'.
    //
    ascii::replace_all( *icu_re, "\\p{Lu}", 6, "(?-i:\\p{Lu})", 12 );
  }

  //
  // XML Schema Part 2 F.1.1: [Unicode Database] groups code points into a
  // number of blocks such as Basic Latin (i.e., ASCII), Latin-1 Supplement,
  // Hangul Jamo, CJK Compatibility, etc. The set containing all characters
  // that have block name X (with all white space stripped out), can be
  // identified with a block escape \p{IsX}.
  //
  // However, ICU uses \p{InX} rather than \p{IsX}.
  //
  // Note that the "5" below is correct since "\\" represents a single '\'.
  //
  ascii::replace_all( *icu_re, "\\p{Is", 5, "\\p{In", 5 );
}

///////////////////////////////////////////////////////////////////////////////

#ifndef ZORBA_NO_UNICODE

namespace unicode {

bool regex::compile( string const &pattern, char const *flags ) {
  UErrorCode status = U_ZERO_ERROR;
  delete matcher_;
  matcher_ = new RegexMatcher( pattern, convert_xquery_flags( flags ), status );
  if ( U_FAILURE( status ) ) {
    delete matcher_;
    matcher_ = 0;
    return false;
  }
  return true;
}

bool regex::match_part( string const &s ) {
  assert( matcher_ );
  matcher_->reset( s );
  return matcher_->find() != 0;
}

bool regex::match_whole( string const &s ) {
  assert( matcher_ );
  matcher_->reset( s );
  UErrorCode status = U_ZERO_ERROR;
  return matcher_->matches( status ) && U_SUCCESS( status );
}

bool regex::next( re_type_t re_type, string const &s, size_type *pos,
                  string *substring, bool *matched ) {
  assert( matcher_ );
  assert( pos );
  unicode::size_type const s_len = s.length();
  if ( *pos < s_len ) {
    matcher_->reset( s );
    UErrorCode status = U_ZERO_ERROR;
    if ( matcher_->find( *pos, status ) ) {
      size_type const end = matcher_->end( status );
      if ( substring ) {
        size_type const start = matcher_->start( status );
        switch ( re_type ) {
          case re_is_match:
            substring->setTo( s, start, end - start );
            break;
          case re_is_separator:
            substring->setTo( s, *pos, start - *pos );
            break;
        }
      }
      *pos = end;
      if ( matched )
        *matched = true;
      return true;
    }
    if ( re_type == re_is_separator ) {
      //
      // Special case: the RE did not match starting at pos, but there *is* a
      // last token.  For example, given the RE of "," and:
      //
      //    s   = "a,b,c"
      //    pos =  01234
      //
      // then calling next_token() with a pos of 4 will not match another ","
      // but we should return the final token after the last "," (the "c").
      //
      if ( substring )
        substring->setTo( s, *pos, s_len - *pos );
      *pos = s_len;
      if ( matched )
        *matched = false;
      return true;
    }
  }
  if ( matched )
    *matched = false;
  return false;
}

bool regex::replace_all( string const &in, string const &replacement,
                         string *out ) {
  assert( matcher_ );
  assert( out );
  matcher_->reset( in );
  UErrorCode status = U_ZERO_ERROR;
  *out = matcher_->replaceAll( replacement, status );
  return U_SUCCESS( status ) == TRUE;
}

bool regex::replace_all( char const *in, char const *replacement,
                         string *out ) {
  string u_in, u_replacement;
  return  to_string( in, &u_in ) &&
          to_string( replacement, &u_replacement ) &&
          replace_all( u_in, u_replacement, out );
}

} // namespace unicode

#endif /* ZORBA_NO_UNICODE */

///////////////////////////////////////////////////////////////////////////////

} // namespace zorba
/* vim:set et sw=2 ts=2: */
<commit_msg>Attempt at fixing ICU regex link error.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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.
 */

#include <cstring>
#include <vector>

#include <zorba/error_list.h>
#include <zorba/xquery_exception.h>

#include "zorbaerrors/dict.h"

#include "ascii_util.h"
#include "regex.h"
#include "stl_util.h"

using namespace std;
U_NAMESPACE_USE

#define bs_c "\\p{L}\\d.:\\p{M}-"       /* \c equivalent contents */
#define bs_i "\\p{L}_:"                 /* \i equivalent contents */

namespace zorba {

///////////////////////////////////////////////////////////////////////////////

typedef uint32_t icu_flags_t;

static icu_flags_t convert_xquery_flags( char const *xq_flags ) {
  icu_flags_t icu_flags = 0;
  if ( xq_flags ) {
    for ( char const *f = xq_flags; *f; ++f ) {
      switch ( *f ) {
        case 'i': icu_flags |= UREGEX_CASE_INSENSITIVE; break;
        case 'm': icu_flags |= UREGEX_MULTILINE       ; break;
        case 's': icu_flags |= UREGEX_DOTALL          ; break;
        case 'x': icu_flags |= UREGEX_COMMENTS        ; break;
        default:
          throw XQUERY_EXCEPTION( FORX0001, ERROR_PARAMS( *f ) );
      }
    }
  }
  return icu_flags;
}

#define INVALID_RE_EXCEPTION(ZED_KEY) \
  XQUERY_EXCEPTION( FORX0002, ERROR_PARAMS( ZED( ZED_KEY ) ) )

void convert_xquery_re( zstring const &xq_re, zstring *icu_re,
                        char const *xq_flags ) {
  icu_flags_t const icu_flags = convert_xquery_flags( xq_flags );
  bool const i_flag = icu_flags & UREGEX_CASE_INSENSITIVE;
  bool const x_flag = icu_flags & UREGEX_COMMENTS;

  icu_re->clear();
  icu_re->reserve( xq_re.length() );    // approximate

  bool got_backslash = false;
  bool in_char_class = false;           // within [...]

  bool in_backref = false;              // '\'[1-9][0-9]*
  unsigned backref_no = 0;
  vector<bool> cap_sub;                 // true = open; false = closed

  FOR_EACH( zstring, xq_c, xq_re ) {
    if ( got_backslash ) {
      if ( x_flag && !in_char_class && ascii::is_space( *xq_c ) ) {
        //
        // XQuery F&O: 7.6.1.1: If [the 'x' flag is] present, whitespace
        // characters ... in the regular expression are removed prior to
        // matching with one exception: whitespace characters within character
        // class expressions ... are not removed.
        //
        continue;
      }
      got_backslash = false;
      switch ( *xq_c ) {
        case 'c': // NameChar
          *icu_re += "[" bs_c "]";
          continue;
        case 'C': // ^\c
          *icu_re += "[^" bs_c "]";
          continue;
        case 'i': // initial NameChar
          *icu_re += "[" bs_i "]";
          continue;
        case 'I': // ^\i
          *icu_re += "[^" bs_i "]";
          continue;
        default:
          if ( ascii::is_digit( *xq_c ) ) {
            backref_no = *xq_c - '0';
            if ( !backref_no )          // \0 is illegal
              throw INVALID_RE_EXCEPTION( BackRef0Illegal );
            if ( in_char_class ) {
              //
              // XQuery F&O 7.6.1: Within a character class expression,
              // \ followed by a digit is invalid.
              //
              throw INVALID_RE_EXCEPTION( BackRefIllegalInCharClass );
            }
            in_backref = true;
          }
          *icu_re += '\\';
          break;
      }
    } else {
      if ( in_backref ) {
        //
        // XQuery F&O 7.6.1: The construct \N where N is a single digit is
        // always recognized as a back-reference; if this is followed by
        // further digits, these digits are taken to be part of the back-
        // reference if and only if the resulting number NN is such that the
        // back-reference is preceded by NN or more unescaped opening
        // parentheses.
        //
        if ( cap_sub.size() > 9 && ascii::is_digit( *xq_c ) )
          backref_no = backref_no * 10 + (*xq_c - '0');
        else
          in_backref = false;
        //
        // XQuery F&O 7.6.1: The regular expression is invalid if a back-
        // reference refers to a subexpression that does not exist or whose
        // closing right parenthesis occurs after the back-reference.
        //
        if ( backref_no > cap_sub.size() )
          throw INVALID_RE_EXCEPTION( NonexistantBackRef );
        if ( cap_sub[ backref_no - 1 ] )
          throw INVALID_RE_EXCEPTION( NonClosedBackRef );
      }
      switch ( *xq_c ) {
        case '\\':
          got_backslash = true;
          continue;
        case '(':
          cap_sub.push_back( true );
          break;
        case ')':
          if ( cap_sub.empty() )
            throw INVALID_RE_EXCEPTION( UnbalancedParen );
          if ( !cap_sub.back() )
            throw INVALID_RE_EXCEPTION( UnbalancedParen );
          cap_sub.back() = false;
          break;
        case '[':
          in_char_class = true;
          break;
        case ']':
          in_char_class = false;
          break;
        default:
          if ( x_flag && ascii::is_space( *xq_c ) ) {
            if ( !in_char_class )
              continue;
            //
            // This is similar to the above case for removing whitespace except
            // ICU removes *all* whitespace (even within character classes)
            // unless the whitespace is escaped; hence we have to escape it.
            //
            *icu_re += '\\';
          }
      }
    }
    *icu_re += *xq_c;
  } // FOR_EACH

  if ( i_flag ) {
    //
    // XQuery F&O 7.6.1.1: All other constructs are unaffected by the "i" flag.
    // For example, "\p{Lu}" continues to match upper-case letters only.
    //
    // However, ICU lower-cases everything for the 'i' flag; hence we have to
    // turn off the 'i' flag for just the \p{Lu}.
    //
    // Note that the "6" and "12" below are correct since "\\" represents a
    // single '\'.
    //
    ascii::replace_all( *icu_re, "\\p{Lu}", 6, "(?-i:\\p{Lu})", 12 );
  }

  //
  // XML Schema Part 2 F.1.1: [Unicode Database] groups code points into a
  // number of blocks such as Basic Latin (i.e., ASCII), Latin-1 Supplement,
  // Hangul Jamo, CJK Compatibility, etc. The set containing all characters
  // that have block name X (with all white space stripped out), can be
  // identified with a block escape \p{IsX}.
  //
  // However, ICU uses \p{InX} rather than \p{IsX}.
  //
  // Note that the "5" below is correct since "\\" represents a single '\'.
  //
  ascii::replace_all( *icu_re, "\\p{Is", 5, "\\p{In", 5 );
}

///////////////////////////////////////////////////////////////////////////////

#ifndef ZORBA_NO_UNICODE

namespace unicode {

bool regex::compile( string const &pattern, char const *flags ) {
  UErrorCode status = U_ZERO_ERROR;
  delete matcher_;
  matcher_ = new RegexMatcher( pattern, convert_xquery_flags( flags ), status );
  if ( U_FAILURE( status ) ) {
    delete matcher_;
    matcher_ = 0;
    return false;
  }
  return true;
}

bool regex::match_part( string const &s ) {
  assert( matcher_ );
  matcher_->reset( s );
  return matcher_->find() != 0;
}

bool regex::match_whole( string const &s ) {
  assert( matcher_ );
  matcher_->reset( s );
  UErrorCode status = U_ZERO_ERROR;
  return matcher_->matches( status ) && U_SUCCESS( status );
}

bool regex::next( re_type_t re_type, string const &s, size_type *pos,
                  string *substring, bool *matched ) {
  assert( matcher_ );
  assert( pos );
  unicode::size_type const s_len = s.length();
  if ( *pos < s_len ) {
    matcher_->reset( s );
    UErrorCode status = U_ZERO_ERROR;
    if ( matcher_->find( *pos, status ) ) {
      size_type const end = matcher_->end( status );
      if ( substring ) {
        size_type const start = matcher_->start( status );
        switch ( re_type ) {
          case re_is_match:
            substring->setTo( s, start, end - start );
            break;
          case re_is_separator:
            substring->setTo( s, *pos, start - *pos );
            break;
        }
      }
      *pos = end;
      if ( matched )
        *matched = true;
      return true;
    }
    if ( re_type == re_is_separator ) {
      //
      // Special case: the RE did not match starting at pos, but there *is* a
      // last token.  For example, given the RE of "," and:
      //
      //    s   = "a,b,c"
      //    pos =  01234
      //
      // then calling next_token() with a pos of 4 will not match another ","
      // but we should return the final token after the last "," (the "c").
      //
      if ( substring )
        substring->setTo( s, *pos, s_len - *pos );
      *pos = s_len;
      if ( matched )
        *matched = false;
      return true;
    }
  }
  if ( matched )
    *matched = false;
  return false;
}

bool regex::replace_all( string const &in, string const &replacement,
                         string *out ) {
  assert( matcher_ );
  assert( out );
  matcher_->reset( in );
  UErrorCode status = U_ZERO_ERROR;
  *out = matcher_->replaceAll( replacement, status );
  return U_SUCCESS( status ) == TRUE;
}

bool regex::replace_all( char const *in, char const *replacement,
                         string *out ) {
  string u_in, u_replacement;
  return  to_string( in, &u_in ) &&
          to_string( replacement, &u_replacement ) &&
          replace_all( u_in, u_replacement, out );
}

} // namespace unicode

#endif /* ZORBA_NO_UNICODE */

///////////////////////////////////////////////////////////////////////////////

} // namespace zorba
/* vim:set et sw=2 ts=2: */
<|endoftext|>


<commit_before>#include <iostream>
#include <Common/TupleUtils.h>
#include <vector>

template <typename ...Iterators>
class ZipIterator
{
public:
  ZipIterator(Iterators... iterators) : m_iterators(iterators...) {}

	ZipIterator<Iterators...>& operator ++ ()
	{
		TupleUtils::ApplyFunction(Increment(),m_iterators);
		return *this;
	}

	ZipIterator<Iterators...> operator[](size_t i) const
	{
		auto advanced_it = *this;
		while ( i != 0 )
		{
			++advanced_it;
			--i;
		}
    return advanced_it;
	}

private:
  struct Increment
	{
		template <typename T>
		T& operator()(T& t)
		{
			return ++t;
		}
	};

	std::tuple<Iterators...> m_iterators;
};

template <typename ...Iterators>
ZipIterator<Iterators...> make_zip_iterator(Iterators... iterators)
{
	return ZipIterator<Iterators...>(iterators...);
}

int main(int argc, char* argv[])
{
	std::vector<int> ints = {1,2,3,4,5};
	std::vector<std::string> words = {"one","two","three","four","five"};

	auto it_begin = make_zip_iterator(ints.begin(), words.begin());
	auto it_end = make_zip_iterator(ints.end(), words.end());

	++it_begin;
	it_begin[3];
}

<commit_msg>Progress made on zip iterator<commit_after>#include <iostream>
#include <Common/TupleUtils.h>
#include <vector>

template <typename ...Iterators>
class ZipIterator
{
public:
  ZipIterator(Iterators... iterators) : m_iterators(iterators...) {}

	ZipIterator<Iterators...>& operator ++ ()
	{
		TupleUtils::ApplyFunction(Increment(),m_iterators);
		return *this;
	}

	ZipIterator<Iterators...> operator[](size_t i) const
	{
		auto advanced_it = *this;
		while ( i != 0 )
		{
			++advanced_it;
			--i;
		}
    return advanced_it;
	}

private:
  struct Increment
	{
		template <typename T>
		T& operator()(T& t)
		{
			return ++t;
		}
	};

	std::tuple<Iterators...> m_iterators;

public:

	template <int N>
  static auto Get(ZipIterator<Iterators...>& z) -> decltype(*std::get<N>(z.m_iterators))
	{
		return *std::get<N>(z.m_iterators);
	}

};

#define ZipIterator_Get(N,x) decltype(x)::Get<N>(x)

template <typename ...Iterators>
ZipIterator<Iterators...> make_zip_iterator(Iterators... iterators)
{
	return ZipIterator<Iterators...>(iterators...);
}

int main(int argc, char* argv[])
{
	std::vector<int> ints = {1,2,3,4,5};
	std::vector<std::string> words = {"one","two","three","four","five"};

	auto it_begin = make_zip_iterator(ints.begin(), words.begin());

	for (size_t i=0; i<ints.size(); ++i, ++it_begin)
	{
		std::cout << ZipIterator_Get(0,it_begin) << " " << ZipIterator_Get(1,it_begin) << std::endl;
	}
}

<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <cmath>

#include "v3ctor.h"
#include "SubdivisionAlgorithms/Liepa.h"

double area_and_density(psalm::mesh& M)
{
	double area = 0.0;
	for(size_t i = 0; i < M.num_faces(); i++)
	{
		psalm::face* f = M.get_face(i);
		for(size_t j = 0; j < 3; j++)
		{
			v3ctor a = f->get_vertex(1)->get_position() - f->get_vertex(0)->get_position();
			v3ctor b = f->get_vertex(2)->get_position() - f->get_vertex(0)->get_position();

			area += 0.5*(a|b).length();
		}
	}

	std::cerr	<< "(area, density) = " << "("
			<< std::fixed << std::setprecision(4) << area << ","
			<< std::fixed << std::setprecision(4) << (M.num_vertices()/area)
			<< ")" << "\n";

	return(M.num_vertices()/area);
}

int main(int argc, char* argv[])
{
	psalm::mesh M;
	psalm::Liepa liepa_scheme;

	M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0008.ply");
	std::cout << "INITIAL: " << area_and_density(M) << "\n";

	/*
	for(int i = 0; i <= 10; i++)
	{
		double alpha = i*3;

		M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0025.ply");

		liepa_scheme.set_alpha(alpha);
		liepa_scheme.apply_to(M);

		std::cout << (alpha) << "\t" << area_and_density(M) << std::endl;
	}
	*/

	M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0008.ply");
	liepa_scheme.set_alpha(sqrt(2));
	liepa_scheme.apply_to(M);

	std::cout << "END: " << area_and_density(M) << "\n";
	return(0);
}
<commit_msg>More tests in density test program<commit_after>#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <utility>

#include "v3ctor.h"
#include "SubdivisionAlgorithms/Liepa.h"

std::pair<double, double> area_and_density(psalm::mesh& M, double initial_area = 0.0)
{
	std::pair<double, double> result;

	result.first = initial_area;
	if(initial_area == 0.0)
	{
		for(size_t i = 0; i < M.num_faces(); i++)
		{
			psalm::face* f = M.get_face(i);
			for(size_t j = 0; j < 3; j++)
			{
				v3ctor a = f->get_vertex(1)->get_position() - f->get_vertex(0)->get_position();
				v3ctor b = f->get_vertex(2)->get_position() - f->get_vertex(0)->get_position();

				result.first += 0.5*(a|b).length();
			}
		}
	}
	result.second = M.num_vertices()/result.first;

	std::cerr	<< "(area, density) = " << "("
			<< std::fixed << std::setprecision(4) << result.first << ","
			<< std::fixed << std::setprecision(4) << result.second
			<< ")" << "\n";

	return(result);
}

int main(int argc, char* argv[])
{
	psalm::mesh M;
	psalm::Liepa liepa_scheme;

	if(argc == 1)
		return(0);

	for(int i = 2; i < argc; i++)
	{
		M.load(argv[i]);
		std::pair<double, double> area_density = area_and_density(M);

		double initial_area = area_density.first;
		double initial_density = area_density.second;

		for(int j = 0; j < 49; j++)
		{
			double alpha = j*0.1;

			M.load(argv[i]);

			liepa_scheme.set_alpha(alpha);
			liepa_scheme.apply_to(M);

			std::cout	<< (initial_density) << "\t"
					<< (initial_area) << "\t"
					<< (area_and_density(M, initial_area).second-initial_density) << "\t"
					<< (alpha)
					<< std::endl;
		}

		std::cout << "\n\n";
	}

	return(0);

	/*

	//M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0008.ply");
	//std::cout << "INITIAL: " << area_and_density(M) << "\n";

	for(int i = 1; i <= 100; i++)
	{
		double alpha = i*0.05;

		M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0025.ply");

		liepa_scheme.set_alpha(alpha);
		liepa_scheme.apply_to(M);

		std::cout << (alpha) << "\t" << area_and_density(M) << std::endl;
	}

	//M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0008.ply");
	//liepa_scheme.set_alpha(sqrt(2));
	//liepa_scheme.apply_to(M);

	std::cout << "\n\n";
	for(int i = 1; i <= 100; i++)
	{
		double alpha = i*0.05;

		M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0008.ply");

		liepa_scheme.set_alpha(alpha);
		liepa_scheme.apply_to(M);

		std::cout << (alpha) << "\t" << area_and_density(M) << std::endl;
	}

	std::cout << "\n\n";
	for(int i = 1; i <= 100; i++)
	{
		double alpha = i*0.05;

		M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0009.ply");

		liepa_scheme.set_alpha(alpha);
		liepa_scheme.apply_to(M);

		std::cout << (alpha) << "\t" << area_and_density(M) << std::endl;
	}

	std::cout << "\n\n";
	for(int i = 1; i <= 100; i++)
	{
		double alpha = i*0.05;

		M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0010.ply");

		liepa_scheme.set_alpha(alpha);
		liepa_scheme.apply_to(M);

		std::cout << (alpha) << "\t" << area_and_density(M) << std::endl;
	}

	std::cout << "\n\n";
	for(int i = 1; i <= 100; i++)
	{
		double alpha = i*0.05;

		M.load("../Holes/Salmanassar3_Holes_w_Normals_HR_CLEAN_with_Indices.pline_0000_0011.ply");

		liepa_scheme.set_alpha(alpha);
		liepa_scheme.apply_to(M);

		std::cout << (alpha) << "\t" << area_and_density(M) << std::endl;
	}

	*/

	//std::cerr << "END: " << area_and_density(M) << "\n";
	return(0);
}
<|endoftext|>


<commit_before><commit_msg>Keep tinderbox happy.<commit_after><|endoftext|>


<commit_before><commit_msg>This doesn't have to be public.<commit_after><|endoftext|>


<commit_before>#include "gc_init.h"

#include <iostream>

#include "details/thread_list.h"
#include "details/gc_pause.h"
#include "details/gc_initator.h"
#include "details/logging.h"

namespace precisegc {

static bool init_flag = false;

static void create_first_thread()
{
    thread_handler first_thread;
    first_thread.pthread = pthread_self();
//    first_thread.stack = StackMap::getInstance();
    first_thread.flags = 0;
    first_thread.routine = nullptr;
    first_thread.arg = nullptr;
    first_thread.stack.reset(new StackMap());
    first_thread.pins.reset(new StackMap());
    first_thread.mark_queue.reset(new details::gc_mark_queue());
    details::thread_list::instance().insert(first_thread);

    details::logging::info() << "Thread " << pthread_self() << " main";
}

int gc_init()
{
    if (!init_flag) {
        details::logging::init(std::clog, details::logging::loglevel::INFO);

        create_first_thread();
        details::gc_pause_init();

        const size_t MEM_UPPER_BOUND = 128 * 1024 * 1024;
        details::init_initator(0.5 * MEM_UPPER_BOUND, MEM_UPPER_BOUND);

        init_flag = true;
    }

    return 0;
}

}
<commit_msg>modify gc_init<commit_after>#include "gc_init.h"

#include <iostream>

#include "details/thread_list.h"
#include "details/gc_pause.h"
#include "details/gc_initator.h"
#include "details/logging.h"

namespace precisegc {

static bool init_flag = false;

static void create_first_thread()
{
    thread_handler first_thread;
    first_thread.pthread = pthread_self();
//    first_thread.stack = StackMap::getInstance();
    first_thread.flags = 0;
    first_thread.routine = nullptr;
    first_thread.arg = nullptr;
    first_thread.stack.reset(new StackMap());
    first_thread.pins.reset(new StackMap());
    first_thread.mark_queue.reset(new details::gc_mark_queue());
    details::thread_list::instance().insert(first_thread);

    details::logging::info() << "Thread " << pthread_self() << " main";
}

int gc_init()
{
    if (!init_flag) {
        details::logging::init(std::clog, details::logging::loglevel::OFF);

        create_first_thread();
        details::gc_pause_init();

        const size_t MEM_UPPER_BOUND = 32 * 1024 * 1024;
        details::init_initator(0.5 * MEM_UPPER_BOUND, MEM_UPPER_BOUND);

        init_flag = true;
    }

    return 0;
}

}
<|endoftext|>