setting environment variables

new topic     » topic index » view thread      » older message » newer message

--=====================_849413188==_

A few days ago someone ask a question about setting environment variable.
I lost that message, anyway here is a demo that demontrate the use of parent
environment to transfert information between parent and child process.
This technic can be use to build a batch extender.

This demo program can be used in a batch file to split file name and extension
. For more information see note at beginning of demo.




--=====================_849413188==_

--  November 30th, 1996
--  Environment demo
--  By Jacques Deschenes
--
--  EnvDemo demonstrate how to use environment of parent process to establish
--  data transfert between a parent and child process
--  this technic is used by some batch extender program.
--  The batch extender program is running as a child process of command.com
--  it's environment is erased when it terminate.
--  So if it modify it's own environment the parent won't see it.
--  The batch extender should write it's functions results in the parent
--  environment.
--  This demo program will read a variable in named FILE in parent envrionment
--  and split name and extension and return the result in NAME and EXT environ-
--  ment variables.
--
--   Exemple of use:
--   write a batch file name SPLIT.BAT  like the following
--
--   REM SPLIT FILE NAME AND EXTENSION
--   SET
--   SET FILE=%1
--   ex envdemo
--   echo name is %NAME%
--   echo extension is %EXT%
--   SET FILE=
--   SET NAME=
--   SET EXT=
--
--   NOTE: parent environment should have enough space to create the new
--         variables.
--  this demo could be use as a foundation to build batch extender.

-- with trace

include machine.e

atom EnvAddr
integer EnvSize, EnvFree

function UpCase(integer a)
    if a >= 'a' and a <= 'z' then
        return a - 'a' + 'A'
    else
        return a
    end if
end function -- UpCase()

function GetParentEnv()
-- return address of parent process environment
sequence r
atom psp   -- program segment prefix
atom Parentpsp -- address of parent psp
atom ParentEnv
  -- in DOS each process has a psp and a copy of environment
  -- Get PSP segment address
  r = repeat(0,10)
  r[REG_AX] = #6200   -- dos call function #62 = get current PSP
  r = dos_interrupt(#21,r) -- return psp segment address in BX
  psp = r[REG_BX]*16 --  convert segment to linear address
  -- get parent process psp address, this is at offset #16 in psp
  Parentpsp = 16*(peek(psp+#16)+peek(psp+#17)*256)
  -- get parent process environment address, this is at offset #2C in PSP
  ParentEnv = 16*(peek(Parentpsp+#2C)+peek(Parentpsp+#2D)*256)
  return ParentEnv
end function -- GetParentEnv()

function SeekEOS()
-- return offset of end of string
integer zero, i, char
    i = 0
    zero = 0
    while 1 do
        char = peek(EnvAddr+i)
        if char = 0 then
            if zero then
                exit
            else
              zero = 1
            end if
        else
          zero = 0
        end if
        i = i + 1
    end while
    return i
end function -- SeekEOS()

function ReadASCIIZ(integer ofs)
-- return a string from environment
-- input: ofs is offset to start reading from.
-- output: string without the zero
integer char
sequence str
    str = {}
    while 1 do
        char = peek(EnvAddr+ofs)
        if char = 0 then
            exit
        else
          str = str & char
        end if
        ofs = ofs + 1
    end while
    return str
end function -- ReadASCIIZ()

function GetVar(sequence Name)
-- return the value of an environment variable
-- input: name is variable name
--        EnvAddr is environment address.
-- ouput: variable value if found or {} if not found
integer i
sequence  str,left
   -- trace(1)
   i = 0
   while 1 do
     str = ReadASCIIZ(i)
     if length(str) = 0 then
        return {}
     end if
     left = str[1..find('=',str)-1]
     if compare(left,Name) = 0 then
        return str[find('=',str)+1..length(str)]
     end if
     i = i + length(str) + 1
   end while
end function --GetVar()

procedure EraseVar(sequence Name)
-- erase an environment variable
-- input: EnvAddr is address environment
--        Name is name of variable to erase
integer i,j, char, zero
sequence  str,left
   i = 0
   while 1 do
     str = ReadASCIIZ(i)
     if length(str) = 0 then
        return
     end if
     left = str[1..find('=',str)-1]
     if compare(left,Name) = 0 then
         zero = 1
         j = i + length(str)+1
         while 1 do -- variable found, erase it.
            char = peek(EnvAddr+j)
            poke(EnvAddr+i,char)
            if char = 0 then
                if zero then
                    exit
                else
                   zero = 1
                end if
            else
              zero = 0
            end if
            i = i + 1
            j = j + 1
         end while
         EnvFree = EnvSize - SeekEOS() - 2
         return
     end if
     i = i + length(str) + 1
   end while
end procedure -- EraseVar()

procedure SetVar(sequence name, sequence value)
-- set the value of an environment variable
-- input: name is variable name
--        value is value affected to variable
integer i
    if length(name) + length(value) + 1 > EnvFree then
        return -- not enough space
    end if
    if length(GetVar(name)) > 0 then
        EraseVar(name) -- erase old value
    end if
    i = SeekEOS()
    poke(EnvAddr+i,name&'='&value&0&0)
end procedure -- SetVar()


------------------------------------------------------------------------------
sequence FileName
integer dotpos

EnvAddr = GetParentEnv()
-- get environment size from dos memory control block.
EnvSize = 16*(peek(EnvAddr-13)+peek(EnvAddr-12)*256)
EnvFree = EnvSize - SeekEOS() - 2

FileName = GetVar("FILE")

if length(FileName) = 0 then
    puts(1,"Environment variable FILE not found.\n")
    abort(1)
end if
dotpos= find('.',FileName)
if not dotpos then
  SetVar("NAME",FileName)
  SetVar("EXT","")
else
  SetVar("NAME",FileName[1..dotpos-1])
  SetVar("EXT",FileName[dotpos+1..length(FileName)])
end if


--=====================_849413188==_

@echo off
echo.
echo current environment
set
set FILE=%1
ex envdemo
echo.
echo name is %NAME%
echo extension is %EXT%
set FILE=
set NAME=
set EXT=


--=====================_849413188==_

Jacques Deschenes
Baie-Comeau, Quebec
Canada
desja at quebectel.com

--=====================_849413188==_--

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu