예제 #1
0
파일: list_test.c 프로젝트: AlgoLab/PIntron
/*
	create two empty lists,
	merge them into the first one,
	verify that the size of the merged list is 0,
	verify that the merged list is empty
*/
Test(listTest,mergeEmptyTest) {
	plist l1=list_create();
	plist l2=list_create();
	list_merge(l1,l2);
	cr_expect(list_size(l1)==0);
	cr_expect(list_is_empty(l1)==1);
}
예제 #2
0
파일: list.c 프로젝트: tpepper/swupd-client
/* Splits a list into two halves to be merged */
static struct list *list_merge_sort(struct list *left, unsigned int len, comparison_fn_t comparison_fn)
{
	struct list *right = NULL;
	unsigned int left_len = len / 2;
	unsigned int right_len = len / 2 + len % 2;
	unsigned int i;

	if (!left) {
		return NULL;
	}

	if (len == 1) {
		return left;
	}

	right = left;

	/* Split into left and right lists */
	for (i = 0; i < left_len; i++) {
		right = right->next;
	}
	right->prev->next = NULL;
	right->prev = NULL;

	/* Recurse */
	left = list_merge_sort(left, left_len, comparison_fn);
	right = list_merge_sort(right, right_len, comparison_fn);
	return list_merge(left, right, comparison_fn);
}
예제 #3
0
LElement * list_flat(LElement * list) {
  LElement * next_element;
  LElement * new_list;
  new_list = list_init();
  next_element = list;

//  printf("Plaszcze:\n");
//  status(list);
//  getchar();
  do {
    next_element = next_element->pointer;

    if (next_element->czy_lista) {
//      printf("To lista, rekursja!\n");
      new_list = list_merge(new_list, list_flat(next_element->sublist));
    } else {
//      printf("To wartosc!\n");
      new_list = list_push_value(new_list, next_element->value);
    }
  } while(next_element != list);
//  printf("...splaszczylem.\n");


  return new_list;
}
예제 #4
0
GList* get_kanji_by_radical(const gchar *radstrg, GHashTable *rad_info_hash) { 
  gint radnum;                   //number of character in radstrg
  RadInfo *rad_info;             
  GList *kanji_info_list = NULL;
  GList *result = NULL;          //list of matched kanji to return
  const gchar *radstrg_ptr;            //pointer to browse radstrg

  radnum = g_utf8_strlen(radstrg, -1); 
  if (radnum == 0) return;  //no character in radstrg

  //to navigate in the string
  int i;
  radstrg_ptr = radstrg;

  //for every characters in the string
  for(i=0;i<radnum; i++){

    //get the radical in utf8 format
    gunichar uniradical = g_utf8_get_char(radstrg_ptr);
    gchar radical[3];
    int at = g_unichar_to_utf8(uniradical, radical);
    radical[at] = '\0';
  
    //lookup the radical (key) and get the radical info (value)
    rad_info = g_hash_table_lookup(rad_info_hash, radical);

    if (rad_info) {
      //contains all the kanji of the current radical
      GList *radical_kanji_list = NULL;

      //add all the kanji from the radical info list to the tmp list
      for (kanji_info_list = rad_info->kanji_info_list;
           kanji_info_list != NULL;
           kanji_info_list = kanji_info_list->next) {
        radical_kanji_list = g_list_prepend(radical_kanji_list, 
                                            (gpointer) ((KanjiInfo *) kanji_info_list->data)->kanji
                                            );
      }
    
      //if the result list is empty (first iteration)
      if(result == NULL){
        //the result is all the kanji for current radical
        result = radical_kanji_list;
      }
      else{
        //the result list is not empty, remove the kanji in result that are not
        //in the radical_kanji_list
        result = list_merge(result, radical_kanji_list);
      }
    }

    radstrg_ptr = g_utf8_next_char(radstrg_ptr);
  }

  return result;
}
예제 #5
0
/*
 * dat_saadvert_in
 *
 *   This is called when active SA discovery is used and SAAdverts
 *   have been detected.
 *
 *     pdat           The DATable which stores the total SA scope list.
 *     pcScopeList    The scope list of the individual discovered SA.
 *     pcAttrlist     The attribute list of the discovered SA.
 *                    This last parameter is currently ignored.
 *
 * Side Effect:
 *   The DATable is updated with the new scopes, if any, in the sa
 *   advert, for the pcSASList field.
 */
EXPORT void dat_saadvert_in(DATable *ignore,
			    const char *pcScopeList,
			    const char *pcAttrlist) {
  DATable* pdat = GetGlobalDATable();
  
  if (!pcScopeList) return;
  if (pdat->pcSASList == NULL) {
    char *pcPacked = list_pack(pcScopeList);
    int i = strlen(pcPacked);
    pdat->pcSASList = safe_malloc(i+LISTINCR,pcPacked,i);
    pdat->iSASListSz = LISTINCR+i;
    free(pcPacked);
  } else {
    list_merge(pcScopeList, &(pdat->pcSASList), &(pdat->iSASListSz), CHECK);
  }
}
예제 #6
0
int main() {
  LElement * list1;
  LElement * list2;
  LElement * list3;
  LElement * list4;

  // Lista 1
  list1 = list_init();
  list1 = list_push_value(list1, 3);
  list1 = list_push_value(list1, 1);
  list1 = list_push_value(list1, 5);

  // Lista 2
  list2 = list_init();
  list2 = list_push_value(list2, 2);
  list2 = list_push_list(list2);
  list2->sublist = list_push_value(list2->sublist, 4);
  list2->sublist = list_push_value(list2->sublist, 7);
  list2 = list_push_list(list2);

  // Lista 3
  list3 = list_init();
  list3 = list_push_list(list3);
  list3->sublist = list_push_list(list3->sublist);
  list3->sublist->sublist = list_push_value(list3->sublist->sublist, 3);
  list3->sublist = list_push_list(list3->sublist);
  list3->sublist->sublist = list_push_value(list3->sublist->sublist, 5);
  list3->sublist->sublist = list_push_value(list3->sublist->sublist, 8);
  list3->sublist = list_push_value(list3->sublist, 2);
  list3 = list_push_list(list3);
  list3->sublist = list_push_value(list3->sublist, 1);
  list3->sublist = list_push_value(list3->sublist, 5);

  list1 = list_merge(list2, list1);
  list4 = list_flat(list3);

  printf("PO POLACZENIU:\n");
  status(list1);

  printf("LISTA 4 - JEDNOPOZIOMOWA:\n");
  status(list4);

  printf("LISTA 3 - WIELOPOZIOMOWA, ZRODLO LISTA 4, NIEZMIENIONE:\n");
  status(list3);

  return 0;
}
예제 #7
0
파일: b.c 프로젝트: cmin764/cmiN
int main()
{
    // cream, initializam si completam listele
    const char errmsg[] = "Nu a putut fi alocata memorie";
    List list1, list2;
    list1 = malloc(sizeof(struct List));
    list2 = malloc(sizeof(struct List));
    if (!(list1 && list2)) {
        fprintf(stderr, "Eroare: %s\n", errmsg);
        return 1;
    }
    #if DBG
    fprintf(stderr, "l1: %p, l2: %p\n", list1, list2);
    #endif
    list_init(list1, NAN);
    list_init(list2, NAN);
    printf("Introdu un numar arbitrar de numere, %d pentru a opri\n",
           NAN);
    // pentru prima lista
    fputs("Lista 1: ", stdout);
    int ret = list_fill(list1);
    if (ret) {
        fprintf(stderr, "Eroare: %s\n", errmsg);
        return ret;
    }
    // pentru a doua lista
    fputs("Lista 2: ", stdout);
    ret = list_fill(list2);
    if (ret) {
        fprintf(stderr, "Eroare: %s\n", errmsg);
        return ret;
    }
    // cream o lista cu cele doua interclasate, implicit e ordonata
    List list3 = list_merge(list1, list2);
    if (!list3) {
        fprintf(stderr, "Eroare: %s\n", errmsg);
        return 1;
    }
    list_print(list3);
    /* sila sa mai eliberez memoria si in cazul in care dadea eroare
       asa ca nu o mai eliberez deloc, o face sistemul la iesire :) */
    return 0;
}
예제 #8
0
/* handlers */
void
_handle_tag_add(const char *path, const char *str)
{
  list_t new_tags;
  list_t tags;

  memset(&new_tags, 0, sizeof(list_t));
  memset(&tags,     0, sizeof(list_t));

  file_tags_get(path, &tags);

  list_parse_tags(&new_tags, str);
  list_merge(&tags, &new_tags);

  list_items_merge(&tags, ' ');

  file_tags_set(path, &tags);

  list_clear(&tags);
  list_clear(&new_tags);
}
예제 #9
0
파일: lsex.c 프로젝트: zxwbj/danei
/* 测试用例5 */
void test5 (void) {
	LIST list1, list2;
	list_init (&list1);
	list_init (&list2);
	srand (time (NULL));
	int i;
	for (i = 0; i < 10; ++i)
		list_insert (&list1, rand () % 100);
	for (i = 0; i < 5; ++i)
		list_insert (&list2, rand () % 100);
	printf ("1:");
	list_print (&list1);
	printf ("2:");
	list_print (&list2);
	list_merge (&list1, &list2);
	printf ("1:");
	list_print (&list1);
	printf ("2:");
	list_print (&list2);
	list_deinit (&list2);
	list_deinit (&list1);
}
예제 #10
0
void list_sort(list_t *list, int compare(const void *, const void *))
{
    list_t extra;
    listcount_t middle;
    lnode_t *node;

    if (list_count(list) > 1) {
        middle = list_count(list) / 2;
        node = list_first_priv(list);

        list_init(&extra, list_count(list) - middle);

        while (middle--)
            node = lnode_next(node);

        list_transfer(&extra, list, node);
        list_sort(list, compare);
        list_sort(&extra, compare);
        list_merge(list, &extra, compare);
    }
    assert (list_is_sorted(list, compare));
}
예제 #11
0
list *
list_dup(list *l, fdup dup)
{
	list *res = list_new_(l);
	return list_merge(res, l, dup);
}
예제 #12
0
파일: webfetch.c 프로젝트: vit1-irk/iitxt-c
struct list fetch_messages (char* adress, struct list echoesToFetch) {
	char* server_msglist_request;
	struct list saved_messages={NULL, 0}; // список сообщений, которые в итоге будут сохранены

	// инициализируем имена файлов для кэша

	char indexcache_fname[100]="\0";
	char bundlecache_fname[100]="\0";

	strcat(indexcache_fname, datadir);
	strcat(bundlecache_fname, datadir);

	strcat(indexcache_fname, "cache-first");
	strcat(bundlecache_fname, "cache-bundle");

	for (i=0; i<echoesToFetch.length; i++) {
		server_msglist_request=(char*)malloc(sizeof(char)*(strlen(adress)+strlen(echoesToFetch.index[i])+5));
		
		strcpy(server_msglist_request, adress);
		strcat(server_msglist_request, "u/e/");
		strcat(server_msglist_request, echoesToFetch.index[i]);
		
		FILE* cached=fopen(indexcache_fname, "wb+");
		
		if (!cached) {
			printf("Не могу открыть файл кэша\n");
			return saved_messages;
		}
	
		int gotEcho=getFile(server_msglist_request, cached, NULL);
		
		int cache_size=ftell(cached)-1;
		rewind(cached); // Сейчас читать будем
		
		char* raw_echobundle=(char*)malloc(cache_size);
		fread(raw_echobundle, cache_size, 1, cached); // прочитали, дальше начнётся какая-то магия
		fclose(cached);
		
		char* bundle_echoarea=strtok(raw_echobundle, "\n");
		if (bundle_echoarea!=NULL) {
			struct list remote_msglist;
			remote_msglist.index=(char**)malloc(sizeof(char*));

			char* nextmessage;

			remote_msglist.length=0;
			while ((nextmessage=strtok(NULL, "\n"))!=NULL) {
				remote_msglist.index=(char**)realloc(remote_msglist.index, sizeof(char*)*(remote_msglist.length+1));
				
				remote_msglist.index[remote_msglist.length]=(char*)malloc(sizeof(char)*21);
				strcpy(remote_msglist.index[remote_msglist.length], nextmessage);
				remote_msglist.index[remote_msglist.length++][20]='\0';
			}

			struct list local_msglist=getLocalEcho(bundle_echoarea);
			struct list difference=messages_difference(remote_msglist, local_msglist);

			if (difference.length>0) {
				int divideCount;
				if (difference.length<=bundle_maxsize) {
					divideCount=1;
				} else {
					if (difference.length%bundle_maxsize==0) divideCount=difference.length/bundle_maxsize;
					else divideCount=difference.length/bundle_maxsize+1;
				}
				
				// следующий цикл отвечает за разделение запросов по 20 сообщений и их выполнение О_о
				char* server_bundle_request;
				int a;
				for (j=0; j<divideCount; j++) {
					server_bundle_request=(char*)malloc(sizeof(char)*(strlen(adress)+3+bundle_maxsize*22));
					// в предыдущей строке, вероятно, может быть утечка

					strcpy(server_bundle_request, adress);
					strcat(server_bundle_request, "u/m");

					for (a=0; a<bundle_maxsize; a++) {
						if (j*bundle_maxsize+a==difference.length) break;
						
						strcat(server_bundle_request, "/");
						strcat(server_bundle_request, difference.index[j*bundle_maxsize+a]);
					}
					
					FILE *bundle_cached=fopen(bundlecache_fname, "w+");
					if (!bundle_cached) {
						printf("Не могу открыть файл кэша бандла\n");
					} else {
						// скачиваем бандл сообщений
						int gotBundle=getFile(server_bundle_request, bundle_cached, NULL);
						
						int bundle_cache_size=ftell(bundle_cached);
						rewind(bundle_cached); // опять подготовка к чтению (идём к началу)
		
						char* raw_bundle=(char*)malloc(bundle_cache_size+1);
						fread(raw_bundle, bundle_cache_size, 1, bundle_cached); // friendship^Wfread is magic
						raw_bundle[bundle_cache_size]='\0';
						fclose(bundle_cached);
						
						struct list bundle_success=saveBundle(bundle_echoarea, raw_bundle); // а эта функция распарсит бандл и попытается сохранить
						if (bundle_success.length>0) {
							list_merge(&saved_messages, &bundle_success);
						}
					}
					free (server_bundle_request);
				}
			}
		}
	}
	return saved_messages;
}
예제 #13
0
/*
 * dat_get_scopes
 *
 *   If there is a net.slp.useScopes property, these scopes are
 *   returned.  Otherwise, starting with the scope list of the first
 *   element, each DA's list is merged in (looking individually at
 *   each of the already-obtained scopes to see if there is a list
 *   intersection with the scopes of each of the subsequent DAs.)
 *
 *   If there are no configured scopes and no DAs, and SA discovery
 *   functionality has been compiled in, then SA discovery will be
 *   used to 
 *
 *    slph         This is used for SA discovery if needed.
 *    pcTypeHint   This is used for SA discovery, to optimize it.
 *    pdat         The da table which is checked for a scope list.
 *    ppcScopes    The scope list to return (an OUT parameter.)
 *
 * Return:
 *
 *   Error if any.
 *   *ppcScopes is set to the scope list obtained.  If no scopes have
 *   been found, this parameter will be set to NULL.
 *
 * Side Effects:
 *
 *   The string list returned in ppcScopes must be freed by the caller.
 *
 * Notes:
 *
 *   SA discovery will be implemented later...
 *
 */
EXPORT SLPInternalError dat_get_scopes(SLPHandle slph,
			       const char *pcTypeHint,
			       const DATable *ignore,
			       char **ppcScopes)
{
    DATable* pdat = GetGlobalDATable();
    char *pcList, *pcScan;
    int iListLen = LISTINCR;
    int  i;
    
    LockGlobalDATable();
        
    *ppcScopes = NULL;
    
    if (!pdat || !ppcScopes) 
        return SLP_PARAMETER_BAD;
  
    if (SLPGetProperty("net.slp.useScopes") != NULL) 
    {
        *ppcScopes = strdup(SLPGetProperty("net.slp.useScopes"));
        return SLP_OK;
    }

#ifdef EXTRA_MSGS  
    if (slph != NULL && pdat->iSize == 0) 
    {
        active_sa_discovery(slph,pcTypeHint);
        if (pdat->pcSASList) 
        {
            int iLen = strlen(pdat->pcSASList);
            *ppcScopes = safe_malloc(iLen+1,pdat->pcSASList,iLen);
        }
        
        return SLP_OK;
    }
#endif /* EXTRA_MSGS */
  
    /* send a merged list of scopes from the DATable */
    if (pdat->iSize == 0) 
        return SLP_OK;
    
    iListLen += strlen(pdat->pDAE[0].pcScopeList);
    pcList = safe_malloc(iListLen, (char*)pdat->pDAE[0].pcScopeList,
                        iListLen-LISTINCR);
    if( !pcList ) return SLP_INTERNAL_SYSTEM_ERROR;
    
    if (pdat->iSize > 1) 
    {
        for (i = 1; i < pdat->iSize; i++) 
        {
            pcScan = list_pack(pdat->pDAE[i].pcScopeList);
            list_merge(pcScan,&pcList,&iListLen,CHECK);
            free(pcScan);
        }
    }
    
    *ppcScopes = pcList;
    
    UnlockGlobalDATable();
    
    return SLP_OK;
}
예제 #14
0
파일: rel_psm.c 프로젝트: jaiminpan/Monetdb
/* 	1
	CASE
	WHEN search_condition THEN statements
	[ WHEN search_condition THEN statements ]
	[ ELSE statements ]
	END CASE

	2
	CASE case_value
	WHEN when_value THEN statements
	[ WHEN when_value THEN statements ]
	[ ELSE statements ]
	END CASE
 */
static list * 
rel_psm_case( mvc *sql, sql_subtype *res, dnode *case_when, int is_func )
{
	list *case_stmts = sa_list(sql->sa);

	if (!case_when)
		return NULL;

	/* case 1 */
	if (case_when->type == type_symbol) {
		dnode *n = case_when;
		symbol *case_value = n->data.sym;
		dlist *when_statements = n->next->data.lval;
		dlist *else_statements = n->next->next->data.lval;
		list *else_stmt = NULL;
		sql_rel *rel = NULL;
		exp_kind ek = {type_value, card_value, FALSE};
		sql_exp *v = rel_value_exp(sql, &rel, case_value, sql_sel, ek);

		if (!v)
			return NULL;
		if (rel)
			return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition");
		if (else_statements) {
			else_stmt = sequential_block( sql, res, NULL, else_statements, NULL, is_func);
			if (!else_stmt) 
				return NULL;
		}
		n = when_statements->h;
		while(n) {
			dnode *m = n->data.sym->data.lval->h;
			sql_exp *cond=0, *when_value = rel_value_exp(sql, &rel, m->data.sym, sql_sel, ek);
			list *if_stmts = NULL;
			sql_exp *case_stmt = NULL;

			if (!when_value || rel ||
			   (cond = rel_binop_(sql, v, when_value, NULL, "=", card_value)) == NULL || 
			   (if_stmts = sequential_block( sql, res, NULL, m->next->data.lval, NULL, is_func)) == NULL ) {
				if (rel)
					return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition");
				return NULL;
			}
			case_stmt = exp_if(sql->sa, cond, if_stmts, NULL);
			list_append(case_stmts, case_stmt);
			n = n->next;
		}
		if (else_stmt)
			list_merge(case_stmts, else_stmt, NULL);
		return case_stmts;
	} else { 
		/* case 2 */
		dnode *n = case_when;
		dlist *whenlist = n->data.lval;
		dlist *else_statements = n->next->data.lval;
		list *else_stmt = NULL;

		if (else_statements) {
			else_stmt = sequential_block( sql, res, NULL, else_statements, NULL, is_func);
			if (!else_stmt) 
				return NULL;
		}
		n = whenlist->h;
		while(n) {
			dnode *m = n->data.sym->data.lval->h;
			sql_rel *rel = NULL;
			sql_exp *cond = rel_logical_value_exp(sql, &rel, m->data.sym, sql_sel);
			list *if_stmts = NULL;
			sql_exp *case_stmt = NULL;

			if (!cond || rel ||
			   (if_stmts = sequential_block( sql, res, NULL, m->next->data.lval, NULL, is_func)) == NULL ) {
				if (rel)
					return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition");
				return NULL;
			}
			case_stmt = exp_if(sql->sa, cond, if_stmts, NULL);
			list_append(case_stmts, case_stmt);
			n = n->next;
		}
		if (else_stmt)
			list_merge(case_stmts, else_stmt, NULL);
		return case_stmts;
	}
}
예제 #15
0
    void *pivot = list_getFrom(l, p);
    int i = 0;
    FOREACH(it, l) {
        void *val = VALUE(it);
        if (i != p) {
            if (sorter(val, pivot)) {
                list_push(left, val);
            } else {
                list_push(right, val);
            }
        }
        i++;
    }
    list r = sortFrom(left, sorter, 0, list_len(left));
    list_push(r, pivot);
    r = list_merge(r, sortFrom(right, sorter, 0, list_len(right)));
    list_destroy(left);
    list_destroy(right);
    return r;
}

list sortFrom(list l, sort_fn sorter, int s, int e) {
    switch (e - s) {
    case 0:
        return list_create();
    case 1:
        return sortOne(l, sorter, s, e);
    case 2:
        return sortTwo(l, sorter, s, e);
    case 3:
        return sortThree(l, sorter, s, e);
예제 #16
0
/**
 * Walk through the timer list and check if any timer is ready to fire.
 * Callback the provided function with the context pointer.
 */
static void
walk_timers(uint32_t * last_run)
{
  unsigned int total_timers_walked = 0, total_timers_fired = 0;
  unsigned int wheel_slot_walks = 0;

  /*
   * Check the required wheel slots since the last time a timer walk was invoked,
   * or check *all* the wheel slots, whatever is less work.
   * The latter is meant as a safety belt if the scheduler falls behind.
   */
  while ((*last_run <= now_times) && (wheel_slot_walks < TIMER_WHEEL_SLOTS)) {
    struct list_node tmp_head_node;
    /* keep some statistics */
    unsigned int timers_walked = 0, timers_fired = 0;

    /* Get the hash slot for this clocktick */
    struct list_node *const timer_head_node = &timer_wheel[*last_run & TIMER_WHEEL_MASK];

    /* Walk all entries hanging off this hash bucket. We treat this basically as a stack
     * so that we always know if and where the next element is.
     */
    list_head_init(&tmp_head_node);
    while (!list_is_empty(timer_head_node)) {
      /* the top element */
      struct list_node *const timer_node = timer_head_node->next;
      struct timer_entry *const timer = list2timer(timer_node);

      /*
       * Dequeue and insert to a temporary list.
       * We do this to avoid loosing our walking context when
       * multiple timers fire.
       */
      list_remove(timer_node);
      list_add_after(&tmp_head_node, timer_node);
      timers_walked++;

      /* Ready to fire ? */
      if (TIMED_OUT(timer->timer_clock)) {

        OLSR_PRINTF(7, "TIMER: fire %s timer %p, ctx %p, "
                   "at clocktick %u (%s)\n",
                   timer->timer_cookie->ci_name,
                   timer, timer->timer_cb_context, (unsigned int)*last_run, olsr_wallclock_string());

        /* This timer is expired, call into the provided callback function */
        timer->timer_cb(timer->timer_cb_context);

        /* Only act on actually running timers */
        if (timer->timer_flags & OLSR_TIMER_RUNNING) {
          /*
           * Don't restart the periodic timer if the callback function has
           * stopped the timer.
           */
          if (timer->timer_period) {
            /* For periodical timers, rehash the random number and restart */
            timer->timer_random = random();
            olsr_change_timer(timer, timer->timer_period, timer->timer_jitter_pct, OLSR_TIMER_PERIODIC);
          } else {
            /* Singleshot timers are stopped */
            olsr_stop_timer(timer);
          }
        }

        timers_fired++;
      }
    }

    /*
     * Now merge the temporary list back to the old bucket.
     */
    list_merge(timer_head_node, &tmp_head_node);

    /* keep some statistics */
    total_timers_walked += timers_walked;
    total_timers_fired += timers_fired;

    /* Increment the time slot and wheel slot walk iteration */
    (*last_run)++;
    wheel_slot_walks++;
  }

  OLSR_PRINTF(7, "TIMER: processed %4u/%d clockwheel slots, "
             "timers walked %4u/%u, timers fired %u\n",
             wheel_slot_walks, TIMER_WHEEL_SLOTS, total_timers_walked, timer_mem_cookie->ci_usage, total_timers_fired);

  /*
   * If the scheduler has slipped and we have walked all wheel slots,
   * reset the last timer run.
   */
  *last_run = now_times;
}
예제 #17
0
파일: rel_psm.c 프로젝트: jaiminpan/Monetdb
static list *
sequential_block (mvc *sql, sql_subtype *restype, list *restypelist, dlist *blk, char *opt_label, int is_func) 
{
	list *l=0;
	dnode *n;

	assert(!restype || !restypelist);

 	if (THRhighwater())
		return sql_error(sql, 10, "SELECT: too many nested operators");

	if (blk->h)
 		l = sa_list(sql->sa);
	stack_push_frame(sql, opt_label);
	for (n = blk->h; n; n = n->next ) {
		sql_exp *res = NULL;
		list *reslist = NULL;
		symbol *s = n->data.sym;

		switch (s->token) {
		case SQL_SET:
			res = psm_set_exp(sql, s->data.lval->h);
			break;
		case SQL_DECLARE:
			reslist = rel_psm_declare(sql, s->data.lval->h);
			break;
		case SQL_CREATE_TABLE: 
			res = rel_psm_declare_table(sql, s->data.lval->h);
			break;
		case SQL_WHILE:
			res = rel_psm_while_do(sql, restype, s->data.lval->h, is_func);
			break;
		case SQL_IF:
			res = rel_psm_if_then_else(sql, restype, s->data.lval->h, is_func);
			break;
		case SQL_CASE:
			reslist = rel_psm_case(sql, restype, s->data.lval->h, is_func);
			break;
		case SQL_CALL:
			res = rel_psm_call(sql, s->data.sym);
			break;
		case SQL_RETURN:
			/*If it is not a function it cannot have a return statement*/
			if (!is_func)
				res = sql_error(sql, 01, 
					"Return statement in the procedure body");
			else {
				/* should be last statement of a sequential_block */
				if (n->next) { 
					res = sql_error(sql, 01, 
						"Statement after return");
				} else {
					reslist = rel_psm_return(sql, restype, restypelist, s->data.sym);
				}
			}
			break;
		case SQL_SELECT: { /* row selections (into variables) */
			exp_kind ek = {type_value, card_row, TRUE};
			reslist = rel_select_into(sql, s, ek);
		}	break;
		case SQL_COPYFROM:
		case SQL_BINCOPYFROM:
		case SQL_INSERT:
		case SQL_UPDATE:
		case SQL_DELETE: {
			sql_rel *r = rel_updates(sql, s);
			if (!r)
				return NULL;
			res = exp_rel(sql, r);
		}	break;
		default:
			res = sql_error(sql, 01, 
			 "Statement '%s' is not a valid flow control statement",
			 token2string(s->token));
		}
		if (!res && !reslist) {
			l = NULL;
			break;
		}
		if (res)
			list_append(l, res);
		else
			list_merge(l, reslist, NULL);
	}
	stack_pop_frame(sql);
	return l;
}