void ob_binclude( binclude_element * in_el ) { uint32_t count; if( search_file_in_dirs( in_el->file, "", "", ds_doc_spec ) ) { fb_binclude_support( in_el ); if( fwrite( buffout.text, sizeof( uint8_t ), buffout.current, out_file_fp ) < buffout.current ) { xx_simple_err_c( err_write_out_file, out_file ); } buffout.current = 0; if( in_el->has_rec_type ) { count = fread( buffout.text, sizeof( uint8_t ), buffout.length, try_fp ); while( count == buffout.length ) { buffout.current = count; if( fwrite( buffout.text, sizeof( uint8_t ), buffout.current, out_file_fp ) < buffout.current ) { xx_simple_err_c( err_write_out_file, out_file ); count = 0; break; } count = fread( buffout.text, sizeof( uint8_t ), buffout.length, try_fp ); } buffout.current = count; if( fwrite( buffout.text, sizeof( uint8_t ), buffout.current, out_file_fp ) < buffout.current ) { xx_simple_err_c( err_write_out_file, out_file ); } if( ferror( try_fp ) ) { xx_simple_err_cc( err_in_file, "BINCLUDE", try_file_name ); } buffout.current = 0; } else { count = fread( binc_buff.text, sizeof( uint8_t ), binc_buff.length, try_fp ); while( count == binc_buff.length ) { binc_buff.current = count; ob_flush(); if( fwrite( binc_buff.text, sizeof( uint8_t ), binc_buff.current, out_file_fp ) < binc_buff.current ) { xx_simple_err_c( err_write_out_file, out_file ); count = 0; break; } count = fread( binc_buff.text, sizeof( uint8_t ), binc_buff.length, try_fp ); } binc_buff.current = count; if( fwrite( binc_buff.text, sizeof( uint8_t ), binc_buff.current, out_file_fp ) < binc_buff.current ) { xx_simple_err_c( err_write_out_file, out_file ); } if( in_el->depth > 0 ) { ob_flush(); } if( ferror( try_fp ) ) { xx_simple_err_cc( err_in_file, "BINCLUDE", try_file_name ); } } } else { xx_tag_err( err_file_not_found, in_el->file ); } return; }
void ob_teardown( void ) { if( binc_buff.text != NULL ) { mem_free( binc_buff.text ); binc_buff.text = NULL; } if( buffout.text != NULL ) { mem_free( buffout.text ); buffout.text = NULL; } if(translated.text != NULL ) { mem_free( translated.text ); translated.text = NULL; } if( out_file_fp != NULL ) { if( fclose( out_file_fp ) ) { xx_simple_err_c( err_close_out_file, out_file ); } out_file_fp = NULL; } return; }
void ob_direct_out( char * text ) // used from .oc { if( fwrite( text, sizeof( uint8_t ), strlen( text ), out_file_fp ) < strlen( text ) ) { xx_simple_err_c( err_write_out_file, out_file ); return; } #ifdef __UNIX__ if( fprintf_s( out_file_fp, "\n" ) < strlen( "\n" ) ) { xx_simple_err_c( err_write_out_file, out_file ); return; } #else if( fprintf_s( out_file_fp, "\r\n" ) < strlen( "\r\n" ) ) { xx_simple_err_c( err_write_out_file, out_file ); return; } #endif return; }
void ob_flush( void ) { if( fwrite( buffout.text, sizeof( uint8_t ), buffout.current, out_file_fp ) < buffout.current ) { xx_simple_err_c( err_write_out_file, out_file ); return; } buffout.current = 0; #ifdef __UNIX__ if( fprintf_s( out_file_fp, "\n" ) < strlen( "\n" ) ) { xx_simple_err_c( err_write_out_file, out_file ); return; } #else if( fprintf_s( out_file_fp, "\r\n" ) < strlen( "\r\n" ) ) { xx_simple_err_c( err_write_out_file, out_file ); return; } #endif return; }
char * get_member_name( char const * in_name ) { char * member_name = NULL; cop_file_type file_type; directory_entry current_entry; entry_found entry_status; size_t member_length; uint16_t entry_type; /* See if in_name is found in try_file_name. */ file_type = parse_header( try_fp ); switch( file_type ) { case file_error: /* File error, including premature eof. */ xx_simple_err_c( err_dev_lib_file, try_file_name ); break; case not_se_v4_1: /* File was created by a different version of gendev. */ xx_simple_err( err_wrong_gendev ); break; case not_bin_dev: case se_v4_1_not_dir: /* Wrong type of file: something is wrong with the device library. */ xx_simple_err_c( err_dev_lib_data, try_file_name ); break; case dir_v4_1_se: /* try_fp was a same-endian version 4.1 directory file. */ /* Skip the number of entries. */ fseek( try_fp, sizeof( uint32_t ), SEEK_CUR ); if( ferror( try_fp ) || feof( try_fp ) ) { break; } for( ;; ) { /* Get the entry_type. This is either the type or the metatype, * depending on whether this is a CompactDirEntry or an * ExtendedDirEntry. */ entry_type = fread_u16( try_fp ); /* Exit the loop when the final entry has been processed. */ if( feof( try_fp ) || ferror( try_fp ) ) { break; } switch( entry_type) { case 0x0000: /* This should only happen when the end-of-file padding is * reached, but continue in case there is more data. */ continue; case 0x0001: /* This will be an ExtendedDirEntry. */ for( ;; ) { /* Get the entry_type. This is always the type, since the * metatype has already been read. */ entry_type = fread_u16( try_fp ); /* Exit the loop when the final entry has been processed. */ if( feof( try_fp ) || ferror( try_fp ) ) { break; } switch( entry_type ) { case 0x0000: /* This should only happen when the end-of-file padding is * reached, but continue in case there is more data. */ continue; case 0x0001: /* This should never actually occur; however, continue * in case there is more data. */ continue; case 0x0101: case 0x0201: case 0x0401: /* For any type, check the defined name. */ entry_status = get_extended_entry( try_fp, ¤t_entry ); switch( entry_status ) { case valid_entry: /* Return the member name, if found. */ if( !stricmp( in_name, current_entry.defined_name ) ) { member_length = strlen( current_entry.member_name ) + 1; member_name = mem_alloc( member_length ); strcpy( member_name, current_entry.member_name ); return( member_name ); } break; case not_valid_entry: break; default: /* The entry_status is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } break; default: /* The entry_type is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } break; } break; case 0x0101: case 0x0201: case 0x0401: /* For any type, check the defined name. */ entry_status = get_compact_entry( try_fp, ¤t_entry ); switch( entry_status ) { case valid_entry: /* Return the member name, if found. */ if( !stricmp( in_name, current_entry.defined_name) ) { member_length = strlen( current_entry.member_name ) + 1; member_name = mem_alloc( member_length ); strcpy( member_name, current_entry.member_name ); return( member_name ); } break; case not_valid_entry: break; default: /* The entry_status is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } break; default: /* The entry_type is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } } break; default: /* The file_type is an unknown value. */ internal_err( __FILE__, __LINE__ ); break; } return( member_name ); }
static void ob_insert_def_ot( char *in_block, size_t count, font_number font ) { size_t text_count; translation * * cur_table = NULL; translation * cur_trans = NULL; char ch; uint32_t i; /* Adjust font if necessary and initialize cur_table and text_count. */ if( font >= wgml_font_cnt ) font = 0; if( wgml_fonts[font].outtrans != NULL ) cur_table = wgml_fonts[font].outtrans->table; text_count = count; for( i = 0; i < count; i++ ) { /* If the buffer is full, flush it. */ if( buffout.current == buffout.length ) ob_flush(); /* Now check for an output translation. */ ch = tr_table[(uint8_t)in_block[i]]; if( ch == in_block[i] ) { if( cur_table == NULL ) { /* No output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } else { /* An :OUTTRANS block exists. */ cur_trans = cur_table[(uint8_t)ch]; if( cur_trans == NULL ) { /* No output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } else { /* An :OUTTRANS block output translation was found. */ if( cur_trans->count == 1 ) { /* This is a single-character output translation. */ buffout.text[buffout.current] = cur_trans->data[0]; buffout.current++; } else { /* This is a multi-character output translation. */ /* If it is too large to fit at all, report overflow. */ if( cur_trans->count > buffout.length ) { xx_simple_err_c( err_out_rec_size, dev_name ); } /* If it won't fit in the current buffer, flush the buffer. */ if( (buffout.current + cur_trans->count) > buffout.length ) { ob_flush(); } /* At this point, it is known that it will fit. */ memcpy_s( &buffout.text[buffout.current], cur_trans->count, cur_trans->data, cur_trans->count ); buffout.current += cur_trans->count; } } } } else { /* A single-byte .tr output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } text_count--; } /* If the buffer is full, flush it. */ if( buffout.current == buffout.length ) ob_flush(); return; }
static void ob_insert_ps_cmd_ot( char *in_block, size_t count, font_number font ) { size_t test_length; size_t text_count; translation * * cur_table = NULL; translation * cur_trans = NULL; char ch; uint32_t i; uint32_t j; uint32_t k; /* Adjust font if necessary and initialize cur_table and text_count. */ if( font >= wgml_font_cnt ) font = 0; if( wgml_fonts[font].outtrans != NULL ) cur_table = wgml_fonts[font].outtrans->table; text_count = count; for( i = 0; i < count; i++ ) { /* If the buffer is full, flush it. */ if( buffout.current == buffout.length ) ob_flush(); /* First process any initial space. */ if( in_block[i] == ' ' ) { /* Now check for an output translation. */ ch = tr_table[(uint8_t)in_block[i]]; if( ch == in_block[i] ) { if( cur_table == NULL ) { /* No output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } else { /* An :OUTTRANS block exists. */ cur_trans = cur_table[(uint8_t)ch]; if( cur_trans == NULL ) { /* No output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } else { /* An :OUTTRANS block output translation was found. */ if( cur_trans->count == 1 ) { /* This is a single-character output translation. */ buffout.text[buffout.current] = cur_trans->data[0]; buffout.current++; } else { /* This is a multi-character output translation. */ /* If it is too large to fit at all, report overflow. */ if( cur_trans->count > buffout.length ) { xx_simple_err_c( err_out_rec_size, dev_name ); } /* If it won't fit, flush the buffer. */ if( (buffout.current + cur_trans->count) > buffout.length ) { ob_flush(); } /* At this point, it is known that it will fit. */ memcpy_s( &buffout.text[buffout.current], cur_trans->count, cur_trans->data, cur_trans->count ); buffout.current += cur_trans->count; } } } } else { /* A single-byte .tr output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } text_count--; /* Process next character, might be another space. */ continue; } /* Get the next token and translate it. */ k = 0; for( j = i; j < count; j++ ) { /* in_block[i] points to a non-space character. */ if( in_block[j] == ' ' ) break; /* At least one character will be added to translated. */ if( k >= translated.length ) { translated.length *= 2; translated.text = mem_realloc( translated.text, translated.length ); } /* Add the non-space character to translated. */ ch = tr_table[(uint8_t)in_block[j]]; if( ch == in_block[j] ) { if( wgml_fonts[font].outtrans == NULL ) { /* No translation exists: copy the character. */ translated.text[k] = ch; k++; } else { /* An :OUTTRANS block exists. */ cur_trans = cur_table[(uint8_t)ch]; if( cur_trans == NULL ) { /* No output translation was found. */ translated.text[k] = ch; k++; } else { /* An :OUTTRANS block output translation was found. */ if( cur_trans->count == 1 ) { /* Single-char translation found. */ translated.text[k] = cur_trans->data[0]; k++; } else { /* Multi-char translation found. */ /* If it is too large to fit at all, report overflow. */ if( cur_trans->count > buffout.length ) { xx_simple_err_c( err_out_rec_size, dev_name ); } if( (k + cur_trans->count) >= translated.length ) { translated.length *= 2; translated.text = mem_realloc( translated.text, translated.length ); } memcpy_s( &translated.text[k], cur_trans->count, cur_trans->data, cur_trans->count ); k += cur_trans->count; } } } } else { /* A single-byte .tr translation found. */ translated.text[k] = ch; k++; } } translated.current = k; i = j; /* If a space followed the current token, test_length must include it. */ test_length = buffout.current + translated.current; if( in_block[i] == ' ' ) test_length++; /* If the token won't fit, flush the buffer. The increment at the top * of the loop will skip any following space character; since this is * not correct except when the buffer has been flushed, decrement i. * text_count is decremented if the flush occurs because the space * will be skipped, but not otherwise since it will be processed. */ if( test_length >= buffout.length ) { ob_flush(); text_count--; } else { i--; } /* Now insert the translated token into the buffer. */ memcpy_s( &buffout.text[buffout.current], translated.current, translated.text, translated.current ); buffout.current += translated.current; text_count -= translated.current; } return; }
void ob_setup( void ) { int i; size_t count; /* Finalize out_file and out_file_attr. */ set_out_file(); set_out_file_attr(); /* The record type must be "t"; it must have only one character and be */ /* followed by ":". */ if( tolower( (out_file_attr[0] ) != 't') || (out_file_attr[1] != ':') ) { xx_simple_err_c( err_rec_att_not_sup, out_file_attr ); } /* The rest of the record type must be numeric. */ count = 0; for( i = 2; i < strlen( out_file_attr ); i++ ) { if( !isdigit( out_file_attr[i] ) ) { xx_simple_err_c( err_rec_att_bad_fmt, out_file_attr ); } count++; } /* Initialize the local variables. */ binc_buff.current = 0; binc_buff.length = 80; binc_buff.text = mem_alloc( binc_buff.length ); buffout.current = 0; buffout.length = strtoul( &out_file_attr[2], NULL, 0 ); if( errno == ERANGE ) { xx_simple_err_i( err_out_rec_size2, ULONG_MAX ); } buffout.text = mem_alloc( buffout.length ); translated.current = 0; translated.length = 80; translated.text = mem_alloc( translated.length ); /* Create (truncate) the output file. */ fopen_s( &out_file_fp, out_file, "uwb" ); if( out_file_fp == NULL ) { xx_simple_err_c( err_open_out_file, out_file ); } /* Initialize tr_table. */ for( i = 0; i < 0x100; i++) { tr_table[i] = i; } return; }
static void ob_insert_ps_text( char *in_block, size_t count, font_number font ) { size_t difference; translation * * cur_table = NULL; translation * cur_trans = NULL; char ch; uint32_t i; /* If the buffer is full, flush it. */ if( buffout.current == buffout.length ) ob_flush(); /* Adjust font if appropriate and initialize cur_trans. */ if( font >= wgml_font_cnt ) font = 0; if( wgml_fonts[font].outtrans != NULL ) cur_table = wgml_fonts[font].outtrans->table; for( i = 0; i < count; i++ ) { difference = buffout.length - buffout.current; if ( difference > 1 ) { /* buffout has room for at least one character. */ ch = tr_table[(uint8_t)in_block[i]]; if( ch == in_block[i] ) { if( cur_table == NULL ) { /* No output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } else { /* An :OUTTRANS block exists. */ cur_trans = cur_table[(uint8_t)ch]; if( cur_trans == NULL ) { /* No output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } else { /* An :OUTTRANS block output translation was found. */ if( cur_trans->count == 1 ) { /* This is a single-character output translation. */ buffout.text[buffout.current] = cur_trans->data[0]; buffout.current++; } else { /* This is a multi-character output translation. */ /* If it is too large to fit at all, report overflow. */ if( cur_trans->count > buffout.length ) { xx_simple_err_c( err_out_rec_size, dev_name ); } /* If it won't fit in the current buffer, finalize * and flush the buffer. */ if( (buffout.current + cur_trans->count + 1) > buffout.length ) { buffout.text[buffout.current] = '\\'; buffout.current++; ob_flush(); } /* At this point, it is known that it will fit. */ memcpy_s( &buffout.text[buffout.current], cur_trans->count, cur_trans->data, cur_trans->count ); buffout.current += cur_trans->count; } } } } else { /* A single-byte .tr output translation was found. */ buffout.text[buffout.current] = ch; buffout.current++; } } else { /* Finalize and flush the buffer. Adjust i so that, when * incremented at the top of the loop, it points to the same * character and that character is not skipped. */ buffout.text[buffout.current] = '\\'; buffout.current++; ob_flush(); i--; } } return; }
void ob_graphic( graphic_element * in_el ) { char begindoc[] = "%%BeginDocument: "; char enddoc[] = "%%EndDocument"; char graphobj[] = "/graphobj save def /showpage { } def"; char restore[] = "graphobj restore"; size_t ps_size; uint32_t count; if( search_file_in_dirs( in_el->file, "", "", ds_doc_spec ) ) { fb_graphic_support( in_el ); ob_flush(); ps_size = strlen( graphobj ); strcpy_s( buffout.text, buffout.length, graphobj ); buffout.current = ps_size; ob_flush(); memset( buffout.text, buffout.length, '\0' ); ps_size = sprintf_s( buffout.text, buffout.length, "%d %d %d %d %d %d %d graphhead", in_el->cur_left, in_el->y_address, in_el->width, in_el->depth, in_el->xoff, -1 * (in_el->depth + in_el->yoff), in_el->scale ); buffout.current = strlen( buffout.text ); ob_flush(); ps_size = strlen( begindoc ); strcpy_s( buffout.text, buffout.length, begindoc ); buffout.current = ps_size; strcpy_s( buffout.text + ps_size, buffout.length - ps_size, in_el->file ); buffout.current = strlen( buffout.text ); ob_flush(); count = fread( buffout.text, sizeof( uint8_t ), buffout.length, try_fp ); while( count == buffout.length ) { buffout.current = count; if( fwrite( buffout.text, sizeof( uint8_t ), buffout.current, out_file_fp ) < buffout.current ) { xx_simple_err_c( err_write_out_file, out_file ); return; } count = fread( buffout.text, sizeof( uint8_t ), buffout.length, try_fp ); } buffout.current = count; if( fwrite( buffout.text, sizeof( uint8_t ), buffout.current, out_file_fp ) < buffout.current ) { xx_simple_err_c( err_write_out_file, out_file ); return; } buffout.current = 0; ps_size = strlen( enddoc ); strcpy_s( buffout.text, buffout.length, enddoc ); buffout.current = ps_size; ob_flush(); ps_size = strlen( restore ); strcpy_s( buffout.text, buffout.length, restore ); buffout.current = ps_size; ob_flush(); if( ferror( try_fp ) ) { xx_simple_err_cc( err_in_file, "GRAPHIC", try_file_name ); } } else { xx_tag_err( err_file_not_found, in_el->file ); } return; }