Exemplo n.º 1
0
/*-----------------------------------------------------------------------------
 *      CAM_SetQVGA:  Configure display size to QVGA (240*320)
 *
 *  Parameters: (none)
 *  Return:     (none)
 *----------------------------------------------------------------------------*/
static void CAM_SetQVGA (void) {
  uint32_t i;

  for (i = 0; i < ARR_SZ(CAM_RegInit); i++) {
    CAM_WrReg (CAM_RegInit[i].Addr, CAM_RegInit[i].Val);
  }

  for (i = 0; i < ARR_SZ(CAM_RegSz); i++) {
    CAM_WrReg (CAM_RegSz[i].Addr, CAM_RegSz[i].Val);
  }
}
Exemplo n.º 2
0
/***********************************************************************
*                  GPIO manager                                        *
************************************************************************/
int emcConfigurePin( int index , egpMode mode )
{
	if( index < 0 || index >= ARR_SZ(GPIOS) )
		return -1;
	if( gpio_in_use[index] != egpNone )
		return -2;
	if( iomem == NULL )
	{
		iomem = mapIoRegister( GPIO_MAP_FADDR, GPIO_MAP_SIZE );
		if( iomem == NULL)
			return -3;
	}
	int pcon_of = (GPIOS[index].PCON - GPIO_MAP_FADDR)/sizeof(int);
	int of_idx     = GPIOS[index].offset;

	// Clear GPIO mode to zero (input )
	*(iomem + pcon_of ) &= ~(3L << (of_idx*2));
	if( mode == egpOut )
	{
		*(iomem + pcon_of) |= (1L << (of_idx*2));
	} else if( mode == egpPerif )
	{
	   *(iomem + pcon_of) |= (2L << (of_idx*2));
	}
	//printf( "PCON[%p]=%x\n",(void*)(iomem + pcon_of), *(iomem + pcon_of ) );
	gpio_in_use[index] = mode;
	return 0;
}
Exemplo n.º 3
0
static void set_data_template(void)
{
	int i, start;
	struct flowset_header *flowset;
	struct data_template_header *data_template;
	struct template_field *field;

	start = pos;

	flowset = (void*)&accum[pos];
	pos += sizeof (*flowset);
	flowset->id = htobe16(0); //Data Template V9

	data_template = (void*)&accum[pos];
	pos += sizeof (*data_template);

	data_template->template_id = htobe16(259);
	data_template->field_count = 0; /*convert endianess at the end */

	for (i = 0; i < ARR_SZ(data); i++)
	{
		field = (void*)&accum[pos];
		pos += sizeof (*field);

		field->type = htobe16(data[i].field);
		field->length = htobe16(data[i].len);
		data_template->field_count++;
	}

	flowset->length = pos-start;
//	printf("--------------\ncnt %d, len %d\n============\n", data_template->field_count, flowset->length);
	flowset->length = htobe16(flowset->length);
	data_template->field_count = htobe16(data_template->field_count);
}
Exemplo n.º 4
0
int emcReservePin( int index )
{
	if( index < 0 || index >= ARR_SZ(GPIOS) )
		return -1;
	if( gpio_in_use[index] == egpNone )
		return -2;
	gpio_in_use[index] = egpRsv;
	return 0;
}
Exemplo n.º 5
0
int emcGetPin( int index )
{
	if( index < 0 || index >= ARR_SZ(GPIOS) )
		return -1;

	if(  gpio_in_use[index] != egpNone )
	{
		int pdat_of = (GPIOS[index].PDAT - GPIO_MAP_FADDR)/sizeof(int);
		int of_idx  = GPIOS[index].offset;
		return (*(iomem + pdat_of ) & (1LL << of_idx)) != 0;
	}
	return -2;
}
Exemplo n.º 6
0
int emcGetPinByName( const char* PinName )
{
    int i, rc = -1;
    for( i =0; i <  ARR_SZ(GPIOS); i++ )
    {
        if( strcmp( PinName, GPIOS[i].name) == 0 )
        {
            rc = i;
            break;
        }
    }
    printf("%s index=%d\n", PinName, i );
    return i;
}
Exemplo n.º 7
0
void pins_exit()
{
    int i;
    for(i=0; i < num_axis; i++)
    {
        fiq_static.axis[i].configured = 0;
    }
    ioctl(pgpio->fd, AXIS_SET_IOCTL, &fiq_static );

    for( i=0; i < ARR_SZ(GPIOS); i++ )
    {
      emcDeConfigurePin( i );
    }
}
Exemplo n.º 8
0
void emcSetPin(int index, int value )
{
	if( index < 0 || index >= ARR_SZ(GPIOS) )
		return;
	if(  gpio_in_use[index] == egpOut )
	{
		if(pgpio->pfiq )
		{
		    int of_idx  = 1 << GPIOS[index].offset;
		    if( value )
                pgpio->pfiq->gpios.gpio_set_reg[GPIOS[index].port_index] |= of_idx;
            else
                pgpio->pfiq->gpios.gpio_clr_reg[GPIOS[index].port_index] |= of_idx;
 		}
	}
}
Exemplo n.º 9
0
static int mm_jpegdec_test_get_input(int argc, char *argv[],
    jpeg_test_input_t *p_test)
{
  int c;

  while ((c = getopt(argc, argv, "I:O:W:H:F:")) != -1) {
    switch (c) {
    case 'O':
      p_test->out_filename = optarg;
      fprintf(stderr, "%-25s%s\n", "Output image path",
        p_test->out_filename);
      break;
    case 'I':
      p_test->filename = optarg;
      fprintf(stderr, "%-25s%s\n", "Input image path", p_test->filename);
      break;
    case 'W':
      p_test->width = atoi(optarg);
      fprintf(stderr, "%-25s%d\n", "Default width", p_test->width);
      break;
    case 'H':
      p_test->height = atoi(optarg);
      fprintf(stderr, "%-25s%d\n", "Default height", p_test->height);
      break;
    case 'F': {
      int format = 0;
      format = atoi(optarg);
      int num_formats = ARR_SZ(col_formats);
      CLAMP(format, 0, num_formats);
      p_test->format = col_formats[format].eColorFormat;
      fprintf(stderr, "%-25s%s\n", "Default image format",
        col_formats[format].format_str);
      break;
    }
    default:;
    }
  }
  if (!p_test->filename || !p_test->filename || !p_test->width ||
      !p_test->height) {
    fprintf(stderr, "Missing required arguments.\n");
    omx_test_dec_print_usage();
    return -1;
  }
  return 0;
}
Exemplo n.º 10
0
void
build_mstbn_col(void *g[], void *parent, int x, int y, int rows, void *f)
{
	int   i;
	int   j;
	char *bgx0[] = {
		PST_UNKNOWN0,
		PST_DISARM0,
		PST_PTBYPASS0,
		PST_BYPASS0,
		PST_NRDY0,
		PST_PTARM0,
		PST_ARM0,
		PST_FRCARM0,
		PST_TMRARM0,
		PST_ALARM0,
		PST_ALARMR0
	};
	
	char *bgx1[] = {
		PST_UNKNOWN1,
		PST_DISARM1,
		PST_PTBYPASS1,
		PST_BYPASS1,
		PST_NRDY1,
		PST_PTARM1,
		PST_ARM1,
		PST_FRCARM1,
		PST_TMRARM1,
		PST_ALARM1,
		PST_ALARMR1
	};

	for (i = 0; i < rows; ++i) {
		g[i] = utk_mst_button_new();
		utk_mst_button_set_type((UtkMSTButton *)g[i]);
		for (j = 0; j < ARR_SZ(bgx0); ++j) {
			utk_mst_button_set_bg((UtkMSTButton*)g[i], bgx0[j]);
			utk_mst_button_set_bg((UtkMSTButton*)g[i], bgx1[j]);
		}
		utk_signal_connect(g[i], "clicked", f, (void*)i);
		utk_widget_add_cntl(parent, g[i], x, y+i*row_h);
	}
}
Exemplo n.º 11
0
int emcDeConfigurePin( int index )
{
	if( index < 0 || index >= ARR_SZ(GPIOS) )
		return -1;
	if( gpio_in_use[index] == egpNone )
		return -2;
	if( iomem == NULL )
	{
		iomem = mapIoRegister( GPIO_MAP_FADDR, GPIO_MAP_SIZE );
		if( iomem == NULL)
			return -3;
	}
	int pcon_of = (GPIOS[index].PCON - GPIO_MAP_FADDR)/sizeof(int);
	int of_idx     = GPIOS[index].offset;

	// Clear GPIO mode to zero (input )
	*(iomem + pcon_of ) &= ~(3L << (of_idx*2));
	gpio_in_use[index] = egpNone;
	return 0;
}
Exemplo n.º 12
0
void process_io()
{
    int i;
     for( i=0; i < ARR_SZ(GPIOS); i++ )
    {
        if(  emcGetPinMode( i ) == egpRsv )
            continue;
        if( emcGetPinMode( i ) == egpIn )
        {
            int val = *( pgpio->io_invert[i]) ^ emcGetPin(i);
           *( pgpio->io_pin[i] ) = val == 0 ? 0 : 1;
        } else if( emcGetPinMode( i ) == egpOut )
        {
            int val = *( pgpio->io_pin[i] ) ^ *( pgpio->io_invert[i]);
            emcSetPin( i, val );
        }
    }
    pgpio->pfiq->gpios_changed = 1;
    for( i = 0; i < MAX_PWM; i++)
        emcPWMSetDutyCycle( i ,  *(pgpio->pwm_duty[i]) );
}
Exemplo n.º 13
0
static void set_data(int random_val)
{
	int i, j, start;
	struct flowset_header *flowset;

	start = pos;

	flowset = (void*)&accum[pos];
	pos += sizeof (*flowset);
	flowset->id = htobe16(259); /*Data*/

	j = random_val%3;
	for (i = 0; i < ARR_SZ(data); i++)
	{
		if (data[i].field == IN_BYTES)
			data[i].value[j][3] = (random_val & 0xff00)>>8;

		if (data[i].field == IN_PKTS)
			data[i].value[j][3] = (random_val & 0xff0000)>>16;

		memcpy(&accum[pos], data[i].value[j], data[i].len);
		pos += data[i].len;
	}

	flowset->length = pos - start;

	while (flowset->length & 0x3)
	{
		pos++;
		flowset->length++;
	}


	flowset->length = pos-start;
//	printf("--------------\ndata len %d, pos %d\n============\n", flowset->length, pos);
	flowset->length = htobe16(flowset->length);
}
Exemplo n.º 14
0
static void cksum(struct ip6_hdr *iph, struct icmp6_hdr *icmp, int len)
{
  vec_t cv[2];
  struct {
    struct in6_addr src, dst;
    uint32_t len;
    uint32_t nxt;
  } psh[1];

  /* checksum pseudo header */
  memset(psh, 0, sizeof (*psh));
  memcpy(&psh->src, &iph->ip6_src, sizeof (psh->src));
  memcpy(&psh->dst, &iph->ip6_dst, sizeof (psh->dst));
  psh->len = htonl(len);
  psh->nxt = htonl(IPPROTO_ICMPV6);

  /* ICMP6 checksum */
  icmp->icmp6_cksum = 0;
  cv[0].ptr = (uint8_t *)psh;
  cv[0].len = sizeof (*psh);
  cv[1].ptr = (uint8_t *)icmp;
  cv[1].len = len;
  icmp->icmp6_cksum = in_cksum(cv, ARR_SZ(cv));
}
Exemplo n.º 15
0
int emcIsPinConfigured( int index )
{
	if( index < 0 || index >= ARR_SZ(GPIOS) )
		return -1;
	return gpio_in_use[index] != egpNone;
}
Exemplo n.º 16
0
 , { 3, 0x56000060, 0x56000064, 12, egpIn, "GPG12" }	// 10
 , { 4, 0x560000d0, 0x560000d4, 12, egpIn, "GPJ12" }	// 11
 , { 4, 0x560000d0, 0x560000d4, 11, egpIn, "GPJ11" }	// 12
 , { 4, 0x560000d0, 0x560000d4, 10, egpIn, "GPJ10" }	// 13
 , { 4, 0x560000d0, 0x560000d4, 9,  egpIn, "GPJ09" }	// 14
 , { 4, 0x560000d0, 0x560000d4, 8,  egpIn, "GPJ08" }	// 15
 , { 4, 0x560000d0, 0x560000d4, 7,  egpIn, "GPJ07" }	// 16
 , { 4, 0x560000d0, 0x560000d4, 6,  egpIn, "GPJ06" }	// 17
 , { 0, 0x56000010, 0x56000014, 1,  egpIn,"GPB01" }	// 18
};
#endif


#define ARR_SZ(x) ( sizeof(x)/sizeof(x[0]) )
static int* iomem = NULL;
static char gpio_in_use[  ARR_SZ(GPIOS) ] = {0};


/***********************************************************************
*                  IO MEMORY MAPPERS                                   *
************************************************************************/

#define MAP_SIZE			4096UL
#define MAP_MASK 			(MAP_SIZE - 1)

void *mapIoRegister(unsigned long addr, size_t length)
{
	void *map_base, * virtAddr;
	off_t target = ((unsigned int)addr) & ~MAP_MASK;
	int fd;
Exemplo n.º 17
0
int rtapi_app_main(void)
{
    int retval, i;
    int in_cnt = 0, out_cnt = 0;
    char buf[128];
    char *pc = axes_conf;

    /* Parsing axes configuration */
    while(*pc != 0)
    {
        int idx = -1;
        switch(*pc)
        {
            case 'X':
            case 'x':
                    idx = 0;
                    break;
            case 'Y':
            case 'y':
                    idx = 1;
                    break;

            case 'Z':
            case 'z':
                    idx = 2;
                    break;

            case 'A':
            case 'a':
                    idx = 3;
                    break;

            case 'B':
            case 'b':
                    idx = 4;
                    break;

            case 'C':
            case 'c':
                    idx = 5;
                    break;

            default: break;
        }
        if(idx >= 0)
            axis_map[num_axis++] = idx;
        pc++;
    }

    fprintf(stderr, "num_axis=%d, fifo_size=%d\n", num_axis, fifo_deep);

    /* test for number of channels */
    if ((num_axis <= 0) || (num_axis > MAX_AXIS)) {
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "miniemcdrv: ERROR: invalid num_chan: %d\n", num_axis);
	return -EINVAL;
    }
    /* have good config info, connect to the HAL */
    comp_id = hal_init("miniemcdrv");
    if (comp_id < 0)
    {
        rtapi_print_msg(RTAPI_MSG_ERR, "miniemcdrv: ERROR: hal_init() failed\n");
        rtapi_app_exit();
        return -EINVAL;
    }
    pgpio = hal_malloc(sizeof(gpio_t));
    memset(pgpio, 0, sizeof(gpio_t));

    pgpio->fd = open("/dev/miniemc", O_RDWR | O_SYNC);

    if(pgpio->fd < 0)
    {
        rtapi_print_msg(RTAPI_MSG_ERR,
            "miniemcdrv: ERROR: unble to create access to stepgen module\n");
        rtapi_app_exit();
        return -EIO;
    }

    pgpio->pfiq = mmap(0, sizeof(struct fiq_ipc_shared), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, pgpio->fd, 0);
	if(pgpio->pfiq == MAP_FAILED)
	{
        rtapi_print_msg(RTAPI_MSG_ERR,
            "miniemcdrv: ERROR: unable to mmap stepgen ringbuffer\n");
        rtapi_app_exit();
        return -EIO;
	}

     /* Setup ringbuff size */
    fiq_static.rb_size = fifo_deep;

    memset(&cmd_pos_prev, 0, sizeof(cmd_pos_prev));
    memset(&cmd_pos_accum, 0, sizeof(cmd_pos_accum));

    //Configure PWM pins and create HAL inputs
    for( i = 0; i < MAX_PWM; i++)
    {
        rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.%d.pwm-in", i);
        retval = hal_pin_float_new(buf, HAL_IN, &(pgpio->pwm_duty[i]), comp_id);
        if (retval != 0)
        {
            rtapi_app_exit();
            return retval;
        }

        if( pwm_pin_num[i] >= 0 )
        {
            emcConfigureDefault( pwm_pin_num[i] );
            emcReservePin( pwm_pin_num[i] );
           fiq_static.pwm_pin_addr[i] =  GPIOS[pwm_pin_num[i]].port_index;
           fiq_static.pwm_pin_mask[i] =  1L << GPIOS[pwm_pin_num[i]].offset;
           pgpio->pfiq->pwm_duty_cycle[i] = 0;
        } else
        {
            fiq_static.pwm_pin_mask[i] = 0;
            fiq_static.pwm_pin_addr[i] = 0;
        }
    }

    // Create axis step and dir pins
    for(i = 0; i < num_axis; i++)
    {
        if(step_pins[i] >=0 && dir_pins[i] >= 0)
        {
            if( emcGetPinMode( step_pins[i]) == egpIn ||  emcGetPinMode( dir_pins[i]) == egpIn )
            {
                rtapi_print_msg(RTAPI_MSG_ERR, "WARN: can't create axis[%d] stepgen, invalid pin\n", i);
                continue;
            }
            fiq_static.axis[i].configured = 0;
            fiq_static.axis[i].step_pin_addr = GPIOS[step_pins[i]].port_index;
            fiq_static.axis[i].step_pin_mask = 1L << GPIOS[step_pins[i]].offset;
            emcConfigureDefault( step_pins[i] );
            emcReservePin( step_pins[i] );
            fiq_static.axis[i].dir_pin_addr = GPIOS[dir_pins[i]].port_index;
            fiq_static.axis[i].dir_pin_mask = 1L << GPIOS[dir_pins[i]].offset;
            emcConfigureDefault( dir_pins[i] );
            emcReservePin( dir_pins[i] );
            fiq_static.axis[i].dir_pin_pol = dir_polarity[i];
            fiq_static.axis[i].configured = 1;
        } else
        {
            rtapi_print_msg(RTAPI_MSG_ERR,
                "miniemcdrv: WARNING: axis[%d] step and/or dir pin(s) not properly configured, skipping\n", i);
        }
        fiq_static.scan_pin_num = -1;
    }

    ioctl(pgpio->fd, AXIS_SET_IOCTL, &fiq_static );
    /*
     * Create IO pins
     */

    for( i=0; i < ARR_SZ(GPIOS); i++ )
    {
        if(  emcGetPinMode( i ) == egpRsv )
            continue;
        if( emcGetPinMode( i ) == egpIn )
        {
            rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.%d.pin-in", in_cnt);
            hal_pin_bit_new(buf, HAL_OUT, &(pgpio->io_pin[i]), comp_id);
            rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.%d.pin-in-inv", in_cnt);
            hal_pin_bit_new(buf, HAL_IN, &(pgpio->io_invert[i]), comp_id);
            in_cnt++;
        } else
        {
            rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.%d.pin-out", out_cnt);
            hal_pin_bit_new(buf, HAL_IN, &(pgpio->io_pin[i]), comp_id);
            rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.%d.pin-out-inv", out_cnt);
            hal_pin_bit_new(buf, HAL_IN, &(pgpio->io_invert[i]), comp_id);
            out_cnt++;
        }
        emcConfigureDefault( i );
    }

	// Trajectory wait output
	rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.traj-wait-out");
	hal_pin_bit_new(buf, HAL_OUT, &(pgpio->traj_wait), comp_id);
    *(pgpio->traj_wait) = 1;

	// Scaner sync
	rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.scan-sync-in");
	hal_pin_bit_new(buf, HAL_IN, &(pgpio->scan_sync), comp_id);

    for(i=0; i < num_axis; i++)
    {
      // Check if pin already added
      char contin = 0;
      int j;
      for(j=0; j < i; j++)
        if(axis_map[j] == axis_map[i])
        {
            contin = 1;
            break;
        }
      if(contin) continue;

  	  // commanded position pin
	  rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.%d.cmd-pos", axis_map[i]);

  	  retval = hal_pin_float_new(buf, HAL_IN, &(pgpio->cmd_pos[axis_map[i]]), comp_id);
	  if (retval != 0)
	  {
        rtapi_app_exit();
		return retval;
	  }
	  //feedback position pin
	  rtapi_snprintf(buf, HAL_NAME_LEN, "miniemcdrv.%d.fb-pos", axis_map[i]);
  	  retval = hal_pin_float_new(buf, HAL_OUT, &(pgpio->fb_pos[axis_map[i]]), comp_id);
	  if (retval != 0)
	  {
        rtapi_app_exit();
		return retval;
	  }
    }



/* export functions */
    retval = hal_export_funct("update-miniemcdrv", update,
                                pgpio, 0, 0, comp_id);
    if (retval != 0)
    {
	rtapi_print_msg(RTAPI_MSG_ERR,
            "miniemcdrv: ERROR: count funct export failed\n");
        rtapi_app_exit();
        return -EIO;
    }

    ioctl(pgpio->fd, SCAN_PIN_SETUP_IOCTL, NULL);

    //emcConfigurePin(11, egpOut );
    //emcSetPin(11, 1 );

    hal_ready(comp_id);
    return 0;
}
Exemplo n.º 18
0
egpMode emcGetPinMode( int index )
{
	if( index < 0 || index >= ARR_SZ(GPIOS) )
		return -1;
	return GPIOS[index].mode;
}
Exemplo n.º 19
0
status_t
grade_article(article_t* article, lang_t* lang, float ratio)
{
    array_t     * a, * temp;
    word_t      * w;
    sentence_t  * s, * s_score;
    size_t        top_occs[] = { 0, 0, 0, 0}, occs, i, max_words;
    word_t      * top_words[] = { 0, 0, 0, 0};
    string_t      ws, ws_stem;
    bool_t        is_first = SMRZR_TRUE;

    PROF_START;

    /* find top occs and corresponding words */
    a = article->words;

    for(w = (word_t*)ARR_FIRST(a); !ARR_END(a); w = (word_t*)ARR_NEXT(a)) {
        for(occs = 0; occs < TOP_OCCS_MAX; ++occs) {
            if(top_occs[occs] < w->num_occ) {
                for(i = TOP_OCCS_MAX-1; i > occs; --i) {
                    top_occs[i] = top_occs[i-1];
                    top_words[i] = top_words[i-1];
                }
                top_occs[occs] = w->num_occ;
                top_words[occs] = w;
                break;
            }
        }
    }

    /*for(occs = 0; occs < TOP_OCCS_MAX; ++occs) {
        fprintf(stdout, "top occ %lu - %lu [%s]\n", occs, top_occs[occs],
               top_words[occs]->stem);
    }*/

    /* score all sentences */
    a = article->sentences;

    for(s=(sentence_t*)ARR_FIRST(a); !ARR_END(a); s=(sentence_t*)ARR_NEXT(a)) {

        ws = s->begin;

        while(ws < s->end) {

            while(0 == *ws && ws < s->end) ++ws;

            if(ws >= s->end) break;

            if(NULL == (ws_stem = get_word_stem(&article->stack, lang, ws,
                                                SMRZR_FALSE)))
                ERROR_RET;

            if(NULL == (w = (word_t*)array_search(article->words, ws_stem,
                                                  comp_word_by_stem)))
            { /* possibly a word excluded */
                ws = ws + strlen(ws);
                continue;
            }

            occs = 0;
            while(top_occs[occs] != w->num_occ && occs < TOP_OCCS_MAX) ++occs;

            switch(occ2score[occs]) {
                case 3: /* score += occ * 3 */
                    s->score += ((w->num_occ << 1) + w->num_occ); break;
                case 2: /* score += occ * 2 */
                    s->score += (w->num_occ << 1); break;
                case 1: /* score += occ */
                    s->score += w->num_occ; break;
                default: 
                    ERROR_RET;
            }

            ws = ws + strlen(ws);
        }

        if(SMRZR_TRUE == s->is_para_begin) {
            s->score *= 1.6;
        } else if(SMRZR_TRUE == is_first) {
            s->score = (s->score << 1); /* super-boost 1st line */
            is_first = SMRZR_FALSE;
        }

        /*fprintf(stdout, "%u ", s->score);*/
    }

    /*fprintf(stdout, "\n");*/

    /* sort on sentence score */
    if(NULL == (temp = array_new(SMRZR_TRUE, sizeof(sentence_t),
                                 ARR_SZ(article->sentences), NULL)))
        ERROR_RET;

    for(s=(sentence_t*)ARR_FIRST(a); !ARR_END(a); s=(sentence_t*)ARR_NEXT(a)) {
        if(NULL == (s_score = array_sorted_alloc(&temp, (elem_t)(size_t)(s->score),
                                                 comp_sentence_by_score)))
            ERROR_RET;

        memcpy(s_score, s, sizeof(sentence_t));
        s_score->cookie = (elem_t)s;
    }

    /* pick sentences with highest scores until we get required ratio of words*/
    max_words = article->num_words * ratio;

    a = temp;
    for(s=(sentence_t*)ARR_FIRST(a); !ARR_END(a) && (ssize_t)max_words > 0;
                                     s=(sentence_t*)ARR_NEXT(a))
    {
        ((sentence_t*)s->cookie)->is_selected = SMRZR_TRUE;
        max_words -= s->num_words;
        /*fprintf(stdout, "Selected sentence: score %u, %lu words, %ld
          remaining\n", s->score, s->num_words, (ssize_t)max_words);*/
    }

    array_free(temp);

    PROF_END("article grading");

    return(SMRZR_OK);
}