C News Volume 1, Number 4

     Volume 1, Number  4                             21 February  1988
     +---------------------------------------------------------------+
     |                                                               |
     |                       -  C   News  -                          |
     |                                                               |
     |                        International                          |
     |                C Programming & Compiler Review                |
     |                         Newsletter                            |
     |                                                               |
     +---------------------------------------------------------------+
     US Office:
     Editor at large                                       Barry Lynch
     Assistant Editor                                      Ami Dworkin
     Technical Editor                                Marshall Presnell

     Australian Office:   
     Editor                                               David Nugent

     C News  is  published  bi-weekly by  the  C BBS as its official
     newsletter.  You are encouraged to submit articles for publication
     in C News.  Articles should be related to C programming and can be
     Tutorials, reviews or articles of interest to the C programming
     community.  All Operating systems are fairly represented and this
     newsletter shows no favoritism to any one in particular.  Instruct-
     ions on how to submit articles for publication is included on the
     last page.
         
     C News is the property of the C BBS and is Copyright 1988 by the
     the C BBS.  All rights are reserved and distribution is limited to
     electronic distribution and personal printed copies.  C News cannot
     be resold at any profit, by any organization.  All material enclosed
     within the newsletter is the opinions of the writers and not the
     C BBS or it's Sysop.

     DISTRIBUTION POINTS:


     EASTERN US - C BBS 109/713   (703)998-8377
   
     CANADA     - Another BBS
     AUSTRALIA  - Alpha Centuri BBS
     EUROPE     - 150/1 - Sysop: Henk Wevers

     New distribution points are always welcome, if you are interested
     send me a netmail message at the above address.

   
     C News 1-04                                          21 Feb 1988

     =================================================================
                             TABLE OF CONTENTS
     =================================================================
   

     1. EDITORIAL
             The Heap: messages from the editor....................  1
             New Column, User requests

     2. PATCHES/MITE REPORTS
        MSC Version 5.0 Bug Listings  .............................  2

     3. SHORT SNIPS 
        Magazine Review's
            by Barry Lynch   ......................................  6

     4. BOOK REVIEWS
        MS-DOS Developer's Guide   ................................  7
            by Barry Lynch
       
     5. SOFTWARE REVIEWS
        Public Domain:   ..........................................  8
        SETPRGMS.ARC, SHIFT_C.ARC, SYSACT11.ARC, XENIXARC.ARC,
        CDATE.ARC, C_DATES.ARC, C-SUBR.ARC, JCL-SRC.ARC, and
        NDMAKE41.ARC
           by David Nugent

     6. FEATURE ARTICLE
        Filename Wildcard Expansion in Microsoft C  ............... 15

     7. /Usr/Bin
           by Marshall Presnell   ................................. 26

     8. NOTES
        Article Submission Standards  ............................. 28
        Address's   ............................................... 29
        USER Response Form  ....................................... 30
   
     9. INDEX   ................................................... 31



     C News 1-04                 Page 1                   21 Feb 1988

     =================================================================
                                 EDITORIAL
     =================================================================

     The HEAP: Messages from the Editor.


          With this issue of C News we start a new column, and begin
     <hopefully> a new tradition.  First, Marshall Presnell joins us
     with his column the "/usr/bin".  Dedicated to technical questions
     and answers relating to C programming.  Marshall has a BS in
     Electrical Engineering and is quite a accomplished programmer in
     C and ASM.  Marshall's column will be a regular feature, and I
     know that he will provide a valuable service to all of us in the
     future.

          The next feature of C News that I am proud of, and hope becomes
     a regular feature.  Is an article by Bill Mayne on Expanding
     arguments from the command line and some other goodies.  Mr. Mayne
     has done an excellent job and should be congratulated by all.  It
     is hoped that articles like his will be forthcoming in future issues
     of C News as well.

          Last Issue, I included a user response form for users to fill
     and send back if they had the chance.  Well, quite a few users did
     and I thank you for the support.  Most of the suggestions dealt
     with more beginner oriented tutorials and a technical question
     and answer column.  Both of these requests have been satisfied
     in this issue, and we will attempt to keep up the quality of work
     that we have been able to produce for this issue in future issues.

   
      B C'ng U

      Barry Lynch


                       
         C News 1-04                 Page 2                   21 Feb 1988

     =================================================================
                          PATCHES/MITE REPORTS
     =================================================================

     MSC Version 5.0

  Be VERY careful when using the MSC5 compiler. The optimizer is
generating a LOT of bad code in places. In some cases you can disable
enough of the optimizer to force it to generate good code, but in
other cases one must simply rewrite code to trick the compiler into
doing the write thing. The problems appear to be with large memory
models. All C code was compiler with "Alfu" memory model.

    In the next two messages I will show two code samples that
generated bad code. The samples are simplified extracts that
demonstrate a compiler bug..

   This demonstrates a bug in the loop optimizer. The cast to a CHAR *
is what confused the optimizer... The code is large memory model
compiled with "Alfu". The bug is correctable by disabling the loop
optimizer.

#include<stdio.h>


#define GETSEGPTR(xseg,xoff) ((char *) (((long) xseg <<16) | xoff))
#define WHATEVER 20

void
fortran
badcode(buffer,unpointer)
char *buffer;
unsigned *unpointer;
{
        char *ptr;
        unsigned segval, get_a_segval();
        int i;

        segval=get_a_segval();

        for(i=0; i< WHATEVER ; i++)
        {
           do_something( GETSEGPTR(segval,0));
           segval+=16;
        }
}


    It does not matter what the called routines do, The compiler does
not generate the code to add 16 (seg size) to the variable SEGVAL..
Below is the asm that the compiler generates....

C News 1-04                 Page 3                   21 Feb 1988

=================================================================
                      PATCHES/MITE REPORTS
=================================================================

MSC Version 5.0

*** 000024      be 14 00        mov     si,20
*** 000027      81 46 fe 40 01  add     WORD PTR [bp-2],320   
;segval
                                        $L20000:
        ;|***         {
        ; Line 20
        ;|***            do_something(GETSEGPTR(segval,0));
        ; Line 21
*** 00002c      ff 76 f6        push    WORD PTR [bp-10]
*** 00002f      ff 76 f4        push    WORD PTR [bp-12]
*** 000032      9a 00  call    FAR PTR _do_something
*** 000037      83 c4 04        add     sp,4
        ;|***            segval+=16;
        ;|***         }
        ; Line 23
*** 00003a      4e              dec     si
*** 00003b      75 ef           jne     $L20000
        ;|*** }



   In this above loop, segval is never changes at all... Nice huh?

  The code sample below is even more terrifying since the compiler is
not generating badly optimized code so much as it is just generating
BAD code. Below is a sample of a C routine that the compiler will kill
you on. This code was compiled with "Alfu". The only way to correct
the compiler was to disable intrinsics, any other optimizer flag made
no difference.


#include<stdio.h>


void
fortran
badcode(buffer,unpointer)
char *buffer;
unsigned *unpointer;
{
        char *ptr, *getaptr();


        ptr=getaptr();


C News 1-04                 Page 4                   21 Feb 1988

=================================================================
                      PATCHES/MITE REPORTS
=================================================================

MSC Version 5.0


        *unpointer = strlen(ptr);
}


   The assignment of strlen() to *numpointer will generate bad code.
It does not really matter if numptr is an unsigned int or an int by
the way. Below is the asm that the compiler will generate...

        ;|***
        ;|***         *unpointer = strlen(ptr);
        ; Line 13
*** 000018      c4 5e 06    les bx,DWORD PTR [bp+6]     ;unpointer
*** 00001b      c4 7e fc    les di,DWORD PTR [bp-4]     ;ptr
*** 00001e      b9 ff    mov cx,-1
*** 000021      33 c0       xor ax,ax
*** 000023      f2          repnz
*** 000024      ae          scasb
*** 000025      f7 d1       not cx
*** 000027      49          dec cx
*** 000028      26 89 0f    mov WORD PTR es:[bx],cx
        ;|*** }


   In the asm above, you will note that it generates an LES twice in a
row. The value loaded into ES by the first LES is clobbered by the
second LES. The last instruction to load CX into ES:[BX] is invalid
since ES does not NECESSARILY point to the correct data segment. If
the segment value of the pointer happens to be equal to SS, the code
will work, but the compiler should not assume this, especially since
the code was generated with "Alfu" - which means among other things,
ES!=DS.... 

    No combination of optimizer switches could get the compiler to
generate the right code for this. The routine had to be modified
to load the strlen() value into an intermediate location, and from
there into the final target.

     Under OS/2 bugs like this make themselves know fairly quickly,
A bad segment value is trapped instantly by the kernel. Such Bugs are
are much more difficult to locate under MS-DOS. The above bugs in the
MSC 5.0 compiler can be reproduced in the OS/2 SDK compiler
as well.............

    The 5.0 compiler is nice, and some of the new features are very
handy. When the optimizer works, it generates wonderful code, but
C News 1-05                 Page 5                   21 Feb 1988

=================================================================
                     PATCHES/MITE REPORTS
=================================================================

MSC Version 5.0

when its bad - its VERY bad. It appears as though MSC5.0 was rushed
to market before it was completely debugged.

Daniel Doman

*** Editors Note:  An arc file is included with this newsletter.

     C News 1-04                 Page 6                   21 Feb 1988
   
     ================================================================
     SHORT SNIPS -      MAGAZINE REVIEWS  by Barry Lynch
     ================================================================
 
     Magazine: The C Users Journal
     Publisher: R&D Publications
     Published: 8 times a year.
     Subject Matter: C

     Issue: Vol 6 No 2 - February 88.

     The C Users Journal is the result of a merger between the C Users
     Group Newsletter and The C Journal.  This is the first time that
     I have had a chance to review - C Users Journal, and here are my
     impressions.

     The subject covered by the articles included:  Revision Control
     Systems, An article on Compiler rounding of floating numbers,
     Standard (ANSI) C,  as well as an article on Null Pointer Errors
     in MSC.  (I for one, needed this article to answer a few pointing
     questions.) 

     Overall, the magazine covered quite alot of territory for one issue.
     At US $3.95 I found it to be a bargain, this compared to the amount
     of C issues covered in Computer Language as reviewed in Issue 3 of
     C News.  I hope that the magazine's staff will continue to produce
     the same amount of coverage that they did in this issue.  I have a
     real problem with magazines that get carried away with the gloss, and
     advertising, and forget the reason for being to begin with.

     The C Users Journal is recommended as a supplement to every C
     programmer's monthly reading regime, as long as it produces quality
     issues such as this one.


         
     C News 1-04                 Page 7                   21 Feb 1988
   
     ================================================================
                             BOOK REVIEWS                   
     ================================================================

     ________________________________________________________________

     MS DOS Developer's Guide
     Author : John Angermeyer & Kevin Jaeger
     Publisher : Howard W. Sams & Company. Indianapolis. 1987.
     Cost : $24.95 (US$) 


     This book is aimed at serious software developer's on the IBM PC
and related clones.  Topics covered include: 1) Program and Memory
Management in MS-DOS, 2) Real-Time Programming Under MS-DOS, 3)
Installable Device Drivers, 4) LANS and MS-DOS  and much more. 

     As with all books that I have purchased from this publisher, I was
not disappointed.  The authors have taken the time to write a clear and
concise book on very technical subject matter.  Prior exposure to the
architecture of the IBM PC is recommended, as the authors assume a
basic working knowledge of how a PC operates.  In regards to memory
management, and CPU management.  Most of the code listed in the book is
in Assembler, so a little prior knowledge there would be of benefit.

     Overall, I enjoyed the book, and consider one of my better buys in
the PC software/reference book arena.

Barry Lynch - Alexandria, VA
     C News 1-04                 Page 8                   21 Feb 1988
   
     ================================================================
     PUBLIC DOMAIN SOFTWARE REVIEWS:
     ================================================================

     *** Editor's Note:  This section is brought to us by the users
         of the Alpha Centuri BBS in Melbourne, Australia.
       
         << Thanks, David >>
     ________________________________________________________________

Filename:  SETPRGMS.ARC

Finding  this  file was quite a surprise; and  its  contents  are
both instructive and useful - even to the veteran programmer.

These  programs  are  specific to MS-DOS.   SET  PRGMS  refer  to
programs which manipulate the environment from within a  program. 
No - not the program's environment, but THE environment: the  one
maintained by COMMAND.COM.

The  theory on how to do this has been known for some time.   But
this  is  the first set of programs I have found  which  actually
make use of the technique.

When  a  program  is loaded, any references  to  the  environment
usually  refer  to  the environment of  THAT  program,  which  is
initially only a copy of it's parent's (usually).  These programs
implement   the  technique  of  chaining  back  to   the   master
environment and altering that, so that when you drop back to  DOS
the environment remains changed.

The  usefulness  of this ability is best shown by   the  examples
presented in the ARC.  These include: the ability to assign to an
environment variable the path name of the current directory, read
a  line  from the console into a variable, and sets  for  current
date  and time variables.  Great stuff for fancy batches, and  an
excellent teacher of the technique.

The file also comes with a system logging utility implemented  in
quite a practical fashion via batch files.

Source included:  Complete ASM source, including .COM executables
and program documentation.  Very well commented and quite  robust
code.

Assembler:   Very little use is made of assembler macros,  and  no
special  include  files  are  assumed.  From  what  I  can  tell,
anything  from way back v1.0 of IBM's ASM.EXE would do.   I  dare
say  that  Eric  Issacson's  blindingly  fast  PD  A86   assembler
(available on this board) would make short work of it.
C News 1-04                 Page 9                   21 Feb 1988
   
================================================================
PUBLIC DOMAIN SOFTWARE REVIEWS:
================================================================

________________________________________________________________

Filename:  SHIFT_C.ARC

Shift  is a handy routine to add to your super-quick  screen  I/O
library.  It is an ASM routine which may be used to shift a  line
of text on the video screen one column left or right.

Source included: Yes

Assembler:  Originally compiled under MASM 5.0, but I can't  find
too much in it that earlier versions would dislike.  Assembles ok
under MASM 4.0 (for example).

Compiler:  This is a C subroutine.  Calling conventions  are  for
MSC or Turbo C (preceding underline), but you can call  _shift()
from other compilers.

Notes:  This routine is VERY hardware specific, and only  applies
to a machine which is 100% IBM compatible.  On the other hand, it
would  be easily adapted to other environments, if you  knew  the
various machine specific addresses.
_________________________________________________________________

Filename: SYSACT11.ARC

This little nugget contains a utility to log "execute" DOS  calls
to a log file, with start and execution timings and the number of
read/write and other DOS calls made by the program.

If you are familiar with Xenix or Unix, this should ring a  bell. 
Something  like acctcom available there.  This program takes  the
form  of a mighty small .ASM TSR used for intercepting DOS  calls
loaded  on boot up, together with two programs and a  batch  file
used to produce reports and summaries.

Its  these last two programs that make the .ARC  so  interesting. 
The  reports  can summarize activity in a number  of  interesting
ways, and can merge the file to produce excellent summaries.

After  all,  who out there who uses a hard  drive  (floppies  not
supported)  can  tell you which program is used the  most  often,
makes  the most disk & device I/O calls or takes the  longest  to
execute.   A  very interesting statistic which  can  change  your
habits remarkably for the better.

This  is not a simple activity logger.  Its a work analysis  tool
useful  to  professionals and serious hobbyists.  It  comes  with
C News 1-04                 Page 10                  21 Feb 1988
   
================================================================
PUBLIC DOMAIN SOFTWARE REVIEWS:
================================================================

full  source (.ASM and .PAS), so it can teach a good  deal  about
intercepting the DOS interrupt.

Source included: Yes

Language: Turbo Pascal, Assembler.

Compiler/Assembler:   Not  specifically  stated,   but   probably
requires TP 3.0 or above.  Version of MASM or other assembler  is
not critical.
_________________________________________________________________

Filename: XENIXARC.ARC

This is SEA's original ARC utility ported to SCO Xenix.  Its  the
first  time  I've seen a successful port, and I've tried  a  few! 
Other   Unix   ports  have  memory/model  problems   and   slight
incompatibilities when compiled under Xenix.

The  beauty  of this program is that it is  100%  PC  compatible.
It can read PC ARCs and the ARCs it creates can be ported to DOS.
It   does  not,  of  coarse,  do  the   newline/carriage   return
translation!   One minor differences is that file names ARE  case
sensitive, like Xenix.  Causes no problems when swapping with DOS
though.

Wildcards  "*"  and "?" are fully supported in the  same  way  as
under  DOS.   However,  because  most  Xenix/Unix  shells  expand
wildcards before a program sees them, you must quote them  (using
quotes) to prevent this when EXTRACTING files.  When updating  or
adding  files though, you can have your choice as to who  expands
the wildcards.

Source Included:  Yes - no executables.

Language:  C, SCO/IBM Implementation (MicroSoft Xenix compiler)

Version:  Minimum compiler version is the 2.1 (IBM 2.0)
C News 1-04                 Page 11                  21 Feb 1988
   
================================================================
PUBLIC DOMAIN SOFTWARE REVIEWS:
================================================================

Filename: CDATE.ARC

This  is  a  handy utility for batch files which  is  capable  of
testing the current system time and date, returning a "truth"  to
the  caller via DOS errorlevel.  The flexibility of this  program
and the parsing technique used for examining the command line are
instructive.

As a utility, CDATE can be quite invaluable; especially those  of
use  running bulletin boards.  The current day of the month,  day
of the week, month of the year or any combination of these can be
tested  and  acted upon.  The program is quite  "intelligent"  in
examining  the  command line and understands a  range  of  common
abbreviations.

Source: Yes.
Language: C
Compiler: Turbo C, but a trivial port to other MS-DOS compilers.
__________________________________________________________________

Filename: C_DATES.ARC

At  last  a  group of routines which  handles  dates!   This  ARC
contains  a number of routines used for converting dates  to  and
from  "long",  allowing dates to be manipulated and  operated  on
mathematically.

These  routines view a date as one day in a continuing series  of
days,  converting  day, month a year to long integer  and  back. 
This is invaluable for business applications.

Both 'long' (4 digit year) and 'short' date format are implicitly
supported.

Source: Yes.
Language: C
Compiler: Quite portable, K & R standard.
Notes:  Two  demonstration  programs  also  provided,   including
source.
C News 1-04                 Page 12                  21 Feb 1988
   
================================================================
PUBLIC DOMAIN SOFTWARE REVIEWS:
================================================================

Filename: C-SUBR.ARC

This file contains a variety of handy routines for a beginner  or
intermediate  C programmer.  It includes all the common  practice
algorithms  and  is well coded to provide both a  high  degree  of
readability (and understandability) and efficiency.  These are  a
good learning tool.

For  the more experienced programmers, it may also save  time  in
providing a library of reliable, short routines which are  easily
incorporated into a project, even at the object (link) level.

Many   common  requirements  of  C  programmers  are  met,   from
displaying  error messages, parsing a line for  information,  de-  and

en-tabbing text, right/left text justification to block  CRC  checking
and copying files.

Source:  Yes

Language: C

Compiler: Written for Turbo C, but easily ported.  Some  routines
include  inline assembler not supported by some  compilers.   (If  you
are using MSC, see the entry in this area for CASM.ARC).
_____________________________________________________________________

Filename: JCL-SRC.ARC

This  program  represents the source code for an  extended  batch
command language provided for operation with MS-DOS called "JCL",
written (and uploaded) by Ian Rutherford.

JCL  in  its  executable form has been available  in  the  public
domain  for  some  time.  It allows special  "JCL"  files  to  be
executed providing a great deal more flexibility and control  for
batch  files,  including support for variables  and  full  screen
control.

The program is very instructive in a number of areas,  especially  to
intermediate C programmers: those familiar with  the  language
looking
to do something useful with it.
Source: Yes - no executables.
Language: C

Compiler: Turbo C, but can be ported to most MS-DOS compilers. Notes:
Executables may be found in the DOS utilities file  area,  called
C News 1-04                 Page 13                  21 Feb 1988
   
================================================================
PUBLIC DOMAIN SOFTWARE REVIEWS:
================================================================

JCL.ARC.   Another version may be found  in  the  286/386  area,
compiled  to  use the extended instruction  set  of  those
microprocessors.
________________________________________________________________

Filename: NDMAKE41.ARC

For  any  programming  project, the  classic,  Unix-style  'make'
utility is an absolute *must*.  This little program I have been
looking for some time.   Ever since I first hacked into the source
code for Binkley Term to see  all of Opus' file transfer secrets.  Bob
Hartman, the author  of  Binkley (and many other Fido/Opus utilities,
AND part of the Opus  development  team,  and  one  of the  developers
of  the  FOSSIL  communications drivers, and ... [need I say more?])
recommended  it  in  his program documentation, due to  some  of  its
unique  abilities.

I was eager to unARC it once I had it on the system.  I have used  a
number  of  MAKE utilities; one received  with  MicroSoft's  C
compiler  (average to useless), POLYTRON's PMAKE (very  powerful,
allows   multiple  directories  for  development  but  has   some
incompatible but very powerful extensions) and a number of public
domain  implementations.  I certainly wasn't  disappointed.   It  had
more facilities than I had bargained for, and all using  make  syntax
compatible with Unix make.

Before  discussing  the features of this make, I  should  mention
what  a  MAKE program does.  MAKEs are used for medium  to  large
scale  program development; particularly in  modular  programming
languages  such  as  C, Pascal, Fortran  and  Assembler.   It  is
historically  attached  to  C (under Unix), but  can  be  easily
adapted to basically any modular programming language.  It  takes
the place  of multiple batch files and compiles,  assembles  and
links modules  only  if  they  are  'out  of  date'.    Complete
applications  can  be assembled simply by  entering  the  command
'make'. If this has you interested, then download it and read the
docs.

NDMAKE  version 4.1 is the most powerful I have ever  seen.   Its
major  feature is the ability to create a LINK and  LIB  response
file whenever the command line would exceed DOS's 128 byte limit. If
that's  not  enough,  it also has  the  ability  to  maintain
multiple versions of the same application from one set of  source
files  (via environment variables), use environment variables  as
macros  (an absolute MUST for ANY make, in my books), and have  a
single  file  called MAKE.INI for definition of  MAKE's  built-in
rules  which may exist in your current directory or  anywhere  in
C News 1-04                 Page 14                  21 Feb 1988
   
================================================================
PUBLIC DOMAIN SOFTWARE REVIEWS:
================================================================

your executable search path.

If  you're  after a MAKE utility that has all the edge,  look  no
further.  It comes in executable form only, but is well worth the
effort of downloading.

Source code: No

Notes: Generic application to all compiler/assembler based modular
programming  languages.   Especially useful for medium  to  large
project development.  Comes with  excellent documentation  (50K), and
has excellent  background information  for  first time  make users. C News 1-04                 Page 15                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

Audience: Beginning to intermediate programmers using Microsoft C.
          Some methods are also applicable to other versions of C.

Topics:   (1) Use of SETARGV.OBJ to expand command line arguments.
          (2) Use of DOS calls (with "intdos()" and "intdosx()") to
              expand wildcards from within programs. Covers use of
              disk transfer area (DTA) and DOS functions 4E and 4F.
          (3) Source code for demonstration programs and C functions 
            to perform the DOS calls.
          (4) Use of recursion to traverse directories.

               Filename Wildcard Expansion in Microsoft C

The power of many DOS commands is enhanced by the wildcard expansion
feature, enabling you to specify a group of files by including the
wildcard characters '*' (match anything) and '?' (match any character)
in the filename or extent part of a path.  For example, "DIR
C:\INCLUDE\*.H" shows you a list of all C header files in the
directory "C:\INCLUDE'.  "ERASE *.BAK" erases all files in the current
directory which have the extension "BAK".  "COPY SUB\PROG1.*" copies
all files with a filename of "PROG1" (and any extent, or none) from
the subdirectory "SUB" to the current directory.  Including this very
useful feature into your own C programs is easier than you might
think.

This article will first show how to expand wildcards in the command
line by means of an object (.OBJ) file provided by Microsoft C. Then
it will demonstrate a more powerful technique of doing your own
wildcard expansion inside a program, using a few simple DOS calls by
means of the "intdos()" and intdosx()" functions.  The latter
technique is portable to any implementation of C under MS/DOS or
PC/DOS providing functions for issuing DOS calls.  Each technique will
be demonstrated by simple programs which are also useful utilities.

          Using SETARGV.OBJ to Expand Command Line Wildcards

Normally, the startup library routines linked with a C program parse
the command line arguments into words and pass the result to the
"main()" function as the arguments "argc" and "argv[]", where "argc"
is the number of words and "argv[]" is an array of argc char pointers
to '\0' terminated strings containing one argument each.  A useful
alternative is to substitute startup code which will not only parse
the arguments into words, but expand those which represent wildcards
for filenames into a list of matching files.  To do this under release
4.0 include the file xSETARGV.OBJ in the link step, where 'x' is the
memory model in use, "SSETARGV" for small, "LSETARGV" for large, etc.
For the program "ARGS.C", shown in figure 1, compiled with the default
small memory model, the command to link is:
C News 1-04                 Page 16                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

    LINK ARGS+SSETARGV

(Using release 5.0, you no longer need to specify the memory model,
but you must specify the "/NOE" link option to avoid an error message
since "setargv" is a duplicate name.  The command to compile and link
would be "CL ARGS.C \BIN\SETARGV.OBJ /link /NOE.)

The resulting ARGS.EXE simply writes its arguments to the standard
output file, one per line, surrounded by double quotation marks.  This
enables you to see exactly what is being done with the arguments you
enter by SETARGV.  To get rid of the double quotes around each
argument, compile with the option "/DNOQUOTES".

A little experimentation with ARGS will show the following:
(1) Arguments which do not contain wildcard characters are passed as
is to "main()", in the normal way.

(2) Wildcard arguments are expanded into the list of files which match
the pattern, each matching file being appearing as a separate
argument. If no files match a pattern the pattern is passed as is to
"main()".

(3) If a drive and directory is specified along with filename.ext, and
filename.ext contains a wildcard, each of the resulting actual
filenames will include the drive and directory.  As with DOS,
wildcards are allowed only in the filename and extent, not in the
directory part.

(4) If null extents are allowed, and any subdirectory names match the
filename part, the names of these subdirectories are also passed to
"main()".  The program must use other means to distinguish between
directories and files.  The simplest, when you expect a file, is to
try to open it and check the return code.

(5) Any string in the command line surrounded by double quotation
marks is passed to "main()" as is.  You can use this to disable
wildcard expansion for a given argument, or to pass strings containing
blanks without splitting them into separate words.  If you mean to
pass "*" as an argument, and you don't want it to be replaced by the
names of all the files in the current directory which have no extents,
include the quote marks in the command line.

(6) "main()" cannot distinguish between a list of files actually given
on the command line and a list resulting from matching a wildcard, nor
can it see the original wildcard argument.  If it is necessary to do
that, you must look at the unparsed command line arguments stored in
the program segment prefix.  Since that area is also used as a disk
transfer area, your program should make a copy of the string before
C News 1-04                 Page 17                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

doing anything else.

(7) Wildcards are not only expanded, the list resulting from each
wildcard is sorted.  Filenames matching a wildcard are passed to
"main()" in alphabetical order.

Obviously just linking with SETARGV.OBJ does a lot for you, most of it
useful.  In fact, the simple ARGS program, written just to test this
option, is a nice file listing utility in own right, displaying a
sorted list of files in one or more directories.  For this use, you
probably don't want the double quote marks around each filename, so
try compiling with the "/DNOQUOTES" option.  The final .EXE file might
be named something like "SFILES.EXE" to give a better indication of
its function.

            Expanding Wildcards With DOS Calls In Programs

As useful as wildcard expansion in command line arguments can be,
there are times when it is necessary to perform the same function
inside a program.  This can be easily accomplished using a few DOS
calls, which is much easier than you might think.  The source code for
a simple file find utility using this technique is shown in figure 2.
All the required DOS function calls are performed in the functions
"findentr()" and "findnext()" (figure 3) and its subroutines
"get_DTA()" and "set_DTA()" (figure 4).

DOS functions are called by executing interrupt 0x21, with the AH
register containing the number of the function to be performed and
other registers used to pass other arguments.  The registers contain
either the arguments for a specific function or the addresses of
blocks of memory to be used by the function.  Filenames are
conveniently passed as ASCII strings terminated by '\0', which is
exactly the way strings are stored in C. You need to know about the
registers and understand the segment:offset addressing scheme used by
the PC, but assembly language is generally not required.

In Microsoft C, the functions "intdos()" and "intdosx()" are used.
The header file "DOS.H" defines the union REGS and structure SREGS
used to hold register values passed to and from the software interrupt
handler. The SREGS structure is used with "intdosx()" to pass values
for the segment registers.  The REGS union is used for the other
registers. When segment registers are not needed "intdos()" is used.
Main memory addresses must be given by segment and offset.  Microsoft
C programs can use the macros FP_SEG and FP_OFF to extract the segment
and offset components of far pointers.  Other implementations of C
usually provide similar functions, so it should be easy to port the
routines shown here to other versions of C.

C News 1-04                 Page 18                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

Microsoft C also provides a few other functions for executing low
level functions.  They are not used by the routines shown here, but
may used in other cases.  For DOS functions which take no arguments,
or only arguments in the DX and AL registers, the simpler "bdos()"
function will do.  It has the advantage of taking only integer
arguments and returning the result as an integer return value.  Many
of the low level keyboard and console functions can use this.  On the
other end of the scale, "int86()" and "int86x()" work like "intdos()"
and "intdosx()", except that they accept an interrupt number so any
interrupt can be executed, not just 0x21.

The DOS functions used to expand wildcards in file names are 0x4E
(Find Match File) and 0x4F (Find Next File).  The process is started
by calling 0x4E, which finds the first file matching the given name
and initializes a data structure used by 0x4F to find successive
matches. As with many DOS functions, these two indicate failure by
setting the carry flag and placing an error code in the AX register,
both of which are returned to the C program in the REGS union.

The data structure initialized by "findentr()" and used by
"findnext()" is located in an area called the disk transfer area
(DTA).  This is not explicitly passed to DOS functions, but is kept
track of by DOS.  When a program starts, the DTA occupies the last
half of the program segment prefix, overlaying the unparsed command
line arguments.  This means that programs which look at the unparsed
command line arguments should make a copy of this area as soon as they
begin, before the DTA is used for anything else.  Programs can get the
current value of the DTA address by executing the DOS function 0x2F
and can change it by function 0x1A. These DOS functions are performed
by "get_DTA()" and "set_DTA()", respectively.

The header file "DOSTYPE.H" (figure 5) gives the format of the DTA
used by "findentr()" and "findnext()", as well as defining the bit
values used for file attributes.  In order to find directories,
hidden, and system files you must specify those attributes when
calling "findentr()".  Besides the file name and extent (ready to use
as a C string) and attributes, the DTA contains the date and time the
file was last written in a coded binary form and the size of the file
as a long integer. The declarations in "DOSTYPE.H" include the bit
fields in the date and time stamps, even though they are not needed by
the sample programs shown here.

To avoid any conflict in the different uses of the DTA, it is a good
idea for each routine using a DTA to save the current address with
"get_DTA()", set their own using "set_DTA()", and restore the old
address with another call to "set_DTA()" when done.  Both "findentr()"
and "findnext()" take the address of a DTA in the caller's local
storage as an argument and call "get_DTA()" and "set_DTA()" to
C News 1-04                 Page 19                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

temporarily set the DTA to that address. They return zero to indicate
that a file was found and 18 to indicate no (or no more) files.
"findentr()" returns two to indicate an invalid pathname.

The program FF (figure 2) is a simple file find utility similar to the
Norton Utilities FF.COM.  FF searches an entire disk or the subtree
starting with a specified directory for files matching a filename and
extent which may contain wildcards.  This is useful when you either
want to find all occurrences of a file which exists in many
directories, or if you forget what directory contains a given file.
The "main()" function simply checks to see that an argument was given
and separates it into a path and filename part.  If no path
(directory) was specified, the root directory on the default drive is
used.  This initial path and filename is then passed to "trav()". The
most interesting function is "trav()" (for traverse).  Traversing a
subtree means to somehow reference or do something at each node.  The
specialized function "trav()" first uses "findentr()" and "findnext()"
to find the matching files in the directory specified and then
finds all the subdirectories by the same method, this time specifying
that files with the DIRECTORY attribute, any file name, and no extent
be returned.  Unless attributes are specified, only normal files which
are not hidden would be found.  It is not possible to exclude regular
files when calling "findentr()", so "trav()" has to check the
DIRECTORY bit in DTA.attr itself.  It would have been useful here to
declare bit fields within the attribute byte, but unfortunately bit
fields cannot be defined within a single byte.  The next best thing is
to use "#define" to give symbolic names to the values of the bits for
each attribute and then use bitwise and operations to test them.

For each subdirectory, "trav()" calls itself recursively, specifying
the subdirectory found and the same filename and extent from the
original argument.  It is because of this recursion that each
invocation of "trav()" must have its own DTA and other local
variables.  This is accomplished by simply declaring them with the
default auto storage class within "trav()".

Recursion is often illustrated by value returning numerical functions,
such as factorials, but is also useful for subroutines (or void
functions in C).  Actually, the usual numerical examples are not
really very practical.  Mathematicians like to work with recursive
definitions of functions not because that is a necessarily a practical
method of computation, but because the recursive definitions are
sometimes simpler and easier to use in inductive proofs.

The example of recursion provided by "trav()" is a more practical one.
Since directories may contain other directories, the natural
definition is recursive, and the traversal implemented by "trav()" is
the most natural way to find all the directories in the tree.  Compare
C News 1-04                 Page 20                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

the simplicity of the method used with any nonrecursive implementation
you can devise (and there are many) and you should get an appreciation
for the little used (but sometimes misused) technique of recursion.

                            Summary

The examples given here are simplified, but are still useful programs.
They illustrate the use of "SETARGV.OBJ" and the functions
"findentr()", "findnext()", "get_DTA()", and "set_DTA()", any or all
of which can be incorporated into your own programs.  Using them, your
programs can expand wildcards without direct reference to the DOS
functions.  More importantly, I hope that you can see from these
examples that it is easy to use DOS functions, even if you do not know
assembly language, and that you will be encouraged to learn about and
use other DOS functions to extend the power of C programs operating in
the DOS environment.


                            Figure 1 - ARGS.C

/* Display command line arguements */
/* Link with SSETARGV.OBJ.         */
#include <stdio.h>
main(argc, argv) int argc; char *argv[];
{
int i;
for (i=1; i<argc; ++i)
  {
  #ifdef NOQUOTES
  puts(argv[i]);
  #else
  /*
     Use of lower level output routines saves space if "printf()"
     is not needed elsewhere, though "printf()" would be a little
     less cumbersome at the source level.
  */
  putchar('"');
  fputs(argv[i],stdout);
  putchar('"');
  putchar('\n');
  #endif
  }
}
                             Figure 2 - FF.C
#include <stdio.h>
#include <string.h>
#include "dostype.h"

C News 1-04                 Page 21                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

main(argc,argv) int argc; char *argv[];
{
char st_dir[128];
char *namepart;
int i, j;
if (argc<2) exit(1);
i=strlen(argv[1])-1;
while (i>=0 && argv[1][i]!='\\' && argv[1][i]!=':') --i;
if (i>=0)
  {
  if (argv[1][i]==':')
    {
    st_dir[i+1]='\\';
    st_dir[i+2]='\0';
    }
  else
    st_dir[i+1]='\0';
  namepart=argv[1]+i+1;
  while (i>=0)
    {
    st_dir[i]=argv[1][i];
    --i;
    }
  }
else
  {
  st_dir[0]='\\';
  st_dir[1]='\0';
  namepart=argv[1];
  }

trav(st_dir,namepart);
}

trav(st_dir,filename_ext)
char st_dir[];
char filename_ext[];
{
char matchname[128];
struct DTA_STRUCT DTA;
unsigned char end_byte;

/* Show matching files in this directory */
strcpy(matchname,st_dir);
strcat(matchname,filename_ext);
if (findentr(&DTA,matchname,0)==0)
  do
    if (!(DTA.attr & DIRECTORY))
C News 1-04                 Page 22                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

      {
      fputs(st_dir,stdout);
      puts(DTA.name);
      }
  while (findnext(&DTA)==0);

/* Recursively search subdirectories */
end_byte=strlen(st_dir);
matchname[end_byte]='*';
matchname[end_byte+1]='\0';
if (findentr(&DTA,matchname,DIRECTORY)==0)
  do
    if ((DTA.attr & DIRECTORY) && (DTA.name[0]!='.'))
      {
      strcpy(matchname+end_byte,DTA.name);
      strcat(matchname,"\\");
      trav(matchname,filename_ext);
      }
  while (findnext(&DTA)==0);
}
                          Figure 3 - FINDENTR.C
#include <dos.h>
#include "dostype.h"

findentr(DTA, search_name, s_attr)
struct DTA_STRUCT *DTA; /* NULL to use current DTA */
char *search_name;
int s_attr; /* permitted attributes (use for H,S,D) */
{
char far *far_sn=search_name;
/* convert DTA to far rather than place burden on caller */
/* (only needed by small or medium memory models)        */
struct DTA_STRUCT far *far_DTA=DTA;
union REGS inregs;
struct SREGS segregs;
unsigned save_DTA_SEG;
unsigned save_DTA_OFF;

if (DTA)
  {
  /* save current DTA address */
  get_DTA(&save_DTA_SEG,&save_DTA_OFF);
  /* set DTA address to argument structure */
  set_DTA(FP_SEG(far_DTA),FP_OFF(far_DTA));
  }

/* Find first match file */
inregs.h.ah=0x4e;
C News 1-04                 Page 23                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

inregs.x.cx=s_attr;
segregs.ds=FP_SEG(far_sn);
inregs.x.dx=FP_OFF(far_sn);
intdosx(&inregs,&inregs,&segregs);

if (DTA)
  /* restore DTA address */
  set_DTA(save_DTA_SEG,save_DTA_OFF);

/* return result */
if (inregs.x.cflag) return (inregs.x.ax);
else return 0;
}

findnext(DTA)
struct DTA_STRUCT *DTA; /* NULL for current DTA */
{
struct DTA_STRUCT far *far_DTA=DTA;
union REGS inregs;
struct SREGS segregs;
unsigned save_DTA_SEG;
unsigned save_DTA_OFF;

if (DTA)
  {
  /* save current DTA address */
  get_DTA(&save_DTA_SEG,&save_DTA_OFF);
  /* set DTA address to argument structure */
  set_DTA(FP_SEG(far_DTA),FP_OFF(far_DTA));
  }

/* Find next entry */
inregs.h.ah=0x4f;
intdos(&inregs,&inregs);

if (DTA)
  /* restore DTA address */
  set_DTA(save_DTA_SEG,save_DTA_OFF);

/*  return  result  */
if  (inregs.x.cflag)  return (inregs.x.ax);
else return 0;
}
                            Figure 4 - DTA.C

#include <dos.h>
/* Set DTA address */
set_DTA(seg,off)
C News 1-04                 Page 24                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

unsigned seg, off;
{
union REGS inregs;
struct SREGS segregs;
inregs.h.ah=0x1a;
segregs.ds=seg;
inregs.x.dx=off;
intdosx(&inregs,&inregs,&segregs);
}

/* Get current DTA address */
get_DTA(seg,off)
unsigned *seg, *off;
{
union REGS inregs;
struct SREGS segregs;
inregs.h.ah=0x2f;
intdosx(&inregs,&inregs,&segregs);
*seg=segregs.es;
*off=inregs.x.bx;
}
                          Figure 5 - DOSTYPE.H

/* FCB_DATE:                                                       
*/
/* Date/time fields of FCB (also DTA_STRUCT, defined below)         
*/

struct FCB_DATE
  {
  struct
    {
    unsigned seconds:5;
    unsigned minutes:6;
    unsigned hours:5;
    } time;
  struct
    {
    unsigned day:5;
    unsigned month:4;
    unsigned year:7; /* 1980=0 */
    } date;
  };

/* DTA.STRUCT:                                                     
*/
/* Data block returned by DOS functions 0x4E and 0x4F, which find   
*/
C News 1-04                 Page 25                  21 Feb 1988
   
================================================================
Title: Filename Wildcard Expansion in Microsoft C
================================================================

/* files and directories matching a pathname, with wildcards.       
*/

#define ARCHIVE 0x20
#define DIRECTORY 0x10
#define SYSTEM 0x04
#define HIDDEN 0x02
#define READONLY 0x01

struct DTA_STRUCT
  {
  char reserved[21];
  char attr;
  union
    {
    struct FCB_DATE field;
    unsigned long date_time; /* For comparing the combination */
    } timestamp;
  unsigned long size;
  char name[13];
  };

C News 1-04                 Page 26                  21 Feb 1988
   
================================================================
/Usr/Bin  by Marshall Presnell
================================================================
   
 
                 The Great Compiler War Myth
 
     If you  have ever read the C Echo Conference on FidoNet,
I'm sure that  you've witnessed  the advent  of "Compiler Wars".
Not that  it's a  new topic,  I'm sure that people have been
arguing the merits of their personal favorite compiler since
the second  compiler was  written. It's  not the  purpose of
this author or C News to say "This is the best compiler".
There are  over 30  (and that's  a LOW  estimate)  currently
available C  compilers for  the PC.  How does  one go  about
determining which  is "best".  It simply  can't be done. One
compiler may  excel in  code optimization but have a limited
library, another  may have  a robust library but be terrible
as far  as compiler features, yet another will have features
out the  wazoo, but produce poor code. It goes on to include
ANSI compatibility,  preprocessor capabilities,  unused code
detection and  elimination, diagnostic  messages, clean user
interfaces,    pointer    optimization,    register    usage
optimization, etc, etc, ad nauseam.

              "But which compiler is the best?"
 
All of  them are,  and none of them are. If they get the job
done efficiently for your purposes, it's a good compiler. If
they fall  down on your job, it's not a good compiler. Since
there  is  no  way  to  adequately  evaluate  the  different
compilers in  such a  manner that  everyone agrees with, the
question is objectively irresolvable.

Oddly enough,  the question  usually  arises  with  specific
reference  to  Borland's  Turbo  C,  Microsoft  C  5.0,  and
Microsoft Quick C. Well.... ALL of the above packages are in
a class  that I  would consider "excellent". All have robust
libraries,  support   graphics,  compile  quickly,  generate
decent  code.   They  all   are  good  packages  to  develop
applications under.  Turbo C  and Quick  C are WONDERFUL for
the novice  programmer who  wants to  see what C is, and get
some experience  with it.  Basically, I'll take all three if
given a  choice. All  have disadvantages,  the  most  common
being that  all of them have bugs. I personally prefer Turbo
C's graphics  and use  it for  any graphic  presentation  of
data, but  for fast code and speed I use Microsoft C 5. It's
ALL a matter of personal preference.

The point is simply, there ain't no such thing as the best C
compiler. There's  no use  even trying  to find it. Use what
you have  or what  you buy to it's fullest extent and it's a
C News 1-04                 Page 27                  21 Feb 1988
   
================================================================
/Usr/Bin  by Marshall Presnell
================================================================

good deal (and you may learn something before it's done!).
If you  have any topic that you would like to see covered in
the /usr/bin,  please feel  free to  drop me a note on the C
BBS or via FidoNet. I'm at 109/639.106.

        Next issue: How to communicate with a FOSSIL

  C News 1-04                 Page 28                  21 Feb 1988
   
================================================================
ARTICLE SUBMISSION STANDARDS AND ADDRESSES
================================================================

     As I have repeatedly stated in this newsletter and previous
issues, I would like to see user-submitted articles, reviews or
questions.  Listed below are the standards that should be
followed to make my job easier as an editor.


     - Articles should be submitted in a ASCII non-formatted
       file. 

     - If the article include code fragments as examples. Then
       you can include the entire source file if you like for
       inclusion with the newsletter.

     - Book or magazine reviews should follow the same format,
       that is outlined in this issue.  The publisher, author,
       title, and ISBN number are a must. 

     - Compiler/and or product reviews, should include the
       version number and manufacture.  If possible, reviews
       should include a sample program with benchmarks.

   
     If you have any questions you can contact me at the
address's included on the next page.

C News 1-04                  Page 29                 21 Feb 1988

================================================================
ADDRESSES
================================================================

The C BBS is located at:

     C BBS
     % BCL Limited
     P.O. Box 9162
     McLean VA, 22102


     or you can send netmail to:


     1:109/713  < The phone number in the current nodelist is
                  inaccurate.  At this time it is not known
                  when it will be corrected. >




      C News 1-04                 Page 30                  21 Feb 1988
   
================================================================
USER RESPONSE FORM:
================================================================

This form will be included as a regular feature in all future
issues of C NEWS.



 What did you think of the content of this Issue?  _____________
   
 _______________________________________________________________


 What improvements can you think of that would make C News a
 better tool for the C Community?

 _______________________________________________________________

 _______________________________________________________________


 What is your favorite section or sections?  ___________________

 _______________________________________________________________


 What don't you like about C News?  ____________________________

 _______________________________________________________________


 Additional Comments:  _________________________________________

 _______________________________________________________________

 _______________________________________________________________

 _______________________________________________________________

C News 1-04                 Page 31                  21 Feb 1988
   
 ================================================================
                              INDEX
 ================================================================

 Subject:                                          Issue:

 Articles:

 Filename Wildcard Expansion in MSC                 4
 TurboC and Interrupts: A few Questions             2
   

 Book Reviews:

 C Database Development                             1
 C Programming Guide                                1
 C Programming Language                             1
 C Programmer's Guide to Serial Communications      3
 C Programmer's Library                             1
 C Primer Plus                                      1
 C the Complete Reference                           2
 Crafting C Tools for the IBM PC                    2
 Learning to Program in C                           1
 Microsoft C Programming on the IBM PC              1
 MS-DOS Developer's Guide                           4
 Programming in Windows                             3
 Reliable Data Structures in C                      1
 TurboC Programmer's Reference Book                 2


 Compilers:

 QuickC                                             1

   
 Software Reviews:
 
 Bplus11.arc                                        3
 C_Dates.arc                                        4
 Cdate.arc                                          4
 Casm.arc                                           3
 C-subr.arc                                         4
 Docu.arc                                           3
 Jcl-src.arc                                        4
 Mscpopup.arc                                       3
 Ndmake41.arc                                       4
 Nuc-subr.arc                                       3
 Shift_c.arc                                        4
 Sysact11.arc                                       4
 Tp_to_qc.arc                                       3
 Xenixarc.arc                                       4


Comments

Popular posts from this blog

WHAT THE WATCH TOWER BIBLE AND TRACT SOCIETY OF PENNSYLVANIA HAD TO SAY ABOUT WHAT WERE SUPPOSED TO HAVE HAPPENED in 1874

Uninterruptable Power Source (UPS) FAQ

Blade Runner FAQ