FreeUDFLib

A Free UDF Library for InterBase Servers

Gregory H. Deatz


Table of Contents


Introduction

FreeUDFLib is a free UDF library for use with InterBase databases. It is written in Delphi, and all source code is provided. Just because it is free, however, does not mean that it is public domain. If you have questions regarding your rights, please see see section Licensing.

Acknowledgements

Hoagland, Longo, Moran, Dunst & Doukas

Hoagland, Longo, Moran, Dunst & Doukas is a law firm in New Brunswick, NJ. This law firm is one of the most technologically advanced law firms in New Jersey, due largely to the fact that their management team has a uniquely clear vision of the future use of technology in the legal field.

Hoagland, Longo, Moran, Dunst & Doukas is dedicated to providing quality legal services to the business community, healthcare and insurance industries. Since our founding in 1977 we have handled thousands of matters spanning the spectrum of business transactions and civil litigation including automobile negligence, commercial litigation, construction claims, coverage, D and O liability, employment practices liability, environmental claims, general liability, municipal liability, products liability, professional liability and workers compensation.

Very special thanks goes to Hoagland, Longo, Moran, Dunst & Doukas. If you ever require legal representation in the New Jersey area, you might want to look these guys up.

InterBase corporation

InterBase corporation has provided their support by providing a home for both FreeUDFLib and FreeUDFLib (see section About the author).

Obviously, without InterBase, FreeUDFLib would be virtually meaningless, so a special thanks goes to all at InterBase, with a strong vote of support to please continue the outstanding work!

Contributors and supporters

Here is a list of all who have contributed or otherwise supported the project. If your name has been omitted, it is not on purpose:

  • Oleg Kukarthev, Gerard Perreault, Stephen W. Boyd, Doug Chamberlin, rberryman@earhlink.net, John Small (john@yagya.demon.co.uk), Graham Bremner (graham_bremner@hlmdd.com), Serge Vannieuwenborgh (sva@netsol.be).

    Technical support

    Since FreeUDFLib is free, it is important to give developers a sense of what kind of support they can expect. Although there are no guarantees of any kind, I want to give developers reasonable assurances of what they can, in general, expect from me.

    I believe that there are four basic levels of support developers require:

    1. Prompt bug resolution.
    2. Thorough documentation.
    3. Wish lists.
    4. Standard help-desk style support. (How do I do ...? When should I do ... ?)

    Bugs

    FreeUDFLib is intended to be used in production environments! To that end, a demonstrated bug will be fixed as promptly as possible.

    Because FreeUDFLib is completely free, developers also have access to the source code. If a bug is fixed, send it to me, and I will incorporate it in future "official releases" of the product.

    If a bug cannot be replicated, I will have a difficult time finding it, so I can't guarantee resolution of these so-called phantom bugs, but I will do my best to resolve them.

    If you provide me with a bug fix, your name will be included in the acknowledgements section of this manual. Bug reports should be submitted as e-mail messages only.

    Documentation

    The policy on resolving source code bugs also stands for correcting and maintaining good documentation. Please send me any and all corrections and/or enhancements to the documentation. Every product needs thorough and complete documentation. Even though this product is free, I have a desire to see it used in all environments. I can't expect a developer to use it if there is no documentation.

    I can't guarantee that I will respond to you, only that your comments will be heard and possibly included in future releases.

    Wish lists

    Users can feel free to provide me with wish list requests and/or FreeUDFLib enhancements.

    If you send me a wish list request, you will not receive a response from me, but you can be assured that your request will be considered for future releases.

    If you send me an enhancement or extension to FreeUDFLib that you would like included in the distribution, I will consider it and respond accordingly. Keep in mind, however, that FreeUDFLib and all source code is free. Do not even think about asking to distribute proprietary products with FreeUDFLib.

    If I distribute product enhancements written by others than myself, their names will be included in the acknowledgements section of this manual, and their source code will be acknowledged appropriately.

    Help desk

    I don't do help desk support, at least not in general. You can feel free to e-mail me with questions, but it is more likely than not that you will not receive a response from me.

    Help desk style questions should be directed to an appropriate Internet support group. The mailing list INTERBASE@dx100.mers.com, for example, provides excellent support for InterBase related questions.

    If you absolutely require my assistance for some issue, I can provide services for standard consulting rates.

    About the documentation

    I have used a product called texinfo to produce all documentation for FreeUDFLib.

    From a single source file, I can produce a formatted manual, ready for print-out (using tex), I can produce html, ready for viewing in a browser, and I can produce rich-text for the production of a help file.

    I don't see the need for producing a help file, so I haven't included one... just the original texinfo documentation, a ready-produced Acrobat file, and a single HTML manual.

    If the reader wishes to find more information on using texinfo with Windows, search the internet for "GNU tex texinfo Windows". (O yeah, texinfo is free, protected under the GNU Public License)

    Release notes

    Planned features

    1. Regular expression matcher.
    2. Search blobs/text strings for regular expressions.

    3/13/98

    Thread-safety has been pretty rigorously tested. Users should not have any problems with FreeUDFLib.

    New functions:

    1. EvaluateExpression: evalute a textual expression with support for symbols and string, date and numeric literals.

    Installation

    After unzipping FreeUDFLib.zip, copy `FreeUDFLib.dll' to the InterBase bin directory, most probably

    c:\Program Files\InterBase Corp\InterBase\Bin
    
    - or -
    
    c:\Program Files\Borland\IntrBase\Bin
    

    Whenever you require the use of FreeUDFLib in an InterBase database, run the `ext_funcs.sql' SQL script against the database.

    Licensing

    GENERAL SOFTWARE LICENSE AGREEMENT CAUTION: THE COPYING, MODIFICATION, TRANSLATION OR DISTRIBUTION OF THE OBJECT CODE, PROGRAM, SOFTWARE OR SOURCE CODE IMPLIES ACCEPTANCE OF THE TERMS OF THIS GENERAL SOFTWARE PROGRAM LICENSE AGREEMENT. YOU SHOULD READ CAREFULLY THE FOLLOWING TERMS AND CONDITIONS BEFORE YOU COPY, MODIFY, TRANSLATE OR DISTRIBUTE THE OBJECT CODE, PROGRAM, SOFTWARE OR SOURCE CODE.

    1.0 DEFINITIONS

    1.1 Licensee - The person who has the privilege to copy, modify, translate or distribute the object code, program, software and source code, subject to the terms and conditions of this General Software License Agreement.

    1.2 Object Code - The version of a computer program in machine language, and therefore, ready to be executed by the computer.

    1.3 Program - A sequence of instructions for executions by a computer.

    1.4 Software - The computer program plus program documentation, if applicable.

    1.5 Source Code - The version of a computer program in assembly language or high-level language, and therefore, not ready to be executed by the computer.

    1.6 Work - All forms of tangible or intangible property, based whole, in part or derived from the object code, program, software or source code.

    1.7 You - The person who has the privilege to copy, modify, translate or distribute the object code, program, software and source code, subject to the terms and conditions of this General Software License Agreement.

    2.0 LICENSE

    2.1 The copyright holder hereby extends a license to you to use its copyrighted object code, program, software and source code, subject to the terms and conditions of this General Software License Agreement.

    2.2 This license is applicable to the object code, program, software and source code distributed under the terms of this General Software License Agreement, any work containing the object code, program, software or source code distributed under the terms of this General Software License Agreement, any modification of the object code, program, software or source code distributed under the terms of this General Software License Agreement, any translation of the object code, program, software or source code distributed under the terms of this General Software License Agreement and any work containing a modification or translation of the object code, program, software or source code distributed pursuant to the terms and conditions of this General Software License Agreement.

    2.3 You may copy, modify, translate and distribute the object code, program, software or source code distributed under the terms of this General Software License Agreement, subject to the terms and conditions of this General Software License Agreement.

    2.4 If you copy, modify, translate or distribute the object code, program, software or source code distributed under the terms of this General Software License Agreement, you must publish and make known in a clear and conspicuous manner on each copy, modification, translation or distribution of the object code, program, software or source code that the copy, modification, translation or distribution of the object code, program, software or source code is subject to the terms and conditions of this General Software License Agreement and provide a copy of this General Software License Agreement with each copy, modification, translation or distribution of the object code, program, software or source code.

    2.5 If you derive, publish or distribute any work that is based whole or in part on the object code, program, software or source code distributed under the terms of this General Software License Agreement, or any modification or translation thereof, you must publish and make known in a clear and conspicuous manner on each such work that the work is subject to the terms and conditions of this General Software License Agreement and provide a copy of this General Software License Agreement with each work.

    2.6 If you copy, modify, translate or distribute the object code, program, software or source code distributed under the terms and conditions of this General Software License Agreement, you must provide clear and conspicuous notice that you have copied, modified, translated or distributed the object code, program, software or source code distributed under the terms of this General Software License Agreement, and indicate the date of each such copy, modification, translation or distribution.

    2.7 If you copy, modify, translate or distribute the object code, program, software or source code distributed under the terms of this General Software License Agreement, or publish or distribute any work that is derived, in whole or in part, from any copy, modification, translation or distribution of the object code, program, software or source code distributed under the terms of this General Software License Agreement, you cannot impose any further obligations or restrictions on any third person or entity other than what is contained in this General Software License Agreement.

    3.0 NO WARRANTY

    3.1 THE OBJECT CODE, PROGRAM, SOFTWARE AND SOURCE CODE ARE PROVIDED "AS IS" WITHOUT ANY WARRANT OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR USE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE OBJECT CODE, PROGRAM, SOFTWARE AND SOURCE CODE IS WITH YOU. SHOULD THE OBJECT CODE, PROGRAM, SOFTWARE AND SOURCE CODE PROVE DEFECTIVE, YOU ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

    4.0 LIMITATION OF DAMAGES

    4.1 IN NO EVENT WILL THE COPYRIGHT HOLDER OR ANY OTHER PERSON OR ENTITY BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING ANY LOST PROFITS, LOST SAVINGS, COMPENSATORY, GENERAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR THE INABILITY TO USE THE OBJECT CODE, PROGRAM, SOFTWARE AND SOURCE CODE, EVEN IF THE COPYRIGHT HOLDER OR ANY OTHER PERSON OR ENTITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.

    5.0 MISCELLANEOUS

    5.1 The article and paragraph headings appearing in this General Software License Agreement have been asserted for the purpose of convenience and ready reference. They do not purport to, and shall not be deemed to define, limit, or extend the scope or intent of the articles and paragraphs to which they pertain.

    5.2 This General Software License Agreement embodies the entire agreement respecting its subject matter. There are no promises, terms, conditions or obligations other than those expressly set forth herein. Unless otherwise expressly set forth herein, this General Software License Agreement supersedes all previous communications, representations, agreements, either verbal or written, warranties, promises, covenants or undertakings. 5.3 This General Software License Agreement shall not be modified, altered, amended or supplemented, except in writing signed by all parties hereto.

    5.4 This General Software License Agreement shall be governed by the laws of the State of New Jersey.

    Functions

    Obsolete functions

    The below functions are now considered obsolete. At some point in future releases of FreeUDFLib, they will no longer exist.

    When a developer has a convincing argument as to why FreeUDFLib should continue to include the function, please let me know, and I will consider your argument.

    1. UserMaintenance is not a terribly useful function for adding and deleting users. It asks IB to start the gsec procedure on the server to add users, etc... Instead, the IBPassword function can be used with a direct connection to ISC4.GDB for adding, deleting and modifying users.
    2. FindFirstWord and FindNextWord don't work properly with InterBase, as they would be used with the assumption that 1 connection = 1 thread, but this is simply not the case. In a multi-user environment, FindFirstWord will always be correct, but FindNextWord could possibly return some whacky results.
    3. FindNthWord is not a terribly efficient method for picking words up out of a string. For FindFirstWord, FindNextWord and FindNthWord, you should now use the functions: FindWord and FindWordIndex.
    4. Strip is a very confusing function to use. (It's hard to read). Start using the function StripString instead.

    List of functions

    Below is a list of all available routines. When appropriate, addition documentation will be provided. [This section is not complete, as the user can tell]

    String routines

    function FindFirstToken(st: String; TokenChars: TCharSet;
      TokenCharsInToken: Boolean): String;
    function FindNextToken(st: String; TokenChars: TCharSet;
      TokenCharsInToken: Boolean): String;
    function FindTokenStartingAt(st: String; var i: Integer;
      TokenChars: TCharSet; TokenCharsInToken: Boolean): String;
    function Left(sz: PChar; var Number: Integer): PChar; cdecl; export;
    function lrTrim(sz: PChar): PChar; cdecl; export;
    function lTrim(sz: PChar): PChar; cdecl; export;
    function Mid(sz: PChar; var Start, Number: Integer): PChar; cdecl; export;
    function PadLeft(sz, szPadString: PChar; var Len: Integer): PChar; cdecl; export;
    function PadRight(sz, szPadString: PChar; var Len: Integer): PChar; cdecl; export;
    function ProperCase(sz: PChar): PChar; cdecl; export;
    { Queue functions - not really done are they? }
    function QPushQueue(szQ: PChar; var MaxQLength: Integer;
      szEntry: PChar): PChar; cdecl; export;
    function Right(sz: PChar; var Number: Integer): PChar; cdecl; export;
    function rTrim(sz: PChar): PChar; cdecl; export;
    function StringLength(sz: PChar): Integer; cdecl; export;
    { Strip all non-alpha-numerics from string, and remove all whitespace.
      Exclude (from being stripped) all chars in exc_list, and include all
      chars in inc_list:
    
      for example
        Strip('HELLO 12$Mama', '$', '12') = 'HELLO$Mama' }
    function Strip(sz, exc_list, inc_list: PChar): PChar; cdecl; export;
    function StripString(sz, szCharsToStrip: PChar): PChar; cdecl; export;
    function SubStr(szSubStr, szStr: PChar): Integer; cdecl; export;
    
    {* ************************************************************************** *}
    {* Some nice "data formatting routines"                                       *}
    {* ************************************************************************** *}
    {* Format a "name"                                                            *}
    {* ************************************************************************** *}
    function GenerateFormattedName(szFormatString, szNamePrefix, szFirstName,
      szMiddleInitial, szLastName, szNameSuffix: PChar): PChar; cdecl; export;
    function InternalGenerateFormattedName(strFormatString: String;
      var strResult: String; strNamePrefix, strFirstName, strMiddleInitial,
      strLastName, strNameSuffix: String): Boolean;
    function ValidateNameFormat(szFormatString: PChar): Integer; cdecl; export;
    
    {* ************************************************************************** *}
    {* Regular expressions!                                                       *}
    {*     declared but not implemented yet....                                   *}
    {* ************************************************************************** *}
    function ValidateRegularExpression(sz: PChar): Integer; cdecl; export;
    function ValidateStringInRE(sz, re: PChar): Integer; cdecl; export;
    

    Blob routines

    function BlobMaxSegmentLength(Blob: PBlob): Integer; cdecl; export;
    function BlobSegmentCount(Blob: PBlob): Integer; cdecl; export;
    function BlobSize(Blob: PBlob): Integer; cdecl; export;
    // String-ish functions
    {* Obviously, these functions should be used with care, and only when you are
       confident that your blob is not overly large.
       Since varchars can go all the way to 32767 (I think), I find
       Blobs to be somewhat useless as containers for large strings, but
       here are some functions to do it anyways... }
    function BlobAsPChar(Blob: PBlob): PChar; cdecl; export;
    function BlobLeft(Blob: PBlob; var Number: Integer): PChar; cdecl; export;
    function BlobLine(Blob: PBlob; var Number: Integer): PChar; cdecl; export;
    function BlobMid(Blob: PBlob; var Start, Number: Integer): PChar; cdecl; export;
    function BlobRight(Blob: PBlob; var Number: Integer): PChar; cdecl; export;
    function StrBlob(sz: PChar; Blob: PBlob): PBlob; cdecl; export;
    

    Miscellaneous routines

    function CloseDebuggerOutput: Integer; cdecl; export;
    function Debug(szDebuggerOutput: PChar): Integer; cdecl; export;
    (* What is the current result value stored in ThreadLocals.UDFString? *)
    function GetCurrentResultValue: PChar; cdecl; export;
    (* Return what IB THINKS is the temp path *)
    function IBTempPath: PChar; cdecl; export;
    function SetDebuggerOutput(szOutputFile: PChar): Integer; cdecl; export;
    function ValidateCycleExpression(szCycleExpression: PChar;
      var ExprStart: Integer): Integer; cdecl; export;
    function EvaluateCycleExpression(szCycleExpression: PChar;
      var ExprStart: Integer; OldDate, NewDate: PISC_QUAD;
      var Amount: Double): Integer; cdecl; export;
    function EvaluateExpression(szExpr: PChar;
      szSymbols: PChar): PChar; cdecl; export;
    

    Math routines

    function DollarVal(var Value: Double): PChar; cdecl; export;
    function FixedPoint(var Value: Double; var DecimalPlaces: Integer): PChar; cdecl; export;
    function Modulo(var Numerator, Denominator: Integer): Integer; cdecl; export;
    function IsDivisibleBy(var Numerator, Denominator: Integer): Integer; cdecl; export;
    function RoundFloat(var Value, RoundToNearest: Double): Double; cdecl; export;
    function Truncate(var Value: Double): Integer; cdecl; export;
    

    Date/Time routines

    function AddMonth(ib_date: PISC_QUAD;
      var months_to_add: Integer): PISC_QUAD; cdecl; export;
    function AddYear(ib_date: PISC_QUAD;
      var years_to_add: Integer): PISC_QUAD; cdecl; export;
    function AgeInDays(ib_date,
      ib_date_reference: PISC_QUAD): integer; cdecl; export;
    function AgeInDaysThreshold(ib_date, ib_date_reference: PISC_QUAD;
      var Min, UseMin, Max, UseMax: Integer): integer; cdecl; export;
    function AgeInMonths(ib_date,
      ib_date_reference: PISC_QUAD): integer; cdecl; export;
    function AgeInMonthsThreshold(ib_date, ib_date_reference: PISC_QUAD;
      var Min, UseMin, Max, UseMax: Integer): integer; cdecl; export;
    function AgeInWeeks(ib_date,
      ib_date_reference: PISC_QUAD): integer; cdecl; export;
    function AgeInWeeksThreshold(ib_date, ib_date_reference: PISC_QUAD;
      var Min, UseMin, Max, UseMax: Integer): integer; cdecl; export;
    function CDOWLong(ib_date: PISC_QUAD): PChar; cdecl; export;
    function CDOWShort(ib_date: PISC_QUAD): PChar; cdecl; export;
    function CMonthLong(ib_date: PISC_QUAD): PChar; cdecl; export;
    function CMonthShort(ib_date: PISC_QUAD): PChar; cdecl; export;
    function DayOfMonth(ib_date: PISC_QUAD): integer; cdecl; export;
    function DayOfWeek(ib_date: PISC_QUAD): integer; cdecl; export;
    function DayOfYear(ib_date: PISC_QUAD): integer; cdecl; export;
    function IsLeapYear(year: Integer): integer; cdecl; export;
    function MaxDate(ib_d1, ib_d2: PISC_QUAD): PISC_QUAD; cdecl; export;
    function MinDate(ib_d1, ib_d2: PISC_QUAD): PISC_QUAD; cdecl; export;
    function Month(ib_date: PISC_QUAD): integer; cdecl; export;
    function Quarter(ib_date: PISC_QUAD): integer; cdecl; export;
    function StripDate(ib_date: PISC_QUAD): PISC_QUAD; cdecl; export;
    function StripTime(ib_date: PISC_QUAD): PISC_QUAD; cdecl; export;
    function WeekOfYear(ib_date: PISC_QUAD): integer; cdecl; export;
    function WOY(ib_date: PISC_QUAD): PChar; cdecl; export;
    function Year(ib_date: PISC_QUAD):  integer; cdecl; export;
    function YearOfYear(ib_date: PISC_QUAD): integer; cdecl; export;
    

    User maintenance routines

    function IBPassword(pInStr: PChar): PChar; cdecl; export;
    function UserMaintenance(username, password, sysuname, syspword,
                                       action: PChar): Integer; cdecl;
    

    About the author

    Gregory Deatz is a senior programmer/analyst at Hoagland, Longo, Moran, Dunst & Doukas, a law firm in New Brunswick, NJ. His current focus is in legal billing and case management applications. He is the author of FreeUDFLib, a free UDF library for InterBase written entirely in Delphi, and FreeIBComponents, a set of native InterBase components for use with Delphi 3.0. Both of these tools can be found at at InterBase Corporation. He can be reached via e-mail at gdeatz@hlmdd.com, by voice at (732) 545-4717, or by fax at (732) 545-4579.


    This document was generated on 27 March 1998 using the texi2html translator version 1.51a.