home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / CLIBSRC3.ZIP / PUTENV.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  6.1 KB  |  211 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - putenv.cas
  3.  *
  4.  * function(s)
  5.  *        putenv - adds string to current environment
  6.  *-----------------------------------------------------------------------*/
  7.  
  8. /*
  9.  *      C/C++ Run Time Library - Version 5.0
  10.  *
  11.  *      Copyright (c) 1987, 1992 by Borland International
  12.  *      All Rights Reserved.
  13.  *
  14.  */
  15.  
  16.  
  17. #pragma inline
  18. #include <string.h>
  19. #include <asmrules.h>
  20. #include <stdlib.h>
  21.  
  22. extern  char            **environ;
  23. extern  unsigned        _envSize;
  24.  
  25. /*-----------------------------------------------------------------------*
  26.  
  27. Name            putenv - adds string to current environment
  28.  
  29. Usage           int putenv(const char *envvar);
  30.  
  31. Prototype in    stdlib.h
  32.  
  33. Description     Define an environment string to be of the form:
  34.  
  35.                         name=string\0
  36.  
  37.                 This function scans the environment looking for an existing
  38.                 string with the same name as the argument *envvar. If it is
  39.                 found then the pointer envvar  is substituted in the table.
  40.                 The replaced string  is not overwritten or freed,  just the
  41.                 reference to it in the environment table is removed.
  42.  
  43.                 If the argument  represents a new name, not  matched in the
  44.                 existing  environment,  then  it  will  be  appended to the
  45.                 environment  table. The  table is  adjusted in  chunks of 4
  46.                 pointers and is initialized with  at least 4 spare entries,
  47.                 but if all spare entries in the table have been used then a
  48.                 new larger  block is allocated.  The environment is  copied
  49.                 into the new  block, the "environ" pointer is  updated, and
  50.                 the old block is deallocated. The envp parameter to  main()
  51.                 will then be invalid.
  52.  
  53.                 The string  comparison is case-sensitive, in  the usual "C"
  54.                 tradition.
  55.  
  56.  
  57. Return value    On success, putenv returns 0; on failure, -1
  58.  
  59. *------------------------------------------------------------------------*/
  60. int _FARFUNC putenv( const char _FAR *nameP )
  61. {
  62.     char  **envP;
  63.  
  64. asm     LES_    di, nameP
  65.  
  66.         /* Check for NULL pointer */
  67. #if (LDATA)
  68. asm     mov     ax, ES
  69. asm     or      ax, di
  70. #else
  71. asm     push    ds
  72. asm     pop     es
  73. asm     or      di, di
  74. #endif
  75. asm     jz      BadPutEnvExit
  76.  
  77.         /* Compute nameP length and remember first character */
  78. asm     mov     ah, ES_ [di]
  79. asm     mov     al, '='
  80. asm     mov     cx, -1
  81. asm     cld
  82. asm     repne   scasb
  83. asm     not     cx
  84. asm     dec     cx
  85. asm     jz      BadPutEnvExit   /* CX = VarName length */
  86.  
  87.         /* Look for nameP in environment array */
  88. #if __HUGE__
  89. asm     mov     di, seg environ
  90. asm     mov     DS, di
  91. #endif
  92. asm     LES_    di, DPTR_(environ)
  93. #if (LDATA)
  94. asm     mov     W1 (envP), ES
  95. asm     mov     bx, ES
  96. asm     or      bx, di
  97. #else
  98. asm     or      di, di
  99. #endif
  100. asm     mov     W0 (envP), di
  101. asm     jnz     FirstVariable
  102.  
  103.         /* If no match can be found, return -1. */
  104. BadPutEnvExit:
  105. asm     mov     ax, -1
  106. asm     jmp     PutEnvExit
  107.  
  108.         /* Does the first character match ??? */
  109. NextVariable:
  110. asm     add     W0 (envP), dPtrSize
  111. asm     LES_    di, envP
  112. FirstVariable:
  113. asm     LES_    di, ES_ [di]
  114. #if (LDATA)
  115. asm     mov     bx, ES
  116. asm     or      bx, di
  117. #else
  118. asm     or      di, di
  119. #endif
  120. asm     jz      VarNotFound
  121. asm     mov     al, ES_ [di]
  122. asm     or      al, al          /* "" terminates environment */
  123. asm     jz      VarNotFound
  124. asm     cmp     ah, al          /* compare first characters */
  125. asm     jne     NextVariable
  126. asm     mov     bx, cx
  127. asm     cmp     BY0 (ES_ [di+bx]), '='
  128. asm     jne     NextVariable    /* must be followed by '=' */
  129.  
  130.         /* Yes, so compare the remainder of nameP */
  131.         pushDS_
  132. asm     LDS_    si, nameP
  133. asm     repe    cmpsb
  134.         popDS_
  135. asm     xchg    cx, bx
  136. asm     jne     NextVariable
  137.  
  138. /* The entries match names.  Replace the old pointer with the new. */
  139. VarFound:
  140. asm     LES_    di, envP
  141. asm     mov     ax, W0 (nameP)
  142. asm     mov     W0 (ES_ [di]), ax
  143. #if (LDATA)
  144. asm     mov     ax, W1 (nameP)
  145. asm     mov     W1 (ES_ [di]), ax
  146. #endif
  147. asm     jmp     short   GoodPutEnvExit
  148.  
  149. /* If arrived here then no matching name exists in the table.  A new */
  150. /*       entry must be made.  Is the existing table big enough ?     */
  151. VarNotFound:
  152. asm     mov     bx, W0(envP)
  153. asm     sub     bx, W0(environ)
  154. asm     add     bx, dPtrSize
  155. asm     cmp     bx, _envSize
  156. asm     jb      Append
  157.  
  158. /* The environment table is full.  It must be enlarged by copying to */
  159. /*       a new memory block.                                         */
  160. asm     add     bx, 4 * dPtrSize
  161. asm     push    bx
  162. asm     call    EXTPROC(malloc)
  163. asm     pop     cx
  164. asm     mov     di, ax
  165. #if (LDATA)
  166. asm     mov     ES, dx
  167. asm     mov     bx, ax
  168. asm     or      bx, dx
  169. #else
  170. asm     push    DS
  171. asm     pop     ES
  172. asm     or      di, di
  173. #endif
  174. asm     jz      BadPutEnvExit
  175. asm     xchg    cx, _envSize
  176. asm     push    cx
  177.         pushDS_
  178. asm     LDS_    si, DPTR_(environ)
  179. asm     rep     movsb
  180.         popDS_
  181. asm     xchg    ax, W0 (environ)
  182. #if (LDATA)
  183. asm     xchg    dx, W1 (environ)
  184. asm     push    dx
  185. #endif
  186. asm     push    ax
  187. asm     call    EXTPROC(free)
  188. asm     add     sp, dPtrSize
  189. asm     pop     bx
  190.  
  191. /* If arrived here then BX points to the first unused table slot  */
  192. /*       and the new entry is to be appended.  The append is done */
  193. /*       by copying the final pointer (to the empty string) up    */
  194. /*       one place and inserting the new string in its place.     */
  195. Append:
  196. asm     LES_    di, DPTR_(environ)
  197. asm     mov     ax, W0 (nameP)
  198. asm     xchg    ax, W0 (ES_ [di+bx-dPtrSize])
  199. asm     mov     W0 (ES_ [di+bx]), ax
  200. #if (LDATA)
  201. asm     mov     ax, W1 (nameP)
  202. asm     xchg    ax, W1 (ES_ [di+bx-dPtrSize])
  203. asm     mov     W1 (ES_ [di+bx]), ax
  204. #endif
  205.  
  206. GoodPutEnvExit:
  207. asm     xor     ax, ax
  208. PutEnvExit:
  209.     return(_AX);
  210. }
  211.