// Decode the base-64 data, and write to d->decoded. // Returns 0 if there was an error. static int do_decode_main(deark *c, lctx *d, de_int64 pos) { de_byte b; de_byte x; de_byte pending_byte = 0; unsigned int pending_bits_used = 0; while(1) { if(pos >= c->infile->len) return 0; // unexpected end of file b = de_getbyte(pos); pos++; if(b==':') { break; } else if(b=='\x0a' || b=='\x0d' || b==' ' || b=='\t') { // Ignore whitespace continue; } x = get_char_value(b); if(x>=64) { de_err(c, "Invalid BinHex data at %d\n", (int)(pos-1)); return 0; } // TODO: Simplify this code if(pending_bits_used==0) { pending_byte = x; pending_bits_used = 6; } else if(pending_bits_used==2) { pending_byte = (pending_byte<<(8-pending_bits_used))|x; dbuf_writebyte(d->decoded, pending_byte); pending_bits_used -= 2; } else if(pending_bits_used==4) { pending_byte = (pending_byte<<(8-pending_bits_used))|(x>>(pending_bits_used-2)); dbuf_writebyte(d->decoded, pending_byte); pending_byte = x&0x03; pending_bits_used -= 2; } else if(pending_bits_used==6) {
/* Escreve no arquivo de saida o resultado da montagem. Recebe arquivos de entrada e saida, e vetores de rotulo e constantes. */ void print_file(char* fileFrom, char* fileTo, label_table t, set_table s){ FILE* _fileFrom = fopen(fileFrom,"r"); FILE* _fileTo = fopen(fileTo,"w"); char word[20]; int position_count= 0; while (!feof(_fileFrom)) { fscanf(_fileFrom," %s ", word); /* Leu comentario. Le toda a linha */ if (strchr(word,'@')) { char character = fgetc(_fileFrom); while (character != '\n') character = fgetc(_fileFrom); } else if (strchr(word,'.')){ /* Eh diretiva, ou seja foi encontrado um '.' */ int d = get_directive(word), isLabel = 0, isContraint = 0; /* Variaveis auxiliares */ char aux[20]; char *_aux_string = (char*) malloc(10*sizeof(char)); int _num, _aux, _value; /* Le primeiro parametro */ fscanf(_fileFrom," %s ",word); switch (d) { /* .org soh precisamos atualizar contador */ case ORG : position_count = get_number(word)*2; break; /* verificamos se preecisamos alinhar mapa de memoria e se ha a necessidade de imprimirmos 00000 a direita de uma linha */ case ALIGN: _num = get_number(word); if (position_count%(2*_num)) { if (position_count%2) /* imprime zeros caso esteja na direita */ fprintf(_fileTo,"%05X\n",0); position_count = position_count/(2*_num)*2 + 2*_num; } break; /* Se eh um .WORD, verificamos se eh um rotulo ou um valor */ case WORD : _value = is_Label(word, t,&isLabel); /* se for rotulo, temos que dividir endereço de memoria por dois */ if (isLabel) sprintf(aux,"%010X", _value/2); else { get_char_value(word, &_aux_string); sprintf(aux,"%s", _aux_string); /* escreve na variavel auxiliar para depois escrevermos no arquivo */ } fprintf(_fileTo,"%03X %s\n",position_count/2, aux); position_count += 2; break;/* atualiza contador */ case WFILL: word[strlen(word)-1] = '\0'; /* ignora-se a ','*/ _num = get_number(word); /* quantidade de iteracoes */ fscanf(_fileFrom," %s ",word); /* transforma valor lido adequadamente para impressao */ get_char_value(word,&_aux_string); /* verifica se um rotulo, constante ou valor */ _value = get_label_value(word, t, s, &isLabel, &isContraint); for (_aux = 0; _aux < _num; _aux++){ /* trata cada caso individualmente */ if (isContraint) { sprintf(word,"%d", _value); /* passa valor da constante para um string, a fim de utilizarmos a funcao get_char_value */ get_char_value(word,&_aux_string); sprintf(aux,"%s", _aux_string); } else if (isLabel) sprintf(aux,"%010X", _value/2); else sprintf(aux,"%s", _aux_string); /* escreve no arquivo */ fprintf(_fileTo,"%03X %s\n",position_count/2, aux); position_count += 2; } break; /* nao faz nada, soh le valor */ case SET : fscanf(_fileFrom," %s ",word); break; default : printf("Erro"); } free(_aux_string ); } /* se nao for rotulo, soh pode ser instrucao */ else if (!strchr(word,':')){ /* Verificamos 'familia' de instrucao */ int _option = get_instruction(word), opcode, isLabel = 0, _val, isContraint = 0; /* Variaveis auxiliares */ char _aux[20], _aux2[20]; switch (_option) { case M_INSTRUCTION : opcode = get_instruction_opcode(word, position_count%2); fscanf(_fileFrom," %s ",word); /* OBTER VALOR ENTRE M() */ strncpy(_aux, word+2, strlen(word)); _aux[strlen(word)-3] = '\0'; /* obtem valor de constante, rotulo ou valor */ _val = get_label_value(_aux,t,s,&isLabel,&isContraint); break; /* Nao ha posicoes de memoria para serem lidas */ case NO_M_INSTRUCTION : opcode = get_instruction_opcode(word, position_count%2); _val = 0; break; /* Devemos verificar se a instrucao refere-se a direita ou esquerda */ case LR_INSTRUCTION : fscanf(_fileFrom," %s ",_aux2); /* OBTER VALOR ENTRE M() */ sprintf(_aux, "%s", _aux2+2); _aux[strlen(_aux)-1] = '\0'; /* obtem valor de constante, rotulo ou valor */ _val = get_label_value(_aux, t,s,&isLabel, &isContraint); /* obtem valor correto da instrucao */ opcode = get_instruction_opcode(word, _val%2); break; } if (isLabel) _val = _val/2; /* Se for um rotulo, o valor deve ser divido por 2, afinal ele representa uma posicao de memoria */ if (position_count%2) /* Verifica se ha a necessidade de escrever a posicao de memoria atual. */ fprintf(_fileTo,"%02X%03X\n",opcode,_val); else fprintf(_fileTo,"%03X %02X%03X",position_count/2,opcode, _val); position_count++; } } /* Verifica se a necessidade de completarmos fim de arquivo com 0 (termicou na direita */ if (position_count%2) fprintf(_fileTo,"%05X\n",0); fclose(_fileFrom); fclose(_fileTo); return; }