Exemplo n.º 1
0
void generar_comparacion(Element *obj, char *etiqueta) {
	Element *operando1 = (Element *)malloc(sizeof(Element));
	Element *operando2 = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&operando2);
	spop(&pila, (void *)&operando1);
	if (operando1->code == REGISTRO) {
		if (operando2->code == REGISTRO) {
			//Registro-Registro
			fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando1->name, operando2->name);
		} else {
			//Registro-Operando
			if (operando2->code == IDENTIFICADOR)
				fprintf(output_fd, "\t\tCMP\t%s, _%s\n", operando1->name, operando2->name);
			else
				fprintf(output_fd, "\t\tCMP\t%s, %d\n", operando1->name, operando2->value);
		}
	} else {
		Element *op_aux2 = get_free(state);
		if (operando2->code == REGISTRO) {
			//Operando-Registro
			if (operando1->code == IDENTIFICADOR) {
				fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name);
				fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando2->name, op_aux2->name);
			} else {
				fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value);
				fprintf(output_fd, "\t\tCMP\t%s, %s\n", operando2->name, op_aux2->name);
			}
		} else {
			//Operando-Operando
			if (operando1->code == IDENTIFICADOR) {
				if (operando2->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name);
					fprintf(output_fd, "\t\tCMP\t%s, _%s\n", op_aux2->name, operando2->name);
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name);
					fprintf(output_fd, "\t\tCMP\t%s, %d\n", op_aux2->name, operando2->value);
				}
			} else {
				if (operando2->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value);
					fprintf(output_fd, "\t\tCMP\t%s, _%s\n", op_aux2->name, operando2->name);
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value);
					fprintf(output_fd, "\t\tCMP\t%s, %d\n", op_aux2->name, operando2->value);
				}
			}
		}
	}
	Element *op_aux = get_free();
	state[op_aux->value] = 1;
	spush(&pila, (void *)op_aux);
	fprintf(output_fd, "\t\t%s\tLABEL00%d\n", etiqueta, labelnumber);
	fprintf(output_fd, "\t\tMOV\t%s, 0\n", op_aux->name);
	fprintf(output_fd, "\t\tJMP\tLABEL00%d\n", labelnumber+1);
	fprintf(output_fd, "\tLABEL00%d:\n\t\tMOV\t%s, 1\n", labelnumber, op_aux->name);
	labelnumber++;
	fprintf(output_fd, "\tLABEL00%d:\n", labelnumber);
	labelnumber++;
}
Exemplo n.º 2
0
/* Libera el registro AL ocupado usando la variable parametro y lo retorna */
Element *free_AL(Element *variable) {
	Stack *pila_aux = (Stack *)0;
	Element *elem_aux = (Element *)malloc(sizeof(Element));
	Element *ret = (Element *)malloc(sizeof(Element));
	
	/* Busco el registro AL ocupado para liberarlo */
	spop(&pila, (void *)&elem_aux);
	while (elem_aux->code != REGISTRO || (elem_aux->code == REGISTRO && elem_aux->value != 0)) {
		spush(&pila_aux, (void *)elem_aux);
		spop(&pila, (void *)&elem_aux);
	}
	/* Vuelco el contenido del registro a liberar en la variable parametro */
	fprintf(output_fd, "\t\tMOV\t_%s, %s\n", variable->name, elem_aux->name);
	/* Apilo la variable en lugar del registro y    *
	 * guardo en la variable el registro a retornar */
	spush(&pila, (void *)variable);
	ret = load_register(0);
	/* Apilo nuevamente los demas operandos sacados de la pila */	
	while (pila_aux != (Stack *)0) {
		spop(&pila_aux, (void *)&elem_aux);
		spush(&pila, (void *)elem_aux);
	}
	
	return ret;
}
Exemplo n.º 3
0
/* Libera cualquier registro ocupado usando la variable parametro y lo retorna */
Element *free_any_notA(Element *variable) {
	Stack *pila_aux;
	Element *elem_aux = (Element *)malloc(sizeof(Element));
	Element *ret = (Element *)malloc(sizeof(Element));
	
	/* Busco un registro ocupado que no sea ni AH ni AL, para liberarlo */
	spop(&pila, (void *)&elem_aux);
	while (elem_aux->code != REGISTRO || (elem_aux->code == REGISTRO && (elem_aux->value == 0 || elem_aux->value == 1))) {
		spush(&pila_aux, (void *)elem_aux);
		spop(&pila, (void *)&elem_aux);
	}
	/* Vuelco el contenido del registro a liberar en la variable parametro */
	fprintf(output_fd, "\t\tMOV\t_%s, %s\n", variable->name, elem_aux->name);
	/* Apilo la variable en lugar del registro y    *
	 * guardo en la variable el registro a retornar */
	spush(&pila, (void *)variable);
	ret->code = REGISTRO;
	strcpy(ret->name, elem_aux->name);
	ret->value = elem_aux->value;
	/* Apilo nuevamente los demas operandos sacados de la pila */
	spop(&pila_aux, (void *)&elem_aux);
	while (elem_aux != (Element *)0) {
		spush(&pila, (void *)elem_aux);
		spop(&pila_aux, (void *)&elem_aux);
	}
	
	return ret;
}
Exemplo n.º 4
0
Arquivo: main.c Projeto: amaceh/KULIAH
int main()
{
	stack S1;
	stack S2;

	char ngaran[5][10];

	CreateEmpty(&S1);
	CreateEmpty(&S2);
	int i;
	for(i=0 ; i<5 ; i++){
		scanf("%s", ngaran[i]);
	}
	printf("S1 -");
	printstack(S1);
	printf("S2 -");
	printstack(S2);
	push(ngaran[0], &S1);
	push(ngaran[1], &S2);
	spop(&S1, &S2);
	printf("S1 -");
	printstack(S1);
	printf("S2 -");
	printstack(S2);
	pop(&S2);
	push(ngaran[2], &S1);
	push(ngaran[3], &S2);
	push(ngaran[4], &S2);
	spop(&S2, &S1);
	printf("S2 -");
	printstack(S2);
	printf("S1 -");
	printstack(S1);
	return 0;
}
Exemplo n.º 5
0
void generar_or(Element *obj) {
	Element *operando1 = (Element *)malloc(sizeof(Element));
	Element *operando2 = (Element *)malloc(sizeof(Element));
	
	spop(&pila, (void *)&operando2);
	spop(&pila, (void *)&operando1);
	if (operando1->code == REGISTRO) {
		if (operando2->code == REGISTRO) {
			//Registro-Registro
			fprintf(output_fd, "\t\tOR\t%s, %s\n", operando2->name, operando1->name);
			state[operando1->value] = 0; /*Libero el registro*/
			spush(&pila, (void *)operando2);
		} else {
			//Registro-Operando
			if (operando2->code == IDENTIFICADOR)
				fprintf(output_fd, "\t\tOR\t%s, _%s\n", operando1->name, operando2->name);
			else
				fprintf(output_fd, "\t\tOR\t%s, %d\n", operando1->name, operando2->value);
			spush(&pila, (void *)operando1);
		}
	} else {
		if (operando2->code == REGISTRO) {
			//Operando-Registro
			if (operando1->code == IDENTIFICADOR)
				fprintf(output_fd, "\t\tOR\t%s, _%s\n", operando2->name, operando1->name);
			else
				fprintf(output_fd, "\t\tOR\t%s, %d\n", operando2->name, operando1->value);
			spush(&pila, (void *)operando2);
		} else {
			//Operando-Operando
			Element *op_aux = get_free();
			if (operando1->code == IDENTIFICADOR) {
				if (operando2->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name);
					fprintf(output_fd, "\t\tOR\t%s, _%s\n", op_aux->name, operando2->name);
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name);
					fprintf(output_fd, "\t\tOR\t%s, %d\n", op_aux->name, operando2->value);
				}
			} else {
				if (operando2->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value);
					fprintf(output_fd, "\t\tOR\t%s, _%s\n", op_aux->name, operando2->name);
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value);
					fprintf(output_fd, "\t\tOR\t%s, %d\n", op_aux->name, operando2->value);
				}
			}
			spush(&pila, (void *)op_aux);
			state[op_aux->value] = 1;
		}
	}
}
Exemplo n.º 6
0
int _tmain2(int argc, _TCHAR* argv[])
{
	//#ifdef _DEBUG
	//	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//退出时检测泄漏
	//#endif
	stack<int> si;
	si.push(1);
	si.push(2);
	si.push(3);
	while (!si.empty())
		cout << spop(si) << endl;

	vector<int> dest = { 3, 4, 99, 6, 7, 8, 9 };

	Nth nth(3);
	//  find_if (beg, end, unaryPred) ;  
	//  操作前:[beg,end)标示输入序列.unaryPred操作符是一元函数对象.  
	//  操作后:确定输入序列中是否存在使unaryPred返回true的元素.  
	//  返回值:如果存在使unaryPred返回true的元素,返回指向第一个该元素位置的迭代器.  
	//                  否则返回end.  
	//  备注:     如果使用二元函数对象,需使用绑定器将其转换为一元函数对象使用.  
	vector<int>::iterator nthItr = find_if(dest.begin(), dest.end(), nth);  //dest内容为连续数字:3,4,5,6,……,12  
	cout << "3rd:" << *nthItr << endl;
	cout << "State:" << nth.GetCount() << endl; 
	//int *p = new int;
	system("pause");
	//_CrtDumpMemoryLeaks();
	return 0;

}
Exemplo n.º 7
0
int _ol_grow_and_rehash_db(ol_database *db) {
    int i;
    ol_bucket *bucket;
    ol_bucket **tmp_hashes = NULL;

    size_t to_alloc = db->cur_ht_size * 2;
    debug("Growing DB to %zu bytes.", to_alloc);
    tmp_hashes = calloc(1, to_alloc);
    check_mem(tmp_hashes);

    struct ol_stack *orphans = NULL;
    orphans = malloc(sizeof(struct ol_stack));
    check_mem(orphans);
    orphans->next = NULL;
    orphans->data = NULL;
    int orphans_found = 0;

    int iterations = ol_ht_bucket_max(db->cur_ht_size);
    for (i = 0; i < iterations; i++) {
        bucket = db->hashes[i];
        if (bucket != NULL) {
            if (bucket->next != NULL) {
                ol_bucket *tmp_bucket = bucket;
                do {
                    spush(&orphans, tmp_bucket->next);

                    ol_bucket *next = tmp_bucket->next;
                    tmp_bucket->next = NULL;
                    tmp_bucket = next;

                    orphans_found++;
                } while (tmp_bucket->next != NULL);
            }
            /* Rehash the bucket itself. */
            _ol_rehash_insert_bucket(tmp_hashes, to_alloc, bucket);
        }
    }

    /* Take care of our orphans */
    ol_log_msg(LOG_INFO, "Have %i orphans to take care of.", orphans_found);
    do {
        ol_bucket *rebucket = spop(&orphans);
        _ol_rehash_insert_bucket(tmp_hashes, to_alloc, rebucket);

        orphans_found--;
    } while (orphans->next != NULL);
    ol_log_msg(LOG_INFO, "We now have %i orphans not accounted for.", orphans_found);

    free(orphans);
    free(db->hashes);
    db->hashes = tmp_hashes;
    db->cur_ht_size = to_alloc;
    debug("Current hash table size is now: %zu bytes.", to_alloc);
    return 0;

error:
    if (tmp_hashes != NULL)
        free(tmp_hashes);
    return -1;
}
Exemplo n.º 8
0
void generar_BF(Element *obj) {
	Element *numero_paso = (Element *)malloc(sizeof(Element));
	Element *operando = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&numero_paso);
	spop(&pila, (void *)&operando);
	if (operando->code == REGISTRO) {
		fprintf(output_fd, "\t\tCMP\t%s, 1\n", operando->name);
	} else {
		if (operando->code == IDENTIFICADOR)
			fprintf(output_fd, "\t\tCMP\t_%s, 1\n", operando->name);
		else
			fprintf(output_fd, "\t\tCMP\t%d, 1\n", operando->value);
	}
	fprintf(output_fd, "\t\tJNE\tLJMP%d\n", numero_paso->value);
}
Exemplo n.º 9
0
static _pit *
_pop_frame(void)
{
    _cstackitem *ci;

    ci = spop(current_ctx->cs);
    if (!ci) {
        return NULL;
    }
    return ci->ckey;
}
Exemplo n.º 10
0
  void re_init_mpop( metapop_t * mpop,
		     const singlepop_t * pop)
  {
    singlepop_t spop(*pop);
    mpop->diploids.clear();
    mpop->gametes.clear();
      
    // //Move construct from spop into mpop
    mpop->fixations = std::move(spop.fixations);
    mpop->fixation_times = std::move(spop.fixation_times);
    mpop->mutations = std::move(spop.mutations);
    mpop->gametes = std::move(spop.gametes);
    mpop->diploids.emplace_back(std::move(spop.diploids));
    mpop->mut_lookup = std::move(spop.mut_lookup);
    
    //Update other data
    mpop->generation = spop.generation;
  }
Exemplo n.º 11
0
void generar_not(Element *obj) {
	Element *operando = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&operando);
	if (operando->code == REGISTRO) {
		fprintf(output_fd, "\t\tNOT\t%s\n", operando->name);
		spush(&pila, (void *)operando);
	} else {
		Element *op_aux = get_free();
		if (operando->code == IDENTIFICADOR) {
			fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando->name);
		} else {
			fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando->value);
		}
		fprintf(output_fd, "\t\tNOT\t%s\n", op_aux->name);
		state[op_aux->value] = 1;
		spush(&pila, (void *)op_aux);
	}
}
Exemplo n.º 12
0
 void lpop()            { spop(); spop(); }
Exemplo n.º 13
0
// Algoritme 'Shunting Yard' pour faire la conversion du type Infixée pour le RPN
char *shuntingYard(char *stringRPN){
#define spush(x) conversionStack[l_stack++].valeur = x
#define spop()   conversionStack[--l_stack].valeur

    char *valeurIndiv = (char*) strtok(stringRPN, " ");
    char *postFixe = malloc(100 * sizeof(char));
    opAssoc conversionStack[100];
    int l_stack = 0;
    int flag = 0;

    strcpy(postFixe, "");

    while(valeurIndiv != NULL) {
        // Si le caractère est constante mettre dans la pile
        if((ILESTNOMBRE) || (ILESTVARIABLE)) {
            strcat(postFixe, valeurIndiv);
            strcat(postFixe, " ");
        
        // Si non, on doit verifier sa priorité et associativité    
        } else {
            if (PRIORITEDEUX) {
                conversionStack[l_stack].priorite = 2;
                conversionStack[l_stack].associativite = 1;
            }
            else if (PRIORITETROIS) {
                conversionStack[l_stack].priorite = 3;
                conversionStack[l_stack].associativite = 1;
            }
            
            else {
                conversionStack[l_stack].priorite = 0;
                conversionStack[l_stack].associativite = 0;
            }
            
            // Verification s'il y a la presence d'un ()
            if (valeurIndiv[0] == '(')
                flag = l_stack;
            
            // Verification de la priorite de l'algoritme
            if (l_stack && conversionStack[l_stack-1].priorite == conversionStack[l_stack].priorite) {
                strcat(postFixe, spop());
                strcat(postFixe, " ");
                
                conversionStack[l_stack].priorite = conversionStack[l_stack+1].priorite;
            }
            
            spush(valeurIndiv);
        }
        
        if(valeurIndiv[0] == ')') {
                l_stack--;
                while(l_stack != flag+1) {
                    strcat(postFixe, spop());
                    strcat(postFixe, " ");
                }
                l_stack--;
        }
        
        valeurIndiv = (char*) strtok(NULL, " ");
    }
    
    // Si il a déjà fini fait le pop jusqu'à le fin
    while(l_stack) {
        strcat(postFixe, spop());
        strcat(postFixe, " ");
    }

    free(valeurIndiv);
    return postFixe;

}
Exemplo n.º 14
0
hoc_parallel_begin() {
#if !OCSMALL
		  Symbol *sym;
        double first, last;
        char *method, *getenv();
	int parallel_hoc_main();
	int i, j;


        last = xpop();
        first = xpop();
	sym = spop();
	pushs(sym);

        method = getenv("NEURON_PARALLEL_METHOD");
        if (!method) {
                pushx(first);
                pushx(last);
                return;
        }
        if (parallel_seen++) {
                hoc_warning("Only one parallel loop per batch run allowed.",
			    "This loop is being executed serially");
                pushx(first);
                pushx(last);
                return;
        }
      
	if (!parallel_sub) { /* if 0 then master */
	    /* the master instance executes the following portion of the loop */
	    for (i = ((int)first)+1; i <= (int)last; i++) {
		char buf[10], *pnt = parallel_argv;

		/* increment pnt to "00000" */
		for (j = 0; j < 2; j++) {
		    /*EMPTY*/
		    while (*pnt++);
		}
		
		/* replace "00000" with actual value */
		sprintf(buf, "%5d", i);
		strcpy(pnt, buf);

		/* farm-out all but the first instance of the loop */
#if LINDA
		/* place arguments for eval() into tuple space, Linda
		   doesn't seem to want to let the fxn in an eval take 
		   arrays as args */
		__linda_out("parallel sargs", sargv, senvp);
 		__linda_out("parallel args", parallel_argv:sargv, parallel_envp:senvp); 
 		__linda_eval("parallel run", parallel_hoc_main(i), i);
#endif
	    }
	    
#if LINDA
	    /* do first pass though loop on master node (first to first) */
	    pushx(first);
	    pushx(first);
#else
	    /* run in serial if not LINDA */
	    pushx(first);
	    pushx(last);
#endif

	    /* block until all instances of loop have finished */
#if LINDA
	    i = (int)last - (int)first;
	    while (i-- > 0) {
		int err_val, err_num;
		
		__linda_in("parallel run", ?err_val, ?err_num);
		/* could test err_val != 0 but currently will always equal 0 */
	    }
#endif

	    /* assign value of symbol to last+1 as would be upon exiting a serial loop */
	    if (!ISARRAY(sym)) {
		if (sym->subtype == USERDOUBLE) {
		    pval = sym->u.pval;
		} else {
		    pval = OPVAL(sym);
		}
	    } else {
		if (sym->subtype == USERDOUBLE) {
		    pval = sym->u.pval + araypt(sym, SYMBOL);
		} else {
		    pval = OPVAL(sym) + araypt(sym, OBJECTVAR);	
		}
	    }
	    end_val = last + 1;

	} else {
Exemplo n.º 15
0
static inline char *tparam_internal(const char *string, va_list ap)
{
#define NUM_VARS 26
int	param[9];
int	popcount;
int	variable[NUM_VARS];
static int sVariable[NUM_VARS];
char	len;
int	number;
int	level;
int	x, y;
int	i;
int	varused = -1;
register const char *cp;

	out_used = 0;
	if (string == NULL)
		return NULL;

	/*
	 * Find the highest parameter-number referred to in the format string.
	 * Use this value to limit the number of arguments copied from the
	 * variable-length argument list.
	 */
	for (cp = string, popcount = number = 0; *cp != '\0'; cp++) {
		if (cp[0] == '%' && cp[1] != '\0') {
			switch (cp[1]) {
			case '%':
				cp++;
				break;
			case 'i':
				if (popcount < 2)
					popcount = 2;
				break;
			case 'p':
				cp++;
				if (cp[1] >= '1' && cp[1] <= '9') {
					int c = cp[1] - '0';
					if (c > popcount)
						popcount = c;
				}
				break;
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9':
			case 'd': case 'c': case 's':
				++number;
				break;
			}
		}
	}

	if (number > 9) number = 9;
	for (i = 0; i < max(popcount, number); i++) {
		/*
		 * FIXME: potential loss here if sizeof(int) != sizeof(char *).
		 * A few caps (such as plab_norm) have string-valued parms.
		 */
		param[i] = va_arg(ap, int);
	}

	/*
	 * This is a termcap compatibility hack.  If there are no explicit pop
	 * operations in the string, load the stack in such a way that
	 * successive pops will grab successive parameters.  That will make
	 * the expansion of (for example) \E[%d;%dH work correctly in termcap
	 * style, which means tparam() will expand termcap strings OK.
	 */
	stack_ptr = 0;
	if (popcount == 0) {
		popcount = number;
		for (i = number - 1; i >= 0; i--)
			npush(param[i]);
	}

#ifdef TRACE
	if (_nc_tracing & TRACE_CALLS) {
		for (i = 0; i < popcount; i++)
			save_number(", %d", param[i]);
		_tracef(T_CALLED("%s(%s%s)"), tname, _nc_visbuf(string), out_buff);
		out_used = 0;
 	}
#endif /* TRACE */

	while (*string) {
		if (*string != '%')
			save_char(*string);
		else {
			string++;
			switch (*string) {
			default:
				break;
			case '%':
				save_char('%');
				break;

			case 'd':
				save_number("%d", npop());
				break;

			case 'x':
				save_number("%x", npop());
				break;

			case '0':
				string++;
				len = *string;
				if (len == '2'  ||  len == '3')
				{
					++string;
					if (*string == 'd') {
						if (len == '2')
							save_number("%02d", npop());
						else
							save_number("%03d", npop());
					}
					else if (*string == 'x') {
						if (len == '2')
							save_number("%02x", npop());
						else
							save_number("%03x", npop());
					}
				}
				break;

			case '2':
				string++;
				if (*string == 'd') {
					save_number("%2d", npop());
				}
				else if (*string == 'x') {
					save_number("%2x", npop());
				}
				break;

			case '3':
				string++;
				if (*string == 'd') {
					save_number("%3d", npop());
				}
				else if (*string == 'x') {
					save_number("%3x", npop());
				}
				break;

			case 'c':
				save_char(npop());
				break;

			case 's':
				save_text(spop());
				break;

			case 'p':
				string++;
				if (*string >= '1'  &&  *string <= '9')
					npush(param[*string - '1']);
				break;

			case 'P':
				string++;
				if (islower(*string)) {
					i = (*string - 'a');
					if (i >= 0 && i < NUM_VARS) {
						while (varused < i)
							variable[++varused] = 0;
						variable[i] = npop();
					}
				} else {
					i = (*string - 'A');
					if (i >= 0 && i < NUM_VARS)
						sVariable[i] = npop();
				}
				break;

			case 'g':
				string++;
				if (islower(*string)) {
					i = (*string - 'a');
					if (i >= 0 && i < NUM_VARS) {
						while (varused < i)
							variable[++varused] = 0;
						npush(variable[i]);
					}
				} else {
					i = (*string - 'A');
					if (i >= 0 && i < NUM_VARS)
						npush(sVariable[i]);
				}
				break;

			case '\'':
				string++;
				npush(*string);
				string++;
				break;

			case L_BRACE:
				number = 0;
				string++;
				while (*string >= '0'  &&  *string <= '9') {
					number = number * 10 + *string - '0';
					string++;
				}
				npush(number);
				break;

			case '+':
				npush(npop() + npop());
				break;

			case '-':
				y = npop();
				x = npop();
				npush(x - y);
				break;

			case '*':
				npush(npop() * npop());
				break;

			case '/':
				y = npop();
				x = npop();
				npush(x / y);
				break;

			case 'm':
				y = npop();
				x = npop();
				npush(x % y);
				break;

			case 'A':
				npush(npop() && npop());
				break;

			case 'O':
				npush(npop() || npop());
				break;

			case '&':
				npush(npop() & npop());
				break;

			case '|':
				npush(npop() | npop());
				break;

			case '^':
				npush(npop() ^ npop());
				break;

			case '=':
				y = npop();
				x = npop();
				npush(x == y);
				break;

			case '<':
				y = npop();
				x = npop();
				npush(x < y);
				break;

			case '>':
				y = npop();
				x = npop();
				npush(x > y);
				break;

			case '!':
				npush(! npop());
				break;

			case '~':
				npush(~ npop());
				break;

			case 'i':
				param[0]++;
				param[1]++;
				break;

			case '?':
				break;

			case 't':
				x = npop();
				if (!x) {
					/* scan forward for %e or %; at level zero */
					string++;
					level = 0;
					while (*string) {
						if (*string == '%') {
							string++;
							if (*string == '?')
								level++;
							else if (*string == ';') {
								if (level > 0)
									level--;
								else
									break;
							}
							else if (*string == 'e'  && level == 0)
								break;
						}

						if (*string)
							string++;
					}
				}
				break;

			case 'e':
				/* scan forward for a %; at level zero */
				string++;
				level = 0;
				while (*string) {
					if (*string == '%') {
						string++;
						if (*string == '?')
							level++;
						else if (*string == ';') {
							if (level > 0)
								level--;
							else
								break;
						}
					}

					if (*string)
						string++;
				}
				break;

			case ';':
				break;

			} /* endswitch (*string) */
		} /* endelse (*string == '%') */

		if (*string == '\0')
			break;

		string++;
	} /* endwhile (*string) */

	if (out_buff == 0)
		out_buff = calloc(1,1);
	if (out_used == 0)
		*out_buff = '\0';

	T((T_RETURN("%s"), _nc_visbuf(out_buff)));
	return(out_buff);
}
Exemplo n.º 16
0
static char *receive_chunked_http(const int request_fd) {
	char *raw_buf = NULL;
	size_t buf_size = 0;
	int times_read = 0;

	fd_set chan_fds;
	FD_ZERO(&chan_fds);
	FD_SET(request_fd, &chan_fds);
	const int maxfd = request_fd;

	while (1) {
		times_read++;

		/* Wait for data to be read. */
		struct timeval tv = {
			.tv_sec = SELECT_TIMEOUT,
			.tv_usec = 0
		};
		select(maxfd + 1, &chan_fds, NULL, NULL, &tv);

		int count;
		/* How many bytes should we read: */
		ioctl(request_fd, FIONREAD, &count);
		if (count <= 0)
			break;
		int old_offset = buf_size;
		buf_size += count;
		if (raw_buf != NULL) {
			char *new_buf = realloc(raw_buf, buf_size);
			if (new_buf != NULL) {
				raw_buf = new_buf;
			} else {
				goto error;
			}
		} else {
			raw_buf = calloc(1, buf_size);
		}

		int recvd = recv(request_fd, raw_buf + old_offset, count, 0);
		if (recvd != count) {
			log_msg(LOG_WARN, "Could not receive entire message.");
		}
	}
	/* printf("Full message is %s\n.", raw_buf); */
	/* Check for a 200: */
	if (raw_buf == NULL || strstr(raw_buf, "200") == NULL) {
		log_msg(LOG_ERR, "Could not find 200 return code in response.");
		goto error;
	}

	/* 4Chan throws us data as chunk-encoded HTTP. Rad. */
	char *header_end = strstr(raw_buf, "\r\n\r\n");
	char *cursor_pos = header_end  + (sizeof(char) * 4);

	size_t json_total = 0;
	char *json_buf = NULL;

	while (1) {
		/* This is where the data begins. */
		char *chunk_size_start = cursor_pos;
		char *chunk_size_end = strstr(chunk_size_start, "\r\n");
		const int chunk_size_end_oft = chunk_size_end - chunk_size_start;

		/* We cheat a little and set the first \r to a \0 so strtol will
		 * do the right thing. */
		chunk_size_start[chunk_size_end_oft] = '\0';
		const int chunk_size = strtol(chunk_size_start, NULL, 16);

		/* printf("Chunk size is %i. Thing is: %s.\n", chunk_size, chunk_size_start); */
		/* The chunk string, the \r\n after it, the chunk itself and then another \r\n: */
		cursor_pos += chunk_size + chunk_size_end_oft + 4;

		/* Copy the json into a pure buffer: */
		int old_offset = json_total;
		json_total += chunk_size;
		if (json_total >= old_offset) {
			if (json_buf != NULL) {
				char *new_buf = realloc(json_buf, json_total);
				if (new_buf != NULL) {
					json_buf = new_buf;
				} else {
					goto error;
				}
			} else {
				json_buf = calloc(1, json_total);
			}
		}
		/* Copy it from after the <chunk_size>\r\n to the end of the chunk. */
		memcpy(json_buf + old_offset, chunk_size_end + 2, chunk_size);
		/* Stop reading if we am play gods: */
		if ((cursor_pos - raw_buf) > buf_size || chunk_size <= 0)
			break;
	}
	/* printf("The total json size is %zu.\n", json_total); */
	/* printf("JSON:\n%s", json_buf); */
	free(raw_buf);

	return json_buf;

error:
	if (raw_buf != NULL)
		free(raw_buf);
	return NULL;
}

static int connect_to_host(const char *host) {
	struct addrinfo hints = {0};
	struct addrinfo *res = NULL;
	int request_fd;

	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;

	getaddrinfo(host, "80", &hints, &res);

	request_fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if (request_fd < 0) {
		log_msg(LOG_ERR, "Could not create socket.");
		goto error;
	}

	int opt = 1;
	setsockopt(request_fd, SOL_SOCKET, SO_REUSEADDR, (void*) &opt, sizeof(opt));

	int rc = connect(request_fd, res->ai_addr, res->ai_addrlen);
	if (rc == -1) {
		log_msg(LOG_ERR, "Could not connect to host %s.", host);
		goto error;
	}

	freeaddrinfo(res);
	return request_fd;

error:
	freeaddrinfo(res);
	close(request_fd);
	return -1;
}

static char *receive_http(const int request_fd, size_t *out) {
	char *raw_buf = NULL;
	size_t buf_size = 0;
	int times_read = 0;

	fd_set chan_fds;
	FD_ZERO(&chan_fds);
	FD_SET(request_fd, &chan_fds);
	const int maxfd = request_fd;

	while (1) {
		times_read++;

		/* Wait for data to be read. */
		struct timeval tv = {
			.tv_sec = SELECT_TIMEOUT,
			.tv_usec = 0
		};
		select(maxfd + 1, &chan_fds, NULL, NULL, &tv);

		int count;
		/* How many bytes should we read: */
		ioctl(request_fd, FIONREAD, &count);
		if (count <= 0)
			break;
		int old_offset = buf_size;
		buf_size += count;
		if (raw_buf != NULL) {
			char *new_buf = realloc(raw_buf, buf_size);
			if (new_buf != NULL) {
				raw_buf = new_buf;
			} else {
				goto error;
			}
		} else {
			raw_buf = calloc(1, buf_size);
		}
		/* printf("IOCTL: %i.\n", count); */

		recv(request_fd, raw_buf + old_offset, count, 0);
	}
	/* printf("Full message is %s\n.", raw_buf); */
	/* Check for a 200: */
	if (raw_buf == NULL || strstr(raw_buf, "200") == NULL) {
		log_msg(LOG_ERR, "Could not find 200 return code in response.");
		goto error;
	}

	/* 4Chan throws us data as chunk-encoded HTTP. Rad. */
	char *header_end = strstr(raw_buf, "\r\n\r\n");
	char *cursor_pos = header_end  + (sizeof(char) * 4);

	size_t result_size = 0;
	char *offset_for_clength = strnstr(raw_buf, "Content-Length: ", buf_size);
	if (offset_for_clength == NULL) {
		log_msg(LOG_ERR, "Could not find content-length.");
		goto error;
	}

	char siz_buf[128] = {0};
	int i = 0;

	const char *to_read = offset_for_clength + strlen("Content-Length: ");
	while (to_read[i] != '\r' && to_read[i + 1] != '\n' && i < sizeof(siz_buf)) {
		siz_buf[i] = to_read[i];
		i++;
	}
	result_size = strtol(siz_buf, NULL, 10);
	log_msg(LOG_INFO, "Received %lu bytes.", result_size);

	char *to_return = malloc(result_size);
	memcpy(to_return, cursor_pos, result_size);
	*out = result_size;
	free(raw_buf);

	return to_return;

error:
	if (raw_buf != NULL)
		free(raw_buf);
	return NULL;
}

static void ensure_directory_for_board(const char *board) {
	/* Long enough for WEBMS_DIR, a /, the board and a NULL terminator */
	const size_t buf_siz = strlen(webm_location()) + sizeof(char) * 2 + strnlen(board, MAX_BOARD_NAME_SIZE);
	char to_create[buf_siz];
	memset(to_create, '\0', buf_siz);

	/* ./webms/b */
	snprintf(to_create, buf_siz, "%s/%s", webm_location(), board);

	struct stat st = {0};
	if (stat(to_create, &st) == -1) {
		log_msg(LOG_WARN, "Creating directory %s.", to_create);
		mkdir(to_create, 0755);
	}
}

static ol_stack *build_thread_index() {
	int request_fd = 0;
	request_fd = connect_to_host(FOURCHAN_API_HOST);
	if (request_fd < 0) {
		log_msg(LOG_ERR, "Could not connect to %s.", FOURCHAN_API_HOST);
		goto error;
	}
	log_msg(LOG_INFO, "Connected to %s.", FOURCHAN_API_HOST);

	/* This is where we'll queue up images to be downloaded. */
	ol_stack *images_to_download = NULL;
	images_to_download = malloc(sizeof(ol_stack));
	images_to_download->next = NULL;
	images_to_download->data = NULL;

	int i;
	for (i = 0; i < (sizeof(BOARDS)/sizeof(BOARDS[0])); i++) {
		const char *current_board = BOARDS[i];

		const size_t api_request_siz = strlen(CATALOG_REQUEST) + strnlen(current_board, MAX_BOARD_NAME_SIZE);
		char new_api_request[api_request_siz];
		memset(new_api_request, '\0', api_request_siz);

		snprintf(new_api_request, api_request_siz, CATALOG_REQUEST, current_board);
		int rc = send(request_fd, new_api_request, strlen(new_api_request), 0);
		if (strlen(new_api_request) != rc)
			goto error;

		log_msg(LOG_INFO, "Sent request to %s.", FOURCHAN_API_HOST);
		char *all_json = receive_chunked_http(request_fd);
		if (all_json == NULL) {
			log_msg(LOG_WARN, "Could not receive chunked HTTP from board for /%s/.", current_board);
			continue;
		}

		ol_stack *matches = parse_catalog_json(all_json, current_board);

		while (matches->next != NULL) {
			/* Pop our thread_match off the stack */
			thread_match *match = (thread_match*) spop(&matches);
			ensure_directory_for_board(match->board);

			log_msg(LOG_INFO, "/%s/ - Requesting thread %i...", current_board, match->thread_num);

			/* Template out a request to the 4chan API for it */
			/* (The 30 is because I don't want to find the length of the
			 * integer thread number) */
			const size_t thread_req_size = sizeof(THREAD_REQUEST) + strnlen(match->board, MAX_BOARD_NAME_SIZE) + 30;
			char templated_req[thread_req_size];
			memset(templated_req, '\0', thread_req_size);

			snprintf(templated_req, thread_req_size, THREAD_REQUEST,
					match->board, match->thread_num);

			/* Send that shit over the wire */
			rc = send(request_fd, templated_req, strlen(templated_req), 0);
			if (rc != strlen(templated_req)) {
				log_msg(LOG_ERR, "Could not send all of request.");
				continue;
			}

			char *thread_json = receive_chunked_http(request_fd);
			if (thread_json == NULL) {
				log_msg(LOG_WARN, "Could not receive chunked HTTP for thread. continuing.");
				/* Reopen and manipulate the socket. */
				close(request_fd);
				request_fd = connect_to_host(FOURCHAN_API_HOST);
				free(match);
				continue;
			}

			ol_stack *thread_matches = parse_thread_json(thread_json, match);
			while (thread_matches->next != NULL) {
				post_match *p_match = (post_match *)spop(&thread_matches);
				/* TODO: Don't add it to the images to download if we already
				 * have that image, with that size, from that board. */
				char fname[MAX_IMAGE_FILENAME_SIZE] = {0};
				get_image_filename(fname, p_match);

				struct stat ifname = {0};
				if (stat(fname, &ifname) != -1 &&
					ifname.st_size == p_match->size) {
					log_msg(LOG_INFO, "Skipping %s.", fname);
					free(p_match);
					continue;
				}

				spush(&images_to_download, p_match);
			}
			free(thread_matches);
			free(thread_json);

			free(match);
		}
		free(matches);

		free(all_json);
	}
	/* We don't need the API socket anymore. */
	close(request_fd);

	return images_to_download;

error:
	if (images_to_download != NULL) {
		while (images_to_download->next != NULL) {
			post_match *_match = (post_match *)spop(&images_to_download);
			free(_match);
		}
		free(images_to_download);
	}
	close(request_fd);
	return NULL;
}
Exemplo n.º 17
0
static inline char *
tparam_internal(const char *string, int *dataptr)
{
#define NUM_VARS 26
    char *p_is_s[9];
    int param[9];
    int lastpop;
    int popcount;
    int number;
    int len;
    int level;
    int x, y;
    int i;
    int len2;
    register const char *cp;
    static int len_fmt = MAX_FORMAT_LEN;
    static char dummy[] = "";
    static char format[MAX_FORMAT_LEN];
    static int dynamic_var[NUM_VARS];
    static int static_vars[NUM_VARS];

    out_used = 0;
    if (string == NULL)
	return NULL;

    if ((len2 = grub_strlen(string)) > len_fmt) {
	return NULL;
    }

    /*
     * Find the highest parameter-number referred to in the format string.
     * Use this value to limit the number of arguments copied from the
     * variable-length argument list.
     */

    number = 0;
    lastpop = -1;
    popcount = 0;
    grub_memset(p_is_s, 0, sizeof(p_is_s));

    /*
     * Analyze the string to see how many parameters we need from the varargs
     * list, and what their types are.  We will only accept string parameters
     * if they appear as a %l or %s format following an explicit parameter
     * reference (e.g., %p2%s).  All other parameters are numbers.
     *
     * 'number' counts coarsely the number of pop's we see in the string, and
     * 'popcount' shows the highest parameter number in the string.  We would
     * like to simply use the latter count, but if we are reading termcap
     * strings, there may be cases that we cannot see the explicit parameter
     * numbers.
     */
    for (cp = string; (cp - string) < (int) len2;) {
	if (*cp == '%') {
	    cp++;
	    cp = parse_format(cp, format, &len);
	    switch (*cp) {
	    default:
		break;

	    case 'd':		/* FALLTHRU */
	    case 'o':		/* FALLTHRU */
	    case 'x':		/* FALLTHRU */
	    case 'X':		/* FALLTHRU */
	    case 'c':		/* FALLTHRU */
		number++;
		lastpop = -1;
		break;

	    case 'l':
	    case 's':
		if (lastpop > 0)
		    p_is_s[lastpop - 1] = dummy;
		++number;
		break;

	    case 'p':
		cp++;
		i = (*cp - '0');
		if (i >= 0 && i <= 9) {
		    lastpop = i;
		    if (lastpop > popcount)
			popcount = lastpop;
		}
		break;

	    case 'P':
	    case 'g':
		cp++;
		break;

	    case '\'':
		cp += 2;
		lastpop = -1;
		break;

	    case '{':
		cp++;
		while (*cp >= '0' && *cp <= '9') {
		    cp++;
		}
		break;

	    case '+':
	    case '-':
	    case '*':
	    case '/':
	    case 'm':
	    case 'A':
	    case 'O':
	    case '&':
	    case '|':
	    case '^':
	    case '=':
	    case '<':
	    case '>':
	    case '!':
	    case '~':
		lastpop = -1;
		number += 2;
		break;

	    case 'i':
		lastpop = -1;
		if (popcount < 2)
		    popcount = 2;
		break;
	    }
	}
	if (*cp != '\0')
	    cp++;
    }

    if (number > 9)
	number = 9;
    for (i = 0; i < max(popcount, number); i++) {
	/*
	 * A few caps (such as plab_norm) have string-valued parms.
	 * We'll have to assume that the caller knows the difference, since
	 * a char* and an int may not be the same size on the stack.
	 */
	if (p_is_s[i] != 0) {
	  p_is_s[i] = (char *)(*(dataptr++));
	} else {
	  param[i] = (int)(*(dataptr++));
	}
    }

    /*
     * This is a termcap compatibility hack.  If there are no explicit pop
     * operations in the string, load the stack in such a way that
     * successive pops will grab successive parameters.  That will make
     * the expansion of (for example) \E[%d;%dH work correctly in termcap
     * style, which means tparam() will expand termcap strings OK.
     */
    stack_ptr = 0;
    if (popcount == 0) {
	popcount = number;
	for (i = number - 1; i >= 0; i--)
	    npush(param[i]);
    }

    while (*string) {
        /* skip delay timings */
	if (*string == '$' && *(string + 1) == '<') {
	    while( *string && *string != '>') 
	        string++;
	    if ( *string == '>' ) string++;
	} else if ( *string == '%') {
	    string++;
	    string = parse_format(string, format, &len);
	    switch (*string) {
	    default:
		break;
	    case '%':
		save_char('%');
		break;

	    case 'd':		/* FALLTHRU */
	    case 'o':		/* FALLTHRU */
	    case 'x':		/* FALLTHRU */
	    case 'X':		/* FALLTHRU */
	    case 'c':		/* FALLTHRU */
		save_number(format, npop(), len);
		break;

	    case 'l':
		save_number("%d", strlen(spop()), 0);
		break;

	    case 's':
		save_text(format, spop(), len);
		break;

	    case 'p':
		string++;
		i = (*string - '1');
		if (i >= 0 && i < 9) {
		    if (p_is_s[i])
			spush(p_is_s[i]);
		    else
			npush(param[i]);
		}
		break;

	    case 'P':
		string++;
		if (isUPPER(*string)) {
		    i = (*string - 'A');
		    static_vars[i] = npop();
		} else if (isLOWER(*string)) {
		    i = (*string - 'a');
		    dynamic_var[i] = npop();
		}
		break;

	    case 'g':
		string++;
		if (isUPPER(*string)) {
		    i = (*string - 'A');
		    npush(static_vars[i]);
		} else if (isLOWER(*string)) {
		    i = (*string - 'a');
		    npush(dynamic_var[i]);
		}
		break;

	    case '\'':
		string++;
		npush(*string);
		string++;
		break;

	    case '{':
		number = 0;
		string++;
		while (*string >= '0' && *string <= '9') {
		    number = number * 10 + *string - '0';
		    string++;
		}
		npush(number);
		break;

	    case '+':
		npush(npop() + npop());
		break;

	    case '-':
		y = npop();
		x = npop();
		npush(x - y);
		break;

	    case '*':
		npush(npop() * npop());
		break;

	    case '/':
		y = npop();
		x = npop();
		npush(y ? (x / y) : 0);
		break;

	    case 'm':
		y = npop();
		x = npop();
		npush(y ? (x % y) : 0);
		break;

	    case 'A':
		npush(npop() && npop());
		break;

	    case 'O':
		npush(npop() || npop());
		break;

	    case '&':
		npush(npop() & npop());
		break;

	    case '|':
		npush(npop() | npop());
		break;

	    case '^':
		npush(npop() ^ npop());
		break;

	    case '=':
		y = npop();
		x = npop();
		npush(x == y);
		break;

	    case '<':
		y = npop();
		x = npop();
		npush(x < y);
		break;

	    case '>':
		y = npop();
		x = npop();
		npush(x > y);
		break;

	    case '!':
		npush(!npop());
		break;

	    case '~':
		npush(~npop());
		break;

	    case 'i':
		if (p_is_s[0] == 0)
		    param[0]++;
		if (p_is_s[1] == 0)
		    param[1]++;
		break;

	    case '?':
		break;

	    case 't':
		x = npop();
		if (!x) {
		    /* scan forward for %e or %; at level zero */
		    string++;
		    level = 0;
		    while (*string) {
			if (*string == '%') {
			    string++;
			    if (*string == '?')
				level++;
			    else if (*string == ';') {
				if (level > 0)
				    level--;
				else
				    break;
			    } else if (*string == 'e' && level == 0)
				break;
			}

			if (*string)
			    string++;
		    }
		}
		break;

	    case 'e':
		/* scan forward for a %; at level zero */
		string++;
		level = 0;
		while (*string) {
		    if (*string == '%') {
			string++;
			if (*string == '?')
			    level++;
			else if (*string == ';') {
			    if (level > 0)
				level--;
			    else
				break;
			}
		    }

		    if (*string)
			string++;
		}
		break;

	    case ';':
		break;

	    }			/* endswitch (*string) */
	} else {             	/* endelse (*string == '%') */
	    save_char(*string);
	}

	if (*string == '\0')
	    break;

	string++;
    }				/* endwhile (*string) */

    get_space(1);
    out_buff[out_used] = '\0';

    return (out_buff);
}
Exemplo n.º 18
0
void generar_BI(Element *obj) {
	Element *operando = (Element *)malloc(sizeof(Element));
	
	spop(&pila, (void *)&operando); //PASO
	fprintf(output_fd, "\t\tJMP\tLJMP%d\n", operando->value);
}
Exemplo n.º 19
0
int download_images() {
	int thumb_request_fd = 0;
	int image_request_fd = 0;
	char *raw_thumb_resp = NULL;
	char *raw_image_resp = NULL;
	FILE *thumb_file = NULL;
	FILE *image_file = NULL;
	post_match *p_match = NULL;

	struct stat st = {0};
	if (stat(webm_location(), &st) == -1) {
		log_msg(LOG_WARN, "Creating webms directory %s.", webm_location());
		mkdir(webm_location(), 0755);
	}

	ol_stack *images_to_download = NULL;
	images_to_download = build_thread_index();
	if (!images_to_download) {
		log_msg(LOG_WARN, "No images to download.");
		goto error;
	}

	thumb_request_fd = connect_to_host(FOURCHAN_THUMBNAIL_HOST);
	if (thumb_request_fd < 0) {
		log_msg(LOG_ERR, "Could not connect to thumbnail host.");
		goto error;
	}

	image_request_fd = connect_to_host(FOURCHAN_IMAGE_HOST);
	if (image_request_fd < 0) {
		log_msg(LOG_ERR, "Could not connect to image host.");
		goto error;
	}

	/* Now actually download the images. */
	while (images_to_download->next != NULL) {
		p_match = (post_match *)spop(&images_to_download);

		char image_filename[MAX_IMAGE_FILENAME_SIZE] = {0};
		get_image_filename(image_filename, p_match);

		/* We already have this file, don't need to download it again. */
		struct stat ifname = {0};
		if (stat(image_filename, &ifname) != -1 && ifname.st_size == p_match->size) {
			log_msg(LOG_INFO, "Skipping %s.", image_filename);
			free(p_match);
			continue;
		}

		char thumb_filename[MAX_IMAGE_FILENAME_SIZE] = {0};
		snprintf(thumb_filename, MAX_IMAGE_FILENAME_SIZE, "%s/%s/thumb_%s.jpg",
				webm_location(), p_match->board, p_match->filename);

		log_msg(LOG_INFO, "Downloading %s%.*s...", p_match->filename, 5, p_match->file_ext);

		/* Build and send the thumbnail request. */
		char thumb_request[256] = {0};
		snprintf(thumb_request, sizeof(thumb_request), THUMB_REQUEST,
				p_match->board, p_match->post_number);
		int rc = send(thumb_request_fd, thumb_request, strlen(thumb_request), 0);
		if (rc != strlen(thumb_request)) {
			log_msg(LOG_ERR, "Could not send all bytes to host while requesting thumbnail.");
			goto error;
		}

		/* Build and send the image request. */
		char image_request[256] = {0};
		snprintf(image_request, sizeof(image_request), IMAGE_REQUEST,
				p_match->board, p_match->post_number, (int)sizeof(p_match->file_ext), p_match->file_ext);
		rc = send(image_request_fd, image_request, strlen(image_request), 0);
		if (rc != strlen(image_request)) {
			log_msg(LOG_ERR, "Could not send all bytes to host while requesting image.");
			goto error;
		}

		size_t thumb_size = 0, image_size = 0;
		raw_thumb_resp = receive_http(thumb_request_fd, &thumb_size);
		raw_image_resp = receive_http(image_request_fd, &image_size);

		if (thumb_size <= 0 || image_size <= 0) {
			/* 4chan cut us off. This happens sometimes. Just sleep for a bit. */
			log_msg(LOG_WARN, "Hit API cutoff or whatever. Sleeping.");
			sleep(30);

			close(thumb_request_fd);
			close(image_request_fd);

			thumb_request_fd = connect_to_host(FOURCHAN_THUMBNAIL_HOST);
			image_request_fd = connect_to_host(FOURCHAN_IMAGE_HOST);
			free(p_match);
			continue;
		}

		if (raw_thumb_resp == NULL) {
			log_msg(LOG_ERR, "No thumbnail received.");
			goto error;
		}

		if (raw_image_resp == NULL) {
			log_msg(LOG_ERR, "No image received.");
			goto error;
		}

		/* Write thumbnail to disk. */
		thumb_file = fopen(thumb_filename, "wb");
		if (!thumb_file || ferror(thumb_file)) {
			log_msg(LOG_ERR, "Could not open thumbnail file: %s", thumb_filename);
			perror(NULL);
			goto error;
		}
		const size_t rt_written = fwrite(raw_thumb_resp, 1, thumb_size, thumb_file);
		log_msg(LOG_INFO, "Wrote %i bytes of thumbnail to disk.", rt_written);
		if (rt_written <= 0 || ferror(thumb_file)) {
			log_msg(LOG_WARN, "Could not write thumbnail to disk: %s", thumb_filename);
			perror(NULL);
			goto error;
		}
		fclose(thumb_file);
		thumb_file = 0;

		image_file = fopen(image_filename, "wb");
		if (!image_file || ferror(image_file)) {
			log_msg(LOG_ERR, "Could not open image file: %s", image_filename);
			perror(NULL);
			goto error;
		}
		const size_t iwritten = fwrite(raw_image_resp, 1, image_size, image_file);
		if (iwritten <= 0 || ferror(image_file)) {
			log_msg(LOG_WARN, "Could not write image to disk: %s", image_filename);
			perror(NULL);
			goto error;
		}
		log_msg(LOG_INFO, "Wrote %i bytes of image to disk.", iwritten);
		fclose(image_file);
		image_file = 0;

		/* Don't need the post match anymore: */
		free(p_match);
		p_match = NULL;
		free(raw_image_resp);
		raw_image_resp = NULL;
		free(raw_thumb_resp);
		raw_thumb_resp = NULL;
	}
	free(images_to_download);
	close(thumb_request_fd);
	close(image_request_fd);
	log_msg(LOG_INFO, "Downloaded all images.");

	return 0;

error:
	if (thumb_request_fd)
		close(thumb_request_fd);

	if (image_request_fd)
		close(image_request_fd);

	if (p_match)
		free(p_match);

	if (images_to_download != NULL) {
		while (images_to_download->next != NULL) {
			post_match *_match = (post_match *)spop(&images_to_download);
			free(_match);
		}
		free(images_to_download);
	}

	if (raw_thumb_resp)
		free(raw_thumb_resp);
	if (raw_image_resp)
		free(raw_image_resp);
	if (thumb_file != NULL)
		fclose(thumb_file);
	if (image_file != NULL)
		fclose(image_file);
	return -1;
}
Exemplo n.º 20
0
void generar_division(Element *obj) {
	Element *operando1 = (Element *)malloc(sizeof(Element));
	Element *operando2 = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&operando2);
	spop(&pila, (void *)&operando1);
	if (operando1->code == REGISTRO && operando1->value == 0) {
		//operando1 ya esta en AL, pasar operando2 a un registro distinto de AH, si es necesario
		;
	} else {
		if (operando2->code == REGISTRO && operando2->value == 0) {
			//operando2 esta en AL, pasar a operando2 a un registro distinto y pasar operando1 a AL
			Element *op_aux = get_free_notA();
			fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando2->name);
			fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
			state[operando2->value] = 1;
			
			Element *op_aux2 = get_free_AL();
			if (operando1->code == REGISTRO) {
				fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux2->name, operando1->name);
				state[operando1->value] = 0;
				operando1 = op_aux2;
			} else {
				if (operando1->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux2->name, operando1->name);
					operando1 = op_aux2;
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux2->name, operando1->value);
					operando1 = op_aux2;				
				}
			}
		} else {
			//ninguno esta en AL. Pasar operando1 a AL y operando2 a un registro distinto de AH, si es necesario
			Element *op_aux = get_free_AL();
			if (operando1->code == REGISTRO) {
				fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando1->name);
				state[operando1->value] = 0;
				operando1 = op_aux;
			} else {
				if (operando1->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name);
					operando1 = op_aux;
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value);
					operando1 = op_aux;
				}
			}
			state[0] = 1;
		}
	}
	if (operando2->code == REGISTRO) {
		if (operando2->value == 1) {
			//esta en AH, moverlo a otro registro libre.
			Element *op_aux = get_free_notA();
			fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
			state[operando2->value] = 1;
		} else {
			//esta en otro registro. No hacer nada.
			;
		}
	} else {
		//conseguir un registro libre distinto de AH y mover operando2 alli.
		Element *op_aux = get_free_notA();
		if (operando2->code == IDENTIFICADOR) {
			fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
		} else {
			fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando2->value);
			operando2 = op_aux;
		}
		state[operando2->value] = 1;
	}
	state[1] = 0;
	
	// Chequear por división por cero
	fprintf(output_fd, "\t\tJNZ\tLABEL00%d\t; Chequeo de división por cero\n", labelnumber);

  incluir_recuperacion_div_cero(operando2);

	fprintf(output_fd, "\tLABEL00%d:\n\t\tCBW\n", labelnumber);
	labelnumber++;


	//A esta altura, operando1 es AL y operando2 es otro registro distinto de AH
	fprintf(output_fd, "\t\tIDIV\t%s\n", operando2->name);
	state[operando2->value] = 0; /*Libero el registro*/
	//Apilo AL, el cociente
	spush(&pila, (void *)operando1);
}
Exemplo n.º 21
0
void generar_multiplicacion(Element *obj) {
	Element *operando1 = (Element *)malloc(sizeof(Element));
	Element *operando2 = (Element *)malloc(sizeof(Element));

	spop(&pila, (void *)&operando2);
	spop(&pila, (void *)&operando1);
	if (operando1->code == REGISTRO && operando1->value == 0) {
		//operando1 ya esta en AL, pasar operando2 a un registro distinto de AH, si es necesario
		;
	} else {
		if (operando2->code == REGISTRO && operando2->value == 0) {
			//operando2 esta en AL, swapear las variables y pasar a operando2 a un registro distinto de AH, si es necesario
			Element *aux = operando1;
			operando1 = operando2;
			operando2 = aux;
		} else {
			//ninguno esta en AL. Pasar operando1 a AL y operando2 a un registro distinto de AH, si es necesario
			Element *op_aux = get_free_AL();
			if (operando1->code == REGISTRO) {
				fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando1->name);
				state[operando1->value] = 0;
				operando1 = op_aux;
			} else {
				if (operando1->code == IDENTIFICADOR) {
					fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando1->name);
					operando1 = op_aux;
				} else {
					fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando1->value);
					operando1 = op_aux;				
				}
			}
			state[0] = 1;
		}
	}
	if (operando2->code == REGISTRO) {
		if (operando2->value == 1) {
			//esta en AH, moverlo a otro registro libre.
			Element *op_aux = get_free_notA();
			fprintf(output_fd, "\t\tMOV\t%s, %s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
			state[operando2->value] = 1;
		} else {
			//esta en otro registro. No hacer nada.
			;
		}
	} else {
		//conseguir un registro libre distinto de AH y mover operando2 alli.
		Element *op_aux = get_free_notA();
		if (operando2->code == IDENTIFICADOR) {
			fprintf(output_fd, "\t\tMOV\t%s, _%s\n", op_aux->name, operando2->name);
			operando2 = op_aux;
		} else {
			fprintf(output_fd, "\t\tMOV\t%s, %d\n", op_aux->name, operando2->value);
			operando2 = op_aux;
		}
		state[operando2->value] = 1;
	}
	state[1] = 0;

	//A esta altura, operando1 es AL y operando2 es otro registro distinto de AH
	fprintf(output_fd, "\t\tIMUL\t%s\n", operando2->name);

  incluir_chequeo_overflow(operando1);

	state[operando2->value] = 0; /*Libero el registro*/
	//Apilo AL, la parte baja del resultado
	spush(&pila, (void *)operando1);
}