home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Fortran.51 / DISK5 / OS2 / STDENVP.AS$ / STDENVP.bin
Text File  |  1989-08-31  |  7KB  |  302 lines

  1.     page    ,132
  2.     title    stdenvp - OS/2 standard _setenvp routine
  3. ;***
  4. ;stdenvp.asm - OS/2 standard _setenvp routine
  5. ;
  6. ;    Copyright (c) 1985-1990, Microsoft Corporation.  All rights reserved.
  7. ;
  8. ;Purpose:
  9. ;    This module is called by the C start-up routine to set up "environ".
  10. ;    It copies the environment strings and a null-terminated table of
  11. ;    pointers to those strings into the heap.
  12. ;    The global symbol "_environ" is set to point to this array.
  13. ;
  14. ;*******************************************************************************
  15.  
  16. include version.inc
  17.     .xlist
  18. include cmacros.inc
  19. include msdos.inc
  20. include rterr.inc
  21.     .list
  22.  
  23. externNP _stdalloc        ; routine to allocate heap/stack space
  24. externNP _amsg_exit        ; Routine for error messages.
  25.  
  26. sBegin    data
  27. assumes ds,data
  28.  
  29. externDP environ        ; environment pointer
  30. externW _aenvseg        ; Environment segment
  31. externB _acfinfo        ; C_FILE_INFO string
  32.  
  33. sEnd    data
  34.  
  35.  
  36. sBegin    code
  37.  
  38. assumes ds,data
  39. assumes cs,code
  40.  
  41. page
  42. ;***
  43. ;_stdenvp - set up "envp" for C programs
  44. ;
  45. ;Purpose:
  46. ;    Reads the environment and build the envp array for C programs.
  47. ;
  48. ;Entry:
  49. ;    The environment strings occur at the beginning of the segment.
  50. ;    The list of environment strings is terminated by an extra null
  51. ;    byte.  Thus two null bytes in a row indicate the end of the
  52. ;    last environment string and the end of the environment, resp.
  53. ;
  54. ;Exit:
  55. ;    "environ" points to a null-terminated list of pointers to ASCIZ
  56. ;    strings, each of which is of the form "VAR=VALUE".  The strings
  57. ;    are copied from the environment segment into space allocated on
  58. ;    the heap.  The list of pointers is also located on there.
  59. ;
  60. ;Uses:
  61. ;    Locks the environment segment before use, and unlocks afterward
  62. ;    Allocates space on the heapfor the environment strings
  63. ;    and a list of pointers to them.
  64. ;
  65. ;    All registers except DS, SS, and BP are modified
  66. ;    Note especially that SI and DI are NOT preserved!
  67. ;
  68. ;Exceptions:
  69. ;
  70. ;*******************************************************************************
  71.  
  72. cProc    _setenvp,<PUBLIC>,<ds>
  73.  
  74. if sizeD
  75.     localW    dataseg     ; DGROUP save area
  76.     localW    envseg        ; segment OS environment segment
  77.     localW    envtab        ; segment environment pointer table
  78.     localW    envstrg     ; segment environment string area
  79. endif
  80.  
  81. cBegin
  82.  
  83.  
  84.     mov    es,_aenvseg    ; point to environment segment
  85.     assumes es,nothing
  86. if sizeD
  87.     mov    [envseg],es    ; save OS seg on stack for later
  88.     mov    [dataseg],ds    ; save DGROUP on stack
  89. endif
  90.  
  91. ;
  92. ; --- Scan the list of environment strings calculating the following
  93. ; values:
  94. ;    (1) si will count the number of environment strings
  95. ;    (2) di will count the number of bytes the strings occupy
  96. ; Stop on a null string
  97. ;
  98. ; es = OS environment segment
  99. ; ds = DGROUP
  100. ;
  101.  
  102.     ; init registers
  103.     xor    ax,ax        ; ax = 0 (search byte)
  104.     xor    si,si        ; si = 0 (env pointer count)
  105.     xor    di,di        ; di = 0 (initial offset)
  106.     mov    cx,-1        ; cx = ffff (infinite count)
  107.  
  108.     cmp    al,es:[di]    ; may not be a double null on OS/2 v1.0
  109.     je    noenv
  110. scanenv:
  111.     repnz    scasb
  112.     inc    si        ; si = envp count
  113.     scasb
  114.     jnz    scanenv
  115.                 ; di = count of string bytes
  116. noenv:
  117.     mov    ax,di        ; ax = length of env strings
  118.     inc    ax
  119.     and    al,not 1    ; round up to even
  120.  
  121.     inc    si        ; si = env pointer count + 1 (for null)
  122.     mov    di,si        ; di = env pointer count (save)
  123.     shl    si,1        ; si = env pointer count * 2
  124. if    sizeD
  125.     shl    si,1        ; si = env pointer count * 4
  126. endif
  127.  
  128. ;
  129. ; --- Allocate space for environment strings
  130. ; ax = # bytes for env strings
  131. ; si = # bytes for env pointers
  132. ; di = # of pointers
  133. ; es = OS environment segment
  134. ; ds = DGROUP
  135. ;
  136.     ; allocate space for strings
  137.                 ; ax = size needed for strings
  138.     call    _stdalloc    ; preserves si, di
  139.     jc    env_err     ; carry set = error
  140. if    sizeD
  141.     mov    word ptr [envstrg],dx ; save segment on frame
  142. endif
  143.     push    ax        ; push offset to string area
  144.  
  145.     ; allocate space for the pointer table
  146.  
  147.     mov    ax,si        ; ax = space for pointers
  148.     call    _stdalloc    ; preserves si, di
  149.     jc    env_err     ; carry set = error
  150.     mov    word ptr [environ],ax    ; init environ
  151. if    sizeD
  152.     mov    word ptr [environ+2],dx ; segment address for large model
  153.     mov    word ptr [envtab],dx    ; save segment here too
  154. endif
  155.     jmp    short env_ok    ; dx:ax = allocated space
  156.  
  157. env_err:            ; Error on space allocation
  158.     mov    ax,_RT_SPACEENV ; Memory error
  159.     jmp    _amsg_exit
  160.  
  161. ;
  162. ; --- Successfully allocated space for env table and strings
  163. ; Init registers for env copy loop
  164. ;
  165. ; ax = offset to env table area
  166. ; di = # of pointers
  167. ; es = OS environment segment
  168. ; ds = DGROUP
  169. ; tos = offset to string area
  170. ;
  171.  
  172. env_ok:
  173.     mov    cx,di        ; cx = envcnt
  174.     mov    bx,ax        ; bx = offset env pointers area
  175.     xor    si,si        ; si = OS env string area
  176.     pop    di        ; di = offset env string area
  177.  
  178.     push    es
  179.     push    ds
  180.     pop    es        ; es = DGROUP
  181.     pop    ds        ; ds = OS env segment
  182.  
  183. assumes es,data
  184. assumes ds,nothing
  185.  
  186. ;
  187. ; --- Check for no environment
  188. ;
  189.  
  190.     dec    cx        ; adjust for the last entry of 0000
  191.     jcxz    envdone     ;   done - no environment
  192.  
  193. ;
  194. ; --- Loop through the environment
  195. ; (1) Setup the environment table of pointers (environ)
  196. ; (2) Copy the environment strings into our address space
  197. ; (3) Do NOT copy the _C_FILE_INFO string
  198. ;
  199. if sizeD
  200. ; cx = # of env strings left to copy
  201. ; bx = offset of env pointer table
  202. ; ds:si = pointer to OS environment area
  203. ; es:di = pointer to next envstrg destination
  204. else
  205. ; cx = # of env strings left to copy
  206. ; ds:si = offset  to OS environment area
  207. ; es:bx = offset of env pointer table
  208. ; es:di = pointer to next envstrg destination
  209. ; es = DGROUP
  210. endif
  211.  
  212. envloop:
  213.  
  214.     ; --- Check for _C_FILE_INFO
  215.  
  216.     mov    ax,ds:[si]    ; get first two bytes of string
  217.  
  218. if sizeD
  219.     mov    es,[dataseg]    ; es = DGROUP
  220.     assumes es,data
  221. endif
  222.     cmp    ax,word ptr es:[_acfinfo]    ; is it "_C" ?
  223.     jne    cfi_check    ; nope, restore es and continue
  224.  
  225.     push    cx        ; save context
  226.     push    si
  227.     push    di
  228.  
  229.     mov    di,dataOFFSET _acfinfo    ; es:di = pointer to _C_FILE_INFO
  230.     mov    cx,6        ; length of string in words
  231.     repe    cmpsw        ; compare the strings
  232.  
  233.     pop    di        ; restore context
  234.     pop    si
  235.     pop    cx
  236.  
  237. cfi_check:            ; is it _C_FILE_INFO ??
  238.  
  239. if sizeD
  240.     mov    es,[envstrg]    ; es:di = next env string area
  241.     assumes es,nothing
  242. endif
  243.  
  244.     je    envcopy     ; yes, don't store this one
  245.     ;fall thru        ; nope, store it
  246.  
  247.     ; --- store env string pointer in table
  248. if sizeD
  249.     mov    ds,[envtab]    ; ds:bx = next table entry
  250. endif
  251.                 ; es:di = next env string area
  252. if sizeD
  253.     mov    ds:[bx],di    ; save env string pointer in table
  254.     mov    ds:[bx+2],es
  255.     add    bx,4        ; bump table pointer
  256. else
  257.     mov    es:[bx],di    ; save env string pointer in table
  258.     inc    bx        ; bump table pointer
  259.     inc    bx
  260. endif
  261.  
  262.     ; --- copy string from OS segment into our memory
  263.  
  264. envcopy:
  265.  
  266. if sizeD
  267.     mov    ds,[envseg]    ; ds:si = string in OS seg
  268. endif
  269.  
  270. envcpy:
  271.     lodsb            ; get a char from OS segment
  272.     stosb            ; copy into library space
  273.     or    al,al        ; end of string ??
  274.     jnz    envcpy        ; nope, continue copying string
  275.  
  276.     loop    envloop     ; do the next environment variable
  277.  
  278. ;
  279. ; --- Done copying strings
  280. ; put a null at the end of the envtab table
  281. ;
  282.  
  283. envdone:
  284.  
  285. if sizeD
  286.     mov    ds,[envtab]        ; ds:bx = env table pointer
  287.     mov    ds:[bx],cx        ; store a null
  288.     mov    ds:[bx+2],cx
  289. else
  290.     mov    es:[bx],cx        ; store a null
  291. endif
  292.  
  293. if sizeD
  294. cEnd
  295. else
  296. cEnd    <nolocals>
  297. endif
  298.  
  299. sEnd    code
  300.  
  301.     end
  302.