; ---------------------------------------------------------------------------
; S t r i n g   c o n v e r t e r
;
; Набор функций для работы со строками. Позволяет модифицировать строки в Clipper
; _независимо_от_языка_ (русский/английский) для 866cp
;
; char FirstUp   (char szLine) Конвертит строку в нижний  регистр, первая буква заглавная
; char All2Upper (char szLine) Конвертит строку в верхний регистр (аналог Upper(szLine))
; char All2Lower (char szLine) Конвертит строку в нижний  регистр	(аналог Lower(szLine))
; 
; Поскольку все функции пользуются одним и тем же типом и количеством :)
; входного параметра, то и используют они все фактически общий код
; (FirstUp), предварительно установив флаг признака вызванной функции
;
; Собственно рабочие функции U2Lower и L2Upper живут в StrWFunc.asm
;
; Исходная строка _не_меняется_.
;
; Ограничение: предельная длина обрабатываемой строки - 0ffh символов.
;              Все лишние символы остануться в исходном состоянии
;
; (с) WhiteUnicorn, 01.02.2000, Freeware, WhiteUnicorn@mail.ru
; ---------------------------------------------------------------------------
 

include	extenda.inc				; МАсмовский файл
extrn		U2Lower:far, L2Upper:far	; Живут в StrWFunc.asm

CLpublic <FirstUp, All2Upper, All2Lower>

DGROUP	group MyDataSeg
MyDataSeg	segment '_DATA'

;	szAsmLine	db  0dh, 0ah, 'Print from Asm$'
;	szPcount0	db  0dh, 0ah, 'Pcount = 0$'
;	szStrVoid	db  0dh, 0ah, 'szLine is NULL$'
	
	iLine_len	dw  ?			; Длина переданной строки
	WhatFunc	db  00h		; какая функция вызвана
	InputBuffer	db  0ffh dup (?)	; Сюда затаскиваем исходную строку,
	ResBuffer	db  0ffh dup (?)	; а тут соберется результирующая

MyDataSeg	ends

; ---------------------------------------------------------------------------
; F u n c t i o n 
; char FirstUp (char szLine)
;
; Конвертим строку в нижний регистр, первая буква заглавная
; Исходная строка _не_меняется_
;
; Все действия по получению исходной строки и возврату результата в Клиппер
; используются еще двумя функциями, поэтому обращаться с ними надо осторожно :)
; ---------------------------------------------------------------------------

CLfunc char FirstUp <char szLine>

CLcode
;	int	03h				; Это для отладчика подарок :)

	assume	ds:DGROUP, es:DGROUP
	mov	WhatFunc,00h		; Застолбили, что вызвана FirstUp

 TestParam:					; Проверяем количество входных параметров
	cmp	PCOUNT,1
	je	TestLine
;	lea	dx,szPcount0
	jmp	ErrorExit

 TestLine:					; и их качество :)
	TESTNUL	szLine
	jnz	StartWork
;	lea	dx,szStrVoid
	jmp	ErrorExit	

 StartWork:
 
 ;GetInputData:				; Затаскиваем строку в свой сегмент данных
	lea	di, InputBuffer
	push	ds
	lds	si, szLine
	mov	cx, word ptr ds:[si-02h]	; Тут должна лежать длина строки
	cmp	cx,0ffh
	jb	SaveCx
	mov	cx,0ffh
 SaveCx:
	push	cx
	repnz	movsb
	pop	cx
	pop	ds
	mov	iLine_len,cx		; Запомнили длину строки
						; Смотрим, какая из функций была вызвана:
	cmp	WhatFunc,01h		; All2Upper
	je	WF01_ModifyData
	cmp	WhatFunc,02h
	je	WF02_ModifyData		; All2Lower
	jmp	ModifyData			; FirstUp
 WF01_ModifyData:
	jmp	ModifyData_All2Up
 WF02_ModifyData:
	jmp	ModifyData_All2Lo

 ModifyData:
	lea	si, InputBuffer
	lea	di, ResBuffer
	mov	cx, 01h
	call	L2Upper		; первую букву делаем заглавной
	mov	cx, iLine_len
	sub	cx,1
	call	U2Lower		; остальные - строчными

; ErrorMes:
;	mov	ah,09h
;	int	21h

 MakeRetRes:
	lea	di, ResBuffer	; Получаем указатель на результирующую строку
	mov	dx,ds			; На всякий случай запоминаем ds:di в dx:ax
	mov	ax,di			; (мало ли чего...)

CLret dx ax				; Возвращаем far-указатель на новую строку

; ---------------------------------------------------------------------------
; F u n c t i o n 
; char All2Upper (char szLine)
;
; Конвертим строку в верхний регистр
; Исходная строка _не_меняется_
;
; Все действия по получению исходной строки и возврату результата 
; выполняются в функции FirstUp
; ---------------------------------------------------------------------------

CLfunc void All2Upper <char szLine>

CLcode
;	int	03h

	assume	ds:DGROUP, es:DGROUP

	mov	WhatFunc,01h	; Признак работы именно All2Upper
	jmp	TestParam		; И полезли в тело FirstUp за исходными данными

 ModifyData_All2Up:		; Вернулись, меняем строку
	lea	si, InputBuffer
	lea	di, ResBuffer
	mov	cx, iLine_len
	call	L2Upper		; конвертим буквы в верхний регистр

	jmp	MakeRetRes		; Опять полезли в тело FirstUp и там выходим

 ErrorExit:				; А это аварийный выход :) для всех функций (без возврата значения)
CLret

; ---------------------------------------------------------------------------
; F u n c t i o n 
; char All2Lower (char szLine)
;
; Конвертим строку в нижний регистр
; Исходная строка _не_меняется_
;
; Все действия по получению исходной строки и запихиванию результата 
; выполняются в функции FirstUp
; ---------------------------------------------------------------------------

CLfunc void All2Lower <char szLine>

CLcode
;	int	03h

	assume	ds:DGROUP, es:DGROUP

	mov	WhatFunc,02h	; Закинули признак, что работает All2Lower,
	jmp	TestParam		; смотались в FirstUp за исходными данными

 ModifyData_All2Lo:		; и меняем их
	lea	si, InputBuffer
	lea	di, ResBuffer
	mov	cx, iLine_len
	call	U2Lower		; конвертим буквочки в нижний регистр :)

	jmp	MakeRetRes		; И опять же умотали в FirsUp на выход

CLret

; ---------------------------------------------------------------------------
; E n d   o f   b a s e   f u n k t i o n s
; ---------------------------------------------------------------------------

END