home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
pgmutl
/
val_link.arc
/
FILES.C
< prev
next >
Wrap
Text File
|
1989-02-18
|
32KB
|
714 lines
/* FILES.C */
/*+-------------------------------------------------------------------------+
| |
| add_extension_to_file |
| |
+-------------------------------------------------------------------------+*/
string_ptr add_extension_to_file(string_ptr fn, string_ptr ext)
BeginDeclarations
EndDeclarations
BeginCode
If index_string(fn,0,colon_string) IsNot 1
Then /* AUX:, CON:, or PRN: */
return(fn);
EndIf;
If index_string(fn,0,dot_string) Is 0xFFFF
Then
concat_string(fn,ext);
EndIf;
return(fn);
EndCode
/*+-------------------------------------------------------------------------+
| |
| add_files_to_list |
| |
+-------------------------------------------------------------------------+*/
void add_files_to_list(file_info_list *file_list, string_ptr fn)
BeginDeclarations
bit_16 already_in_list;
byte_ptr matched_file;
bit_16 compare_len;
file_info_ptr file_entry;
#define File_entry (*file_entry)
#define File_list (*file_list)
bit_16 rc;
EndDeclarations
BeginCode
matched_file = String(current_filename);
rc = start_file_search(fn, 0);
If rc IsNotZero
Then
linker_error(4,"No matching files for file specification:\n"
"\t\"%Fs\"\n",
String(fn));
EndIf;
While rc IsZero
BeginWhile
compare_len = Length(current_filename) + 1;
already_in_list = 0;
TraverseList(File_list, file_entry)
BeginTraverse
already_in_list = far_compare(matched_file,
BytePtr(File_entry.filename),compare_len)
IsZero;
ExitIf(already_in_list);
EndTraverse;
If Not already_in_list
Then
file_entry = (file_info_ptr)
allocate_memory(Addr(static_pool),
Bit_32(sizeof(file_info_type)) +
Bit_32(compare_len) - 1L);
File_entry.attribute = (*DTA).attribute;
File_entry.time_stamp = (*DTA).time_stamp;
File_entry.date_stamp = (*DTA).date_stamp;
File_entry.file_size = (*DTA).file_size;
File_entry.pass_count =
File_entry.module_count = 0;
far_move(File_entry.filename, matched_file, compare_len);
Insert file_entry AtEnd InList File_list EndInsert;
EndIf;
rc = continue_file_search();
EndWhile;
return;
EndCode
#undef File_entry
#undef File_list
/*+-------------------------------------------------------------------------+
| |
| change_extension |
| |
+-------------------------------------------------------------------------+*/
string_ptr change_extension(string_ptr fn, string_ptr ext)
BeginDeclarations
EndDeclarations
BeginCode
trunc_string(fn, reverse_index_string(fn,0xFFFF,dot_string));
concat_string(fn, ext);
return(fn);
EndCode
/*+-------------------------------------------------------------------------+
| |
| continue_file_search |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
bit_16 continue_file_search()
BeginDeclarations
bit_16 rc;
EndDeclarations
BeginCode
/*+-------------------------------------------------------------------------+
| |
| Set up a new DTA |
| |
+-------------------------------------------------------------------------+*/
old_DTA = get_DTA_address();
set_DTA_address(DTA);
inregs.h.ah = 0x4F; /* Continue file search */
rc = (bit_16) intdos(Addr(inregs), Addr(outregs));
set_DTA_address(old_DTA);
If rc IsNotZero
Then
copy_string(current_filename, null_string);
Else
far_to_lower((*DTA).filename, 12);
copy_string(current_filename, current_path);
concat_string(current_filename, string((*DTA).filename));
EndIf;
return(rc);
EndCode
/*+-------------------------------------------------------------------------+
| |
| default_directory |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
string_ptr default_directory(string_ptr drive, string_ptr directory)
BeginDeclarations
EndDeclarations
BeginCode
inregs.h.ah = 0x47; /* Get current directory*/
inregs.h.dl = *String(drive) - 'a' + 1;
inregs.x.si = Offset(String(directory)) + 1;
segregs.ds = Segment(String(directory));
intdosx(Addr(inregs), Addr(outregs), Addr(segregs));
*String(directory) = '\\';
Length(directory) = far_index(String(directory), 0);
far_to_lower(String(directory), Length(directory));
If LastCharIn(directory) IsNot '\\'
Then
concat_string(directory,backslash_string);
EndIf;
return(directory);
EndCode
/*+-------------------------------------------------------------------------+
| |
| default_drive |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
string_ptr default_drive()
BeginDeclarations
string_ptr drive;
EndDeclarations
BeginCode
drive = make_constant_string(Addr(static_pool), (byte *) " :");
inregs.h.ah = 0x19; /* Report current drive */
intdosx(Addr(inregs), Addr(outregs), Addr(segregs));
/* DOS_int21("Failed to get current drive.\n");*/
*String(drive) = (char) (outregs.h.al + 'a');
return(drive);
EndCode
/*+-------------------------------------------------------------------------+
| |
| file_close_for_read |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void file_close_for_read()
BeginDeclarations
#define File infile
EndDeclarations
BeginCode
If File.file_handle Exceeds 4
Then /* Only issue close if not one of the standard handles. */
inregs.h.ah = 0x3E; /* Close for read */
inregs.x.bx = File.file_handle;
DOS_int21("Trouble closing \"%Fs\".\n",
(*File.file_info).filename);
EndIf;
return;
EndCode
#undef File
/*+-------------------------------------------------------------------------+
| |
| file_close_for_write |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void file_close_for_write()
BeginDeclarations
#define File outfile
EndDeclarations
BeginCode
If File.bytes_in_buffer Exceeds 0
Then
inregs.h.ah = 0x40; /* Write */
inregs.x.bx = File.file_handle;
inregs.x.cx = File.bytes_in_buffer;
inregs.x.dx = Offset(File.buffer);
segregs.ds = Segment(File.buffer);
DOS_int21("Trouble writing file \"%Fs\" at byte %lu.\n",
(*File.file_info).filename, File.next_buffer_position);
EndIf;
If File.file_handle Exceeds 4
Then /* Only issue close if not one of the standard handles. */
inregs.h.ah = 0x3E; /* Close for read */
inregs.x.bx = File.file_handle;
DOS_int21("Trouble closing \"%Fs\".\n",
(*File.file_info).filename);
EndIf;
return;
EndCode
#undef File
/*+-------------------------------------------------------------------------+
| |
| file_exists |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
bit_16 file_exists(string_ptr fn, bit_16 attr)
BeginDeclarations
bit_16 rc;
EndDeclarations
BeginCode
old_DTA = get_DTA_address();
set_DTA_address(DTA);
inregs.h.ah = 0x4E; /* Start file search */
segregs.ds = Segment(String(fn));
inregs.x.dx = Offset(String(fn));
inregs.x.cx = attr;
rc = (bit_16) intdosx(Addr(inregs), Addr(outregs), Addr(segregs));
set_DTA_address(old_DTA);
return(rc IsZero);
EndCode
/*+-------------------------------------------------------------------------+
| |
| file_delete |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void file_delete(file_info_ptr file_info)
BeginDeclarations
#define File_info (*file_info)
EndDeclarations
BeginCode
inregs.h.ah = 0x41; /* Delete file */
inregs.x.dx = Offset(File_info.filename);
segregs.ds = Segment(File_info.filename);
DOS_int21("Trouble deleting file \"%Fs\".\n",
File_info.filename);
return;
EndCode
#undef File_info
/*+-------------------------------------------------------------------------+
| |
| file_IO_limit |
| |
+-------------------------------------------------------------------------+*/
void file_IO_limit(bit_16 limit)
BeginDeclarations
#define File infile
EndDeclarations
BeginCode
If (limit IsZero) OrIf (limit Exceeds File.buffer_size)
Then
File.IO_limit = File.buffer_size;
Else
File.IO_limit = limit;
EndIf;
return;
EndCode
#undef File
/*+-------------------------------------------------------------------------+
| |
| file_open_for_read |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void file_open_for_read(file_info_ptr file_info)
BeginDeclarations
#define File infile
#define File_info (*file_info)
EndDeclarations
BeginCode
/*+-------------------------------------------------------------------------+
| |
| Initialize the data structure |
| |
+-------------------------------------------------------------------------+*/
File.current_byte = File.buffer;
File.IO_limit = File.buffer_size;
File.start_of_buffer_position =
File.next_buffer_position = 0L;
File.bytes_in_buffer =
File.bytes_left_in_buffer =
File.byte_position = 0;
File.file_info = file_info;
/*+-------------------------------------------------------------------------+
| |
| Open the file and save the handle |
| |
+-------------------------------------------------------------------------+*/
If compare_string(string(File_info.filename), device_AUX) IsZero
Then
File.file_handle = 3;
return;
EndIf;
If compare_string(string(File_info.filename), device_CON) IsZero
Then
File.file_handle = 0;
return;
EndIf;
If compare_string(string(File_info.filename), device_PRN) IsZero
Then
File.file_handle = 4;
return;
EndIf;
inregs.h.ah = 0x3D; /* Open for read */
inregs.h.al = 0x00; /* Access code */
inregs.x.dx = Offset(File_info.filename);
segregs.ds = Segment(File_info.filename);
DOS_int21("Trouble opening \"%Fs\" for input.\n",
File_info.filename);
File.file_handle = outregs.x.ax;
return;
EndCode
#undef File
#undef File_info
/*+-------------------------------------------------------------------------+
| |
| file_open_for_write |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void file_open_for_write(file_info_ptr file_info)
BeginDeclarations
#define File outfile
#define File_info (*file_info)
EndDeclarations
BeginCode
/*+-------------------------------------------------------------------------+
| |
| Initialize the data structure |
| |
+-------------------------------------------------------------------------+*/
File.current_byte = File.buffer;
File.bytes_left_in_buffer =
File.IO_limit = File.buffer_size;
File.start_of_buffer_position =
File.next_buffer_position = 0L;
File.bytes_in_buffer =
File.byte_position = 0;
File.file_info = file_info;
/*+-------------------------------------------------------------------------+
| |
| Open the file and save the handle |
| |
+-------------------------------------------------------------------------+*/
If compare_string(string(File_info.filename), device_AUX) IsZero
Then
File.file_handle = 3;
return;
EndIf;
If compare_string(string(File_info.filename), device_CON) IsZero
Then
File.file_handle = 1;
return;
EndIf;
If compare_string(string(File_info.filename), device_PRN) IsZero
Then
File.file_handle = 4;
return;
EndIf;
inregs.h.ah = 0x3C; /* Open for write */
inregs.x.cx = 0x00; /* File attribute */
inregs.x.dx = Offset(File_info.filename);
segregs.ds = Segment(File_info.filename);
DOS_int21("Trouble opening \"%Fs\" for output.\n",
File_info.filename);
File.file_handle = outregs.x.ax;
return;
EndCode
#undef File
#undef File_info
/*+-------------------------------------------------------------------------+
| |
| file_position |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void file_position(bit_32 position)
BeginDeclarations
#define File infile
EndDeclarations
BeginCode
If (position NotLessThan File.start_of_buffer_position) AndIf
(position LessThan File.next_buffer_position)
Then
File.byte_position = Bit_16(position-File.start_of_buffer_position);
File.current_byte = Addr(File.buffer[File.byte_position]);
File.bytes_left_in_buffer = File.bytes_in_buffer - File.byte_position;
Else
inregs.h.ah = 0x42; /* Move file pointer */
inregs.h.al = 0x00; /* Relative to start of file */
inregs.x.bx = File.file_handle;
inregs.x.cx = High(position);
inregs.x.dx = Low(position);
DOS_int21("Trouble positioning file \"%Fs\" to byte %lu.\n",
(*File.file_info).filename, position);
File.start_of_buffer_position =
File.next_buffer_position = position;
File.byte_position =
File.bytes_in_buffer =
File.bytes_left_in_buffer = 0;
File.current_byte = File.buffer;
EndIf;
return;
EndCode
#undef File
/*+-------------------------------------------------------------------------+
| |
| file_read |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void file_read(byte_ptr into, bit_16 length)
BeginDeclarations
#define File infile
EndDeclarations
BeginCode
While length Exceeds 0
BeginWhile
If length Exceeds File.bytes_left_in_buffer
Then
If File.bytes_left_in_buffer Exceeds 0
Then
far_move(into, File.current_byte, File.bytes_left_in_buffer);
length -= File.bytes_left_in_buffer;
into += File.bytes_left_in_buffer;
EndIf;
inregs.h.ah = 0x3F; /* Read */
inregs.x.bx = File.file_handle;
inregs.x.cx = File.IO_limit;
inregs.x.dx = Offset(File.buffer);
segregs.ds = Segment(File.buffer);
DOS_int21("Trouble reading file \"%Fs\" at byte %lu.\n",
(*File.file_info).filename, File.next_buffer_position);
File.bytes_in_buffer =
File.bytes_left_in_buffer = outregs.x.ax;
File.current_byte = File.buffer;
File.byte_position = 0;
File.start_of_buffer_position = File.next_buffer_position;
File.next_buffer_position = File.start_of_buffer_position +
File.bytes_in_buffer;
Else
far_move(into, File.current_byte, length);
into += length;
File.current_byte += length;
File.bytes_left_in_buffer -= length;
File.byte_position += length;
length = 0;
EndIf;
EndWhile;
return;
EndCode
#undef File
/*+-------------------------------------------------------------------------+
| |
| file_write |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void file_write(byte_ptr from, bit_32 length)
BeginDeclarations
#define File outfile
EndDeclarations
BeginCode
While length Exceeds 0L
BeginWhile
If length Exceeds Bit_32(File.bytes_left_in_buffer)
Then
far_move(File.current_byte, from, File.bytes_left_in_buffer);
length -= Bit_32(File.bytes_left_in_buffer);
from += File.bytes_left_in_buffer;
File.bytes_in_buffer += File.bytes_left_in_buffer;
inregs.h.ah = 0x40; /* Write */
inregs.x.bx = File.file_handle;
inregs.x.cx = File.bytes_in_buffer;
inregs.x.dx = Offset(File.buffer);
segregs.ds = Segment(File.buffer);
DOS_int21("Trouble writing file \"%Fs\" at byte %lu.\n",
(*File.file_info).filename, File.next_buffer_position);
File.current_byte = File.buffer;
File.bytes_left_in_buffer = File.buffer_size;
File.bytes_in_buffer =
File.byte_position = 0;
File.start_of_buffer_position = File.next_buffer_position;
File.next_buffer_position = File.start_of_buffer_position +
File.bytes_left_in_buffer;
Else
far_move(File.current_byte, from, Bit_16(length));
from += Bit_16(length);
File.current_byte += Bit_16(length);
File.bytes_left_in_buffer -= Bit_16(length);
File.byte_position += Bit_16(length);
File.bytes_in_buffer += Bit_16(length);
length = 0;
EndIf;
EndWhile;
return;
EndCode
#undef File
/*+-------------------------------------------------------------------------+
| |
| get_DTA_address |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
DTA_ptr get_DTA_address()
BeginDeclarations
DTA_ptr DTA_address;
EndDeclarations
BeginCode
inregs.h.ah = 0x2F; /* Get DTA address */
intdosx(Addr(inregs), Addr(outregs), Addr(segregs));
DTA_address = (DTA_ptr) MakeFarPtr(segregs.es, outregs.x.bx);
return(DTA_address);
EndCode
/*+-------------------------------------------------------------------------+
| |
| process_filename |
| |
+-------------------------------------------------------------------------+*/
string_ptr process_filename(string_ptr fn)
BeginDeclarations
bit_16 left;
bit_16 right;
EndDeclarations
BeginCode
lowercase_string(fn);
/*+-------------------------------------------------------------------------+
| |
| Check for AUX:, CON: & PRN: |
| |
+-------------------------------------------------------------------------+*/
If compare_string(substr(fn,0,4), device_AUX) IsZero
Then
copy_string(fn, device_AUX);
return(fn);
EndIf;
If compare_string(substr(fn,0,4), device_CON) IsZero
Then
copy_string(fn, device_CON);
return(fn);
EndIf;
If compare_string(substr(fn,0,4), device_PRN) IsZero
Then
copy_string(fn, device_PRN);
return(fn);
EndIf;
/*+-------------------------------------------------------------------------+
| |
| Add drive designator if missing. |
| |
+-------------------------------------------------------------------------+*/
If compare_string(substr(fn,1,1), colon_string) IsNotZero
Then
paste_string(fn, 0, default_drive_string);
EndIf;
/*+-------------------------------------------------------------------------+
| |
| Substitute current directory if not based from root. |
| |
+-------------------------------------------------------------------------+*/
If compare_string(substr(fn,2,1), backslash_string) IsNotZero
Then
default_directory(fn, default_directory_string);
paste_string(fn, 2, default_directory_string);
EndIf;
/*+-------------------------------------------------------------------------+
| |
| Scan out all \. and \.. from filename. |
| |
+-------------------------------------------------------------------------+*/
left = index_string(fn, -1, backslash_string);
right = index_string(fn, left+1, backslash_string);
While right IsNot 0xffff
BeginWhile
If compare_string(substr(fn,left,4), backslash_dot_dot_string) IsZero
Then
cut_string(fn, left, 3);
right = left;
left = reverse_index_string(fn, right-1, backslash_string);
If left Is 0xffff
Then
return(null_string);
EndIf;
cut_string(fn, left, right-left);
right = index_string(fn, left+1, backslash_string);
ContinueLoop;
Else
If compare_string(substr(fn,left,3), backslash_dot_string) IsZero
Then
cut_string(fn, left, 2);
right = index_string(fn, left+1, backslash_string);
ContinueLoop;
EndIf;
EndIf;
left = right;
right = index_string(fn, left+1, backslash_string);
EndWhile;
return(fn);
EndCode
/*+-------------------------------------------------------------------------+
| |
| set_DTA_address |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
void set_DTA_address(DTA_ptr DTA_address)
BeginDeclarations
EndDeclarations
BeginCode
inregs.h.ah = 0x1A; /* Set DTA address */
segregs.ds = Segment(DTA_address);
inregs.x.dx = Offset(DTA_address);
intdosx(Addr(inregs), Addr(outregs), Addr(segregs));
return;
EndCode
/*+-------------------------------------------------------------------------+
| |
| start_file_search |
| |
| O/S dependent |
| |
+-------------------------------------------------------------------------+*/
bit_16 start_file_search(string_ptr fn, bit_16 attr)
BeginDeclarations
bit_16 rc;
EndDeclarations
BeginCode
/*+-------------------------------------------------------------------------+
| |
| Set up a new DTA |
| |
+-------------------------------------------------------------------------+*/
old_DTA = get_DTA_address();
set_DTA_address(DTA);
/*+-------------------------------------------------------------------------+
| |
| Remember the current file path |
| |
+-------------------------------------------------------------------------+*/
copy_string(current_path, fn);
trunc_string(current_path,
reverse_index_string(current_path, 0xFFFF, backslash_string)+1);
inregs.h.ah = 0x4E; /* Start file search */
segregs.ds = Segment(String(fn));
inregs.x.dx = Offset(String(fn));
inregs.x.cx = attr;
rc = (bit_16) intdosx(Addr(inregs), Addr(outregs), Addr(segregs));
set_DTA_address(old_DTA);
If rc IsNotZero
Then
copy_string(current_filename, null_string);
Else
far_to_lower((*DTA).filename, 12);
copy_string(current_filename, current_path);
concat_string(current_filename, string((*DTA).filename));
EndIf;
return(rc);
EndCode