// UNPAKDEC.VDM -- Unpack/convert EBCDIC file with upto 32 packed-decimal fields. // Fixed length records may optionally have newlines appended. // Converted file is saved as "filename.ASC". // // Originally by: Theodore Green, Greenview Data, Inc. // Last change: 10/05/99 // // Requires: VEDIT PLUS 5.11 dated 10/20/98 or later. // // Record description file UNPAKDEC.LAY. (See UNPAKDEC.TXT). // See UNPAKDEC.LAY for prototype. // // From OS: VPW [-N] [-Y] -X UNPAKDEC filename // // File UNPAKDEC.LAY must exist in the current directory // or in Vedit's "Home" directory. When done, saves file // and displays it in Visual Mode. // // -Y exits Vedit after saving the translated file. // // -N uses "filename.LAY" as its record description file. // Also can set numeric variable #75 to always use // "filename.LAY". See below. // // Note: Uses speed-optimized Unpack_BCD() command to unpack // the entire file. // ////////////////////////////////////////////////////////////////////////////// // // Numeric register usage: // // #10 - #73 Beginning/ending columns for up to 32 packed fields // #74 Reserved (zero when 32 fields) // #75 Override flag to use "filename.LAY" instead of UNPAKDEC.LAY // #80 Temp // #81 Temp; # chars in packed field // #82 Temp // #83 Options for Unpack_BCD() based on "+bz" // #84 Register to use for customized decoding ('c') // #85 Current data type // #86 File header size // #87 Input fixed record size // #88 Output record size/type ('r=input_rec,output_rec') // #89 Output field size override // #90 Original buffer # // #91 Number of fields specified // #92 "Extra" buffer with UNPAKDEC.LAY // #93 1st line number to convert, possibly skipping header // #94 1st unprocessed field in file // #95 Beginning column of packed field // #96 Ending column of packed field // #97 Offset for columns due to unpacking // #98 Unused // #99 ID flag, possibly set by WILDFILE macro // ////////////////////////////////////////////////////////////////////////////// // // Initialize. // Num_Push(10,99) //Save numeric regs used here Reg_Push(10,12) //Save T-Regs used here #90 = Buf_Num //#90 = current buffer # #92 = Buf_Free(EXTRA) //#92 = "extra" buffer for UNPAKDEC.LAY #75 = 0 //Set nonzero to always use filename.LAY //instead of UNPAKDEC.LAY. Win_Clear() Message('\n *************************************************************') Message('\n * UNPAKDEC.VDM - 10/05/99 *') Message('\n * Convert EBCDIC file with packed-decimal fields to ASCII *') Message('\n *************************************************************') Type_Newline() // // If no file open, prompt for file and open it. // if (Is_Open_Write==0) { repeat(ALL) { Get_Input(10,"\nEnter name of file to convert: ",NOCR) if (File_Exist(@10)) { Break } Alert() Message("\nFile not found; please try again or to cancel.\n") } File_Open(@10,NOEVENT) } // // Save converted file as "filename.ASC". // Set T-Reg[11] = "filename.LAY". // Reg_Set(10,PATHNAME) //T-Reg 10 = full pathname Buf_Switch(#92) //Switch to temp buffer Buf_Empty(OK) Reg_Ins(10) //Insert full pathname Replace(".|M|>","",REVERSE+NOERR) //Delete any existing extent EOF() Ins_Text(".ASC") //Add ".ASC" as new extent Reg_Copy_Block(10,0,File_Size) //Copy new filename back to T-reg 10 Replace(".|M|>",".LAY",BEGIN) //Change extent to "LAY Reg_Copy_Block(11,0,File_Size) //Copy filename.LAY to T-reg 11 Buf_Switch(#90) File_Save_As(@10,OK+NOMSG) //Save converted file as filename.ASC Config(F_OVER_MODE,0) // // Determine name of record description file - UNPAKDEC.LAY or filename.LAY. // Load it from the current directory if possible; else from the VEDIT // Home Directory. Quit if no such file. // Buf_Switch(#92) //Switch to temp buffer Buf_Empty(OK) if (!(Is_Option(n) || #75)) { Reg_Set(11,"unpakdec.lay") } if (File_Exist(@11)) { //If local data file, open it File_Open(@11,FORCE+NOEVENT) } else { if (File_Exist("|(HOME)\|@(11)")) { File_Open("|(HOME)\|@(11)",FORCE+NOEVENT) } else { Message(`\nCannot find `); Reg_Type(11) Message(` in current nor VEDIT's "home" directory.`) Message(`\nRefer to UNPAKDEC.DOC for details.\n`) Break_Out(EXTRA+CONFIRM) }} // ////////////////////////////////////////////////////////////////////////////// // // Process UNPAKDEC.LAY (or "filename.LAY") // Strip comments. // Ascertain header & record size and optional output filetype code. // Remove any explicit 'd's (Packed Decimal field type). // Load Numeric regs 10 - 73 with up to 32 sets of field columns. // Perform error checking; break out if bad input. // #93 = 1 //Convert line 1, unless header #86 = #87 = #88 = -1 //Init that record-size and header not specified Replace("|<|[|W]//|Y|L","",BEGIN+ALL+NOERR) //Strip comment lines Replace("|W//|Y|>","",BEGIN+ALL+NOERR) //Strip inline comments Replace("|<|w","",BEGIN+ALL+NOERR) //Remove leading whitespace Replace("|73){goto TOOMANY} //Only 32 fields available #81 = Num_Eval(SUPPRESS+ADVANCE) //Get field starting column if (#81 < 1 || #81 > 65535) { goto BADDAT } //Check for valid range if (#81 < #80 ) { goto BADDAT } //Fields must be in ascending order #80 = #81 //Save column for validity check #@91 = #81 //Set begin column # #91++ //Increment index if (!Search_Block("|D",Cur_Pos,EOL_Pos,NOERR)) { goto BADDAT } #81 = Num_Eval(SUPPRESS+ADVANCE) //Get field ending column if (#81 < 1 || #81 > 65535) { goto BADDAT } //Check for valid range if (#81 < #80 ) { goto BADDAT } //Fields must be in ascending order #80 = #81 //Save column for validity check #83 = 0 //No flags yet Match("|W",ADVANCE) //Advance to possible flags if(match("+",ADVANCE)==0){#83 = 1 } //Force '+' if(match("b",ADVANCE)==0){#83 = #83 | 2 } //Put sign at begin of field if(match("z",ADVANCE)==0){#83 = #83 | 4 } //Leading zeros #@91 = #81 + (#83 << 24 ) //Set end col # and flags #91++ //Increment index :NEXTLN: line(1,errbreak) } #@91 = 0 //Signal end of fields #91 = (#91 - 10) >> 1 //#91 = # of fields // // ///////////////////////////////////////////////////////////////////////////// // // Convert fixed length records to terminated text lines, perhaps. // // Buf_Switch(#90) if (#87>7 && #88>=0 && #88<3) { Message("\nAppending newlines...") Goto_Line(1) while(!At_EOF) { char(#87) if ((#88&1) == 0){InsChar(0x0d)} //DOS and MAC if (#88<2){InsChar(0x0a)} //DOS and UNIX } Type_Newline() Config(F_F_TYPE,#88,LOCAL) File_Save(BEGIN) //Quickly go to beginning of file } // ///////////////////////////////////////////////////////////////////////////// // // Display estimated conversion time. // #80 = File_Size/60000 #80 = (#91 * #80)/30 + 1 //#80 = estimated # seconds Message("\nConverting. Estimated time (200mhz Pentium) is ") Num_Type(#80,LEFT+NOCR) Message(" seconds...") // // ///////////////////////////////////////////////////////////////////////////// // // Perform the Conversion. // Convert normal (unpacked) fields using simple EBCDIC to ASCII conversion. // Goto_Line(#93) //Start at 1st record (skip custom header) Unpack_BCD(Cur_Pos,File_Size) //Translate and unpack fields Type_Newline() // // Clean up and terminate. // Buf_Switch(#90) File_Save(BEGIN) //Save file; goto BOF (quickly) Num_Pop(10,99) //Restore numeric regs Reg_Pop(10,12) //Restore T-Regs if (Is_Option(y)) { Xall } //If "-Y" invocation, exit now if (#99==0x57495C44) { //If WILDFILE macro running File_Close(NOMSG) //Close buffer, save file } return // ////////////////////////////////////////////////////////////////////////////// // :BADDAT: Message("\nInvalid data description line:\n") BOL() Goto COMERROR // :TOOMANY: Message("\nMore than 32 fields specified in ") Reg_Type(11) Message("\nError occurred at:\n") :COMERROR: Alert() Type(1) GetKey("\nPress any key to edit .LAY file...") Buf_Switch(#92) Reg_Set(11,PATHNAME) Buf_Quit(OK) File_Open(@11) Break_Out(EXTRA)