From: rnelson@wsuaix.csc.wsu.edu (roger nelson;S23487)
Newsgroups: comp.os.msdos.programmer
Subject: C version of foreign language translation unit
Date: 12 Jan 93 03:59:43 GMT
Article-I.D.: serval.1993Jan12.035943.25423
Organization: Washington State University

Several people have requested the C version of my foreign language
translation unit,  so here it is:

---Cut Here---------8<--------8<----Cut Here---------8<--------8<

/* language.h Version 1.0  by Roger Nelson*/

/*
   Phrases are stored in the phrases file: PHRASES.LNG
   which must be placed in in the same directory as the application
   program executables.
   (The phrases.lng file must also be available to the compiler.)

   The phrases file has the following format which allows for the compiler
   to double check the existance of a phrase so you can't inadvertantly
   leave out a phrase from your translations!!!!


    phraseID,
    / * programlist
    ENGLISH English phrase
    SPANISH Spanish phrase
    ITALIAN Italian phrase
    FRENCH French phrase
       :
       :
    * /
    NextphrasesID,
       :
       :


   Note / * and * / are actually the C comment characters!

   The phraseID must be a unique valid Identifier and must be
   followed by a comma. The phraseID and comma must be on their own line.

   After the first comment (on the same line) is a list of all programs in
   which the phrase is used, only those phrases used by the program will
   be loaded. This is useful if your application consists of several programs,
   but where not all phrases are used in all the programs.

   Each translation must be on its own line, the name of the language
   must be uppercase with consistent spelling and one word.

   There must be only one space or one tab character seperating the
   language from the phrase.

   There must not be any blank lines between the } and the next phrase ID.

   The very first phrases in PHRASES.LNG must be the translation for the
   name of the language:

   L_LANGUAGE,
   / * PROGRAM1 PROGRAM2
   ENGLISH English phrase
   FRENCH Francais phrase
   SPANISH Espanol phrase
   ITALIAN Italiano phrase
   * /

   If the phrase is to be a null string or a single space, then use
   an underscore character _,  Ie:  ENGLISH _



Tips for restarting a TurboVision application with a new application.

  You may want to allow the user to change the language within the
  application.

  The easiest thing to do is shutdown and restart TurboVision.

  1. Create a boolean variable that will be used to test for the actual exit
     of the application.

  2. Put a while loop using this variable as the test around the application
     init, run and done procedures.

  3. Call the language_init function near the beginning of the program.
     Call the language_end function near the end of the program.

  4. Usually object registration for TurboVision is done in the
     application.init procedure.
     Move these registrations to a point before the exit_application loop
     otherwise TurboVision will complain about stream registration when
     init gets call more than once.

  5. Provide menu options for changing the language.
     This may be a user preferences dialog box or submenus etc...

  6. Provide an application event handler point for each language:

    I.e.

    case cmLanguageDefault :
         language_load(getenv("LANGUAGE"),argv_0);
         message(@self,evCommand,cmQUIT,NIL);
      break;
    case cmLanguageEnglish :
         language_load("ENGLISH",argv_0);
         message(@self,evCommand,cmQUIT,NIL);
      break;
    case cmLanguageFrench  :
         language_load("FRENCH",argv_0);
         message(@self,evCommand,cmQUIT,NIL);
      break;
    case cmLanguageSpanish :
         language_load("SPANISH",argv_0);
         message(@self,evCommand,cmQUIT,NIL);
      break;
    case cmLanguageItalian :
         language_load("ITALIAN",argv_0);
         message(@self,evCommand,cmQUIT,NIL);
      break;

      Where argv_0 is a char * set to argv_0 at the beginning of main.

  7. When you actually want to exit the program with cmQUIT, set
     exit_application to TRUE:

      case cmExit_MyApp :
          exit_application = 1;
          message(@self,evCommand,cmQUIT,0);
       break;

  8. To use a phrase translation simply call tranlate() with the phrase_Id
     Ie.
     printf("%s (%s)",translate(L_mouse),translate(L_Not_available));

I.e. The main module of the program MYAPP would look something like this:

main(int argc; char *argv[0]);
{
  argv_0 = argv[0];


  // Get the default language from the DOS environment variable LANGUAGE,
  // set before running the program. If the environment variable doesn't
  // exist, then language_init will use ENGLISH.


  if (!language_init(getenv("LANGUAGE"),argv[0]))
  { printf("Unable to open language translation file: PHRASES.LNG\n"
             "This file should be placed in the same directory as %s\n",argv[0]);
    exit(1);
  };

  RegisterObjects;
  RegisterViews;
  RegisterMenus;
  RegisterDialogs;
  RegisterApp;
  RegisterHelpFile;

  exit_application = 0;                //  <- global variable
  while (!exit_application)
  {
     theapplication.Init;
     theapplication.Run;
     theapplication.Done;
  };

  language_end();
};

*/

enum phrases {
#include "phrases.lng"
END_PHRASES };

/* program_name is a fully qualified filename: i.e.  C:\APPDIR\MYAPP.EXE
   Usually just use argv[0].
*/

int language_init(char *language_name, char *program_name);
int language_load(char *language_name, char *program_name);
void language_end();
char *translate(long phrase_ID);

---Cut Here---------8<--------8<----Cut Here---------8<--------8<

/* language.cpp  Version 1.0*/

/*
   This Borland C/C++ module will help provide translation of text strings
   to different human languages.

   Written by Roger Nelson  Jan. 1993
   Comments, suggestions, questions and bug reports can be sent to:

       Roger Nelson
       Biological Systems Engr. Dept.
       Washington State University
       Pullman, WA 99164-6120

       rnelson@wsuaix.csc.wsu.edu

       Phone: (509)335-1578
       FAX  : (509)335-2722


   An equivelent module can also be provided for the programming languages:
   Pascal and scheme by request.
   ________________________________________________________________________
*/
#include <language.h>
#include <malloc.h>
#include <string.h>
#include <dir.h>           /* <- MS-DOS */
#include <stdio.h>


struct language_node
{
  long phrase_ID;
  char *phrase;
  struct language_node *right;
};

struct language_node *language_list = 0;

void language_path_program(char *path_program,char *path,char *program)
{
   char drive[MAXDRIVE];
   char dir[MAXDIR];
   char ext[MAXEXT];

   fnsplit(path_program,drive,dir,program,ext);
   strcpy(path,drive);
   strcat(path,dir);
};

void clear_language_list(struct language_node *node)
{
   if (node)
   {
     clear_language_list(node->right);
     free(node->phrase);
     free(node);
   };
};

int language_read_phrase
 (FILE *phrase_file,
  char *phrase,         /* Where to put the read phrase. */
  char *language_name,  /* The language to read. */
  char *used_by         /* This list of programs using this phrase */
 )
  /* Returns true is the next phrase was read successfully. */
{
   char phrase_ID_str[255];
   char language_name_in[255];
   int read_complete;
   char phrase_in[255];

   if (feof(phrase_file))  /* If at eof then phrase not read */
      return(0);

   fscanf(phrase_file,"%s,\n",phrase_ID_str);  /* get the phrase ID (not used) */

   if ((phrase_ID_str[0] == 0) || (feof(phrase_file)))
      return(0);

   fscanf(phrase_file,"\n%[^\n]",used_by);

   read_complete = 0;
   phrase[0] = 0;      /* Clear the phrase */
   do
   {
     fscanf(phrase_file,"%s%*c%[^\n]",language_name_in,phrase_in);
     if (language_name_in[0] == '*')
        read_complete = 1;
     else
     {  strupr(language_name_in);
        if (strcmp(language_name_in,language_name) == 0)
           strcpy(phrase,phrase_in);
        else
           /* Use english if translation not provided */
           if ((strcmp(language_name_in,"ENGLISH") == 0) &&
               (phrase[0] == 0))
              strcpy(phrase,phrase_in);
     };
   } while (!read_complete);
   return(1);
};


/* load_language returns 1 if the translations loaded successfully
   0 if the file is not found or corrupt.
*/
int language_load(char *language_name, char *program_name)
{
   FILE *phrase_file;
   char phrase_filename[MAXPATH];
   char phrase_directory[MAXPATH];
   char program_filename[MAXFILE];
   struct language_node *node = 0;
   long phrase_ID;   /* long may be int depending on implementation of enum */
   struct language_node *last_node = 0;
   char phrase[255];
   char used_by[255];

   if (language_list)
      clear_language_list(language_list);

   language_list = 0;


   if (strcmp(language_name,"") == 0)
     strcpy(language_name,"ENGLISH");

   phrase_ID = L_LANGUAGE;

   language_path_program(program_name,phrase_directory,program_filename);

   sprintf(phrase_filename,"%sPHRASES.LNG",phrase_directory);

   if ((phrase_file = fopen(phrase_filename,"rt")) == NULL)
      return(0);  /* Unable to open phrases file. */

   for (phrase_ID = L_LANGUAGE ; phrase_ID < END_PHRASES; phrase_ID++)
   {
     if (!language_read_phrase(phrase_file,phrase,language_name,used_by))
     {  fclose(phrase_file);
        return(0);   /* language read failed. */
     };
     if (strstr(strupr(used_by),strupr(program_filename)))
     {
        node = (struct language_node *)malloc(sizeof(struct language_node));
        language_list = language_list ? language_list : node;
        node->phrase_ID = phrase_ID;
        node->phrase = (char *)malloc(strlen(phrase)+1);
        strcpy(node->phrase,phrase);
        node->right = 0;
        if (last_node) last_node->right = node;
        last_node = node;
     }
   };
   fclose(phrase_file);
   return(1);
};

static char L_unable_to_translate_str[] = "???";
static char L_blank_str[] = " ";

char *translate(long phrase_ID)
{
   struct language_node *curr;
   static char *translation;

   for (curr = language_list;
        curr && (curr->phrase_ID != phrase_ID);
        curr = curr->right);  /*  <- Yes semicolon here! */

   if (curr)
      translation = curr->phrase;
   else
      translation = L_unable_to_translate_str;
   if (translation[0] == '_')
      translation = L_blank_str;
   return(translation);
};

int language_init(char *language_name, char *program_name)
{
   language_list = 0;

   return(language_load
          ((strcmp(language_name,"") == 0) ? "ENGLISH" : language_name,
           program_name));
};

void language_end()
{
   clear_language_list(language_list);
};

---Cut Here---------8<--------8<----Cut Here---------8<--------8<

begin 644 phrases.lng
M3%],04Y'54%'12P-"B\J(%!!4DU34$%7#0I%3D=,25-(($5N9VQI<V@-"D92
M14Y#2"!&<F%N8V%I<PT*251!3$E!3B!)=&%L:6%N;PT*4U!!3DE32"!%<W!A
M;F]L#0HJ+PT*3%]!8F]U="P-"B\J(%!!4DU34$%7#0I%3D=,25-(($%B;W5T
M#0I&4D5.0T@@075T;W5R#0I)5$%,24%.(%)I9W5A<F1O#0I34$%.25-(($%C
M97)C82!D90T**B\-"DQ?07!R+`T*+RH@4$%235-005<-"D5.1TQ)4T@@07!R
M#0I&4D5.0T@@079R#0I)5$%,24%.($%P<@T*4U!!3DE32"!!8G(-"BHO#0I,
M7T%P<FEL+`T*+RH@4$%235-005<-"D5.1TQ)4T@@07!R:6P-"D9214Y#2"!!
M=G)I;`T*251!3$E!3B!!<')I;&4-"E-004Y)4T@@06)R:6P-"BHO#0I,7T%U
M9RP-"B\J(%!!4DU34$%7#0I%3D=,25-(($%U9PT*1E)%3D-(($%O=`T*251!
M3$E!3B!!9W0-"E-004Y)4T@@06=O#0HJ+PT*3%]!=6=U<W0L#0HO*B!005)-
M4U!!5PT*14Y'3$E32"!!=6=U<W0-"D9214Y#2"!!;Q9T#0I)5$%,24%.($%G
M;W-T;PT*4U!!3DE32"!!9V]S=&\-"BHO#0I,7T-H86YG95]$:7)E8W1O<GDL
M#0HO*B!005)-4U!!5PT*14Y'3$E32"!#:&%N9V4@1&ER96-T;W)Y#0I&4D5.
M0T@@0VAA;F=E<B!R`G!E<G1O:7)E#0I)5$%,24%.($-A;6)I;R!D:2!D:7)E
M8W1O<GD-"E-004Y)4T@@0V%M8FEA<B!D:7)E8W1O<FEO#0HJ+PT*3%]#:&5C
M:U]P871H7V]R7W-P96QL:6YG+`T*+RH@4$%235-005<-"D5.1TQ)4T@@0VAE
M8VL@=&AE('!A=&@@;W(@<W!E;&QI;F<N#0I&4D5.0T@@4&5U="T(=')E(&5R
M<F5U<B!S96YT:65R(&]U(`)P96QL871I;VXN#0I)5$%,24%.(%9E<FEF:6-A
M<F4@:6P@<&5R8V%R<V\@;R!I;"!N;VUE+@T*4U!!3DE32"!697)I9FEQ=64@
M;&$@<G5T82!O(&QA(&]R=&]G<F%F(6$N#0HJ+PT*3%]#;&]S92P-"B\J(%!!
M4DU34$%7#0I%3D=,25-(($-L;W-E#0I&4D5.0T@@1F5R;65R#0I)5$%,24%.
M($-H:75D:0T*4U!!3DE32"!#97)R87(-"BHO#0I,7T-U<G)E;G1?9&ER96-T
M;W)Y+`T*+RH@4$%235-005<-"D5.1TQ)4T@@0W5R<F5N="!$:7)E8W1O<GD-
M"D9214Y#2"!2`G!E<G1O:7)E($-O=7)A;G0-"DE404Q)04X@1&ER96-T;W)Y
M($-O<G)E;G1E#0I34$%.25-(($1I<F5C=&]R:6\@8V]R<FEE;G1E#0HJ+PT*
M3%]#7V%?<V-A9&4L#0HO*B!005)-4U!!5PT*14Y'3$E32"!#?F%^<V-A9&4-
M"D9214Y#2"!#?F%^<V-A9&4-"DE404Q)04X@1FEN97-T<F4@:6X@?E-^;W9R
M87!P;W-I>FEO;F4-"E-004Y)4T@@0WYA?G-C861A#0HJ+PT*3%]$871E+`T*
M+RH@4$%235-005<-"D5.1TQ)4T@@1&%T90T*1E)%3D-(($1A=&4-"DE404Q)
M04X@1&%T80T*4U!!3DE32"!&96-H80T**B\-"DQ?1&%T97-?9F]R7W!R;V9I
M;&5?;W5T<'5T+`T*+RH@4$%235-005<-"D5.1TQ)4T@@1&%T97,@9F]R(')E
M<&]R=&EN9R!S;VEL('!R;V9I;&4@=F%R:6%B;&5S#0I&4D5.0T@@1&%T97,@
M<&]U<B!L)V]U='!U="!D97,@:&]R:7IO;G,-"DE404Q)04X@1&%T92!P97(@
M;"=O=71P=70@9&5L;&$@=&%V;VQA(&1E;"!S=6]L;PT*4U!!3DE32"!&96-H
M87,@<&%R82!R97!O<G1A<B!V87)I86)L97,@9&5L('!E<F9I;"!D92!S=65L
M;PT**B\-"DQ?1&%Y+`T*+RH@4$%235-005<-"D5.1TQ)4T@@1&%Y#0I&4D5.
M0T@@2F]U<@T*251!3$E!3B!':6]R;F\-"E-004Y)4T@@1"%A#0HJ+PT*3%]$
M87ES+`T*+RH@4$%235-005<-"D5.1TQ)4T@@1&%Y<PT*1E)%3D-(($IO=7)S
M#0I)5$%,24%.($=I;W)N:0T*4U!!3DE32"!$(6%S#0HJ+PT*3%]$87E?;V9?
M;6]N=&@L#0HO*B!005)-4U!!5PT*14Y'3$E32"!$87D@;V8@=&AE(&UO;G1H
M#0I&4D5.0T@@2F]U<B!D=2!M;VES#0I)5$%,24%.($EL(&=I;W)N;R!D96P@
M;65S90T*4U!!3DE32"!$(6$@9&5L(&UE<PT**B\-"DQ?1&5C+`T*+RH@4$%2
M35-005<-"D5.1TQ)4T@@1&5C#0I&4D5.0T@@1&5C#0I)5$%,24%.($1I8PT*
M4U!!3DE32"!$96,-"BHO#0I,7T1E8V5M8F5R+`T*+RH@4$%235-005<-"D5.
M1TQ)4T@@1&5C96UB97(-"D9214Y#2"!$96-E;6)R90T*251!3$E!3B!$:6-E
M;6)R90T*4U!!3DE32"!$:6-I96UB<F4-"BHO#0I,7V1E9F%U;'0L#0HO*B!0
M05)-4U!!5PT*14Y'3$E32"!D969A=6QT#0I&4D5.0T@@4&%R(&0"9F%U=`T*
M251!3$E!3B!P<F5D969I;FET;PT*4U!!3DE32"!S=&%N9&%R9`T**B\-"DQ?
M1&5L971E+`T*+RH@4$%235-005<-"D5.1TQ)4T@@1&5L971E#0I&4D5.0T@@
M4W5P<')I;65R#0I)5$%,24%.($-A;F-E;&QA#0I34$%.25-((%-U<')I;6ER
M#0HJ+PT*3%]%;G1E<BP-"B\J(%!!4DU34$%7#0I%3D=,25-(($5N=&5R#0I&
M4D5.0T@@16YT<F4-"DE404Q)04X@26YT<F]D=7)R90T*4U!!3DE32"!%;G1R
M90T**B\-"DQ?17AI="P-"B\J(%!!4DU34$%7#0I%3D=,25-(($5X:70-"D92
M14Y#2"!1=6ET=&5R#0I)5$%,24%.($5S8VD-"E-004Y)4T@@4V%L:7(-"BHO
M#0I,7T5X=&5N<VEO;E]M=7-T7VYO=%]S<&5C:69I960L#0HO*B!005)-4U!!
M5PT*14Y'3$E32"!4:&4@97AT96YS:6]N(&UU<W0@;F]T(&)E('-P96-I9FEE
M9"X-"D9214Y#2"!%>'1E;G-I;VX@;B=E<W0@<&%S(&YE8V5S<V%I<F4N#0I)
M5$%,24%.($PG97-T96YS:6]N92!N;VX@9&5V92!E<W-E<F4@<W!E8VEF:6-A
M=&$N#0I34$%.25-(($QA(&5X=&5N<VEO;B!N;R!D96)E(&5S<&5C:69I8V%R
M<V4N#0HJ+PT*3%]%7WA?:70L#0HO*B!005)-4U!!5PT*14Y'3$E32"!%?GA^
M:70-"D9214Y#2"!^47YU:71T97(-"DE404Q)04X@17YS?F-I#0I34$%.25-(
M('Y3?F%L:7(-"BHO#0I,7T9E8BP-"B\J(%!!4DU34$%7#0I%3D=,25-(($9E
M8@T*1E)%3D-(($9E=@T*251!3$E!3B!&96(-"E-004Y)4T@@1F5B#0HJ+PT*
M3%]&96)R=6%R>2P-"B\J(%!!4DU34$%7#0I%3D=,25-(($9E8G)U87)Y#0I&
M4D5.0T@@1F5V<FEE<@T*251!3$E!3B!&96)B<F%I;PT*4U!!3DE32"!&96)R
M97)O#0HJ+PT*3%](96QP+`T*+RH@4$%235-005<-"D5.1TQ)4T@@2&5L<`T*
M1E)%3D-(($%I9&4-"DE404Q)04X@06EU=&\-"E-004Y)4T@@07EU9&$-"BHO
M#0I,7TAO=7)S+`T*+RH@4$%235-005<-"D5.1TQ)4T@@2&]U<G,-"D9214Y#
M2"!H975R97,-"DE404Q)04X@3W)E#0I34$%.25-((&AO<F%S#0HJ+PT*3%])
M;G-E<G0L#0HO*B!005)-4U!!5PT*14Y'3$E32"!);G-E<G0-"D9214Y#2"!)
M;G-E<F5R#0I)5$%,24%.($EN<V5R:7-C:0T*4U!!3DE32"!);G-E<G1A<@T*
M*B\-"DQ?2F%N+`T*+RH@4$%235-005<-"D5.1TQ)4T@@2F%N#0I&4D5.0T@@
M2F%N#0I)5$%,24%.($=E;@T*4U!!3DE32"!%;G(-"BHO#0I,7TIA;G5A<GDL
M#0HO*B!005)-4U!!5PT*14Y'3$E32"!*86YU87)Y#0I&4D5.0T@@2F%N=FEE
M<@T*251!3$E!3B!'96YN86EO#0I34$%.25-(($5N97)O#0HJ+PT*3%]*=6PL
M#0HO*B!005)-4U!!5PT*14Y'3$E32"!*=6P-"D9214Y#2"!*=6P-"DE404Q)
M04X@3'5G#0I34$%.25-(($IU;`T**B\-"DQ?2G5L>2P-"B\J(%!!4DU34$%7
M#0I%3D=,25-(($IU;'D-"D9214Y#2"!*=6EL;&5T#0I)5$%,24%.($QU9VQI
M;PT*4U!!3DE32"!*=6QI;PT**B\-"DQ?2G5N+`T*+RH@4$%235-005<-"D5.
M1TQ)4T@@2G5N#0I&4D5.0T@@2G5N#0I)5$%,24%.($=I=0T*4U!!3DE32"!*
M=6X-"BHO#0I,7TIU;F4L#0HO*B!005)-4U!!5PT*14Y'3$E32"!*=6YE#0I&
M4D5.0T@@2G5I;@T*251!3$E!3B!':75G;F\-"E-004Y)4T@@2G5N:6\-"BHO
M#0I,7TQI;F5S7W!E<E]P86=E+`T*+RH@4$%235-005<-"D5.1TQ)4T@@3&EN
M97,@<&5R('!A9V4-"D9214Y#2"!,:6=N97,@<&%R('!A9V4-"DE404Q)04X@
M4FEG:&4@<&5R('!A9VEN80T*4U!!3DE32"!,(6YE87,@<&]R('`@9VEN80T*
M*B\-"DQ?3&EN95]W:61T:"P-"B\J(%!!4DU34$%7#0I%3D=,25-(($QI;F4@
M=VED=&@-"D9214Y#2"!,;VYG=65U<B!D92!L:6YG97,-"DE404Q)04X@3&%R
M9VAE>GIA(')I9V$-"E-004Y)4T@@06YC:&\@9&4@;&$@;"%N96$-"BHO#0I,
M7TQO860L#0HO*B!005)-4U!!5PT*14Y'3$E32"!,;V%D#0I&4D5.0T@@3&5C
M='5R90T*251!3$E!3B!#87)I8V$-"E-004Y)4T@@06)R:7(-"BHO#0I,7TQO
M861?0W)E871E+`T*+RH@4$%235-005<-"D5.1TQ)4T@@3&]A9"]#<F5A=&4-
M"D9214Y#2"!#:&%R9V5R+T-R`F5R#0I)5$%,24%.($-A<FEC82]#<F5A#0I3
M4$%.25-(($%B<FER+V-R96%R#0HJ+PT*3%]-87(L#0HO*B!005)-4U!!5PT*
M14Y'3$E32"!-87(-"D9214Y#2"!-87(-"DE404Q)04X@36%R#0I34$%.25-(
M($UA<@T**B\-"DQ?36%R8V@L#0HO*B!005)-4U!!5PT*14Y'3$E32"!-87)C
M:`T*1E)%3D-(($UA<G,-"DE404Q)04X@36%R>F\-"E-004Y)4T@@36%R>F\-
M"BHO#0I,7TUA>2P-"B\J(%!!4DU34$%7#0I%3D=,25-(($UA>0T*1E)%3D-(
M($UA:0T*251!3$E!3B!-86=G:6\-"E-004Y)4T@@36%Y;PT**B\-"DQ?36]U
M<V4L#0HO*B!005)-4U!!5PT*14Y'3$E32"!-;W5S90T*1E)%3D-((%-O=7)I
M<PT*251!3$E!3B!-;W5S90T*4U!!3DE32"!2870B;@T**B\-"DQ?3F5X=%]W
M:6YD;W<L#0HO*B!005)-4U!!5PT*14Y'3$E32"!.97AT('=I;F1O=PT*1E)%
M3D-(($9E;@AT<F4@<W5I=F%N=`T*251!3$E!3B!0<F]S<VEM82!F:6YE<W1R
M80T*4U!!3DE32"!696YT86YA(%-I9W5I96YT90T**B\-"DQ?3F]T7T%V86EL
M86)L92P-"B\J(%!!4DU34$%7#0I%3D=,25-(($YO="!!=F%I;&%B;&4-"D92
M14Y#2"!.;VX@1&ES<&]N:6)L90T*251!3$E!3B!.;VX@1&ES<&]N:6)I;&4-
M"E-004Y)4T@@3F\@9&ES<&]N:6)L90T**B\-"DQ?3F]T7V5N;W5G:%]M96UO
M<GE?=&]?8V]M<&QE=&5?;W!E<F%T:6]N+`T*+RH@4$%235-005<-"D5.1TQ)
M4T@@3F]T(&5N;W5G:"!M96UO<GD@879A:6QA8FQE('1O(&-O;7!L971E(&]P
M97)A=&EO;BX-"D9214Y#2"!-`FUO<FEE(&YO;B!D:7-P;VYI8FQE+B!/<`)R
M871I;VX@;F]N(&-O;7!L970N#0I)5$%,24%.($UE;6]R:6$@9&ES<&]N:6)I
M;&4@:6YS=69F:6-I96YT92!P97(@8V]M<&QE=&%R92!L)V]P97)A>FEO;F4N
M#0I34$%.25-(($YO(&AA>2!S=69I8VEE;G1E(&UE;6]R:6$@<&%R82!C;VUP
M;&5T87(@;&$@;W!E<F%C:2)N+@T**B\-"DQ?3F]T7W5S960L#0HO*B!005)-
M4U!!5PT*14Y'3$E32"!.;W0@57-E9`T*1E)%3D-(($EN=71I;&ES`@T*251!
M3$E!3B!.;VX@571I;&EZ>F%T;PT*4U!!3DE32"!.;R!S92!U<V$-"BHO#0I,
M7TYO=BP-"B\J(%!!4DU34$%7#0I%3D=,25-(($YO=@T*1E)%3D-(($YO=@T*
M251!3$E!3B!.;W8-"E-004Y)4T@@3F]V#0HJ+PT*3%].;W9E;6)E<BP-"B\J
M(%!!4DU34$%7#0I%3D=,25-(($YO=F5M8F5R#0I&4D5.0T@@3F]V96UB<F4-
M"DE404Q)04X@3F]V96UB<F4-"E-004Y)4T@@3F]V:65M8G)E#0HJ+PT*3%]/
M8W0L#0HO*B!005)-4U!!5PT*14Y'3$E32"!/8W0-"D9214Y#2"!/8W0-"DE4
M04Q)04X@3W1T#0I34$%.25-(($]C=`T**B\-"DQ?3V-T;V)E<BP-"B\J(%!!
M4DU34$%7#0I%3D=,25-(($]C=&]B97(-"D9214Y#2"!/8W1O8G)E#0I)5$%,
M24%.($]T=&]B<F4-"E-004Y)4T@@3V-T=6)R90T**B\-"DQ?3W!E;BP-"B\J
M(%!!4DU34$%7#0I%3D=,25-(($]P96X-"D9214Y#2"!/=79R:7(-"DE404Q)
M04X@07!R:0T*4U!!3DE32"!!8G)I<@T**B\-"DQ?3W!E;E]A7T9I;&4L#0HO
M*B!005)-4U!!5PT*14Y'3$E32"!/<&5N(&$@1FEL90T*1E)%3D-(($]U=G)I
M<B!U;F4@9FEC:&EE<@T*251!3$E!3B!!<')I('5N($9I;&4-"E-004Y)4T@@
M06)R:7(@=6X@87)C:&EV;PT**B\-"DQ?3U]+7RP-"B\J(%!!4DU34$%7#0I%
M3D=,25-(($]^2WX-"D9214Y#2"!/?DM^#0I)5$%,24%.('Y%?G-E9W5I#0I3
M4$%.25-(('Y'?G5A<F1A<@T**B\-"DQ?4&%G:6YA=&EO;BP-"B\J(%!!4DU3
M4$%7#0I%3D=,25-((%!A9VEN871I;VX-"D9214Y#2"!086=I;F%T:6]N#0I)
M5$%,24%.($EM<&%G:6YA>FEO;F4-"E-004Y)4T@@4&%G:6YA8VDB;@T**B\-
M"DQ?4&QE87-E7W=A:70L#0HO*B!005)-4U!!5PT*14Y'3$E32"!0;&5A<V4@
M5V%I="XN+@T*1E)%3D-(($%T=&5N9&5Z+BXN#0I)5$%,24%.(%!R96=O(&%T
M=&5N9&5R92XN+@T*4U!!3DE32"!%<W!E<F4L('!O<B!F879O<BXN+@T**B\-
M"DQ?4')E<W-?4D5455).7W1O7V-O;G1I;G5E+`T*+RH@4$%235-005<-"D5.
M1TQ)4T@@4')E<W,@6U)E='5R;ET@=&\@8V]N=&EN=64N#0I&4D5.0T@@5&%P
M97(@6R`\1$19(%T@<&]U<B!C;VYT:6YU97(N#0I)5$%,24%.(%!R96UE<F4@
M6TEN=FEO72!P97(@8V]N=&EN=6%R92X-"E-004Y)4T@@4')E<VEO;F4@6T5N
M=')A<ET@<&%R82!C;VYT:6YU87(N#0HJ+PT*3%]0<F5V7W=I;F1O=RP-"B\J
M(%!!4DU34$%7#0I%3D=,25-((%!R978@=VEN9&]W#0I&4D5.0T@@1F5N`G1R
M92!P<@)C960"#0I)5$%,24%.($9I;F5S=')A('!R96,N#0I34$%.25-((%9E
M;G1A;F$@86YT97)I;W(-"BHO#0I,7U-A=F4L#0HO*B!005)-4U!!5PT*14Y'
M3$E32"!3879E#0I&4D5.0T@@4V%U=F5R#0I)5$%,24%.(%-A;'8-"E-004Y)
M4T@@1W5A<F1A<@T**B\-"DQ?4V5L96-T7V%?1FEL92P-"B\J(%!!4DU34$%7
M#0I%3D=,25-((%-E;&5C="!A($9I;&4-"D9214Y#2"!#:&]I<VER('5N(&9I
M8VAI97(-"DE404Q)04X@4V5L97II;VYA('5N('-I;&4-"E-004Y)4T@@4V5L
M96-C:6]N92!U;B!A<F-H:79O#0HJ+PT*3%]397!T96UB97(L#0HO*B!005)-
M4U!!5PT*14Y'3$E32"!397!T96UB97(-"D9214Y#2"!397!T96UB<F4-"DE4
M04Q)04X@4V5T=&5M8G)E#0I34$%.25-((%-E<'1I96UB<F4-"BHO#0I,7U-P
M="P-"B\J(%!!4DU34$%7#0I%3D=,25-((%-P=`T*1E)%3D-((%-P=`T*251!
M3$E!3B!3970-"E-004Y)4T@@4W!T#0HJ+PT*3%]4>7!E7T58251?=&]?<F5T
M=7)N+`T*+RH@4$%235-005<-"D5.1TQ)4T@@5'EP92!%6$E4('1O(')E='5R
M;BXN+@T*1E)%3D-((%1A<&5Z($58250@!2!R971O=7)N97(N+BX-"DE404Q)
M04X@26YV:6$@:6P@8V]M86YD;R!%6$E4('!E<B!R:71O<FYA<F4N+BX-"E-0
M04Y)4T@@17-C<FEB82!%6$E4('!A<F$@<F5T;W)N87(N+BX-"BHO#0I,7UEE
M87(L#0HO*B!005)-4U!!5PT*14Y'3$E32"!996%R#0I)5$%,24%.($%N;F\-
M"E-004Y)4T@@021O#0I&4D5.0T@@06YN90(-"BHO#0I,7UIO;VTL#0HO*B!0
M05)-4U!!5PT*14Y'3$E32"!:;V]M#0I&4D5.0T@@6F]O;0T*251!3$E!3B!:
M;V]M#0I34$%.25-((%IO;VT-"BHO#0I,7U]!7W!P96YD+`T*+RH@4$%235-0
M05<-"D5.1TQ)4T@@?D%^<'!E;F0-"D9214Y#2"!^07YJ;W5T97(-"DE404Q)
M04X@?D%^9V=I=6YG:0T*4U!!3DE32"!^07YG<F5G87(-"BHO#0I,7U]#7V%N
M8V5L+`T*+RH@4$%235-005<-"D5.1TQ)4T@@?D-^86YC96P-"D9214Y#2"!^
M07YN;G5L97(-"DE404Q)04X@07YN?FYU;&QA#0I34$%.25-(('Y#?F%N8V5L
M87(-"BHO#0I,7U]#7VAD:7(L#0HO*B!005)-4U!!5PT*14Y'3$E32"!^0WYH
M1&ER#0I&4D5.0T@@?D-^:&%N9V5R#0I)5$%,24%.('Y#?F%M8FEA#0I34$%.
M25-(('Y#?F%M8FEA<@T**B\-"DQ?7T-?;&]S92P-"B\J(%!!4DU34$%7#0I%
M3D=,25-(('Y#?FQO<V4-"D9214Y#2"!^1GYE<FUE<@T*251!3$E!3B!^0WYH
M:75D:0T*4U!!3DE32"!^0WYE<G)A<@T**B\-"DQ?7T1?96QE=&4L#0HO*B!0
M05)-4U!!5PT*14Y'3$E32"!^1'YE;&5T90T*1E)%3D-(('Y3?G5P<')I;65R
M#0I)5$%,24%.('Y#?F%N8V5L;&$-"E-004Y)4T@@?E-^=7!R:6UI<@T**B\-
M"DQ?7T1?:7)E8W1O<GDL#0HO*B!005)-4U!!5PT*14Y'3$E32"!^1'YI<F5C
M=&]R>0T*1E)%3D-(('Y2?@)P97)T;VER90T*251!3$E!3B!^1'YI<F5C=&]R
M>0T*4U!!3DE32"!^1'YI<F5C=&]R:6\-"BHO#0I,7U]$7T]37W-H96QL+`T*
M+RH@4$%235-005<-"D5.1TQ)4T@@?D1^3U,@<VAE;&P-"D9214Y#2"!^1'Y/
M4R!S:&5L;`T*251!3$E!3B!^1'Y/4R!S:&5L;`T*4U!!3DE32"!^1'Y/4R!S
M:&5L;`T**B\-"DQ?7T5?>&ET+`T*+RH@4$%235-005<-"D5.1TQ)4T@@?D5^
M>&ET#0I&4D5.0T@@?E%^=6ET=&5R#0I)5$%,24%.('Y%?G-C:0T*4U!!3DE3
M2"!^4WYA;&ER#0HJ+PT*3%]?1E]I;&4L#0HO*B!005)-4U!!5PT*14Y'3$E3
M2"!^1GYI;&4-"D9214Y#2"!^1GYI8VAI97(-"DE404Q)04X@?D9^:6QE#0I3
M4$%.25-(('Y&?FEC:&5R;PT**B\-"DQ?7TE?;G-E<G0L#0HO*B!005)-4U!!
M5PT*14Y'3$E32"!^27YN<V5R=`T*1E)%3D-(('Y)?FYS97)E<@T*251!3$E!
M3B!^27YN<V5R:7-C:0T*4U!!3DE32"!^27YN<V5R=&%R#0HJ+PT*3%]?3%]O
M860L#0HO*B!005)-4U!!5PT*14Y'3$E32"!^3'YO860-"D9214Y#2"!^3'YE
M8W1U<F4-"DE404Q)04X@?D-^87)I8V$-"E-004Y)4T@@?D%^8G)I<@T**B\-
M"DQ?7TY?86UE+`T*+RH@4$%235-005<-"D5.1TQ)4T@@?DY^86UE#0I&4D5.
M0T@@?DY^;VT-"DE404Q)04X@?DY^;VUE#0I34$%.25-(('Y.?F]M8G)E#0HJ
M+PT*3%]?3E]E>'1?=VEN9&]W+`T*+RH@4$%235-005<-"D9214Y#2"!^1GYE
M;@AT<F4@<W5I=F%N=`T*14Y'3$E32"!^3GYE>'0@=VEN9&]W#0I)5$%,24%.
M('Y0?G)O<W-I;6$@9FEN97-T<F$-"E-004Y)4T@@5F5N=&%N82!^4WYI9W5I
M96YT90T**B\-"DQ?7T]?<&5N+`T*+RH@4$%235-005<-"D5.1TQ)4T@@?D]^
M<&5N#0I&4D5.0T@@?D]^<&5N#0I)5$%,24%.('Y!?G!R:0T*4U!!3DE32"!^
M07YB<FER#0HJ+PT*3%]?3U]R:6=I;BP-"B\J(%!!4DU34$%7#0I%3D=,25-(
M('Y/?G)I9VEN#0I&4D5.0T@@3W)I9VEN90T*251!3$E!3B!^3WYR:6=I;F4-
M"E-004Y)4T@@?D]^<FEG:6YA;`T**B\-"DQ?7T]?=F5R=W)I=&4L#0HO*B!0
M05)-4U!!5PT*14Y'3$E32"!^3WYV97)W<FET90T*1E)%3D-(('Y2?F5M<&QA
M8V5R#0I)5$%,24%.('Y2?FES8W)I=FD-"E-004Y)4T@@?D-^86UB:6%R#0HJ
M+PT*3%]?4%]R:6YT+`T*+RH@4$%235-005<-"D5.1TQ)4T@@?E!^<FEN=`T*
M1E)%3D-(('Y)?FUP<FEM97)I90T*251!3$E!3B!^4WYT86UP80T*4U!!3DE3
M2"!^27YM<')I;6ER#0HJ+PT*3%]?4E]E<VEZ95]M;W9E+`T*+RH@4$%235-0
M05<-"D5.1TQ)4T@@?E)^97-I>F4O;6]V90T*1E)%3D-(('Y#?F%L:6)R86=E
M#0I)5$%,24%.('Y2?FED:6UE;G-I;VYA+VUU;W9I#0I34$%.25-(($-A;6)I
M87(@?E1^86UA)&\O;6]V97(-"BHO#0I,7U]27W5N=&EM95]G<F%P:"P-"B\J
M(%!!4DU34$%7#0I%3D=,25-(('Y2?G5N=&EM92!'<F%P:`T*1E)%3D-(('Y'
M?G)A<&AI<75E#0I)5$%,24%.('Y'?G)A9FEC:2!V<R!T96UP;PT*4U!!3DE3
M2"!^1WYR(&9I8V]S#0HJ+PT*3%]?4U]A=F4L#0HO*B!005)-4U!!5PT*14Y'
M3$E32"!^4WYA=F4-"D9214Y#2"!^4WYA=79E<@T*251!3$E!3B!^4WYA;'9A
M#0I34$%.25-(('Y'?G5A<F1A<@T**B\-"DQ?7U1?:6QE+`T*+RH@4$%235-0
M05<-"D5.1TQ)4T@@?E1^:6QE#0I&4D5.0T@@?D-^$W1E(`4@8Q-T90T*251!
M3$E!3B!^07YF9FEA;F-A;65N=&\@9&5L;&4@9FEN97-T<F4-"E-004Y)4T@@
M?E9^96YT86YA<R!C;W-T861O(&$@8V]S=&%D;PT**B\-"DQ?7U9?:61E;U]M
M;V1E7S(U7S4P+`T*+RH@4$%235-005<-"D5.1TQ)4T@@?E9^:61E;R!M;V1E
M(#(U+S4P#0I&4D5.0T@@?E9^:61E;R!M;V1E(#(U+S4P#0I)5$%,24%.('Y3
M?F-H97)M;R!I;B!-;V1A;&ET!2`R-2\U,`T*4U!!3DE32"!M;V1A(&1E;"!^
M5GYI9&5O(#(U+S4P#0HJ+PT*3%]?5U]I;F1O=RP-"B\J(%!!4DU34$%7#0I%
M3D=,25-(('Y7?FEN9&]W#0I&4D5.0T@@?D9^96X(=')E#0I)5$%,24%.('Y&
M?FEN97-T<F$-"E-004Y)4T@@?E9^96YT86YA#0HJ+PT*3%]?6E]O;VTL#0HO
M*B!005)-4U!!5PT*1E)%3D-(('Y:?F]O;0T*14Y'3$E32"!^6GYO;VT-"DE4
M04Q)04X@?EI^;V]M#0I34$%.25-(('Y:?F]O;0T**B\-"DQ?1&%Y7V]F7WEE
M87(L#0HO*B!005)-4U!!5PT*14Y'3$E32"!$87D@;V8@=&AE('EE87([#0I&
M4D5.0T@@2F]U<B!D92!L)V%N;@)E.PT*251!3$E!3B!':6]R;F\@9&5L;"=A
M;FYO#0I34$%.25-(($0A82!D96P@821O.PT**B\-"DQ?9&ES86)L960L#0HO
M*B!005)-4U!!5PT*14Y'3$E32"!D:7-A8FQE9`T*1E)%3D-((&YO;B!H86)I
M;&ET`@T*251!3$E!3B!D:7-A8FEL:71A=&D-"E-004Y)4T@@9&5S:&%B:6QI
M=&%D;PT**B\-"DQ?96YA8FQE9"P-"B\J(%!!4DU34$%7#0I%3D=,25-((&5N
M86)L960-"D9214Y#2"!H86)I;&ET`@T*251!3$E!3B!A8FEL:71A=&D-"E-0
M04Y)4T@@:&%B:6QI=&%D;PT**B\-"DQ?1D%)3$5$+`T*+RH@4$%235-005<-
M"D5.1TQ)4T@@1D%)3$5$#0I&4D5.0T@@$$-(14,-"DE404Q)04X@1D%,3$E4
M3PT*4U!!3DE32"!&4D%#05-!#0HJ+PT*3%]N;W1?=F%L:60L#0HO*B!005)-
M4U!!5PT*14Y'3$E32"!N;W0@=F%L:60-"D9214Y#2"!N;VX@=F%L86)L92X-
M"DE404Q)04X@;F]N('9A;&ED;PT*4U!!3DE32"!N;R!E<R!V(&QI9&\-"BHO
M#0I,7U!!4U-%1"P-"B\J(%!!4DU34$%7#0I%3D=,25-((%!!4U-%1`T*1E)%
M3D-((%!!4U,0#0I)5$%,24%.(%!!4U-!5$\-"E-004Y)4T@@15A)5$]33PT*
M*B\-"DQ?5F%L:61A=&EN9RP-"B\J(%!!4DU34$%7#0I%3D=,25-((%9A;&ED
M871I;F<-"D9214Y#2"!686QI9&%T:6]N(&5N(&-O=7)S#0I)5$%,24%.(%9A
M;&ED87II;VYE(&EN(&%T=&\-"E-004Y)4T@@5F%L:61A;F1O#0HJ+PT*3%]6
M86QI9&%T:6]N+`T*+RH@4$%235-005<-"D5.1TQ)4T@@5F%L:61A=&EO;@T*
M1E)%3D-((%9A;&ED871I;VX-"DE404Q)04X@5F%L:61A>FEO;F4-"E-004Y)
M4T@@5F%L:61A8VDB;@T**B\-"DQ?5F5R:69Y:6YG7V5X:7-T86YC95]O9E]F
M:6QE+`T*+RH@4$%235-005<-"D5.1TQ)4T@@5F5R:69Y:6YG(&5X:7-T96YC
M92!O9B!F:6QE#0I&4D5.0T@@5@)R:69I8V%T:6]N(&1E(&PG`GAI<W1E;F-E
M(&1U(&9I8VAI97(-"DE404Q)04X@5F5R:69I8V$@9&5L;"=E<VES=&5N>F$@
M9&5L(&9I;&4@:6X@871T;PT*4U!!3DE32"!697)I9FEC86YD;R!E>&ES=&5N
38VEA(&1E;"!A<F-H:79O#0HJ+U!!
`
end
Newsgroups: comp.os.msdos.programmer