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++; }
/* 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; }
/* 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; }
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; }
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; } } }
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; }
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; }
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); }
static _pit * _pop_frame(void) { _cstackitem *ci; ci = spop(current_ctx->cs); if (!ci) { return NULL; } return ci->ckey; }
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; }
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); } }
void lpop() { spop(); spop(); }
// 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; }
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 {
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); }
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; }
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); }
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); }
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; }
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); }
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); }