
                      SISTEMA DE PARAMETROS EXTENDIDO
                      

        Quiz hayis observado que algunos programas permiten un sistema
extendido de parmetros, que nos permite que estos sean leidos de un
fichero de texto. Generalmente se usa para ello el caracter '@'. Bien, esta
es mi implementacin de un sistema de caractersticas similares en Turbo
Pascal. La ventaja que tiene es que nosotros apenas tenemos que hacer nada
para que funcione, pues basta con poner esta unidad en la sentencia USES y
los tpicos Paramcount y ParamStr sern substituidos por nuevas funciones
que soportan este sistema.

        Adems, se permite que cualquier fichero de texto sea aadido a los
parmetros, dando as soporte a todo tipo de ficheros .INI.

        Bueno, este es el listado de la unidad:


(*----------------------------------------------------------------------------*)

UNIT Params;
{$S-,R-,I-}


(* EJEMPLO DE FICHERO INCLUDE:

   MI_EXE.EXE -p /r03 -H @MI_EXE.INI /R /nosound


   En este caso cada lnea del fichero MI_EXE.INI sera aadida como
   parmetros justo en la posicin del parmetro @MI_EXE.INI. Por tanto
   /R no tiene por que ser el quinto parmetro, depender de cuantos haya
   en el fichero INCLUDE.

   Nota: Se admiten varios includes, pero no se admite anidamiento. Dicho de
   otra forma: si en un fichero include aparece un parmetro que comienza por
   '@', ser tomado como un parmetro normal.

*)


(* Otro detalle: En los ficheros include, las lneas que comienzan por '#',
   por '|', por '%' o por ';' se consideran comentarios y se ignoran. Adems,
   los parmetros vlidos deben estar situados en la primera columna, pues
   si hay espacios delante confundirn a las rutinas.
   En los ficheros include se puede poner ms de un parmetro por lnea, para
   ello hay que separarlos por un nico espacio *)

{$I-,R-,S-}

INTERFACE

FUNCTION ParamStr(W:Word):String;

FUNCTION ParamCount:Word;           (* Substituyen a las funciones normales *)

PROCEDURE AddFile(S:String);
(* Permite que se aada manualmente un fichero a los parmetros. Cada lnea  *)
(* de este se considerar un parmetro, al igual que en los ficheros include *)
(* Es til para aadir ficheros .INI y luego leer juntos parmetros y lo del *)
(* fichero                                                                   *)

IMPLEMENTATION

CONST SizeParams=2048; (* Aumentar o disminuir segn se suponga que el nmero
                          de parmetros en el programa va a ser grande o
                          pequeo *)

VAR ParamASCIIZ:^char;
    Pos:Word;
    I:Word;
    S:String;


PROCEDURE Error(N:Byte);
BEGIN
 ASM
  MOV AX,3
  INT 10h
 END;
 Write('Error en parmetros : ');
 CASE N OF
  1:WriteLn('Demasiados parmetros.');
  2:WriteLn('Fichero no se encuentra.');
 END;
 Halt(N)
END;

PROCEDURE AddFile(S:String);
CONST COMENT:SET OF CHAR=['#','|',';','%'];
VAR F:Text;
BEGIN
 Assign(F,S);
 reset(F);
 IF IOResult<>0 THEN Error(2);
 WHILE NOT EOF(F) DO
  BEGIN
   ReadLn(F,S);
   IF NOT (S[1] IN COMENT) AND (S<>'') THEN
    BEGIN
     IF Byte(S[0])+Pos+1>=SizeParams THEN Error(1);
     Move(S[1],pointer(longint(ParamASCIIZ)+Pos)^,byte(S[0]));
     Inc(Pos,byte(S[0]));
     char(pointer(longint(ParamASCIIZ)+Pos)^):=' ';
     Inc(pos);
    END;
  END;
 Close(F);
END;

FUNCTION ParamStr(W:Word):String;
VAR I,J:Word;
    S:String;
    P:^char;
BEGIN
 I:=ParamCount;
 IF (W>I) THEN S:=''
          ELSE IF W=0 THEN S:=System.ParamStr(0)
 ELSE BEGIN
       Pointer(P):=ParamASCIIZ;
       J:=0;
       DEC(W);
       WHILE J<W DO BEGIN
                     IF p^=' ' THEN INC(J);
                     INC(longint(p));
                    END;
       S:='';
       WHILE P^<>' ' DO BEGIN
                         S:=S+P^;
                         INC(longint(p))
                        END;
      END;
 ParamStr:=S;
END;

FUNCTION ParamCount:Word; Assembler;
ASM
 XOR BX,BX
 PUSH DS
 LDS SI,ParamASCIIZ
@BUCLE:
 LODSB
 OR AL,AL
 JZ @ya
 CMP AL,32
 JNZ @BUCLE
 INC BX
 JMP @BUCLE
@YA:
 MOV AX,BX
 POP DS
END;


BEGIN (* StartUp *)
 GetMem(pointer(ParamASCIIZ),SizeParams);
 Pos:=0;
 FOR I:=1 TO System.ParamCount DO
  BEGIN
   S:=System.ParamStr(I);
   IF Copy(S,1,1)='@' THEN AddFile(Copy(S,2,255))
                      ELSE BEGIN
                             IF Byte(S[0])+Pos+1>=SizeParams THEN Error(1);
                             Move(S[1],pointer(longint(ParamASCIIZ)+Pos)^,byte(S[0]));
                             Inc(Pos,byte(S[0]));
                             char(pointer(longint(ParamASCIIZ)+Pos)^):=' ';
                             Inc(pos);
                            END;
  END;
 char(pointer(longint(ParamASCIIZ)+Pos)^):=#0;
END.

(*----------------------------------------------------------------------------*)

        Como podris ver estas rutinas os ayudan en caso de tener un fichero
INI y parmetros, pues os bastar una sola rutina para examinar ambos.


        Dudas, comentarios y mejoras del sistema a:

        Carlos Snchez
        Ctra. Boadilla del Monte, 25
        28024 Madrid


