Sunteți pe pagina 1din 517

AutoCAD 14

R E L E A S E

Visual LISP
Guide

April 23, 1998

Copyright 1998 Autodesk, Inc.


All Rights Reserved
This publication, or parts thereof, may not be reproduced in any form, by any method, for any purpose.
AUTODESK, INC. MAKES NO WARRANTY, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, REGARDING THESE MATERIALS AND MAKES
SUCH MATERIALS AVAILABLE SOLELY ON AN AS-IS BASIS.
IN NO EVENT SHALL AUTODESK, INC. BE LIABLE TO ANYONE FOR SPECIAL, COLLATERAL, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES IN CONNECTION WITH OR ARISING OUT OF PURCHASE OR USE OF THESE MATERIALS. THE SOLE AND EXCLUSIVE
LIABILITY TO AUTODESK, INC., REGARDLESS OF THE FORM OF ACTION, SHALL NOT EXCEED THE PURCHASE PRICE OF THE
MATERIALS DESCRIBED HEREIN.
Autodesk, Inc. reserves the right to revise and improve its products as it sees fit. This publication describes the state of this product at
the time of its publication, and may not reflect the product at all times in the future.

Autodesk Trademarks
The following are registered trademarks of Autodesk, Inc., in the USA and/or other countries: 3D Plan, 3D Props, 3D Studio, 3D Studio
MAX, 3DSurfer, ADCADD, ADE, ADI, Advanced Modeling Extension, AEC AUTHORITY, AEC-X, AME, Animator Pro, Animator Studio,
ATC, Auto-Architect, AutoCAD, AutoCAD Data Extension, AutoCAD Development System, AutoCAD LT, AutoCAD Map, Autodesk,
Autodesk Animator, the Autodesk logo, Autodesk University, Autodesk View, AutoLISP, AutoShade, AutoSketch, AutoSolid, AutoSurf,
AutoVision, CAD OVERLAY, DesignBlocks, Design Companion, DRAFIX, Education by Design, Generic, Generic CADD, Generic Software,
Generic 3D Drafting, Geodyssey, Heidi, HOOPS, Inside Track, Kinetix, MaterialSpec, Mechanical Desktop, Multimedia Explorer, NAAUG,
Office Series, Opus, Picture This Home!, PLANIX, RASTATION, Softdesk (goods), Softdesk (services), Solution 3000, STAR DESIGN,
TECHTALK, Texture Universe, THE AEC AUTHORITY, THE AUTO ARCHITECT, TinkerTech, WHIP!, Woodbourne, WorkCenter, and WorldCreating Toolkit.
The following are trademarks of Autodesk, Inc., in the USA and/or other countries: 3D for the PC, 3D Studio VIZ, ACAD, Advanced User
Interface, AEC Office, AME Link, Animation Partner, Animation Player, Animation Pro Player, A Studio in Every Computer, ATLAST,
Auto-Architect, AUGI, AutoCAD Learning Assistance, AutoCAD LT Learning Assistance, AutoCAD Simulator, AutoCAD SQL Extension,
AutoCAD SQL Interface, AutoCDM, Autodesk Animator Clips, Autodesk Animator Theatre, Autodesk Device Interface, Autodesk
MapGuide, Autodesk PhotoEDIT, Autodesk Software Developers Kit, Autodesk View DwgX, Autodesk WalkThrough, Autodesk World,
AutoEDM, AutoFlix, AutoLathe, AutoSnap, Biped, bringing information down to earth, Built with ObjectARX, Carpe Datum, Character
Studio, Concept Studio, Content Explorer, cornerStone Toolkit, DESIGNX, DesignScape, Designers Vision, Design Your World, DXF,
DWG Unplugged, Exegis, FLI, FLIC, GDX Driver, Generic 3D, Home Series, HyperWire, MAX DWG, Multiped, NetHead, ObjectARX,
ObjectDXF, Octoped, PeopleTracker, PHOTO LANDSCAPE, PHOTOSCAPE, Physique, PolarSnap, Power and Light, Powered with
Autodesk Technology, Quadruped, QuickCAD, RadioRay, SchoolBox, SketchTools, Smoke and Mirrors, Suddenly Everything Clicks,
Supportdesk, Total House, Transforms Ideas Into Reality, and Visual LISP.

Third Party Trademarks


Microsoft, Visual Basic, and Windows are registered trademarks, and ActiveX, Windows NT, and Windows 95 are trademarks of Microsoft
Corporation. Delphi is a trademark of Borland International. All other brand names, product names or trademarks belong to their
respective holders.

GOVERNMENT USE
Use, duplication, or disclosure by the U. S. Government is subject to restrictions as set forth in FAR 12.212 (Commercial Computer
Software-Restricted Rights) and DFAR 267.7202 (Rights in Technical Data and Computer Software), as applicable.

Contents - Visual LISP Guide

Contents - Visual LISP Guide iv


Introduction 14
AutoLISP and Visual LISP 15
AutoLISP 15
Visual LISP 15
What Visual LISP Offers 15
Working With Visual LISP and AutoCAD 16
How This Guide is Organized 17
Recommendations on Using This Guide 17
First: Read Chapter 1 18
Next: Are You Ready for the Tutorial, or...?
Using the Heart of the Manual 18
Document Conventions 19
Chapter 1

Quick Tour

18

22

Getting Started 23
Before You Begin 23
Starting Visual LISP 23
Overview of the Visual LISP User Interface 24
The Visual LISP Text Editor 25
Other Visual LISP Windows 26
Menu Overview 26
Variable Menu Contents 26
Menu Summary 27
The Console 28
Text Editor Overview 29
Loading and Running AutoLISP Programs 30
Running Selected Lines of Code 32
Exiting the Visual LISP Environment 32

iv

Chapter 2

AutoLISP Basics

34

AutoLISP Expressions 35
AutoLISP Data Types 36
Integers 36
Reals 36
Strings 37
Lists 37
Selection Sets 37
Entity Names 38
VLA Objects 38
File Descriptors 38
Symbols and Variables 39
AutoLISP Function Syntax 39
AutoLISP Program Files 40
Formatting AutoLISP Code 40
Spaces in AutoLISP Code 41
Comments 41
Visual LISP Comment Styles 42
Color Coding 42
AutoLISP Variables 42
Displaying the Value of a Variable 43
Nil Variables 43
Predefined Variables 44
Number Handling 44
String Handling 45
Basic Output Functions 47
Displaying Messages 48
Exiting Quietly 48
Control Characters in Strings 49
Wild-Card Matching 50
Equality and Conditional 52
List Handling 52
Point Lists 54
Dotted Pairs 56
Symbol and Function Handling 57
C:XXX Functions 58
Adding Commands 60
Redefining AutoCAD Commands 60
Local Variables in Functions 62
Local Variables Versus Global Variables
Example Using Local Variables 63
Functions with Arguments 64

Contents

62

Chapter 3

Using AutoLISP to
Communicate with
AutoCAD 66
Query and Command Functions 67
Command Submission 67
Foreign-Language Support 68
Pausing for User Input 68
Passing Pick Points to AutoCAD Commands 69
System and Environment Variables 69
Configuration Control 70
Display Control 70
Controlling Menus 70
Control of Graphics and Text Windows 73
Control of Low-level Graphics 74
Getting User Input 74
The getxxx Functions 75
Control of User-Input Function Conditions 77
Input Options for User-Input Functions 77
Key Word Options 78
Arbitrary Keyboard Input 79
Input Validation 79
Geometric Utilities 80
Object Snap 80
Text Extents 81
Conversions 84
String Conversions 85
Angular Conversion 87
ASCII Code Conversion 88
Unit Conversion 89
Converting from Inches to Meters 90
The Unit Definition File 90
Coordinate System Transformations 92
Point Transformations 94
File Handling 95
File Search 95
Accessing Help Files 96
Device Access and Control 97
Accessing User Input 97
Calibrating Tablets 98

Chapter 4

Using AutoLISP to
Manipulate AutoCAD
Objects 102
Selection Set Handling 103

Contents

vi

Selection Set Filter Lists 105


Wild-Card Patterns in Filter Lists 107
Filtering for Extended Data 107
Relational Tests 107
Logical Grouping of Filter Tests 108
Selection Set Manipulation 109
Passing Selection Sets Between AutoLISP and ObjectARX
Applications 110
Object Handling 111
Entity Name Functions 111
Entity Handles and Their Uses 112
Entity Context and Coordinate Transform Data 113
Entity Access Functions 116
Entity Data Functions 116
Working with Blocks 120
Anonymous Blocks 120
Creating Complex Entities 121
Entity Data Functions and the Graphics Screen 123
Polylines and Lwpolylines 123
Processing Curve-Fit and Spline-Fit Polylines 124
Nongraphic Object Handling 124
Symbol Table Objects 125
Dictionary Objects 126
Extended DataXdata 126
Organization of Extended Data 127
Registration of an Application 130
Retrieval of Extended Data 130
Attachment of Extended Data to an Entity 131
Management of Extended Data Memory Use 132
Handles in Extended Data 132
Xrecord Objects 134
Symbol Table and Dictionary Access 134
Symbol Tables 135
Dictionary Entries 137
Accessing AutoCAD Groups 137
Chapter 5

Developing Programs
With Visual LISP 138
Getting Organized 139
The System Console 139
System Console Behavior 140
The System Console Context Menu 141
Separators Processing 142
Color Coding of Console Input 143

Contents

vii

Context-Sensitive Help for Visual LISP Functions 143


Logging Console Activity 143
Accessing Native AutoLISP from Visual LISP 144
Bouncing Between AutoCAD and Visual LISP 145
Using the Text Editor 145
Working with Files 145
Entering Text 146
Undoing the Last Change You Made 146
Saving Your Changes 147
Automatic Backup Files 147
Editing an Existing File 147
Color Coding 148
Context-Sensitive Help for Functions 149
The Text Editor Context Menu 149
Words in the Visual LISP Text Editor 150
Text Editor Shortcuts 151
Complete Word by Match 151
Complete Word by Apropos 151
Formatting Shortcut Keys 154
Navigation Shortcuts 155
Text Correction Shortcuts 155
Text Selection Shortcuts 156
Moving and Copying Text 157
Indenting Text 157
Searching for Text 158
Replacing Text 160
Bookmarking Text 160
Formatting Code with the Visual LISP Formatter 162
Running the Formatter 162
Visual LISP Formatting Fundamentals 163
Basic Formatting Styles 163
Additional Formatting Options 165
Comment Styles 170
Indentation Rules 171
Saving and Restoring Formatting Options 171
Formatter Restrictions 171
Checking for Syntax Errors 172
Checking the Balance of Parentheses 172
Using Color Coding to Detect Syntax Errors 173
Using the Check Command to Look for Syntax Errors
Running Your Program 175
Chapter 6

174

Debugging Programs 176


Debugging in Visual LISP 177

Contents

viii

Debugging Example 178


Setting a Breakpoint to Interrupt Program Execution 178
Stepping Through the Program 179
Tracing the Evaluation Results of an Expression 181
Tracing Variables During Program Execution 182
Continuing Program Execution 183
Debugging Features 183
Starting Debugging 184
The Break Loop 184
Continuable Break Loops 185
Non-continuable Break Loops 186
Breakpoints 186
Setting and Deleting Breakpoints 186
Disabling Breakpoints 187
Listing and Viewing the Breakpoints in Your Program 188
Life Cycle of a Breakpoint 188
Visual LISP Data Inspection Tools 189
The Watch Window 190
Adding a Variable to the Watch Window 190
Watch Toolbar 191
Using the Watch Item Context Menu 191
The Trace Stack Window 193
Stack Element Lists 194
Viewing the Current Trace Stack 195
Displaying Information on a Trace Stack Element 195
Frame Binding Window 196
Keyword Frames 196
Special Function Call Frames 198
Viewing an Error Trace Stack 198
Trace Stack Toolbar 199
The Symbol Service Dialog 199
Symbol Service Toolbar 200
Symbol Flags 201
Inspector Windows 201
Inspector Dialog Box 202
Object Element List Formats 202
Opening an Inspector Dialog 203
Handling Errors in the Inspect Command 203
Closing all Inspector Dialogs 204
Common Inspector Commands 204
Specific AutoLISP Datatype Inspectors 205
Viewing AutoCAD Drawing Entities 208
Viewing Entities in the Drawing Database 208
Viewing Tables in the Drawing Database 210
Viewing Blocks in the Drawing Database 211

Contents

ix

Viewing Selected Objects in a Drawing 211


Viewing Extended Data 212
Chapter 7

Building Applications

214

Compiling and Linking Programs 215


How to Use the Compiler 215
Compiling a Program from a File 216
Choosing a Compiler Mode 216
Identifying the Input File 216
Naming an Output File 217
Walking Through a Compile Example 218
Loading and Running a Compiled Program 218
Linking Function Calls 219
Building Stand-alone Applications 219
Making Functions Known to AutoCAD 220
Explicitly Exporting Function Names to AutoCAD 220
Implicitly Exporting Function Names to AutoCAD 221
Identifying Functions Defined in External Applications 221
Using the Visual LISP Run-Time System 223
Shipping the RTS With Your Application 224
Loading the Visual LISP RTS 224
Initializing the Run-time System 224
Using a Start-Up File 225
Functions Defined by the Sample Start-Up File 225
Using the RTS and Native AutoLISP Environments
Concurrently 227
Controlling the Verbosity of RTS Initialization 228
Partial Reinitialization at AutoCAD New/Open Commands 228
Making Application Modules 228
Using the Application Wizard 229
Starting the Application Wizard 230
Wizard Step 1: Choosing an Application Type 230
Wizard Step 2: Naming the Executable File 231
Wizard Step 3: Identifying the Load Method 232
Wizard Step 4: Identifying the Program Files 233
Wizard Step 5: Identifying Dialog Control (DCL) Files 234
Wizard Step 6: Defining External Functions 235
Wizard Step 7: Setting Initialization Options 236
Wizard Step 8: Making the Application 238
Understanding the Output from the Make Application 239
Loading and Running Applications 240
Loading and Running an ARX Application 240
Loading and Running a VLX Application 242
Rebuilding an Application 242

Contents

Using the Application Wizard to Rebuild an Application 242


Rebuilding an Application from Its Make File 242
Chapter 8

Maintaining Visual LISP Applications

244

Managing Multiple LISP Files 245


Introducing Visual LISP Projects 245
LSP, FAS and other File Types 245
Defining a Project 247
Assigning Project Properties 248
Selecting the Files to Include in a Project 248
Changing the Order in Which Visual LISP Loads Files 251
Choosing Compiler Build Options 251
Using the Project Window to Work with Project Files 252
Selecting Multiple Project Members 254
Loading Project Files 254
Compiling and Recompiling Project Files 255
Editing Project Files 255
Saving and Closing the Project 256
Working With Existing Projects 256
Opening a Project 256
Finding a String in Project Source Files 257
Making an Application from a Project 258
Optimizing Application Code 260
Defining Build Options 260
Choosing a Compilation Mode 261
Analyzing for Optimization Correctness 262
Understanding Project Build Options 263
Link Mode 263
Dropping Functions 263
Localizing Variables 264
Safe Optimization 264
Compiler Checking of Optimizing Conditions 266
Chapter 9

Advanced Topics

268

Using ActiveX Objects with Visual LISP 269


Understanding the AutoCAD Object Model 270
Object Properties 270
Object Methods 271
Collections of Objects 271
Accessing AutoCAD Objects 271
Using the Inspect Tool to View Object Properties 272
Moving Forward From the Application Object 273
Summarizing the Process 274

Contents

xi

Using Visual LISP Functions with ActiveX Methods 275


Determining the Visual LISP Function You Need 275
Determining How to Call a Function 276
Translating Visual Basic Arguments to Visual LISP
Arguments 278
Viewing and Updating Object Properties 279
Determining If an Object Can be Accessed 281
Using ActiveX Methods That Return Values in Arguments 282
Listing an Objects Properties and Methods 283
Determining if a Method or Property Applies to an Object 283
Working With Collection Objects 284
Retrieving Member Objects in a Collection 287
Converting Arguments 287
Releasing Objects and Freeing Memory 288
Converting Object References 288
Attaching Reactors to AutoCAD Drawings 290
Reactor Types and Events 290
Defining Callback Functions 291
Defining Linker, Editor, and Database Reactors 292
Defining Object Reactor Callback Functions 292
Using Predefined Callback Functions 292
Creating Reactors 292
Using Object Reactors 294
Querying, Modifying and Removing Reactors 296
Inspecting Reactors 296
Querying Reactors Using Function Calls 297
Modifying Reactors 298
Disabling Reactors 299
Transient versus Persistent Reactors 300
Appendix A

AutoLISP
Function Reference 302
Selection Set Filters 422
Relational Tests 422
Logical Grouping of Filter Tests

424

Contents

xii

Contents

xiii

Introduction

In this chapter
For years, AutoLISP has set the standard for customizing

AutoLISP and Visual


LISP

CAD. Visual LISP represents the next generation of LISP for

Working with Visual


LISP and AutoCAD

How this Guide is


Organized

Recommendations on
Using this Guide

Document Conventions

AutoCAD. Visual LISP now adds significantly more capabilities to AutoLISP for AutoCAD. It extends the language to

interface with objects via the Microsoft ActiveX Automation interface, and adds the ability to have AutoLISP
respond to events via object reactors. As a development
tool, Visual LISP provides a complete integrated development environment (IDE), including a compiler, debugger,
and other tools to increase productivity in rapidly customizing AutoCAD.

14

AutoLISP and Visual LISP


AutoLISP
AutoLISP is a programming language designed for extending and customizing AutoCAD functionality. It is based on the LISP programming language,
whose origins date back to the late 1950s. LISP was originally designed for use
in Artificial Intelligence (AI) applications, and is still the basis of many AI
applications.
AutoCAD introduced AutoLISP as an application programming interface
(API) in release 2.1, in the mid-1980s. LISP was chosen as the initial AutoCAD
API because it was uniquely suited for the unstructured design process of
CAD projects, which involves iteratively trying different solutions to a problem.

Visual LISP
Visual LISP(VLISP) is a software tool designed to expedite AutoLISP program
development. VLISPs integrated development environment provides features to help ease the tasks of source-code creation and modification, program testing, and debugging. In addition, VLISP provides a vehicle for delivering stand-alone ObjectARX applications written in AutoLISP.
In the past, developing AutoLISP programs for AutoCAD meant working with
some text editor (which you had to provide) to write your code, then loading
the code into AutoCAD and running it. Debugging your program meant adding statements to print the contents of variables at strategic points in your
program. You had to figure out what were good points in your program to do
this, and what variables you needed to look at. If you discovered you still
didnt have enough information to determine the error, you had to go back
and change the code again, adding more debugging points. And finally,
when you got the program to work correctly, you needed to either comment
out or remove the debugging code you added.

What Visual LISP Offers


During the development cycle of an AutoLISP application or routine, the
AutoLISP user performs a number of operations which are not available
within the AutoCAD software. Some of these operations, like text editing, are
available with other software tools. Others, such as full AutoLISP source-level
debugging, are introduced only with Visual LISP. With Visual LISP the user
can perform most of the necessary operations inside the single environment,

Introduction

15

which permits text editing, program debugging, and interaction with


AutoCAD and other applications.
Visual LISP is an integrated development environment (IDE) that combines
several functional components to support major user requirements during
the development cycle of AutoLISP programs. These components include:

Complete AutoLISP emulation with transparent compile-during-load


technology
A Syntax Checker that recognizes erroneous AutoLISP constructs and
improper arguments in calls to built-in functions
A File Compiler that improves the execution speed and provides a secure
and efficient delivery platform
A source debugger, designed specifically for AutoLISP, that provides maximum flexibility through a powerful break loop. This feature also supports
stepping through AutoLISP source code in one window while simultaneously displaying the code effect in an AutoCAD drawing window
Text file editing with AutoLISP and DCL color coding, as well as other
AutoLISP syntax support features
An AutoLISP Formatter to restructure programs into an easily readable format
Comprehensive Inspector and Watch facilities that provide convenient
access to variable and expression values for data structure browsing and
modification. These features may be used to explore AutoLISP data and
AutoCAD drawing entities
Context sensitive help for AutoLISP functions and a powerful Apropos feature for symbol name search
A Project Management system that makes it easy to maintain multiple-file
applications
Packaging of compiled AutoLISP files into a single ADS or ARX module
Desktop Save/Restore capabilities to preserve and reuse the windowing
environment from any Visual LISP session
An intelligent System Console that introduces a new level of convenience
and efficiency for AutoLISP users. The basic functions of the Console correspond to the AutoCAD Text Screen functions and provide a number of
interactive features, such as history scrolling and full-input line editing

Working With Visual LISP and AutoCAD


Visual LISP is an integrated development environment for developing and
running AutoLISP code. It contains its own set of windows and menus, distinct from AutoCAD. But Visual LISP does not run independently of
AutoCAD. Whenever you work in Visual LISP, AutoCAD must be running as
well. And when you run AutoLISP programs from the Visual LISP environ-

AutoLISP and Visual LISP

16

ment, you will need to interact with AutoCAD in order to work with graphics
and, in some instances, to respond to prompts for input.
TIP
LISP.

Keep AutoCAD open on your desktop whenever you work with Visual

If AutoCAD is minimized when Visual LISP turns control over to it, you have
to manually restore and activate the AutoCAD window in order to continue.
Visual LISP will not restore the AutoCAD window for you. Instead, the following symbol appears in the Visual LISP window

and remains there until you activate AutoCAD and respond to the prompts
at the AutoCAD Command prompt. The Quick Tour chapter shows an
example of this; see Loading and Running AutoLISP Programs on page 30.

How This Guide is Organized


The Visual LISP Guide explains how to use the Visual LISP interactive development environment, and how to build and run Visual LISP applications.
The Guide also introduces the constructs of the AutoLISP language.
This manual assumes that you have some experience with AutoCAD and
have basic user-level skills with Microsoft Windows. Prior experience with
AutoLISP is not required, but will make your learning curve much smoother.
The Visual LISP Guide is divided into 3 sections:

Part 1: Visual LISP and AutoLISP Guide.


This is the core section of the manual, which details the use of Visual LISP
and AutoLISP.

Part 2: Tutorial: Creating a Garden Path.


This section contains step-by-step instructions guiding you toward building a working Visual LISP application.

Part 3: Function Reference.


The Function Reference defines and briefly describes every AutoLISP and
Visual LISP function.

Recommendations on Using This Guide


This is a big book, and you are not expected to read it from beginning to end.
Well, not in one sitting, anyway. Part 3 is a reference section, and is meant to

Introduction

17

be referred to when you need to look up the syntax of a function, or what


that function returns. You can also browse the Function Reference to search
for a function that meets a particular programming need.
For Part 1 and Part 2 of the Visual LISP Guide, here are some guidelines to
help you get the most out of the documentation.

First: Read Chapter 1


All readers should begin by reading Chapter 1, Quick Tour. This chapter
gets you started using Visual LISP by telling you how to invoke it from
AutoCAD, what youll see when Visual LISP first starts, and how you can load
and run existing AutoLISP programs from Visual LISP. Chapter 1 introduces
and briefly describes the windows you will be working with in the Visual LISP
IDE. Use this chapter to orient you to the Visual LISP environment.

Next: Are You Ready for the Tutorial, or...?


Part 2 of the Visual LISP Guide is a step-by-step tutorial that guides you to
build a working Visual LISP application.

If you are already familiar with AutoLISP, you may want to go right to the
tutorial after reading Chapter 1. This is a matter of personal comfort: if
you feel you need to understand how everything works before using a
tool, you might be better off reading some or all of chapters 5 through 9
before trying the tutorial. See Using the Heart of the Manual (below) for
a brief description of each chapter.
If you do not already know AutoLISP, read all of Chapter 2, AutoLISP
Basics, and at least browse Chapters 3 and 4 (Using AutoLISP to Communicate with AutoCAD and Using AutoLISP to Manipulate AutoCAD
Objects. After that, you can either work through the tutorial or choose
from the chapters described below.

If youre ready to tackle the tutorial, here is one more word of caution: the
tutorial is somewhat irreverent -- well, for Autodesk, at least.

Using the Heart of the Manual


The heart of the manual is Part 1, Visual LISP and AutoLISP Guide. Here,
chapter by chapter, is how this section is organized:
1 Chapter 1 is the Quick Tour, which everyone should read in order to get
oriented in Visual LISP.
2 Chapter 2, AutoLISP Basics, introduces basic AutoLISP concepts, such as
how to use expressions and variables, handle numbers and strings, display
output, build lists, and define functions.

How This Guide is Organized

18

3 Chapter 3, Using AutoLISP to Communicate with AutoCAD, describes


AutoLISP functions you can use to issue AutoCAD commands and to interact
with users in the AutoCAD environment.
4 Chapter 4, Using AutoLISP to Manipulate AutoCAD Objects, describes
AutoLISP functions you can use to manipulate AutoCAD drawing entities,
selections sets, extended data, and symbol tables.
5 Chapter 5, Developing Programs With Visual LISP, shows you how to use
the Visual LISP text editor to enter AutoLISP program code, format the code,
and check the code for AutoLISP syntax errors. It also shows you how to run
the code youve developed, right from the Visual LISP editor window.
6 Chapter 6, Debugging Programs, shows you how to use Visual LISP to trace
program execution, watch the value of variables change during program execution, see the sequence in which expressions are evaluated, and step
through program execution one instruction at a time.
7 Chapter 7, Building Applications, introduces you to the Visual LISP file
compiler and how you can use the Visual LISP Make Application Wizard to
build stand-alone applications.
8 Chapter 8, Maintaining Visual LISP Applications, describes how to define
Visual LISP projects and use them to simplify working with multi-file applications. This chapter also explains the Visual LISP compilers optimization
features, and how to use them with a project.
9 Chapter 9, Advanced Topics, describes how to use ActiveXobjects with
Visual LISP, and how to attach reactors to AutoCAD drawings and objects.

Document Conventions
This document follows a number of stylistic and naming conventions when
describing actions or defining terms. Often, distinct typefaces are used to distinguish items from the rest of the text. The following table lists some of the
conventions used in the Visual LISP Guide:
Typographical conventions
Text element

Example

Program code examples are displayed (defun initfunc ( )


in an 8 pt Courier font
(setq *GLOBAL-WARMING* 4.0))
Text you enter is shown in boldface At the Visual LISP prompt, enter shape

Introduction

19

Typographical conventions (continued)


Text element

Example

File names and directory names are Double-click the file name drawline.lsp.
shown in italics, when referred to in a The default install directory is
C:\Program Files\AutoCAD R14\VLISP
sentence
In definitions that include variable
text, the variable is in italics

A FAS file named appname-init.fas, where


appname is the application module name...
(vl-import-exsubrs (app-name {entry-name}))
The function takes a list as an argument. The first
argument is the applications full name. The
entry-name arguments are the application function
names to be defined to Visual LISP.

AutoLISP and Visual LISP variable


names are in courier type

Double-click on any occurrence of the variable name origin-y...


The *LAST-VALUE* system variable...

Use the entget function...


AutoLISP and Visual LISP function
names are shown in bold courier Use VL-IMPORT-EXSUBRS to import...
type in the context of a sentence

Document Conventions

20

Introduction

21

1
Quick Tour

In this chapter

Getting Started

User Interface Overview

Menu Overview

Console Overview

capabilities to LISP for CAD. It extends the language to

Text Editor Overview

interface with objects via the Microsoft ActiveX Automa-

Loading and Running


AutoLISP Programs

Visual LISP represents the next generation of LISP for


AutoCAD. For years, AutoLISP has set the standard for customizing CAD. Visual LISP now adds significantly more

tion interface, and adds the ability to have LISP respond to


events via object reactors. As a development tool, Visual
LISP provides a complete integrated development environment (IDE), including a compiler, debugger, and other tools
to increase productivity in rapidly customizing AutoCAD.

22

Getting Started
Before You Begin
Before you start, note where the Visual LISP program files are installed on
your computer. By default, it installs in a folder named VLISP, as a subdirectory of the AutoCAD install directory. For example:
C:\PROGRAM FILES\AUTOCAD R14\VLISP

If you changed the default when you installed Visual LISP, substitute that
directory path anywhere you see
C:\PROGRAM FILES\AUTOCAD R14\VLISP referenced in this document.

Starting Visual LISP


Visual LISP (VLISP) runs as an ObjectARX application within AutoCAD. To
launch VLISP, start AutoCAD, then do the following:
1 From the AutoCAD menu bar, choose Tools>Load Application...

2 In the Load dialog box, click File...


3 In the file selection window, go to the folder containing your VLISP program
files. Find the file named vlide.arx, and double-click the file name.
By default, the file selection dialog box may list only LSP files when you first display it. If this is the case, you wont see the vlide.arx file listed. You may have to
click in the "Files of type" dropdown list box and select "ARX" in order to list
vlide.arx.
4 In the Load dialog box, if the Save List checkbox does not contain a check
mark, click in the box to select it. The next time you select Load Application

Chapter 1

23

Quick Tour

from the Tools menu, this file name will automatically be listed in the Load
dialog box.
5 Click the Load button to start Visual LISP.
As VLISP loads, one or more VLISP windows display momentarily, then the
AutoCAD window returns.
If the Visual LISP window is not the active window (that is, if AutoCAD is on
top), type vlide in the AutoCAD command area, then press ENTER.

Overview of the Visual LISP User Interface


The first time you start Visual LISP, it displays a screen like the following:
Menu

Toolbars

Console

Status
Bar
The areas shown in the Visual LISP screen are:

Menu. You can issue VLISP commands by selecting from the various
menus items. If you highlight an item on a menu, VLISP displays a brief
description of the commands function in the status bar at the bottom of
the screen.

Overview of the Visual LISP User Interface

24

Toolbars. Click toolbar buttons to quickly issue VLISP commands. There


are 5 toolbars (Debug, Edit, Find, Inspect, and Run), each representing a
distinct functional group of VLISP commands. You can execute many, but
not all, menu commands from the toolbars. If you move your mouse
pointer over a toolbar button and leave it there for a couple of seconds,
VLISP displays a tool tip (label) indicating the function of the button; a
more descriptive explanation appears in the status bar at the bottom of
the VLISP screen.
Console window. This is a separate, scrollable window within the main
Visual LISP window. In the Console window, you can type AutoLISP commands, similar to the way you do in the AutoCAD command window. You
can also issue many Visual LISP commands from this window, instead of
using the menu or toolbars. See The Console on page 28 for more information about the Console.
Status bar. The information displayed in the status bar located at the
bottom of the screen varies according to what you are currently doing in
VLISP.

You may also see a minimized Trace window. At start-up, this window contains informational messages about the current release of Visual LISP, and
may contain additional information if VLISP encounters errors during startup.

The Visual LISP Text Editor


Most of the time spent working in a Visual LISP session will be spent creating
or modifying AutoLISP programs. VLISP comes with an integrated text editor
for you to use when working on AutoLISP code.
To see what the text editor window looks like, open a sample AutoLISP
program. Some sample programs are provided with VLISP. Open the sample
program named drawline.lsp by taking the following steps:
1 From the Visual LISP menu, choose File>Open File...
2 Using the Open File dialog box, go to the \VLISP\Sample folder.
3 Double-click the file name drawline.lsp.
Visual LISP opens the file in a new window, the text editor window, and displays the name of the file in the status bar. If you make a change to text in
the editor, or add new text, VLISP places an asterisk (*) next to the file name
in the status bar. The asterisk remains next to that file name until you either
save your changes or close the file.
You can work on more than one file at a time. Each time you open a file,
VLISP displays the file in a new text editor window.

Chapter 1

25

Quick Tour

Other Visual LISP Windows


Visual LISP displays some output in the Console window, but several VLISP
functions create their own windows in which to display results. For example,
when you are tracing the sequence of events as an AutoLISP program runs,
the Trace function opens a window in which it displays program events. You
cant type in these output windows, but you can copy text from them and
paste the text in the editor or Console window.

Menu Overview
You can issue VLISP commands by selecting from the various menus items.
For example, from the File menu you can create a new AutoLISP program file,
select an existing program file to edit, and print the file youre editing.

Variable Menu Contents


Menu contents may vary depending on which VLISP window (for example,
text editor, Console) is currently active. To activate a different window, click
in the window's title bar, or in any empty area of that window.

Menu Overview

26

As an example, click in the text editor window containing drawline.lsp, then


choose Edit from the Visual LISP menu. Youll see the following list of items:

The last items on the menu are Parentheses Matching and Extra Commands.
Now click in the title bar of the AutoLISP Console window, then select the
Edit menu item again:

Notice that Extra Commands is no longer the last item on the menu.
Parentheses Matching is followed by two new items, Console History Up
and Console History Down; these items apply only to a Console window.

Menu Summary
Here is a brief summary of the contents of each menu item; you will learn
how to use the various menu commands as you proceed to learn Visual LISP:

Chapter 1

27

The File menu allows you to create a new AutoLISP program file for editing, open an existing file, save changes you make to program files, and
print the program file.
The Edit menu allows you to copy and paste text, undo the last change
you made to text (or undo the last command entered in the Console window), select text in the editor or Console windows, match parentheses in

Quick Tour

expressions, and redisplay previous commands youve entered at the Console prompt.
The Search menu allows you to find and replace text strings, set bookmarks, and navigate among bookmarked text. See Developing Programs
With Visual LISP for information on these topics.
The View menu contains commands for finding and displaying the value
of variables and symbols in your AutoLISP code. For more information on
this topic, see Debugging Programs.
The Project menu contains commands for working with projects and
compiling programs.
The Debug menu allows you to set and remove break points in your program, and to step through program execution one expression at a time.
You can then check the state of variables and the results of expressions.
See Debugging Programs.
The Tools menu contains commands for setting Visual LISP options for
text formatting, and for setting various environment options such as the
placement of windows and toolbars.
The Window menu allows you to organize the windows currently displayed in your VLISP session, and to activate another Visual LISP or
AutoCAD window.
The Help menu displays online Help.

The Console
From the Console window, you can enter and run AutoLISP commands and
see the results of those commands. This is similar to what you can do in the
AutoCAD command window, but Visual LISP contains its own distinctive
command interpreter for executing commands. As a result, there are a few
differences -- some subtle -- in how you accomplish the same task in each
interface. For example, to display the current value of an AutoLISP variable
in Visual LISP, you simply type the variable name in the Console window and
press ENTER. To view the value of a variable in AutoCAD, you must precede
the variable name with an exclamation point (!) when you type it in the command window.
The Console is also where Visual LISP displays AutoLISP diagnostic messages
and displays the result of many AutoLISP functions. For example, output
from the print and princ functions are displayed in the Console window.
You can scroll through the Console window to view previously entered text
and output.

The Console

28

In addition to executing AutoLISP commands and displaying messages, the


Visual LISP interpreter supports the many debugging features that are unique
to VLISP.
Here is a brief summary of Console functions:

You can enter an AutoLISP expression for Visual LISP to read, evaluate,
and display the results. If you need more than one line to type your
expression, press CTRL+ENTER to continue it on a second line.
You can enter more than one expression before pressing the ENTER key.
You can copy and transfer text between the Console and the text editor
window. Most text editor commands are also available in the Console.
Pressing the TAB key retrieves the previous command you entered in the
Console. You can press TAB repeatedly to retrieve earlier commands. Pressing SHIFT+TAB key retrieves commands in the opposite direction.
The TAB key lets you perform an associative search in the input history.
For example, if you begin an expression with (+ and then press TAB,
VLISP retrieves the last command you entered that begins with (+. To
reverse the direction of the search, press SHIFT+TAB.
The ESC key clears any text following the Console prompt.
Pressing SHIFT+ESC leaves the text you typed at the Console prompt without interpreting it, and displays a new Console prompt.
Clicking the right mouse button, or pressing SHIFT+F10 anywhere in the
Console window, displays a menu of Visual LISP commands and options.
For example, you can use this feature to copy and paste text in the Console command line, search for text, and initiate VLISP debugging features.

Note that if you type text at the Console prompt, but switch to the AutoCAD
window before pressing ENTER, the text is lost from the prompt when you
return to the Visual LISP window.

Text Editor Overview


The Visual LISP text editor is much more than a writing tool: its a central
component of the Visual LISP programming environment. To appreciate the
versatility and value of the VLISP editor, you need to be familiar with the
AutoLISP language.If you are not familiar with AutoLISP yet, you can learn
the basics in the AutoLISP Basics chapter, and find additional information
in the Using AutoLISP to Communicate with AutoCAD and Using
AutoLISP to Manipulate AutoCAD Objects chapters.
Here is a list of some major features of the text editor:

Chapter 1

29

Quick Tour

Color Coding. The editor identifies different parts of an AutoLISP program and assigns distinct colors to them. This allows you to easily find
program components such as function calls and variable names, and can
help you find typographical errors.
Text Formatting. The editor can format AutoLISP code for you, making
it easier to read. You can choose from a number of different formatting
styles.
Parenthesis Matching. AutoLISP code contains many parentheses. The
editor can help you find the close parenthesis that goes with an open
parenthesis, and help you detect missing parentheses.
Execution of AutoLISP Expressions. You can test expressions and
lines of code without leaving the text editor.
Searching Through Multiple Files. You can search for a word or
expression in several files with a single command.
Syntax Checking. You can use Visual LISP syntax-checking features
from within the editor.

Details on using the Visual LISP text editor are in Developing Programs With
Visual LISP.

Loading and Running AutoLISP Programs


Once youve opened an AutoLISP program file in Visual LISPs text editor,
you can load and run it. Loading is the process whereby text in a file is made
available to VLISPs command interpreter.
1 To load text from an editor window, first make sure that the window is active.
If youre not sure, click anywhere in the window to activate it. Try this with
the drawline.lsp sample program.
2 After activating the editor window, click the Load Buffer button in the Run
toolbar, or choose Tools>Load Text in Editor from the Visual LISP menu.
Visual LISP responds by displaying a message in the Console window indicating that it has loaded the program.
3 Once loaded, you can run the program from the Console command line by
typing the program name in parentheses:

and then pressing the ENTER key.

Loading and Running AutoLISP Programs

30

The drawline program doesnt do much: it asks you to specify two points in
an AutoCAD graphics window, and then it draws a straight line between
those points.
Because drawline asks for user input, Visual LISP turns control over to
AutoCAD, where you have the option of specifying points in the graphics
window or the command line. What you see next depends on whether or not
the AutoCAD windows are currently displayed on your desktop. If they are,
youll see the AutoCAD windows. But if AutoCAD is currently minimized on
your desktop, it wont automatically be restored and displayed. Instead,
Visual LISP will remain visible and your mouse pointer will change to the following icon:

This indicates that the Visual LISP window is no longer active. If this is the
case, you need to manually switch to the AutoCAD window. Click the
AutoCAD icon on the Windows task bar to activate AutoCAD.
Notice that prompts for input are displayed in the AutoCAD command window:

4 After you respond to all the prompts, control returns to Visual LISP and youll
once again see the VLISP window.
When you enter commands in the Visual LISP Console or run a program
loaded from the text editor, you may frequently be switching back and forth
between the Visual LISP and AutoCAD windows. Besides using the standard
Windows methods of switching between applications, you have a couple of
alternate methods of switching between Visual LISP and AutoCAD windows:

Chapter 1

31

From Visual LISP, you can activate the AutoCAD window by either
choosing Window>Activate AutoCAD from the menu, or clicking on the
Activate AutoCAD button on the Run toolbar.

Quick Tour

If you are in AutoCAD and want to return to the Visual LISP environment,
you can enter the command vlide in the command window.

Running Selected Lines of Code


Visual LISP allows you to select lines of code in the text window and run just
that code, instead of the whole program. Using the drawline program as an
example, highlight the following lines of code:
(setq pt1(getpoint "\nEnter the start point for the line: ")
pt2(getpoint pt1 "\nEnter the end point for the line: "))

Click the Load Selection button on the Run toolbar. VLISP immediately runs
the code through its command interpreter, and turns control over to
AutoCAD to prompt you for input.

Exiting the Visual LISP Environment


When you are finished with your Visual LISP session, you can exit VLISP by
either choosing File>Exit from the menu, or by clicking on the Windows
close button. VLISP asks you to verify that you really want to exit.
If you have made any changes to the text in any editor window, and have not
saved those changes, Visual LISP will next ask if you want to save the
changes:

You can either save all the changes youve made (Yes) or none of the changes
(No).
If you exit Visual LISP while there are still programs open in text windows,
Visual LISP automatically opens those same programs the next time you start
a VLISP session.

Exiting the Visual LISP Environment

32

Chapter 1

33

Quick Tour

2
AutoLISP Basics

In this chapter

AutoLISP Expressions

AutoLISP Program
Files

AutoLISP Variables

Number Handling

line and see the results immediately. Some of the examples

String Handling

in this chapter are intended to be entered from the Visual

Basic Output Functions

LISP Console window, while others take advantage of the

Equality and Conditional

Visual LISP text editor.

List Handling

Symbol and Function


Handling

This chapter introduces the basic concepts of the AutoLISP


programming language. Because AutoLISP code does not
need to be compiled, you can enter the code at a command

34

AutoLISP Expressions
An AutoLISP program consists of a series of expressions. AutoLISP expressions
have the following form:
(function arguments)

Each expression begins with a left parenthesis and consists of a function


name and, optionally, arguments to that function. Each argument can itself
be an expression. The expression ends with a right parenthesis. Every expression returns a value that can be used by a surrounding expression. The value
of the last interpreted expression is returned to the calling program.
For example, the following code example involves three functions.
(fun1 (fun2 arguments)(fun3 arguments))

If you enter this code at the Visual LISP Console prompt, Visual LISP invokes
its AutoLISP interpreter to process the code. The first function, fun1, has two
arguments, and the other functions, fun2 and fun3, have one argument each.
The functions fun2 and fun3 are surrounded by function fun1, so their return
values are passed to fun1 as arguments. Function fun1 evaluates those two
arguments and returns the value to Visual LISP, which in this case was the
calling function. Visual LISP displays the returned value in the Console window.
The following example shows the use of the * (multiplication) function,
which accepts one or more real numbers as arguments.
_$ (* 2 27)
54
Because this code example has no surrounding expression, it returns the
result to Visual LISP.

Chapter 2

35

AutoLISP Basics

Expressions nested within other expressions return their result to the surrounding expression. The following example uses the result from the
+ (addition) function as one of the arguments for the * (multiplication)
function.
_$ (* 2 (+ 5 10))
30
If you enter the incorrect number of closing (right) parentheses, Visual LISP
displays the following prompt:
(_>
The number of left parentheses in this prompt indicates how many levels of
left parentheses remain unclosed. If this prompt appears, you must enter the
required number of right parentheses for the expression to be evaluated.
_$ (* 2 (+ 5 10
((_> ) )
30
A common mistake is to omit the closing quotation mark (") in a text string,
in which case the right parentheses are interpreted as being part of the string
and have no effect in resolving the open parentheses. To correct this condition, cancel the function by pressing SHIFT+ESC and re-enter it correctly.

AutoLISP Data Types


AutoLISP expressions are processed according to the order and data type of
the code within the parentheses. Before you can fully utilize AutoLISP, you
must understand the differences between the data types and how to use
them.

Integers
Integers are whole numbers that do not contain a decimal point. AutoLISP
integers are 32-bit signed numbers with values ranging from +2,147,483,648
to 2,147,483,647. When you explicitly use an integer in an AutoLISP expression, that value is known as a constant. Numbers such as 2, 56, and
1,200,196 are valid AutoLISP integers.

Reals
A real is a number containing a decimal point. Numbers between 1 and 1
must contain a leading zero. Real numbers are stored in double-precision
floating-point format, providing at least 14 significant digits of precision.
Note that Visual LISP does not show you all of the significant digits.

AutoLISP Expressions

36

Reals can be expressed in scientific notation, which has an optional e or E followed by the exponent of the number (for example, 0.0000041 is the same
as 4.1e-6). Numbers such as 3.1, 0.23, 56.123, and 21,000,000.0 are valid
AutoLISP reals.

Strings
A string is a group of characters surrounded by quotation marks. Within
quoted strings the backslash (\) character allows control characters (or escape
codes) to be included. When you explicitly use a quoted string in an
AutoLISP expression, that value is known as a literal string or a string constant.
Examples of valid strings are "string 1" and "\nEnter first point:".

Lists
An AutoLISP list is a group of related values separated by spaces and enclosed
in parentheses. Lists provide an efficient method of storing numerous related
values. AutoCAD expresses 3D points as a list of three real numbers.
Examples of lists are (1.0 1.0 0.0), ("this" "that" "the other"), and (1 "ONE").

Selection Sets
Selection sets are groups of one or more objects (entities). You can interactively add objects to, or remove objects from, selection sets with AutoLISP
routines.

Chapter 2

37

AutoLISP Basics

The following example uses the ssget function to return a selection set containing all of the objects in a drawing.
_$ (ssget "X")
<Selection set: 1>

Entity Names
An entity name is a numeric label assigned to objects in a drawing. It is actually a pointer into a file maintained by AutoCAD, and can be used to find the
objects database record and its vectors (if they are displayed). This label can
be referenced by AutoLISP functions to allow selection of objects for processing in various ways. Internally, AutoCAD refers to objects as entities.
The following example uses the entlast function to get the name of the last
object entered into the drawing.
_$ (entlast)
<Entity name: 27f0540>

VLA Objects
Objects in a drawing may be represented as VLA objects, a data type introduced with Visual LISP. (VLA stands for Visual LISP ActiveX.) When working with ActiveX functions, you must refer to VLA objects, not the ename
pointer returned by functions such as entlast. For information on working
with ActiveX objects, see Using ActiveX Objects with Visual LISP on
page 269.

File Descriptors
File descriptors are alphanumeric labels assigned to files opened by AutoLISP
functions. When an AutoLISP function needs to read or write to a file, the
label of the file must be referenced.
The following example opens the file myinfo.dat for reading. The open function returns the file label:
_$ (setq file1 (open "c:\\myinfo.dat" "r") )
#<file "c:\\myinfo.dat">
In this example, the file label is stored in variable file1.
Files remain open until you explicitly close them in your AutoLISP program.
The close function closes a file. The following code closes the file whose
label is stored in variable file1:
_$
nil

(close file1)

AutoLISP Expressions

38

Symbols and Variables


AutoLISP uses symbols to refer to data. Symbol names are not case sensitive
and can consist of any sequence of alphanumeric and notation characters
except the following:
( (Open Parenthesis)
) (Close Parenthesis)
. (Period)
(Apostrophe)
" (Quote symbol)
; (Semicolon)

A symbol name cannot consist of only numeric characters.


Technically, AutoLISP applications consist of either symbols or constant values, such as strings, reals, and integers. For the sake of clarity this guide uses
the term symbol to refer to a symbol name that stores data that is static, such
as built-in and user-defined functions. The term variable is used to refer to a
symbol name that stores program data. The following example uses the setq
function to assign the string value "this is a string" to the variable str1:
_$ (setq str1 "this is a string")
"this is a string"
TIP
Be kind to yourself and to others that need to read your code: choose
meaningful names for your program symbols and variables.

AutoLISP Function Syntax


In this guide, the following conventions describe the syntax for AutoLISP
functions.

Chapter 2

39

AutoLISP Basics

In the preceding example, the function foo has one required argument,
string, and one optional argument, number. Additional number arguments
can be provided. Frequently, the name of the argument indicates the
expected data type. The examples in the following table show both valid and
invalid calls to the foo function.
Valid and invalid calls to the foo function
Valid calls

Invalid calls

(foo "catch")

(foo 44 13)

(foo "catch" 22)

(foo "fi" "foe" 44 13)

(foo "catch" 22 31)

(foo)

AutoLISP Program Files


Although AutoLISP code can be entered at the Visual LISP Console, testing
and debugging is considerably easier when you load the AutoLISP code from
a file rather than re-entering it each time you make a refinement. The syntax
is the same for AutoLISP expressions entered in files or at the Console
prompt. AutoLISP code is usually stored in ASCII text files with a .lsp or .mnl
extension. However, you can load AutoLISP code from any ASCII text file.
From the File menu, choose Open..., and use the Open File dialog box to
select your file. Visual LISP loads this file into its text editor and displays the
contents in a new window.

Formatting AutoLISP Code


The extensive use of parentheses in AutoLISP code can make it difficult to
read. The traditional technique for combatting this confusion is indentation.
The more deeply nested a line of code is, the farther to the right you start it.
Visual LISP automatically formats your code as you type it.
Visual LISP also includes tools that allow you to reformat a selection or an
entire file. This can improve the appearance of your code, making it more
readable.
To format the entire text in an active Visual LISP edit window, select
Tools>Format AutoLISP in Editor from the Visual LISP menu. To format just
some of the text, highlight the portion of the code you want to format and
choose Format AutoLISP in Selection from the Tools menu. The code format-

AutoLISP Program Files

40

ter issues an error message if the text you selected is not a sequence of valid
AutoLISP expressions.
You can set a number of options to customize the way the code formatter lays
out your code. See Formatting Code with the Visual LISP Formatter on
page 162 for more details on using the Visual LISP code formatter.

Spaces in AutoLISP Code


In AutoLISP, multiple spaces between variable names, constants, and function names are equivalent to a single space. The end of a line is also treated
as a single space.
The following two expressions produce the same result.
(setq test1 123 test2 456)
(setq
test1 123
test2 456
)

Comments
It is a good practice to include comments in AutoLISP program files. Comments are useful to both the programmer and future users who may need to
revise a program to suit their needs. Use comments to

Give a title, authorship, and creation date


Provide instructions on using a routine
Make explanatory notes throughout the body of a routine
Make notes to yourself during debugging
Allow for characters that provide visual aesthetics and organization

Comments begin with a semicolon (;) and continue through the end of the
line.
; This entire line is a comment
(setq area (* pi r r)) ; Compute area of circle

Any text within ;| ... |; is ignored; therefore, comments can be included


within a line of code or extend for multiple lines. This type of comment is
known as an in-line comment.
(setq tmode ;|some note here|; (getvar "tilemode"))

The following example shows a comment that continues for multiple lines:
(setvar "orthomode" 1) ;|comment starts here
and continues to this line,
but ends way down here|; (princ "\nORTHOMODE set On.")

Chapter 2

41

AutoLISP Basics

It is recommended that you use comments liberally when writing AutoLISP


programs. Most of the .lsp files provided with Visual LISP contain good examples of commenting style. For instance, the file sym-exp.lsp is extensively
commented and contains some interesting and useful AutoLISP routines.
You can find this file in the Visual LISP \Sample directory.

Visual LISP Comment Styles


The Visual LISP code formatter recognizes five types of comments, and positions each comment according to its type. Refer to Comment Styles on
page 170 for a description of each comment style.
Regardless of your commenting style, it is more important that comments be
present than that they obey any particular layout rules.

Color Coding
Visual LISP provides an additional solution to making AutoLISP text easier to
read: color coding. Visual LISP looks at each word of text and tries to determine what type of AutoLISP language element it represents (for example, a
built-in function, a number, a string). Every type of element is assigned its
own color, so you can easily distinguish among them when viewing the code.
Keep in mind that color coding is a Visual LISP editor feature, and it is possible that someone who does not have access to Visual LISP may need to read
your code some day. For this reason, you should still use indentation and
alignment to enhance your programs readability.

AutoLISP Variables
An AutoLISP variable assumes the data type of the value assigned to it. Until
they are assigned new values, variables retain their original values. You use
the AutoLISP setq function to assign values to variables.
(setq variable_name1 value1 [variable_name2 value2 ...])

The setq function assigns the specified value to the variable name given. It
returns the value as its function result. If you issue setq at the Visual LISP
Console prompt, the result is displayed in the Console window:
_$ (setq val 3 abc 3.875)
3.875
_$ (setq layr "EXTERIOR-WALLS")
"EXTERIOR-WALLS"
_$

AutoLISP Variables

42

Displaying the Value of a Variable


To display the current value of a variable, just enter the variable name at the
Console prompt:
_$ abc
3.875
NOTE This behavior differs in the AutoCAD environment. If you set a variable
from the AutoCAD Command prompt and want to display that variables value,
you must precede the variable name with an exclamation point (!). For example:
Command: !abc
3.875

Nil Variables
An AutoLISP variable that has not been assigned any value is said to be nil.
nil is different from blank, which is considered a character string, and 0,
which is a number. So in addition to checking a variable for its current value,
you can test to determine whether or not the variable has been assigned a
value.
Each variable consumes a small amount of memory, so it is good programming practice to reuse variable names or to set variables to nil when their
values are no longer needed. Setting a variable to nil releases the memory
used to store that variables value. If you no longer need the val variable, you
can release its value from memory with the following expression:
_$
nil

(setq val nil)

Another efficient programming practice is to use local variables whenever


possible. See Local Variables in Functions on page 62 for more information
on this topic.

Chapter 2

43

AutoLISP Basics

Predefined Variables
The following predefined variables are commonly used in AutoLISP applications:
PAUSE

Defined as a string consisting of a single backslash (\)


character. This variable is used with the command function
to pause for user input.

PI

Defined as the constant (pi). It evaluates to approximately 3.1415926.

Defined as the constant T. This is used as a non-nil value.

NOTE You can change the value of these variables with the setq function.
However, other applications might rely on their values being consistent; therefore, it is recommended that you do not modify these variables. Visual LISP, by
default, protects these variables from redefinition. You must override this protection through the Symbol Service feature in order to modify a predefined variable.

Number Handling
AutoLISP provides functions for working with integers and real numbers. The
number-handling functions are as follows:

+ (addition)

abs

gcd

minusp

(subtraction)

atan

log

rem

* (multiplication)

cos

logand

sin

/ (division)

exp

logior

sqrt

~ (bitwise NOT)

expt

lsh

zerop

1+ (increment)

fix

max

1 (decrement)

float

min

Each number-handling function is described in AutoLISP Function Reference.


In addition to performing complex mathematical computations in applications, you can use the number-handling functions to help you in your daily
use of AutoCAD. If you are drawing a steel connection detail that uses a 2.5"

Number Handling

44

bolt that is 0.5" in diameter, how many threads are there if this bolt has 13
threads per inch? Use the * (multiplication) function at the Console prompt.
_$ (* 2.5 13)
32.5
The arithmetic functions that have a number argument (as opposed to num or
angle, for example) return different values if you provide integers or reals as
arguments. If all arguments are integers, the value returned is an integer.
However, if one or all of the arguments are reals, the value returned is a real.
To ensure that your application passes real values, make sure that at least one
of the arguments is a real.
_$ (/ 12 5)
2
_$ (/ 12.0 5)
2.4
NOTE In some cases, you can use integers and reals interchangeably. This is
not the case, however, when using ActiveX function. See Converting Arguments on page 287 in chapter 9.

String Handling
AutoLISP provides functions for working with string values. The string-handling functions are as follows:

strcase

strlen

strcat

substr

wcmatch

The following functions convert string values into numeric values and
numeric values into string values.

Chapter 2

45

angtof

atof

distof

angtos

atoi

itoa

ascii

chr

rtos

AutoLISP Basics

AutoLISP provides numerous control characters for use in strings; for a complete listing, see Control Characters in Strings on page 49.
The strcase function returns the conversion of all alphabetic characters in a
string to upper or lower case. It accepts two arguments: a string, and an
optional argument that specifies the case in which the characters are
returned. If the optional second argument is omitted, it evaluates to nil and
strcase returns the characters converted to upper case.
_$ (strcase "This is a TEST.")
"THIS IS A TEST."
If the second argument is provided and has a non-nil value, the characters
are returned as lower case. AutoLISP provides the predefined variable T to use
in situations like this where a non-nil value is used as a type of true/false toggle. However, you dont need to use T here; if it suits your application better,
you can use any non-nil value.
_$ (strcase "This is a TEST." T)
"this is a test."
The strcat function combines multiple strings into a single string value.
This is useful for placing a variable string within a constant string. The following code sets a variable to a string value and then uses strcat to insert
that string into the middle of another string.
_$ (setq str "BIG") (setq bigstr (strcat "This is a " str " test."))
"This is a BIG test."
If the variable bigstr is set to the preceding string value, you can use the
strlen function to find out the number of characters (including spaces) in
that string.
_$ (strlen bigstr)
19
The substr function returns a substring of a string. It has two required arguments and one optional argument. The first argument is the string. The second argument is an integer that specifies the first character of the string that
you want to include in the substring. If the third argument is provided, it
specifies the number of characters to include in the substring. If the third
argument is not provided, substr returns all characters including and following the specified start character.
You can use the substr function to strip off the three-letter extension from a
file name. First, set a variable to a file name. (Depending on the application,

String Handling

46

you would normally do this by querying a system variable or by requesting


user input.)
_$ (setq filnam "bigfile.txt")
"bigfile.txt"
You need to get a string that contains all characters except the last four (the
period and the three-letter extension). Use strlen to get the length of the
string, and subtract four from that value. Then use substr to specify the first
character of the substring and its length.
_$ (setq newlen (- (strlen filnam) 4))
7
_$ (substr filnam 1 newlen)
"bigfile"
If your application has no need for the value of newlen, you can combine
these two lines of code into one.
_$ (substr filnam 1 (- (strlen filnam) 4))
"bigfile"

Basic Output Functions


AutoLISP includes functions for controlling the AutoCAD display, including
both text and graphics windows. Some of these functions also display information in the Visual LISP Console window. The major text display functions
are

prin1

print

princ

prompt

The remaining display functions are covered in the Using AutoLISP to Communicate with AutoCAD chapter.
The following file-handling functions can also display output to the command line area.
read-char

Chapter 2

47

AutoLISP Basics

read-line

write-char

write-line

Displaying Messages
The basic output functions are prompt, princ, prin1, and print. The prompt
function displays a message (a string) on the AutoCAD command line and
returns nil to the Visual LISP Console. The princ, prin1, and print functions all display an expression (not necessarily a string) at the AutoCAD command line and return the expression to the Visual LISP Console. Optionally,
these functions can send output to a file. The differences are:
displays strings without the enclosing quotation marks
displays strings enclosed in quotation marks
print also displays strings enclosed in quotation marks, but places a blank
line before the expression and a space afterward.

princ
prin1

The following example demonstrates the differences between the four basic
output functions and how they handle the same string of text. The text following prints is what you would see at the AutoCAD Command prompt;
text following returns would appear within the Visual LISP Console or within
an application. See the following section for an explanation of the control
characters used in the example.
(setq str "The \"allowable\" tolerance is \261 \274\"")
(prompt str)

prints
The "allowable" tolerance is
and returns nil

(princ str)

prints
The "allowable" tolerance is
1/4"
and returns
"The \"allowable\" tolerance is

1/4""

prints
"The \"allowable\" tolerance is
1/4""
and returns
"The "\allowable\" tolerance is

1/4""

(prin1 str)

(print str)

prints

1/4"

<blank line>

"The \"allowable\" tolerance is


1/4"" <space>
and returns
"The \"allowable\" tolerance is

1/4""

Exiting Quietly
If you invoke the princ function without passing an expression to it, it displays nothing and has no value to return. So if you write an AutoLISP expression that ends with a call to princ without any arguments, the ending nil is
suppressed (because it has nothing to return). This practice is called exiting
quietly.

Basic Output Functions

48

Control Characters in Strings


Within quoted strings, the backslash (\) character allows control characters
(or escape codes) to be included. The following table shows the currently recognized control characters.
Control characters
Code

Description

\\

\ character

\"

" character

\e

Escape character

\n

Newline character

\r

Return character

\t

Tab character

\nnn

Character whose octal code is nnn

\U+xxxx

Unicode character sequence

\M+nxxxx

Multi-byte character sequence

The prompt and princ functions expand the control characters in a string
and display the expanded string in the AutoCAD command window.
If you need to use the backslash character (\) or quotation mark (") within a
quoted string, it must be preceded by the backslash character (\). For example, if you enter
_$

(princ "The \"filename\" is: D:\\ACAD\\TEST.TXT. ")

The following displays in the AutoCAD command window:


The "filename" is: D:\ACAD\TEST.TXT
You will also see this output in the Visual LISP Console window, along with
the return value from the princ function (which is your original input, with
the unexpanded control characters).

Chapter 2

49

AutoLISP Basics

To force a line break at a specific location in a string, use the newline


character (\n).
_$ (prompt "An example of the \nnewline character. ")
An example of the
newline character.
The return character (\r) returns to the beginning of the current line. This is
useful for displaying incremental information (such as the number of objects
processed).
The tab character (\t) can be used in strings to indent or to provide alignment with other tabbed text strings. In this example, note the use of the
princ function to suppress the ending nil.
_$ (prompt "\nName\tOffice\n \t
1> \nSue\t101\nJoe\t102\nSam\t103\n") (princ)

Name

Office

Sue

101

Joe

102

Sam

103

Wild-Card Matching
The wcmatch function enables applications to compare a string to a wild-card
pattern. You can use this facility when you are building a selection set (in
conjunction with ssget) and when you are retrieving extended entity data
by application name (in conjunction with entget).
The wcmatch function compares a single string to a pattern. It returns T if the
string matches the pattern, and nil if it does not. The wild-card patterns are
similar to the regular expressions used by many system and application
programs. In the pattern, alphabetic characters and numerals are treated literally; brackets can be used to specify optional characters or a range of letters
or digits; a question mark (?) matches a single character; an asterisk ( *)
matches a sequence of characters; and certain other special characters have
special meanings within the pattern. When you use the * character at the
beginning and end of the search pattern, you can locate the desired portion

Basic Output Functions

50

anywhere in the string. For more information, see wcmatch in AutoLISP


Function Reference.
In the following examples, a string variable called matchme has been declared
and initialized.
_$ (setq matchme "this is a string - test1 test2 the end")
"this is a string - test1 test2 the end"
The following code checks whether matchme begins with the four characters
"this".
_$
T

(wcmatch matchme "this*")

The following code illustrates the use of brackets in the pattern. In this case,
wcmatch returns T if matchme contains "test4", "test5", "test6", or "test9"
(note the use of the * character).

_$
nil

(wcmatch matchme "*test[4-69]*")

However,
_$
T

(wcmatch matchme "*test[4-61]*")

because the string contains "test1".


The pattern string can specify multiple patterns, separated by commas. The
following code returns T if matchme equals "ABC", or if it begins with "XYZ", or
if it ends with "end".
_$
T

Chapter 2

51

(wcmatch matchme "ABC,XYZ*,*end")

AutoLISP Basics

Equality and Conditional


AutoLISP includes functions that provide equality verification as well as conditional branching and looping. The equality and conditional functions are
as follows:

= (equal to)

and

or

/= (not equal to)

Boole

repeat

< (less than)

cond

while

<= (less than or equal to)

eq

> (greater than)

equal

>= (greater than or equal to)

if

Each equality and conditional function is described in AutoLISP Function


Reference.

List Handling
AutoLISP provides functions for working with lists. The list-handling functions are as follows:

append

foreach

listp

reverse

assoc

last

mapcar

subst

car and cdr

length

member

cons

list

nth

This section provides examples of the append, assoc, car, cons, list, nth,
and subst functions. Each list-handling function is described in AutoLISP
Function Reference.
Lists provide an efficient and powerful method of storing numerous related
values. After all, LISP is so-named because it is the LISt Processing language.

Equality and Conditional

52

Once you understand the power of lists, youll find that you can create even
more powerful and flexible applications.
Several AutoLISP functions provide a basis for programming two-dimensional and three-dimensional graphics applications. These functions return
point values in the form of a list.
The list function provides a simple method of grouping related items. These
items do not need to be of similar data types. The following code groups
three related items as a list.
_$ (setq lst1 (list 1.0 "One" 1))
(1.0 "One" 1)
You can retrieve a specific item from the list in variable lst1 with the nth
function. The nth function accepts two arguments. The first argument is an
integer that specifies which item to return. A 0 specifies the first item in a list,
1 specifies the second item, and so on. The second argument is the list itself.
The following code returns the second item in lst1.
_$ (nth 1 lst1)
One
The car and cdr functions provide another way to extract items from a list.
For examples on using car and cdr, and combinations of the two, see Point
Lists on page 54.
Three functions let you modify an existing list. The append function returns
a list with new items added to the end of it, and the cons function returns a
list with new items added to the beginning of the list. The subst function
returns a list with a new item substituted for every occurrence of an old item.
These functions do not modify the original list, they return a modified list.
To modify the original list, you must explicitly replace the old list with the
new list.
The append function takes any number of lists and runs them together as one
list. Therefore, all arguments to this function must be lists. The following
code adds another "One" to the list lst1. Note the use of the quote (or )
function as an easy way to make the string "One" into a list.
_$ (setq lst2 (append lst1 (One)))
(1.0 "One" 1 "One")

Chapter 2

53

AutoLISP Basics

The cons function combines a single element with a list. You can add another
string "One" to the beginning of this new list, lst2, with the cons function.
_$ (setq lst3 (cons "One" lst2 ))
("One" 1.0 "One" 1 "One")
You can substitute all occurrences of an item in a list with a new item with
the substr function. The following code replaces all strings "One" with the
string "one".
_$ (setq lst4 (subst "one" "One" lst3))
("one" 1.0 "one" 1 "one")

Point Lists
AutoLISP observes the following conventions for handling graphics coordinates. Points are expressed as lists of two or three numbers surrounded by
parentheses.
2D points

Expressed as lists of two real numbers (X and Y respectively), as in


(3.4 7.52)

3D points

Expressed as lists of three real numbers (X, Y, and Z


respectively), as in
(3.4 7.52 1.0)

Point variables contain X, Y, and (optionally) Z components. The first item


in the list is the X component of the point, the second is the Y component,
and the third (if present) is the Z component. You can use the list function
to form such lists.
_$ (list 3.875 1.23)
(3.875 1.23)
_$ (list 88.0 14.77 3.14)
(88.0 14.77 3.14)

List Handling

54

To assign particular coordinates to a point variable, you can use one of the
following expressions:
_$ (setq pt1 (list 3.875 1.23))
(3.875 1.23)
_$ (setq pt2 (list 88.0 14.77 3.14))
(88.0 14.77 3.14)
_$ (setq abc 3.45)
3.45
_$ (setq pt3 (list abc 1.23))
(3.45 1.23)
The latter uses the value of variable abc as the X component of the point.
If all of the members of a list are constant values, you can use the quote function to explicitly define the list, rather than use the list function. The quote
function returns an expression unevaluated.
_$ (setq pt1 (quote (4.5 7.5)))
(4.5 7.5)
The single quotation mark () can be used as shorthand for the quote function. The following code produces the same result as the preceding code.
_$ (setq pt1 (4.5 7.5))
(4.5 7.5)
You can refer to X, Y, and Z components of a point individually, using three
additional built-in functions called car, cadr, and caddr. The following
examples show how to extract the X, Y, and Z coordinates from a 3D point
list. The variable pt is set to the point (1.5 3.2 2.0).
_$ (setq pt (1.5 3.2 2.0))
(1.5 3.2 2.0)
The car function returns the first member of a list. In this example it returns
the X value of point pt to the variable x_val.
_$ (setq x_val (car pt))
1.5

Chapter 2

55

AutoLISP Basics

The cadr function returns the second member of a list. In this example it
returns the Y value of point pt to the variable y_val.
_$ (setq y_val (cadr pt))
3.2
The caddr function returns the third member of a list. In this example it
returns the Z value of point pt to the variable z_val.
_$ (setq z_val (caddr pt))
2.0
You can use the following code to define the lower-left and upper-right (pt1
and pt2) corners of a rectangle.
_$ (setq pt1 (1.0 2.0) pt2 (3.0 4.0))
(3.0 4.0)
You can use the car and cadr functions to set variable pt3 to the upper-left
corner of the rectangle, by extracting the X component of pt1 and the Y component of pt2.
_$ (setq pt3 (list (car pt1) (cadr pt2)))
(1.0 4.0)
The preceding expression sets pt3 equal to point (1.0,4.0).

Dotted Pairs
Another way AutoCAD uses lists to organize data is with a special type of list
called a dotted pair. A dotted pair is a list that must always contain two members. When representing a dotted pair, AutoLISP separates the members of
the list with a period (.). Most list-handling functions will not accept a dotted
pair as an argument, so you should be sure you are passing the right kind of
list to a function.
In addition to adding an item to the beginning of a list, the cons function
can create a dotted pair. If the second argument to the cons function is a constant or quoted value, it creates a dotted pair.
_$ (setq sublist (cons lyr "WALLS"))
(LYR . "WALLS")
The car, cdr, and assoc functions are useful for handling dotted pairs. The
following code creates an association list. An association list is a list of lists

List Handling

56

and is the method that AutoCAD uses to maintain entity definition data. The
following code creates an association list of dotted pairs.
_$ (setq wallinfo (list sublist(cons len 240.0) (cons hgt 96.0)))
( (LYR . WALLS) (LEN . 240.0) (HGT . 96.0) )
The assoc function returns a specified list from within an association list
regardless of the specified lists location within the association list. The assoc
function searches for a specified key element in the lists.
_$ (assoc len wallinfo)
(LEN . 240.0)
_$ (cdr (assoc lyr wallinfo))
"WALLS"
_$ (nth 1 wallinfo)
(LEN . 240.0)
_$ (car(nth 1 wallinfo))
LEN

Symbol and Function Handling


AutoLISP provides functions for handling symbols and variables. The symbol-handling functions are as follows:

atom

not

quote

atoms-family

null

set

boundp

numberp

setq

type

Each symbol-handling function is described in AutoLISP Function Reference.


AutoLISP provides functions for handling one or more groups of functions.
The function-handling functions are as follows:

apply

eval

progn

defun

lambda

trace

untrace

This section provides examples of the defun function. Each function-handling function is described in AutoLISP Function Reference.

Chapter 2

57

AutoLISP Basics

With AutoLISP you can define your own functions. Once they are defined,
you can use these user-defined functions at the Visual LISP Console prompt
or within other AutoLISP expressions just as you use the standard functions.
You can also create your own AutoCAD commands, because commands are
just a special type of function.
The defun function (see defun in AutoLISP Function Reference) combines a group of expressions into a function or command. This function
requires at least three arguments, the first of which is the name of the function (symbol name) to define. The second argument is the argument list (a
list of arguments and local variables used by the function). The argument list
can be nil or an empty list ( ). Argument lists are discussed in greater detail
in Functions with Arguments on page 64. If local variables are provided,
they are separated from the arguments by a slash ( / ). Local variables are discussed in Local Variables in Functions on page 62. Following these arguments are the expressions that make up the function; there must be at least
one expression in a function definition.
(defun symbol_name ( args / local_symbols )
expressions
)

The following code defines a simple function that accepts no arguments and
displays a message in the AutoCAD command line. Note that the argument
list is defined as an empty list ( () ).
_$ (defun DONE ( ) (prompt "\nbye! "))
DONE
Now that the DONE function is defined, you can use it as you would any other
function. Because it prints the message bye! to a new line at the command
line, you might use the DONE function in the following manner:
_$ (prompt "The value is 127. ")(DONE)(princ)
The value is 127
bye!
Functions that accept no arguments may seem useless. However, you might
use this type of function to query the states of certain system variables or
conditions and to return a value that indicates those values.

C:XXX Functions
If an AutoLISP function is defined with a name of the form C:XXX, it can be
issued at the AutoCAD Command prompt in the same manner as a built-in
AutoCAD command. This is true regardless of whether you define and load
the function in the Visual LISP environment or in the AutoCAD environ-

Symbol and Function Handling

58

ment. You can use this feature to add new commands to AutoCAD or to redefine existing commands.
There are two important things to note about using functions named C:XXX
in the Visual LISP environment:
1 When you execute a C:XXX-named function from within the Visual LISP environment, you cannot omit the c: or parentheses when you type the function
name.
2 The ability to define a function named c:xxx in Visual LISP and have it automatically recognized as an AutoCAD command is controlled by a VLISP variable named *C-COLON-EXPORT*. By default, this feature is enabled.
To use functions as AutoCAD commands, be sure that they adhere to the
following rules:

The function name must use the form C:XXX (upper- or lowercase characters). The C: portion of the name must always be present; the XXX portion
is a command name of your choice. C:XXX functions can be used to
override built-in AutoCAD commands. (See Redefining AutoCAD Commands on page 60.)

NOTE In this case, C: is not a reference to a disk drive. Its a special prefix that
denotes a command line function.

The function must be defined with no arguments. However, local variables are permitted and it is a good programming practice to use them.

A function defined in this manner can be issued transparently from within


any prompt of any built-in AutoCAD command, provided that the function
issued transparently does not call the command function (the command function is the AutoLISP function you use to issue AutoCAD commands; see the
entry on command). When issuing a C:XXX defined command transparently, you must precede the XXX portion with a single quotation mark ().
You can issue a built-in command transparently while a C:XXX command is
active by preceding it with a single quotation mark (), as you would with all
commands that are issued transparently. However, you cannot issue a C:XXX
command transparently while a C:XXX command is active.
When calling a function defined as a command from the code of another
AutoLISP function, you must use the whole name, including the parentheses;
for example, (C:HELLO). You also must use the whole name when you invoke
the function from the Visual LISP Console prompt, even though you can
eliminate the parentheses at the AutoCAD Command prompt.

Chapter 2

59

AutoLISP Basics

Adding Commands
Using the C:XXX feature, you can define a command that displays a simple
message.
_$ (defun C:HELLO () (princ "Hello world. \n") (princ))
C:HELLO
HELLO is now defined as a command, in addition to being an AutoLISP function. This means that you can issue the command from the AutoCAD Command prompt.

Command: hello
Hello world.
This new command can be issued transparently because it does not call the
command function itself. At the AutoCAD Command prompt, you could do
the following:
Command: line
From point: hello
Hello world.
From point:
Remember: to run this function from the Visual LISP Console prompt, you
need to issue the function call using the parentheses, since the Visual LISP
environment cannot execute AutoCAD commands:
_$ (c:hello)
Hello world.
If you follow your function definition with a call to the setfunhelp function,
you can associate a Help file and topic with a user-defined command. When
a user calls help transparently (help) at a prompt within the user-defined
command the topic specified by setfunhelp displays.
You cannot usually use an AutoLISP statement to respond to prompts from
an AutoLISP-implemented command. However, if your AutoLISP routine
makes use of the initget function, you can use arbitrary keyboard input
with certain functions. This allows an AutoLISP-implemented command
to accept an AutoLISP statement as a response.

Redefining AutoCAD Commands


With AutoLISP, external commands, and the alias feature, you can define
your own AutoCAD commands. You can use the UNDEFINE command to
redefine a built-in AutoCAD command with a user-defined command of the
same name. To restore the built-in definition of a command, use the

Symbol and Function Handling

60

REDEFINE command. The UNDEFINE command is in effect for the current


editing session only.

You can always activate an undefined command by specifying its true name,
which is the command name prefixed by a period. For example, if you undefine QUIT, you can still access the command by entering .quit at the
AutoCAD Command prompt. This is also the syntax that should be used
within the AutoLISP command function.
Consider the following example. Whenever you use the LINE command, you
want AutoCAD to remind you about using the PLINE command. You can
define the AutoLISP function C:LINE to substitute for the normal LINE
command as follows:
_$ (defun C:LINE ( )
1> (princ "Shouldnt you be using PLINE?\n")
1> (command ".LINE") (princ) )
C:LINE
In this example, the function C:LINE is designed to issue its message and
then to execute the normal LINE command (using its true name, .LINE).
Before AutoCAD will use your new definition for the LINE command, you
must undefine the built-in LINE command. At the Visual LISP Console
prompt, enter the following command:
_$

(command "undefine" "line")

Now, if you enter line at the AutoCAD Command prompt, AutoCAD uses the
C:LINE AutoLISP function:

Command: line
Shouldnt you be using PLINE?
.LINE From point:
From point:
The previous code example assumes that the CMDECHO system variable is set
to 1 (On). If CMDECHO is set to 0 (Off) AutoCAD does not display prompts

Chapter 2

61

AutoLISP Basics

that are the result of a command function call. The following code uses the
CMDECHO system variable to control the display of command prompts.
_$ (defun C:LINE (/ cmdsave )
(_> (setq cmdsave(setvar "cmdecho" 0))
(_> (princ "Shouldnt you be using PLINE?\n")
(_> (command ".LINE")
(_> (setvar "cmdecho" cmdsave)
(_> (princ) )
C:LINE
You could use this feature in a drawing management system, for example.
You could redefine the NEW, OPEN, QUIT, and END commands to write billing information to a log file before you terminate the editing session.
NOTE It is recommended that you protect your menus, scripts, and AutoLISP
programs by using the period-prefixed forms of all commands. This ensures that
your applications use the built-in command definitions rather than a redefined
command.

Local Variables in Functions


AutoLISP provides a method for defining a list of symbols (variables) that are
available only to your function. These are known as local variables.
TIP
later on!

Using local variables will save you from a lot of debugging headaches

Local Variables Versus Global Variables


The use of local variables ensures that the variables in your functions are
unaffected by the surrounding application and that your variables do not
remain available after the calling function has completed its task.
Many user-defined functions are used as utility functions within larger applications. User-defined functions also typically contain a number of variables
whose values and use are specific to that function.
The danger in using global variables, instead of local variables, is that you
may inadvertently modify them outside of the function they were declared
in and intended for. This can lead to unpredictable behavior. And it can be
very difficult to identify the source of this type of problem.
Another advantage of using local variables is that Visual LISP can recycle the
memory space used by these variables, whereas global variables keep accumulating within AutoCAD memory space.

Symbol and Function Handling

62

There are some legitimate uses for global variables, but these should be kept
to a minimum. It is also a good practice to indicate that you intend a variable
to be global. A common way of doing this is to add an opening and closing
asterisk to the variable name, for example, *default-layer*.

Example Using Local Variables


The following example shows the use of local variables in a user-defined
function (make sure that there is at least one space between the slash and the
local variables).
_$ (defun LOCAL ( / aaa bbb)
1> (setq aaa "A" bbb "B")
1> (princ (strcat "\naaa has the value " aaa ))
1> (princ (strcat "\nbbb has the value " bbb))
1> (princ) )
LOCAL
Before you test the new function, assign variables aaa and bbb to values other
than those used in the LOCAL function.
_$ (setq aaa 1 bbb 2)
2
You can verify that the variables aaa and bbb are actually set to those values.
_$
1
_$
2

aaa
bbb

Now test the LOCAL function.


_$ (local)
aaa has the value A
bbb has the value B
You will notice that the function used the values for aaa and bbb that are
local to the function. You can verify that the current values for aaa and bbb
are still set to their nonlocal values.
_$
1
_$
2

Chapter 2

63

aaa
bbb

AutoLISP Basics

In addition to ensuring that variables are local to a particular function, this


technique also ensures that the memory used for those variables is available
for other functions.

Functions with Arguments


With AutoLISP you can define functions that accept arguments. Unlike many
of the standard AutoLISP functions, user-defined functions cannot have
optional arguments. When you call a user-defined function that accepts
arguments, you must provide values for all of the arguments.
The symbols to use as arguments are defined in the argument list before the
local variables. Arguments are treated as a special type of local variable; argument variables are not available outside the function. You cannot define a
function with multiple arguments of the same name.
The following code defines a function that accepts two string arguments,
combines them with another string, and returns the resulting string.
_$ (defun ARGTEST ( arg1 arg2 / ccc )
1> (setq ccc "Constant string")
1> (strcat ccc ", " arg1 ", " arg2) )
ARGTEST
The ARGTEST function returns the desired value since AutoLISP always
returns the results of the last expression it evaluates. The last line in ARGTEST
uses strcat to concatenate the strings, and the resulting value is returned.
This is one example where you should not use the princ function to suppress
the return value from your program.
This type of function can be used a number of times within an application
to combine two variable strings with one constant string in a specific order.
Because it returns a value, you can save the value to a variable for use later in
the application.
_$ (setq newstr (ARGTEST "String 1" "String 2") )
"Constant string, String 1, String 2"
The variable newstr is now set to the value of the three strings combined.
Note that the ccc variable was defined locally within the ARGTEST function.
Once the function runs to completion, Visual LISP recycles the variable,
recapturing the memory that had been allocated to it. To prove this, check
from the Visual LISP Console to see if there is still a value assigned to ccc.
_$ ccc
nil

Symbol and Function Handling

64

Chapter 2

65

AutoLISP Basics

3
Using AutoLISP to
Communicate with
AutoCAD
In this chapter

AutoLISP provides various functions for examining the


contents of the currently loaded drawing. This chapter
introduces these functions and describes how to use them
in conjunction with other functions.

Query and Command


Functions

Display Control

Getting User Input

Geometric Utilities

Conversions

File Handling

Device Access and


Control

66

NOTE The AutoLISP examples in this chapter show code entered from the
AutoCAD Command prompt, not the Visual LISP Console.

Query and Command Functions


The query and command functions described in this section provide direct
access to AutoCAD commands and drawing services. Their behavior depends
on the current state of the AutoCAD system and environment variables, and
on the drawing that is currently loaded. The query and command functions
are as follows:
acad_colordlg

getcfg

getvar

setvar

command

getenv

setcfg

ver

Examples of the command, getcfg, getvar, setcfg, and getvar functions are
provided in this section. The help, getenv, and ver functions are described
in the AutoLISP Function Reference. Access to the AutoCAD help system is
implemented by the help function.

Command Submission
The command function sends an AutoCAD command directly to the AutoCAD
Command prompt. The command function has a variable-length argument
list. These arguments must correspond to the types and values expected by
that commands prompt sequence; these may be strings, real values, integers,
points, entity names, or selection set names. Data such as angles, distances,
and points can be passed either as strings or as the values themselves (as integer or real values, or as point lists). An empty string ("") is equivalent to
entering a space or ENTER on the keyboard.
There are some restrictions on the commands that you can use with the
command function. See the AutoLISP Function Reference definition of this
function for more information.
The following code fragment shows representative calls to command.
(command "circle" "0,0" "3,3")
(command "thickness" 1)
(setq p1 (1.0 1.0 3.0))
(setq rad 4.5)
(command "circle" p1 rad)

If AutoCAD is at the Command prompt when these functions are called,


AutoCAD performs the following actions:

Chapter 3

67

Using AutoLISP to Communicate with AutoCAD

1 The first call to command passes points to the CIRCLE command as strings
(draws a circle centered at (0.0,0.0) and passes through (3.0,3.0)).
2 The second call passes an integer to the THICKNESS command (changes the
current thickness to 1.0).
3 The last call uses a 3D point and a real (floating-point) value, both of which
are stored as variables and passed by reference to the CIRCLE command
(draws another [extruded] circle centered at (1.0,1.0,3.0) with a radius of 4.5).

Foreign-Language Support
If you develop AutoLISP programs that might be used with a foreign-language version of AutoCAD, the standard AutoCAD commands and key words
are automatically translated if you precede each command or key word with
an underscore (_).
(command "_line" pt1 pt2 pt3 "_c")

If you are using the dot prefix (to avoid using redefined commands), you can
place the dot and underscore in either order. Both "._line" and "_.line" are
valid.

Pausing for User Input


If an AutoCAD command is in progress and the predefined symbol PAUSE is
encountered as an argument to command, the command waits (is suspended)
to allow direct user input (usually point selection or dragging). This is similar
to the backslash pause mechanism provided for menus.
If you issue a transparent command while a command function is suspended,
the command function remains suspended. Therefore, users can ZOOM and
PAN while at a command pause. The pause remains in effect until AutoCAD
gets valid input, and no transparent command is in progress. For example,
the following code begins the CIRCLE command, sets the center point at
(5,5), and then pauses to let the user drag the circles radius on screen. When
the user specifies the desired point (or types in the desired radius), the function resumes, drawing a line from (5,5) to (7,5).
(command "circle" "5,5" pause "line" "5,5" "7,5" "")

Menu input is not suspended by an AutoLISP pause. If a menu item is active


when the command function pauses for input, that input request can be satisfied by the menu. If you want the menu item to be suspended as well, you
must provide a backslash (\) in the menu item. When valid input is found,
both the command function and the menu item resume.

Query and Command Functions

68

Passing Pick Points to AutoCAD Commands


Some AutoCAD commands (such as TRIM, EXTEND, and FILLET) require the
user to specify a pick point as well as the object itself. To pass such pairs of
object and point data by means of the command function without the use of a
PAUSE, you must first store them as variables. Points can be passed as strings
within the command function or can be defined outside the function and
passed as variables, as shown in the following example. This code fragment
shows one method of passing an entity name and a pick point to the command
function.
(command "circle" "5,5" "2")
(command "line" "3,5" "7,5" "")
(setq el (entlast))
(setq pt (5 7))
(command "trim" el "" pt "")

Draws circle
Draws line
Gets last entity name
Sets point pt
Performs trim

If AutoCAD is at the Command prompt when these functions are called,


AutoCAD performs the following actions:
1 Draws a circle centered at (5,5) with a radius of 2.
2 Draws a line from (3,5) to (7,5).
3 Creates a variable el that is the name of the last object added to the database.
(See Using AutoLISP to Manipulate AutoCAD Objects for more discussion of
objects and object handling functions.)
4 Creates a variable pt that is a point on the circle. (This point selects the portion of the circle to be trimmed.)
5 Performs the TRIM command by selecting the object el and by selecting the
point specified by pt.

System and Environment Variables


The functions getvar and setvar allow AutoLISP applications to inspect and
change the value of AutoCAD system variables. These functions use a string
to specify the variable name. The setvar function specifies a value of the
type that the system variable expects. AutoCAD system variables come in various types: integers, real values, strings, 2D points, and 3D points. Values supplied as arguments to setvar must be of the expected type. If an invalid type
is supplied, an AutoLISP error is generated.
The following code fragment ensures that subsequent FILLET commands use
a radius of at least 1:
(if (< (getvar "filletrad") 1)
(setvar "filletrad" 1)
)

Chapter 3

69

Using AutoLISP to Communicate with AutoCAD

An additional function, getenv, provides AutoLISP routines access to the currently defined operating-system environment variables.

Configuration Control
AutoCAD uses the acad14.cfg file to store configuration information. The
AppData section of this file is provided for users and developers to store configuration information that pertains to their applications. The getcfg and
setcfg functions allow AutoLISP applications to inspect and change the
value of parameters in the AppData section.

Display Control
AutoLISP includes functions for controlling the AutoCAD display, including
both text and graphics windows. Some of these functions prompt for, or
depend on, input from the AutoCAD user. The display-control functions are
as follows:
graphscr

menucmd

print

textpage

grdraw

menugroup

prompt

textscr

grtext

prin1

redraw

vports

grvecs

princ

terpri

The prin1, princ, print, and prompt functions are the primary text output
functions and are described in AutoLISP Basics. The terpri and vports
functions are described in the AutoLISP Function Reference.

Controlling Menus
The menucmd function controls the display of the graphics window menus. It
displays, modifies, or queries one of the submenus of the current menu, and
accepts a string argument that specifies the submenu and the action to
perform on that submenu.
The menucmd function takes a string argument that consists of two fields,
separated by an equal sign, in the following form:
"menu_area=action"

Display Control

70

This syntax can load a submenu into a specified menu area, or perform an
action on a menu item or a currently loaded menu area. The menu_area field
specifies which part of the menu is to receive the action. This field can specify
a menu area, such as P0 (for the cursor menu) or S (for the screen menu), or
a specific menu item. The action field specifies the action to perform on the
menu area or menu item, or a submenu to load into the menu area. The
menu areas that can receive an action are the same as those used in menu file
submenu references.
Every menu area has a currently loaded submenu. By default the first submenu following a menu section label is loaded into that menu area.
If menu_area specifies a pull-down menu or image tile menu, action can be
an asterisk (*). This causes the menu to displayed (pull-down menus and
image tile menus are not automatically displayed when they are called). On
Windows, only the P0 (cursor) menu and image tile menus are displayed
with the asterisk.
NOTE Do not include the dollar sign that introduces the similar instructions
in a menu file in the string argument. Also, do not include the asterisks that precede submenu labels in the menu file in the action field of the string argument.
The following menucmd function call causes the **OSNAP screen submenu
defined in the current menu file to be displayed (assuming that the screen
menu is currently enabled).
(menucmd "S=OSNAP")

In Windows, you can reference the menu group. This can be useful if there
may be multiple menus loaded that contain the same submenu name. The
following code displays the **OSNAP screen submenu in the ACAD menu
group.
(menucmd "S=ACAD.OSNAP")

The menucmd function can load submenus into the BUTTONS and AUX menu
areas. You might want your digitizer buttons to function differently depending on whether Tablet mode is On or Off. You could have two submenus
defined in the ***BUTTONS1 section, **DIG-BUTTONS and **TAB-BUTTONS, and
switch between them with the following code.
(menucmd "B1=DIG-BUTTONS")
(menucmd "B1=TAB-BUTTONS")

Chapter 3

71

Enables the DIG-BUTTONS submenu


Enables the TAB-BUTTONS submenu

Using AutoLISP to Communicate with AutoCAD

The following code loads the ***POP0 menu into the P0 (cursor) menu area
and displays it.
(menucmd "P0=POP0")
(menucmd "P0=*")

Loads the ***POP0 menu into the P0 menu area


Displays it

If you are sure that the correct menu is loaded into a particular menu area,
you do not need to specifically load it each time you want to display it.
The following call displays the pull-down menu currently loaded in the P1
(first pull-down menu) location.
(menucmd "P1=*")

Using "P1=*" without previously loading the menu can result in unexpected
behavior. Although you can load virtually any menu at a pull-down or cursor
menu location, it is best to use only menus specifically designed for that
menu area. For example, if you have a submenu called **MORESTUFF, you can
load it at the P1 location with the following code:
(menucmd "P1=MORESTUFF")
(menucmd "P1=*")

Loads the **MORESTUFF menu in the


P1 menu location
Displays it

This menu remains in this location until you replace it by loading another
menu, as in the following:
(menucmd "P1=POP1")

If your menu uses the disabling (graying-out) and marking features, you can
retrieve and change the state of a menu label with the menucmd function. The
following call retrieves the current state of the fourth label in the pull-down
menu P2.
(menucmd "P2.4=#?")

If disabled returns

"P2.4=~"

These function calls enable and disable that same label:


(menucmd "P2.4=")
(menucmd "P2.4=~")

Enables the label


Disables the label

You can also place and remove marks to the left of menu labels.
The previously described method of menu item handling works relatively
well with a single static menu. However, it becomes unreliable when menu
item locations change when you load multiple partial menu files. You can
make use of the menu-group and name-tag features to keep track of menu
items. Instead of specifying a menu item by its location in the menu file, you
specify the menu group and name tag associated with the menu item.

Display Control

72

When you use the menu group to enable, disable, and mark menu labels, you
must precede the group name with a G, as shown in the following examples.
(menucmd "Gacad.ID_New=~")
(menucmd "Gacad.ID_New=")

Disables the label


Enables the label

Not only can an AutoLISP function enable and disable menu labels, it can
also modify the text displayed in the label by placing a DIESEL string expression in the label itself. Because DIESEL accepts only strings as input, you can
pass information to the DIESEL expression through a USERS15 system variable that has been set to a value returned by your function.
You can use the menucmd function also to evaluate DIESEL string expressions
within an AutoLISP function. The following routine returns the current time:
(defun C:CTIME ( / ctim)
(setq ctim
(menucmd "M=$(edtime,$(getvar,date),H:MMam/pm)"))
(princ (strcat "\nThe current time is " ctim ))
(princ)
)

Control of Graphics and Text Windows


You can control the display of the graphics and text windows from an
AutoLISP application. On single-screen AutoCAD installations a call to
graphscr displays the graphics window, or to textscr displays the text window. Using these functions is equivalent to toggling the Flip Screen function
key. The function textpage is like textscr, but textpage clears the text window before displaying the text window (as the AutoCAD STATUS and LIST
commands do).
The redraw function is similar to the AutoCAD REDRAW command but provides more control over what is displayed: it not only redraws the entire
graphics area but can also specify a single object to be redrawn or undrawn
(that is, blanked out). If the object is a complex object such as a polyline or
block, redraw can draw (or undraw) either the entire object or its header. The
redraw function can also highlight and unhighlight specified objects.

Chapter 3

73

Using AutoLISP to Communicate with AutoCAD

Control of Low-level Graphics


AutoLISP provides functions that control the low-level graphics and allow
direct access to the AutoCAD graphics screen and input devices.
The grtext function displays text directly in the status or menu areas, with
or without highlighting. The grdraw function draws a vector in the current
viewport with control over color and highlighting. The grvecs function
draws multiple vectors.
NOTE Because these functions depend on code in AutoCAD, their operation
can be expected to change from release to release. There is no guarantee that
applications calling these functions will be upward compatible. Also, they depend
on the current hardware configuration: in particular, applications that call grtext
are not likely to work the same on all configurations unless the developer is very
careful to use them as described and to avoid hardware-specific features. Finally,
because they are low-level functions, they do almost no error reporting and can
alter the graphics screen display unexpectedly (see the following example for a
way to fix this).
The following sequence restores the default graphics window display caused
by incorrect calls to grtext, grdraw, or grvecs:
(grtext)
(redraw)

Restores standard text

Getting User Input


Several functions enable an AutoLISP application to prompt the user for
input of data. The user-input functions are as follows:
entsel

getfiled

getpoint

nentsel

getangle

getint

getreal

nentselp

getcorner

getkword

getstring

getdist

getorient

initget

Getting User Input

74

The getxxx Functions


Each user-input getxxx function pauses for data entry of the indicated type
and returns the value entered. The application can specify an optional
prompt to display before the function pauses. The following table lists the
getxxx functions and the type of user input requested.
Allowable input to the getxxx user-input functions
Function
name

Type of user input

getint

An integer value on the command line

getreal

A real or integer value on the command line

getstring

A string on the command line

getpoint

A point value on the command line or selected from the screen

getcorner

A point value (the opposite corner of a box) on the command line or


selected from the screen

getdist

A real or integer value (of distance) on the command line or determined


by selecting points on the screen

getangle

An angle value (in the current angle format) on the command line or
based on selected points on the screen

getorient

An angle value (in the current angle format) on the command line or
based on selected points on the screen

getkword

A predefined key word or its abbreviation on the command line

NOTE Although the getvar, getcfg and getenv functions begin with the letters g, e, and t, they are not user-input functions.
The functions getint, getreal, and getstring pause for user input on the
AutoCAD command line. They return a value only of the same type as that
requested.
The getpoint, getcorner, and getdist functions pause for user input on the
command line or from points selected on the graphics screen. The getpoint
and getcorner functions return 3D point values, and getdist returns a real
value.
Both getangle and getorient pause for input of an angle value on the command line or as defined by points selected on the graphics screen. For the

Chapter 3

75

Using AutoLISP to Communicate with AutoCAD

getorient function, the zero angle is always to the right: East or


3 oclock. For getangle, the zero angle is the value of ANGBASE, which can
be set to any angle. Both getangle and getorient return an angle value (a

real) in radians measured counterclockwise from a base (zero angle), for


getangle equal to ANGBASE, and for getorient to the right.

For example, ANGBASE is set to 90 degrees (north), and ANGDIR is set to 1


(clockwise direction for increasing angles). The following table shows what
getangle and getorient return (in radians) for representative input values
(in degrees).
Possible return values from getangle and getorient
Input
(degrees)

getangle

getorient

0.0

1.5708

90

1.5708

3.14159

180

3.14159

4.71239

90

4.71239

0.0

The getangle function honors the settings of ANGDIR and ANGBASE when
accepting input. You can use getangle to obtain a rotation amount for a
block insertion, because input of 0 degrees always returns 0 radians. The
getorient function honors only ANGDIR. You use getorient to obtain
angles such as the baseline angle for a text object. For example, given the
preceding settings of ANGBASE and ANGDIR, for a line of text created at an
angle of 0, getorient returns an angle value of 90.
The user-input functions take advantage of the error-checking capability of
AutoCAD. Trivial errors are trapped by AutoCAD and are not returned by the
user-input function. A prior call to initget provides additional filtering

Getting User Input

76

capabilities, lessening the need for error checking.


The getkword function pauses for the input of a key word or its abbreviation.
Key words must be defined with the initget function before the call to
getkword. All user-input functions (except getstring) can accept key word
values in addition to the values they normally return, provided that initget
has been called to define the key words.
All user-input functions allow for an optional prompt argument. It is recommended that you use this argument rather than a prior call to the prompt or
princ functions. If a prompt argument is supplied with the call to the userinput function, that prompt is reissued in the case of invalid user input. If no
prompt argument is supplied and the user enters incorrect information, the
following message appears at the AutoCAD prompt line:
Try again:
This can be confusing, because the original prompt may have scrolled out of
the Command prompt area.
NOTE The AutoCAD user cannot typically respond to a user-input function by
entering an AutoLISP expression. If your AutoLISP routine makes use of the
initget function, arbitrary keyboard input is permitted to certain functions that
can allow an AutoLISP statement as response to an AutoLISP-implemented
command.

Control of User-Input Function Conditions


The initget function provides a level of control over the next user-input
function call. The initget function establishes various options for use by the
next entsel, nentsel, nentselp, or getxxx function (except getstring,
getvar, and getenv). This function accepts two arguments, bits and string,
both of which are optional. The bits argument specifies one or more control
bits that enable or disable certain input values to the following user-input
function call. The string argument can specify key words that the following
user-input function call will recognize.
The control bits and key words established by initget apply only to the next
user-input function call. They are discarded afterward. The application
doesnt have to call initget a second time to clear special conditions.

Input Options for User-Input Functions


The value of the bits argument restricts the types of user input to the following user-input function call. This reduces error checking. These are some of
the available bit values: 1 disallows null input, 2 disallows input of 0 (zero),
and 4 disallows negative input. If these values are used with a following call

Chapter 3

77

Using AutoLISP to Communicate with AutoCAD

to the getint function, the user is forced to enter an integer value greater
than 0.
To set more than one condition at a time, add the values together (in any
combination) to create a bits value between 0 and 255. If bits is not
included or is set to 0, none of the control conditions apply to the next
user-input function call. (For a complete listing of initget bit settings, see
initget in AutoLISP Function Reference.)
(initget (+ 1 2 4))
(getint "\nHow old are you? ")

This sequence requests the users age. AutoCAD displays an error message
and repeats the prompt if the user attempts to enter a negative or zero value,
press ENTER only, or enter a string (the getint function rejects attempts to
enter a value that is not an integer).

Key Word Options


The optional string argument specifies a list of key words recognized by the
next user-input function call.
The initget function allows key word abbreviations to be recognized in
addition to the full key words. The user-input function returns a predefined
key word if the input from the user matches the spelling of a key word (not
case sensitive), or if the user enters the abbreviation of a key word. There are
two methods for abbreviating key words; both are discussed in Key Word
Specifications.
The following user-defined function shows a call to getreal, preceded by a
call to initget, that specifies two key words. The application checks for these
key words and sets the input value accordingly.
(defun C:GETNUM (/ num)
(initget 1 "Pi Two-pi")
(setq num (getreal "Pi/Two-pi/<number>: "))
(cond
((eq num "Pi") pi)
((eq num "Two-pi") (* 2.0 pi))
(T num)
)
)

This initget call inhibits null input (bits = 1) and establishes a list of two
key words, "Pi" and "Two-pi". The getreal function is then used to obtain
a real number, issuing the following prompt:
Pi/Two-pi/<number>:
The result is placed in local symbol num. If the user enters a number, that
number is returned by C:GETNUM. However, if the user enters the key word Pi

Getting User Input

78

(or simply P), getreal returns the key word Pi. The cond function detects this
and returns the value of p in this case. The Two-pi key word is handled
similarly.
NOTE You can also use initget to enable entsel, nentsel, and nentselp
to accept key word input. For more information on these functions, see Object
Handling and entsel, nentsel, and nentselp in the AutoLISP Function Reference.

Arbitrary Keyboard Input


The initget function also allows arbitrary keyboard input to most getxxx
functions. This input is passed back to the application as a string. An application using this facility can be written to permit the user to call an AutoLISP
function at a getxxx function prompt.
These functions show a method for allowing AutoLISP response to a getxxx
function call:
(defun C:ARBENTRY ( / pt1)
(initget 128)
; Sets arbitrary entry bit
(setq pt1 (getpoint "\nPoint: ")) ; Gets value from user.
(if (= STR (type pt1))
; If its a string, convert it
(setq pt1 (eval (read pt1)))
; to a symbol, try evaluating
; it as a function; otherwise,
pt1
; just return the value.
)
)
(defun REF ( )
(setvar "LASTPOINT" (getpoint "\nReference point: "))
(getpoint "\nNext point: " (getvar "LASTPOINT"))
)

If both the C:ARBENTRY and REF functions are loaded into the drawing, the
following command sequence is acceptable.
Command: arbentry
Point: (ref)
Reference point: Select a point
Next point: @1,1,0

Input Validation
You should protect your code from unintentional user errors. The AutoLISP
user input getxxx functions do much of this for you. However, its dangerous
to forget to check for adherence to other program requirements that the
getxxx functions do not check for. If you neglect to check input validity, the
programs integrity can be seriously affected.

Chapter 3

79

Using AutoLISP to Communicate with AutoCAD

Geometric Utilities
A group of functions allow applications to obtain pure geometric information and geometric data from the drawing. The geometric utility functions
are as follows:
angle

inters

polar

distance

osnap

textbox

The angle function finds the angle in radians between a line and the X axis
(of the current UCS), distance finds the distance between two points, and
polar finds a point by means of polar coordinates (relative to an initial
point). The inters function finds the intersection of two lines. The osnap
and textbox functions are described separately.
The following code fragment shows calls to the geometric utility functions:
(setq
(setq
(setq
(setq

pt1 (3.0 6.0 0.0))


pt2 (5.0 2.0 0.0))
base (1.0 7.0 0.0))
rads (angle pt1 pt2))

(setq len
(setq endpt

(distance pt1 pt2))

Angle in XY plane of current UCS


(value is returned in radians)
Distance in 3D space

(polar base rads len))

The call to polar sets endpt to a point that is the same distance from (1,7) as
pt1 is from pt2, and at the same angle from the X axis as the angle between
pt1 and pt2.

Object Snap
The osnap function can find a point by using one of the AutoCAD Object
Snap modes. The Snap modes are specified in a string argument.
The following call to osnap looks for the midpoint of an object near pt1:
(setq pt2 (osnap pt1 "midp"))

The following call looks for the midpoint, the endpoint, or the center of an
object nearest pt1:
(setq pt2 (osnap pt1 "midp,endp,center"))

In both examples, pt2 is set to the snap point if one is found that fulfills the
osnap requirements. If more than one snap point fulfills the requirements,
the point is selected based on the setting of the SORTENTS system variable.
Otherwise, pt2 is set to nil.

Geometric Utilities

80

NOTE The APERTURE system variable determines the allowable proximity of


a selected point to an object when you use Object Snap.

Text Extents
The textbox function returns the diagonal coordinates of a box that encloses
a text object. It takes an entity definition list of the type returned by entget
(an association list of group codes and values) as its single argument. This list
can contain a complete association list description of the text object or just
a list describing the text string.
The points returned by textbox describe the bounding box (an imaginary
box that encloses the text object) of the text object as if its insertion point
were located at (0,0,0) and its rotation angle were 0. The first list returned is
the point (0.0 0.0 0.0) unless the text object is oblique or vertical or it contains letters with descenders (such as g and p). The value of the first point list
specifies the offset distance from the text insertion point to the lower-left
corner of the smallest rectangle enclosing the text. The second point list specifies the upper-right corner of that box. The returned point lists always
describe the bottom-left and upper-right corners of this bounding box,
regardless of the orientation of the text being measured.
The following example shows the minimum allowable entity definition list
that textbox accepts. Because no additional information is provided,
textbox uses the current defaults for text style and height.
Command: (textbox ((1 . "Hello world")) )
((0.0 0.0 0.0) (2.80952 1.0 0.0))
The actual values returned by textbox will vary depending on the current
text style.

Chapter 3

81

Using AutoLISP to Communicate with AutoCAD

The following example demonstrates one method of providing the textbox


function with an entity definition list.
Command: dtext
Justify/Style/<Start point>: 1,1
Height <1.0000>: ENTER
Rotation angle <0>: ENTER
Text: test
Text: ENTER
Command: (setq e (entget (entlast)))
((-1 . <Entity name: 6000001c>) (0 . "TEXT") (8 . "0")
(10 1.0 1.0 0.0) (40 . 1.0) (1 . "test") (50 . 0.0)
(41 . 1.0)(51 . 0.0) (7 . "STANDARD") (71 . 0) (72 . 0)
(11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (73 . 0))
Command: (textbox e)
((0.0 0.0 0.0) (0.8 0.2 0.0))
The following figure shows the results of applying textbox to a text object
with a height of 1.0. The figure also shows the baseline and insertion point
of the text.

Points returned by textbox

If the text is vertical or rotated, pt1 is still the bottom-left corner and pt2 is
the upper-right corner; the bottom-left point may have negative offsets if
necessary.
The following figure shows the point values (pt1 and pt2) that textbox
returns for samples of vertical and aligned text. In both samples, the height
of the letters is 1.0. (For the aligned text, the height is adjusted to fit the
alignment points.)

Geometric Utilities

82

pt2 = 1.0,0.0

Vertical and aligned text

insertion
point: (0,0)

When using vertical text styles, the points are still returned in left-to-right,
bottom-to-top order as they are for horizontal styles, so the first point list will
contain negative offsets from the text insertion point.
Regardless of the text orientation or style, the points returned by textbox are
such that the text insertion point (group code 10) directly translates to the
origin point of the Object Coordinate System (OCS) for the associated text
object. This point can be referenced when translating the coordinates
returned from textbox into points that define the actual extents of the text.
The two sample routines that follow use textbox to place a box around
selected text regardless of its orientation.
The first routine uses the textbox function to draw a box around a selected
text object.

pt1 =
0.5,20.0

(defun C:TBOX ( / textent tb ll ur ul lr)


(setq textent (car (entsel "\nSelect text: ")))
(command "ucs" "Object" textent)
(setq tb (textbox (list (cons -1 textent)))
ll (car tb)
ur (cadr tb)
ul (list (car ll) (cadr ur))
lr (list (car ur) (cadr ll))
)
(command "pline" ll lr ur ul "Close")
(command "ucs" "p")
(princ)
)

The second routine, which follows, accomplishes the same task as the first
routine by performing the geometric calculations with the sin and cos
AutoLISP functions. The result is correct only if the current UCS is parallel to
the plane of the text object.

Chapter 3

83

Using AutoLISP to Communicate with AutoCAD

(defun C:TBOX2 ( / textent ang sinrot cosrot


t1 t2 p0 p1 p2 p3 p4)
(setq textent (entget (car (entsel "\nSelect text: "))))
(setq p0 (cdr (assoc 10 textent))
ang (cdr (assoc 50 textent))
sinrot (sin ang)
cosrot (cos ang)
t1 (car (textbox textent))
t2 (cadr (textbox textent))
p1 (list
(+ (car p0)
(- (* (car t1) cosrot)(* (cadr t1) sinrot))
)
(+ (cadr p0)
(+ (* (car t1) sinrot)(* (cadr t1) cosrot))
)
)
p2 (list
(+ (car p0)
(- (* (car t2) cosrot)(* (cadr t1) sinrot))
)
(+ (cadr p0)
(+ (* (car t2) sinrot)(* (cadr t1) cosrot))
)
)
p3 (list
(+ (car p0)
(- (* (car t2) cosrot)(* (cadr t2) sinrot))
)
(+ (cadr p0)
(+ (* (car t2) sinrot)(* (cadr t2) cosrot))
)
)
p4 (list
(+ (car p0)
(- (* (car t1) cosrot)(* (cadr t2) sinrot))
)
(+ (cadr p0)
(+ (* (car t1) sinrot)(* (cadr t2) cosrot))
)
)
)
(command "pline" p1 p2 p3 p4 "c")
(princ)
)

Conversions
The functions described in this section are utilities for converting data types
and units. The conversion functions are as follows:
angtof

atof

cvunit

rtos

Conversions

84

angtos

atoi

distof

ascii

chr

itoa

trans

String Conversions
The functions rtos (real to string) and angtos (angle to string) convert
numeric values used in AutoCAD to string values that can be used in output
or as textual data. The rtos function converts a real value, and angtos converts an angle. The format of the result string is controlled by the value of
AutoCAD system variables: the units and precision are specified by LUNITS
and LUPREC for real (linear) values and by AUNITS and AUPREC for angular
values. For both functions, the dimensioning variable DIMZIN controls how
leading and trailing zeros are written to the result string.
The following code fragments show calls to rtos and the values returned
(assuming that the DIMZIN system variable equals 0). Precision (the third
argument to rtos) is set to 4 places in the first call and 2 places in the others.
(setq x 17.5)
(setq str "\nValue formatted as ")

Chapter 3

85

(setq fmtval (rtos x 1 4))


(princ (strcat str fmtval))

Mode 1 = scientific
displays
Value formatted as 1.7500E+01

(setq fmtval (rtos x 2 2))


(princ (strcat str fmtval))

Mode 2 = decimal
displays
Value formatted as 17.50

(setq fmtval (rtos x 3 2))


(princ (strcat str fmtval))

Mode 3 = engineering
displays
Value formatted as 1-5.50"

(setq fmtval (rtos x 4 2))


(princ (strcat str fmtval))

Mode 4 = architectural
displays
Value formatted as 1-5 1/2"

(setq fmtval (rtos x 5 2))


(princ (strcat str fmtval))

Mode 5 = fractional
displays
Value formatted as 17 1/2

Using AutoLISP to Communicate with AutoCAD

When the UNITMODE system variable is set to 1, specifying that units are displayed as entered, the string returned by rtos differs for engineering (mode
equals 3), architectural (mode equals 4), and fractional (mode equals 5) units.
For example, the first two lines of the preceding sample output would be the
same, but the last three lines would appear as follows:
Value formatted as 15.50"
Value formatted as 15-1/2"
Value formatted as 17-1/2
Because the angtos function takes the ANGBASE system variable into
account, the following code always returns "0".
(angtos (getvar "angbase"))

There is no AutoLISP function that returns a string version (in the current
mode/precision) of either the amount of rotation of ANGBASE from true zero
(East) or an arbitrary angle in radians.
To find the amount of rotation of ANGBASE from AutoCAD zero (East) or the
size of an arbitrary angle, you can do one of the following:

Add the desired angle to the current ANGBASE, and then check to see if
the absolute value of the result is greater than 2 (2 * pi). If so, subtract 2;
if the result is negative, add 2. Then use the angtos function on the
result.
Store the value of ANGBASE in a temporary variable, set ANGBASE to 0, and
evaluate the angtos function. Then set ANGBASE to its original value.

Subtracting the result of (atof (angtos 0)) from 360 degrees (2 radians or
400 grads) also yields the rotation of ANGBASE from 0.
The distof (distance to floating point) function is the complement of rtos,
so the following calls, which use the strings generated in the previous examples, all return the same value: 17.5. (Note the use of the backslash (\) with
modes 3 and 4.)
(distof "1.7500E+01" 1)

Mode 1 = scientific

(distof "17.50" 2)

Mode 2 = decimal

(distof "1-5.50\"" 3)

Mode 3 = engineering

(distof "1-5 1/2\"" 4)

Mode 4 = architectural

(distof "17 1/2" 5)

Mode 5 = fractional

Conversions

86

The following code fragments show similar calls to angtos and the values
returned (still assuming that DIMZIN equals 0). Precision (the third argument
to angtos) is set to 0 places in the first call, 4 places in the next three calls,
and 2 places in the last.
(setq ang 3.14159 str2 "\nAngle formatted as ")
(setq fmtval (angtos ang 0 0))
(princ (strcat str2 fmtval))

Mode 0 = degrees
displays Angle formatted as 180

(setq fmtval (angtos ang 1 4))


(princ (strcat str2 fmtval))

Mode 1 = deg/min/sec
displays Angle formatted as 180d00"

(setq fmtval (angtos ang 2 4)


(princ (strcat str2 fmtval))

Mode 2 = grads
displays Angle formatted as 200.0000g

(setq fmtval (angtos ang 3 4)


(princ (strcat str2 fmtval))

Mode 3 = radians
displays Angle formatted as 3.1416r

(setq fmtval (angtos ang 4 2)


(princ (strcat str2 fmtval))

Mode 4 = surveyors
displays Angle formatted as W

The UNITMODE system variable also affects strings returned by angtos when
it returns a string in surveyors units (mode equals 4). If UNITMODE equals 0,
the string returned can include spaces (for example, "N 45d E"); if UNITMODE equals 1, the string contains no spaces (for example, "N45dE").
The angtof function complements angtos, so all of the following calls return
the same value: 3.14159.
(angtof
(angtof
(angtof
(angtof
(angtof

"180" 0)
"180d00\"" 1)
"200.0000g" 2)
"3.14159r" 3)
"W" 4)

Mode 0 = degrees
Mode 1 = deg/min/sec
Mode 2 = grads
Mode 3 = radians
Mode 4 = surveyors

When you have a string specifying a distance in feet and inches, or an angle
in degrees, minutes, and seconds, you must precede the quotation mark with
a backslash (\") so that it doesnt look like the end of the string. The preceding examples of angtof and distof demonstrate this.

Angular Conversion
If your application needs to convert angular values from radians to degrees,
you could use the angtos function, which returns a string, and then convert
that string into a floating point value with atof.
(setq pt1 (1 1) pt2 (1 2))
(setq rad (angle pt1 pt2))
(setq deg (atof (angtos rad 0 2)))

Chapter 3

87

Using AutoLISP to Communicate with AutoCAD

returns

90.0

However, a more efficient method might be to include a Radian->Degrees


function in your application. The following code shows this.
; Convert value in radians to degrees
(defun Radian->Degrees (nbrOfRadians)
(* 180.0 (/ nbrOfRadians pi))
)

After this function is defined, you can use the Radian->Degrees function
throughout your application, as in
(setq degrees (Radian->Degrees rad))

returns

90.0

You may also need to convert from degrees to radians. The following code
shows this.
; Convert value in degrees to radians
(defun Degrees->Radians (numberOfDegrees)
(* pi (/ numberOfDegrees 180.0))
) ;_ end of defun

ASCII Code Conversion


AutoLISP provides the ascii and chr functions that handle decimal ASCII
codes. The ascii function returns the ASCII decimal value associated with a
string, and chr returns the character associated with an ASCII decimal value.
To see your systems characters with their codes in decimal, octal, and hexadecimal form, save the following AutoLISP code to a file named ascii.lsp.
Then load the file and enter the new ASCII command at the Command
prompt. This command prints the ASCII codes to the screen and to a file
called ascii.txt. The C:ASCII function makes use of another function BASE.
You may find this conversion utility useful in other applications.
; BASE converts from a decimal integer to a string in another base
(defun BASE ( bas int / ret yyy zot )
(defun zot ( i1 i2 / xxx )
(if (> (setq xxx (rem i2 i1)) 9)
(chr (+ 55 xxx))
(itoa xxx)
)
)
(setq ret (zot bas int) yyy (/ int bas))
(while (>= yyy bas)
(setq ret (strcat (zot bas yyy) ret))
(setq yyy (/ yyy bas))
)
(strcat (zot bas yyy) ret)
)

Conversions

88

(defun C:ASCII ( / chk out ct code dec oct hex )


(initget "Yes")
(setq chk (getstring "\nWriting to ASCII.TXT, continue? <Y>: "))
(if (or (= chk "Yes")(= chk ""))
(progn
(setq out (open "ascii.txt" "w") chk 1 code 0 ct 0)
(princ "\n \n CHAR
DEC OCT HEX \n")
(princ "\n \n CHAR
DEC OCT HEX \n" out)
(while chk
(setq dec (strcat " " (itoa code))
oct (base 8 code) hex (base 16 code))
(setq dec (substr dec (- (strlen dec) 2) 3))
(if (< (strlen oct) 3)(setq oct (strcat "0" oct)))
(princ (strcat "\n " (chr code) "
" dec " "
oct " " hex ) )
(princ (strcat "\n " (chr code) "
" dec " "
oct " " hex ) out)
(cond
((= code 255)(setq chk nil))
((= ct 20)
(setq xxx (getstring
"\n \nPress X to eXit or any key to continue: "))
(if (= (strcase xxx) "X")
(setq chk nil)
(progn
(setq ct 0)
(princ "\n \n CHAR
DEC OCT HEX \n")
)
)
)
)
(setq ct (1+ ct) code (1+ code))
)
(close out)
(setq out nil)
)
)
(princ)
)

Unit Conversion
The file acad.unt defines various conversions between real-world units such
as miles to kilometers, Fahrenheit to Celsius, and so on. The function cvunit
takes a value expressed in one system of units and returns the equivalent
value in another system. The two systems of units are specified by strings
containing expressions of units defined in acad.unt.
The cvunit function does not convert incompatible dimensions. For example, it does not convert inches into grams.

Chapter 3

89

Using AutoLISP to Communicate with AutoCAD

The first time that cvunit converts to or from a unit during a drawing editor
session, it must look up the string that specifies the unit in acad.unt. If your
application has many values to convert from one system of units to another,
it is more efficient to convert the value 1.0 by a single call to cvunit and then
use the returned value as a scale factor in subsequent conversions. This works
for all units defined in acad.unt, except temperature scales, which involve an
offset as well as a scale factor.

Converting from Inches to Meters


If the current drawing units are engineering or architectural (feet and inches),
the following routine converts a user-specified distance of inches into
meters:
(defun C:I2M ( / eng_len metric_len eng metric)
(princ "\nConverting inches to meters. ")
(setq eng_len
(getdist "\nEnter a distance in inches: "))
(setq metric_len (cvunit eng_len "inches" "meters"))
(setq eng (rtos eng_len 2 4)
metric (rtos metric_len 2 4))
(princ
(strcat "\n\t" eng " inches = " metric " meters."))
(princ)
)

The Unit Definition File


With the AutoCAD unit definition file acad.unt, you can define factors to
convert data in one set of units to another set of units. The definitions in
acad.unt are in ASCII format and are used by the unit-conversion function
cvunit.
You can make new units available by using a text editor to add their definitions to acad.unt. A definition consists of two lines in the filethe unit name
and the unit definition. The first line must have an asterisk (*) in the first
column, followed by the name of the unit. A unit name can have several
abbreviations or alternate spellings, separated by commas. If a unit name has
singular and plural forms, you can specify these using the following format:
*[ [common] [ ( [singular.] plural) ] ]...

You can specify multiple expressions (singular and plural). They dont have
to be located at the end of the word, and a plural form isnt required.
*inch(es)
*milleni(um.a)
*f(oot.eet) or (foot.feet)

The line following the *unit name line defines the unit as either fundamental
or derived.

Conversions

90

Fundamental Units
A fundamental unit is an expression in constants. If the line following the
*unit name line begins with something other than an equal sign (=), it defines
fundamental units. It consists of five integers and two real numbers in the
following form:
c, e, h, k, m, r1, r2

The five integers correspond to the exponents of these five constants:


c

velocity of light in a vacuum

electron charge

Plancks constant

Boltzmans constant

electron rest mass

As a group, these exponents define the dimensionality of the unit: length,


mass, time, volume, and so on.
The first real number (r1) is a multiplier, and the second (r2) is an additive
offset (used only for temperature conversions). The fundamental unit definition allow for different spellings of the unit (for example, meter and metre);
the case of the unit is ignored. An example of a fundamental unit definition
is as follows.
*meter(s),metre(s),m
-1,0,1,0,-1,4.1214856408e11,0

In this example, the constants that make one meter are


1
1--- h ---- ( 4.1214856 10 11 )
c
m
Derived Units
A derived unit is defined in terms of other units. If the line following the
*unit name line begins with an equal sign (=), it defines derived units. Valid
operators in these definitions are * (multiplication), / (division),
+ (addition), (subtraction), and ^ (exponentiation). You can specify a
predefined unit by naming it, and you can use abbreviations (if provided).
The items in a formula are multiplied together unless some other arithmetic
operator is specified. For example, the units database defines the dimensionless multiple and submultiple names, so you can specify a unit such as
micro-inches by entering micro inch. The following are examples of
derived unit definitions.

Chapter 3

91

Using AutoLISP to Communicate with AutoCAD

; Units of area
*township(s)
=93239571.456 meter^2

The definition of a township is given as 93,239,571.456 square meters.


; Electromagnetic units
*volt(s),v
=watt/ampere

In this example, a volt is defined as a watt divided by an ampere. In the


acad.unt, both watts and amperes are defined in terms of fundamental units.
User Comments
To include comments, begin the line with a semicolon. The comment continues to the end of the line.
; This entire line is a comment

List the acad.unt file itself for more information and examples.

Coordinate System Transformations


The trans function translates a point or a displacement from one coordinate
system into another. It takes a point argument, pt, that can be interpreted as
either a three-dimensional (3D) point or a 3D displacement vector, distinguished by a displacement argument called disp. The disp argument must
be nonzero if pt is to be treated as a displacement vector; otherwise, pt is
treated as a point. A from argument specifies the coordinate system in which
pt is expressed, and a to argument specifies the desired coordinate system.
The following is the syntax for the trans function.
(trans pt from to [disp])

The following AutoCAD coordinate systems can be specified by the from and
to arguments.
WCS

World Coordinate System: the reference coordinate system. All other coordinate systems are defined relative to
the WCS, which never changes. Values measured relative
to the WCS are stable across changes to other coordinate
systems.

UCS

User Coordinate System: the working coordinate system. The user specifies a UCS to make drawing tasks easier.
All points passed to AutoCAD commands, including those
returned from AutoLISP routines and external functions,
are points in the current UCS (unless the user precedes
them with a * at the Command prompt). If you want your

Conversions

92

application to send coordinates in the WCS, OCS, or DCS


to AutoCAD commands, you must first convert them to
the UCS by calling the trans function.
OCS

Object Coordinate System: point values returned by


entget are expressed in this coordinate system, relative to
the object itself. These points are usually converted into
the WCS, current UCS, or current DCS, according to the
intended use of the object. Conversely, points must be
translated into an OCS before they are written to the database by means of entmod or entmake. This is also known as
the Entity Coordinate System.

DCS

Display Coordinate System: the coordinate system into


which objects are transformed before they are displayed.
The origin of the DCS is the point stored in the AutoCAD
system variable TARGET, and its Z axis is the viewing direction. In other words, a viewport is always a plan view of
its DCS. These coordinates can be used to determine
where something will be displayed to the AutoCAD user.
When the from and to integer codes are 2 and 3, in either
order, 2 indicates the DCS for the current model space
viewport and 3 indicates the DCS for paper space (PSDCS).
When the 2 code is used with an integer code other than
3 (or another means of specifying the coordinate system),
it is assumed to indicate the DCS of the current space,
whether paper space or model space. The other argument
is also assumed to indicate a coordinate system in the
current space.

PSDCS

Chapter 3

93

Paper Space DCS: this coordinate system can be transformed only to or from the DCS of the currently active
model space viewport. This is essentially a 2D transformation, where the X and Y coordinates are always scaled and
are offset if the disp argument is 0. The Z coordinate is
scaled but is never translated; therefore, it can be used to
find the scale factor between the two coordinate systems.
The PSDCS (integer code 2) can be transformed only into
the current model space viewport: if the from argument
equals 3, the to argument must equal 2, and vice versa.

Using AutoLISP to Communicate with AutoCAD

Both the from and to arguments can specify a coordinate system in any of
the following ways:

As an integer code that specifies the WCS, current UCS, or current DCS (of
either the current viewport or paper space).
As an entity name returned by one of the entity name or selection set
functions described in Using AutoLISP to Manipulate AutoCAD Objects.
This specifies the OCS of the named object. For planar objects, the OCS
can differ from the WCS, as described in the AutoCAD Users Guide. If the
OCS does not differ, conversion between OCS and WCS is an identity
operation.
As a 3D extrusion vector. Extrusion vectors are always represented in
World coordinates; an extrusion vector of (0,0,1) specifies the WCS itself.

The following table lists the valid integer codes that can be used as the to and
from arguments.

Coordinate system codes


Code

Coordinate system

World (WCS)

User (current UCS)

Display; DCS of current viewport when used with code 0


or1 DCS of current model space viewport when used with
code 3

Paper space DCS, PSDCS (used only with code 2)

The following example translates a point from the WCS into the current
UCS.
(setq pt (1.0 2.0 3.0))
(setq cs_from 0)
(setq cs_to 1)
(trans pt cs_from cs_to 0)

WCS
UCS
disp = 0 indicates that pt is a point

If the current UCS is rotated 90 degrees counterclockwise around the World


Z axis, the call to trans returns a point (2.0,1.0,3.0). However, if you swap
the to and from values, the result differs as shown in the following code.
(trans pt cs_to cs_from 0) ; the result is

(2.0,1.0,3.0)

Point Transformations
If you are doing point transformations with the trans function and you need
to make that part of a program run faster, you can construct your own

Conversions

94

transformation matrix on the AutoLISP side by using trans once to transform each of the basis vectors (0 0 0), (1 0 0), (0 1 0), and (0 0 1). Writing
matrix multiplication functions in AutoLISP can be difficult, so it might not
be worthwhile unless your program is doing a lot of transformations.

File Handling
AutoLISP provides functions for handling files and data I/O. The file-handling functions are as follows:
close

help

read-line

findfile

open

setfunhelp

getfiled

read-char

write-char

write-line

Examples of the findfile, getfiled, and help functions are provided in this
section. The other file handling functions are described in AutoLISP Function Reference.

File Search
An application can use the findfile function to search for a particular file
name. The application can specify the directory to search, or it can use the
current AutoCAD library path.
In the following code fragment, findfile searches for the requested file
name according to the AutoCAD library path:
(setq refname "refc.dwg")
(setq fil (findfile refname))
(if fil
(setq refname fil)
(princ (strcat "\nCould not find file " refname ". " ))
)

If the call to findfile is successful, the variable refname is set to a fully qualified path name string, such as
"/home/work/ref/refc.dwg"

NOTE When specifying a path name, you must precede the backslash (\)
with another backslash so that the path name will be recognized by AutoLISP.
Alternatively, you can use the slash character (/) as a directory separator.

Chapter 3

95

Using AutoLISP to Communicate with AutoCAD

The getfiled function displays a dialog box containing a list of available


files of a specified extension type in the specified directory. This gives
AutoLISP routines access to the AutoCAD Get File dialog box.
A call to getfiled takes four arguments that determine the appearance and
functionality of the dialog box. The application must specify the following
string values, each of which can be nil: a title, placed at the top of the dialog;
a default file name, displayed in the edit box at the bottom of the dialog; and
an extension type, which determines the initial files provided for selection in
the list box. The final argument is an integer value that specifies how the
dialog interacts with selected files.
This simple routine uses getfiled to let you view your directory structure
and select a file:
(defun C:DDIR ( )
(setq dfil (getfiled "Directory Listing" "" "" 2))
(princ (strcat "\nVariable dfil set to selected file " dfil ))
(princ)
)

This is a useful utility command. The variable dfil is set to the file you select,
which can then be used by other AutoLISP functions or as a response to a
command line prompt for a file name. To use this variable in response to a
command line prompt, enter !dfil.
NOTE
line.

You cannot use !dfil in a dialog box. It is valid only at the command

For more information, see getfiled.

Accessing Help Files


The help function provides access to both AutoCAD help files (.ahp) and
Windows Help files (.hlp). Depending on the Help files extension, the help
function calls the AutoCAD or the Windows help viewer with the specified
file. You can use this function to add a help facility to your applications. The
following code fragment calls the default AutoCAD help file and provides
information on the LINE command.
(help "" "line")

You can create a help file that provides information about your applications
or about procedures that you use in your business. The following userdefined command displays your help file morehelp.ahp.

File Handling

96

(defun C:MYHELP ( )
(help "morehelp.ahp")
(princ)
)

See the AutoCAD Customization Guide for information on creating and modifying help files.
The setfunhelp function provides help for user-defined commands. After
the definition of your new command, adding a call to setfunhelp associates
a specific help file and topic with that command. The following example
assigns the help topic Mycmd in the file morehelp.ahp to the user-defined
command MYCMD.
(defun C:MYCMD ( )
.
. Command definition
.
)
(setfunhelp c:mycmd "morehelp.ahp" "mycmd")

Device Access and Control


AutoLISP provides functions for accessing data from the various input
devices. The device access and control functions are as follows:
grread

tablet

The following file-handling functions can also read input from the keyboard
input buffer. (See the AutoCAD Customization Guide for more information on
these functions.)
read-char

read-line

Accessing User Input


The grread function returns raw user input, whether from the keyboard or
from the pointing device (mouse or digitizer); if the call to grread enables
tracking, the function returns a digitized coordinate that can be used for such
things as dragging.
NOTE There is no guarantee that applications calling grread will be upward
compatible. Because it depends on the current hardware configuration, applications that call grread are not likely to work in the same way on all configurations.

Chapter 3

97

Using AutoLISP to Communicate with AutoCAD

Calibrating Tablets
AutoCAD users can calibrate a digitizing tablet by using the TABLET command (see the AutoCAD Command Reference for a description of this command). The tablet function enables applications to manage calibration by
setting the calibrations directly and by saving those settings for future use.
The first argument to the tablet function is an integer code. If code is equal
to 0, the function returns the current calibration. If code is equal to 1, the calibration is set according to the remaining arguments. Calibrations are
expressed as four 3D points (in addition to the code). The first three points
row1, row2, and row3are the three rows of the tablets transformation
matrix. The fourth point, direction, is a vector that is normal to the plane
in which the tablets surface is assumed to lie (expressed in WCS, the World
Coordinate System). When the calibration is set with the TABLET command,
the tablets surface is assumed to lie in the XY plane of the current UCS.
NOTE The TABMODE system variable controls whether Tablet mode is
turned on (1) or off (0). You can control it by using the setvar function.
The following sample routine retrieves the current tablet calibration and
stores it in the variable tcal.
(defun C:TABGET ( )
(setq tcal (tablet 0))
(if tcal
(princ
(strcat "\nConfiguration saved, "
"use TABSET to retrieve calibration.")
)
(princ "\nCalibration not obtainable ")
)
(princ)
)

If the preceding routine was successful, the symbol tcal now contains the list
returned by the tablet function. This list might appear as follows:
(1 (0.00561717 -0.000978942 -7.5171)
(0.000978942 0.00561717 -9.17308)
(0.0 0.0 1.0)
(0.0 0.0 1.0)
)

Device Access and Control

98

To reset the calibration to the values retrieved by the preceding routine, you
can use the C:TABSET routine.
(defun C:TABSET ( )
(if (not (apply tablet tcal))
(princ "\nUnable to reset calibration. ")
(progn
(princ "\nTablet calibration reset. ")
(setvar "tabmode" 1)
(if (= (getvar "tabmode") 0)
(princ "\nUnable to turn on tablet mode ")
)
)
)
(princ)
)

The transformation matrix passed as row1, row2, and row3 is a 33 transformation matrix that is meant to transform a two-dimensional point. The 2D
point is expressed as a column vector in homogeneous coordinates (by appending 1.0 as the third element), so the transformation looks like this:

M 00 M 01 M 02
X
X
Y = M 10 M 11 M 12 Y
1.0
D
M 20 M 21 1.0
The calculation of a point is similar to the 3D case. AutoCAD transforms the
point by using the following formulas:

X = M 00 X + M 01 Y + M 02
Y = M 10 X + M 11 Y + M 12
D = M 20 X + M 21 Y + 1.0
To turn the resulting vector back into a 2D point, the first two components
are divided by the third component (the scale factor D) yielding the point
(X/D,Y/D).
For projective transformations, the most general case, tablet does the full
calculation. But for affine and orthogonal transformations, M20 and M21 are
both 0, so D would be 1.0. The calculation of D and the division are omitted; the resulting 2D point is simply (X,Y).

Chapter 3

99

Using AutoLISP to Communicate with AutoCAD

As the previous paragraph implies, an affine transformation is a special, uniform case of a projective transformation. An orthogonal transformation is a
special case of an affine transformation: not only are M20 and M21 zero, but
M00 = M11 and M10 = M01.
NOTE When you set a calibration, the list returned does not equal the list provided if the direction isnt normalized; AutoCAD normalizes the direction vector
before it returns it. Also, it ensures that the third element in the third column
(row3[Z]) is equal to 1. This situation should not arise if you set the calibration
by using values retrieved from AutoCAD by means of tablet. However, it can
happen if your program calculates the transformation itself.

Device Access and Control

100

Chapter 3

101

Using AutoLISP to Communicate with AutoCAD

4
Using AutoLISP to
Manipulate AutoCAD
Objects
In this chapter

Most AutoLISP functions that handle selection sets and

Selection Set
Handling

Object Handling

Extended Data
Xdata

Xrecord Objects

Symbol Table and


Dictionary Access

objects identify a set or an object by its entity name. Before


it can manipulate a selection set or object, an AutoLISP
application must first obtain the current name by calling
one of the functions that return a selection set or entity
name.
For selection sets, which are valid only in the current
session, the volatility of names poses no problem, but it
does for objects because they are saved in the drawing
database. An application that must refer to the same objects
in the same drawing (or drawings) at different times can use
the objects handles.

102

AutoLISP uses symbol tables to maintain lists of graphic and nongraphic data
related to a drawing, such as layers, linetypes, and block definitions. Each
symbol table entry has a related entity name and handle and can be manipulated in a manner similar to the way that other AutoCAD entities are
manipulated.
NOTE The AutoLISP examples in this chapter show code entered from the
AutoCAD Command prompt, not the Visual LISP Console.

Selection Set Handling


AutoLISP provides functions for handling selection sets. The selection
sethandling functions are as follows:

ssadd

ssget

ssmemb

ssdel

sslength

ssname

The ssget function provides the most general means of creating a selection
set. It can create a selection set in one of the following ways:

By explicitly specifying the objects to select, using the Last, Previous, Window, Implied, WPolygon, Crossing, CPolygon, or Fence options.
By specifying a single point.
By selecting the entire database.
By prompting the user to select objects.

With either option, you can use filtering to specify a list of attributes and conditions that the selected objects must match.
NOTE Selection set and entity names are volatile; that is, they apply only to
the current drawing session.
The first argument to ssget is a string that describes which selection option
to use. The next two arguments, pt1 and pt2, specify point values for the relevant options (they should be left out if they dont apply). A point list,
pt-list, must be provided as an argument to the selection methods that
allow selection by polygons (that is, Fence, Crossing Polygon, and Window
Polygon). The last argument, filter-list, is optional. If filter-list is supplied, it specifies the list of entity field values used in filtering. The following
table summarizes the available mode values and the arguments used with

Chapter 4

103

Using AutoLISP to Manipulate AutoCAD Objects

each. (A filter-list can be used as an additional argument to all of the


selection methods listed.)
Selection options for ssget
Mode

Selection method

Prototypes

none

User selection or single-point


selection (if pt1 is specified)

(ssget) or
(ssget pt1)

"L"

Last created object visible on


screen

(ssget "L")

NOTE If mode "X" is specified and a filter-list is not provided, ssget


selects all entities in the database, including entities on layers that are off, frozen,
and out of the visible screen.
The following code shows calls to ssget.
(setq pt1
pt2
pt3
pt4
)
(setq ss1

(0.0
(5.0
(4.0
(2.0

0.0
5.0
1.0
6.0

0.0)
0.0)
0.0)
0.0)

(ssget))

Sets pt1, pt2, pt3, and pt4 to point values

Asks the user for a general object selection


and places those items in a selection set

(setq ss1 (ssget "P"))

Creates a selection set of the most recently


selected objects

(setq ss1 (ssget "L"))

Creates a selection set of the last object added


to the database that is visible on the screen

(setq ss1 (ssget pt2))

Creates a selection set of an object passing


through point (5,5)

(setq ss1 (ssget "W" pt1 pt2))

Creates a selection set of the objects inside the

window from (0,0) to (5,5)


(setq ss1 (ssget "F" (list pt2 pt3 pt4))) Creates a selection set of the objects crossing
the fence and defined by the points (4,1),

and (2,6)
(setq ss1 (ssget "WP" (list pt1 pt2 pt3)))Creates a selection set of the objects inside the
polygon defined by the point (0,0),(5,5), and
(4,1)
(setq ss1

(ssget "X"))

Creates a selection set of all objects in the


database

Selection Set Handling

104

When an application has finished using a selection set, it is important to


release it from memory. You can do this by setting it to nil.
(setq ss1 nil)

NOTE Attempting to manage a large number of selection sets simultaneously


is not recommended. An AutoLISP application cannot have more than 128 selection sets open at once. (The limit may be lower on your system.) When the limit
is reached, AutoCAD refuses to create more selection sets. Keep a minimum
number of sets open at a time, and set unneeded selection sets to nil as soon as
possible. If the maximum number of selection sets is reached, you must call gc
before another ssget will work.

Selection Set Filter Lists


An entity filter list is an association list that uses DXF group codes in the
same format as a list returned by entget. The ssget function recognizes all
group codes except entity names (group 1), handles (group 5), and xdata
codes (groups greater than 1000). If an invalid group code is used in a
filter-list, it is ignored by ssget.
When a filter-list is provided as the last argument to ssget, the function
scans the selected objects and creates a selection set containing the names of
all main entities matching the specified criteria. For example, you can obtain
a selection set that includes all objects of a given type, on a given layer, or of
a given color.
The filter-list specifies which property (or properties) of the entities are
to be checked and what values constitute a match.
The following examples demonstrate methods of using a filter-list with
various mode selection options.
Prompts for general object selection but
adds only text objects to the selection set

(setq ss1 (ssget


((0 . "TEXT")))
)

Chapter 4

105

(setq ss1 (ssget "P"


((0 . "LINE")))
)

Creates a selection set of the most recently


selected objects that are also line objects

(setq ss1 (ssget "W" pt1 pt2


((8 . "FLOOR9")))
)

Creates a selection set of all objects inside


the window that are also on layer FLOOR9

Using AutoLISP to Manipulate AutoCAD Objects

(setq ss1 (ssget "X"


((0 . "CIRCLE")))
)

Creates a selection set of all objects in the


database that are circle objects

If both the code and the desired value are known, the list may be quoted as
shown previously. If either is specified by a variable, the list must be constructed (using the list and cons functions).
(setq lay_name "FLOOR3")
(setq ss1
(ssget "X"
(list (cons 8 lay_name))
)
)

Creates a selection set of all objects in the


database that are on layer FLOOR3

If the filter-list specifies more than one property, an entity is included in


the selection set only if it matches all specified conditions, as in the following
example:
(ssget "X"

(list

(cons 0 "CIRCLE")(cons 8 lay_name)(cons 62 1)))

This code selects only circle objects on layer FLOOR3 that are the color red.
This type of test performs a Boolean AND operation.
The ssget function filters a drawing by scanning the selected entities and
comparing the fields of each main entity against the specified filtering list. If
an entitys properties match all specified fields in the filtering list, it is
included in the returned selection set. Otherwise, the entity is not included
in the selection set. The ssget function returns nil if no entities from those
selected match the specified filtering criteria.
NOTE The meaning of certain group codes can differ from entity to entity,
and not all group codes are present in all entities. If a particular group code is
specified in a filter, entities not containing that group code are excluded from the
selection set that ssget returns.
When ssget filters a drawing, the selection set it retrieves might include entities from both paper space and model space. However, when the selection set
is passed to an AutoCAD command, only entities from the space that is currently in effect are used.

Selection Set Handling

106

Wild-Card Patterns in Filter Lists


Symbol names specified in filtering lists can include wild-card patterns. The
wild-card patterns recognized by ssget are the same as those recognized by
the function wcmatch, and are described in Wild-Card Matching on
page 50 and under wcmatch.
NOTE When filtering for anonymous blocks, you must precede the * character with a reverse single quotation mark (), also known as an escape character,
because the * is read by ssget as a wild-card character. For example, you can
retrieve an anonymous block named *U2 with the following:
(ssget "X" ((2 . "`*U2")))

Filtering for Extended Data


Using the ssget filter-list, you can select all entities containing extended
data for a particular application. To do this, use the 3 group code, as shown
in the following example:
(ssget "X" ((0 . "CIRCLE") (-3 ("APPNAME"))))

This code would select all circles that include extended data for the "APPNAME"
application. If more than one application name is included in the 3 groups
list, an AND operation is implied and the entity must contain extended data
for all of the specified applications. So the following statement would select
all circles with extended data for both the "APP1" and "APP2" applications.
(ssget "X" ((0 . "CIRCLE") (-3 ("APP1")("APP2"))))

Wild-card matching is permitted, so either of the following statements would


select all circles with extended data for either or both of these applications.
(ssget "X" ((0 . "CIRCLE") (-3 ("APP[12]"))))
(ssget "X" ((0 . "CIRCLE") (-3 ("APP1,APP2"))))

Relational Tests
Unless otherwise specified, an equivalency is implied for each item in the
filter-list. For numeric groups (integers, reals, points, and vectors), you
can specify other relations by including a special 4 group code that specifies
a relational operator. The value of a 4 group is a string indicating the test
operator to be applied to the next group in the filter-list. For more
information, see Relational Tests in AutoLISP Function Reference.
The following selects all circles with a radius (group code 40) greater than or
equal to 2.0:
(ssget "X" ((0 . "CIRCLE") (-4 . ">=") (40 . 2.0)))

Chapter 4

107

Using AutoLISP to Manipulate AutoCAD Objects

Logical Grouping of Filter Tests


You can also test groups by creating nested Boolean expressions that use the
logical grouping operators shown under Logical Grouping of Filter Tests in
the AutoLISP Function Reference. The grouping operators are specified by
4 groups, like the relational operators. They are paired and must be balanced
correctly in the filter list or the ssget call will fail. An example of grouping
operators in a filter list follows:
(ssget "X"
(
(-4 . "<OR")
(-4 . "<AND")
(0 . "CIRCLE")
(40 . 1.0)
(-4 . "AND>")
(-4 . "<AND")
(0 . "LINE")
(8 . "ABC")
(-4 . "AND>")
(-4 . "OR>")
)
)

This code selects all circles with a radius of 1.0 plus all lines on layer "ABC".
The grouping operators are not case sensitive.
Grouping operators are not allowed within the 3 group itself. Multiple
application names specified in a 3 group use an implied AND operator. If
you want to test for extended data using other grouping operators, specify
separate 3 groups and group them as desired. To select all circles having
extended data for either application "APP1" or "APP2" but not both, enter the
following:
(ssget "X"
((0 . "CIRCLE")
(-4 . "<XOR")
(-3 ("APP1"))
(-3 ("APP2"))
(-4 . "XOR>")
)
)

Selection Set Handling

108

You can simplify the coding of frequently used grouping operators by setting
them equal to a symbol. The previous example could be rewritten as follows
(notice that in this example you must explicitly quote each list):
(setq <xor (-4 . "<XOR")
xor> (-4 . "XOR>") )
(ssget "X"
(list
(0 . "CIRCLE")
<xor
(-3 ("APP1"))
(-3 ("APP2"))
xor>
)
)

As you can see, this method may not be sensible for short pieces of code but
can be beneficial in larger applications.

Selection Set Manipulation


Once a selection set has been created, you can add entities to it or remove
entities from it with the functions ssadd and ssdel. You can use the ssadd
function to create a new selection set, as shown in the following example.
The following code fragment creates a selection set that includes the first and
last entities in the current drawing (entnext and entlast are described later
in this chapter).
(setq fname (entnext))
(setq lname (entlast))
(if (not fname)
(princ "\nNo entities in drawing.
(progn
(setq ourset (ssadd fname))
(ssadd lname ourset)
)
)

Gets first entity in the drawing


Gets last entity in the drawing
")

Creates a selection set of the first entity


Adds the last entity to the selection set

The example runs correctly even if only one entity is in the database (in
which case both entnext and entlast set their arguments to the same entity
name). If ssadd is passed the name of an entity already in the selection set,
it ignores the request and does not report an error. The following function
removes the first entity from the selection set created in the previous
example:
(ssdel fname ourset)

If there is more than one entity in the drawing (that is, if fname and lname
are not equal), then the selection set ourset contains only lname, the last
entity in the drawing.

Chapter 4

109

Using AutoLISP to Manipulate AutoCAD Objects

The function sslength returns the number of entities in a selection set, and
ssmemb tests whether a particular entity is a member of a selection set. Finally,
the function ssname returns the name of a particular entity in a selection set,
using an index to the set (entities in a selection set are numbered from 0).
The following code shows calls to ssname:
(setq sset (ssget))
Prompts the user to create a selection set
(setq ent1 (ssname sset 0))
Gets the name of the first entity in sset
(setq ent4 (ssname sset 3))
Gets the name of the fourth entity in sset
(if (not ent4)
(princ "\nNeed to select at least four entities. ")
)
(setq ilast (sslength sset))
Finds index of the last entity in sset
Gets the name of the last entity in sset
(setq lastent (ssname sset (1- ilast)))

Regardless of how entities have been added to a selection set, the set never
contains duplicate entities. If the same entity is added more than once, the
later additions are ignored. Therefore, sslength accurately returns the number of distinct entities in the specified selection set.

Passing Selection Sets Between AutoLISP and


ObjectARX Applications
When passing selection sets between AutoLISP and ObjectARX applications,
the following should be observed:
If a selection set is created in AutoLISP and stored in an AutoLISP variable,
then overwritten by a value returned from an ObjectARX application, the
original selection set is eligible for garbage collection (it is freed at the next
automatic or explicit garbage collection).
This is true even if the value returned from the ObjectARX application was
the original selection set. In the following example, if the adsfunc
ObjectARX function returns the same selection set it was fed as an argument,
then this selection set will be eligible for garbage collection even though it is
still assigned to the same variable.
(setq var1 (ssget))
(setq var1 (adsfunc var1))

If you want the original selection set to be protected from garbage collection,
then you must not assign the return value of the ObjectARX application to
the AutoLISP variable that already references the selection set. Changing the
previous example as follows prevents the selection set referenced by var1
from being eligible for garbage collection:
(setq var1 (ssget))
(setq var2 (adsfunc var1))

Selection Set Handling

110

Object Handling
AutoLISP provides functions for handling objects. The object-handling
functions are as follows:

entdel

entlast

entmod

entupd

entget

entmake

entnext

handent

The object-handling functions are organized into two categories: functions


that retrieve the entity name of a particular object, and functions that
retrieve or modify entity data.

Entity Name Functions


To operate on an object, an AutoLISP application must obtain its entity name
for use in subsequent calls to the entity data or selection set functions. Two
of the functions described in this section, entsel and nentsel, return not
only the entitys name but also additional information for the applications
use.
Both functions require the AutoCAD user to select an object interactively by
picking a point on the graphics screen. All of the other entity name functions
can retrieve an entity even if it is not visible on the screen or if it is on a
frozen layer. The entsel function prompts the user to select an object by
picking a point on the graphics screen, and entsel returns both the entity
name and the value of the point selected. Some entity operations require
knowledge of the point by which the object was selected. Examples from the
set of existing AutoCAD commands include BREAK, TRIM, and EXTEND.
These functions accept key words if they are preceded by a call to initget.
The entnext function retrieves entity names sequentially. If entnext is called
with no arguments, it returns the name of the first entity in the drawing database. If its argument is the name of an entity in the current drawing, entnext
returns the name of the succeeding entity.
The following code fragment illustrates how ssadd can be used in conjunction with entnext to create selection sets and add members to an existing set.

Chapter 4

111

Using AutoLISP to Manipulate AutoCAD Objects

(setq e1 (entnext))
(if (not e1)
Sets e1 to name of first entity
(princ "\nNo entities in drawing. ")
(progn
(setq ss (ssadd))
Sets ss to a null selection set
(ssadd e1 ss)
Returns selection set ss with e1 added
(setq e2 (entnext e1))
Gets entity following e1
(ssadd e2 ss)
Adds e2 to selection set ss
)
)

The entlast function retrieves the name of the last entity in the database.
The last entity is the most recently created main entity, so entlast can be
called to obtain the name of an entity that has just been created with a call
to command.
You can set the entity name returned by entnext to the same variable name
passed to this function. This walks a single entity name variable through
the database, as shown in the following example:
(setq one_ent (entnext))

Gets name of first entity

(while one_ent
.
.
Processes new entity
.
(setq one_ent (entnext one_ent))
)

Value of one_ent is now nil

Entity Handles and Their Uses


The handent function retrieves the name of an entity with a specific handle.
As with entity names, handles are unique within a drawing; however, an
entitys handle is constant throughout its life. AutoLISP applications that
manipulate a specific database can use handent to obtain the current name
of an entity they must use. You can use the DDMODIFY command to get the
handle of a selected object.
The following code fragment uses handent to obtain and display an entity
name.
(if (not (setq e1 (handent "5a2")))
(princ "\nNo entity with that handle exists. ")
(princ e1)
)

In one particular editing session, this code fragment might display the
following:
<Entity name: 60004722>

Object Handling

112

In another editing session with the same drawing, the fragment might
display an entirely different number. But in both cases the code would be
accessing the same entity.
The handent function has an additional use. Entities that have been deleted
from the database (with entdel, described in the following section) are not
purged until the current drawing ends. This means that handent can recover
the names of deleted entities, which can then be restored to the drawing by
a second call to entdel.
NOTE

Handles are provided for block definitions, including subentities.

Entities in drawings that are cross-referenced by way of XREF Attach are not
actually part of the current drawing; their handles are unchanged but cannot
be accessed by handent. However, when drawings are combined by means of
INSERT, INSERT *, XREF Bind ( XBIND), or partial DXFIN, the handles of entities in the incoming drawing are lost, and incoming entities are assigned new
handle values to ensure that each handle in the current drawing remains
unique.

Entity Context and Coordinate Transform Data


The nentsel and nentselp functions are similar to entsel, except that they
return two additional values to handle entities nested within block
references.
Another difference between these functions is that when the user responds
to a nentsel call by selecting a complex entity or a complex entity is selected
by nentselp, these functions return the entity name of the selected subentity
and not the complex entitys header, as entsel does.
For example, when the user selects a polyline, nentsel returns a vertex subentity instead of the polyline header. To retrieve the polyline header, the
application must use entnext to walk forward to the seqend subentity, and
then obtain the name of the header from the seqend subentitys 2 group.
The same applies when the user selects attributes in a nested block reference.
The nentselp function is preferred to nentsel, because it returns a transformation matrix of the same format as that returned by grvecs.
The first of the additional elements returned by nentsel is the Model to
World Transformation Matrix. It is a list consisting of four sublists, each of
which contains a set of coordinates. This matrix can be used to transform the
entity definition data points from an internal coordinate system called the
Model Coordinate System (MCS) to the WCS. The insertion point of the
block (this refers to xrefs also) containing the selected object defines the origin of the MCS. The orientation of the UCS when the block is created determines the direction of the MCS axes.

Chapter 4

113

Using AutoLISP to Manipulate AutoCAD Objects

The second additional element is a list containing the entity name of the
block that contains the selected object. If the selected object is contained in
a nested block (a block within a block), the list also contains the entity names
of all blocks in which the selected entity is nested, starting with the innermost block and continuing outward until the name of the outermost block
that was inserted in the drawing is reported.
(<Entity Name: ename1>
(Px Py Pz)
( (X0 Y0 Z0)
(X1 Y1 Z1)
(X2 Y2 Z2)
(X3 Y3 Z3)
)
(<Entity name: ename2>
.
.
.
<Entity name: enamen>)
)

Name of entity
Pick point
Model to World
transformation matrix

Name of most deeply nested block


containing selected object
Name of outermost block
containing selected object

In the following example, create a block to use with the nentsel function.
Command: line
From point: 1,1
to point: 3,1
to point: 3,3
to point: 1,3
to point: c
Command: block
Block name (or ?): square
Insertion base point: 2,2
Select objects: Select the four lines you just drew
Select objects: ENTER
Then insert the block in a UCS rotated 45 degrees about the Z axis:
Command: ucs
Origin/ZAxis/3point/obJect/View/X/Y/Z/Prev/Restore/Save/Del/?/
<World>: z
Rotation angle about Z axis <0>: 45
Command: insert
Block name (or ?): square
Insertion point: 7,0
X scale factor <1> / Corner / XYZ: ENTER
Y scale factor (default=X): ENTER
Rotation angle: ENTER

Object Handling

114

Use nentsel to select the lower-left side of the square.


(setq ndata (nentsel))

This code sets ndata equal to a list similar to the following:


(<Entity Name: 400000a0>
(6.46616 -1.0606 0.0)
((0.707107 0.707107 0.0)
(-0.707107 0.707107 0.0)
(0.0 -0.0 1.0)
(4.94975 4.94975 0.0)
)
(<Entity name:6000001c>)
)

Entity name
Pick point
Model to World
Transformation Matrix

Name of block containing selected object

Once you have obtained the entity name and the Model to World Transformation Matrix is obtained, you can transform the entity definition data
points from the MCS to the WCS. Use entget and assoc on the entity name
to obtain the desired definition points expressed in MCS coordinates. Then
pass the points and the Model to World Transformation Matrix data
(obtained in the first nentsel call) to the formulas that follow.
If the selected entity is not a nested entity, the transformation matrix is set
to the identity matrix.
1
0
0
0

0
1
0
0

0
0
1
0

The following equations show how to transform a point or vector.

X = XM 00 + YM 10 + ZM 20 + M 30
Y = XM 01 + YM 11 + ZM 21 + M 31
Z = XM 02 + YM 12 + ZM 22 + M 32
The Mij, where 0 i, j 2, are the Model to World Transformation Matrix
coordinates; X, Y, and Z is the entity definition data point expressed in MCS
coordinates; and X, Y, and Z is the resulting entity definition data point
expressed in WCS coordinates.
NOTE To transform a vector (rather than a point), do not add the translation
vector [M30 M31 M32] (from the fourth column of the transformation matrix).

Chapter 4

115

Using AutoLISP to Manipulate AutoCAD Objects

The following example illustrates how to obtain the MCS start point of a line
(group code 10) contained in a block definition. The statement stores the
entity data (using the entity name obtained with nentsel earlier) in the symbol edata. It returns the following:
(setq edata (assoc 10
(10 -1.0 1.0 0.0)

(entget

(car ndata))))

The following statement stores the Model to World Transformation Matrix


sublist in the symbol matrix.
(setq matrix (caddr ndata))

It returns the following:


((0.707107 0.707107 0.0)
(-0.707107 0.707107 0.0)
(0.0 -0.0 1.0)
(4.94975 4.94975 0.0)
)

X transformation
Y transformation
Z transformation
Displacement from WCS origin

Apply the transformation formula for X to change the X coordinate of the


start point of the line from an MCS coordinate to a WCS coordinate. Store
the results in the symbol answer:
(setq answer
(+
(* (car (nth 0 matrix))(cadr edata))
(* (car (nth 1 matrix))(caddr edata))
(* (car (nth 2 matrix))(cadddr edata))
(car (nth 3 matrix))
)
)

add:
M00 * X
M10 * Y
M20 * Z
M30

This statement returns 3.53553, the WCS X coordinate of the start point of
the selected line.

Entity Access Functions


The entity access functions are relatively slow. It is best to get the contents of
a particular entity (or symbol table entry) once and keep that information
stored in memory, rather than repeatedly ask AutoCAD for the same data. Be
sure that the data remains valid; if the user has an opportunity to alter the
entity or symbol table entry, you should reissue the entity access function to
ensure the validity of the data.

Entity Data Functions


The functions described in this section operate on entity data and can be
used to modify the current drawing database.

Object Handling

116

The entdel function deletes a specified entity. The entity is not purged from
the database until the end of the current drawing session, so if the application calls entdel a second time during that session and specifies the same
entity, the entity is undeleted.
NOTE Attributes and polyline vertices cannot be deleted independently of
their parent entities. The entdel function operates only on main entities. If you
need to delete an attribute or vertex, you can use command to invoke the
AutoCAD ATTEDIT or PEDIT commands.
The entget function returns the definition data of a specified entity. The data
is returned as a list. Each item in the list is specified by a DXF group code. The
first item in the list contains the entitys current name.
In this example, the following (default) conditions apply to the current
drawing:

Layer is 0
Linetype is CONTINUOUS
Elevation is 0

The user has drawn a line with the following sequence of commands.
Command: line
From point: 1,2
To point: 6,6
To point: ENTER
An AutoLISP application can retrieve and print the definition data for the
line by using the following AutoLISP function:
(defun C:PRINTDXF ( )
(setq ent (entlast))
(setq entl (entget ent))
(setq ct 0)
(textpage)
(princ "\nentget of last entity:")
(repeat (length entl)
(print (nth ct entl))
(setq ct (1+ ct))
)
(princ)

Sets ent to the last entity


Sets entl to the last entitys association
list of the last entity
Sets ct (a counter) to 0
Switches to the text screen
Repeats for the number of members in the list
Prints a newline and then each list member
Increments the counter by one
Exits quietly

Chapter 4

117

Using AutoLISP to Manipulate AutoCAD Objects

This would print the following:


Results from entget of last entity:
(1 . <Entity name: 60000014>)
(0 . "LINE")
(8 . "0")
(5 . "2D")
(10 1.0 2.0 0.0)
(11 6.0 6.0 0.0)
(210 0.0 0.0 1.0)
The first member of the list (1) contains the name of the entity that this list
represents. The entmod function, which is described in this section, uses it to
identify the entity to be modified.
The codes for the components of the entity are those used by DXF. As with
DXF, the entity header items (color, linetype, thickness, the attributes-follow
flag, and the entity handle) are returned only if they have values other than
the default. Unlike DXF, optional entity definition fields are returned
whether or not they equal their defaults and associated X, Y, and Z coordinates are returned as a single point variable rather than as separate X (10), Y
(20), and Z (30) groups.
The assoc function searches a list for a group of a specified type. The following code returns the object type "LINE" (0) from the list entl.
(cdr (assoc 0 entl))

If the DXF group code specified is not present in the list (or if it is not a valid
DXF group), assoc returns nil.
The entmod function modifies an entity. It passes a list that has the same format as a list returned by entget but with some of the entity group values
(presumably) modified by the application. This function complements
entget. The primary mechanism by which an AutoLISP application updates
the database is by retrieving an entity with entget, modifying its entity list,
and then passing the list back to the database with entmod.

Object Handling

118

The following code fragment retrieves the definition data of the first entity
in the drawing and changes its layer property to MYLAYER.
(setq en (entnext))
Sets en to the first entity name in the drawing
(setq ed (entget en))
Sets ed to the entity data for entity name en
(setq ed
(subst (cons 8 "MYLAYER")
(assoc 8 ed)
Changes the layer group in ed
ed
to layer MYLAYER
)
)
(entmod ed)
Modifies entity ens layer in the drawing

There are restrictions on the changes to the database that entmod can make;
entmode cannot change the following:

The entitys type or handle.


Internal fields. (Internal fields are the values that AutoCAD assigns to certain group codes: 2, entity name reference; 1, entity name; 5, entity
handle.) Any attempt to change an internal fieldfor example, the main
entity name in a seqend subentity (group 2)is ignored.
Viewport entities. An attempt to change a viewport entity causes an error.

Other restrictions apply when modifying dimensions and hatch patterns.


AutoCAD must recognize all objects (except layers) that the entity list refers
to. The name of any text style, linetype, shape, or block that appears in an
entity list must be defined in the current drawing before the entity list is
passed to entmod. There is one exception: entmod accepts new layer names.
If the entity list refers to a layer name that has not been defined in the
current drawing, entmod creates a new layer. The attributes of the new layer
are the standard default values used by the New option of the AutoCAD
LAYER command.
The entmod function can modify subentities such as polyline vertices and
block attributes.
NOTE If you use entmod to modify an entity in a block definition, this affects
all INSERT or XREF references to that block. Also, entities in block definitions
cannot be deleted by entdel.
An application can also add an entity to the drawing database by calling the
entmake function. Like that of entmod, the argument to entmake is a list
whose format is similar to that returned by entget. The new entity that the
list describes is appended to the drawing database (it becomes the last entity
in the drawing). If the entity is a complex entity (a polyline or block), it is
not appended to the database until it is complete.

Chapter 4

119

Using AutoLISP to Manipulate AutoCAD Objects

The following code fragment creates a circle on the layer MYLAYER.


(entmake ((0 . "CIRCLE")
(8 . "MYLAYER")
(10 5.0 7.0 0.0)
(40 . 1.0)
) )

Object type
Layer
Center point
Radius

The restrictions on entmake are similar to those for entmod:

The first or second member in the list must specify the object type. The
type must be a valid DXF group code. If the first member does not specify
the type, it can specify only the name of the entity: group 1 (the name is
not saved in the database).
AutoCAD must recognize all objects (except layers) that the entity list
refers to. There is one exception: entmake accepts new layer names.
Any internal fields passed to entmake are ignored.
entmake cannot create viewport entities.

Both entmod and entmake perform the same consistency checks on the entity
data passed to them as the DXFIN command performs when reading DXF
files. They will fail if they cannot create valid drawing entities.

Working with Blocks


There is no direct method for an application to check whether a block listed
in the BLOCK table is actually referenced by an insert object in the drawing.
You can use the following code to scan the drawing for instances of a block
reference:
(ssget "x" ((2 . "BLOCKNAME")) )

You must also scan each block definition for instances of nested blocks.

Anonymous Blocks
The block definitions (BLOCK) table in a drawing can contain anonymous
blocks (also known as unnamed blocks), which AutoCAD creates to support
hatch patterns and associative dimensioning. The entmake function can create anonymous blocks other than *Dnnn (dimensions) and *Xnnn (hatch
patterns). Unreferenced anonymous blocks are purged from the BLOCK table
at the beginning of each drawing session. Referenced anonymous blocks
(those that have been inserted) are not purged. You can use entmake to create
a block reference (insert object) to an anonymous block. (You cannot pass an
anonymous block to the INSERT command.) Also, you can use entmake to
redefine the block. You can modify the entities in a block (but not the block
object itself) with entmod.

Object Handling

120

The name (group 2) of an anonymous block created by AutoLISP or ARX has


the form *Unnn, where nnn is a number generated by AutoCAD. Also, the loworder bit of an anonymous blocks block type flag (group 70) is set to 1. When
entmake creates a block whose name begins with * and whose anonymous bit
is set, AutoCAD treats this as an anonymous block and assigns it a name. Any
characters following the * in the name string passed to entmake are ignored.
NOTE Anonymous block names do not remain constant. Although a referenced anonymous block becomes permanent, the numeric portion of its name
can change between drawing sessions.

Creating Complex Entities


To create a complex entity (a polyline or block), you make multiple calls to
entmake, using a separate call for each subentity. When entmake first receives
an initial component for a complex entity, it creates a temporary file in
which to gather the definition data (and extended data, if that is present.).
For each subsequent entmake call, the function checks to see if the temporary
file exists. If it does, the new subentity is appended to the file. When the definition of the complex entity is complete (that is, when entmake receives an
appropriate seqend or endblk subentity), the entity is checked for consistency; if it is valid, it is added to the drawing. The file is deleted when the
complex entity is complete or when its creation has been cancelled.
NOTE The entity does not appear in the drawing database until the final
seqend or endblk subentity has been passed to entmake. Specifically, entlast
cannot be used to retrieve the most recently created subentity for a complex
entity that has not been completed.
As the previous paragraphs imply, entmake can construct only one complex
entity at a time. If a complex entity is being created and entmake receives
invalid data or an entity that is not an appropriate subentity, both the invalid
entity and the entire complex entity are rejected. You can explicitly cancel
the creation of a complex entity by calling entmake with no arguments.
The following example contains five entmake functions that create a single
complex entity, a polyline. The polyline has a linetype of DASHED and a
color of BLUE. It has three vertices located at coordinates (1,1,0), (4,6,0), and
(3,2,0). All other optional definition data assume default values. (For this
example to work properly, the linetype DASHED must be loaded.)

Chapter 4

121

Using AutoLISP to Manipulate AutoCAD Objects

(entmake ((0 . "POLYLINE")


(62 . 5)
(6 . "dashed")
(66 . 1)
) )
(entmake ((0 . "VERTEX")
(10 1.0 1.0 0.0)
) )
(entmake ((0 . "VERTEX")
(10 4.0 6.0 0.0)
) )
(entmake ((0 . "VERTEX")
(10 3.0 2.0 0.0)
) )
(entmake ((0 . "SEQEND")))

Object type
Color
Linetype
Vertices follow
Object type
Start point
Object type
Second point
Object type
Third point
Sequence end

NOTE When defining dotted pairs, as in the above example, there must be a
space on both sides of the dot. Otherwise you will get an invalid dotted pair error
message.
Block definitions begin with a block entity and end with an endblk subentity.
Block definitions cannot be nested, nor can they reference themselves. A
block definition can contain references to other block definitions.
NOTE Before you use entmake to create a block, you should use tblsearch
to ensure that the name of the new block is unique. The entmake function does
not check for name conflicts in the block definitions table, so it can redefine
existing blocks.
Block references can include an attributes-follow flag (group 66). If present
and equal to 1, a series of attribute (attrib) entities is expected to follow the
insert object. The attribute sequence is terminated by a seqend subentity.
Polyline entities always include a vertices-follow flag (also group 66). The
value of this flag must be 1, and the flag must be followed by a sequence of
vertex entities, terminated by a seqend subentity.
Complex entities can exist in either model space or paper space but not both.
If you have changed the current space by invoking either MSPACE or PSPACE
(with command) while a complex entity is being constructed, a subsequent call
to entmake cancels the complex entity. This can also occur if the subentity
has a 67 group whose value does not match the 67 group of the entity header.

Object Handling

122

Entity Data Functions and the Graphics Screen


Changes to the drawing made by the entity data functions are reflected on
the graphics screen, provided that the entity being deleted, undeleted, modified, or made is in an area and on a layer that is currently visible. There is
one exception to this: when entmod modifies a subentity, it does not update
the image of the entire (complex) entity. If, for example, an application modifies 100 vertices of a complex polyline with 100 calls to entmod, the time
required to recalculate and redisplay the entire polyline is unacceptably slow.
Instead, an application can perform a series of subentity modifications and
then redisplay the entire entity with a single call to the entupd function.
Consider the following: If the first entity in the current drawing is a polyline
with several vertices, the following code modifies the second vertex of the
polyline and regenerates its screen image.
(setq e1 (entnext))
(setq v1 (entnext e1))
(setq v2 (entnext v1))
(setq v2d (entget v2))
(setq v2d
(subst
(10 1.0 2.0 0.0)
(assoc 10 v2d)
v2d
)
)
(entmod v2d)
(entupd e1)

Sets e1 to the polylines entity name


Sets v1 to its first vertex
Sets v2 to its second vertex
Sets v2d to the vertex data

Changes the vertexs location in v2d


to point (1,2,0)
Moves the vertex in the drawing
Regenerates the polyline entity e1

The argument to entupd can specify either a main entity or a subentity. In


either case, entupd regenerates the entire entity. Although its primary use is
for complex entities, entupd can regenerate any entity in the current
drawing.
NOTE To ensure that all instances of the block references are updated, you
must regenerate the drawing by invoking the AutoCAD REGEN command (with
command). The entupd function is not sufficient if the modified entity is in a block
definition.

Polylines and Lwpolylines


An lwpolyline is defined in the drawing database as a single graphic entity.
This is different than a standard polyline, which is defined as a group of subentities. Lwpolylines display faster and consume less disk space and RAM.

Chapter 4

123

Using AutoLISP to Manipulate AutoCAD Objects

As of Release 14 of AutoCAD, 3D polylines are always created as standard


polyline entities. 2D polylines are created as lwpolyline entities unless they
have been curved or fitted with the PEDIT command. When a drawing from
an earlier release is opened in Release 14 or a later release, all 2D polylines
convert to lwpolylines automatically unless they have been curved or fitted
or contain xdata.

Processing Curve-Fit and Spline-Fit Polylines


When an AutoLISP application uses entnext to step through the vertices of
a polyline, it might encounter vertices that were not created explicitly. Auxiliary vertices are inserted automatically by the PEDIT commands Fit and
Spline options. You can safely ignore them, because changes to these vertices
will be discarded the next time the user uses PEDIT to fit or spline the
polyline.
The polyline entitys group 70 flags indicate whether the polyline has been
curve-fit (bit value 2) or spline-fit (bit value 4). If neither of these bits is set,
all of the polylines vertices are regular user-defined vertices. However, if the
curve-fit bit (2) is set, alternating vertices of the polyline have the bit value 1
set in their 70 group to indicate that they were inserted by the curve-fitting
process. If you use entmod to move the vertices of such a polyline with the
intent of refitting the curve by means of PEDIT, ignore these vertices.
Likewise, if the polyline entitys spline-fit flag bit (bit 4) is set, an assortment
of vertices will be foundsome with flag bit 1 (inserted by curve fitting if system variable SPLINESEGS was negative), some with bit value 8 (inserted by
spline fitting), and all others with bit value 16 (spline frame-control point).
Here again, if you use entmod to move the vertices and you intend to refit the
spline afterward, move only the control-point vertices.

Nongraphic Object Handling


AutoCAD uses two types of nongraphic objects, dictionary objects and symbol table objects. Although there are similarities between these object types,
they are handled differently.
All object types are supported by the entget, entmod, entdel and entmake
functions, although object types individually dictate their participation in
these functions and may refuse any or all processing. With respect to
AutoCAD built-in objects, the following rules apply (all rules and restrictions
that apply to graphic objects, apply to nongraphic objects as well). Nongraphic objects cannot be passed to the entupd function.
When using entmake, the object type determines where the object will reside.
For example, if a layer object is passed to entmake, it automatically goes to

Object Handling

124

the layer symbol table. If a graphic object is passed to entmake, it will reside
in the current space (model or paper).

Symbol Table Objects


The following rules apply to symbol tables:

Symbol table entries can be created through entmake with few restrictions
other than being valid record representations, and name conflicts can
only occur in the VPORT table. *ACTIVE entries can not be created.
Symbol table and symbol table entry object state may be accessed with
entget by passing the entity name. The tblobjname function can be used
to retrieve the entity name of a symbol table entry.
Symbol tables themselves can not be created with entmake, however,
symbol table entries can be created with entmake.
Handle groups (5, 105) may not be changed in entmod, nor specified in
entmake.
Symbol table entries can have many of their fields modified with entmod.
To be passed to entmod, a symbol table record list must include its entity
name, which can be obtained from entget but not from the tblsearch
and tblnext functions. The 70 group of symbol table entries is ignored in
entmod and entmake operations.

Renaming symbol table entries to duplicate names is not acceptable, except


for the VPORT symbol table. The following entries may not be modified or
renamed. Except that most LAYER entries can be renamed and xdata can be
modified on all symbol table entries.
Entries that cannot be modified or renamed
table

entry name

VPORT

*ACTIVE

LINETYPE

CONTINUOUS

LAYER

Entries may not be modified, except for xdata, and renaming

The following entries may not be renamed, but are otherwise modifiable,
subject to restriction
Entries that cannot be renamed

Chapter 4

125

table

entry name

LAYER

Using AutoLISP to Manipulate AutoCAD Objects

Entries that cannot be renamed (continued)


table

entry name

STYLE

STANDARD

DIMSTYLE

STANDARD

BLOCKS

*MODEL_SPACE

BLOCKS

*PAPER_SPACE

APPID

No entries may be renamed

Dictionary Objects
The following rules apply to dictionary objects:

Dictionary objects can be examined with entget and their xdata modified
with entmod. Their entries cannot be altered with entmod. All access to their
entries are made through the dictsearch and dictnext functions.
Dictionary entry contents cannot be modified through entmod, although
xdata can be modified.
Dictionary entries that begin with ACAD* cannot be renamed.

Extended DataXdata
Several AutoLISP functions are provided to handle extended data, which is
created by applications written with ARX or Visual LISP. If an entity contains
extended data, it follows the entitys regular, definition data.
The extended data-handling functions are as follows:
regapp

xdroom

xdsize

You can retrieve an entitys extended data by calling entget. The entget
function retrieves an entitys regular definition data and the extended data
for those applications specified in the entget call.

Extended DataXdata

126

When extended data is retrieved with entget, the beginning of extended


data is indicated by a 3 code. The 3 code is in a list that precedes the first
1001 group. The 1001 group contains the application name of the first application retrieved, as shown in the table and as described in the following
sections.

Group Code

Field

(1, 2
(0239

Entity name)
Regular definition data fields)
.
.
.

Normal entity
definition data

Extended data sentinel


Registered application name 1)

Extended data

(3
(1001
(1000,
10021071

XDATA fields)
.
.
.

(1001
(1000,
10021071

Registered application name 2)


XDATA fields)
.
.
.

(1001

Registered application name 3)


.
.

Extended data

Organization of Extended Data


Extended data consists of one or more 1001 groups, each of which begins
with a unique application name. The extended data groups returned by
entget follow the definition data in the order in which they are saved in the
database.

Chapter 4

127

Using AutoLISP to Manipulate AutoCAD Objects

Within each applications group, the contents, meaning, and organization of


the data are defined by the application itself. AutoCAD maintains the information but doesnt use it. The table also shows that the group codes for
extended data are in the range 10001071. Many of these group codes are for
familiar data types, as follows:
String

1000. Strings in extended data can be up to 255 bytes long


(with the 256th byte reserved for the null character).

Application
name

1001 (also a string value). Application names can be up to


31 bytes long (the 32d byte is reserved for the null character) and must adhere to the rules for symbol table names
(such as layer names). An application name can contain
letters, digits, and the special characters $ (dollar sign), (hyphen), and _ (underscore). It cannot contain spaces.
Letters in the name are converted to upper case.

Layer name

1003. Name of a layer associated with the extended data.

Database
handle

1005. Handle of an entity in the drawing database.

3D point

1010. Three real values, contained in a point.

Real

1040. A real value.

Integer

1070. A 16-bit integer (signed or unsigned).

Long

1071. A 32-bit signed (long) integer. If the value that


appears in a 1071 group is a short integer or real value, it
is converted to a long integer; if it is invalid (for example,
a string), it is converted to a long zero (0L).

NOTE AutoLISP manages 1071 groups as real values. If you use entget to
retrieve an entitys definition list that contains a 1071 group, the value is returned
as a real, as shown in the following example:
(1071 . 12.0)
If you want to create a 1071 group in an entity with
entmake or entmod, you can use either a real or an integer

value, as shown in the following example:


(entmake
(entmake
(entmake
(entmake

((.....
((.....
((.....
((.....

(1071
(1071
(1071
(1071

.
.
.
.

12) .... )))


12.0) .... )))
65537.0) .... )))
65537) .... )))

Extended DataXdata

128

But AutoLISP still returns the group value as a real:


(entmake ((..... (1071 . 65537) .... )))

The preceding statement returns the following:


(1071 . 65537.0)

ARX always manages 1071 groups as long integers.


Several other extended data groups have special meaning in this context (if
the application chooses to use them):
Control string

1002. An extended data control string can be either "{" or


"}". These braces enable the application to organize its
data by subdividing it into lists. The left brace begins a list,
and the right brace terminates the most recent list. Lists
can be nested.

NOTE If a 1001 group appears within a list, it is treated as a string and does
not begin a new application group.
Binary data

1004. Binary data that is organized into variable-length


chunks, which can be handled in ObjectARX with the
ads_binary structure. The maximum length of each
chunk is 127 bytes.

NOTE AutoLISP cannot directly handle binary chunks, so the same precautions that apply to long (1071) groups apply to binary groups as well.

Chapter 4

129

World space
position

1011. Unlike a simple 3D point, the WCS coordinates are


moved, scaled, rotated, and mirrored along with the parent entity to which the extended data belongs. The WCS
position is also stretched when the STRETCH command is
applied to the parent entity and when this point lies
within the select window.

World space
displacement

1012. A 3D point that is scaled, rotated, or mirrored along


with the parent, but not stretched or moved.

World
direction

1013. A 3D point that is rotated or mirrored along with


the parent, but not scaled, stretched or moved. The WCS
direction is a normalized displacement that always has a
unit length.

Distance

1041. A real value that is scaled along with the parent


entity.

Scale factor

1042. Also a real value that is scaled along with the parent.

Using AutoLISP to Manipulate AutoCAD Objects

Registration of an Application
To be recognized by AutoCAD an application must register the name or
names that it uses. Application names are saved with the extended data of
each entity that uses them, and also in the APPID table. Registration is done
with the regapp function. The regapp function specifies a string to use as an
application name. If it successfully adds the name to APPID, it returns the
name of the application; otherwise it returns nil. A result of nil indicates
that the name is already present in the symbol table. This is not an actual
error condition but an expected return value, because the application name
needs to be registered only once per drawing.
To register itself, an application should first check that its name is not already
in the APPID table. If the name is not there, the application must register it.
Otherwise, it can simply go ahead and use the data, as described later in this
section.
The following fragment shows the typical use of regapp.
(setq appname "MYAPP_2356")
Unique application name
(if (tblsearch "appid" appname)
Checks if already registered
(princ (strcat
"\n" appname " already registered. "))
(if (= (regapp appname) nil)
Some other problem
(princ (strcat
"\nCant register XDATA for " appname ". "))
)
)

NOTE The regapp function provides a measure of security, but it cannot


guarantee that two separate applications have not chosen the same name. One
way of ensuring this is to adopt a naming scheme that uses the company or product name and a unique number (like your telephone number or the current date
and time).

Retrieval of Extended Data


An application can call entget to obtain the extended data that it has registered. The entget function can return both the definition data and the
extended data for the applications it requests. It requires an additional argument, application, that specifies the application names. The names passed
to entget must correspond to applications registered by a previous call to
regapp; they can also contain wild-card characters.

Extended DataXdata

130

By default, associative hatch patterns contain extended data. The following


code shows the association list of this extended data.
Command: (entget (car (entsel)) ("ACAD"))
Select object: Select an associative hatch
Entering the preceding code at the command line returns a list that looks
something like this:
((-1 . <Entity name: 600000c0>) (0 . "INSERT") (8 . "0") (2 . "*X0")
(10 0.0 0.0 0.0) (41 . 1.0) (42 . 1.0) (50 . 0.0) (43 . 1.0) (70 . 0) (71 . 0)
(44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0) (-3 ("ACAD" (1000 . "HATCH")
(1002 . "{") (1070 . 16) (1000 . "LINE") (1040 . 1.0) (1040 . 0.0)
(1002 . "}"))))
This fragment shows a typical sequence for retrieving extended data for two
specified applications. Note that the application argument passes application names in list form.
(setq working_elist
(entget ent_name
("MY_APP_1" "SOME_OTHER")
)
)
(if working_elist
(progn
...
(entmod working_elist)
)
)

Only extended data from "MY_APP_1"


and "SOME_OTHER" is retrieved

Updates working entity groups


Only extended data from registered
applications still in the working_elist
list are modified

As the sample code shows, you can modify extended data retrieved by entget
by using a subsequent call to entmod, just as you use entmod to modify normal
definition data. You can also create extended data by defining it in the entity
list passed to entmake.
Returning the extended data of only those applications specifically requested
protects one application from corrupting another applications data. It also
controls the amount of memory that an application needs to use, and simplifies the extended data processing that an application needs to perform.
NOTE Because the strings passed by application can include wild-card
characters, an application name of "*" will cause entget to return all extended
data attached to an entity.

Attachment of Extended Data to an Entity


You can use extended data to store any type of information you want. The
following is an example of attaching extended data to an entity.

Chapter 4

131

Using AutoLISP to Manipulate AutoCAD Objects

You must first draw an entity (such as a line or a circle) and then enter the
following code:
(setq lastent (entget (entlast)))Gets the association list of definition

data for the last entity


(regapp "NEWDATA")
Registers the application name
(setq exdata
Sets the variable exdata equal
((-3 ("NEWDATA"
to the new extended data
(1000 . "This is a new thing!")in this case a text string
)))
)
(setq newent
(append lastent exdata))
Appends the new data list to the entitys list
(entmod newent)
Modifies the entity with the new

definition data
To verify that your new extended data has been attached to the entity, enter
the following code and select the object.
(entget (car (entsel)) ("NEWDATA"))

This example shows the basic method for attaching extended data to an
entity.

Management of Extended Data Memory Use


Extended data is currently limited to 16K per entity. Because the extended
data of an entity can be created and maintained by multiple applications,
problems can result when the size of the extended data approaches its limit.
AutoLISP provides two functions, xdsize and xdroom, to assist in managing
the memory that extended data occupies. When xdsize is passed a list of
extended data, it returns the amount of memory (in bytes) that the data will
occupy; when xdroom is passed the name of an entity, it returns the remaining number of free bytes that can still be appended to the entity.
The xdsize function reads an extended data list, which can be large. This
function can be slow, so it is not recommended that you call it frequently. A
better approach is to use it (in conjunction with xdroom) in an error handler.
If a call to entmod fails, you can use xdsize and xdroom to find out whether
the call failed because the entity didnt have enough room for the extended
data.

Handles in Extended Data


Extended data can contain handles (group 1005) to save relational structures
within a drawing. One entity can reference another by saving the others
handle in its extended data. The handle can later be retrieved from extended
data and passed to handent to obtain the other entity. Because more than one
entity can reference another, extended data handles are not necessarily

Extended DataXdata

132

unique. The AUDIT command does require that handles in extended data
either be NULL or valid entity handles (within the current drawing). The best
way to ensure that extended entity handles are valid is to obtain a referenced
entitys handle directly from its definition data by means of entget. The handle value is in group 5.
When you reference entities in other drawings (for example, entities that are
attached with XREF), you can avoid protests from AUDIT by using extended
entity strings (group 1000) rather than handles (group 1005), because the
handles of cross-referenced entities are either not valid in the current drawing
or they conflict with valid handles. However, if an XREF Attach changes to
an XREF Bind or is combined with the current drawing in some other way, it
is up to the application to revise the entity references accordingly.
When drawings are combined by means of INSERT, INSERT*, XREF Bind
(XBIND), or partial DXFIN, handles are translated so that they become valid
in the current drawing. (If the incoming drawing did not employ handles,
new ones are assigned.) Extended entity handles that refer to incoming
entities are also translated when these commands are invoked.
When an entity is placed in a block definition (with the BLOCK command),
the entity within the block is assigned new handles. (If the original entity is
restored by means of OOPS, it retains its original handles.) The value of any
extended data handles remain unchanged. When a block is exploded (with
the EXPLODE command), extended data handles are translated, in a manner
similar to the way they are translated when drawings are combined. If the
extended data handle refers to an entity that is not within the block, it is
unchanged. However, if the extended data handle refers to an entity that is
within the block, the data handle is assigned the value of the new (exploded)
entitys handle.

Chapter 4

133

Using AutoLISP to Manipulate AutoCAD Objects

Xrecord Objects
Xrecord objects are used to store and manage arbitrary data. They are composed of DXF group codes with "normal object" groups (that is, non-xdata
group codes), ranging from 1 through 369 for supported ranges. This object
is similar in concept to xdata but is not limited by size or order.
Xrecord objects are designed to work in such a way as to not offend releases
R13c0 through R13c3. However, if read into a pre-R13c4 level of AutoCAD,
xrecord objects disappear.
The following examples provide methods for creating and listing xrecord
data.
(defun C:MAKEXRECORD( / xrec xname )
; create the xrecords data list
(setq xrec ((0 . "XRECORD")(100 . "AcDbXrecord")
(1 . "This is a test xrecord list")
(10 1.0 2.0 0.0) (40 . 3.14159) (50 . 3.14159)
(62 . 1) (70 . 180))
)
; use entmakex to create the xrecord with no owner
(setq xname (entmakex xrec))
; add the new xrecord to the named object dictionary
(dictadd (namedobjdict) "XRECLIST" xname)
(princ)
)

(defun C:LISTXRECORD ( / xlist )


; find the xrecord in the named object dictionary
(setq xlist (dictsearch (namedobjdict) "XRECLIST"))
; print out the xrecords data list
(princ xlist)
(princ)
)

Symbol Table and Dictionary Access


AutoLISP provides functions for accessing symbol table and dictionary
entries. The symbol table and dictionary access functions are as follows:

dictsearch

namedobjdict

tblnext

tblsearch

Xrecord Objects

134

dictnext

snvalid

tblobjname

Examples of the tblnext and tblsearch functions are provided in this section. See AutoLISP Function Reference for information on the other symbol table and dictionary access functions.

Symbol Tables
Symbol table entries can also be manipulated by the following functions:

entdel

entmake

entget

entmod

handent

The tblnext function sequentially scans symbol table entries, and the
tblsearch function retrieves specific entries. Table names are specified by
strings. The valid names are "LAYER", "LTYPE", "VIEW", "STYLE", "BLOCK",
"UCS", "VPORT", "DIMSTYLE", and "APPID". Both functions return lists with
DXF group codes that are similar to the entity data returned by entget.
The first call to tblnext returns the first entry in the specified table. Subsequent calls that specify the same table return successive entries, unless the
second argument to tblnext (rewind) is nonzero, in which case tblnext
returns the first entry again.
In the following example, the function GETBLOCK retrieves the symbol table
entry for the first block (if any) in the current drawing, and then displays it
in a list format.

Chapter 4

135

Using AutoLISP to Manipulate AutoCAD Objects

(defun C:GETBLOCK (/ blk ct)


(setq blk (tblnext "BLOCK" 1))
Gets the first BLOCK entry
(setq ct 0)
Sets ct (a counter) to 0
(textpage)
Switches to the text screen
(princ "\nResults from GETBLOCK: ")
(repeat (length blk)
Repeats for the number of members in the list
(print (nth ct blk))
Prints a new line and then each list member
(setq ct (1+ ct))
Increments the counter by 1
)
(princ)
Exits quietly
)

Entries retrieved from the BLOCK table contain a 2 group that contains the
name of the first entity in the block definition. If the block is empty, this is
the name of the blocks ENDBLK entity, which is never seen on nonempty
blocks. In a drawing with a single block named BOX, a call to GETBLOCK
displays the following. (The name value varies from session to session).
Results from GETBLOCK:
(0 . "BLOCK")
(2 . "BOX")
(70 . 0)
(10 9.0 2.0 0.0)
(2 . <Entity name: 40000126>)
As with tblnext, the first argument to tblsearch is a string that names a
table, but the second argument is a string that names a particular symbol in
the table. If the symbol is found, tblsearch returns its data. This function
has a third argument, setnext, that you can use to coordinate operations
with tblnext. If setnext is nil, the tblsearch call has no effect on tblnext,
but if setnext is non-nil, the next call to tblnext returns the table entry following the entry found by tblsearch.
The setnext option is useful when you are handling the VPORT symbol table,
because all viewports in a particular viewport configuration have the same
name (such as *ACTIVE).
If the VPORT symbol table is accessed when TILEMODE is turned off, any
changes have no visible effect until TILEMODE turned on. Do not confuse
VPORTS, which is described by the VPORT symbol table with paper space viewport entities.

Symbol Table and Dictionary Access

136

The following processes all viewports in the 4VIEW configuration.


(setq v (tblsearch "VPORT" "4VIEW" T))
Finds first VPORT entry
(while (and v (= (cdr (assoc 2 v)) "4VIEW"))
.
.
... Processes entry ...
.
(setq v (tblnext "VPORT"))
Gets next VPORT entry
)

Dictionary Entries
A dictionary is a container object, similar to symbol tables in function. Dictionary entries can be queried with the dictsearch and dictnext functions.
Each dictionary entry consists of a text name key plus a hard ownership handle reference to the entry object. Dictionary entries may be removed by
directly passing entry object names to the entdel function. The text name
key uses the same syntax and valid characters as symbol table names.

Accessing AutoCAD Groups


The following is an example of one method for accessing the entities contained in a group. This example assumes that a group named G1 exists in the
current drawing.
(setq objdict (namedobjdict))
(setq grpdict (dictsearch objdict "ACAD_GROUP"))

This sets the variable grpdict to the entity definition list of the ACAD_GROUP
dictionary and returns the following:
((-1 . <Entity name: 8dc10468>) (0 . "DICTIONARY") (5 . "D")
(102 . "{ACAD_REACTORS") (330 . <Entity name: 8dc10460>)
(102 . "}") (100 . "AcDbDictionary") (3 . "G1")
(350 . <Entity name: 8dc41240>))
The following code sets the variable group1 to the entity definition list of the
G1 group.
(setq group1 (dictsearch (cdar grpdict) "G1"))

It returns the following:


((-1 . <Entity name: 8dc10518>) (0 . "GROUP") (5 . "23")
(102 . "{ACAD_REACTORS") (330 . <Entity name: 8dc10468>)
(102 . "}") (100 . "AcDbGroup") (300 . "line and circle") (70 . 0) (71 . 1)
(340 . <Entity name: 8dc10510>)(340 . <Entity name: 8dc10550>) )
The 340 group codes are the entities that belongs to the group.

Chapter 4

137

Using AutoLISP to Manipulate AutoCAD Objects

5
Developing Programs
With Visual LISP

In this chapter

Visual LISP provides a number of tools and features to help


you develop AutoLISP programs. This chapter describes the
features that help you enter AutoLISP text, format it to

The System Console

Using the Text Editor

Formatting Code

Checking for Syntax


Errors

Running Your
Program

improve readability, and detect syntax errors in your code.

138

Getting Organized
Developing an AutoLISP program using Visual LISP involves the following
tasks:
1 Thinking about what tasks you want to accomplish with your program, and
how you might go about doing this
2 Designing the program
3 Writing the code
4 Formatting the code text for readability
5 Checking for errors in the program
6 Testing and debugging the program
This chapter provides you with information you need in order to accomplish
steps 3, 4 and 5. Debugging Programs, describes the debugging features of
Visual LISP. Building Applications, and Maintaining Visual LISP Applications, describe how to package your programs into applications that can be
run by other users, and how to organize application components to facilitate
future updates.

The System Console


Most of the programming you do in Visual LISP takes place within the confines of the VLISP text editor, but the ability to program interactively with
AutoLISP provides some unique advantages to the development process.
Using the Visual LISP System Console, you can enter AutoLISP code and
immediately see the results of that code.

You enter text in the Console window following the Console prompt, which
looks like the following:
_$

Chapter 5

139

Developing Programs With Visual LISP

Visual LISP saves the text you enter, and any output it displays in response,
so that you can scroll through the Console window and see what has previously transpired. You can copy any text in the window, and paste it following
the Console prompt or in another Windows application.

System Console Behavior


The Visual LISP System Console is similar in many respects to the AutoCAD
command window, but it provides many additional features. And where the
Console and the AutoCAD command window provide similar capabilities,
you dont always accomplish tasks in the same exact way. For example, to display the current value of an AutoLISP variable in Visual LISP, you simply type
the variable name in the Console window and press ENTER. To view the value
of a variable in AutoCAD, you must precede the variable name with an exclamation point (!) when you type it in the command window.
A number of features are unique to the Console. For example:

You can continue an AutoLISP expression on a new line. To continue typing an expression on a new line, press CTRL+ENTER at the point you want
to continue.
In contrast, expressions entered from the AutoCAD Command prompt are
interpreted as soon as you press the ENTER key. AutoCAD treats the
incomplete expression as an error, although it does allow you fix the error
by completing the expression at the Command prompt.

You can enter more than one expression before pressing the ENTER key,
and Visual LISP will evaluate each expression before returning a value to
the Console.
If the cursor is in the Console window but not at the Console prompt,
pressing the ENTER key positions the cursor at the prompt. If you select
some text in the Console window before you press ENTER, (for example,
the result of a previous command or a previously-entered expression),
Visual LISP copies the selected text following the Console prompt.
To retrieve text you previously entered from the Console, press the TAB
key while at the Console prompt. Each time you press TAB, the previously
entered text replaces the text at the Console prompt. You can repeat this
until youve cycled through all the text entered at the Console prompt. If
you repeatedly entered a specific expression, that expression appears only
once in the cycle. After you scroll to the first entered line, the list jumps
back to the last line entered and the cycle is repeated.

SHIFT+TAB acts like TAB, but scrolls the input history in the opposite direc-

tion.

The System Console

140

The TAB key lets you perform an associative search in the input history.
For example, if you type (+ at the Console prompt and then press TAB,
Visual LISP searches for the last text you entered that began with the (+
characters. If it doesnt find a match, VLISP does nothing (except possibly
emit a beep). Use SHIFT+TAB to perform an associative search from earlier
to later inputs.
The ESC key clears the input area following the Console prompt. Pressing
SHIFT+ESC leaves the text you typed in the Console window, but brings
you to a new prompt without evaluating the text.

The System Console Context Menu


The most important functions needed when working with the System Console are combined into a context menu for fastest execution. Click the right
mouse button, or press SHIFT+F10 anywhere in the Console window to display the context menu:

Chapter 5

141

Developing Programs With Visual LISP

Depending on whether there is text highlighted in the Console window and


depending on where the cursor position is, some commands may not be
appropriate at the moment and are inactive.

Cut

Removes the selected text from the Console window and


moves it to the Windows clipboard

Copy

Copies the selected text to the clipboard

Paste

Pastes the clipboard contents to the cursor location

Clear Console Window Empties the Console window


Find

Finds a specified text in the Console window

Inspect

Opens the Inspector dialog

Add Watch

Opens the Watch window

Apropos Window

Opens the Apropos window

Symbol service

Opens the Symbol Service dialog

Undo

Reverses the last operation

Redo

Reverses the effects of the previous Undo

AutoCAD Mode

Transfers all input to the AutoCAD Command line for evaluation

Toggle Console Log

Copies the Console output to the log file

Note also that you can cut and paste text between the Visual LISP Console
and the AutoCAD command window.

Separators Processing
The Visual LISP System Console and the AutoCAD command window differ
in the way they process the SPACE and TAB keys. In the Visual LISP Console,
a space plays no special role and serves as a separator only. In the AutoCAD
command window, if you press the SPACE bar outside of an expression, it
causes termination of input and the processing of the text, as if you had
pressed the ENTER key.

The System Console

142

Color Coding of Console Input


As soon as you enter text at the Console prompt, Visual LISP determines if
the entered word is a built-in AutoLISP function, a number, a string, or some
other language element that it is aware of. Every type of element gets its own
color. See Color Coding on page 148 for more information on how Visual
LISP flags language elements with color coding.

Context-Sensitive Help for Visual LISP Functions


If you enter and select a function name at the Console prompt, then press
the Help button on the Tools toolbar, Visual LISP displays help for the function. This feature works for any AutoLISP, Visual LISP, or ActiveX function
recognized by Visual LISP.

Logging Console Activity


You can keep a record of all Console activity by logging the activity in a disk
file. Later, you can view the file and review the activity that occurred at the
Console.
To create a log file, choose File>Toggle Console Log from the Visual LISP
menu. Note that the Console window must be active within Visual LISP in
order for the Toggle Console Log option to be available.

Choose a directory for the log file and then specify a filename for the log. If
the file already exists, Visual LISP prompts you with the following:

Chapter 5

143

Developing Programs With Visual LISP

If you reply Yes, Visual LISP will append future Console information to the
current contents of the file. If you reply No, Visual LISP overwrites the file
and the original contents will be lost. Click Cancel to terminate the operation and specify a different file name.
To close the log file and end logging, choose Toggle Console Log from the File
menu again. The state of Console logging is indicated in the Console windows title bar. If logging is in effect, Visual LISP displays the name of the log
file in the title bar. If logging is off, no file name appears in the title bar.
If you do not close the log file before exiting Visual LISP, Visual LISP closes it
automatically upon exit. After a log file is closed, you can view its contents
with any text editor, such as the Visual LISP text editor.

Accessing Native AutoLISP from Visual LISP


Visual LISP enables you to interact directly with native AutoLISP through the
Console window. To switch to this mode of Console operation, choose
Tools>AutoCAD Mode from the Visual LISP menu, or use the Console context menu and choose AutoCAD mode. The prompt in the console window
will change to:
Command:

Any character sequence entered at this prompt will be transferred directly to


the AutoCAD command line. In this way, you can enter AutoCAD commands from within Visual LISP and you can set variables in native AutoLISP.
Remember that native AutoLISP and Visual LISP are separate environments.
_$ (setq x 1)
Command: (setq y 2)
Command: !x
$ y
NIL
$ x
1

; sets x to 1 in the Visual LISP environment


; sets y to 2 in the AutoLISP environment
; displays nil at the AutoCAD console_

To return to the standard Visual LISP Console mode of operation, choose


AutoCAD Mode again, just as you did to turn the mode on. The
AutoCAD Mode menu item works as an on/off toggle: if the mode is cur-

The System Console

144

rently turned on, choosing it turns it off; if AutoCAD mode is off, choosing
it turns it on.

Bouncing Between AutoCAD and Visual LISP


At times you may find yourself in a situation where the Visual LISP Console
is waiting for input from AutoCAD, and AutoCAD thinks Visual LISP should
be in control. When this occurs, you may try to interrupt an AutoCAD command and find control passed right back to Visual LISP. You may see something like the following in the Visual LISP Console:
1_$
; entering keyboard break loop

If this occurs, you need to return control to AutoCAD and press the ESC key
to reset your environment. To return control to AutoCAD, press the
Activate AutoCAD button on the View toolbar:

After you press ESC in the AutoCAD window, youll be able to resume interaction with the Visual LISP Console.

Using the Text Editor


If you just need to run a few simple AutoLISP expressions, entering the
expressions in the Visual LISP System Console may suffice. For anything
more than that, however, you will need to use the Visual LISP text editor and
save your AutoLISP code in a file.
The text editor is one of the basic components of Visual LISP. It is easy to use
and, if you have some experience using Windows, you can begin using it
after a quick review of this chapter.
The Visual LISP text editor has a number of features designed to support
AutoLISP programming, such as selection of complete AutoLISP expressions,
matching of balanced parentheses, syntax coloring, and executing AutoLISP
expressions without leaving the editor window. Most text editor commands
can be called from the menu bar, and some of the most frequently used commands are also available from toolbar push buttons.

Working with Files


To open a new file in the VLISP text editor, choose File>New File from the
menu bar. An empty editor window appears on the screen:

Chapter 5

145

Developing Programs With Visual LISP

Entering Text
To enter text, begin typing in the active editor window. To start a new line,
press the ENTER key. The text editor does not wrap your text when it reaches
the end of the visible editor window, so everything you type goes on the
same line until you press ENTER.
To indent a line of text, type some spaces or press the TAB key. Eventually,
youll want to use the Visual LISP Code Formatter to automatically indent
and space your code; see Formatting Code with the Visual LISP Formatter
on page 162 for details.
A couple of key combinations result in a new line with automatic indenting:

Pressing SHIFT+ENTER clears trailing space and tab characters, inserts a


new line, and indents using the previous non-empty line indent.
Pressing CTRL+ENTER clears trailing space and tab characters, inserts a
Newline character, and performs smart indent. The smart indent feature
is described in Indentation Rules on page 171.

To insert new text into existing text, click at the place you want the text to
begin and start typing. You can also use the arrow keys to move the cursor to
the desired insertion point.

Undoing the Last Change You Made


If you change your mind about text you just typed, you can reverse the last
edit action by selecting Edit>Undo from the menu bar. The Undo command
only works on the last change you made. For example, if you delete a paragraph, then issue the Undo command, Visual LISP restores the paragraph you
deleted. But if you delete the paragraph, then start typing in a new line and
issue the Undo command, Visual LISP only removes the new text you typed;
it is too late to restore the paragraph.
You can also reverse the effects of the Undo command, if you change your
mind again. Select Edit>Redo from the menu to undo the undo (got that?).
So if you delete a paragraph, issue the Undo command to restore it, then
issue the Redo command, the paragraph is deleted again. Redo only works if
you issue it immediately after Undo.

Using the Text Editor

146

Saving Your Changes


Until you save the changes youve made to the text in the editor window,
everything you typed exists only in the computers memory. If you turn off
your PC, everything youve entered is lost. To save the changes in a file,
where you can retrieve the text from one Visual LISP session to another,
choose File>Save As from the Visual LISP menu, and specify a path and file
name. If you attempt to exit Visual LISP before youve saved your file, VLISP
will ask you whether to save the changes youve made before it will end your
session.

Automatic Backup Files


Visual LISP supports the automatic creation of backup copies of files loaded
by the text editor. The actual backup creation occurs when you save the file
for the first time. The backup file has the same name as the original file,
except that the file extension begins with the underscore (_) character and is
followed by the first 2 characters of the original extension. For example, the
backup file for drawline.lsp would be drawline._ls.
Automatic creation of backup files is an option you can set by choosing
Tools>Environment>Options>General Options. Select the Editor option
labeled Backup the File Edited on First Save in order to turn on automatic
backup. By default, this option is already selected when you first install
Visual LISP.
Restoring From the Backup File
If a backup file exists, you can restore the file you are editing to its original
contents, reversing all the changes you made. From the File menu, choose
Revert to restore the file. If there is no backup file for the text in the editor
window, an error message results.

Editing an Existing File


To load and edit an existing file, choose File>Open from the Visual LISP
menu. This results in a standard Windows Open dialog box, from which you
specify the file you want to edit. Visual LISP opens a new text editor window
for the file you select. You can open any number of files and work on them
simultaneously; Visual LISP places each file in its own editor window.
TIP If you highlight (select) text in any Visual LISP window before choosing
File>Open, the selected text is placed in the File name field of the Open dialog
box.
When you exit Visual LISP, it notes which files are open and saves this information for your next Visual LISP session. The next time you start Visual LISP,
it automatically opens these files for you.

Chapter 5

147

Developing Programs With Visual LISP

Color Coding
As soon as you enter text in the text editor window, Visual LISP determines
if the entered word is a built-in AutoLISP function, a number, a string, or
some other language element that it is aware of. Every type of element gets
its own color. This helps you detect missing quotes or misspelled function
names. The default color scheme is:

AutoLISP Language Element

Color

Built-in functions and protected symbols

Blue

Strings

Magenta

Integers

Green

Real numbers

Teal

Comments

Magenta, on gray background

Parentheses

Red

Unrecognized items (for example, user variables) Black

You can change the default colors from the dialog box displayed by choosing
Tools>Window Attributes>Configure Current from the Visual LISP menu.
NOTE Visual LISP may not recognize every function you use in your programs. Many commonly used functions are not defined as part of the AutoLISP
language, but are instead defined in external applications. If an external function
has not been made known to Visual LISP, it will not be identified and color coded.
See Identifying Functions Defined in External Applications on page 221 for
information on how external functions are defined to Visual LISP.
The Visual LISP editor provides color coding for LISP files, DCL files, SQL files
and C language source files (see LSP, FAS and other File Types on page 245
for a list of file types recognized by Visual LISP ). Visual LISP uses the file
name extension to determine a files type, and selects the color coding
accordingly. You can change the color coding style associated with a file type
by choosing Tools>Window Attributes>Syntax Coloring from the Visual LISP
menu.

Using the Text Editor

148

Context-Sensitive Help for Functions


If you enter and select a function name in the text editor window, then press
the Help button on the Tools toolbar, Visual LISP displays help for the function. This feature works for any AutoLISP, Visual LISP, or ActiveX function
recognized by Visual LISP.

The Text Editor Context Menu


As it did in the Console window, right-clicking your mouse in an active text
editor window brings up a context menu for quick access to frequently-used
commands:

Chapter 5

149

Developing Programs With Visual LISP

Depending on whether there is text highlighted in the editor window and


depending on the position of the cursor, some commands may be inactive.

Cut

Moves the selected text to the clipboard

Copy

Copies the selected text to the clipboard

Paste

Pastes the clipboard contents to the cursor position

Find

Finds the specified text in one or more editor windows

Go to Last Edited Moves the cursor to the position you last edited
Toggle Breakpoint Sets a breakpoint at the cursor position, or removes a
breakpoint if one currently is set at that position
Inspect

Opens the Inspector dialog

Add Watch

Opens the Watch window

Apropos Window Opens the Apropos window


Symbol Service

Opens the Symbol Service dialog

Undo

Reverses the last operation

Redo

Reverses the effects of the previous Undo

Words in the Visual LISP Text Editor


Some text editor commands rely on breaking the text into segments, called
words. In the Visual LISP text editor, the term word means a sequence of
characters separated by one or more of the following special characters:

space
tab

single quote

left parenthesis

right parenthesis

"

double quote

Using the Text Editor

150

semicolon

\n

Newline

[]

Unprintable ASCII characters (for example, \001-\037)

Text Editor Shortcuts


Two text editor features, Complete Word by Match and Complete Word by Apropos, allow you to type in part of a word and have Visual LISP complete the
rest of the word for you.

Complete Word by Match


Using Complete Word by Match, Visual LISP completes a partially-entered
word by matching the part youve typed with another word in the same edit
window. Press ALT+/ (ALT+slash) to invoke Complete Word by Match on a
partially-entered word. The feature is case insensitive.

Complete Word by Apropos


With the Complete Word by Apropos feature, Visual LISP completes a partially entered word with a matching symbol name from the Visual LISP symbol table. The VLISP symbol table lists the elements in an AutoLISP program;
for example, the symbols, subroutines, and variables referenced by the program. Press CTRL+SHIFT+/ to invoke Complete Word by Apropos on a partially-entered word.
If Visual LISP finds several matching names in the symbol table, it presents a
context menu from which you can choose the name you want. If more than
15 names are found, the Apropos dialog box appears:

To insert a symbol from the dialog box:


1 Select a symbol from the list

Chapter 5

151

Developing Programs With Visual LISP

2 Right-click your mouse and select Copy to Clipboard from the list of options
3 Click in the editor window at the point you want to insert the symbol name
4 Right-click your mouse and select Paste from the context menu, or press
CTRL+V to paste the text
If no symbols match what youve entered, Visual LISP displays the Apropos
options dialog box:

The message area of the Apropos options dialog box shows the value that
Apropos could not match.
In the input field of the Apropos options dialog, you change the text you
want Apropos to match. The dialog box contains the following options:

Match by Prefix. If this option is turned on, Apropos searches for a


match starting only from the first character of the symbol name. If the
option is turned off, Apropos tries to match the text you entered starting
at any position of a symbol name.
Use WCMATCH (WildCard Match). If this option is turned on, Apropos
treats asterisks as wildcard characters when searching. For example, if you
specify fun* as the symbol you want matched, Apropos looks for all
names that begin with fun, no matter what characters follow. In contrast, with Use WCMATCH turned off, the asterisk is treated as a string and
Apropos only matches names that precisely match fun*.
Downcase Symbols. If turned on, any symbols you copy to the clipboard with the Apropos service are converted to lower case characters. If
you paste the symbol name in another window, it appears in lower case.
Filter Value. Opens the Filter Value dialog, from which you can select a
filter for Apropos to use in searching for matching symbols. You can
choose one of the following]

All

No filter

Null value

Only nil-valued symbols are considered

Using the Text Editor

152

Nonull value

Only non-nil-valued symbols are considered

Functions

All function types are considered (user-defined, built-in, etc.)

User function

Only user-defined functions are considered

Built-in function Only built-in Visual LISP functions are considered for matching
EXSUBR

Only external function names are matched

Filter Flags. Lets you choose symbols with matching flag settings. Visual
LISP displays a list of check boxes that correspond to the symbol flags
described in The Symbol Service Dialog on page 199. If the flag filter is
on, only symbols set with the selected flags are considered.

If you specify a filter value or filter flag, the message area of the Apropos
options dialog box indicates your selections.

Chapter 5

153

Developing Programs With Visual LISP

Formatting Shortcut Keys


If you press CTRL+E while in an active Visual LISP text editor window, a list
containing the following editor options displays:

Indent Block

Indents the selected block of text by adding a tab to the beginning of each line

Unindent

Unindents the selected block of text by removing a tab

Prefix With

Adds a text string to the beginning of the current line, or to each


line in a block of selected lines, after prompting you for the string

Append With

Appends a text string to selected lines of text, after prompting


you for the string

Comment Block

Converts a block of code to comments

Uncomment
Block

Changes a block of comments to active text

Save Block As

Copy selected text to a new file

Upcase

Converts the selected text to all upper case

Downcase

Converts the selected text to all lower case

Capitalize

Capitalizes the first letter of each word in the selected text

Insert Date

Insert the current date (default format is MM/DD/YY)

Insert Time

Insert the current time (default format is HH:MM:SS)

Format
Date/Time

Change the date and time format

Sort Block

Sort the selected block of code in alphabetical order

Insert File

Insert the contents of a text file into the current editor window at
the cursor position

Delete to EOL

Erase everything from the cursor position to the end of the current line

Delete Blanks

Delete all blank spaces from the cursor position to the first nonblank character in the line

Using the Text Editor

154

Navigation Shortcuts
In addition to using the cursor arrow keys, you can use the following Visual
LISP editor shortcuts to navigate through your text.

To move

Press

One word to the left

CTRL+LEFT ARROW

One word to the right

CTRL+RIGHT ARROW

To the end of a line

END

To the beginning of a line

HOME

Down one window

PAGEDOWN

Up one window

PAGEUP

To the end of a document

CTRL+END

To the start of a document

CTRL+HOME

To the matching left parenthesis

CTRL+[

Before the innermost opening parenthesis

CTRL+[

To the matching right parenthesis

CTRL+]

After the innermost closing parenthesis

CTRL+]

Text Correction Shortcuts


You can delete words, lines, or paragraphs using the following shortcuts:.

To

Press

Erase a word to the left of the cursor

CTRL+BACKSPACE

Erase a word to the right of the cursor

SHIFT+BACKSPACE

Delete characters from the cursor position to the end of CTRL+E and choose Delete
the current line
to EOL from the menu
Delete the current line

Chapter 5

155

Developing Programs With Visual LISP

CTRL+E

You can also can use overstrike mode to insert text. Overstrike mode is toggled on and off by pressing the INSERT key. When in overstrike mode, each
character you type replaces existing text. The cursor changes shape from vertical to horizontal when in overstrike mode.

Text Selection Shortcuts


To select text using the keyboard, press and hold the SHIFT key while pressing
the direction (arrow) keys on the keyboard. Other keyboard methods of text
selection are listed below.

To

Press

Expand the selection to the next line, or to abandon selection SHIFT+Down Arrow
of the next line if it is currently selected
Expand the selection to the previous line, or to abandon selec-SHIFT+Up Arrow
tion of the previous line if it is currently selected
Expand the selection to the end of the line

SHIFT+END

Expand the selection to the beginning of the line

SHIFT+HOME

Expand the selection down one window, or to abandon selec-SHIFT+PAGEDOWN


tion of the next window if it is currently selected
Expand the selection up one window, or to abandon selection SHIFT+PAGEUP
of the previous window if it is currently selected
Expand the selection to the next word, or to abandon selec- CTRL+SHIFT+Right
Arrow
tion of the next word if it is currently selected
Expand the selection to the previous word, or to abandon
selection of the previous word if it is currently selected

CTRL+SHIFT+Left
Arrow

Expand the selection up to the matching left parenthesis

CTRL+SHIFT+[

Expand the selection up to the innermost opening parenthesis CTRL+SHIFT+[


Expand the selection up to the matching right parenthesis

CTRL+SHIFT+]

Expand the selection up to the innermost closing parenthesis CTRL+SHIFT+]


Move the cursor to the other side of the selection

ALT+ENTER

Using the Text Editor

156

Moving and Copying Text


In addition to using the standard Windows Cut, Copy, and Paste functions,
the Visual LISP editor allows you to drag text from one location to another
within the edit window. To move text:
1 Highlight the text you want to move
2 Point anywhere inside the selected area, and press and hold the left mouse
button
3 Using your mouse, drag the text to the new location
4 Release the mouse button
To copy the text instead of move it, follow the same steps but press CTRL
before releasing the mouse button in step 4.
You can also take selected text and copy it into a new file. With the text
selected, press CTRL+E to display a list of options, and choose Save Block As.
Visual LISP replies by displaying a dialog box for you to specify where you
want to save the text.
Visual LISP uses the Windows clipboard for all cut and copy operations, so
you can exchange text with any other Windows application that supports
these functions. This also means that you can copy and paste text between
the text editor and the Visual LISP Console window.
Remember that immediately after moving or copying text, you can change
your mind and reverse the action using the Undo function.

Indenting Text
Most indenting of program code is best handled by running the Visual LISP
Code Formatter and customizing the Formatters options (see Formatting
Code with the Visual LISP Formatter). But there are some things you may
want to do by yourself.

To

Do

Insert a Newline character and place the cursor at Press CTRL+ENTER


the proper indent level on a new line
Adjust the indent of a line according to the preceding AutoLISP text

Place the cursor anywhere in the line


and press SHIFT+TAB

Adjust the indent of the current selection to that Press SHIFT+TAB


of the preceding AutoLISP text

Chapter 5

157

Developing Programs With Visual LISP

To indent selected lines of code, press the TAB key or press CTRL+E and
choose Indent Block. Visual LISP inserts a tab character at the beginning of
each line you selected. You can control the indent amount of the tab character by choosing Tools>Window Attributes>Configure Current and setting
the Tab Width value.

Searching for Text


The Visual LISP text editor has extensive text searching capabilities. From the
Search menu, choose Find to begin a search, or press the Find toolbar button.
Visual LISP displays the Find dialog box:

In the data entry field labeled Find What, type the character string you
want to search for. If there is text selected when you enter the Find command, this text is automatically placed in the Find What field.
Under the Search heading, indicate the extent of the search you want Visual
LISP to conduct. You can choose one of the following:

Current Selection. Visual LISP searches only the text you have highlighted in the editor window.
Current File. Visual LISP searches through the entire file in the active
editor window.
Find in Project. With this option selected, Visual LISP prompts you to
specify the name of the Visual LISP project you want to search. It will
search all the files in this project and display all matches in a new output
window. See Finding a String in Project Source Files on page 257 for
more information on this option.
Find in Files. If you select this option, Visual LISP allows you to specify
a Windows directory (folder) to search for the text. Optionally, you can
instruct VLISP to search all subdirectories of that directory as well. Visual
LISP will search through all the files and display all matches in a new output window.

When searching for text within the current file, the Direction setting determines where Visual LISP looks next for the search text. Select Down to search

Using the Text Editor

158

forward (toward the end of the file) from the cursor position. Select Up to
search backwards (toward the beginning of the file) from the cursor position.
You can select any or all of the following options:

Match Whole Word Only. If selected, Visual LISP will only match complete words. For example, if the search term is ent and VLISP encounters
the word enter in the text, VLISP does not consider this a match. However, if the Match Whole Word Only option is not selected, Visual LISP
considers the ent within enter to be a match.
Match Case. If selected, Visual LISP only matches text whose case
matches. In this instance, Ent and ent are not considered a match. If
Match Case is not selected, Ent and ent are considered a match.
Mark Instances. If you select this option, the position of the located
text will be added to the Mark Ring (see Bookmarking Text on
page 160). This lets you quickly return to this code position at a later time.
Searches that find all occurrences of a string add each position to the Mark
Ring.

Click the Find button to start the search. When searching through a single
file, press F3 to search for the next occurrence of your search string. Click the
Cancel button to end the search.
Visual LISP saves each search string you enter in a pull-down list on the toolbar:

Repeating an Earlier Search


To repeat a search you made earlier, you can select a search term from the list
on the toolbar:

Click the pull-down arrow and select a search term from the list. Click the
Find Via Toolbar button to conduct the search.

Chapter 5

159

Developing Programs With Visual LISP

Replacing Text
The Search menu contains a Replace function that allows you to replace
search text with a text string that you specify.

The Replace dialog box is similar to the Find dialog box, but with fewer
options. It contains an additional Replace With entry field, in which you
specify the text you want Visual LISP to substitute for the search text. Specify
the search text in the Find what field.
You can take the following actions from the Replace dialog box:

Press the Find Next button to find the next occurrence of the search string.
Press Replace to replace the found text with the replacement string.
If you dont want to replace this occurrence of the text, press Find Next to
search for the next occurrence of the text, or Cancel to end the search.
Press Replace All to replace all occurrences of the search string with the
replacement string, depending on the search Direction.
Press Cancel to end the Replace function.

Bookmarking Text
The bookmark feature helps you navigate through editor, Console, and other
text-based windows by letting you mark up to 32 positions (bookmarks) in
each window. Each window maintains its own set of bookmarks, and the
bookmark navigation tools let you walk through the marks within each window independently of the other windows. A set of bookmarks within a window is known as a bookmark ring. You can step either forward or backward
through the ring, and eventually get back to the starting point.
Whenever you step to a bookmark, Visual LISP automatically places a marker
at the location you are stepping from. In effect, the marker for the place you
are jumping to is moved to the place you jumped from. This makes it easy
to return back to your original location, just by stepping back in the opposite
direction, or by cycling through all of the bookmarks until you get back to
the starting point.

Using the Text Editor

160

To add a bookmark, move the cursor to the location you want to mark, then
press the Toggle Bookmark button on the toolbar or press ALT+. (ALT key plus
period).
Bookmarks may also be inserted automatically when using the Find command to search for text; see the discussion on search options in Searching
for Text on page 158 for more information on this feature.
When the current window contains bookmarks, you can:

Move the cursor to the previous bookmark in the ring by choosing


Search>Bookmarks>Previous Bookmark, or by pressing the
Previous bookmark toolbar icon. You can also accomplish this by pressing
CTRL+, (the Ctrl and comma keys).
Move the cursor to the next bookmark in the ring by choosing
Search>Bookmarks>Next Bookmark, or by pressing the Next bookmark
toolbar icon. You can also accomplish this by pressing CTRL+. (the Ctrl
and period keys).

In addition to jumping between bookmarks, you can also jump and select
(highlight) the text between two bookmarks:

Press CTRL+SHIFT+, (Ctrl, SHIFT, and comma keys) to select the text
between the current location and the previous bookmark.
Press CTRL+SHIFT+. (Ctrl, SHIFT, and period keys) to select the text
between the current location and the next bookmark.

Removing Bookmarks
Remove a single bookmark the same way you set the bookmark: move the
cursor to the bookmarked location, then press the Toggle bookmark button
or press ALT+. (ALT key plus period). The Toggle Bookmark command works
as an on/off switch. If you issue the command when a bookmark is set, Toggle Bookmark turns it off. Issue the same command when there is no bookmark set, and Toggle Bookmark inserts a bookmark.
To remove all the bookmarks in your program, press the Clear all bookmarks
button on the toolbar, or choose Search>Bookmarks>Clear All Bookmarks
from the Visual LISP menu.

Chapter 5

161

Developing Programs With Visual LISP

Formatting Code with the Visual LISP


Formatter
The Visual LISP Code Formatter arranges the text of AutoLISP expressions in
a so-called pretty-print style, which improves text appearance and readability.
The Visual LISP Smart Indent helps to set better indentation during program
code input.
Note: The Formatter assumes that a fixed font is used to display or print the formatted text.

Running the Formatter


To format all the text in an active editor window, choose
Tools>Format AutoLISP in Editor from the Visual LISP menu, or click the
Format Edit window button on the Tools toolbar.
To format just part of your code, select a fragment of code text and choose
Format AutoLISP in Selection from the Tools menu, or click the
Format selection button on the Tools toolbar. The selection should contain a
sequence of valid AutoLISP expressions. The Formatter issues an error
diagnostic if the selected text is not a sequence of valid AutoLISP expressions.
If the Formatter finds unbalanced parentheses in your code, it issues the following message:

Click Yes to have Visual LISP add parentheses where it thinks they belong;
click No if you want to fix the parentheses on your own.
NOTE The Formatter can balance the number of parentheses, but usually
does not insert the additional parentheses in the right places. See Checking the
Balance of Parentheses on page 172 for more information on detecting and correcting unmatched parentheses.

Formatting Code with the Visual LISP Formatter

162

Visual LISP Formatting Fundamentals


The Visual LISP Formatter chooses the appropriate formatting style according
to rules that are explained below. You can influence these rules through the
AutoLISP Format Options dialog. To initiate the dialog, choose
Tools>Environment Options>AutoLISP Format Options from the Visual LISP
menu.

Basic Formatting Styles


There are two main formatting style sets:

A single-line formatting style: Plane


Multiple-line formatting styles: Wide, Narrow, Column

The sample text below demonstrates the different formatting styles.


Sample text initial appearance:
(autoload "appload"
("appload"))

For a general function call expression, the Formatter applies one of the styles
listed below:
Plane Style
In the Plane style, all arguments are placed in the same line, separated by a
single space:
(autoload "appload" ("appload"))

Chapter 5

163

Developing Programs With Visual LISP

The plane style is applied to an expression when all of the following conditions are met:

The expressions last character position does not exceed the value of the
environment option Text right margin
The expressions printing length is less than the value of the environment
option Maximum length for plane expression (that is, last character
position minus starting indentation position is less then this value)
The expression does not contain embedded comments with Newline characters

Wide Style
In the Wide style, the first argument is placed in the same line as the function
name, and other arguments are aligned in a column below the first argument.
(autoload "appload"
("appload")
)

The Wide formatting style applies to an expression when the following conditions are met:

The Plane style cannot be applied


The first element is a symbol and the first element's length is less than the
Maximum wide style car length environment option

Narrow Style
In the Narrow style, the first argument is placed on the next line after the
function name, and other arguments are aligned in a column below the first
argument. The displacement of the first argument's starting position relative
to the expression starting position is controlled by the value of the
Narrow style indentation environment option (in the following example,
this value is equal to 2):
(autoload
"appload"
("appload")
)

The Narrow formatting style applies for PROGN expressions, and for those
instances when the Plane and Wide formatting styles can not be applied.
The Narrow style indentation option (in AutoLISP Format Options) sets the
standard indentation for function arguments that use the Narrow formatting
style.

Formatting Code with the Visual LISP Formatter

164

Column Style
In the Column style, all elements are positioned in a column. This style is
appropriate for displaying quoted lists and COND-expression clauses. For
example, the following text:
((10 "{insertion}")
(7 "{style}"))

(1 "{string}")

would be displayed as:


((10 "{insertion}")
(1 "{string}")
(7 "{style}")
)

Additional Formatting Options


In addition to affecting the basic formatting styles, you can set the following
AutoLISP Format Options:

Closing paren style


This style controls the position of the closing parenthesis for multiple-line
formatting styles. You can select one of the following options:

Close at the same line

Close parenthesis on the last line of each formatting expression

Close at the new line with inner Close parenthesis on the next line following the
indentation
last line of each formatting expression with the
inner indent
Close at the new line with outer Close parenthesis on the next line following the
indentation
last line of each formatting expression with the
outer indent

Chapter 5

165

Developing Programs With Visual LISP

Examples:
The initial expression is written as:
(cond
((/= (logand mask flg) 0)
(list (list txton)))
)

Formatting result when Close at the same line option is selected:


(cond ((/= (logand mask flg) 0)
(list (list txton))))

Formatting result when Close at the new line with inner indentation
option is selected:
(cond ((/= (logand mask flg) 0)
(list (list txton))
)
)

Formatting result when Close at the new line with outer indentation is
selected:
(cond ((/= (logand mask flg) 0)
(list (list txton))
)
)

Insert form-closing comment


If you select this option, Visual LISP adds a comment following the close
of an expression. However, the option takes effect only if the Closing
parenthesis style format setting is either Close at the new line with
inner indentation, or Close at the new line with outer indentation.
When the Insert form-closing comment option is on, the Formatter
inserts a comment of the form:
;_ end of <function name>

after each multiple-line function. This comment does not appear if an


inline-comment, single-semicolon comment, or pasted-comment exists
after the function call. You can change the comment text by entering a
different comment in the Form-closing comment prefix field of the
AutoLISP Format Options dialog box.

Formatting Code with the Visual LISP Formatter

166

Example
Initial text:
(autoxload "image"
("gifin" "pcxin" "riaspect" "ribackg" "riedge"
"rigamut" "rigrey" "rithresh" "tiffin"))

Formatted text:
(autoxload "image"
("gifin"
"ribackg"
"rigrey"
)
) ;_ end of autoxload

"pcxin"
"riedge"
"rithresh"

"riaspect"
"rigamut"
"tiffin"

Preserve existing line breaks


When the Preserve existing line breaks option is on, the Formatter inserts
new lines whenever a new line is detected in the text it is formatting.
When the option is off, the formatter can squeeze a multiple-line expression to the plane style if it fits within the right margin. The Formatter also
preserves all new lines between top-level expressions.
The following example shows how the Preserve existing line breaks option
works:
Initial text:
(if (/= s "Function canceled")
"\nError: "
s)) ;single semicolon cmt
)

(princ (strcat

Formatting result if the option is on (default):


(if (/= s "Function canceled")
(princ (strcat
"\nError: "
s
)
)
)

;single semicolon cmt

Formatting result when the option is off:


(if (/= s "Function canceled")
princ (strcat "\nError: " s))
)

;single semicolon cmt

Note that multiple-line PRINC and STRCAT expressions are compressed to a


single line.

Chapter 5

167

Developing Programs With Visual LISP

Split Comments
When the Split Comments option is on, the Formatter splits long comments that extend past the right margin.
For the previous example, if the Text Right Margin setting is 60, and Single-semicolon comment indentation is 40, the Formatter will split the
comment as follows:
(if (/= s "Function canceled")
(princ (strcat "\nError: " s))

;single
;semicolon cmt

Longlist format style


Longlists are lists of formal arguments in DEFUN, LAMBDA, or quoted lists
containing more than 5 elements.
To specify a Longlist option, click the More Options button in the
AutoLISP Format Options dialog box. This expands the dialog box window with additional formatting options:

Formatting Code with the Visual LISP Formatter

168

The available modes for Longlist format are listed below and illustrated with
an example based on the following list elements:
("aseadmin" "aserows" "aselinks" "aseexport"
"aseselect" "asesqled")

Single-column formatting
("aseadmin"
"aserows"
"aselinks"
"aseexport"
"aseselect"
"asesqled"
)

2-column formatting
("aseadmin"
"aselinks"
"aseexport"
)

Multi-column formatting
("aseadmin"
"aseselect"
)

"aserows"
"aseselect"
"asesqled"

"aserows"
"aseexport"

"aselinks"
"asesqled"

Fill-the-string formatting (places as many quoted strings on one line as


possible, up to the right margin)
("aseadmin" "aserows" "aselinks" "aseselect" "aseexport" "asesqled"

Setting Case for symbols


By default, The AutoLISP Formatter does not change the case of AutoLISP
symbols. You can set the Formatter to change the case of symbols according to the Visual LISP protection state for symbols.
The Protected options subgroup controls the case conversion of
protected symbols (that is, built-in symbols or symbols with the
ASSIGN-PROTECT flag set):

Chapter 5

169

None

Does not change the case

downcase

Forces all characters in a symbols name to lower case

UPCASE

Forces all characters in a symbols name to upper case

Developing Programs With Visual LISP

The Unprotected options subgroup controls case conversion of unprotected (user) AutoLISP symbols:

None

Does not change the case

downcase

Forces all characters in a symbols name to lower case

UPCASE

Forces all characters in a symbols name to upper case

Comment Styles
The Visual LISP AutoLISP Formatter recognizes five types of comments, and
positions each comment according to its type.
Visual LISP Comment Formatting
Comment

Formatted Appearance

;| Inline comment |;

The single-line comment appears after formatting as


any other expression; the multiple-line comment
appears starting at a new line.

; Single-semicolon comment

Starts at the comment-column position, as defined by


the Single-semicolon comment indentation
AutoLISP Format option.

;; Current-column comment

The comment appears starting on a new line, indented


at the same level as the last line of program code.

;;; Heading or 0-column comment Appears on a new line, without indentation.


;_ Function-closing comment

Appears just after the previous expression

Formatting Code with the Visual LISP Formatter

170

The following example demonstrates each comment style:


Initial text:
(defun foo (x)
;|inline comment |;
(list 1 2 3) ;comment-column comment
;;current-column comment
;;; heading or 0-column comment
)
;_ function-closing comment

Formatted text:
(defun foo (x) ;|inline comment |;
(list 1 2 3)
;;current-column comment
;;; heading or 0-column comment
) ;_ function-closing comment

;comment-column comment

Indentation Rules
The Visual LISP Smart Indent feature works in the background as you type
in the text editor. The indent is evaluated up to the current AutoLISP parenthesis nesting level. If before the current expression there is only a sequence
of completed top-level AutoLISP expressions, the indentation will be zero.
The indenting commands use formatting parameters consistently with the
Formatter. Re-indenting after running the Formatter will not change the text
if it was formatted using the same parameter values.

Saving and Restoring Formatting Options


To save your Formatter options so that they remain in effect across Visual
LISP sessions, choose Tools>Save Settings from the Visual LISP menu. Alternatively, you can save the current settings specifically for the program in the
active text editor window. Visual LISP saves Formatter settings in a program
when the Save formatting options in source file option is checked off.
To turn this option on or off, choose
Environment Options>AutoLISP Format Options from the Tools menu. If
the option is in effect, Visual LISP adds formatting information as comments
at the end of the program, when you run the Formatter.
Each Formatter invocation checks for formatting options settings at the bottom of the selected text. If found, these settings override the session settings
listed under Tools>Environment Options>AutoLISP Format options.

Formatter Restrictions
The following restrictions apply to the Visual LISP AutoLISP Code Formatter:

Chapter 5

171

The formatter relies on a fixed window font and a particular Tabulation


size. You can change these settings using the
Window Attributes>Configure current option of the Tools menu.

Developing Programs With Visual LISP

The Formatter is available only within Visual LISP Editor windows.


Existing Space and Tab characters placed outside of inline comments and
strings will not influence the formatting result.

Checking for Syntax Errors


One of the main attractions of using Visual LISP is the extensive debugging
tools it provides. These tools allow you to watch what your program is doing
while it is executing, and to take a snapshot of your program at any point.
But Visual LISP also provides a number of features designed to detect program errors before you even run the program.

Checking the Balance of Parentheses


AutoLISP uses parentheses more frequently than most other computer languages. One of the most frequent syntax errors in AutoLISP is an unequal
number of opening and closing parentheses. Visual LISP includes a number
of tools to help you detect unbalanced or unmatched parentheses.
As noted earlier in this chapter (Running the Formatter on page 162), the
Visual LISP Code Formatter searches for unbalanced parentheses when it formats your code. If you allow it to, the Formatter will add parentheses where
it thinks they are missing. Typically, though, the Formatter adds parentheses
at the end of a program, not where you really need them. So if you let it add
the parentheses, you will probably have to remove them later.
NOTE At the current time, if you do not allow the Formatter to add the balancing parentheses, it wont format your code either!
In any event, you need to check the structure of your program to determine
where the parentheses are really missing. You can use the Parentheses Matching items on the Edit menu to help you find unbalanced parentheses:

Match Forward

(CTRL+])

Moves the insertion point (marked by the cursor) just past the
closing parenthesis that matches the next open parenthesis. If
there is no nearby match, it moves you one step up in the nesting
hierarchy.

Match Backward Moves the insertion point to just before the open parenthesis that
matches the previous close parenthesis. If there is no nearby
(CTRL+[)
match, it moves you one step up in the nesting hierarchy.
Select Forward

Moves the insertion point as the Match Forward command does,

(CTRL+SHIFT+]) but also selects all text in between the start and end positions.

Checking for Syntax Errors

172

Select Backward Moves the insertion point as the Match Backward command does,
(CTRL+SHIFT+[) but also selects all text in between the start and end positions.

For example, look at the following code:

1
2
3
4
5

17

The line numbers are not part of the text; they are used to help explain the
example.
Here is what would happen if you loaded this code in Visual LISP and continually issued the Match Forward command, starting with the insertion
point at the beginning of line 1:
1 Cursor moves to the end of line 1
2 Cursor moves to the end of line 2
3 Cursor moves to the end of line 3
4 Cursor jumps to the last right parenthesis in the program! (17)
In other words, the close parenthesis that matches the open parenthesis on
line 4 is all the way at the end of the program. Notice also that all the
statements after line 4 are indented in a manner unlike that of the preceding
program code. These are 2 clues that indicate something is amiss at this point
of the program. In fact, the close parenthesis to the command on line 4 is
missing.

Using Color Coding to Detect Syntax Errors


The Visual LISP Sample directory contains a file named drawline-with-errors.
It is similar to the drawline program introduced earlier in this manual, but it

Chapter 5

173

Developing Programs With Visual LISP

contains a couple of errors. Open the file in Visual LISP, so that you can see
how color is used in the file:
(defun drawline(/ pt1 pt2); local variables declared
;; get two points from the user
(setq pt1 (getpoint "\nEnter the start point for the line: "))
(setq pt2 (getpoint pt1 "\nEnter the end point for the line: "))
;; check to see that the two points exist
(iff (and pt1 pt2)
(command "_.line" pt1 pt2 "")
(princ "\nInvalid or missing points!")
(princ)
;; exit quietly
)
)

The example above uses different fonts to substitute for the different colors.
If you use the standard Visual LISP syntactic colorations, systems functions
such as setq, defun, getdist, getpoint, and / are displayed in blue. Items
Visual LISP does not recognize, such as user-defined variables, are printed in
black. In this example, if you look at the unrecognized elements in the program, the word iff might easily catch your eye. Change it to the correct
spelling, if, and the color immediately changes to that used for system
functions.

Using the Check Command to Look for Syntax Errors


You can perform additional syntax checking with the Visual LISP Check command. To check the syntax of all the text in an editor window, do the following:

Switch to the editor window containing the code you want to check
Choose Tools>Check Editor from the Visual LISP menu

You can also perform a syntax check on a selected piece of code, instead of
the whole program, by using the Check Selection item on the Tools menu.
Visual LISP displays error messages in a new output window, if it detects any.
The sample code above results in the following error message:

The message indicates that an IF statement contains too many arguments.

Checking for Syntax Errors

174

Finding the Location of the Syntax Error in Your Program


If you double-click on the error message in the output window, Visual LISP
activates the editor window, places the cursor at the beginning of the statement that caused the error, and highlights the entire expression:

This error results from the last princ statement following the if. The if statement only allows two arguments: the statement to execute if the expression
is true, and the statement to execute if the expression is false. The last princ
statement, which is used in this program to cause a quiet exit, belongs after
the close parenthesis that currently follows it. If you move the statement to
the correct location and run Check again, the code should pass as error-free.

Running Your Program


To run a program that is in an editor window, first activate the window
containing the code. With the text editor window active, choose
Tools>Load Text in Editor from the Visual LISP menu, or click the Load active
edit window button (shown at left) in the Run toolbar. Visual LISP responds
by displaying a message in the Console window indicating that the program
has been loaded.
To run the program, enter the function name (not the file name) at the Console prompt, in parentheses. For example:
_1$ (drawline)
Note that you can also choose to run just part of your code by selecting the
text you want to run, then choosing Tools>Load Selection.
If the program fails with an error message, or does not do what you expect it
to do, Visual LISP can help you determine why. See Debugging Programs
for information on using Visual LISP to analyze what your program is doing.

Chapter 5

175

Developing Programs With Visual LISP

6
Debugging Programs

In this chapter
Programs do not always behave in the way they were
intended to. When the results you get appear to be wrong,

Debugging Example

Debugging Features

Data Inspection Tools

or are causing the program to crash, it can be difficult to


determine what is going wrong. Debugging is the process of
finding and resolving program problems. Visual LISP provides many features that assist you in the debugging process.

176

Debugging in Visual LISP


Debugging is usually the most time-consuming stage in the development of
any program. For this reason, Visual LISP includes a powerful debugger that
allows you, among other things, to do the following:

Trace program execution


Trace variable values during program execution
See the sequence in which various expressions are evaluated
Inspect the values of parameters used within function calls
Interrupt program execution
Step through program execution one instruction at a time
Inspect the stack

Visual LISP provides the following facilities to implement these features:

Chapter 6

177

Break Loop Mode allows you to halt program execution at specified


points, and to look at and modify the value of objects during the break.
Examples of AutoLISP objects are variables, symbols, functions, and
expressions.
Inspectors provide detailed information on an object in an Inspector
dialog window. If the object being inspected is composed of nested objects
(a list, for example), the Inspector allows you to inspect all the components, each one listed on its own line within the window. You can also
recursively inspect any nested object until an atomic object (such as a
number or a symbol) is reached.
The Watch window allows you to watch the values of variables during
program execution. The content of the Watch window is updated automatically. This means that if the value of a variable placed in the Watch
window is changed, this change will automatically be reflected in the
Watch window.
The Trace Stack Facility allows you to view the function call stack. The
call stack is a mechanism by which Visual LISP records the sequence of
functions as they are executed by your program. You can view the stack
during a debugging session (when the program is in a suspended state,
such as stepping through after a breakpoint), or after your program has
crashed. If viewed after your program crashes, the function call stack
shows what Visual LISP was doing at the moment the application failed.
The Trace Facility is a standard LISP facility that allows you to log the
calls and return values of traced functions into the special Trace window.

Debugging Programs

Debugging Example
This section takes you through a Visual LISP sample program, using many of
the VLISP debugging facilities along the way. You can find the sample program, yinyang.lsp, in the VLISP \sample directory. Open the file in Visual LISP
so that you can try the examples in this section.
First, load the file and run the yinyang function in order to see what it does.
The function draws the Yin-Yang symbol, which is used symbolically by a
number of religions and philosophies, including Confucianism and Taoism:

When you run the program, Visual LISP passes control to AutoCAD and you
need to respond to the prompts in the AutoCAD command window.
Visual LISP evaluates AutoLISP programs by evaluating the expressions contained in parentheses (parenthetical expressions). Parenthetical expressions
are similar to operators in other programming languages such as C++ and
Visual Basic. The Visual LISP debugger uses an expression-based approach,
unlike the line-by-line debuggers of languages such as C. In this approach,
the debugger can suspend program execution immediately before or after the
evaluation of any expression.
Debugging options are controlled from several different places within Visual
LISP, including the text editor, the System Console, and various menus.

Setting a Breakpoint to Interrupt Program Execution


Begin by entering some debugging information in the text editor window
containing the yinyang.lsp program. Set a breakpoint to halt program
execution:
1 Move the cursor in front of the opening parenthesis in the line of code that
reads:
(setq half-r (/ radius 2))

Debugging in Visual LISP

178

Breakpoint

2 Click the Toggle Breakpoint button in the Debug toolbar,

or choose Debug>Toggle Breakpoint from the Visual LISP menu. Toggle


Breakpoint works as an on/off toggle: when no breakpoint exists, Toggle
Breakpoint adds a break; if a breakpoint already exists at the cursor position,
Toggle Breakpoint removes it.
3 Load the yinyang function, if you have not done so already, then run it from
the Visual LISP Console prompt by entering the following command:
(yinyang)

After you reply to the prompts the program displays at the AutoCAD
command line, Visual LISP halts yinyang execution at the breakpoint you
set, and displays the code in the text editor window:

Note how the statement following the cursor is highlighted.

Stepping Through the Program


The Step commands allow you to move through a program by executing one
or more expressions at a time. With your program stopped at the breakpoint:

Chapter 6

179

Debugging Programs

1 Click the Step Into button, or choose Debug>Step Into from the Visual LISP
menu. You can also press F8 to issue the Step Into command.
Execution begins and halts before evaluation of the inner parenthetical
expression, that is, before the specified division occurs.

Now look at the Step Indicator button on the Debug toolbar; it is the last button on that toolbar:

Step Indicator
Button
The Step Indicator button is active when you are stepping through a program. It indicates where you are in relation to the expression at the breakpoint. The current symbol indicates that you are stopped just before an open
parenthesis.
2 Click the Step Into button again. The cursor moves to a position directly after
the evaluated expression, and the Step Indicator button indicates this with
the following icon:

3 Click the Step Into button again.The cursor moves to the end of the entire
statement (the expression and all nested expressions).
4 Click the Step Into button again and the cursor moves to a position just
before the beginning of the statement on the next line:

Debugging in Visual LISP

180

5 Now take a bigger step. Click the Step Over button, or choose Debug>Step
Over from the menu; you can also press SHIFT+F8 to issue this command:

With the Step Over command, Visual LISP evaluates an entire expression
(and all nested expressions), then stops at the end of the overall expression.
The cursor moves to the end of the expression.

Tracing the Evaluation Results of an Expression


As you step through a program, you may want to trace the values resulting
from the evaluation of individual expressions. Start by checking the value of

Chapter 6

181

Debugging Programs

the last evaluated expression. From the Debug menu, choose Watch Last
Evaluation:

VLISP displays the Watch window, which shows the value of the
*LAST-VALUE* system variable. Visual LISP always stores the value of the last
evaluated expression in the *LAST-VALUE* variable.

Tracing Variables During Program Execution


You can use the Watch window to trace variables during program execution.
1 In the text editor window containing yinyang.lsp, double-click on any occurrence of the variable name origin-y.
2 Click the Add Expr button in the Watch window: Visual LISP passes the
origin-y variable name to the Watch window and displays the current value
of the variable in the window:

If the Watch window were not already open and you wanted to view a variables value, you could open the window by choosing View>Watch Window
from the Visual LISP menu.
If you click the Watch windows Add Expr button without double-clicking on
a variable name first, the following window appears:

In this window, you can enter the name of the variable you want to view.
Visual LISP anticipates you by copying the name of the variable nearest the

Debugging in Visual LISP

182

cursor into the window; if this is not the one you want to view, simply type
over the name.
Visual LISP updates the variables in the Watch window after each execution
step.
Click the Step Over button (or press SHIFT+F8) twice. In the Watch window,
note how the value of ORIGIN-Y changes. It was nil at first, but after execution it took on the value corresponding to the point you clicked in the
AutoCAD window:

Continuing Program Execution


To continue running your program to the next break point, or to the end if
there are no more break points, click the Continue button on the Debug toolbar, or choose Debug>Continue from the Visual LISP menu.

Debugging Features
In addition to setting breakpoints as you saw in the Introduction section of
this chapter, Visual LISP provides the following options for controlling program execution:

Chapter 6

183

Break on Error. This option activates the interactive break loop automatically whenever your program encounters a runtime error. You turn on
this mode of operation by choosing Debug>Break On Error from the
Visual LISP menu.
Stop Once. This option causes Visual LISP to break unconditionally
when it evaluates the very first LISP expression prepared for debugging.
From the Debug menu, choose Stop Once to initiate this mode.
Break on Function Entry. Setting the Debug-on-entry flag for a functions name symbol causes a break to occur every time you invoke that
function. At the break, the source code for the function will be shown in
a special window. You can set or clear the Debug-on-entry flag interactively with the Symbol Service dialog. See The Symbol Service Dialog on
page 199 for information on setting this flag.
Debug Top-Level Mode allows you to control the loading of a program
from a file or from an editor window. Breaks occur before evaluating every

Debugging Programs

top level expression (such as defun). The Debug Top-Level mode is turned
on by switching off the Do not Debug Top Level option. To find the checkbox for this option, choose Tools>Environment Options>General Options
from the Visual LISP menu, then click the Diagnostic tab.
Note that if Top-Level debugging is turned on, and Stop Once mode is also
turned on, Visual LISP will enter the debugging mode every time you load
a file. This is due to the fact that Visual LISP is debugging defun, setq, and
other functions defined within the file as they are loaded. This is usually
not a helpful debugging technique and should only be required in rare
instances.

Animate Mode operates as if a Step Into command is executed repeatedly with a specified delay. Editor windows in the Animate mode will
highlight expressions being evaluated, and the Watch window will permanently update its data. To turn on Animate mode, choose Debug>Animate
from the Visual LISP menu. When Animate mode is on, Stop Once mode
is ignored.
Animation speed is controlled by the value of the Animation delay environment option. To view and set this option, choose
Tools>Environment Options>General Options from the VLISP menu, and
click the Diagnostic tab.

Starting Debugging
The easiest way to start debugging is to choose Debug>Stop Once from the
Visual LISP menu. When this item is selected, the evaluation of the first LISP
expression will be interrupted. After that you can resume program execution
using various Debugger commands. Another way to enter into the debug
mode is to set a breakpoint, as shown in Setting a Breakpoint to Interrupt
Program Execution on page 178.
When a break occurs, the corresponding Visual LISP text editor window will
show the current LISP expression at the point which the break took place. A
break loop marker will appear in the Console window. Using the Console
window, you can access and manipulate the program environment in which
the break occurred. You can also examine variables using the Watch window.

The Break Loop


Expressions are the basic structural units of AutoLISP. Visual LISP works by
repeatedly reading, evaluating, and printing expressions. In LISP terminology, this is a read-eval-print loop.

Debugging Features

184

When you are running an AutoLISP program without any debugging intervention by Visual LISP, you are running in the Top Level read-eval-print
loop. When you evaluate an expression within the Visual LISP Console, and
the normal prompt is displayed, you are also working at the Top Level.
When a programs evaluation is interrupted or suspended in the middle of
execution, Visual LISP passes control to the Console and you enter a break
loop. This break loop is a separate read-eval-print loop, and is nested underneath the original read-eval-print loop. It is possible to interrupt a break loop
and start yet another read-eval-print loop beneath it. The nesting level of a
break loop with respect to the Top Level is called the break level.
When you enter a break loop, Visual LISP prefixes the Console prompt with
a number indicating the level you are at. For example, when you first enter a
break loop in a program, the prompt indicates this with the number 1:
_1_$

While you are in a break loop, you cannot switch control to the AutoCAD
window.
On exiting from a break loop (for example, after issuing the Quit command),
the current read-eval-print loop is terminated and the previous level loop is
resumed. If you change the value of a variable in the break loop, this value
will be used when the program resumes execution.

Continuable Break Loops


There are continuable and noncontinuable break loops in Visual LISP. You
can enter the continuable break loop at the very first break in program execution by:

Turning on the Stop Once mode and reaching an expression with debugging information (that is, an expression that is loaded from source code,
as opposed to from a compiled .exe file
Reaching a function marked for Debug on Entry
Reaching a breakpoint you set in the program
Entering a break loop by pressing the Pause button
Proceeding with a Step Over, Step Into or Step Out command from the
previous break loop state

When the program is interrupted, you enter the break loop. This is apparent
if the Visual LISP Console is active, since the prompt is changed to reflect the
current level of the break loop. In this suspended state, you have read-write
access to all variables in the environment in which the break occurred. For
example, if the break occurred within a function containing several local
variable declarations, those variables are accessible and you can change their
values by issuing setq assignments at the Console prompt.

Chapter 6

185

Debugging Programs

When stopped at a breakpoint, you can control subsequent program execution by choosing one of the following items from the Debug menu, or by
pressing the equivalent toolbar button:

Reset to Top Level. This terminates all currently active break loops and
returns to the Console top-level (the top read-eval-print loop).
Quit Current Level. This option terminates the current break loop and
returns to a break loop one level up. This may be another break loop or
the top level read-eval-print loop.
Continue resumes normal program execution from the breakpoint.

The Step commands evaluate portions of program code before resuming suspended mode:

Step Over looks for the closing parenthesis matching the opening parenthesis where the program is currently paused, and evaluates the expressions in between.
Step Into jumps into a nested expression, if any. If there are no nested
expressions, it jumps to the next expression in sequence.
Step Out searches for the end of the function where the program is currently paused, and evaluates all of the expressions up to that point.

After exiting the break loop to the Console top level, the Console prompt
returns to its original form (without a number prefix).

Non-continuable Break Loops


A non-continuable break loop is activated when an error causes program
interruption and the Break on Error option is set. In a non-continuable break
loop, you can access all variables in the error environment, but you cannot
continue program execution or execute any of the Step commands.
To leave a non-continuable break loop step, use either the Reset to Top Level
command to jump to the Console top-level loop, or Quit Current Level to
return to the previous break loop level.
To distinguish between continuable and non-continuable break loops, check
to see whether the Step and Continue toolbar buttons are active or not.

Breakpoints
A breakpoint allows you to mark a position in a program at which program
execution should be interrupted. You can set breaks to occur before or after
parenthetical expressions.

Setting and Deleting Breakpoints


Breakpoints can only be set from a Visual LISP text editor window. To set a
breakpoint, move the cursor to the position at which you want to halt exe-

Debugging Features

186

cution. For example, to halt execution just before the open parenthesis of an
expression, place the cursor just to the left of that open parenthesis. Then
click the Toggle Breakpoint toolbar button or press F9 to set the breakpoint.
(For variety, you can set a breakpoint by choosing Debug>Toggle Breakpoint
from the Visual LISP menu, or by clicking the right mouse button and selecting Toggle Breakpoint from the resulting context menu.)
To remove the breakpoint at a later time, follow the same exact procedure.
The Toggle Breakpoint works as an on/off toggle: when no breakpoint exists,
Toggle Breakpoint adds a break; if a breakpoint already exists at the cursor
position, Toggle Breakpoint removes it. You can also use the Breakpoint service dialog to remove breakpoints; see Listing and Viewing the Breakpoints
in Your Program on page 188 for information on this procedure.
If you move the cursor to an ambiguous position, such as in the middle of an
expression, Visual LISP will move the cursor to the nearest parenthesis and
ask you if you agree with the breakpoint placement:

Click Yes to accept the breakpoint location, or No if that is not where you
want to set the break.
Breakpoint Highlighting
Visual LISP marks each breakpoint position with a colored rectangle, so you
can easily locate the breakpoints in your program. By default, active breakpoints are marked in red. You can change this color by setting the
:BPT-ACTIVE option under Tools>Window Options>Configure Current.

Disabling Breakpoints
When using multiple breakpoints within a source file, it may be useful to
temporarily disable one or more breakpoints, but leave the breakpoint position defined for possible later use. This saves time over deleting and restoring
the breakpoint.
To disable a breakpoint, place the cursor at the breakpoint marker and press
the right mouse button. From the resulting menu, choose Break point service. Visual LISP displays the following dialog box:

Chapter 6

187

Debugging Programs

Click the Disable button in the Breakpoint service dialog window to temporarily disable the breakpoint. Visual LISP changes the color of the breakpoint
marker when it disables the breakpoint. By default, it marks disabled breakpoints in blue. You can change this color by setting the :BPT-DISABLE option.

Listing and Viewing the Breakpoints in Your Program


From the View menu, choose Breakpoints Window to see a list of all breakpoints currently defined to Visual LISP:

The Breakpoints window lists the breakpoints in all programs you are editing
in Visual LISP, not just the program in the active editor window. In the example above, only one program (yinyang) is listed, because that is the only one
currently open. But you could be editing and setting breakpoints in any
number of open files.
Each entry in the Breakpoints window shows the name of the source file containing the breakpoint, and the location of the breakpoint in the source. A
leading + or - sign differentiates between active and disabled breakpoints.
The dialog box allows you to delete all breakpoints at once or to edit (or display) one breakpoint at a time. Pressing Show displays the source position of
the breakpoint. The Edit button opens the Breakpoint service dialog, from
which you can disable the breakpoint.

Life Cycle of a Breakpoint


You can set breakpoints in a program either before or after you load the program. However, if you change the text in a program after loading the pro-

Debugging Features

188

gram, and then add a breakpoint, the breakpoint only takes effect after you
reload the code.
Breakpoints remain in effect during the Visual LISP editing session and will
survive between sessions if you choose Save Settings from the Tools menu.
In addition to removing breakpoints using the methods previously described
in this chapter, program breakpoints are automatically lost when you do any
of the following:

Delete the code fragment containing the breakpoint


Modify the file outside of the Visual LISP editor (for example, edit and save
it with Notepad)
Apply Visual LISP formatting commands to code fragments containing
breakpoints

Note also, that if you modify a programs code and run it without reloading
it (with the Load Active Edit Window command), the program will be interrupted when a breakpoint is reached, but the exact source position will not
be shown. The following dialog box indicates that this situation has
occurred:

To enable proper display of a source position, you need to reload the code
and restart the program.

Visual LISP Data Inspection Tools


Visual LISP gives you almost unlimited access to symbols, values, and functions at any stage of program execution. Visual LISPs data inspection tools
are implemented as modeless dialog windows (except for the Symbol Service), meaning that they stay on the screen as long as you need them, no
matter what your program does:

Chapter 6

189

The Watch window displays the current value of any set of variables.
The Trace Stack window displays the most current call hierarchy. At
any level of the stack you can view the corresponding code, the calling
code, the local variables, and more.

Debugging Programs

The Symbol Service window displays the current value of a symbol as


well as its current flags. You can modify both the value and the flags from
here.
Inspector windows display any LISP object (from a string to an
AutoCAD block definition) to any level of detail needed.
Frame binding windows display the values of all local variables for
their particular stack frame (that is, the specific function invocation in the
call sequence).

The Watch Window


The Watch window monitors the values of AutoLISP variables during program execution. Each Watch window element line displays the name of a
variable and its current value:

The Watch window is updated at each step of a Visual LISP interactive session
and always shows the current environment state. In debugger mode, the
Watch window is refreshed automatically at the end of every expression evaluation.
The Watch dialog retains its contents during a Visual LISP session. This
means that if you open the Watch dialog and make it inactive, it will have
the same contents the next time you invoke the Watch command during the
current session.

Adding a Variable to the Watch Window


To add a variable to the Watch window, simply highlight the variable name
in any context (that is, in an editor window, Console, etc.) and press the Add
Watch button, or choose Add Watch from the Debug menu. You can also
select Add Watch from a context menu by clicking the right mouse button
while the cursor is on a variable name.
If the Watch window is already active, you can add additional variables to the
watch list by clicking the Add Watch button on the toolbar in the Watch window.
If Visual LISP cannot determine which variable you are interested in based on
the cursor position or the text youve selected, it displays the Enter expression to watch window:

Visual LISP Data Inspection Tools

190

Specify the name of the variable to be watched in this window, then click OK.
The introductory section of this chapter includes an example of using the
Watch window; see Tracing Variables During Program Execution on
page 182.

Watch Toolbar
The toolbar on the Watch window contains the following buttons:

Add Watch

Invokes the Add Watch command to add a new variable to


the Watch window; this variable can be selected at any
active Text Window or typed in the Add Watch dialog

Clear Window

Removes all variables from the Watch window

Sort Expressions

Sort the variables in the Watch window alphabetically by


name

Copy to Trace/Log Invokes the log command and copies the contents of the
Watch dialog to the Trace window

Using the Watch Item Context Menu


To display the Watch Item context menu, highlight the item from the watch
list and right-click:

Chapter 6

191

Debugging Programs

On the Watch item menu:

Inspect value invokes the Inspector dialog for the selected value.
Copy value copies the value of the selected variable into system variable
*obj*.
Print value prints the selected variable value in the Console window,
prefixed with a single quote ().
Symbol... calls the symbol service dialog for the selected variable.
Apropos... calls the Apropos dialog using the selected symbols name as
the Apropos argument.
Remove from Watch removes the selected variable from the Watch
window.

Visual LISP Data Inspection Tools

192

The Trace Stack Window


Visual LISP has a special debugging tool called a trace stack. A trace stack is a
historical record of the execution of functions within your program. It is
called a stack because of the computer programming structure of the same
name. The illustration below shows adding and removing items from a stack.
You can see why a stack structure is often referred to as LIFO Last In, First
Out.

The trace stack is used by Visual LISP to remember its way out of a nested
series of expressions. By viewing the stack you can see what is happening
within your program as it is executing (within a suspended, break mode) or
immediately after it crashed.
Before you invoke a function at the Console window or from AutoCAD, the
trace stack is empty. The action of invoking a function causes a record, or element, to be placed on the stack. As that function calls additional nested functions to perform the work of your program, additional elements may be
added to the stack. Visual LISP only needs to place elements on the stack
when it needs to remember its way out of nested functions.
There are two conditions where it is useful to examine trace stacks. The first
is when your program is in a suspended state, such as during a breakpoint
pause. The second is after an error has occurred, causing your program to fail.

Chapter 6

193

Debugging Programs

Stack Element Lists


A stack element is an individual record or line-item history within a trace
stack. There are five kinds of elements that may appear within a stack:

Function call frames show one individual function invocation. Each


function call frame appears in the following format:
level (function-name {argument1}...)

Arguments within this listing are displayed not by their local parameter
name, but by the values that were actually passed to the function.

Keyword frames are displayed at the very top and bottom of a trace
stack. They are displayed in the form:
level :keyword {optional-data}

The keyword indicates the type of the frame. The optional-data displays
additional information relating to the state of the program.

Top forms indicate an action that was initiated by typing in an expression at the top level Console window, or from the invocation of a function
that was triggered during the loading of a file or selection within a Visual
LISP editor window.
Lambda Forms are placed within a stack whenever a lambda function is
encountered within your program.
Special Forms display the invocation of the foreach and repeat functions. The arguments for these functions are not displayed. They appear
as:
level (function-form ...)

Function Call Frames and Keyword Frames are discussed in more detail in the
following sections. These sections use the following code to demonstrate the
trace stack. If you wish, you can copy this code into a Visual LISP editor window, set a breakpoint as indicated in the code comments, and run this sample:
(defun stack-tracing (indexVal maxVal)
(princ "At the top of the stack-tracing function, indexVal = ")
(princ indexVal)
(if (< indexVal maxVal)
(stack-tracing (1+ indexVal) maxVal)
(princ "Reached the maximum depth.") ; place a breakpoint at the
; beginning of this line
)
)
(defun c:trace-10-deep ()
(terpri)
(stack-tracing 1 10)
)

Visual LISP Data Inspection Tools

194

Viewing the Current Trace Stack


To see the state of a function call stack while your program is suspended at
a break point, choose View>Trace Stack from the Visual LISP menu, or click
the Trace stack toolbar button:

The Trace Stack window displayed above shows a Function Call Frame for the
stack-tracing function. The second element, or frame, in the trace stack is
highlighted:
[2] (STACK-TRACING 10 10)

The number [2] simply identifies it as the second element in the stack. The
numbers following the stack-tracing function name (10 10) indicate the
actual values that were passed to the function.

Displaying Information on a Trace Stack Element


To obtain more information about an element in the trace stack, select the
element and right-click to display a context menu:

Active items available on the context menu depend on the type of stack element you selected before right-clicking. Possible menu commands include
the following:

Chapter 6

195

Inspect calls the Inspector for the selected stack element.


Print prints the stack element to the Console window.
Function Symbol calls the Symbol Service dialog for the function call
in the stack frame, if the function is called by the symbol.

Debugging Programs

Copy copies the selected trace stack element to system variable *obj*.
Local Variables displays the Frame Bindings dialog to allow browsing of
local variable values at the time the function was called; see Frame Binding Window on page 196.
Source Position checks whether the source text is available for the function called at the selected stack frame. If the source code is available, the
text window with the source code is displayed, with the current position
inside the function highlighted.
Call Point Source shows the position of the caller expression, similar to
Source Position.

Frame Binding Window


Choose the Local Variables menu item to display the Frame Binding window:

The Frame Binding window displays information about the local variables in
the frame. In the example above, it lists the parameter names (INDEXVAL,
MAXVAL), along with the values assigned to these parameters. These are the
values that were passed to the function. The parameters are listed in the order
that they are defined within the function.
If you right-click on an entry in the Frame binding window, Visual LISP displays a context menu:

The menu contains the following items:

Inspect calls the Inspector for the selected value.


Print displays the selected value in the Console window.
Symbol calls the Symbol Service dialog for the selected symbol.
Copy copies the selected value into the system variable *obj*.
Add to Watch adds the selected symbol to a Watch window.

Keyword Frames
A Keyword Frame indicates a specific type of operation that has occurred
within the Visual LISP environment. The keyword indicates the type of oper-

Visual LISP Data Inspection Tools

196

ation. Keyword frames will appear in only two locations: at the very top of
the stack, or at the very bottom of the stack.
The following types of Keyword Frames will appear only at the bottom of a
stack:

:TOP-COMMAND indicates that the Visual LISP interactive environment


requested the action resulting in the first element placed within the stack.
This situation occurs, for example, when a function is invoked directly
from loading a selection or a file.
:USER-INPUT indicates that the character string shown in the frame was
entered from the Visual LISP Console. The frame immediately above the
keyword describes the expression as it was translated from the user input.
If the input string is too long, right-click to open a context menu, and
choose Show Message to view the entire text. You can also choose the
Inspect command to inspect the entered string.
:ACAD-REQUEST indicates that a call to the function shown in the
frame immediately above the :ACAD-REQUEST keyword frame was
invoked from the AutoCAD command prompt.
:DCL-ACTION indicates that execution of a DCL tile or dialog action was
requested from AutoCAD. The keyword :DCL-ACTION is followed by two
strings: the DCL dialog name, and the value of the $KEY variable in the
DCL action body. If a number appears, it is the value of the $REASON variable in the DCL action body. The frame immediately above the keyword
describes the function call built from the action string.
:INSPECT-EVAL indicates the evaluation of an Inspect command.
:INSPECT-VERBOSE indicates entrance into a drawing Inspector hook
function.
:WATCH-EVAL indicates the evaluation of a watch expression.

The following types of keyword frames may appear at the top of a stack:
:BREAK-POINT indicates a user-specified break point.
:ERROR-BREAK indicates a general runtime error. The Show Message rightclick context menu selection allows you to view more specific error messages.
:READ-ERROR indicates an error during a read operation. The Show Message right-click context menu selection provides additional information
about the error.
:SYNTAX-ERROR will appear when Visual LISP encounters incorrect
AutoLISP program syntax.
:FUNCTION-ENTRY indicates that the reason for program interruption is a
debugger break upon entering the function. The stack element following this
message contains the call frame for the function in which the break occurred.

Chapter 6

197

Debugging Programs

:BEFORE-EXP indicates that the reason for program interruption is a


debugger break upon entering the function. This message will appear whenever you are stepping through using Step Into or Step Over, and the step is
entering an expression (as opposed to just leaving an expression, which is
indicated by the :AFTER-EXP keyword.)
:AFTER-EXP like :BEFORE-EXP indicates that your program is interrupted
in a debugging break mode, and that the Step Into or Step Over command
just stepped out of an expression.
:KBD-BREAK indicates that the PAUSE key was pressed, placing the program on hold.
:PROTECT-ASSIGN indicates that the break was caused by assigning a
value to a protected symbol. From the right-click context menu, you can
choose Show Message to view the variable name, the current value, and the
new value that was attempted to be assigned to the variable. You can also
choose the Inspect command to view the list containing the symbol, and the
new value indicated following :PROTECT-ASSIGN.

Special Function Call Frames


The special function call forms are as follows:

(FOREACH ...) Indicates a call to the foreach function.


(REPEAT ...) Indicates a call to the repeat function.
From the context menu, the Local variables command displays the special
name counter and the current value of the repeat internal counter. The
internal counter value is initially set to the integer value passed to repeat,
indicating the number of iterations desired. The counter decreases by one
at each loop iteration. It shows the number of iterations remaining, minus
one.
Note that each repeat expression possesses its own counter, but only one
such counter can be added to the Watch window.

AutoLISP functions such as if, cond, and, and setq do not appear on the
stack. They are not necessary because their call position may be viewed
within the source file in the text editor window.

Viewing an Error Trace Stack


If your program terminates due to an error, choose Error Trace from the View
menu to see the state of function invocations up to the time your program
crashed:

Visual LISP Data Inspection Tools

198

An error trace stack cannot display live data, since it is essentially a postmortem record of the events leading to your programs failure.

Trace Stack Toolbar


The toolbar on the Trace stack window contains two buttons:

Refresh
Refresh contents of Trace stack window.

Copy to Trace/Log Copy the window contents to the Trace window or open log
file.

The Symbol Service Dialog


The Symbol Service dialog is designed to simplify access to the different
debugger features provided for symbols. Most facilities available for symbols
are also available through this dialog.
To open the Symbol Service dialog box, first highlight any symbol (for example, a variable name in your programs source code, or in the Console window). Then choose View>Symbol Service from the Visual LISP menu, or press
the Symbol Service button on the Debug toolbar.

Chapter 6

199

Debugging Programs

The Symbol service dialog box contains the following components:

A toolbar
The Name field, where you can enter or change the symbol to work on
A Value field displaying the symbols value or its initial substring
Flags, a series of check boxes for symbol flags, which are described in the
Symbol Flags topic.

To update the value of the displayed symbol, enter an expression in the Value
field. When you press OK, Visual LISP evaluates the expression and assigns
its value to the symbol.
If the symbol is flagged Assign protected, this field will be read-only. To
remove the flag, check the Protect Assign check box below the value field.
Use the OK and Cancel buttons to close the dialog and to continue working
in Visual LISP.

Symbol Service Toolbar


The Symbol service toolbar contains the following buttons:

Watch
Adds the symbol to the Watch window.

Inspect
Opens the Inspector for the value of the symbol.

Show the function definition If the symbol names a user-defined function, this command
opens the text editor window containing the function definition, and highlights the function.

Visual LISP Data Inspection Tools

200

Help

Displays information from the Visual LISP Help file, if the


symbol refers to a built-in function.

Symbol Flags
The Symbol Service dialog provides direct access to symbol flags and properties of functional objects that may be associated with them. The following
symbol flag options are available:

Trace (Tr). The Trace flag activates the tracing of any user-defined function (shown as a symbol within the symbol service window). Tracing will
only occur when the symbol is a function, and the expression being evaluated uses the symbol name as a function (not as a local variable name,
for example.)

Protect Assign (Pa). This flag intercepts assignments to symbols. For


instance, the symbol pi is an Assign-protected symbol. All symbols that are
the names of built-in AutoLISP functions are Assign-protected by default.
Note that this protection works only for explicit setq, set, or defun invocations. Binding a protected symbol in an argument list of a user-defined
function is not intercepted.

Debug on Entry (De). If this flag is set, a breakpoint occurs at each function invocation, regardless of whether the function was loaded with
debugging information. The De flag is tested at each function invocation,
not during load or defun execution.
Note that Visual LISP ignores the Debug on Entry flag for all SUBR,
EXSUBR and EXRXSUBR symbols.

Export to ACAD (Ea). If the Ea flag is set, a function associated with the
symbol is defined in native AutoLISP as an external subroutine.

Inspector Windows
The Inspector is the component of Visual LISP that provides you with the
ability to browse, examine and modify AutoLISP and AutoCAD objects. It is
a powerful and easy to use tool. You can use the Inspector for the following
purposes:

Chapter 6

201

To view any objects accessible in AutoLISP (for example, lists, numbers,


strings, and variables)
To view AutoCAD drawing entities
To view AutoCAD selection sets

Debugging Programs

The Inspector also allows you to browse through complex data structures.
The Inspector creates a separate dialog window for each object you inspect.

Inspector Dialog Box


All Inspector dialog boxes have a similar appearance and contain a system
menu box, a caption, an object line (just under the caption), and an object
element list (possibly empty).

The Caption of an Inspector dialog box shows the type of the object
being inspected.
The Object Line shows a printed representation of the inspected object.
The Element List displays the components of the inspected object. The
list may vary in size and contents for different object types. Each element
list is shown as a pair: name and contents. The name is enclosed in brackets. Square brackets ([ ]) denote that this item can be modified with a
Modify command from the context menu associated with the item, and
curly brackets ({ }) designate an unmodifiable item.

Both the object line and the element List lines have their own associated context menus.

Object Element List Formats


The object element list formats for AutoLISP object types are:

INT (integer number) Inspector. The element list shows the various
representations of integers.
REAL (floating point number) Inspector. This element list is empty.
STRING Inspector. This element list contains the sequence of characters in the string, which and may in turn be inspected as integers.
SYMBOL Inspector. The symbol element list has 3 elements: value,
print name, and flags.
LIST Inspector for proper lists. This element list displays the items of
the inspected list.
LIST Inspector for improper lists. This list has 2 elements: the car
and cdr fields. It serves for all cases that are not proper LISP lists, that is,
the last cdr is not nil.
FILE Inspector. The File Inspector shows the name of the corresponding
file and the files opening attributes.
SUBR, EXSUBR, and USUBR Inspectors. These Inspectors contain
the name of the function (the name was specified in defun or at load
time).
ENAME (drawing entity) Inspector. The fields in this element list
correspond to the AutoCAD DXF object list, as returned by the AutoLISP
built-in function.

Visual LISP Data Inspection Tools

202

PICKSET (selection set) Inspector. This element list is simply the list
of selected AutoCAD objects.

Opening an Inspector Dialog


To inspect an object, highlight the object name in any context, then choose
View>Inspect from the Visual LISP menu, or press the Inspect button on the
Debug toolbar. The Inspect command is also available from a number of context menus, and from the windows displayed by tools such as Apropos and
Symbol Service.
For example, to inspect the definition of the yinyang function, select the
name in the text editor window containing the functions source code, then
press the Inspect button on the Debug toolbar:

A new Inspector dialog box appears showing the value of the expression you
selected. For example, if you want to inspect a symbol, you should see this
symbol in the form of my-variable.
If you invoke the Inspect command without selecting an object name, Visual
LISP prompts you to specify the object you want to inspect:

Enter the object or expression you want to inspect, then press OK to open the
Inspector window or press CANCEL to cancel the action.
Visual LISP saves the last 15 items you enter in the Inspector prompt box. You
can choose a previously-specified object for inspection by selecting it from
the drop-down list.

Handling Errors in the Inspect Command


In text editor windows it is not possible to inspect selected expressions longer
than 256 characters. If you select a string longer than 256 symbols, you will
be prompted to enter an object name.
If you specify an object or expression that Visual LISP cannot evaluate, it
issues a standard AutoLISP error message. Once the error message appears,

Chapter 6

203

Debugging Programs

you can correct the expression in the dialog box and try to evaluate it once
more.
Errors arising from evaluation of the object you entered cannot be investigated from a nested break loop, because all breaks are disabled during such
evaluation. If you wish to examine the error, choose View>Error Trace from
the Visual LISP menu, or copy the expression to the Console prompt and
press ENTER.

Closing all Inspector Dialogs


You can close all Inspector windows by choosing
Window>Close Windows>Inspectors from the Visual LISP menu.

Common Inspector Commands


The Inspector dialog boxes provide context menus with commands relevant
to the data being inspected.
Object Line Commands
The object line (or Item) context menu appears after pressing Alt+O or by
right-clicking the dialogs object line. The following commands may be
present in an object line menu:

Symbol Service invokes the Symbol Service dialog.


Print (ALT+P) prints the object to the Console.
Pretty Print formats and prints the object to the Console.
Copy copies the object to the *obj* variable.
Log copies the current contents of the Inspector dialog to the Trace Frame
window.
Update (ALT+U) updates the Inspector dialog to show the most recent status of inspected object.

When the object line has the focus, these commands are also available as keyboard combinations. The frame status bar should read Print (Alt+P) Update
(Alt+U).
Element Line Commands
The element line (or item) context menu appears after highlighting the element line and right-clicking.

Inspect (ALT+I) calls the Inspector and gives it the element (field) value
as an argument
Descend (ALT+D) calls the Inspector and gives it the element (field) value
as an argument and closes the current Inspector.
Copy copies the value of the inspected element (field) to the
*obj* variable.

Visual LISP Data Inspection Tools

204

View source activates a text editor window containing the selected text.
If it was loaded from the Console or from a list representation, this command activates a new text editor window.

The default command for the element line, invoked by pressing ENTER, is the
Inspect command. Other commands available as keyboard combinations can
be seen from the frame status bar prompt field, when the element line has
the focus. However, some lines in the Inspector do not correspond to any
sub-objects, and as a result these lines have no joined pop-up menus. Clicking on these lines has no effect.
Paging
When inspecting long sequences, the Inspector does not show the whole
sequence. Instead, it uses paging. For paging, the special paging element lines
appear in the Element List. If a sequence is too long the special ">>> [Next
page]" element line appears at the end of the Element list. To page the
sequence, follow the same procedure that initiates the element line pop-up
menu.

To page down, choose the ">>> [Next page]" element line and press Alt+E,
double-click, or right-click in that element line.
To page up, choose the "<<< [Previous page]" element line and repeat the
previously-mentioned process.
To return to the first page, choose "<<< [First page]" and repeat the previously-mentioned process.

Copying to the *obj* System Variable


Sometimes it is useful to access some part of an object from your program or
from the Visual LISP Console. You may also want to copy the value of one
objects item into another item and so on. To perform all these tasks the
Inspector manages a reserved system variable named *obj*. It can be used as
a temporary storage area while browsing through data structures. From
inside an Inspector dialog box, you can assign a value to this variable and
replace the value of the current item with the value of *obj*.
To assign the value of an inspected object to the *obj* variable, right-click
the item in the Inspector window and choose Copy.

Specific AutoLISP Datatype Inspectors


There are unique Inspectors for each Visual LISP data type.
INT Inspector
The INT (integer) Inspector shows the list of available representations of an
integer number:

Chapter 6

205

Debugging Programs

The number is represented as each of the following:

Binary
Octal
Decimal
Hexadecimal
Character

The last representation means that the ASCII character corresponds to the
number (for large numbers it takes the last byte).
The INT Inspector does not have an Element List.
REAL Inspector

The REAL Inspector does not have an Element List.


SYMBOL Inspector

The SYMBOL Inspector contains the following fields:

Name is the element line that shows the symbol print name (which is
always a string)
Value is the element line that contains the symbol value
Flags are element lines that reflect symbol attributes. These may be:
Pa Protect Assign
Tr Trace
De Debug on entry
Ea Export to ACAD

Visual LISP Data Inspection Tools

206

To change a symbols value or flag settings, use the object line menu command Symbol Service, which shows the Symbol Service window.
NOTE The information for the SYMBOL Inspector is available in a more convenient way through the Symbol Service dialog. So, the symbols Inspector is provided mainly to maintain uniform Inspector access for all of AutoLISPs data types.
LIST Inspector

FILE Inspector

File Inspector fields include the following:

Name This field shows the file name string that was used in the AutoLISP
open function.
Mode Can be one of three values: INPUT, OUTPUT, APPEND, or :CLOSED.
id Shows the internal file identifier.
Position Shows the current position in the file.
EOF indicates whether or not the end of the file has been reached. This
field does not appear if a file is open for output.

STRING Inspector

SUBR Inspector

Chapter 6

207

Debugging Programs

The SUBR Inspector contains the following field:

Name shows the symbol print name, which is always a string.

USUBR Inspector

The USUBR Inspector contains the following fields:

Name shows with the symbol print name, which is always a string
Parameters shows the list of user function parameters
Auxiliary displays a list of auxiliary variables listed after the / in the
DEFUN argument list

EXSUBR Inspector

The EXSUBR Inspector contains a Name field showing the symbol print
name.

Viewing AutoCAD Drawing Entities


In Visual LISP, AutoCAD drawing entities are represented by objects of ename
type. Visual LISP provides facilities to walk through the AutoCAD drawing
database and to inspect the raw entity data as reported by AutoCAD. You
access drawing entities through the Visual LISP Browse Database feature.
In view entity information, you can set a diagnostic option telling Visual
LISP how much information to supply in Inspector windows for entities.
Choose Tools>Environment Options>General Options and click the
Diagnostic tab in the General Options window. Select
Inspect drawing objects verbosely to view detailed entity information. Clear
the option check box to minimize the amount of information supplied by
the Inspector.

Viewing Entities in the Drawing Database


To Open an Inspector for the collection of entities in the current drawing
database, choose View>Browse Drawing Database>Browse All Entities from
the Visual LISP menu:

Visual LISP Data Inspection Tools

208

Note that VERTEX and ATTRIB entity types are not included in this list. You
access these entity types through their parent entities, which are available
with the POLYLINE and INSERT Inspectors.
The context menu commands available for the object line in the ACAD Entities Inspector window are Log and Update.
Select the entity you are interested in, then right-click and choose Inspect to
open an Inspector window for the entity:

The title bar of this window identifies the drawing entity type. The object
line of the window displays the entity name:
<Entity name: 27e0540>

The context menu for the object line contains the common Inspector commands Print, Copy, Log, and Update, plus some new items:

Chapter 6

209

Modify, if available, opens the standard AutoCAD DDMODIFY dialog for


the inspected entity.
Inspect raw data displays an Inspector window showing the list that
results from the entget AutoLISP function call for the entity.
Inspect next entity displays an Inspector window for the next entity in
the ACAD Entities list.
Inquire extended data displays a list of applications currently registered by regapp. If you select an item from the list, any extended data
related to the chosen application is included into the Inspector entget
list.

Debugging Programs

Viewing Tables in the Drawing Database


Choosing View>Browse Drawing Database>Browse Tables from the Visual
LISP menu opens an Inspector window for the collection of drawing tables:

You can inspect each table as a collection of named attributes. Select and
right-click on a table name, then choose Inspect:

To view a table entry for a selected attribute, right-click and choose Inspect
again:

Visual LISP Data Inspection Tools

210

Viewing Blocks in the Drawing Database


Choosing View>Browse Drawing Database>Browse Blocks from the Visual
LISP menu opens an Inspector window for the drawing blocks:

Select the block you are interested in, then right-click and choose Inspect to
open an Inspector window for the block.

Viewing Selected Objects in a Drawing


Choose View>Browse Drawing Database>Browse Selection from the Visual
LISP menu to select the drawing objects you want to view. Visual LISP
invokes the ssget function to prompt you to define a selection set in the
AutoCAD drawing window. When you complete the selection, Visual LISP
opens the Inspector for your selection:
.

Chapter 6

211

Debugging Programs

You can select an entity from the selection set and right-click to invoke the
Inspector for the entity.

Viewing Extended Data


Choose View>Browse Drawing Database>Inquire Extended Data from the
Visual LISP menu to see a list of the applications currently registered
(through regapp) as containing extended data. If you select an application
from this list, its extended data is included into the Inspector entget list.

Visual LISP Data Inspection Tools

212

Chapter 6

213

Debugging Programs

7
Building Applications

In this chapter
This chapter describes Visual LISPs AutoLISP File Compiler.

Compiling and Linking Programs

The first part of the chapter provides basic knowledge about

Building Stand-alone
Applications

Making Application
Modules

the compiler and may be sufficient for initial work with


Visual LISP. The rest of this chapter will be useful for
advanced users who want to get the best performance from
their compiled code.
Note that the functionality described in this chapter will be
supported in future releases of Visual LISP, however the terminology and access to this functionality will change.

214

Compiling and Linking Programs


Each time you run AutoLISP code from the Visual LISP Console, or load the
code from the Visual LISP text editor and run it, Visual LISP translates the
source code you entered into instructions your computer understands
(executable code). The Visual LISP feature that does this is the
immediate-execution compiler. The immediate-execution compiler plays the
same role as the AutoLISP interpreter did in AutoCAD. It is useful for quickly
testing new code, and for debugging that code.
Visual LISP has another compiler, the file compiler, which generates executable machine code from your source files. The compiled versions are saved in
files named with a .FAS extension. This executable code can be run from
within Visual LISP, and runs faster than code generated by the immediateexecution compiler. But more importantly, it allows you to create applications that others can use. These can be stand-alone applications, or applications accompanied by the Visual LISP Run-Time Support System (RTS). Compiled executable files contain only machine-readable code, so the source code
that you spent weeks or months developing remains hidden even if you distribute your application to thousands of users. Even strings and symbol
names are encrypted by the Visual LISP file compiler.
The remainder of this chapter describes how to use the Visual LISP file compiler to build stand-alone applications. In this chapter, the file compiler is
referred to as simply the compiler. Executable files produced by the compiler are referred to as either compiled programs, or as FAS files.

How to Use the Compiler


Visual LISP provides several ways to access and use the file compiler. To
compile a single LISP file you use the vlisp-compile function. The
vlisp-compile function is described in this chapter.
If your application consists of a set of AutoLISP files loaded in parallel, use
Visual LISPs integrated project management facilities to compile your files.
The project manager automatically recompiles files that have changed,
allows you to find code segments without knowing which files contain them,
and can optimize the use of function calls and local variables in the compiled
files. These features are explained in detail in Managing Multiple LISP Files
on page 245.
If you plan to ship your application to clients, you can package the executable files along with a small subset of Visual LISP into a stand-alone ARX
application.

Chapter 7

215

Building Applications

Compiling a Program from a File


To compile a single AutoLISP file, issue the vlisp-compile command at the
Visual LISP Console prompt:
(vlisp-compile mode filename [out-filename])

For this command:

mode is the compiler mode


filename is the source file name
out-filename is the name of the compiled output file

These parameters are described in more detail below.

Choosing a Compiler Mode


The mode parameter indicates the compilation mode, which can be one of
the following:
- standard build mode
- optimize, but do not link
lsa - optimize and link

st

lsm

The standard mode produces the smallest output file and is suitable for programs consisting of a single file.
The optimization options result in more efficient compiled files, which
becomes important as your programs grow in size and complexity. The basic
functions of optimization are to:

Link function calls to create direct references to the compiled function in


the compiled code, instead of to the function symbol. This feature
improves the performance of the compiled code and protects the code
against function redefinition at run-time.
Drop function names to make the compiled code more secure and to
decrease program size and load time.
Drop the names of all local variables and directly link their references.
This also makes the compiled code more secure and decreases program
size and load time.

Identifying the Input File


If your source file is in AutoCADs Support File Search Path, you do not
have to include the path name when specifying filename. The Support File
Search Path is set from the AutoCAD menu by choosing Tools>Preferences:

Compiling and Linking Programs

216

For example, if you are compiling the yinyang.lsp program file in the Visual
LISP Sample directory, and Support File Search Path is set as indicated in the
window shown above, you can issue this command:
(vlisp-compile st "yinyang.lsp")

If the Visual LISP Sample directory is not in the Support File Search Path, you
would need to include the entire path name when specifying the source file:
(vlisp-compile st "c:/program files/autocad R14/vlisp/sample/yinyang.lsp")

If you omit the file extension from a file name, Visual LISP assumes .lsp.
NOTE When specifying the file path name, replace the backslash symbol (\)
you normally use for file names with a forward slash or double backslash, following the usual AutoCAD convention.

Naming an Output File


The Visual LISP compiler produces code in the fast-load AutoLISP format
(FAS). By default, the output file containing this code has the same name as
the input file, but with an extension of .fas. You can override the default
name by specifying an output file name. For example:
(vlisp-compile st "yinyang.lsp" GoodKarma.fas)

NOTE If you do not specify a path name for either the input or the output file,
Visual LISP places the output file in the AutoCAD install directory! This is probably
not what you want.
In most instances, youll want to specify the full path name of the output file:
(vlisp-compile st yinyang.lsp "c:/program files/.../sample/GoodKarma")

Chapter 7

217

Building Applications

Walking Through a Compile Example


The following example uses the yinyang.lsp file in the Visual LISP Sample
directory.
1 At the Visual LISP Console prompt, enter the following:
(vlisp-compile st "c:/program files/autocad R14/vlisp/sample/yinyang.lsp")

This command requests a standard mode compile of the yinyang.lsp file. No


output file name is specified, so the compiled result will be saved in a file
named c:\program files\autocad R14\vlisp\sample\yinyang.lsp.
2 Look at the <Build Output> window displayed after the command executes.
If necessary, scroll up in the window to see all the compiler messages. If the
compile completed successfully, the window contains messages like the following:

During compilation, the compiler prints function names and various messages about each stage of compilation. The first stage is syntax and lexical
checking of the source code. If the compiler encounters errors, it issues messages and halts the compilation process. The compiler issues warnings if it
encounters expressions it considers dangerous, such as redefining existing
AutoLISP functions or assigning new values to protected symbols.
If compilation is successful, as in the example above, the <Build Output>
window displays the name of the compiled output file.
TIP Remember that, if warning or error messages are displayed, you can view
and edit the source code that caused these messages by double-clicking on the
message in the <Build Output> window.

Loading and Running a Compiled Program


To load and run a compiled program, do the following:
1 Load the program by entering the load command at the Visual LISP Console
prompt. For the compiled yinyang program created in Walking Through a
Compile Example on page 218, the command is:
(load c:/program files/autocad R14/vlisp/sample/yinyang.fas")

Compiling and Linking Programs

218

If you do not specify the file extension, Visual LISP assumes .fas. The file
extension FAS is reserved in Visual LISP; .FAS files are assumed to be compiled
AutoLISP files.
If you prefer less typing and more clicking, choose File>Load File from the
Visual LISP menu, and use the Load Lisp File dialog box to select yinyang.lsp.
Remember to use the Files of Type pull-down list in this dialog, and select
Compiled AutoLISP Files, otherwise Visual LISP only lists LSP files in the
dialog.
2 Run the program the same way you would a program loaded from the text
editor window. Issue the following at the Console prompt:
(yinyang)

Linking Function Calls


The process of linking function calls results in Visual LISP creating a loadable
module containing copies of AutoLISP built-in functions. This static linkage
of built-in functions increases the efficiency of the resulting code, but may
change the behavior of some tricky AutoLISP programs.
For example, if your program makes calls to a built-in function that is statically linked, and that function is subsequently redefined, your program does
not use the new function definition. A copy of the old definition is part of
the programs load module, and that version of the function is used. You
must re-link your program in order to pick up the new function definition.
Note also that if you include both linked and non-linked calls to this same
function, your program could end up using different versions for different
function calls. This is one reason why combining linked and non-linked calls
within a single file is not recommended.
When using multiple-file applications in conjunction with static linking, it
is highly recommended that you use Visual LISPs built-in project management system along with its functions to automatically optimize code. See
Managing Multiple LISP Files on page 245 for details.

Building Stand-alone Applications


Using Visual LISP, you can create commercial AutoLISP applications for distribution to customers. Compiling the programs in your application
improves their performance and hides their source code from your customers.
You can ship binary FAS files to customers, but in order to run these files, they
must have available the Visual LISP Run-Time System (RTS). The RTS contains

Chapter 7

219

Building Applications

a subset of the Visual LISP environment and can load and run FAS files in
AutoCAD. You can send customers individual FAS files, or create a single VLX
module (Visual LISP executable) that contains all your FAS and DCL files. In
both cases, though, you need to send the RTS executable along with your
files. The executable is provided in the form of an ObjectARX program. See
Using the Visual LISP Run-Time System on page 223 for more information
about using the RTS.
An alternative method of building applications is to package the RTS along
with your FAS and DCL files into a single ARX module. This results in a much
larger module then either FAS or VLX files, but it is self-contained and can be
loaded and run in AutoCAD like any other ARX application.
Whether you run your Visual LISP application from the Integrated Development Environment (IDE), or run the application from AutoCAD using the
RTS, you are running an application in a Visual LISP environment.

Making Functions Known to AutoCAD


To use functions created in Visual LISP in native AutoCAD, you must export
the function names to AutoCAD. This is true whether you are delivering your
application as FAS files or as a stand-alone ARX module. Only function
names that are called directly from AutoCAD (from the Command prompt
or a menu, for instance) need to be exported. For example, say your program
contains functions yinyang and set-time. The user will issue the yinyang command in AutoCAD to draw yinyang symbols, so the yinyang name must be
exported to AutoCAD. Internally, yinyang calls set-time to create a timestamp. AutoCAD does not need to know about set-time, because it is invoked
only from within yinyang.
Function names can be explicitly exported to AutoCAD, or implicitly exported.

Explicitly Exporting Function Names to AutoCAD


Function names can be explicitly exported by using the vl-acad-defun function:
(vl-acad-defun symbol)

The yinyang.lsp sample program uses this method to make itself known to
AutoCAD:
(vl-acad-defun yinyang)

In AutoCAD, the symbol yinyang will be defined as an external function and


you can invoke it the way you would any other function:
Command: (yinyang)

Building Stand-alone Applications

220

Implicitly Exporting Function Names to AutoCAD


By default, any Visual LISP functions whose name begins with c: are automatically exported to AutoCAD. For example, if you change the defun statement
in yinyang.lsp to:
(defun C:yinyang (/ origin radius ....)

the function name is automatically exported to AutoCAD when you load the
application in the AutoCAD environment. Remember that c: functions can
be issued as AutoCAD commands from the AutoCAD Command prompt.
Refer to C:XXX Functions on page 58 for more information on using c:
functions in Visual LISP and in AutoCAD, including some limitations
imposed on their use.
The automatic export of c: functions by Visual LISP occurs if the VLISP system variable *C-COLON-EXPORT* is set to T. By default, the feature is enabled.
You can disable the feature by setting *C-COLON-EXPORT* to NIL.
If all function names intended for use as AutoCAD commands begin with c:,
you can get by without explicitly exporting any functions.

Identifying Functions Defined in External Applications


Visual LISP programs can call external subroutines defined by other ADS and
ObjectARX applications. Visual LISP is aware of standard AutoLISP external
functions, but to recognize other functions as ADS subroutines (EXSUBR) or
ARX subroutines (EXRXSUBR), Visual LISP relies on information you supply
in an Externally Defined Function (XDF) file. You only need to define an XDF
file if you intend to call an ADS or ARX subroutine from code running within
a Visual LISP environment.
Visual LISP automatically retrieves information from an XDF file for ADS or
ARX applications loaded before the Visual LISP IDE or RTS, or when an
ARXLOAD or XLOAD function is called from a Visual LISP application. Visual
LISP searches for an XDF file in the following sequence:

In the applications directory under the same name as the application


(with an extension of .xdf)
n the directory containing the Visual LISP Run-Time System or Visual
LISP IDE under the name xload.xdf or arxload.xdf

NOTE You must describe every external function defined in an external ADS
or ARX module, if you call it from a Visual LISP environment (IDE or RTS). If a function description is missing, Visual LISP will be unable to call that function.
If an application is loaded from the AutoCAD Command prompt or from
another application after the Visual LISP IDE or RTS is loaded, Visual LISP will
not be able to correctly recognize the applications functions. If this happens,

Chapter 7

221

Building Applications

an explicit call to the Visual LISP vl-import-exsubrs function is necessary.


The call format is
(vl-import-exsubrs (app-name {entry-name}))

The function takes a list as an argument:


(vl-import-exsubrs("c:/Autocad R14/nirvana.arx" "C:ohm" "bliss"))

The first argument is the applications full name. The remaining arguments
are the application function names to be defined to Visual LISP.
Creating XDF Files
To assist you in the creation of an XDF file for a custom ADS or ARX application, Visual LISP provides the make-xdf utility function. This function
attempts to load your application, so if the application is already loaded in
AutoCAD, you need to unload it. The make-xdf function assumes that your
application defines its function entries after loading, and it retrieves all those
function symbols after the load.
To start make-xdf, first load the make-xdf.lsp file found in the Visual LISP
install directory. Use Tools>Load Application on the AutoCAD menu to load
the file. Then enter the following at the AutoCAD Command prompt:
Command: make-xdf

The command asks for the name of the external application to browse. Either
enter the path name for the application module, or press ENTER without
specifying a name and select the file from a dialog box. The make-xdf function loads your application, looks for new function symbols, and writes definitions for them in an XDF file it creates in your application directory. The
XDF file has the same name as your application module, with an extension
of .xdf.
If you do not want to use the make-xdf function to build your externally
defined functions file, you can use any text editor to create one from scratch.
XDF File Format
The XDF file is a plain ASCII file containing a LISP list for each AutoCAD version used. Blank lines and AutoLISP-style comments are allowed. Each entry
requires the following syntax:
(ACADver* ( application (symbol...) ) ...

The list contents are:

ACADver - the version of AutoCAD the external subroutine is being


defined for. The asterisk must follow the version name, for example:
14*

Building Stand-alone Applications

222

application - a string containing the applications file name, without the


directory path and file extension. For example:
zoomer

symbol - function symbol defined by this application

Here is a sample entry for an application named zoomer, which refers to 3


external subroutines:
("14*" ; ACAD version
("zoomer"
; module name
yinyang
; function
c:drawline
; function
shakaree
; function
)
)

Using the Visual LISP Run-Time System


Visual LISPs Run-Time System (RTS) is an ObjectARX program that loads and
executes compiled or uncompiled AutoLISP files. Two versions of the RTS are
provided with Visual LISP:

vlrts.arx
vlarts.arx

These files are in the Visual LISP install directory.


The difference between the two versions is that vlarts employs ActiveX
methodology, while vlrts does not. Which RTS you use depends on whether
or not your programs call ActiveX functions.
For a simple program like yinyang, which contains no external references or
ActiveX function calls, running a compiled FAS or VLX version in AutoCAD
can be accomplished with the following steps:
1 Load the vlrts.arx module (non-ARX version of the Visual LISP Run-Time System). Choose Tools>Load Application from the AutoCAD menu, or issue the
arxload function at the Command prompt to load vlrts.arx.
2 Initialize the RTS. You can use the vlrts-init function, supplied with Visual
LISP, to accomplish this. Invoke the vlrts-init function at the Command
prompt.
3 Issue the vl-load command. This command is defined by vlrts-init, and
loads compiled Visual LISP code into the RTS. When vl-load prompts for a
file name, specify the file containing the compiled yinyang code.
4 Run the program.

Chapter 7

223

Building Applications

These steps, along with requirements for more complex applications, are
explained in the following sections.

Shipping the RTS With Your Application


You can ship the Visual LISP RTS modules with your applications, if necessary. Remember that if you build an ARX application from your program, you
dont need to send a separate RTS with your program files. See Making
Application Modules on page 228 for more information on creating standalone ARX applications.

Loading the Visual LISP RTS


To load the Visual LISP Run-Time System from AutoCAD, choose
Tools>Load Application from the AutoCAD menu, or issue the arxload
function from the AutoCAD Command prompt. For example:
(arxload c:/program files/autocad r14/vlisp/vlrts.arx)

If the RTS file is in AutoCADs Support File Search Path, you can simply issue:
(arxload vlrts)

AutoCAD assumes that the file name ends with .arx.


NOTE Remember that there are two types of RTS modules, one for applications that reference ARX functions and one for applications that do not reference
ARX functions. Specify the RTS that your application requires.

Initializing the Run-time System


After the RTS is loaded, it needs to be initialized. Initialization may include
definition of functions, loading of compiled LISP files, and initialization of
global variables. You can accomplish this by running a Visual LISP supplied
initialization command from the AutoCAD Command prompt, or by using
instructions in an AutoLISP initialization file you create specifically for your
application.
Using the Visual LISP Supplied Initialization Command
Visual LISP comes with functions you can use to initialize the RTS for your
applications. The initialization routine for vlrts.arx is vlrts-init; for
vlarts.arx, it is vlarts-init. These functions check to see which external
applications are loaded into the current AutoCAD session, and define the
corresponding LISP functions in the Visual LISP run-time environment. If
your application calls functions defined by other applications, the RTS needs
a list defining which function belongs to which application. Provide this list
in a file of type XDF (Externally Defined Functions); see Identifying Functions Defined in External Applications on page 221 for details.

Building Stand-alone Applications

224

Using a Start-Up File


For ARX and VLX applications built using the Application Wizard, the RTS
looks for an application start-up file. Loading of the start-up file should initialize the application. The file may contain all your application code or just
short sequences of LOAD statements. For example, you might include a set of
initialization instructions in the same file that contains all your programs
function definitions, like the following:
(defun initfunc ( )
(setq *GLOBAL-WARMING* 4.0)
(strcat Hello
(getvar username)
)
)
(initfunc)

Or you might create a file to just load some applications and greet users:
(load karma.fas)
(arxload nirvana.arx)
(princ Hello Earthians)
(princ)
)

If you do not supply a start-up file name to Visual LISP, the RTS looks for a
FAS file named appname-init.fas, where appname is the name of your
applications executable file. If it finds a file with that name, the RTS executes
the instructions in the file. If the RTS does not find a file with that name, it
loads vlrts.fas (or vlarts.fas, if youve loaded the RTS for ActiveX applications).
If VLISP does not find a FAS file of that name, it uses the LSP version of the
file.
In looking for the start-up file, the RTS first searches the Visual LISP install
directory, then the AutoCAD Support File Search Path. If you renamed the
RTS executable, you must also rename the FAS or LSP file accordingly.
To avoid calling the vlrts-init function explicitly, you can provide any
number of end user functions available immediately after loading the application. These functions are called initialization functions. On the first call to
any of these functions, Visual LISP calls the vlrts-init function, which
loads the start-up file. Then the original function definition will be executed.
NOTE

The start-up file should export all initialization functions to AutoCAD.

Functions Defined by the Sample Start-Up File


Visual LISP comes with a sample start-up file, VLRTS.LSP. You can use this file
as-is, or modify it for your application. The supplied file defines four useful
external functions that interact with the RTS environment. After initialization the following functions will be defined in native AutoLISP:

Chapter 7

225

Building Applications

vl-eval-str
c:vl-eval
vl-load
c:vl-load

Using VL-LOAD to Load Files into the RTS


You can use the vl-load function or vl-load command to load AutoLISP
source files (LSP), compiled files (FAS), or Visual LISP application modules
(VLX) into the Visual LISP RTS. Any functions in those files that have been
explicitly or implicitly exported to AutoCAD will be available in native
AutoLISP, and can be invoked from AutoCAD.
Issue vl-load at the AutoCAD Command prompt; it responds with the following prompt:
VLISP/RTS load file:

If the file you want to load is in AutoCADs Support File Search Path, you can
enter the file name without specifying a path. If you do not include the file
extension, vl-load looks for files with either a .vlx, .fas, or .lsp extension, in
that order.
If you press ENTER without specifying a file name, vl-load opens a dialog
box for you to indicate the file you want to load.
If you issue vl-load for the yinyang.lsp file, which includes a vl-acad-defun
call to export the function name, you can verify that yinyang is known to
native AutoLISP. Use the AutoLISP type function to see how yinyang is
defined in AutoLISP:
Command: (type yinyang)
EXRXSUBR

Using VL-EVAL-STR to Access Functions Not Exported to AutoCAD


To access functions loaded but not exported to AutoCAD, use the
vl-eval-str function or the vl-eval command. For example:
Command: (vl-eval-str (drawline))
Enter the start point for the line:

The vl-eval-str function also gives you the ability to set variables in the
Visual LISP RTS environment. For example, if applications test a global variable, you can set the variable with vl-eval-str:
Command: (vl-eval-str "(setq *RUN-WILD* T)")
T

Building Stand-alone Applications

226

To invoke a function and pass it a string, use the backslash (/) escape code for
each quotation mark. For example to pass the following to vl-eval-str:
(setq str "These are \"\" double quotes")

Use the backslash escape code for quotes, and add double escape codes before
any escape codes in the string:
Command: (vl-eval-str "(setq str \"These are \\\"\\\" double
quotes\")")
"These are "" double quotes"

Note that internal functions may not be available if the optimizing compiler
dropped their names from the compiled files.

Using the RTS and Native AutoLISP Environments Concurrently


When using native AutoLISP and the Visual LISP RTS in parallel you have
access to two different LISP environments concurrently. You need to be aware
of the scope of functions and variables in the these environments:

A load in native AutoLISP loads the LISP file into the native AutoCAD
environment, while a vl-load integrates the files contents into the Visual
LISP RTS environment.
Functions known in the RTS environment are not visible in the native
AutoLISP environment if they were not explicitly exported. Functions
defined in native AutoLISP are not available in the RTS environment.
A setq in native AutoLISP sets a variable in native AutoLISP only. This
variable is unknown in the Visual LISP RTS environment (or worse: it may
have a different value in the Visual LISP RTS). Similarly, any setq in a file
loaded to the Visual LISP RTS or through vl-eval-str will set the variable
in the Visual LISP RTS environment, leaving the AutoLISP environment
unaffected.

Note that AutoCAD automatically loads acad.lsp, acadr*.lsp, and all files with
a *.mnl extension during initialization of the native AutoLISP environment.
Those files are not automatically loaded to the RTS environment during initialization. You can add the vl-init function call to your initialization file
to mimic the AutoCAD initialization procedure and load the aforementioned
LISP files.
The vl-eval and vl-load functions give you access to the internals of the
RTS environment. However supplying vl-eval or vl-load to users also provides a way for them to observe and change variables and symbols in the RTS
environment, which may affect your application. If you are concerned about
this, drop these functions before distributing your application to customers.

Chapter 7

227

Building Applications

Controlling the Verbosity of RTS Initialization


The built-in variables *LOAD-VERBOSE*, *VLISP-XDF-VERBOSE*, and
*LOAD-PRINT* control whether or not messages appear on the screen during
RTS initialization, and which messages appear. By default these variables are
NIL, which provides silent loading of the RTS. You can use the initialization
file to set any of these variables to T.

Partial Reinitialization at AutoCAD New/Open Commands


If your application loads many files during initialization, you can use the
*VL-NEW-FULL-INIT* variable to speed up the loading process when
AutoCAD opens a new drawing. If you set *VL-NEW-FULL-INIT* to NIL, Visual
LISP will only provide partial initialization when a new drawing is opened.
Partial initialization consists of:

Closing all dialogs


Disabling all objects of type ENTITY (ENAME), in Visual LISP
Re-exporting of all function names identified by vl-acad-defun

Partial initialization preserves Visual LISP function symbols and variable values, so your LISP application environment extends to the new drawing.
If *VL-NEW-FULL-INIT* is set to T, which is the default setting, Visual LISP reloads completely when a new drawing is opened.
NOTE When using partial initialization, your application is responsible for
resetting data handles of global variables related to the previous drawing. Such
handles may turn to hanging references for the new drawing, and using
them may lead to unpredictable results.

Making Application Modules


Visual LISP provides you with the ability to create a single, stand-alone, ARX
executable module for your application. This module incorporates the RTS
and all of your applications compiled files.
You also have the option of building a VLX file, which contains all your
application compiled files, but does not include the RTS. This greatly reduces
the size of the executable file, but you need to supply a copy of the RTS along
with the VLX file, unless your customers already have Visual LISP installed.
A Wizard guides you through the application building process in Visual
LISP. The result of this process is a Make file, which is often referred to by its
file extension, MKP. The Make file contains all the instructions Visual LISP
needs to build the application executable.

Making Application Modules

228

As an alternative to the Application Wizard, advanced users can choose to


use Visual LISP Application API functions, along with a custom MKP file, to
build an executable module.

Using the Application Wizard


The Application Wizard is a tool that guides you through the process of
building a stand-alone Visual LISP application. It takes you step by step
through the process, asking you questions at each step. At the completion of
the process, the wizard produces a Make file. The Make file is an AutoLISP
program containing the commands required to compile your applications
programs, export its functions to AutoCAD, and generate an initialization
file to be run in the AutoCAD environment. Visual LISP names Make files
with a .mkp extension.
NOTE It is recommended that you build your application only after you have
fully debugged it. Compiler errors during the Make process may prevent the
Application Wizard from completing successfully.
The examples that follow use some sample programs from the Visual LISP
tutorial. You can find these files in the Lesson5 folder of the VLISP Tutorial
directory. For AutoCAD Release 14, the default directory is:
c:\Program Files\AutoCAD R14\Vlisp\Tutorial\Lesson5

The tutorial files are:

Chapter 7

229

Gpmain.lsp
Gpdraw.lsp
Gp-io.lsp
Utils.lsp

Building Applications

Starting the Application Wizard


Choose File>Make Application>New Application Wizard from the Visual
LISP menu to start the Application Wizard.

Choose the path for the output Make file, and enter a name for the file. For
this example, give it the same name as the program, GardenPath. The Wizard
automatically adds a .mkp extension to the file name. Press ENTER or click
Save to proceed.

Wizard Step 1: Choosing an Application Type


In step 1, the Application Wizard asks you to specify the type of application
you want to create:

There are 3 choices available:

ARX Standard Application. Visual LISP produces a single ARX module


that can be loaded and run in AutoCAD. This module includes a copy of
the Visual LISP Run-time System (RTS), along with your program and any
DCL files.

Making Application Modules

230

ARX Application with ActiveX Automation. Visual LISP also produces a single ARX module, similar to the Standard option, except that it
employs ActiveX methodology in the module.
WARNING! If any programs in your application use ActiveX methodology,
you must choose this option in order to create an ARX application. If you choose
the ARX Standard option instead, the program will not run in AutoCAD.

VLX. A VLX module contains your application and all supporting files,
but it does not include the Visual LISP RTS. Because the RTS is not
included, the resulting module size is smaller than ARX modules, and you
can use a single RTS for all your VLX modules. However, you are responsible for setting up the run-time environment for VLX modules in
AutoCAD. See Using the Visual LISP Run-Time System on page 223 for
information on setting up the run-time environment for VLX modules.

The Executable prototype identified under the list of application types refers
to the ARX RTS module on which Visual LISP models your executable module.
The tutorial sample programs use ActiveX methodology, so you must choose
the ARX with ActiveX Automation option if you are building an application
from these programs.
Press the NEXT button to continue to step 2.

Wizard Step 2: Naming the Executable File


In step 2 you name the executable file the Wizard is helping you create:

You can type the full path name in the supplied field, or click the Browse button and use a standard Windows dialog to identify the output destination.
By default, the Wizard assumes that you want the executable file created in

Chapter 7

231

Building Applications

the same directory as the Make file, with the same file name as the Make file
and a file extension of .arx.
If you need to go back to a previous Application Wizard step and change
something, you can click the Previous button. Otherwise, click Next to continue.

Wizard Step 3: Identifying the Load Method


Step 3 of the Application Wizard asks you to identify how you want application code loaded into the AutoCAD environment:

If you select the default option, Load all files automatically, Visual LISP creates a start-up file named VLI$prefix.$$$, where prefix is the first 4 characters of the executable file you named in Step 2. The start-up file loads all your
application FAS files. Remember that you can include initialization functions
in your FAS files.
If you choose to supply an initialization file (such as VLARTS.LSP), clear the
Load all files automatically check box and click the Browse button to identify
the name of the initialization file you created. This file will be loaded at startup.
Click Next to continue.

Making Application Modules

232

Wizard Step 4: Identifying the Program Files


In step 4, you identify the program files in your application:

Pull-down list to
select type of
program file

You can specify AutoLISP source code files, compiled AutoLISP files, or a
Visual LISP project file. If you specify a project file, all of the projects FAS files
are included in the output module. See chapter 8, Managing Multiple LISP
Files, for information on creating and using project files.
If you specify AutoLISP source files, Visual LISP compiles those program files
when it builds the application.
Click the pull-down button to choose the type of file you want to include. If
you are building the tutorial application, there are no compiled program files
available (unless youve gone ahead and compiled the source files on your
own), so choose LISP Source Files. Then click Add:

You can only select one file at a time using this dialog box. After selecting a
file name, click Open to add it to the application.

Chapter 7

233

Building Applications

For the tutorial application, you need to specify the Lesson5 folder of the
VLISP Tutorial directory. Then add each of the following files from that
folder:

Gpmain.lsp
Gpdraw.lsp
Gp-io.lsp
Utils.lsp

If you need to remove or replace files in the future, select the files you no
longer want and click Remove. You can also select one or more files, rightclick, and choose Remove from the context menu.
If you want to replace all the LSP files with FAS files, click [Un]Select All to
select all the files in your application, then click Remove. Use the Add button
to specify the new files.
Using the Up and Down Buttons to Change Load Order
Visual LISP loads the applications files in the order they are listed. You may
need to reorder the file list in this step of the Application Wizard. For example, if you call a function at load time, the function must be defined before
it is used. In this case, you want to place the file defining that function first.
The Wizard dialog box contains buttons you can use to move files around in
the list. Select a file name, then click either:

Top. Move to the top of the list


Up. Move ahead of the file just above in the list
Dn. Move behind the file just below in the list
Btm. Move to the bottom of the list

You can also right-click and choose these actions from a context menu.
Note that the load order of project files is specified when you define the
project; see Changing the Order in Which Visual LISP Loads Files on
page 251 of the Maintaining Visual LISP Applications chapter.

Wizard Step 5: Identifying Dialog Control (DCL) Files


If your application includes Dialog Control Language (DCL) files, you can
have Visual LISP compile them and include them in the output module:

Making Application Modules

234

DCL is a tag language that can be used to create custom windows for an application. The Visual LISP tutorial demonstrates how to use DCL in an application. Click the Add button to select the DCL file from the Lesson5 directory;
the file name is Gpdialog.dcl.
After selecting the DCL file and adding it to the application, click Next to
continue.

Wizard Step 6: Defining External Functions


If your application calls functions defined in other ARX or ADS applications,
you need to create an External Definitions File (XDF) and specify it in this
step:

If your application does not use any XDF files, click Next to continue. Otherwise, use the Add button to specify the XDF file you defined. Refer to Identifying Functions Defined in External Applications on page 221 for information on defining XDF files and calling other ARX or ADS applications.

Chapter 7

235

Building Applications

Wizard Step 7: Setting Initialization Options


Your application can be initialized automatically at load time, or by calling
an initialization function:

Initializing at Load Time


If you select Initialize in load time, Visual LISP will automatically initialize
the LISP environment when any of your applications functions are invoked.
Creating an Initialization List Automatically
Visual LISP creates a function list for you if you select the
Form the list automatically option. To choose this option, you must first
clear the Initialize in load time option, if it is currently selected.
NOTE You cannot choose this option if you specified compiled (FAS) files in
step 4. Visual LISP cannot gather the information it needs to build a function list
from FAS files.
If you choose this option, Visual LISP scans your application files for all functions exported to AutoCAD either implicitly (C: functions) or explicitly (for
example, by vl-export-to-acad function calls). It builds a list of these functions and defines them as initialization functions.
If you choose Form the list automatically, you can click the Preview button
to see the list that Visual LISP creates:

Making Application Modules

236

For the tutorial application, a single function is implicitly defined. This is the
function you call to start the application.
Defining Your Own List of Initialization Functions
If you choose neither the Initialize in load time or Form the list automatically
options, you can selectively choose the functions you want to define as initialization functions. An Add button appears where the Preview button previously appeared.
1 Click the Add button to begin the process of specifying initialization functions.

2 Click the Browse button to get a list of exported function names. You may
receive the following message:

Chapter 7

237

Building Applications

This indicates that one or more of the source files in the application have
been modified since their last compile. Click OK to allow Visual LISP to
recompile the changed files.

3 In the tutorial application, there is only one exported function name. Select
the name and click Add.
4 Click the Close button to return to the step 7 window.
Click Next to continue to the final step.

Wizard Step 8: Making the Application


In this final step, the Application Wizard summarizes the options youve
chosen and allows you to build the application now:

If you do not elect to build the application now, Visual LISP saves the information in a Make (.mkp) file that you can use to build the application later.
To run that Make file, choose File>Load File from the Visual LISP menu, and
specify the Make file name (for this example, GardenPath.mkp).

Making Application Modules

238

If you are following along using the sample tutorial application, select Make
the application now, then click Finish. Visual LISP builds a Make file and executes the instructions in that file. Output messages from this process appear
in two VLISP windows. These messages are explained in the following section.

Understanding the Output from the Make Application


When you run the Make file, Visual LISP automatically compiles any application source files for which either of the following are true:

There is no compiled (FAS) version of the file


There is a compiled version, but the source file has been modified since
that compile

Visual LISP displays messages from the Make process in both the Console
window and the <Build Output> window. Here are the Console messages
from the tutorial:

The path and file names of all input and output files are identified in the
Console messages.
If Visual LISP compiles or recompiles any of the source files in the application, compiler messages appear in the <Build Output> window for the Make:

Chapter 7

239

Building Applications

Youll see some compiler warning messages if you compile the tutorial code.
You can safely ignore these message.
The last group of messages in the <Build Output> window show compile
messages for the automatically-generated initialization file Visual LISP builds
for the application:

Note that Visual LISP generates the file name by appending the first 4 characters of the output file name (GardenPath.arx) to the prefix VLI$. The extension for the initialization source file is always $$$.

Loading and Running Applications


The method you use to run a stand-alone Visual LISP application in
AutoCAD depends on whether you created an ARX module or a VLX module.
An ARX module just needs to be loaded before you can run it. A VLX module
requires that the Visual LISP Run-time system (RTS) be loaded and initialized
first.

Loading and Running an ARX Application


To run an ARX application in AutoCAD, load the ARX file and invoke it from
the Command prompt. You can load the file using the ARXLOAD function, or
by choosing Tools>Load Application dialog from the AutoCAD menu.
Using the ARXLOAD Function to Load the Application
You can invoke the arxload function from either the AutoCAD Command
prompt or the Visual LISP Console prompt. The function has the following
syntax:
(arxload filename)

For filename, specify the full path name of the ARX file, in quotes. For example:
(arxload c:/Program Files/AutoCAD R14/VLISP/Sample/Gardenpath.arx)

If the load fails with no indication why, it is possible that the application is
already loaded. You can issue the arx command at the AutoCAD Command
to view a list of loaded ARX applications:

Making Application Modules

240

Use the arxunload function to unload the application, if it is currently


loaded. The syntax is the same as for arxload; just substitute arxunload in
the function name.
The arxload function can accept an optional onfailure argument; see the
AutoLISP Function Reference for further information.
Using the Tools Menu to Load the Application
To load the application from the Tools menu:
1 Choose Tools>Load Application from the AutoCAD menu.

2 If the file name is not listed, click the File button to open a dialog and select
your ARX file. If you select the Save List option, AutoCAD saves the file name
and includes it in this list for future references.
3 Click Load to load the ARX file.
Running the Application
Once the application is loaded, run it from the AutoCAD Command prompt
as you would any AutoLISP function. For example:
Command: (gpath)

Remember that if the function name begins with c:, you can issue it as an
AutoCAD command; that is, without enclosing the name in parentheses. The
gpath function that starts the GardenPath application does not begin with a
c:, so you must include the parentheses. Review C:XXX Functions on
page 58 for more information on this topic.

Chapter 7

241

Building Applications

Loading and Running a VLX Application


To run a VLX application, you must first load the Visual LISP Run-time System (RTS). Using the Visual LISP Run-Time System on page 223 describes
how to set up the run-time environment for the RTS. Once the RTS is initialized, use the vl-load function to load VLX modules. For example:
(vl-load c:/Program Files/AutoCAD R14/VLISP/Sample/Gpathvlx.vlx)

Once the application is loaded, run it from the AutoCAD Command prompt
as you would any AutoLISP function. Remember that if the name of the function you invoke to start the application begins with c:, you can issue it as an
AutoCAD command; that is, without enclosing the name in parentheses.

Rebuilding an Application
To rebuild your application after you have made changes to the code, either
use the Application Wizard or load the applications MKP file.
NOTE Before you rebuild your application, make sure it is not currently
loaded in AutoCAD. If it is loaded, unload it. For example, if your application is
an ARX module, use ARXUNLOAD to unload it. The application building process
will fail if the target application file is currently loaded, as Visual LISP will not overwrite the existing module.

Using the Application Wizard to Rebuild an Application


To use the Wizard to rebuild an application, choose File>Make Application>Existing Application Wizard from the Visual LISP menu. Select the
Make file for your application, and proceed with the Wizard as described in
this chapter. You can make changes at any step of the process.

Rebuilding an Application from Its Make File


If you do not need to change the way your application is defined, you can
quickly rebuild the application by simply loading and running its Make file.
If the applications MKP file is loaded in a Visual LISP editor window, you can
activate that window and click the Load active edit window button on the
Run toolbar.
Note that, when you load a Make file, Visual LISP automatically executes the
instructions in the file.

Making Application Modules

242

Chapter 7

243

Building Applications

8
Maintaining Visual LISP
Applications

In this chapter

This chapter describes how you can maintain large applica-

Managing Multiple
LISP Files

Optimizing Application Code

tions containing multiple files by defining the application


as a Visual LISP project. Besides defining the components in
your application, you can use projects to define compiler
options for the application. This chapter describes the various compiler options and the consequences of each, and
tells you how to override these options for individual files
in a project.
Note that the functionality described in this chapter will be
supported in future releases of Visual LISP, however the terminology and access to this functionality will change.

244

Managing Multiple LISP Files


Many of the program examples you have seen so far in this document have
been small, stand-alone AutoLISP files. Typically, however, AutoLISP applications consist of larger files with many lines of code, and functions in each file
calling functions in the other files.
The Garden Path tutorial application used to demonstrate the Application
Wizard in the Building Applications chapter is a more typical AutoLISP
application. It includes several source code files and a Dialog Control Language (DCL) file. After compiling the programs in this application, you also
have a number of FAS files to keep track of. As the number of LISP and FAS
files grows, it can become difficult to maintain an application. Simply determining when you need to re-compile files due to source code changes can be
a challenge. Visual LISP provides functions that greatly simplify the process
of management of multiple-file applications.

Introducing Visual LISP Projects


To aid you in the process of maintaining multiple-file applications, Visual
LISP recognizes constructs called projects. A project is basically a list of source
files, and a set of rules on how to compile these files. Using the project definition, Visual LISP can do the following:

Check which LSP files have changed and automatically re-compile only
the modified files in your application. This procedure is known as Make.
Simplify access to source files by listing all source files associated with a
project, making them accessible with a single mouse click.
Help you find code fragments by searching for strings when you do not
know which source files contain the text youre looking for.
Optimize compiled code by directly linking the corresponding parts of
multiple source files.

Before discussing how to define and use Visual LISP projects, it may help to
introduce file types used in Visual LISP.

LSP, FAS and other File Types


The basic file type in Visual LISP, as in native AutoLISP, is the LISP source file.
Typically, LISP source files are named with a .lsp file extension. Youve seen
LSP files used frequently in previous chapters.
The .fas file type was introduced in the previous chapter, Building Applications. FAS files are compiled LISP files. These files load faster and are more
secure than LSP files, because the source code is not intelligible to users.

Chapter 8

245

Maintaining Applications

Here is a brief summary of the types of files recognized by Visual LISP project
management functions:

File Ext.

Type of File

Function

dsk

Desktop Save

Contains Visual LISP environment and window settings. (Note: do not edit this file
unless you are certain you know what you are
doing.)

fas

Compiled AutoLISP Code

Compiled AutoLISP programs. May be


loaded and run from Visual LISP RTS or IDE,
or compiled into VLX or ARX modules.

lsp

AutoLISP Source Code

Program source files.

ob

Object Code

Used internally by Visual LISP, these files contain compiled LISP code used in building FAS
files.

pdb

Project Database

Used internally by Visual LISP, these files contain symbol information used by the compiler.

prj

Project Definition

Contains the location and names of all source


files that build the project as well as certain
parameters and rules on how to create the
final FAS files.

In addition to the files recognized by the project manager, Visual LISP either
creates or can process a number of additional types of files, summarized
below:

File Ext.

Type of File

Function

_xx

Backup files

Backup copies of edited files, maintained by


the Visual LISP editor. Backup files contain the
same name as the original, except that the
file extension begins with the underline character (_) and is followed by the first two characters of the original files extension. For
example, the backup file of a LISP source file
is named *._LS; the backup of a DCL file has a
*._DC extension.

arx,
vlx

Stand-alone Applications

Stand-alone AutoCAD applications, which


can be created using Visual LISP.

Managing Multiple LISP Files

246

File Ext.

Type of File

Function

c, cpp,
Language Source Files
cch, hpp, hh

Contain program source code. The Visual


LISP editor recognizes the syntax of these
files and color-codes reserved words, strings
and numbers.

dcl

Dialog Control Language

Contain definitions of AutoCAD dialog


boxes.

mkp

Make Application

Used by Visual LISP to create stand-alone


application files (files you can run in native
AutoCAD without Visual LISP). Describes contents of the application.

sql

Structured Query Language Contains SQL statements. The Visual LISP


text editor recognizes this file type and colorcodes the text according to SQL syntax rules.

xdf

Externally Defined Functions Defines ADS and ARX functions to Visual LISP.
XDF files provide information that allows
Visual LISP applications to call ADS and ARX
programs.

xdv

Exported LISP Functions

Used by the Visual LISP application builder


and the Visual LISP run-time system to generate automatic init-functions lists. Generated
by the compiler for each FAS file.

Defining a Project
To demonstrate the use of projects in Visual LISP, you can use the sample programs that come with the Visual LISP tutorial. The files are in the \Lesson5
folder of the VLISP Tutorial directory:

Gpmain.lsp
Gpdraw.lsp
Gp-io.lsp
Utils.lsp

To create a Visual LISP project, choose Project>New Project from the Visual
LISP menu:

Chapter 8

247

Maintaining Applications

Visual LISP displays a standard Windows dialog box for you to specify a file
path and name. For this example, use the name Tutorial. Visual LISP assigns
a .prj extension to the project file name.

Assigning Project Properties


The Project Properties dialog box displays after you specify a project file
name:

Project Home
Directory
List of Selected
Files Displays
in this Window
Click to
Change Source
Directory

List of LSP Files


in the Source
Directory

Selecting the Files to Include in a Project


There are two tabs in the Project Properties dialog box. Clicking on the
Project Files tab displays the window shown above. In this window, you specify the source files for the project.

Managing Multiple LISP Files

248

The projects home directory is identified just below the tabs. This is where
the project file (tutorial.prj) resides. In this example, the home directory is
c:\Program Files\AutoCAD R14\VLISP\Sample. Thats not the directory that
contains the tutorial sample files, though. To identify the source directory,
click the
button:

Use the Browse for Folder window to identify the location of the project
source files. If you select the Lesson5 directory, the Project Properties window
should look like the following:

Visual LISP lists only files that have a .lsp extension to their name, but it does
not display the extension in the list. To include all the source files in your

Chapter 8

249

Maintaining Applications

project, click the button labeled (Un)Select all, then click the right arrow
button ( ); Visual LISP moves the file names to the window on the right:

This window is designed so that, by default, you can select multiple file
names by just clicking each name; you do not have to press and hold CTRL
to select more than one file. To clear a selected name, just click it again.
To remove a file from the project, select it in the right window and click the
left-arrow button( ).
Identifying the Path Name of Project Files
The list of included files does not identify the path name of each file (nor
does the Look In field; this just identifies the path of the files listed in the
left window). Since you can include files from multiple directories in your
project, you need to be able to identify the path name of each file. You can
do this by highlighting one or more file names and right-clicking to display
a context menu:

To display the full path name and the size (in bytes) of source files in the
project, choose Log Filename and Size from the context menu. The informa-

Managing Multiple LISP Files

250

tion appears in a small, scrollable window near the bottom of the Project
Properties dialog box:

If a file is in the Home directory shown in the Project Properties dialog box,
Visual LISP does not spell out its path name. Use the scroll bar to see information about all the files in the project.
Note that you cannot include two files of the same name in a project, even
though they are in different directory paths.

Changing the Order in Which Visual LISP Loads Files


The context menu also provides commands to move files up and down in the
list of included files, and to sort the list by file name or by full path name.
Visual LISP loads the projects files in the order in which they are listed.
Sometimes the load order is important. For example, you might have an initialization file that defines global variables needed by all the other program
files, and thus must be loaded first. You could select that file name and
choose Move to Top to place it first in the projects file list.
You can also use buttons in the Project Properties dialog box to move files
around in the list: Top (Move to Top), Up (Move Up), Dn (Move
Down), and Btm (Move to Bottom).
For the tutorial project, the gpmain.lsp file should be loaded last. It contains
the following instructions at the end of the file:
(princ "\nType GPATH to draw a garden path.")
(princ)

This results in a prompt telling users how to invoke the application. If Visual
LISP loads gpmain.lsp last, these instructions will display at the AutoCAD
Command prompt.
After youve moved any files you need to, click Apply.

Choosing Compiler Build Options


The Build Options tab displays a dialog box in which you can specify compiler options to Visual LISP. This topic is covered in the Choosing a Compilation Mode section later in this chapter. For now, click OK to close the
Project Properties dialog.

Chapter 8

251

Maintaining Applications

Using the Project Window to Work with Project Files


Visual LISP displays a window containing a list of the projects members:

By default, VLISP lists the project members in the order in which they will be
loaded (as defined in the Project Properties window). You can change this
order by choosing Arrange Files from the context menu for this window (see
below).
The project name appears in the window title bar. Below the title bar are 5
icons. Each icon is a button that performs a function. The button and their
functions are:

Project Properties

Displays the Project Properties window for the project. This allows
you to view the full path name of the files in the project, add,
remove, and reorder project files, and view and change project
compiler options.

Load Project FAS

Loads all compiled (FAS) files for the project.

Load Source Files

Loads all the projects source files, making them available to be run.

Build Project FAS

Compiles all project source files that have been modified since their
last compile.

Rebuild Project FAS Recompiles all project source files, whether or not they have
changed since their last compile.

Managing Multiple LISP Files

252

If you right-click within the file list of the Project window, Visual LISP displays the following context menu:

Many of the functions available from the project context menu can also be
accomplished in other ways. For example, youve already seen how to add
files to projects and remove files from projects. Choosing Remove File from
the context menu is a quick way of removing a file from a project, while
choosing Add File merely brings you to the Project Properties window.
The following summarizes the commands on the context menu:

Chapter 8

253

Edit

Edit the source code of the selected project members.

Add File

Open the Project Properties dialog, in order to add files to the project.

Remove file

Remove the selected members from the project.

Load

Load the FAS file for the selected project members. If no FAS file exists
for a member, load the LSP file.

Load source

Load the source LSP file for the selected project members.

Check syntax

Check AutoLISP syntax of the source code for the selected members.

Touch

Indicate that the selected source files have been updated, but make no
change to the files. This causes Visual LISP to recompile these programs
the next time you ask to compile all changed project files.

Arrange files

Sort the project member list, according to one of the available suboptions (load order, name, type, or date).

Multiple
Selection

Tells Visual LISP whether or not to allow selection of multiple members


from the list in the Project window. If this option is checked off, multiple selection is allowed.

Maintaining Applications

[Un]Select all

Selects all members of the project list, if none are currently selected. If
any members are currently selected, this command un-selects them.

Close project

Close the project.

Save project as Save the project.

Selecting Multiple Project Members


The Multiple Selector menu item is available only from the Project windowss
context menu. Choosing this option allows you to select multiple members
from the list in the Project window. If the option is selected, a check mark
appears next to the Multiple Selector item on the menu. Click on the menu
item to toggle it on and off.
If Multiple Selector is in effect, clicking a member name in the Project window acts as a toggle to select or deselect the member. For example, none of
the members listed in the following window are selected:

If you click on the name GPIO, then click on the name GPDRAW, both are
selected.

This is unlike the usual Windows behavior, where selecting the second list
item cancels the first items selection, unless you press CTRL while selecting
it.
You can also use the Project windows context menu to select all members of
the project or cancel selection of all members. If no members are currently
selected, right-click and choose [Un]Select all to select all the members. If any
or all members are already selected, [Un]Select all cancels all selections.

Loading Project Files


To load the projects compiled program files, click the Load Project FAS button. This allows you to run the application in Visual LISP. If Visual LISP

Managing Multiple LISP Files

254

detects that some of the source files do not exist in compiled format, it displays a message and asks you if you want to compile those files:

If you click Yes, Visual LISP attempts to compile all LSP files that do not have
a corresponding FAS file. If you click No, VLISP loads all FAS files it finds for
the project, and loads the LSP file for the remaining project. Press Cancel to
abort the load operation.
To load all project source files, instead of their compiled versions, click the
Load Source Files button. Remember that debugging breakpoints may be
saved within source code files, but are removed from the compiled version of
the code. You might want to the load source files in order to debug changes
youve made to your programs.
Using the Project window context menu, you can choose to load just selected
files. Select the files you want to load, then right-click and choose Load to
load FAS files, or Load Source to load the source code. Note that if you choose
Load and a FAS file does not exist for a selected file, Visual LISP loads the
source LSP for that file.

Compiling and Recompiling Project Files


One of the key advantages in defining Visual LISP projects for your applications is that it provides an efficient method of updating compiled code. You
can elect to have Visual LISP recompile all source files that have changed
since the last time they were compiled. By choosing this option, you insure
that all FAS files in your application correspond to the latest versions of the
program source code. At the same time, you save time by avoiding unnecessary compiles. To invoke this feature, click the Build Project FAS button in
the Project window.
You can also choose to recompile all the programs in your project, whether
or not they have changed; click the Rebuild Project FAS button to enable this
feature.

Editing Project Files


To edit the source file of a project member, select the member from the list
in the Project window, then right-click and choose Edit. If the Multiple Selector option is on, you can select multiple members and Visual LISP will open
a text editor window for each.

Chapter 8

255

Maintaining Applications

NOTE If the Multiple Selector option is not turned on, you can simply doubleclick a member name to edit it.

Saving and Closing the Project


To save the project properties you defined or modified, right-click in the
Project window and choose Save Project As from the context menu. Visual
LISP displays a list of project files. You can either select the name of the current project file, to update its contents, or enter a new file name to save the
changes as a new project.
When you are finished working with a project, right-click in the Project window and choose Close Project. Note that this only closes the PRJ file; any
project files that are open in Visual LISP editor windows remain open.
NOTE If you close the Project window by clicking the windows Close button,
this does not close the project itself. The Project is still open, and you can reopen
a Project window for it by choosing it from the Project menu, as described below
in Opening a Project.

Working With Existing Projects


Some of the Visual LISP features described in previous chapters have special
application with Visual LISP projects. The features described in this section
are the text editor search functions and the Make Application Wizard.

Opening a Project
To open an existing project, choose Project>Open Project from the Visual
LISP menu:

If the project file you want to open is in the current directory, you can simply
enter the project name here. If it is not, or if you dont know what the current
directory is, click the Browse button to get a standard Open dialog box.
Note that you can have more than one project open at a time. You can view
a list of all open projects by choosing the Project menu and looking at the
bottom of the menu displayed:

Managing Multiple LISP Files

256

At any time, one of the projects is the active one. You can determine which
project is active by the check mark in front of the project name. The commands in the Project menu, such as Load and Build, apply to the active
project. These commands work the same as they do when selected from a
Project window, as described earlier in this chapter.

Finding a String in Project Source Files


The Visual LISP text search function, described in Searching for Text on
page 158, provides you with the ability to search all of a projects source files
for a string of text.
For example, suppose that in reviewing gpmain.lsp you see calls to a function
called gp:getPointInput, and you cannot remember which source file this
function is defined in. To search for it, choose Search>Find from the Visual
LISP menu. In the Find dialog box, select Find in project under the list of
Search options:

A Project selection field now appears at the bottom of the Find dialog box. If
the name of the project you want to search is not already displayed in this
field, choose it from the pull-down list. Click the Find button to perform the
search. Visual LISP displays the results in the <Find Output> window:

Chapter 8

257

Maintaining Applications

The output shows that 4 files were searched (there are 4 source files in the
project), and that 4 occurrences of gp:getPointInput were found. The
occurences were found in 2 files; the (defun) for the function is in gp-io.lsp.
You can open an editor window for the file by double-clicking anywhere
within the highlighted text in the <Find Output> window. You can also press
SHIFT+F11 to display the first source location at which the text string was
found, and then repeatedly press F11 to view subsequent occurrences in the
source files.

Making an Application from a Project


After youve made changes to an applications source files, youll need to
incorporate those changes to the applications binary files. The topic Using
the Application Wizard, in chapter 7, showed you how to keep individual
application files in synch. Defining those files as members of a single project
simplifies this process even further.
For example, Using the Application Wizard created a Make file named
GardenPath.mkp. The application was defined as 4 source files and a DCL file.
You can instead define the application as 1 project file and a DCL file. If you
add files to the project, you do not have to change the Make file to account
for this.
If you have already defined an application composed of source or FAS files,
and want to change it to refer to a project instead, you can choose
File>Make Application>Existing Application Wizard in order to modify it.
For the tutorial application, you would use the existing Application Wizard
options until you reached step 4, which lists the applications source files:

Managing Multiple LISP Files

258

To remove the existing LISP source files from the application definition and
replace them with the tutorial project file:
1 Click the [Un]Select All button.
2 Click Remove.
3 Click in the pull-down list that currently contains LISP Source Files, and
choose Visual LISP Projects.
4 Click Add...
5 Select Tutorial.prj from the Open project dialog box.
From this point forward, you can keep the existing application options. Refer
to Using the Application Wizard in chapter 7 to review all the steps
involved in making an application.

Chapter 8

259

Maintaining Applications

Optimizing Application Code


Visual LISP provides a number of options for compiling and linking a
projects source code.

Defining Build Options


To specify the build options for a project, open the project, then click the
Project Properties button in the Project window. In the Project properties
window, click the Build Options tab:

The Build Options dialog box contains a number of options. Some of these
options require extensive background information, which is provided in the
following sections:

Compilation mode. Choose between standard and optimized compilation. Optimized compilation creates smaller and faster programs, but not
every project is suited for optimized compilation.
Merge files mode. Tell the compiler whether to create a separate FAS file
for each source file, or to merge all compiled files into a single FAS file.
Edit Global Declarations. Create or edit a global declarations file for
the project.
Note that this feature is provided for compatability with the Preview version of Visual LISP. The functionality provided by the Global Declarations
file will be provided by other features in futures releases of Visual LISP.

Optimizing Application Code

260

FAS directory. Specify the directory for compiled files. If you indicate a
relative path, Visual LISP applies it relative to the projects home directory.
If you leave the field blank, VLISP places compiled files in the same directory as the project definition file.
Tmp directory. Specify the directory for project-related temporary files.
A relative path is applied relative to the projects home directory.
Link mode. Specify how function calls are to be optimized.
Localize variables. Choose whether or not to have the compiler remove
the names of all local symbols from compiled files, where possible.
Safe optimize. Directs the compiler to refuse some types of optimization
if there is a chance it will result in incorrect code.
Message Mode. Select the level of detail you want Visual LISP to produce
in its compilation reports. You can choose to receive a report showing
only fatal errors (those causing compilation failure), a report showing
errors and warning messages, or a full report showing errors, warnings,
and compiler statistics.

Merge files mode specifies whether the compiler will create a separate FAS file
for each source file or whether all compiled files will be merged to create a
single FAS-file. A single FAS file is faster to load and is required for certain
types of optimization. Sometimes, however, you will prefer to load your code
one file at a time. This is important if you have not completed the debugging
or modification of the applications code. FAS files do not allow source code
debugging, so we recommend that you compile your code only after the initial debugging is done.
The Link mode area determines how function calls will be optimized. It is
only available if optimized compilation is on. Linking functions means that
the compiler directly addresses the function definition and all calls where the
function is referenced. The Internal mode additionally removes the function
name from the resulting FAS file(s).
If Localize variables is set, the compiler removes the names of all local symbols from the resulting file(s), if possible.
Safe optimize lets the compiler refuse some types of optimization if there is
a chance to create incorrect code. For more information on optimization see
the corresponding section below.
After closing the dialog the Project Desktop window automatically appears.

Choosing a Compilation Mode


Combining compiled code from multiple files to a single binary file allows
the compiler to add a high level of optimization. It also means you have
more choices to make.

Chapter 8

261

Maintaining Applications

When producing standard, non-optimized binary code, the Visual LISP compiler preserves the symbol names associated with functions and global variables, since these symbols may be referenced from other files. When the symbol is referenced, Visual LISP looks in a table to determine what area in memory is assigned to the symbol.
When optimizing code, the Visual LISP compiler assumes that all files in a
project work together to form a complete application. This allows it to discard the symbol names and, when executing the code, jump directly to the
memory region of the code.

Analyzing for Optimization Correctness


Optimizing code may introduce bugs to software that runs perfectly when
non-optimized. Also the level of performance gain depends highly on the
internal structure of the source code. LISP is a language in which you can easily write programs that create or modify functions at run-time. It should be
clear that this use of the language by definition contradicts compile-time
optimization.
The Visual LISP compiler analyzes the code it is compiling and linking, and
creates a report pointing you to all source code segments that may cause
problems when optimized. If you do not receive any optimization warning
messages, you can assume that optimization did not introduce new problems
to your code.
The compiler is able to detect most problematic situations in AutoLISP code.
However there are situations in which it is impossible to detect code that may
become incorrect during the optimization. If your program uses one of the
following constructs, the compiler will not able to definitively prove correctness of the optimized code:

Interaction with external ARX applications that set or retrieve AutoLISP


variables.
Dynamic calls to functions defined by other ARX applications. You should
list the name of these functions and their parent applications in an XDF
file, if the application is to be loaded after the Visual LISP application is
loaded.
Dynamically built code, evaluated using eval, apply, mapcar, or load.
Use of set to set dynamically supplied variables.
Dynamic (program evaluated) action strings in action_tile and
new_dialog.

Dynamic exporting or unexporting of functions to native AutoLISP using


vl-acad-defun (or vl-acad-undefun).

Remember: Any optimization changes program semantics. The compiler


intends to preserve the behavior of project components relative to one

Optimizing Application Code

262

another. The compiler cannot guarantee unchanged behavior between your


project and external procedures. Typical effects are:

Outer applications and the AutoLISP console lose access to program functions and symbols.
Functions available from the Console in interpreter mode are unknown in
compiled mode.
Functions are available from the Console, but redefining them does not
change the programs behavior.

Understanding Project Build Options


There are a number of compilation options to choose from when you define
your project. Defining Build Options on page 260 briefly noted the options
available to you. To choose from among those options, you need more information as to what they mean.

Link Mode
If you direct the Visual LISP compiler to link functions in your project, it tries
to directly link all explicit function calls to the function definition, which
may reside in a different source file. In contrast, when you do not link your
functions, the compiler creates references to symbols that Visual LISP uses to
look up the actual memory location of the function. Linking improves the
performance of the compiled code and protects the code against function
redefinition. However, if your application is designed so that it is necessary
to redefine a function in order for it to work properly, you cannot statically
link that function.
The Build Options dialog lists 3 options for link mode:

Do Not Link. Do not link any functions.


Link. Link all functions in the project.
Internal. Link, then drop all functions. See Dropping Functions,
below.

Dropping Functions
Once function calls are statically linked, the compiler can optimize one level
further by dropping the function name completely. By dropping the function name, the function becomes invisible to users. This feature is selected by
choosing the Internal Link mode option.
Symbols exported to ACAD (for example, function names starting with C:)
will never be dropped.

Chapter 8

263

Maintaining Applications

Localizing Variables
Similar to function symbols, local variables are also subject to optimization.
If the Localize variables option is set, the compiler drops the names of all
local variables and directly links their references. This means that the program code points to the address where a variable is stored, instead of to a
symbol used to find the address of the variable.

Safe Optimization
Choosing the Safe optimize option reduces the amount of compiler optimization but protects your code from compiler-induced errors. Conditions handled by Safe optimizing relate to uncertain effects that can take place at program run-time. They may lead to a failure of the optimized program even
though the source code seems to be correct. For example:

The function symbol fishlips is defined by defun and used somewhere


in your code. This is a typical candidate for link optimization.
In another segment of your code, a variable named fishlips is assigned
using (setq fishlips <expr>).

Now there are two possible conditions: if the value assigned through setq is
intended to alter the definition of the function fishlips, static linking will
prevent this from happening. The first definition will be linked and cannot
be changed by the setq function. On the other hand, if the identical names
are handled independently, fishlips can be linked without creating incorrect code.
If Safe optimizing is on, the compiler will always stay on the safe side, even
if the user explicitly requests linking fishlips. This may result in less efficient code, but it ensures code correctness. If Safe optimizing is off, you can
override the compilers not-link recommendation for fishlips: you are
responsible for the link.
The Safe optimize mode is on by default. Be sure that you fully understand
the consequences before you turn it off.
LINK Conditions Ignored if Safe Optimizing is On
If the compiler encounters the following situations while Safe optimize is on,
it ignores any related LINK directive:

A symbol is bound as a parameter anywhere in the project


A symbol is bound as an auxiliary variable and referenced by value anywhere in the project
A symbol is explicitly assigned somewhere (by setq)

Optimizing Application Code

264

DROP Conditions Ignored if Safe Optimizing is On


If the compiler encounters a symbol referenced by value, it ignores any DROP
directive for the symbol.
LOCALIZE Conditions Ignored if Safe Optimizing is On
If the compiler encounters the following situations while Safe optimize is on,
it ignores the LOCALIZE directive:

A variable has a non-local reference or assignment to it within the project


A variable is called by name

Safe Optimization Warning Messages


If optimized compilation is on and the compiler finds a condition that forbids a certain level of optimization, it issues a warning message. For example,
if the function fishlips cannot be linked because the compiler found two
definitions for the function, youll see:
;*** WARNING: Cannot LINK fishlips;
Two DEFUNs found.
See Another DEFUN

Right-clicking on a warning message opens a menu. In addition to symbol


commands, the menu allows you to view the source code associated with the
message. Double-clicking on the highlighted message also shows the source
code. To browse all source files related to the compiler messages, press F11
repeatedly, or press SHIFT+F11 to return to the first message.
Each line of the warning message above guides you to a different code segment:
; *** WARNING: Cannot LINK fishlips

shows the function call that could not be linked.


; Two DEFUNs found

shows the first DEFUN found for function fishlips.


; See Another DEFUN

shows the second DEFUN found for function fishlips.


When the compiler works in safe optimization mode and finds a problem
condition, the warning starts with:
; *** WARNING: Safe: Cannot

If Safe optimization is off, but message mode is set to Full report, the same
warnings are prefixed by:
; *** WARNING: Dangerous

Chapter 8

265

Maintaining Applications

If you disable Safe optimize mode, these problematic conditions result in


compiler warnings.

Compiler Checking of Optimizing Conditions


The compiler always checks for optimizing consistency. If you specify an
optimization option that contradicts certain security rules, the compiler will
issue warning messages. These are briefly listed below.
LINK Requirements
The compiler links LISP function calls only if the following conditions are
met:

The function is defined only once, or is system defined (and poses no


defun).
The function is not bound anywhere in the project.
The function is not assigned anywhere in the project.
The linking call appears in the same module (FAS file) as the defun.

DROP Requirements
The compiler tries to drop a function name only if all corresponding function calls could be linked and are actually linked to the function definition.
The compiler does not drop the function name for a function definition if
the program calls a function by its symbol name.
A function is called by name in the following cases:

The symbol appears in a vl-acad-defun declaration.


The function was called from an ACTION_TILE action string.
The function symbol is a quoted argument for apply or mapcar or eval
somewhere in the project.

Note that for functions called from top-level expressions, the DROP declaration will be ignored without any warning messages.
LOCALIZE Requirements
The compiler does not localize a variable in bound lists of defun,lambda,
and foreach expressions if:

The variable has a non-local reference (or assignment) to it within the


outer top-level expression
The variable is called as a function by name
The variable symbol appears as a function call somewhere in the top-level
read-eval loop

Besides these conditions, which always cancel the optimization and result in
warning messages, there are other conditions which may or may not result
in incorrect code. Choosing the Safe optimize option for the project disallows these conditions as well. Disabling of Safe optimization results in com-

Optimizing Application Code

266

piler warnings if these conditions are met. See Safe Optimization on


page 264 for more information on this topic.

Chapter 8

267

Maintaining Applications

9
Advanced Topics

In this chapter
Visual LISP not only makes program development easier

Using ActiveX
Objects in AutoLISP

and faster, it also provides new functionality to AutoLISP

Attaching Reactors to
AutoCAD Drawings

applications. For example, you can use Visual LISP to access


ActiveX objects from AutoLISP code. And you can attach
reactors to entities in the AutoCAD drawing window, allowing your application to respond to user actions on these
entities.

268

Using ActiveX Objects with Visual LISP


ActiveX Automation is a new way to programmatically work with the contents of an AutoCAD drawing. In many instances, ActiveX works faster than
traditional AutoLISP functions in manipulating AutoCAD drawing objects.
ActiveX functionality is a programming interface that is usable from a number of languages and environments, such as C++, Visual Basic, and Delphi.
When you work with ActiveX objects in Visual LISP, you are working with
the same object model, properties, and methods that can be manipulated
from these other programming environments.
Objects are the main building blocks of an ActiveX application. In some
ways, you are already familiar with this notion. For example, AutoCAD drawing items such as lines, arcs, polylines, and circles have long been referred to
as objects. But in the ActiveX schema, many other components of the
AutoCAD interface are viewed as objects. For example, all of the following are
represented as objects:

Style settings, such as linetypes and dimension styles


Organizational structures, such as layers, groups, and blocks
The drawing display, such as the view and viewport
The drawings model space and paper space

Even the drawing and the AutoCAD application itself are considered objects.
In Visual LISP, ActiveX Automation includes much of the functionality provided by LISP functions such as entget, entmod, and setvar. Compared to
these standard AutoLISP functions, ActiveX runs faster, provides easier access
to object properties, and is more readable. For example, to access the radius
of a circle with traditional AutoLISP function, you must use entget to obtain
a list of entities, and assoc to find the property you are looking for. Furthermore, you must know the code number (DXF key value) associated with that
property in order to obtain it with assoc:
(setq radius (cdr (assoc 40 (entget circle-entity))))

With an ActiveX function, you simply ask for the radius of a circle:
(setq radius (vla-get-radius circle-object))

Whether or not to use ActiveX Automation is not always a matter of choice.


There are some things that you can only do using ActiveX. For example, to
access drawing objects from reactor callback functions, you must use
ActiveX. Youll learn more about this in Attaching Reactors to AutoCAD
Drawings on page 290.

Chapter 9

269

Advanced Topics

Understanding the AutoCAD Object Model


Objects are structured in a hierarchical fashion, with the Application object
at the root. The view of this hierarchical structure is referred to as the object
model. The object model shows you which object provides access to the next
level of objects. The AutoCAD object model is pictured below.
The AutoCAD Object Model

Object Properties
All objects in the AutoCAD object model have one or more properties. For
example, a circle object can be described by its radius, area, or linetype; each
of these are properties. An ellipse object also has area and linetype properties,
but it cannot be described in terms of its radius. Rather, you describe it in
terms of its major to minor axis ratio, a property named RadiusRatio in the

Using ActiveX Objects with Visual LISP

270

AutoCAD object model. Youll use property names when accessing AutoCAD
data through ActiveX functions.

Object Methods
ActiveX objects also contain methods, which are simply the actions available
for a particular kind of object. Some methods are applicable to most
AutoCAD drawing objects. For example, the Mirror method (creating a mirror image copy of an object around a mirror axis), and the Move method
(moving a drawing object along a specified vector) are among the methods
that apply to most drawing objects. By contrast the Offset method, which
creates a new object at a specified distance from an existing object, applies
only to a few classes of AutoCAD objects, such as Arc, Circle, Ellipse, and
Line.
In Visual LISP, ActiveX methods are implemented as AutoLISP functions.
Youll see many references to "ActiveX functions" in Visual LISP documentation, but keep in mind that in native ActiveX terminology, these are always
known as methods.
To determine which methods and properties apply to a specific type of
AutoCAD object, refer to the AutoCAD ActiveX Automation Reference. The
Reference is available from the AutoCAD Help menu, or by opening the
acadauto.hlp file in the AutoCAD Help directory.
TIP You will probably want to have the ActiveX Automation Reference open
at all times when you are developing Visual LISP programs that use ActiveX. If you
open the acadauto.hlp file from the AutoCAD Help directory, you can keep the
ActiveX Automation Reference open when you use Visual LISP online help. If you
open the Automation Reference by selecting it from the AutoCAD Help menu, it
closes when you choose an item from the Visual LISP Help menu.

Collections of Objects
All objects in the AutoCAD object model are grouped in collections. For example, the Blocks collection is made up of all blocks in an AutoCAD drawing,
and the ModelSpace collection is comprised of all graphical objects (circles,
lines, polylines, etc.) in the drawings model space. Collections are labeled in
the object model diagram.

Accessing AutoCAD Objects


The Application object is the root object for the AutoCAD ActiveX Automation object model. From the Application object, you can access any of the
other objects, or the properties or methods assigned to objects.
The first thing you need to do to access AutoCAD objects with ActiveX is to
establish a connection to the AutoCAD Application object. Use the

Chapter 9

271

Advanced Topics

vlax-get-acad-object function to establish this connection, as in the fol-

lowing example:
(setq acadObject (vlax-get-acad-object))

The vlax-get-acad-object function returns a pointer to the AutoCAD


Application object. In the example above, the pointer is stored in variable
acadObject. This return value exists as a unique Visual LISP data type called
VLA object (Visual LISP ActiveX object). When you refer to AutoCAD objects
with ActiveX functions, you must specify a VLA object type. For this reason,
you cannot use entget to access an object and then refer to that object with
an ActiveX function.
NOTE The entget function returns an object of data type ename. Although
you cannot use this object directly with an ActiveX function, you can convert it
to a VLA object using the vlax-ename->vla-object function. (See Converting
Object References on page 288.)

Using the Inspect Tool to View Object Properties


To view the properties associated with an Application object, you can select
the variable that points to the object (acadobject, in the previous example),
and click the Inspect button on the Visual LISP View toolbar:

You can readily identify many of the properties listed in the VLA Object
Inspector window. For example, FullName is the file name of the AutoCAD
executable file, Version is the current AutoCAD version, and Caption is
the contents of the AutoCAD window title bar. An [RO] following a property
name indicates that the property is read-only; you cannot change it.
Any property identified as a #<VLA OBJECT...> refers to another AutoCAD
ActiveX object. The Application object has two such properties,
ActiveDocument and Preferences. If you look at the diagram of the
AutoCAD object model, youll see that these two objects are just below the
Application object in the model hierarchy. To view the properties associated

Using ActiveX Objects with Visual LISP

272

with an object, double-click the object line in the Inspector window (or rightclick and choose Inspect). Here is the Inspector window for the Preferences
object:

You may have noticed that the properties of the Preferences object correspond to the settings in the AutoCAD Preferences dialog box. This makes it
easy for you to programmatically access Preferences information. For example, you can identify the AutoCAD configuration file with the following
function call:
$ (vla-get-ConfigFile acadPreferences)
"C:\\Program Files\\AutoCAD R14\\acad14.cfg"

Youll learn more about using ActiveX functions in Using Visual LISP Functions with ActiveX Methods on page 275.

Moving Forward From the Application Object


Following the AutoCAD object model hierarchy, the ActiveDocument property of the Application object leads you to the Document object. This represents the current AutoCAD drawing:
(setq acadDocument (vla-get-ActiveDocument acadObject))

The Document object has many properties. Access to non-graphical objects


(layers, linetypes, and groups, for example) is provided through like-named
properties such as Layers, Linetypes, and Groups. To get to the graphical
objects in the AutoCAD drawing, youll need to access either the drawings

Chapter 9

273

Advanced Topics

model space (through the ModelSpace property) or paper space (through the
PaperSpace property). For example:
(setq mSpace (vla-get-ModelSpace acadDocument))

At this point, you have access to the AutoCAD drawing and can add objects
to the drawing. For example, you can add a circle to the model space with the
following command:
(setq mycircle

(vla-addCircle mSpace (3.0 3.0 0.0) 2.0))

Summarizing the Process


In this section, you saw code examples that led to the drawing of a circle
object to an AutoCAD drawing, using ActiveX Automation. The following
sequence of function calls was used:
(setq
(setq
(setq
(setq

acadObject
acadDocument
mSpace
mycircle

(vlax-get-acad-object))
(vla-get-ActiveDocument acadObject))
(vla-get-ModelSpace acadDocument))
(vla-addCircle mSpace (3.0 3.0 0.0) 2.0))

The four statements in this example accomplished the following:


1 The first statement returned a pointer to the root AutoCAD object, the Application object. The pointer to the object was stored in variable acadObject.
2 The second statement obtained a pointer to the Document object, which is
a property of the Application object. This provided access to the current
AutoCAD drawing. The pointer to the Document object was stored in variable acadDocument.
3 The third statement obtained a pointer to the ModelSpace object, a property
of the Document. The pointer to the ModelSpace object was stored in variable mSpace.
4 The last statement drew a circle in the ModelSpace.
The hierarchical path traversed in the AutoCAD object model is pictured
below:

Using ActiveX Objects with Visual LISP

274

Using Visual LISP Functions with ActiveX Methods


Visual LISP contains an extensive set of functions to provide access to
ActiveX objects. The function names are prefixed with vla-; for example,
vla-addCircle, vla-get-ModelSpace, vla-getColor. Each vla- function corresponds to an ActiveX method or property.
Visual LISP also contains ActiveX-related functions whose names are prefixed
with vlax-. These are specialized ActiveX functions designed specifically for
use within Visual LISP.
There are vla- functions for all of the methods and properties described in the
ActiveX Automation Reference. If your drawing contains custom ActiveX
objects, you can use the vlax-invoke, vlax-get, and vlax-put functions to
access their methods and properties. See the AutoLISP Function Reference
for information on using these functions.

Determining the Visual LISP Function You Need


The Visual LISP ActiveX functions actually provide access to ActiveX methods. For example, take another look at this AutoLISP statement, which adds
a circle to a drawing:
_$ (setq mycircle (vla-addCircle mSpace (3.0 3.0 0.0) 2.0))
#<VLA-OBJECT IAcadCircle 03ad067c>

The function that is called to draw the circle is vla-addCircle.


If you did not know what function to use to add a circle to an AutoCAD drawing, you could figure it out by looking in the ActiveX Automation Reference.
Look up the definition for a Circle object in the ActiveX Automation Reference. Heres what the entry for a Circle object looks like:

Chapter 9

275

Advanced Topics

Sometimes, as in this Circle entry, there is descriptive text that identifies the
method you need. Often, though, youll need to look through the list of
Methods to find the one that matches the action you want to take.
Once youve found the name of the method, add a vla- prefix to the method
name in order to get the name of the Visual LISP function that implements
the method. In this example, it is vla-AddCircle. Note that in Visual LISP
the function name is not case sensitive; vla-addcircle is the same as
vla-AddCircle.

Determining How to Call a Function


Once youve identified the Visual LISP function you need, you still need to
determine how to call the function. At the present time, there is no reference
available defining the AutoLISP syntax for each function call. You need to
look up the method in the ActiveX Automation Reference and derive the
syntax from there.
For example, from the reference page for the Circle object, click on the
AddCircle hyperlink to view the definition of this method:

Using ActiveX Objects with Visual LISP

276

Note that you can also get to this page by clicking on the Methods button
near the top of the Help window, and choosing AddCircle from a list of methods.
The syntax definitions in the Automation Reference apply to the Visual Basic
language. For AddCircle, the syntax is defined as:
RetVal = object.AddCircle(Center, Radius)

Compare this to an equivalent function call in Visual LISP:


(setq myCircle (vla-addCircle mSpace (3.0 3.0 0.0) 2.0))

The return value (RetVal, in Visual Basic) is straight-forward. The Automation Reference defines this as a Circle object. In Visual LISP, whenever an
AutoCAD object is returned by an ActiveX function, it is stored as a
VLA object data type.
The object referred to before the method name (object.AddCircle) is always
the first argument in a vla function call. This is the object you are viewing
or modifying. For example, you add a circle to the drawing model space:
(vla-addCircle

mSpace ...)

In this example, mspace refers to the ModelSpace object. Recall from the discussion on the AutoCAD object model (in Accessing AutoCAD Objects on
page 271), that you use the properties of one AutoCAD object to access

Chapter 9

277

Advanced Topics

another object, in a hierarchical manner. The ModelSpace object provides


access to the model space of the current drawing.

Translating Visual Basic Arguments to Visual LISP Arguments


There are two parameters remaining to decipher. These are referred to as
Center and Radius in the method definition. Center is said to be a
Variant (3-element array of doubles) data type, and Radius is listed as a
Double:

The ActiveX Automation Reference explains what these parameters are used
for, but the data types it indicates for these parameters are Visual Basic data
types. You need to convert these to Visual LISP data types. The following
table shows how:

Visual Basic Data Type

Visual LISP Data Type

Boolean

INT (0 = False, Other = True)

Integer

INT

Integer

INT

Real

REAL

Double

REAL

String

STRING

Array

LIST

4 x 4 Array of Doubles

LIST of 4 LISTs = Transformation matrix

Object

VLA object

In looking up the Visual LISP data type for the Center argument, you need to
convert the data type described in parentheses after the word Variant
(3-element array of doubles). The table shows that an array in Visual Basic is
a list in Visual LISP, and a double in Visual Basic is a real number in Visual

Using ActiveX Objects with Visual LISP

278

LISP. So the Center argument requires a list of real numbers. For example, a
center point of 3.0 on the X and Y axes is:
(3.0 3.0 0.0)

The Radius argument, a Double in Visual Basic, requires a real number in LISP.
Here is a diagram of the translation from Visual Basic to Visual LISP:

When you use ActiveX functions within Visual LISP, you must always provide arguments that are of the data types specified in the ActiveX method
definitions. Failure to do so (for example, passing an integer value when a
real is required) may cause your program to crash. To convert points and
matrices to the appropriate form, use the vlax-3D-point and vlax-tmatrix
functions described in Converting Arguments on page 287.

Viewing and Updating Object Properties


Visual LISP contains functions to read and update object properties. To demonstrate these functions, begin by entering the following at the Visual LISP
Console prompt:
(setq myCircle (vla-addcircle mspace (getpoint "\nPick the center
point for a circle: ") 2.0))

Then pick a point in the AutoCAD drawing window. This will be the center
point of the circle. You can use a Visual LISP function to identify the center
point.
Reading Object Properties
Functions that read object properties are named with a vla-get prefix and
require the following syntax:
(vla-get-property object)

For example, vla-get-center returns the center point of a circle. You can use
this function to draw a second circle concentric to the first:
(vla-addCircle mSpace (vla-get-center myCircle) 1.0)
#<VLA-OBJECT IAcadCircle 03ad0a1c>

The AutoCAD drawing window now contains the following objects:

Chapter 9

279

Advanced Topics

Updating Object Properties


Functions that update properties are prefixed with vla-put and use the following syntax:
(vla-put-property object new-value)

For example, vla-put-center changes the center point of a circle. The following sequence of function calls subtracts 1 unit from the X-axis of the original circle, then uses vla-put-center to update the circle with the new Xaxis:
_$ (setq myCenter (vla-get-center myCircle))
(6.98607 4.52594 0.0)
_$ (setq Xaxis (- (car myCenter) 1 )) ;
5.98607
_$ (setq newcenter (list Xaxis (cadr myCenter) (caddr myCenter)))
(5.98607 4.52594 0.0)
_$ (vla-put-center myCircle newcenter)
nil

The AutoCAD drawing window shows the result:

Note that changing an objects property may not immediately affect the display of the object in the AutoCAD drawing. AutoCAD delays property
changes to allow you to change more than one property at a time. To explicitly update the drawing window, issue the vla-update function:
(vla-update object)

Using ActiveX Objects with Visual LISP

280

Sometimes you can use pre-defined constants to update an object. For


example, to set the fill color of a circle to red, you can use the constant
acRed instead of specifying a numeric index value:
$ (vla-put-color myCircle acRed)

The AutoCAD ActiveX Automation Reference lists predefined constants in a


section titled Constants. You can use these constants in Visual LISP
ActiveX function calls.

Determining If an Object Can be Accessed


If other applications are working with AutoCAD objects at the same time
your program is, those objects may not be accessible to your program. This is
especially important to look out for if your application includes reactors,
since reactors execute code segments in response to external events which
cannot be predicted in advance (see Attaching Reactors to AutoCAD Drawings on page 290). But even a simple thing such as a locked layer can prevent you from changing an objects properties.
Visual LISP provides functions that allow you to test the accessibility of an
object before you try to use it:

vlax-read-enabled-p tests whether you can read an object.


vlax-write-enabled-p tests whether you can modify an objects properties.
vlax-erased-p check to see if an object has been erased. Erased objects
may still exist in the drawing database.

These test functions return T if true, nil if false. The following examples test
a line object:
$ (vlax-read-enabled-p WhatsMyLine)
T
$ (vlax-write-enabled-p WhatsMyLine)
T
$ (vlax-erased-p WhatsMyLine)
nil

After erasing the WhatsMyLine object:


$ (vlax-read-enabled-p WhatsMyLine)
nil
$ (vlax-erased-p WhatsMyLine)
T

Chapter 9

281

Advanced Topics

Using ActiveX Methods That Return Values in Arguments


Some ActiveX methods require you to supply them with variables into which
they can place values. The GetBoundingBox method is an example of this
type of method. Here is how it is defined in the ActiveX Automation Reference:

Note that the MinPoint and MaxPoint parameters are described as output
items of data type 3-element array of doubles. In Visual LISP, this is a list
data type. You need to provide these arguments as quoted variable names.
The following example shows a Visual LISP function call to return the minimum and maximum bounding points of a circle, and the results of that call:
_$ (vla-getboundingbox myCircle minpoint maxpoint)
((1.0 1.0 -1.0e-008) (5.0 5.0 1.0e-008))
_$ minpoint
(1.0 1.0 -1.0e-008)
_$ maxpoint
(5.0 5.0 1.0e-008)
_$

(Note that the quoted symbol parameters that you pass to the function
become AutoLISP variables just like ones created through setq. Because of
this, you should include them as local variables in your function definition
so that they do not become global variables by default.)

Using ActiveX Objects with Visual LISP

282

Listing an Objects Properties and Methods


Earlier in this chapter, you saw how to use the Visual LISP Inspect tool to
display an objects properties. Another way to view an objects properties is
to call the vlax-dump-object function. You can invoke this function from
the Visual LISP Console or in an application program. The vlax-dump-object
function prints a list of the properties of the specified object. For example,
the following code obtains an object from the model space and then issues
vlax-dumpObject to print the objects properties:
_$ (setq WhatsMyLine (vla-item mSpace 2))
#<VLA-OBJECT IAcadLWPolyline 036f1d0c>
_$ (vlax-dump-object WhatsMyLine)
; IAcadLWPolyline: AutoCAD Lightweight Polyline Interface
; Property values:
;
Application (RO) = #<VLA-OBJECT IAcadApplication 00b3b91c>
;
Area (RO) = 15.6259
;
Closed = 0
;
Color = 256
; Coordinates = (15.6022 6.26923 15.9361 3.73077 13.111 3.807 ... )
;
EntityName (RO) = "AcDbPolyline"
;
EntityType (RO) = 24
;
Handle (RO) = "4E"
;
Layer = "0"
;
Linetype = "BYLAYER"
;
LinetypeScale = 1.0
;
Normal = (0.0 0.0 1.0)
;
ObjectID (RO) = 42009904
;
Thickness = 0.0
;
Visible = -1
T

There is an optional second argument you can supply to vlax-dump-object


that causes it to also list all the methods that apply to the object. Simply specify T following the object name:
(vlax-dump-object WhatsMyLine T)

Note that vlax-dump-object displays the information in the Console window or an AutoCAD text window, however the function returns either T or
nil, not a list of strings containing the displayed information.

Determining if a Method or Property Applies to an Object


Trying to use a method that does not apply to the specified object will result
in an error. Trying to reference a property that does not apply to an object
also results in an error. In instances where you are not sure what applies, use
the vlax-method-applicable-p and vlax-property-available-p functions
to test the objects. These functions return T if the method or property is available for the object, and nil if it is not.
The syntax for vlax-method-applicable-p is:

Chapter 9

283

Advanced Topics

(vlax-method-applicable-p object method)

For example:
_$ (vlax-method-applicable-p WhatsMyLine "copy")
T
_$ (vlax-method-applicable-p WhatsMyLine "AddBox")
nil

For vlax-property-available-p, the syntax is:


(vlax-property-available-p object property [T])

For example:
_$ (vlax-property-available-p WhatsMyLine "Color")
T
_$ (vlax-property-available-p WhatsMyLine "center")
nil

Supplying the optional T argument to vlax-property-available-p


changes the meaning of the test. If you supply this argument, the function
returns T only if the object has the property and the property can be
modified. If the object has no such property or the property is read-only,
vlax-property-available-p returns nil. For example, a circle contains an
area property, but you cannot update it. If you check the property without
specifying the optional argument, the result is T:
_$ (vlax-property-available-p myCircle "area")
T

If you supply the optional argument, the result is nil:


_$ (vlax-property-available-p myCircle "area" T)
nil

Working With Collection Objects


The concept of collections was introduced in Understanding the AutoCAD
Object Model. Recall that all ActiveX objects in the AutoCAD object model
are grouped in collections. For example, the Blocks collection is made up of
all blocks in an AutoCAD document. Visual LISP provides functions to help
you work with collections of AutoCAD objects. These functions are
vlax-map-collection and vlax-for.
The vlax-map-collection function applies a function to every object in a
collection. The syntax is:
(vlax-map-collection collection-object function)

Using ActiveX Objects with Visual LISP

284

For example, to list all properties of every object in a drawings model space:
$ (vlax-map-collection (vla-get-ModelSpace acadDocument)
vlax-dumpObject)
; IAcadLWPolyline: AutoCAD Lightweight Polyline Interface
; Property values:
;
Application (RO) = #<VLA-OBJECT IAcadApplication 00b3b91c>
;
Area (RO) = 3.67152
;
Closed = -1
;
Color = 256
;
Coordinates = (9.59247 4.44872 9.25814 5.34715 4.1991 5.679 ...)
;
EntityName (RO) = "AcDbPolyline"
;
EntityType (RO) = 24
;
Handle (RO) = "4C"
;
Layer = "0"
;
Linetype = "BYLAYER"
;
LinetypeScale = 1.0
;
Normal = (0.0 0.0 1.0)
;
ObjectID (RO) = 42009888
;
Thickness = 0.0
;
Visible = -1
; IAcadCircle: AutoCAD Circle Interface
; Property values:
;
Application (RO) = #<VLA-OBJECT IAcadApplication 00b3b91c>
;
Area (RO) = 0.661383
;
Center = (8.53948 4.91026 0.0)
;
Color = 256
;
EntityName (RO) = "AcDbCircle"
;
EntityType (RO) = 8
;
Handle (RO) = "4D"
;
Layer = "0"
;
Linetype = "BYLAYER"
;
LinetypeScale = 1.0
;
Normal = (0.0 0.0 1.0)
;
ObjectID (RO) = 42009896
;
Radius = 0.45883
;
Thickness = 0.0
;
Visible = -1

To evaluate a series of functions with each object in a collection, use


vlax-for:
(vlax-for symbol collection [expressions] ...)

Like the foreach function, vlax-for returns the result of the last expression
evaluated inside the for loop. Note that modifying the collection (that is,
adding or removing members) while iterating through it may cause an error.

Chapter 9

285

Advanced Topics

Heres an example using vlax-for to show color statistics for each object in
the active drawing:
(defun show-Color-Statistics (/ objectColor colorSublist colorList)
(setq modelSpace (vla-get-ModelSpace
(vla-get-ActiveDocument (vlax-get-Acad-Object))
)
)
(vlax-for obj modelSpace
(setq objectColor (vla-get-Color obj))
(if (setq colorSublist (assoc objectColor colorList))
(setq colorList (subst (cons objectColor (1+ (cdr colorSub list)))

colorSublist
colorList
)
)
(setq colorList (cons (cons objectColor 1) colorList))
)
)
(if colorList
(progn (setq
colorList (vl-sort colorList
(lambda (lst1 lst2) (< (car lst1) (car lst2)))
)
)
(princ "\nColorList = ")
(princ colorList)
(foreach subList colorList
(princ "\nColor ")
(princ (car subList))
(princ " is found in ")
(princ (setq count (cdr subList)))
(princ " object")
(princ (if (= count 1)
"."
"s."
)
)
)
)
)
(princ)
)

Using ActiveX Objects with Visual LISP

286

Retrieving Member Objects in a Collection


The Item method retrieves a member object in a collection. The Count property shows the number of items in a collection. Using the Item method and
Count property, you can process each object in a collection individually. For
example, you can test each object in a model space to determine what type
of object it is, then process only the types you are interested in. The following
code prints the start angle for each arc object in a model space:
(setq index 0)
(repeat
(vla-get-count mspace)
(if (= 4 (vla-get-entitytype (vla-item mspace index)))
(progn
(princ "\nThe start angle of the arc is ")
(princ (vla-get-startangle (vla-item mspace index)))
)
)
(setq index (+ index 1))
)

Note that Item and Count also apply to groups and selection sets.

Converting Arguments
When creating AutoCAD entities using the command and entmake functions,
AutoLISP allows a great deal of flexibility regarding the composition of coordinate data lists (that is, 2D or 3D points). When working with ActiveX functions, however, you must be very precise when passing these parameters. A
3D point must consist of three reals. To ensure that points are formatted correctly, you can use the vlax-3D-point function. The function syntax allows
you to specify either a list representing a 2D or 3D point, or coordinate values:
(vlax-3D-point <list>)
(vlax-3D-point x y [z])

For example:
_$ (setq aPoint(vlax-3D-point (list 1 2)))
(1.0 2.0 0.0)
$ (setq aPoint(vlax-3D-point 1 2))
(1.0 2.0 0.0)

The vlax-TMatrix function performs a similar task for transformation matrices, which are required by the vla-TransformBy function. It builds the transformation matrix from four lists of four numbers each, converting all numbers to reals, if necessary. For example:
_$ (vlax-tmatrix (list(list 1 1 1 0)(list 1 2 3 0)(list 2 3 4 5)(list
2 9 8 3)))
((1.0 1.0 1.0 0.0) (1.0 2.0 3.0 0.0) (2.0 3.0 4.0 5.0) (2.0 9.0 8.0

Chapter 9

287

Advanced Topics

3.0))

Releasing Objects and Freeing Memory


Just as you can have different symbols pointing to the same AutoCAD entity,
you can have multiple VLA objects pointing to the same drawing object. As
long as a VLA object points to a drawing object, AutoCAD keeps all the memory needed for the object. To free this memory when you no longer need to
reference the object, use the vlax-release-object function:
(vlax-release-object object)

After releasing an object, it is no longer accessible through the VLA object


pointer. This is similar to closing a file. No memory is freed in Visual LISP
when you issue vlax-release-object, but memory may be freed in
AutoCAD when you have released all references to the object.
To test whether an object has been released or not, use the
vlax-object-released-p function:
(vlax-object-released-p object)

This function returns T if the object has been released, nil if it has not.
You can compare two VLA objects with the equal function. It returns T if
both objects point to the same drawing object.

Converting Object References


Visual LISP provides a function that allow you to convert entity names
(enames) obtained through functions such as entget, to VLA objects you can
use with ActiveX functions. VLISP also provides a function to convert a VLA
object to an ename.
To convert entity names to VLA objects, use the vlax-ename->vla-object
function. For example:
_$ (setq ename-circle (car (entsel "\nPick a Circle:")))
<Entity name: 27f0538>
_$ (setq vlaobject-circle (vlax-ename->vla-object ename-circle))
#<VLA-OBJECT IAcadCircle 03642c24>

To convert VLA objects to enames, use the vlax-vla-object->ename function. For example:
$ (setq new-ename-circle (vlax-vla-object->ename vlaobject-circle))
<Entity name: 27f0538>

Using ActiveX Objects with Visual LISP

288

You may find the same drawing object represented by different data types: a
handle string, an ename, a VLA object, or an ARX Object ID integer. To convert between these types:

To find the handle associated with an ename, use the DXF 5 group of the
enames association list:
_$ (setq handle-circle (cdr (assoc 5 (entget ename-circle))))
"4F

To find the ename associated with a handle, use the handent function:
_$ (handent handle-circle)
<Entity name: 27f0538>

To find the VLA object associated with a handle, use the


vla-handleToObject function:

$ (setq vla-circle (vla-handleToObject acadDocument handle-circle))


#<VLA-OBJECT IAcadCircle 03642c24>

To find the handle associated with a VLA object, use vla-get-handle to


obtain the handle property:
$ (vla-get-handle vla-circle)
"4F"

The ObjectID property identifies the ARX Object ID of a VLA object:


_$ (setq
41878840

objid-Circle (vla-get-objectid vla-circle))

Finally, to translate from an ARX Object ID back to its VLA object, use the
ObjectIDtoObject method on the AutoCAD Document object:
_$ (vla-ObjectIDtoObject acadDocument objid-circle)
#<VLA-OBJECT IAcadCircle 03642c24>

Chapter 9

289

Advanced Topics

Attaching Reactors to AutoCAD Drawings


A reactor is an object that you attach to AutoCAD drawing objects in order to
have AutoCAD notify your application when events you are interested in
occur. For example, if a user moves an entity that your application has
attached a reactor to, your application will receive notification that the
entity has moved. If you have designed it to do so, your application can react
to this notification with appropriate actions, such as moving other entities
associated with the one moved, or perhaps updating a text tag that records
revision information on the drawing feature that was altered.
A reactor communicates with your application by calling a function you
have associated with the reactor. Such a function is referred to as a callback
function. There isnt anything particularly unusual about callback functions
-- they are like other functions you write with Visual LISP. They become callback functions when you attach them to reactor events.

Reactor Types and Events


There are several types of AutoCAD reactors, each corresponding to general
categories of events your application can respond to:

Linker Reactors notify your application every time an ARX application


is loaded or unloaded.
Editor Reactors notify you each time an AutoCAD command is
invoked, a drawing opens, closes, or is saved, a DXF file is imported or
exported, or a system variable changes value.
Database Reactors notify your application when specific events occur
to the drawing database, such as when an object has been added to the
database.
Object Reactors notify you each time a specific object is changed, copied, or deleted.

The function vlr-types returns a list of Visual LISP reactor types. Currently,
the reactor types it returns are:

:VLR-Linker-Reactor - linker reactor


:VLR-Editor-Reactor - editor reactor
:VLR-AcDb-Reactor - database reactor
:VLR-Object-Reactor - object reactor

For each reactor type there are a number of callback events that notify your
application under specific circumstances. For instance, when a drawing is
saved, a :vlr-beginSave event occurs, the drawing is saved, and finally a

Attaching Reactors to AutoCAD Drawings

290

:vlr-saveComplete event occurs. In designing a reactor-based application,


it is up to you to determine the events that you are interested in, and to write
the callback functions to be triggered when these events occur.

The vlr-reaction-names function returns a list of all available events for a


given reactor type:
(vlr-reaction-names reactor type)

For example:
$ (vlr-reaction-names :VLR-Editor-Reactor)
(:vlr-unknownCommand :vlr-commandWillStart :vlr-commandEnded....

You can print out a list of all available reactor events, sorted by reactor type,
by loading and running the following code in Visual LISP:
(progn (foreach rtype (vlr-types)
(terpri)
(princ rtype)
(foreach rname(vlr-reaction-names rtype)
(terpri)
(princ "\t")
(princ
rname
)
)
)
(princ)
)

The AutoLISP Function Reference lists the name and a brief description of
each event available for a reactor type. For each reactor type, you can find
this information by looking up the description of the function you use to
define a reactor of that type. These functions are listed in Creating Reactors
on page 292.

Defining Callback Functions


A callback function is a regular AutoLISP function, which you define using
defun. After you define a callback function, you link the function to an event
by creating a reactor object.
NOTE Some AutoLISP functions cannot be used within callback functions.
You cannot call AutoCAD commands using the command function. Also note that
to access drawing objects, you must use ActiveX functions (vla-*); entget and
entmod are not allowed inside callback functions.

Chapter 9

291

Advanced Topics

Defining Linker, Editor, and Database Reactors


Callback functions for linker, editor, and database reactors must be defined
to accept two arguments. The first argument identifies the reactor object that
called the function. The second argument is a list of parameters that is set by
AutoCAD. The list of parameters is dependent on the type of event the function is associated with.
For example, an event called :vlr-commandWillStart indicates that an
AutoCAD command has been issued. A callback function that reacts to
:vlr-commandWillStart will receive a parameter list containing the name of
the AutoCAD command that triggered the event. A callback function that
reacts on :vlr-sysVarChanged, on the other hand, receives a parameter list
containing the name of a system variable (a string) and a flag indicating
whether or not the change was successful. You can find a list of events for
each reactor type, and the parameters associated with each event, in the
AutoLISP Function Reference. The events are listed under the description
of the functions used to define each type of reactor. These functions are
listed in Creating Reactors on page 292

Defining Object Reactor Callback Functions


Callback functions for object reactors must be defined to accept three arguments. The first argument identifies the object that fired the notification, the
second identifies the reactor object that called the function, and the third is
a list of parameters specific to the callback condition.

Using Predefined Callback Functions


Visual LISP supplies you with two predefined callback functions:

vlr-beep-reaction is a simple function that beeps your PC.


vlr-trace-reaction prints a list of arguments to the Visual LISP Trace
window each time a reactor fires this callback function.

Creating Reactors
To add reactor functionality to your application, you first need to write a callback function that performs the tasks needed at the time of the reactor event.
For example, here is a function named saveDrawingInfo that displays file

Attaching Reactors to AutoCAD Drawings

292

path and size information. This function will be attached to an editor reactor
that will fire when an AutoCAD drawing is saved:
(defun saveDrawingInfo (calling-reactor commandInfo / dwgname filesize)
(setq dwgname (cadr commandInfo)
filesize (vl-file-size dwgname)
)
(alert (strcat "The file size of " dwgname " is "
(itoa filesize) " bytes."
)
)
(princ)
)

The function retrieves the drawing name from the commandInfo parameter,
then uses the vl-file-size function to retrieve the size of the drawing. The
information is then displayed in an alert box in the AutoCAD window.
NOTE After you activate a reactor and its callback function is executed, you
may need to enter vlide at the AutoCAD Command prompt in order to return
to Visual LISP. Simply switching focus to the Visual LISP window will not work.
You link the callback function to an event when you create a reactor. There
is a Visual LISP function to create each type of reactor. These functions are
listed in the following table:

Function

Reactor
Type

Arguments

vlr-acdb-reactor

Database

data - any AutoLISP data to be associated with a reactor


object
callbacks - a list of pairs (event-name . callback_function)

vlr-editor-reactor Editor

data - any AutoLISP data to be associated with the reactor object


callbacks - a list of pairs(event-name . callback_function)

vlr-linker-reactor Linker

data - any AutoLISP data to be associated with the reactor object


callbacks - a list of pairs (event-name . callback_function)

vlr-object-reactor Object

owners - AutoLISP list of VLA objects identifying valid


drawing objects to be watched
data - any AutoLISP data to be associated with the reactor object
callbacks - a list of pairs (event-name . callback_function)

The table above indicates that the callbacks argument to these functions is a
list of pairs naming the event and the callback function to be associated with

Chapter 9

293

Advanced Topics

that event. Possible events for each function are listed under the functions
entry in the AutoLISP Function Reference. All of these reactor construction
functions return the reactor object.
Editor reactors monitor AutoCAD commands such as the Save command.
The following defines an editor reactor that responds to a user issuing a save
by invoking the saveDrawingInfo function:
(vlr-editor-reactor nil ((:vlr-saveComplete . saveDrawingInfo)))

The first argument is nil because there is no application-specific data to


attach to this reactor. The second argument is a list consisting of dotted pair
lists. Each dotted pair list identifes an event the reactor is to be notified
about, and the callback function to be run in response to that event. In this
case only one event, :vlr-save-Complete, will be reacted to.
Note that an editor reactor is notified each time the user issues a command,
whether through the AutoCAD Command line, a menu, a toolbar, or
through an AutoLISP program. So, the callback function for this editor
reactor needs to determine precisely what it is responding to. In the current
example, saveDrawingInfo simply checks for the Save command.

Using Object Reactors


Unlike editor, database, and linker reactors, object reactors are attached to
specific AutoCAD entities (objects). When you define an object reactor, you
must identify the entity the reactor is to be attached to.
The following code defines a callback function named print-radius. This
function can be used to print the radius of a circle object. Note that the code
uses the vlax-property-available-p function to verify that the drawing
object that notified this function contains a radius property:
(defun print-radius (notifier-object reactor-object parameter-list)
(cond
(
(vlax-property-available-p
notifier-object
"Radius"
)
(princ "The radius is ")
(princ (vla-get-radius notifier-object))
)
)
)

Attaching Reactors to AutoCAD Drawings

294

Here is some code to draw a circle:


(setq myCircle
; Prompt the user for the center point and radius
(progn (setq ctrPt
(getpoint "\nCircle center point: ")
radius (distance ctrPt
(getpoint ctrpt "\nRadius: ")
)
)
; Add a circle to the drawing model space. Nest the function
; calls to obtain the path to the current drawings model
; space: AcadObject > ActiveDocument > ModelSpace
(vla-addCircle
(vla-get-ModelSpace
(vla-get-ActiveDocument (vlax-get-acad-object))
)
ctrPt
radius
)
)
)

The code creates a variable called myCircle, which contains a pointer to the
circle object that is drawn. Notice that an ActiveX method is used to draw the
circle. This was not an arbitrary choice: you must use ActiveX methods to create or modify drawing objects from a callback function. ActiveX methods
work with ActiveX (VLA) objects.
To modify ename objects, such as those obtained through entlast and
entsel functions, you must first convert them into VLA objects using the
vlax-ename>vla-object function.
The function that creates object reactors requires three arguments. The first
argument is a list identifying the objects that are to fire notifications to the
reactor. These objects are referred to as the owners of the reactor. The owners
list must consist of VLA objects only; no enames are allowed. The second and
third arguments are those accepted by all reactor types: application-specific
data to attach to the reactor (if any), and a dotted pair list identifying the
events to which to react and the callback function to be invoked by each
event.
Attaching a Reactor to Objects
The following code attaches an object reactor to the myCircle object. It
defines the reactor to respond whenever the object is modified
(:vlr-modified) and to call the print-radius function in such an event:
(setq circleReactor (vlr-object-reactor (list myCircle)
Circle Reactor '((:vlr-modified . print-radius))))

Chapter 9

295

Advanced Topics

The reactor object is stored in variable circleReactor; you can refer to the reactor using this variable, as youll see below in Querying, Modifying and
Removing Reactors.
You may have noticed that the previous example included a string, Circle
Reactor, in the call to vlr-object-reactor. You do not have to specify any
data to be included with the reactor; you can specify nil instead. However,
an object may have several reactors attached to it. Including an identifying
text string, or other data that your application can use, allows you to distinguish among the different reactors attached to an object.
If you load and run each of the code samples in this section in Visual LISP,
you can test how the reactor works by altering the size of the circle drawn.
NOTE If you do not disable all reactors before exiting AutoCAD, you may
crash when you exit. See Disabling Reactors on page 299 for information on
how to disable reactors.

Querying, Modifying and Removing Reactors


There are various ways to obtain information about reactors. Visual LISP supplies functions to query reactors, and you can also use standard Visual LISP
data inspection tools to view information on them.
To receive a list of all reactors of a given type, use the vlr-reactors function:
(vlr-reactors reactor-type)

For reactor-type, specify one of the values returned by the vlr-types function;
these are listed in Reactor Types and Events on page 290. For example:
_$ (setq reactorList (vlr-reactors :VLR-Object-Reactor))
(#<VLR-Object-reactor>)

In this case, the return value of the function, stored in variable reactorList, is
a list containing a single object reactor pointer. This represents the reactor
created using the functions in the previous section.

Inspecting Reactors
You can examine reactors using the Visual LISP Inspector tool. For example,
the object reactor defined in Using Object Reactors on page 294 was
returned to a variable named circleReactor. If you open an Inspector window for this variable, Visual LISP displays the following information:

Attaching Reactors to AutoCAD Drawings

296

The object line indicates that the reactor is enabled (registered) in AutoCAD.
The list items in the Inspector window show the following:

Event and associated callback function


User data attached to the reactor
Objects owning the reactor

Double-click on the item that begins with {Owners} to view a list of the
owner objects:

Double-click on a list item to obtain detailed infomation about the object:

Querying Reactors Using Function Calls


Visual LISP also provides functions to inspect a reactor definition from
within an application program, or at the Console prompt:

vlr-type returns the type of the specified reactor. For example:


$ (vlr-type circleReactor)
:VLR-Object-Reactor

Chapter 9

297

vlr-current-reaction-name returns the name of the event that caused


the callback function to be called.

Advanced Topics

vlr-data returns the application-specific data value attached to the reactor. You can use this to distinguish among multiple reactors that can fire
the same callback function.
$ (vlr-data circleReactor)
"Circle Reactor"

vlr-owners returns a list of the objects in an AutoCAD drawing that fire


notifications to an object reactor.
_$ (vlr-owners circleReactor)
(#<VLA-OBJECT IAcadCircle 03ad077c>)

vlr-reactions returns the callback list of condition-function pairs of the


specified reactor.
$ (vlr-reactions circleReactor)
((:vlr-modified . PRINT-RADIUS))

Modifying Reactors
Visual LISP provides functions to modify reactor definitions:

vlr-reaction-set changes the callback function link for the specified


reactor event. The function syntax is:
(vlr-reaction-set reactor callback-condition callback-function)
For example, the following command changes the circleReactor reactor
to call the print-area function when an object is modified:
$ (vlr-reaction-set circleReactor :vlr-modified print-area)
PRINT-AREA

vlr-data-set changes the application-specific data associated with the


reactor. For example, the following call replaces the text string used to
identify the circleReactor reactor:
$ (vlr-data-set circleReactor "Circle Area Reactor")
"Circle Area Reactor"

You can verify that the reactor has changed by using the Visual LISP
Inspector feature. If the Inspector window shown in Inspecting Reactors
on page 296 is still displayed in your Visual LISP session, right-click in the
windows object line and choose Update. If youve modified the
circleReactor reactor as shown in this section, the updated Inspector
window will look like the following:

Attaching Reactors to AutoCAD Drawings

298

vlr-owner-add adds a database object to the list of owners of the specified reactor. In the following example, an arc object named archie is
added to the owner list of reactor circleReactor:
$ (vlr-owner-add circleReactor archie)
#<VLA-OBJECT IAcadArc 03ad0bcc>

Now, if a user modifies the archie object, the callback function defined
for reactor circleReactor is invoked. You can verify this by inspecting the
reactor. Update the Inspector window for the circleReactor reactor, then
right-click on the list item that begins with {Owners} and choose
Inspect:

Both Arc and Circle objects are listed in the Inspector window.

vlr-owner-remove removes an owner object from the list of reactor


owners. For example:
$ (vlr-owner-remove circleReactor archie)
#<VLA-OBJECT IAcadArc 03ad0bcc>

Disabling Reactors
If you want to disable a reactor, you need to remove it from AutoCAD. Note
that the reactor object still exists. You can activate it again using the vlr-add
function. To determine whether or not a reactor is active (registered to
AutoCAD), use the vlr-added-p function:
_$ (vlr-added-p circleReactor)
T

The vlr-added-p function returns T, if the reactor is active, nil if it is not.

vlr-remove disables the specified reactor. For example, the following


command disables reactor circleReactor:
_$ (vlr-remove circleReactor)
#<VLR-Object-reactor>

You can use vlr-added-p to verify that the circleReactor object reactor
has been disabled:
$ (vlr-added-p circleReactor)
nil

To enable the circleReactor reactor, use vlr-add:


$ (vlr-add circleReactor)
#<VLR-Object-reactor>

Chapter 9

299

Advanced Topics

vlr-remove-all disables all reactors of the specified type. The following


function call disables all object reactors:
$ (vlr-remove-all :vlr-object-reactor)
(#<VLR-Object-reactor>)

NOTE If you do not disable all reactors before exiting AutoCAD, you may
crash upon exit.

Transient versus Persistent Reactors


AutoCAD reactors may be transient or persistent. Transient reactors are lost
when a drawing closes; this is the default reactor mode. Persistent reactors are
saved with a drawing and exist when the drawing is next opened.
NOTE Keep in mind that a reactor is only a link between an event and a callback function. While this link remains, the callback function itself is not part of the
reactor and not part of the drawing. The reactors saved in the drawing are only
usable if the callback functions are defined to Visual LISP.
If you open a drawing containing Visual LISP reactor information and associated callback functions are not loaded, AutoCAD displays an error message.
Visual LISP includes functions to make a reactor persistent, to release a persistent reactor, and to check if a reactor is persistent or not.

vlr-pers makes a reactor persistent.


vlr-pers-release releases a persistent reactor.
vlr-pers-p determines whether or not a reactor is persistent. It returns T
if the reactor is persistent, nil if it is not.

Each function takes a reactor objects as its only argument. For example:
_$ (vlr-pers-p circleReactor)
nil

Attaching Reactors to AutoCAD Drawings

300

Chapter 9

301

Advanced Topics

A
AutoLISP
Function Reference

In this appendix
The following is a catalog of all standard AutoLISP functions defined

Brief description of functions use

by AutoCAD, along with additional functions supplied with Visual

Function syntax showing


the order and type of
arguments

LISP. The functions are listed alphabetically.


In this chapter, each listing contains a brief description of the functions use and a function syntax statement showing the order and the
type of arguments required by the function. (For specific information
on syntax statements, see AutoLISP Function Syntax.)
Note that any functions, variables, or features not described here or
in other parts of the documentation are subject to change in future
releases.

302

The number argument needs additional information: a number can be a real number, an
integer, or a symbol set to a real or integer value. If all arguments are integers, the result
is an integer. If any of the arguments are real numbers, the integers are promoted to real
numbers and the result is a real number.
Most AutoLISP functions are always available; however, some are defined by a
AutoLISP or ARX applications. The file that contains the externally defined functions is
identified after the heading Externally defined function. Before you attempt to use these
functions, you may want to test for their availability.
The value returned by some functions is specified as indeterminate. This indicates that
you cannot rely on using the value returned from this function.

+ (addition)
Returns the sum of all numbers

(+ [number number] ...)


If you supply only one number argument, this function returns the result of adding it to
zero; it returns the number. Supplying no arguments returns 0.
(+ 1 2)
(+ 1 2 3 4.5)
(+ 1 2 3 4.0)

returns 3
returns 10.5
returns 10.0

(subtraction)
Subtracts the second and following numbers from the first and returns the
difference

( [number number] ...)


If you supply more than two number arguments, this function returns the result of subtracting the sum of the second through last numbers from the first number. If you supply

Appendix A AutoLISP Function Reference

303

only one number argument, this function returns the result of subtracting it from zero; it
returns the number. Supplying no arguments returns 0.
(- 50 40)
(- 50 40.0)
(- 50 40.0 2.5)
(- 8)

returns 10
returns 10.0
returns 7.5
returns -8

* (multiplication)
Returns the product of all numbers

(* [number number] ...)


If you supply only one number argument, this function returns the result of multiplying
it by one; it returns the number. Supplying no arguments returns 0.
(* 2 3)
(* 2 3.0)
(* 2 3 4.0)
(* 3 -4.5)
(* 3)

returns 6
returns 6.0
returns 24.0
returns -13.5
returns 3

/ (division)
Divides the first number by the product of the remaining numbers and returns
the quotient

(/ [number number] ...)


If you supply more than two number arguments, this function divides the first number by
the product of the second through last numbers, and returns the final quotient. If you supply only one number argument, this function returns the result of dividing it by one; it
returns the number. Supplying no arguments returns 0.
(/ 100 2)
(/ 100 2.0)
(/ 100 20.0 2)
(/ 100 20 2)
(/ 4)

returns 50
returns 50.0
returns 2.5
returns 2
returns 4

* (multiplication)

304

= (equal to)
Returns T if all arguments are numerically equal, and returns nil otherwise

(= numstr [numstr] ...)


Each numstr argument can be a number or a string.
(= 4 4.0)
(= 20 388)
(= 2.4 2.4 2.4)
(= 499 499 500)
(= "me" "me")
(= "me" "you")

returns T
returns nil
returns T
returns nil
returns T
returns nil

See also the eq and equal functions

/= (not equal to)


Returns T if the arguments are not numerically equal, and nil if the arguments
are numerically equal

(/= numstr [numstr] ...)


Each numstr argument can be a number or a string.
(/= 10 20)
(/= "you" "you")
(/= 5.43 5.44)
(/= 10 20)

returns T
returns nil
returns T
returns T

Appendix A AutoLISP Function Reference

305

< (less than)


Returns T if each argument is numerically less than the argument to its right, and
returns nil otherwise

(< numstr [numstr] ...)


Each numstr argument can be a number or a string.
(< 10 20)
(< "b" "c")
(< 357 33.2)
(< 2 3 88)
(< 2 3 4 4)

returns T
returns T
returns nil
returns T
returns nil

<= (less than or equal to)


Returns T if each argument is numerically less than or equal to the argument to
its right, and returns nil otherwise

(<= numstr [numstr] ...)


Each numstr argument can be a number or a string.
(<= 10 20)
(<= "b" "b")
(<= 357 33.2)
(<= 2 9 9)
(<= 2 9 4 5)

returns T
returns T
returns nil
returns T
returns nil

< (less than)

306

> (greater than)


Returns T if each argument is numerically greater than the argument to its right,
and returns nil otherwise

(> numstr [numstr] ...)


Each numstr argument can be a number or a string.
(> 120 17)
(> "c" "b")
(> 3.5 1792)
(> 77 4 2)
(> 77 4 4)

returns T
returns T
returns nil
returns T
returns nil

>= (greater than or equal to)


Returns T if each argument is numerically greater than or equal to the argument
to its right, and returns nil otherwise

(>= numstr [numstr] ...)


Each numstr argument can be a number or a string.
(>= 120 17)
(>= "c" "c")
(>= 3.5 1792)
(>= 77 4 4)
(>= 77 4 9)

returns T
returns T
returns nil
returns T
returns nil

~ (bitwise NOT)
Returns the bitwise NOT (1s complement) of the argument

(~ int)
(~ 3)
(~ 100)
(~ -4)

returns -4
returns -101
returns 3

Appendix A AutoLISP Function Reference

307

1+ (increment)
Returns the argument increased by 1 (incremented)

(1+ number)
(1+ 5)
(1+ -17.5)

returns 6
returns -16.5

1 (decrement)
Returns the argument reduced by 1 (decremented)

(1 number)
(1- 5)
(1- -17.5)

returns 4
returns -18.5

abs
Returns the absolute value of the argument

(abs number)
(abs 100)
(abs -100)
(abs -99.25)

returns 100
returns 100
returns 99.25

acad_colordlg
Displays the standard AutoCAD color selection dialog box

(acad_colordlg colornum [flag])


The colornum argument is an integer in the range 0256 (inclusive). It specifies the
AutoCAD color number to display as the initial default. A colornum value of 0 defaults

1+ (increment)

308

to BYBLOCK, and a value of 256 defaults to BYLAYER. Setting the optional flag argument
to nil disables the BYLAYER and BYBLOCK buttons. Omitting the flag argument or
setting it to a non-nil value enables the BYLAYER and BYBLOCK buttons.
The acad_colordlg function returns the user-selected color number. If the user cancels
the dialog box, acad_colordlg returns nil.
The following code prompts the user to select a color and specifies a default of green:
(acad_colordlg 3)

Externally defined function acadapp ARX application

acad_helpdlg
Invokes the help facility (obsolete)

(acad_helpdlg helpfile topic)


This externally defined function has been replaced by the built-in function help. It is provided for compatibility with previous releases of AutoCAD. See help for a complete
description of this function.
Externally defined function acadr14.lsp AutoLISP function

acad_strlsort
Sorts a list of strings by alphabetical order

(acad _strlsort list)


The list argument is the list of strings to be sorted. The acad_strlsort function
returns a list of the same strings in alphabetical order. If the list argument list is invalid
or if there isnt enough memory to do the sort, acad_strlsort returns nil.
The following code sorts the list of abbreviated month names:
(setq mos ("Jan" "Feb" "Mar" "Apr" "May" "Jun"
"Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))
(acad_strlsort mos)

It returns the following list:


("Apr" "Aug" "Dec" "Feb" "Jan" "Jul"

Appendix A AutoLISP Function Reference

309

"Jun" "Mar" "May" "Nov" "Oct" "Sep")

Externally defined function acadapp ARX application

action_tile
Assigns an action to evaluate when the user selects the specified tile in a dialog
box

(action_tile key action-expression)


The key and action-expression arguments are strings. The key argument is the name
of the tile that triggers the action (specified as its key attribute). The key argument is
case-sensitive. The action-expression is evaluated when the tile is selected.
The action assigned by action_tile supersedes the dialog boxs default action
(assigned by new_dialog) or the tiles action attribute, if these are specified. The
expression can refer to the tiles current value (its value attribute) as $value, its name
as $key, its application-specific data (as set by client_data_tile) as $data, its callback reason as $reason, and its image coordinates (if the tile is an image button) as $x
and $y.
You cannot call the AutoLISP command function from the action_tile function.

add_list
Adds or modifies a string in the currently active dialog box list

(add_list string)
Before using add_list, you must open the list and initialize it with a call to
start_list. Depending on the operation specified in start_list, the string either
is added to the current list or replaces the current list item.
Assuming that the currently active DCL file has a popup_list or list_box with a key of
longlist, the following code fragment initializes the list and adds to it the text strings
in llist.
(setq llist ("first line" "second line" "third line"))
(start_list "longlist")
(mapcar add_list llist)
(end_list)

action_tile

310

After the list has been defined, the following code fragment changes the text in the second
line to "2nd line".
(start_list "longlist" 1 0)
(add_list "2nd line")
(end_list)

See also the start_list and end_list functions

ads
Returns a list of the currently loaded ADS applications

(ads)
Each application and its path is a quoted string in the list.
(ads) might return ("files/progs/PROG1" "PROG2")

See also the xload and xunload functions

alert
Displays an alert box with the error or warning message passed as a string

(alert string)
An alert box is a dialog box with a single OK button.
(alert "That function is not available.")

You can display multiple lines by using the newline character in string.
(alert "That function\nis not available.")

Line length and the number of lines in an alert box are platform, device, and window
dependent. AutoCAD truncates any string that is too long to fit inside an alert box.

Appendix A AutoLISP Function Reference

311

alloc
Sets the segment size to a given number of nodes

(alloc int)
This function returns the previous segment size.

and
Returns the logical AND of a list of expressions

(and expr ...)


If any of the expressions evaluate to nil, this function ceases further evaluation and
returns nil; otherwise it returns T.
For example, given the assignments
(setq a 103 b nil c "string")

then
(and 1.4 a c)
(and 1.4 a b c)

returns T
returns nil

angle
Returns an angle in radians of a line defined by two endpoints

(angle pt1 pt2)


The angle is measured from the X axis of the current construction plane, in radians, with
angles increasing in the counterclockwise direction. If 3D points are supplied, they are
projected onto the current construction plane.
(angle (1.0 1.0) (1.0 4.0)) returns 1.5708
(angle (5.0 1.33) (2.4 1.33) returns 3.14159

See also Angular Conversion on page 87.

alloc

312

angtof
Converts a string representing an angle into a real (floating-point) value in
radians

(angtof string [mode])


The string argument describes an angle based on the format specified by the mode argument. The mode argument, shown in the following table, specifies the units in which the
string is formatted. The value should correspond to values allowed for the AutoCAD system variable AUNITS. If mode is omitted, angtof uses the current value of AUNITS.
Angular units values
Mode value

String format

Degrees

Degrees/minutes/seconds

Grads

Radians

Surveyors units

The string must be a string that angtof can parse correctly to the specified mode. It can
be in the same form that angtos returns, or in a form that AutoCAD allows for keyboard
entry.
The angtof and angtos functions are complementary: if you pass angtof a string created by angtos, angtof is guaranteed to return a valid value, and vice versa (assuming
the mode values match).
If angtof succeeds, it returns a real value in radians; otherwise it returns nil.

Appendix A AutoLISP Function Reference

313

angtos
Converts an angular value in radians into a string

(angtos angle [mode [precision]])


The angtos function takes angle (a real number, in radians) and returns it edited into a
string according to the settings of mode, precision, the AutoCAD UNITMODE system
variable, and the DIMZIN dimensioning variable. The mode and precision arguments
are integers that specify the angular units mode and precision.
Angular units values
Mode value

String format

Degrees

Degrees/minutes/seconds

Grads

Radians

Surveyors units

The precision argument is an integer that selects the number of decimal places of precision desired. The mode and precision correspond to the AutoCAD system variables
AUNITS and AUPREC. If you omit these arguments, angtos uses the current settings of
AUNITS and AUPREC, respectively.
The angtos function accepts a negative angle argument, but always reduces it to a positive value between zero and 2 pi radians before performing the specified conversion.
(angtos 0.785398 0 4) returns "45.0000"
(angtos -0.785398 0 4) returns "315.0000"

angtos

314

The UNITMODE variable affects the returned string when surveyors units are selected
(a mode value of 4). If UNITMODE = 0, spaces are included in the string (for example,
"N 45d E"); if UNITMODE = 1, no spaces are included in the string (for example,
"N45dE").
Routines that use the angtos function to display arbitrary angles (those not relative to the
value of ANGBASE) should check and consider the value of ANGBASE.

append
Takes any number of lists and runs them together as one list

(append list ...)


(append (a b) (c d))
returns (A B C D)
(append ((a)(b)) ((c)(d))) returns ((A)(B)(C)(D))

apply
Passes a list of arguments to a specified function

(apply function list)


The apply function works with both built-in functions (subrs) and user-defined functions
(those created with either defun or lambda).
(apply + (1 2 3))
returns 6
(apply strcat ("a" "b" "c")) returns "abc"

Appendix A AutoLISP Function Reference

315

arx
Returns a list of the currently loaded ARX applications

(arx)
Each application and its path is a quoted string in the list.
(arx) might return ("files/progs/PROG1" "PROG2")

See also the arxload and arxunload functions

arxload
Loads an ARX application

(arxload application [onfailure])


The application argument is entered as a quoted string or as a variable that contains
the name of an executable file. At the time the file is loaded, it is verified to be a valid
ARX application.
If the arxload operation fails, it normally causes an AutoLISP error. However, if the
onfailure argument is supplied, arxload returns the value of this argument upon failure instead of an error message.
If the application is successfully loaded, the application name is returned.
(arxload "/myapps/appx") if successful, returns "/myapps/appx"

If you attempt to load an application that is already loaded, arxload issues the following
message and returns the application name.
Application "application" already loaded.
You may want to check the currently loaded ARX applications with the arx function
before using arxload.

arx

316

arxunload
Unloads an ARX application

(arxunload application [onfailure])


If the application is successfully unloaded, the application name is returned, otherwise, an
error message is issued.
Enter application as a quoted string or as a variable containing the name of an application that was loaded with the arxload function. The application name must be entered
exactly as it was entered for the arxload function. If a path (directory name) or extension
was entered for the application in arxload, it can be omitted in the arxunload function.
For example, the following code unloads the application appx, which was previously
loaded with the arxload function:
(arxunload "appx") if successful, returns "appx"

If the arxunload operation fails, it normally causes an AutoLISP error. However, if the
onfailure argument is supplied, arxunload returns the value of this argument upon
failure instead of issuing an error message. This feature of arxunload is similar to that
in the arxload function.

ascii
Returns the conversion of the first character of a string into its ASCII character
code (an integer)

(ascii string)
(ascii "A")
(ascii "a")
(ascii "BIG")

returns 65
returns 97
returns 66

This is similar to the ASC function in the BASIC language.

Appendix A AutoLISP Function Reference

317

assoc
Searches an association list for an element and returns that association list entry

(assoc item alist)


Searches the association list alist for item as the key element and returns the alist
entry. If assoc does not find item as a key in alist, it returns nil.
For example, given the code:
(setq al ((name box) (width 3) (size 4.7263) (depth 5)))

then
(assoc size al)
(assoc weight al)

returns (SIZE 4.7263)


returns nil

Association lists are frequently used for storing data that can be accessed by a key. The
subst function provides a convenient means of replacing the value associated with one
key in an association list.

atan
Returns the arctangent of a number in radians

(atan num1 [num2])


If you supply only one argument to atan, it returns the arctangent of num1, in radians. If
you supply both num1 and num2 arguments, atan returns the arctangent of num1/num2,
in radians. If num2 is zero, it returns an angle of plus or minus 1.570796 radians (+90
degrees or 90 degrees), depending on the sign of num1. The range of angles returned
is pi/2 to +pi/2 radians.
(atan 0.5)
(atan 1.0)
(atan -1.0)
(atan 2.0 3.0)
(atan 2.0 -3.0)
(atan 1.0 0.0)

returns 0.463648
returns 0.785398
returns -0.785398
returns 0.588003
returns 2.55359
returns 1.5708

The angtos function converts the radian value returned from atan into a string value.

assoc

318

(angtos (atan -1.0) 0 4)


returns "315.0000"
(angtos (atan 2.0 3.0) 0 4)
returns "33.6901"
(angtos (atan 2.0 -3.0) 0 4) returns "146.3099"
(angtos (atan 1.0 0.0) 0 4)
returns "90.0000"

atof
Returns the conversion of a string into a real number

(atof string)
(atof "97.1")
(atof "3")
(atof "3.9")

returns 97.1
returns 3.0
returns 3.9

atoi
Returns the conversion of a string into an integer

(atoi string)
(atoi "97")
(atoi "3")
(atoi "3.9")

returns 97
returns 3
returns 3

atom
Verifies that an item is an atom

(atom item)
Returns nil if item is a list; returns T otherwise. Anything thats not a list is considered
an atom.

Appendix A AutoLISP Function Reference

319

For example, given the assignments


(setq a (x y z))
(setq b a)

then
(atom a)
(atom a)
(atom b)
(atom b)
(atom (a b c))

returns T
returns nil
returns T
returns T
returns nil

Some versions of LISP differ in their interpretation of atom, so take care when using converted code.

atoms-family
Returns a list of the currently defined symbols

(atoms-family format [symlist])


The format argument is an integer value of 0 or 1. If the value of format is 0, atomsfamily returns the symbol names as a list. If format is 1, it returns the symbol names as
a list of strings. The atoms-family function searches for a specific list of symbol names
if you supply the symlist argument. The symlist argument is a list of strings that specify the symbol names. The atoms-family function returns a list of the type that is specified by format (symbols or strings) and that contains the names of the symbols that are
defined. It returns nil for those that are not defined.
(atoms-family 0)

returns a list of the currently defined symbols

The following code verifies that the symbols CAR, CDR, and XYZ have been defined, and
returns the list as strings:
(atoms-family 1
("CAR" "CDR" "XYZ"))

returns ("CAR" "CDR" nil)

The preceding return value shows that the symbol XYZ has not been defined.

atoms-family

320

autoarxload
Predefines command names to load an associated ARX file

(autoarxload filename cmdlist)


The filename argument is a string that specifies the .arx file that is loaded when one of
the commands defined by the cmdlist argument is entered at the Command prompt. The
cmdlist argument must be a list of strings. The autoarxload function returns nil.
The following code defines the C:APP1, C:APP2, and C:APP3 functions to load the bounsapp.arx file. The first time one of the command, APP1, APP2, or APP3 are entered at the
Command prompt the ARX application loads and the command continues.
(autoarxload "BONUSAPP" ("APP1" "APP2" "APP3"))

The commands listed by the cmdlst argument must be defined as commands by the file
specified by filename.

Externally defined function acadr14.lsp AutoLISP function

autoload
Predefines command names to load an associated AutoLISP file

(autoload filename cmdlist)


The filename argument is a string that specifies the .lsp file that is loaded when one of
the commands defined by the cmdlist argument is entered at the Command prompt. The
cmdlist argument must be a list of strings. The autoload function returns nil.

Appendix A AutoLISP Function Reference

321

The following code defines the C:APP1, C:APP2, and C:APP3 functions to load the bounsapp.lsp file. The first time one of the command, APP1, APP2, or APP3 are entered at the
Command prompt the AutoLISP file loads and the command continues.
(autoload "BONUSAPP" ("APP1" "APP2" "APP3"))

The commands listed by the cmdlst argument must be defined as commands by the file
specified by filename.

Externally defined function acadr14.lsp AutoLISP function

autoxload
Predefines command names to load an associated ADS application

(autoxload filename cmdlist)


The filename argument is a string that specifies the ADS application that is loaded when
one of the commands defined by the cmdlist argument is entered at the Command
prompt. The cmdlist argument must be a list of strings. The autoxload function
returns nil.
The following code defines the C:APP1, C:APP2, and C:APP3 functions to load the bounsapp ADS application. The first time one of the command, APP1, APP2, or APP3 is
entered at the Command prompt the ADS application loads and the command continues.
(autoxload "BONUSAPP" ("APP1" "APP2" "APP3"))

The commands listed by the cmdlst argument must be defined as commands by the file
specified by filename.

Externally defined function acadr14.lsp AutoLISP function

autoxload

322

Boole
Serves as a general bitwise Boolean function

(Boole func int1 int2 ...)


The func argument is an integer between 0 and 15 representing one of the 16 possible
Boolean functions in two variables. Successive integer arguments are bitwise (logically)
combined based on this function and on the following truth table.
Boolean truth table
Int1

Int2

Func bit

Each bit of int1 is paired with the corresponding bit of int2, specifying one horizontal
row of the truth table. The resulting bit is either 0 or 1, depending on the setting of the
func bit that corresponds to this row of the truth table.
If the appropriate bit is set in func, the resulting bit is 1; otherwise the resulting bit is 0.
Some of the values for func are equivalent to the standard Boolean operations AND, OR,
XOR, and NOT.
Boole function bit values
Func

Operation

Resulting bit is 1 if

AND

Both input bits are 1

XOR

Only one of the two input bits is 1

OR

Either or both of the input bits are 1

NOR

Both input bits are 0 (1s complement)

Appendix A AutoLISP Function Reference

323

The following specifies a logical AND of the values 12 and 5:


returns 4

(Boole 1 12 5)

Similarly, the following specifies a logical XOR of the values 6 and 5:


(Boole 6 6 5)

returns 3

You can use other values of func to perform other Boolean operations for which there are
no standard names. For example, if func is 4, the resulting bits are set if the corresponding bits are set in int2 but not in int1. Thus
(Boole 4 3 14)

returns 12

boundp
Verifies if a value is bound to a symbol

(boundp sym)
Returns T if sym has a value bound to it. If no value is bound to sym (or if it has been
bound to nil), boundp returns nil. If sym is an undefined symbol, it is automatically
created and is bound to nil.
For example, given the assignments
(setq a 2 b nil)

then
(boundp a)
(boundp b)

returns T
returns nil

The atoms-family function provides an alternate method of determining the existence


of a symbol without automatically creating the symbol.

boundp

324

car and cdr


Returns the first element of a list or a list containing all but the first element of a
list

(car list) and (cdr list)


If list is empty, car returns nil.
(car (a b c))
(car ((a b) c))
(car ())

returns A
returns (A B)
returns nil

If list is empty, cdr returns nil.


(cdr (a b c))
(cdr ((a b) c))
(cdr ())

returns (B C)
returns (C)
returns nil

When the list argument is a dotted pair (see cons), cdr returns the second element
without enclosing it in a list.
(cdr (a . b))
(cdr (1 . "Text"))

returns B
returns "Text"

AutoLISP supports concatenations of car and cdr up to four levels deep. The following
are valid functions:
caaaar

cadaar

cdaaar

cddaar

caaadr

cadadr

cdaadr

cddadr

caaar

cadar

cdaar

cddar

caadar

caddar

cdadar

cdddar

caaddr

cadddr

cdaddr

cddddr

caadr

caddr

cdadr

cdddr

caar

cadr

cdar

cddr

Appendix A AutoLISP Function Reference

325

These concatenations are the equivalent of nested calls to car and cdr. Each a represents
a call to car, and each d represents a call to cdr. For example:
(caar x)
(cdar x)
(cadar x)
(cadr x)
(cddr x)
(caddr x)

is equivalent to (car (car x))


is equivalent to (cdr (car x))
is equivalent to (car (cdr (car x)))
is equivalent to (car (cdr x))
is equivalent to (cdr (cdr x))
is equivalent to (car (cdr (cdr x)))

In AutoLISP, cadr is frequently used to obtain the Y coordinate of a 2D or 3D point (the


second element of a list of two or three reals). Likewise, caddr can be used to obtain the
Z coordinate of a 3D point. For instance, given the assignments
(setq pt2 (5.25 1.0))
(setq pt3 (5.25 1.0 3.0))

a 2D point
a 3D point

then
(car pt2)
(cadr pt2)
(caddr pt2)
(car pt3)
(cadr pt3)
(caddr pt3)

returns 5.25
returns 1.0
returns nil
returns 5.25
returns 1.0
returns 3.0

chr
Returns the conversion of an integer representing an ASCII character code into
a single-character string

(chr integer)
(chr 65)
(chr 66)
(chr 97)

returns "A"
returns "B"
returns "a"

This function is similar to the chr$ function in the BASIC language.

chr

326

client_data_tile
Associates application-managed data with a dialog box tile

(client_data_tile key clientdata)


The key argument is a string that specifies a tile. The key argument is case-sensitive. The
data is a string specified by the clientdata argument. An action expression or callback
function can refer to the string as $data.

close
Closes an open file

(close file-desc)
The file-desc argument is a file descriptor obtained from the open function. After a
close, the file descriptor is unchanged but is no longer valid. Data added to an open file
is not actually written until the file is closed. The close function returns nil if filedesc is valid, otherwise, it returns an error message.
For example, the following code counts the number of lines in the file somefile.txt and sets
the variable ct equal to that number.
(setq fil "SOMEFILE.TXT")
(setq x (open fil "r") ct 0)
(while (read-line x)
(setq ct (1+ ct))
)
(close x)

command
Executes an AutoCAD command

(command [arguments] ...)


The arguments argument represents AutoCAD commands and their options. The arguments to the command function can be strings, reals, integers, or points, as expected by
the prompt sequence of the executed command. A null string ("") is equivalent to press-

Appendix A AutoLISP Function Reference

327

ing ENTER on the keyboard. Invoking command with no argument is equivalent to pressing Esc and cancels most AutoCAD commands. The command function returns nil.
The command function evaluates each argument and sends it to AutoCAD in response to
successive prompts. It submits command names and options as strings, 2D points as lists
of two reals, and 3D points as lists of three reals. AutoCAD recognizes command names
only when it issues a Command prompt.
If you use the command function in an acad.lsp or MNL file, it should be called only from
within a defun statement. Use the S::STARTUP function to define commands that need
to be issued immediately when you begin a drawing session.
The following example sets two variables pt1 and pt2 equal to two point values 1,1 and
1,5. It then uses the command function to issue the LINE command and pass the two point
values.
(setq pt1 (1 1) pt2 (1 5))
(command "line" pt1 pt2 "")

If your application is to be used with foreign language versions of AutoCAD, command


names must be prefixed with an underscore (_) so they can be translated. If you are using
the dot prefix (to avoid using redefined commands), you can place the dot and underscore
in either order; both "._line" and "_.line" are valid.
Commands executed from the command function are not echoed to the command line if
the CMDECHO system variable (accessible from setvar and getvar) is set to 0.
The getxxx user-input functions (getangle, getstring, getint, getpoint, and so
on) cannot be used inside the command function. An attempt to do so results in the following message and terminates the function in progress.
error: AutoCAD rejected function
If user input is needed, issue the getxxx functions beforehand, or place them between
successive command function calls.
For AutoCAD commands that require the selection of an object (like the BREAK and
TRIM commands), you can supply a list obtained with entsel instead of a point to select
the object.
The AutoCAD DTEXT and SKETCH commands read the keyboard and digitizer directly
and therefore cannot be used with the AutoLISP command function. If the SCRIPT command is used with the command function, it should be the last function call in the
AutoLISP routine.
An UNDO Group is explicitly created around each command used with the command
fucntion. If a user enters U (or UNDO) after running an AutoLISP routine, only the last
command will be undone. Additional entries of UNDO will step backwards through the

command

328

commands used in that routine. If you want a group of commands to be considered a


group (or the entire routine), use the UNDO Begin and UNDO End options.
Using the PAUSE Symbol
If an AutoCAD command is active and the predefined symbol PAUSE is encountered as
an argument to the command function, the command function is suspended to allow direct
user input.
The PAUSE symbol is defined as a string consisting of a single backslash. You can use a
backslash instead of the PAUSE symbol. However, if the command function is invoked
from a menu item, the backslash suspends the reading of the menu item, which results in
partial evaluation of the AutoLISP expression. Also, the pause mechanism might require
a different trigger value in future versions of AutoLISP, so it is recommended that you
always use the PAUSE symbol rather than an explicit backslash.
When a backslash (\) is used in a string, it must be preceded by another backslash (\\).
If PAUSE is encountered when a command is expecting input of a text string or an attribute
value, AutoCAD pauses for input only if the TEXTEVAL system variable is nonzero. Otherwise, AutoCAD does not pause for user input but uses the value of the PAUSE symbol
(a single backslash) text.
When the command function pauses for user input, the function is considered active, so
the user cannot enter another AutoLISP expression to be evaluated.
The following is an example of using the PAUSE symbol (the layer NEW_LAY and the
block MY_BLOCK must exist in the drawing prior to testing this code):
(setq blk "MY_BLOCK")
(setq old_lay (getvar "clayer"))
(command "layer" "set" "NEW_LAY" "")
(command "insert" blk pause "" "" pause)
(command "layer" "set" old_lay "")

Appendix A AutoLISP Function Reference

329

The preceding code fragment sets the current layer to NEW_LAY, pauses for user selection of an insertion point for the block MY_BLOCK (which is inserted with X and Y scale
factors of 1) and pauses again for user selection of a rotation angle. The current layer is
then reset to the original layer.
If the command function specifies a PAUSE to the SELECT command and a PICKFIRST
set is active, the SELECT command obtains the PICKFIRST set without pausing for the
user.

The Radius and Diameter subcommands of the Dim prompt issue additional prompts in
some situations. This can cause a failure of AutoLISP programs written prior to Release
11 that use these commands.

cond
Serves as the primary conditional function for AutoLISP

(cond (test1 result1 ...) ...)


The cond function accepts any number of lists as arguments. It evaluates the first item in
each list (in the order supplied) until one of these items returns a value other than nil. It
then evaluates those expressions that follow the test that succeeded, and returns the value
of the last expression in the sublist. If there is only one expression in the sublist (that is,
if result is missing), the value of the test expression is returned.
The following example uses cond to perform an absolute value calculation:
(cond
((minusp a) (- a))
(t a)
)

If the variable a is set to the value 10, this returns 10.

cond

330

As shown, cond can be used as a case type function. It is common to use T as the last
(default) test expression. Heres another simple example. Given a user response string
in the variable s, this function tests the response and returns 1 if it is Y or y, 0 if it is N or
n, and nil otherwise.
(cond
((= s "Y") 1)
((= s "y") 1)
((= s "N") 0)
((= s "n") 0)
(t nil)
)

cons
Constructs basic lists

(cons new-first-element list)


The cons function takes an element (new-first-element) and a list, and returns the
addition of that element to the beginning of the list. The first element can be an atom or a
list.
(cons a (b c d))
(cons (a) (b c d))

returns (A B C D)
returns ((A) B C D)

The cons function also accepts an atom in place of the list argument, constructing a
structure known as a dotted pair. When displaying a dotted pair, AutoLISP prints a period,
or dot, between its first and second elements. You can use the cdr function to return the
second atom of a dotted pair.
(cons a 2)
(car (cons a 2))
(cdr (cons a 2))

returns (A . 2)
returns A
returns 2

A dotted pair is a special kind of list and is not accepted as an argument by some functions
that handle ordinary lists.

Appendix A AutoLISP Function Reference

331

cos
Returns the cosine of an angle expressed in radians

(cos ang)
(cos 0.0)
(cos pi)

returns 1.0
returns -1.0

cvunit
Converts a value from one unit of measurement to another

(cvunit value from to)


The value argument is the numeric value that you want to convert. It can also be a list
containing two or three numbers to be conrted (a 2D or 3D point). The from argument is
the unit that the value is being converted from, and to is the unit that the value is being
converted into. The from and to arguments can name any unit type found in the acad.unt
file.
If successful, cvunit returns the converted value. If either unit name is unknown (not
found in the acad.unt file), or if the two units are dimensionally incompatible (as in converting grams into years), cvunit returns nil.
(cvunit 1 "minute" "second") returns 60.0
(cvunit 1 "gallon" "furlong") returns nil
(cvunit 1.0 "inch" "cm")
returns 2.54
(cvunit 1.0 "acre" "sq yard") returns 4840.0
(cvunit (1.0 2.5) "ft" "in") returns (12.0 30.0)
(cvunit (1 2 3) "ft" "in") returns (12.0 24.0 36.0)

If you have several values to convert in the same manner, it is more efficient to convert
the value 1.0 once and then apply the resulting value as a scale factor in your own function
or computation. This works for all predefined units except temperature, where an offset
is involved as well.

cos

332

defun
Defines a function

(defun sym argument-list expr ...)


The defun function defines a function with the name sym (the function name is automatically quoted). Following the function name is a list of arguments (possibly void), optionally followed by a slash and the names of one or more local symbols for the function. The
slash must be separated from the first local symbol and from the last argument, if any, by
at least one space. If you dont declare any arguments or local symbols, you must supply
an empty set of parentheses after the function name.
The following argument-list examples show valid and invalid values:
(defun myfunc (x y) ...)
Function takes two arguments
(defun myfunc (/ a b) ...)
Function has two local symbols
(defun myfunc (x / temp) ...) One argument, one local symbol
(defun myfunc () ...)
No arguments or local symbols

You cannot define a function with multiple arguments of the same name. But you can
have one argument that defines a local variable with the same name as another local variable or with the same name as one of the arguments:
(defun fubar (a a / b) ...) Not legal
(defun fubar (a b / a a b) ...) Legal, but useless

If the argument/symbol list contains duplicate entries, the first occurrence of each name
is used and the following occurrences are ignored.
One or more expressions following the list of arguments and local symbols are evaluated
when the function is executed.
The defun function returns the name of the function being defined. When the defined
function is invoked, its arguments are evaluated and bound to the argument symbols. You
can use the local symbols within the function without changing their bindings at outer levels. The function returns the result of the last expression evaluated. All previous expressions have only side effects.

Appendix A AutoLISP Function Reference

333

The following examples define new functions with defun and show the values returned
by the new functions:
(defun add10 (x)
(+ 10 x)
)
(add10 5)
(add10 -7.4)

returns ADD10
returns 15
returns 2.6

and
(defun dots (x y / temp)
(setq temp (strcat x "..."))
(strcat temp y)
)
returns DOTS
(dots "a" "b")
returns "a...b"
(dots "from" "to")
returns "from...to"

Never use the name of a built-in function or symbol as sym. This makes the built-in function inaccessible. To get a list of built-in and previously defined functions, see atomsfamily.

See also Symbol and Function Handling.

dictadd
Adds a nongraphical object to the specified dictionary

(dictadd ename symbol newobj)


Adds the object newobj to the dictionary ename. The symbol argument is the key name
of the object to be added to the dictionary; symbol must be a unique name that does not
already exist in the dictionary. The object specified by newobj corresponds only to a nongraphical object.
As a general rule, each object added to a dictionary must be unique to that dictionary. This
is specifically a problem when adding group objects to the group dictionary. Adding the
same group object using different key names results in duplicate group names which can
send the dictnext function into an infinite loop.

dictadd

334

dictnext
Finds the next item in a dictionary

(dictnext ename [rewind])


The ename argument is an entity name that specifies a dictionary object to search.
When dictnext is used repeatedly, it returns the next entry in the specified dictionary
each time. The dictsearch function specifies an entry to retrieve. If the rewind argument is present and evaluates to a non-nil value, the dictionary is rewound and the first
entry in it is retrieved. When there are no more entries in the dictionary, nil is returned.
Deleted dictionary entries are never returned.
See namedobjdict for the master dictionary entity name.
Once you have begun stepping through the contents of a dictionary, passing a different
dictionary name to dictnext will cause the place to be lost in the original dictionary. In
other words, only one global iterator is maintained for use in this function.
If an entry is found, it is returned as a list of dotted pairs of DXF-type codes and values.

dictremove
Removes an entry from the specified dictionary

(dictremove ename symbol)


Removes the dictionary entry specified by symbol from the dictionary specified by
ename.
If ename is invalid or symbol is not found, dictremove returns nil. If successful, dictremove returns the entity name of the removed entry.

Appendix A AutoLISP Function Reference

335

By default, removing an entry from a dictionary does not delete it from the database. This
must be done with a call to entdel. Currently the exceptions to this rule are groups and
mlinestyles. The code that implements these features requires that the database and these
dictionaries be up to date, and therefore automatically deletes the entity when it is
removed (with dictremove) from the dictionary.
The dictremove function disallows the removal of an mlinestyle from the mlinestyle
dictionary if it is actively referenced by an mline in the database.

dictrename
Renames a dictionary entry

(dictrename ename oldsym newsym)


Renames a dictionary entrys key name from oldsym to newsym. The dictionary is specified by ename.
If the oldname is not present in the dictionary, ename is invalid, newname is invalid, or
newname is already present in the dictionary. dictrename returns nil.

dictsearch
Searches a dictionary for an item

(dictsearch ename symbol [setnext])


The ename argument is an entity name that specifies a dictionary object to search. The
symbol argument is a string that specifies the item within the dictionary.
If dictsearch finds an entry for the given item, it returns that entry in the format
described for dictnext. If no such entry is found, it returns nil.
Normally, dictsearch has no effect on the order of entries retrieved by dictnext.
However, if dictsearch is successful and the setnext argument is present and nonnil, the dictnext entry counter is adjusted so that the following dictnext call returns
the entry after the one returned by this dictsearch call.
The following example uses dictsearch to retrieve the definition list of the G2 group
(this code assumes that a group named G2 exists in the current drawing).
(setq grp (dictsearch (namedobjdict) "ACAD_GROUP"))

dictrename

336

(setq g2 (dictsearch (cdr (assoc -1 grp)) "G2"))

See namedobjdict for the master entity name.

dimx_tile and dimy_tile


Retrieves the dimensions of a tile in dialog box units

(dimx_tile key) and ( dimy_tile key)


The dimx_tile function returns the width of the tile, and dimy_tile returns its height.
For both functions, the key argument is a string that specifies the tile. The key argument
is case-sensitive.
The coordinates returned are the maximum allowed within the tile; because coordinates
are zero based, these functions return one less than the total X or Y dimension (X1 and
Y1). The dimx_tile and dimy_tile functions are provided for use with
vector_image, fill_image, and slide_image, which require you to specify absolute
tile coordinates.

distance
Returns the 3D distance between two points

(distance pt1 pt2)


(distance (1.0 2.5 3.0) (7.7 2.5 3.0)) returns 6.7
(distance (1.0 2.0 0.5) (3.0 4.0 0.5)) returns 2.82843

If one or both of the supplied points is a 2D point, then distance ignores the Z coordinates of any 3D points supplied and returns the 2D distance between the points as projected into the current construction plane.

Appendix A AutoLISP Function Reference

337

distof
Converts a string that represents a real (floating-point) value into a real value

(distof string [mode])


The mode argument specifies the units in which the string is formatted. The value should
correspond to values allowed for the AutoCAD system variable LUNITS, as shown in the
following table. If mode is omitted, distof uses the current value of LUNITS.
Linear units values
Mode value

String format

Scientific

Decimal

Engineering (feet and decimal inches)

Architectural (feet and fractional inches)

Fractional

The argument string must be a string that distof can parse correctly to the mode specified by mode. It can be in the same form that rtos returns, or in a form that AutoCAD
allows for keyboard entry. The distof and rtos functions are complementary. If you
pass distof a string created by rtos, distof is guaranteed to return a valid value, and
vice versa (assuming the mode values are the same).
The distof function treats modes 3 and 4 the same. That is, if mode specifies 3 (engineering) or 4 (architectural) units, and string is in either of these formats, distof
returns the correct real value.
If distof succeeds, it returns a real number; otherwise it returns nil.

distof

338

done_dialog
Terminates a dialog box

(done_dialog [status])
You must call done_dialog from within an action expression or callback function (see
action_tile).
If you specify the optional status argument, it must be a positive integer, which
start_dialog will return instead of returning 1 for OK or 0 for Cancel. The meaning
of any status value greater than 1 depends on your application.
The done_dialog function returns a two-dimensional point list that is the (X,Y) location
of the dialog box when the user exited it. You can pass this point to a subsequent
new_dialog call to reopen the dialog box in the user-selected location.
If you provide a callback for the button whose key is "accept" or "cancel" (usually
the OK and Cancel buttons), the callback must call done_dialog explicitly. If it doesnt,
the user can be trapped in the dialog box. If you dont provide an explicit callback for
these buttons and use the standard exit buttons, AutoCAD handles them automatically.
Also, an explicit AutoLISP action for the accept button must specify a status of 1
(or an application-defined value); otherwise, start_dialog returns the default value, 0,
which makes it appear as if the dialog box was canceled.

end_image
Ends creation of the currently active dialog box image

(end_image)
This function is the complement of start_image.

Appendix A AutoLISP Function Reference

339

end_list
Ends processing of the currently active dialog box list

(end_list)
This function is the complement of start_list.

entdel
Deletes objects (entities) or undeletes previously deleted objects

(entdel ename)
The entity specified by ename is deleted if it is currently in the drawing. The entdel
function undeletes the entity (restores it to the drawing) if it has been deleted previously
in this editing session. Deleted entities are purged from the drawing when the drawing is
exited. The entdel function can delete both graphical and non-graphical entities.
(setq e1 (entnext)) ;Sets e1 to the name of the first
;entity in the drawing
(entdel e1)
;Deletes entity e1
(entdel e1)
;Undeletes (restores) deleted entity e1

The entdel function operates only on main entities. Attributes and polyline vertices cannot be deleted independently of their parent entities. You can use the command function
to operate the ATTEDIT or PEDIT commands to achieve modify subentities.
You cannot delete entities within a block definition. However, you can completely redefine a block definition, minus the entity you want deleted, with entmake.

end_list

340

entget
Retrieves an objects (entitys) definition data

(entget ename [applist])


The entget function returns a list containing the entity definition data of the entity
ename. This applies to both graphical and non-graphical entities. If you supply applist,
an optional list of registered application names, entget also returns the extended data
associated with the specified applications.
The data returned by entget is coded as an association list, from which you can extract
items by using the assoc function. Objects in the list are assigned AutoCAD DXF group
codes for each part of the entity data.
Assume that the last object created in the drawing is a line drawn from point (1,2) to point
(6,5). You can retrieve the entity name of the last object with the entlast function, and
pass that name to entget.
(entget (entlast))

This might return the following:


((-1 . <Entity name: 60000014>) Entity name
(0 . "LINE")
Object type
(8 . "0")
Layer
(10 1.0 2.0 0.0)
Start point
(11 6.0 5.0 0.0)
Endpoint
)

The DXF group codes used by AutoLISP differ slightly from the group codes in a DXF
file.
As with DXF, entity header items (color, linetype, thickness, the attributes-follow flag,
and the entity handle) are exported only if they have nondefault values. Unlike DXF,
optional entity definition fields are exported whether they are equal to their defaults or
not. This simplifies processing. Programs can always assume these fields to be present for
general algorithms that operate on them. Also unlike DXF, associated X, Y, and Z coordinates are grouped together into one point list, as in (10 1.0 2.0 3.0), rather than appearing
as separate 10, 20, and 30 groups.

Appendix A AutoLISP Function Reference

341

The 1 item at the start of the list contains the entity name of this entity. The individual
dotted pairs that represent the values can be extracted by assoc, using cdr to pull out
their values.
The sublists for points are not dotted pairs like the rest. The convention is that the cdr of
the sublist is the groups value. Because a point is a list of two (or three) reals, the entire
group is a three- (or four-) element list. The cdr of the group is the list representing the
point, so the convention that cdr always returns the value is preserved.
When writing functions to process these entity lists, be sure to make them insensitive to
the order of the sublists. Use assoc to guarantee this. The 1 group containing the entitys
name allows modification operations to accept the entity list, and avoids the need to keep
the entity name in a parallel structure. A seqend entity at the end of a polyline or a set of
attributes contains a 2 group whose cdr is the entity name of the header of this entity.
This allows the header to be found from a subentity by walking forward to the Seqend and
then using the cdr of the 2 group as the entity name to retrieve the associated main
entity.

Before performing an entget on vertex entities, you should read or write the polyline
entitys header. If the most recently processed polyline entity is different from the one to
which the vertex belongs, width information (the 40 and 41 groups) can be lost.

All points associated with an object are expressed in terms of that objects Object Coordinate System (OCS). For point, line, 3dline, 3dface, 3dpolyline, 3dmesh, and dimension
objects, the OCS is equivalent to the WCS (the object points are World points). For all
other objects, the OCS can be derived from the WCS and the objects extrusion direction
(its 210 group). When working with objects that have been drawn using coordinate systems other than the WCS, you might need to convert the points to the WCS or to the current UCS by using the trans function.

entget

342

entlast
Returns the name of the last nondeleted main object (entity) in the drawing

(entlast)
The entlast function is frequently used to obtain the name of a new entity that has just
been added with the command function. The entity need not be on the screen or on a
thawed layer to be selected.
Sets e1 to the name of the last main
entity in the drawing
(setq e2 (entnext e1))
Sets e2 to nil (or to an attribute or vertex
subentity name)
(setq e1 (entlast))

If your application requires the name of the last nondeleted entity (main entity or subentity), define a function such as the following and call it instead of entlast.
(defun lastent (/ a b)
(if (setq a (entlast))
Gets last main entity
(while (setq b (entnext a)) If subentities follow, loops
(setq a b)

until there are no more


subentities

)
)
a
)

Returns last main entity


or subentity

entmake
Creates a new entity (graphical object) in the drawing

(entmake [elist])
The elist argument must be a list of entity definition data in a format similar to that
returned by the entget function. The elist argument must contain all of the information necessary to define the entity. The entmake function can define both graphical and
nongraphical entities. If any required definition data is omitted, entmake returns nil and
the entity is rejected. If you omit optional definition data (such as the layer), entmake
uses the default value.
If entmake successfully creates a new entity, it returns the entitys list of definition data.
If entmake is unable to create the entity, it returns nil.
One method of creating a new entity is by obtaining an entitys definition data with the
entget function, modifying it, and then passing the revised data to the entmake func-

Appendix A AutoLISP Function Reference

343

tion. Before creating a new entity, entmake verifies that a valid layer name, linetype
name, and color are supplied. If a new layer name is introduced, entmake automatically
creates the new layer. The entmake function also checks for block names, dimension
style names, text style names, and shape names if the entity type requires them.
The entity type (for example, CIRCLE or LINE) must be the first or second field of the
elist. If it is the second field, it can be preceded only by the entity name. This is the format returned by entget. In such cases, it ignores the entity name when the new entity is
created. If the elist contains an entity handle, it also is ignored.
The following code creates a red circle, centered at (4,4) with a radius of 1. The optional
layer and linetype fields have been omitted and therefore assume default values.
(entmake
((0 . "CIRCLE")
Entity type
(62 . 1)
Color
(10 4.0 4.0 0.0)
Center point
(40 . 1.0)
Radius
)
)

Objects created on a frozen layer are not regenerated until the layer is thawed.
Complex Entities
A complex entity (a block definition, a polyline, or a block reference containing
attributes) can be created by several entmake calls to define its subentities (attributes or
vertices). When entmake sees that a complex entity is being created, it creates a temporary file to gather the definition data. For each entmake, a check is performed to see if
the temporary file exists; if so, the new data is appended to the file. When the definition
of the complex entity is complete (by appending the appropriate seqend or endblk entity),
the supplied data is rechecked and the complex entity is added to the drawing. Completion
of a block definition (entmake of an endblk) returns the blocks name rather than the
entity data list normally returned.
You cannot create viewport objects with entmake.

entmake

344

If data is received that is invalid for that entity type, the entity is rejected as well as the
entire complex entity. A block definition cannot be nested, nor can it reference itself.
However, it can contain references to other block definitions. All entities of a complex
entity can exist in either model space or paper space, but not both.
A group 66 code is honored only for insert objects (meaning attributes follow). For
polyline entities, the group 66 code is forced to a value of 1 (meaning vertices follow), and
for all other entities it takes a default of 0. The only entity that can follow a polyline entity
is a vertex entity.
No portion of a complex entity is displayed on your drawing until its definition is complete. You can cancel the creation of a complex entity by entering entmake with no arguments. This clears the temporary file and returns nil.
The block and endblk entities can be used to create a new block definition. Newly created
blocks are automatically entered into the symbol table where they can be referenced.
Applications can represent polygons with an arbitrarily large number of sides in polyface
meshes. However, the AutoCAD entity structure imposes a limit on the number of vertices that a given face entity can specify. You can represent more complex polygons by
dividing them into triangular wedges. AutoCAD represents triangular wedges as four-vertex faces where two adjacent vertices have the same value. Their edges should be made
invisible to prevent visible artifacts of this subdivision from being drawn. The PFACE
command performs this subdivision automatically, but when applications generate polyface meshes directly, the applications must do this themselves.
The number of vertices per face is the key parameter in this subdivision process. The
PFACEVMAX system variable provides an application with the number of vertices per
face entity. This value is read-only and is set to 4.

When entmake creates a block, it can overwrite an existing block. The entmake function
does not check for name conflicts in the block definitions table, so before you use it, use
the tblsearch function to ensure that the name of the new block is unique. However,
using entmake to redefine anonymous blocks, as described in the following section, can
be useful.

Anonymous Blocks
The block definitions table in a drawing can contain anonymous blocks. Anonymous
blocks are created to support hatch patterns and associative dimensioning. They can also
be created by entmake for the applications own purposes, usually to contain entities that
the user cannot access directly.
The group code 2 (block name) of a dimension entity is optional for the entmake function. If the block name is omitted from the entity definition list, AutoCAD creates a new
one. Otherwise, AutoCAD creates the dimension using the name provided.

Appendix A AutoLISP Function Reference

345

The name (group 2) of an anonymous block is *Unnn, where nnn is a number generated
by AutoCAD. Also, the low-order bit of an anonymous blocks Block type flag (group 70)
is set to 1. When entmake creates a block whose name begins with * and whose anonymous bit is set, AutoCAD treats this as an anonymous block and assigns it a name. Characters following the * in the name string passed to entmake are ignored. After the block
is created, entmake returns its name. If you are creating the block by multiple entmake
calls, it returns the name after a successful call of
(entmake "endblk")

Whenever a drawing is opened, all unreferenced anonymous blocks are purged from the
block definitions table. Referenced (inserted) anonymous blocks are not purged. You can
use entmake to create a block reference (Insert) to an anonymous block (you cannot pass
an anonymous block to the INSERT command). You can also use entmake to redefine the
block. The entities in a block (but not the block entity itself) can be modified with entmod.
Although a referenced anonymous block becomes permanent, the numeric portion of its
name can change between drawing sessions. Applications cannot rely on anonymous
block names remaining constant.

entmakex
Makes a new object or entity, gives it a handle and entity name (but, does not
assign an owner), and then returns the new entity name

(entmakex [elist])
The elist argument must be a list of entity definition data in a format similar to that
returned by the entget function. The elist argument must contain all of the information necessary to define the entity or object. The entmakex function can define both
graphical and nongraphical objects. If any required definition data is omitted, entmakex
returns nil and the object is rejected. If you omit optional definition data (such as the
layer), entmakex uses the default values.
If entmakex successfully creates a new entity, it returns the entity name. If entmakex is
unable to create the entity, it returns nil.

Objects and entities without owners are not written out to .dwg or .dxf files. Be sure to set
an owner at some point after using entmakex. For example, you can use dictadd to set
a dictionary to own an object.

entmakex

346

entmod
Modifies the definition data of an object (entity)

(entmod elist)
The entmod function is passed a list (elist) in the format returned by entget, and it
updates the database information for the entity name specified by the 1 group in elist.
The primary mechanism through which AutoLISP updates the database is by retrieving
entities with entget, modifying the list defining an entity, and updating the entity in the
database with entmod. The entmod function can modify both graphical and nongraphical
objects.
(setq en (entnext))
(setq ed (entget en))
(setq ed
(subst (cons 8 "0")
(assoc 8 ed)
ed
)
)
(entmod ed)

Sets en to the name of the first entity in the drawing


Sets ed to the entity data of entity en
Changes the layer group in ed to layer 0

Modifies entity ens layer in drawing

The entmod function imposes some restrictions on the changes it makes. First of all, an
entitys type and handle cannot be changed. If you want to do this, just entdel it and
make a new entity with the command or entmake functions. All objects referenced by the
entity list must be known to AutoCAD before the entmod is executed. Thus text style,
linetype, shape, and block names must be defined in a drawing before they can be used in
an entity list with entmod. An exception to this is layer names: entmod creates a new
layer with the standard defaults used by the New option of LAYER if a previously undefined layer is named in an entity list.
For entity fields with floating-point values (such as thickness), entmod accepts integer
values and converts them to floating point. Similarly, if you supply a floating-point value
for an integer entity field (such as color number), entmod truncates it and converts it to
an integer.
The entmod function performs consistency checking on the list supplied to it. If a serious
error is detected, the database is not updated and nil is returned. Otherwise, entmod
returns the list given to it as its argument. entmod cannot change internal fields such as
the entity name in the 2 group of a seqend entityattempts to change such fields are
ignored.
When entmod updates a main entity, it modifies the entity and updates its image on screen
(including subentities). When entmod updates a subentity (a polyline vertex or a block

Appendix A AutoLISP Function Reference

347

attribute), the subentity is updated in the database but the image on the screen is not redisplayed. After all modifications are made to a given entitys subentities, the entupd function can be used to update the image on the screen.
You cannot use the entmod function to modify a viewport entity. You can change an
entitys space visibility field to 0 or 1 (except for viewport objects). If you use entmod to
modify an entity within a block definition, the modification affects all instances of the
block in the drawing.
Before performing an entmod on vertex entities, you should read or write the polyline
entitys header. If the most recently processed polyline entity is different from the one to
which the vertex belongs, width information (the 40 and 41 groups) can be lost.

You can use entmod to modify entities within a block definition, but doing so can create
a self-referencing block, which will cause AutoCAD to stop.

entnext
Returns the name of the next object (entity) in the drawing

(entnext [ename])
If entnext is called with no arguments, it returns the entity name of the first nondeleted
entity in the database. If entnext is called with an entity name argument ename, it
returns the entity name of the first nondeleted entity following ename in the database. If
there is no next entity in the database, it returns nil. The entnext function returns both
main entities and subentities.
The entities selected by ssget are main entities, not attributes of blocks or vertices of
polylines. You can access the internal structure of these complex entities by walking
through the subentities with entnext. Once you obtain a subentitys name, you can operate on it like any other entity. If you obtain the name of a subentity with entnext, you
can find the parent entity by walking forward with entnext until a seqend entity is found,
then extracting the 2 group from that entity, which is the main entitys name.
(setq e1 (entnext))
(setq e2 (entnext e1))

Sets e1 to the name of the first entity in the drawing


Sets e2 to the name of the entity following e1

entnext

348

entsel
Prompts the user to select a single object (entity) by specifying a point

(entsel [msg])
The entsel function returns a list whose first element is the entity name of the chosen
object and whose second element is the coordinates (in terms of the current UCS) of the
point used to pick the object. If a string is specified for msg, that string is used to ask the
user for the object. Otherwise, the prompt defaults to Select object.
The pick point returned by entsel does not represent a point that lies on the selected
object. The point returned is the location of the crosshairs at the time of selection. The
relationship between the pick point and the object will vary depending on the size of the
pickbox and the current zoom scale.
A list of the form returned by entsel can be supplied to AutoCAD in response to any of
its object selection prompts. It is treated by AutoCAD as a pick of the designated object
by pointing to the specified point.
The following AutoCAD command sequence illustrates the use of the entsel function
and the list returned:
Command: line
From point: 1,1
To point: 6,6
To point: ENTER
Command: (setq e (entsel "Please choose an object: "))
Please choose an object: 3,3
(<Entity name: 60000014> (3.0 3.0 0.0))
Sometimes when operating on objects, you will want to simultaneously select an object
and specify the point by which it was selected. Examples of this in AutoCAD can be
found in Object Snap and in the BREAK, TRIM, and EXTEND commands. The entsel
function allows AutoLISP programs to perform this operation. It selects a single object,
requiring the selection to be by a point pick. The current Osnap setting is ignored by this
function (no object snap) unless you specifically request it while you are in the function.
The entsel function honors key words from a preceding call to initget.

Appendix A AutoLISP Function Reference

349

entupd
Updates the screen image of an object (entity)

(entupd ename)
When a polyline vertex or block attribute is modified with entmod, the entire complex
entity is not updated on the screen. The entupd function can be used to cause a modified
polyline or block to be updated on the screen. This function can be called with the entity
name of any part of the polyline or block; it need not be the head entity. While entupd is
intended for polylines and blocks with attributes, it can be called for any entity. It always
regenerates the entity on the screen, including all subentities.
If entupd is used on a nested entity (an entity within a block) or on a block that contains
nested entities, some of the entities might not be regenerated. To ensure complete regeneration, you must invoke the REGEN command.
Assuming that the first entity in the drawing is a polyline with several vertices, then
(setq e1 (entnext))
Sets e1 to the polylines entity name
(setq e2 (entnext e1)) Sets e2 to its first vertex
(setq ed (entget e2)) Sets ed to the vertex data
(setq ed
(subst (10 1.0 2.0)
(assoc 10 ed)
Changes the vertexs location in ed
ed
to point (1,2)
)
)
(entmod ed)
Moves the vertex in the drawing
(entupd e1)
Regenerates the polyline entity e1

eq
Determines whether two expressions are identical

(eq expr1 expr2)


The eq function determines whether expr1 and expr2 are bound to the same object (by
setq, for example). Returns T if the two expressions are identical, and returns nil otherwise.
You can use this function to determine whether two lists are the same. For example, given
the assignments
(setq f1 (a b c))

entupd

350

(setq f2 (a b c))
(setq f3 f2)

then
(eq f1 f3) returns nil, f1 and f3 are not the same list
(eq f3 f2) returns T, f3 and f2 are exactly the same list

See also the = (equal to) and equal functions

equal
Determines whether two expressions are equal

(equal expr1 expr2 [fuzz])


The equal function determines whether expr1 and expr2 evaluate to the same thing.
When comparing two real numbers (or two lists of real numbers, as in points), the two
identical numbers can differ slightly if different methods are used to calculate them.
Therefore, you can use an optional numeric argument, fuzz, to specify the maximum
amount by which expr1 and expr2 can differ and still be considered equal.
For example, given the assignments
(setq f1 (a b c))
(setq f2 (a b c))
(setq f3 f2)
(setq a 1.123456)
(setq b 1.123457)

then
(equal f1 f3)
returns T
(equal f3 f2)
returns T
(equal a b)
returns nil
(equal a b 0.000001)
returns T

Although two lists that the equal function finds the same might not be found so using the
eq function, atoms that are found to be the same using the equal function are always
found to be the same if you use the eq function. However, if the eq function finds that the
list or atoms are the same, the equal function also finds them to be the same.

See also the = (equal to)and eq functions

Appendix A AutoLISP Function Reference

351

*error*
A user-definable error-handling function

(*error* string)
If *error* is not nil, it is executed as a function whenever an AutoLISP error condition
exists. AutoCAD passes one argument to *error*, which is a string containing a description of the error.
The following function does the same thing that the AutoLISP standard error handler
does. Print error and the description.
(defun *error* (msg)
(princ "error: ")
(princ msg)
(princ)
)

Your *error* function can include calls to the command function without arguments (for
example, (command)). This will cancel a previous AutoCAD command called with the
command function.

eval
Returns the result of evaluating an AutoLISP expression

(eval expr)
For example, given the assignments
(setq a 123)
(setq b a)

then
(eval 4.0)
(eval (abs -10))
(eval a)
(eval b)

returns 4.0
returns 10
returns 123
returns 123

*error*

352

exit
Forces the current application to quit

(exit)
If exit is called, it returns the error message quit/exit abort and returns to the AutoCAD
Command prompt.

See also the quit function

exp
Returns the constant e (a real number) raised to a specified power (the natural
antilog)

(exp num)
(exp 1.0)
(exp 2.2)
(exp -0.4)

returns 2.71828
returns 9.02501
returns 0.67032

expand
Allocates node space by requesting a specified number of segments

(expand int)

Appendix A AutoLISP Function Reference

353

expt
Returns a number raised to a specified power

(expt number power)


If both arguments are integers, the result is an integer. Otherwise, the result is a real. These
are examples:
(expt 2 4)
(expt 3.0 2.0)

returns 16
returns 9.0

fill_image
Draws a filled rectangle in the currently active dialog box image tile

(fill_image x1 y1 wid hgt color)


The fill_image function must be used between start_image and end_image calls.
The color parameter is an AutoCAD color number or one of the logical color numbers
shown in the following table.
Symbolic names for the color attribute
Color number

ADI mnemonic

Description

BGLCOLOR

Current background of the AutoCAD graphics


screen

15

DBGLCOLOR

Current dialog box background color

16

DFGLCOLOR

Current dialog box foreground color (text)

18

LINELCOLOR

Current dialog box line color

The first (upper-left) corner of the rectangle is located at (x1,y1) and the second (lowerright) corner is located the relative distance (wid,hgt) from the first corner (wid and hgt
must be positive values). The origin (0,0) is the upper-left corner of the image. You can
obtain the coordinates of the lower-right corner by calling the dimension functions
dimx_tile and dimy_tile.

expt

354

findfile
Searches the AutoCAD library path for the specified file

(findfile filename)
The findfile function makes no assumption about the file type or extension of filename. If filename does not specify a drive/directory prefix, findfile searches the
AutoCAD library path. If a drive/directory prefix is supplied, findfile looks only in
that directory. The findfile function always returns a fully qualified drive/directory/file
name or nil if the specified file is not found.
Consider the following examples. If the current directory is /acad and it contains the file
abc.lsp.
(findfile "abc.lsp") returns "/acad/abc.lsp"

If you are editing a drawing in the /acad/drawings directory, the ACAD environment variable is set to /acad/support, and the file xyz.txt exists only in the /acad/support directory.
(findfile "xyz.txt") returns "/acad/support/xyz.txt"

Appendix A AutoLISP Function Reference

355

If the file nosuch is not present in any of the directories on the library search path.
(findfile "nosuch") returns nil

The fully qualified name returned by findfile is suitable for use with the open function.

fix
Returns the conversion of a real number into the nearest smaller integer

(fix num)
The fix function truncates number to the nearest integer by discarding the fractional portion.
(fix 3)
(fix 3.7)

returns 3
returns 3

If number is larger than the largest possible integer (+2,147,483,647 or 2,147,483,648


on a 32-bit platform), fix returns a truncated real (although integers transferred between
AutoLISP and AutoCAD are restricted to 16-bit values).

float
Returns the conversion of a number into a real number

(float num)
(float 3)
(float 3.75)

returns 3.0
returns 3.75

fix

356

foreach
Evaluates expressions for all members of a list

(foreach name lst expr...)


Steps through lst, assigning each element to name, and evaluates each expr for every
element in the list. Any number of exprs can be specified. The foreach function returns
the result of the last expr evaluated.
(foreach n (a b c) (print n))

is equivalent to
(print a)
(print b)
(print c) and returns c

except that foreach returns the result of only the last expression evaluated.

gc
Forces a garbage collection, which frees up unused nodes

(gc)

gcd
Returns the greatest common denominator of two integers

(gcd int1 int2)


The int1 and int2 arguments must be integers greater than 0.
(gcd 81 57)
(gcd 12 20)

returns 3
returns 4

Appendix A AutoLISP Function Reference

357

get_attr
Retrieves the DCL value of a dialog box attribute

(get_attr key attribute)


The key argument is a string that specifies the tile and is case-sensitive. The attribute
argument specifies the name of the attribute as it appears in the tiles DCL description.
Both the key and attribute arguments are strings. The value returned is the attributes
initial value as specified in its DCL description; it does not reflect changes to the state of
the tile that come about with user input or set_tile calls. Returns the attribute value as
a string.

get_tile
Retrieves the current run-time value of a dialog box tile

(get_tile key)
The key argument is a string that specifies the tile and is case-sensitive. It returns the tiles
value as a string.

getangle
Pauses for user input of an angle, and returns that angle in radians

(getangle [pt] [msg])


The pt argument is a 2D base point in the current UCS, and msg is a string to be displayed
as a prompt. The pt argument, if specified, is assumed to be the first of two points, so that
the user can show AutoLISP the angle by pointing to one other point. You can supply a
3D base point, but the angle is always measured in the current construction plane.
The getangle function measures angles with the zero-radian direction (set by the ANGBASE system variable) with angles increasing in the counterclockwise direction. The
returned angle is expressed in radians with respect to the current construction plane (the
XY plane of the current UCS, at the current elevation).

get_attr

358

The user can specify an angle by entering a number in the AutoCAD current angle units
format. Although the current angle units format might be in degrees, grads, or some other
unit, this function always returns the angle in radians. The user can also show AutoLISP
the angle by pointing to two 2D locations on the graphics screen. AutoCAD draws a rubber-band line from the first point to the current crosshair position to help you visualize the
angle.
It is important to understand the difference between the input angle and the angle returned
by getangle. Angles that are passed to getangle are based on the current settings of
ANGDIR and ANGBASE. However, once an angle is provided, it is measured in a counterclockwise direction (ignoring ANGDIR) with zero radians as the current setting of
ANGBASE. The following code examples show how different arguments can be used.
(setq ang (getangle))
(setq ang (getangle (1.0 3.5)))
(setq ang (getangle "Which way? "))
(setq ang (getangle (1.0 3.5) "Which way? "))

The user cannot enter another AutoLISP expression as the response to a getangle
request.

See also the illustration and comparison to the getorient function

getcfg
Retrieves application data from the AppData section of the acad.cfg file

(getcfg cfgname)
The cfgname argument is a string (maximum length of 347 characters) naming the section and parameter value to retrieve. If cfgname is not valid, getcfg returns nil. The
cfgname argument must be a string of this form:
"AppData/application_name/section_name/.../param_name"

For example, assuming that the WallThk parameter in the AppData/ArchStuff section has
a value of 8,
(getcfg "AppData/ArchStuff/WallThk") returns "8"

Appendix A AutoLISP Function Reference

359

See also the setcfg function

getcname
Retrieves the localized or English name of an AutoCAD command

(getcname cname)
The cname argument specifies the localized or underscored English command name,
which must be 64 characters or less in length. If cname is not preceded by an underscore
(assumed to be the localized command name), getcname returns the underscored English
command name. If cname is preceded by an underscore, getcname returns the localized
command name. This function returns nil if cname is not a valid command name.
For example, in a French version of AutoCAD, the following is true.
(getcname "ETIRER")
returns "_STRETCH"
(getcname "_STRETCH") returns "ETIRER"

getcorner
Pauses for user input of a rectangles second corner

(getcorner pt [msg])
The getcorner function requires a base point argument, pt, based on the current UCS,
and draws a rectangle from that point as the user moves the crosshairs on the screen. The
msg argument is a string to be displayed as a prompt. The getcorner function returns a
point in the current UCS, similar to getpoint. If the user supplies a 3D point, its Z coordinate is ignored. The current elevation is used as the Z coordinate.
The user cannot enter another AutoLISP expression as the response to a getcorner
request.

getcname

360

getdist
Pauses for user input of a distance

(getdist [pt] [msg])


The pt argument is a 2D or 3D base point in the current UCS. If provided, pt is used as
the first of the two points and the user is prompted for only the second point. The msg
argument is a string to be displayed as a prompt.
The user can specify the distance by selecting two points, or the second point if a base
point is provided. The user can also specify a distance by entering a number in the
AutoCAD current distance units format. Although the current distance units format might
be in feet and inches (architectural), the getdist function always returns the distance as
a real.
The getdist function draws a rubber-band line from the first point to the current
crosshair position to help the user visualize the distance.
If a 3D point is provided, the returned value is a 3D distance. However, setting the 64 bit
of the initget function instructs getdist to ignore the Z component of 3D points and
to return a 2D distance.
(setq dist (getdist))
(setq dist (getdist (1.0 3.5)))
(setq dist (getdist "How far "))
(setq dist (getdist (1.0 3.5) "How far? "))

The user cannot enter another AutoLISP expression as the response to a getdist request.

getenv
Returns the string value assigned to a system environment variable

(getenv variable-name)
The variable-name argument is a string specifying the name of the variable to be read.
If this variable does not exist, getenv returns nil. You must enclose the variable name
in quotation marks. Environment variable names must be spelled and cased exactly as
they are stored in the system registry.

Appendix A AutoLISP Function Reference

361

For example, if the system environment variable ACAD is set to /acad/support and there
is no variable named NOSUCH, then
(getenv "ACAD")
returns "/acad/support"
(getenv "NOSUCH") returns nil

Assuming that the MaxArray environment variable was set to 10000,


(getenv "MaxArray") returns "10000"

See also the setenv function

getfiled
Prompts the user for a file name with the standard AutoCAD file dialog box, and
returns that file name

(getfiled title default ext flags)


The title argument specifies the dialog box label, default specifies a default file name
to use (which can be a null string [""]), and ext is the default file name extension. If ext
is passed as a null string [""], it defaults to * (all file types). If the file type dwg is included
in the ext argument, the getfiled function displays an image preview in the dialog. The
flags argument is an integer value (a bit-coded field) that controls the behavior of the
dialog box. To set more than one condition at a time, add the values together to create a
flags value between 0 and 15.
Flag value = 1
(bit 0)

Set this bit when you prompt for the name of a new file to create.
Do not set this bit when you prompt for the name of an existing file
to open. In the latter case, if the user enters the name of a file that

getfiled

362

doesnt exist, the dialog box displays an error message at the bottom
of the box.
If this bit is set and the user chooses a file that already exists,
AutoCAD displays an alert box and offers the choice of proceeding
with or canceling the operation.
Flag value = 4
(bit 2)

Lets the user enter an arbitrary file name extension, or no extension


at all.
If this bit is not set, getfiled accepts only the extension specified
in the ext argument and appends this extension to the file name if
the user doesnt enter it in the File text box.

Flag value = 8
(bit 3)

If this bit is set and bit 0 is not set, getfiled performs a library
search for the file name entered. If it finds the file and its directory
in the library search path, it strips the path and returns only the file
name. (It doesnt strip the path name if it finds that a file of the same
name is in a different directory.)
If this bit is not set, getfiled returns the entire file name, including the path name.
Set this bit if you use the dialog box to open an existing file whose
name you want to save in the drawing (or other database).

If the dialog box obtains a file name from the user, getfiled returns a string that specifies the file name; otherwise, it returns nil.
The following call to getfiled displays the Select a Lisp File dialog box:
(getfiled "Select a Lisp File" "/acadr14/support/" "lsp" 8)

Appendix A AutoLISP Function Reference

363

set by the title argument

set by the path name


portion of the default
argument (if default
doesnt specify a path,
this is initially the current
directory)
set by the file name portion of
the default argument

set by the ext argument


Sample getfile dialog box

The getfiled function displays a dialog box containing a list of available files of a specified extension type. You can use this dialog box to browse through different drives and
directories, select an existing file, or specify the name of a new file.

getint
Pauses for user input of an integer, and returns that integer

(getint [msg])
The msg argument is an optional string to be displayed as a prompt. The getint function
returns the integer value or nil.
(setq num (getint))
(setq num (getint "Enter a number: "))

Values passed to getint can range from 32,768 to +32,767. The user cannot enter
another AutoLISP expression as the response to a getint request.

See also the if function

getint

364

getkword
Pauses for user input of a key word, and returns that key word

(getkword [msg])
Valid key words are set prior to the getkword call with the initget function. The msg
argument is a string to be displayed as a prompt. The getkword function returns the key
word matching the user input as a string. AutoCAD tries again if the input is not a key
word. If the input is null ( ENTER ), getkword returns nil (if null input is allowed). This
function also returns nil if it wasnt preceded by a call to initget that established one
or more key words.
The following example shows an initial call to initget that sets up a list of key words
(Yes and No) and disallows null input (bits value equal to 1) to the following getkword
call:
(initget 1 "Yes No")
(setq x (getkword "Are you sure? (Yes or No) "))

This code prompts the user for input and sets the symbol x to either Yes or No, depending
on the response. If the response does not match any of the key words, or if the user gives
a null reply, AutoCAD prompts again with the string supplied in the msg argument. If no
msg argument is provided, AutoCAD supplies this prompt:
Try again:
The user cannot enter another AutoLISP expression as the response to a getkword
request.

See also the if function

getorient
Pauses for user input of an angle, and returns that angle in radians

(getorient [pt] [msg])


This function is similar to the getangle function, except that the angle value returned by
getorient is unaffected by the system variables ANGBASE and ANGDIR. However, the
angle input by the user is still based on the current settings of ANGDIR and ANGBASE.

Appendix A AutoLISP Function Reference

365

The pt argument is a 2D base point in the current UCS, and msg is a string to be displayed
as a prompt. The pt argument, if specified, is assumed to be the first of two points, allowing the user to show AutoLISP the angle by pointing to one other point. You can supply
a 3D base point, but the angle is always measured in the current construction plane.
The getorient function measures angles with the zero-radian direction to the right
(east) and angles that are increasing in the counterclockwise direction. As with
getangle, getorient expresses the returned angle in radians, with respect to the current construction plane. Angles input to getorient are based on the current settings of
ANGDIR and ANGBASE. However, once an angle is provided, it is measured in a counterclockwise direction, with zero radians being to the right (ignoring ANGDIR and ANGBASE). Therefore, some conversion must take place if you select a different zero-degree
base or a different direction for increasing angles by using the UNITS command or the
ANGBASE and ANGDIR system variables.
Use getangle when you need a rotation amount (a relative angle). Use getorient to
obtain an orientation (an absolute angle).
The user cannot enter another AutoLISP expression as the response to a getorient
request.

See also the getangle and if functions

getpoint
Pauses for user input of a point, and returns that point

(getpoint [pt] [msg])


The pt argument is a 2D or 3D base point in the current UCS, and msg is a string to be
displayed as a prompt. The user can specify a point by pointing or by entering a coordinate
in the current units format. If the pt argument is present, AutoCAD draws a rubber-band
line from that point to the current crosshair position. The returned value is a 3D point
expressed in terms of the current UCS.
(setq p (getpoint))
(setq p (getpoint "Where? "))
(setq p (getpoint (1.5 2.0) "Second point: "))

The user cannot enter another AutoLISP expression as the response to a getpoint
request.

getpoint

366

See also the getcorner and if functions

getreal
Pauses for user input of a real number, and returns that real number

(getreal [msg])
The msg argument is a string to be displayed as a prompt.
(setq val (getreal))
(setq val (getreal "Scale factor: "))

The user cannot enter another AutoLISP expression as the response to a getreal request.

getstring
Pauses for user input of a string, and returns that string

(getstring [cr] [msg])


If the cr argument is supplied and is not nil, the input string can contain blanks (and
must be terminated by ENTER ). Otherwise, the input string is terminated by space or
ENTER . The msg argument is a string to be displayed as a prompt.
If the string is longer than 132 characters, it returns only the first 132 characters of the
string. If the input string contains the backslash character (\), it is converted to two backslash characters (\\). This is done so that the returned value can contain file name paths
that can be used by other functions.
(setq s (getstring "Whats your first name? "))

responding John sets s to "John"


(setq s (getstring T "Whats your full name? "))

responding John Doe sets s to "John Doe"


(setq s (getstring "Enter filename: "))

responding \acad\mydwg sets s to "\\acad\\mydwg"


The user cannot enter another AutoLISP expression as the response to a getstring
request.

Appendix A AutoLISP Function Reference

367

See also the getkword function for a routine that requires the user to enter one of
several known options (key words).

getvar
Retrieves the value of an AutoCAD system variable

(getvar varname)
The varname argument is a string that names the system variable. If varname is not a
valid system variable, getvar returns nil.
For example, assuming that the fillet radius is set to 0.25 units,
(getvar "FILLETRAD")

returns 0.25

You can find a list of the current AutoCAD system variables in the Command Reference.

See also the setvar function

graphscr
Displays the AutoCAD graphics screen

(graphscr)
The graphscr function always returns nil.
This function is equivalent to the GRAPHSCR command or to pressing the Flip Screen
function key. The textscr function is the complement of graphscr.

getvar

368

grclear
Clears the current viewport (obsolete function)

(grclear)
To preserve limited compatibility with previous releases, the grclear function returns
nil.

grdraw
Draws a vector between two points, in the current viewport

(grdraw from to color [highlight])


The from and to arguments are 2D or 3D points (lists of two or three reals) that specify
the endpoints of the vector in terms of the current UCS. AutoCAD clips the vector to fit
the screen. The grdraw function draws the vector with the color specified by the integer
color argument, with 1 signifying XOR ink, which complements anything it draws over
and which erases itself when overdrawn. If the integer highlight argument supplied is
nonzero, the vector is drawn using the default highlighting method of the display device
(usually dashed). If highlight is omitted or is zero, grdraw uses the normal display
mode. This function always returns nil.

See also the grvecs function for a routine that draws multiple vectors

grread
Reads values from any of the AutoCAD input devices

(grread [track] [allkeys [curtype]])


Only specialized AutoLISP routines need this function. Most input to AutoLISP should
be obtained through the various getxxx functions.

Appendix A AutoLISP Function Reference

369

If the track argument is supplied and is not nil, it enables the return of coordinates from
a pointing device as it is moved. If the allkeys argument is present, grread performs
functions depending on the code supplied. The curtype argument can be used to control
the type of cursor displayed. The allkeys and curtype arguments are both integers and
are explained as follows:
allkeys

The allkeys bit code values can be added together for combined
functionality.
1 (bit 0) Return drag mode coordinates. If this bit is set and the
user moves the pointing device instead of selecting a button or
pressing a key, grread returns a list where the first member is a
type 5 and the second member is the (X,Y) coordinates of the current
pointing device (mouse or digitizer) location. This is how
AutoCAD implements dragging.
2 (bit 1) Return all key values, including function and cursor key
codes, and dont move the cursor when the user presses a cursor key.
4 (bit 2) Use the value passed in the curtype argument to control
the cursor display.
8 (bit 3) Dont display the error: console break message when the
user presses CTRL + C .

curtype

The allkeys value for bit 2 must be set for the curtype values to
take effect. The curtype argument affects only the cursor type during the current grread function call.
0 Display the normal crosshairs.
1 Do not display a cursor (no crosshairs).
2 Display the object-selection target cursor.

Additional control bits might be defined in future AutoCAD releases.

grread

370

The grread function returns a list whose first element is a code specifying the type of
input. The second element of the list is either an integer or a point, depending on the type
of input. The return values are listed in the following table.
grread return values
First element

Second element

Value

Type of input

Value

Description

Keyboard input

varies

Character code

Selected point

3D point

Point coordinates

Screen/pull-down menu item


(from pointing device)

0 to 999
1001 to 1999
2001 to 2999
3001 to 3999
and so, to
16001 to 16999

Screen menu box no.


POP1 menu box no.
POP2 menu box no.
POP3 menu box no.

POP16 menu box no.

Pointing device (returned only


if tracking is enabled)

3D point

Drag mode coordinate

BUTTONS menu item

0 to 999
1000 to 1999
2000 to 2999
3000 to 3999

BUTTONS1 menu button no.


BUTTONS2 menu button no.
BUTTONS3 menu button no.
BUTTONS4 menu button no.

TABLET1 menu item

0 to 32767

Digitized box no.

TABLET2 menu item

0 to 32767

Digitized box no.

TABLET3 menu item

0 to 32767

Digitized box no.

10

TABLET4 menu item

0 to 32767

Digitized box no.

11

AUX menu item

0 to 999
1000 to 1999
2000 to 2999
3000 to 3999

AUX1 menu button no.


AUX2 menu button no.
AUX3 menu button no.
AUX4 menu button no.

12

Pointer button (follows a type 6


or type 11 return)

3D point

Point coordinates

Appendix A AutoLISP Function Reference

371

Entering Esc while a grread is active aborts the AutoLISP program with a keyboard
break (unless the allkeys argument has disallowed this). Any other input is passed
directly to grread, giving the application complete control over the input devices.
If the user presses the pointer button within a screen menu or pull-down menu box,
grread returns a type 6 or type 11 code, but in a subsequent call, it does not return a type

12 code: the type 12 code follows type 6 or type 11 only when the pointer button is pressed
while it is in the graphics area of the screen.
It is important to clear the code 12 data from the buffer before attempting another operation with a pointer button or with an auxiliary button. To accomplish this, perform a
nested grread like this:
(setq code_12 (grread (setq code (grread))))

This sequence captures the value of the code 12 list as streaming input from the device.
Because input is handled differently on the various platforms supported by AutoCAD, the
grread function may return unexpected results.

The default pointing device on platforms that use a system mouse returns a code 11,
not a code 6.
On the Macintosh platform, the pop menus return a code 11, not a code 4. Also on the
Macintosh, a double-click returns a code 11 (not a code 6) and is followed by a code
5 coordinate pair if selected in the current viewport. Conversely, a double-click in a
viewport other than the current one returns a code 3 coordinate pair followed by a code
11.

grtext
Writes text to the status line or to screen menu areas

(grtext [box text [highlight]])


The box argument is an integer that specifies the location in which to write the text. The
text argument is a string that specifies the text to be written to the screen menu or status
line location. The text argument is truncated if it is too long to fit in the available area.
The highlight argument is an integer that selects or deselects a screen menu location.
The values for these arguments vary depending on the screen location to which you are
writing.
This function displays the supplied text in the menu area; it does not change the underlying menu item. The grtext function can be called with no arguments to restore all text
areas to their standard values. If successful, the grtext function returns the string passed
in the text argument, and returns nil if unsuccessful.

grtext

372

Screen Menu Area


Setting box to a positive or zero value specifies a screen menu location. Valid box values
range from 0 to the highest-numbered screen menu box minus 1. The SCREENBOXES
system variable reports the maximum number of screen menu boxes. If the highlight
argument is supplied as a positive integer, grtext highlights the text in the designated
box. Highlighting a box automatically dehighlights any other box already highlighted. If
highlight is zero, the menu item is dehighlighted. If highlight is a negative number,
it is ignored. On some platforms, the text must first be written without the highlight
argument and then must be highlighted. Highlighting of a screen menu location works
only when the cursor is not in that area.
Status Line Area
If grtext is called with a box value of 1, it writes the text into the mode status line area.
The length of the mode status line differs from display to display (most allow at least 40
characters). The following code uses the $(linelen) DIESEL expression to report the
length of the mode status area.
(setq modelen (menucmd "M=$(linelen)"))

If a box value of 2 is used, grtext writes the text into the coordinate status line area. If
coordinate tracking is turned on, values written into this field are overwritten as soon as
the pointer sends another set of coordinates. For both 1 or 2 box values, the highlight
argument is ignored.

grvecs
Draws multiple vectors on the graphics screen

(grvecs vlist [trans])


The vlist argument is a vector list comprised of a series of optional color integers and
two point lists. The trans argument is a transformation matrix that you can use to change
the location or proportion of the vectors defined in your vector list. This matrix is a list of
four lists of four real numbers.

Appendix A AutoLISP Function Reference

373

The format for vlist is as follows:


([color1] from1 to1 [color2] from2 to2 ...)

The color value applies to all succeeding vectors until vlist specifies another color.
AutoCAD colors are in the range 0255. If the color value is greater than 255, succeeding
vectors are drawn in XOR ink, which complements anything it draws over and which
erases itself when overdrawn. If the color value is less than zero, the vector is highlighted.
Highlighting depends on the display device. Most display drivers indicate highlighting by
a dashed line, but some indicate it by using a distinctive color.
A pair of point lists, from and to, specify the endpoints of the vectors, expressed in the
current UCS. These can be two-dimensional or three-dimensional points. You must pass
these points as pairstwo successive point listsor the grvecs call will fail.
AutoCAD clips the vectors as required to fit on the screen. If the call to grvecs is successful, it returns nil.
The following code draws five vertical lines on the graphics screen, each a different color:
(grvecs (1 (1 2)(1 5)
2 (2 2)(2 5)
3 (3 2)(3 5)
4 (4 2)(4 5)
5 (5 2)(5 5)
))

Draws a red line from (1,2) to (1,5)


Draws a yellow line from (2,2) to (2,5)
Draws a green line from (3,2) to (3,5)
Draws a cyan line from (4,2) to (4,5)
Draws a blue line from (5,2) to (5,5)

The following matrix represents a uniform scale of 1.0 and a translation of 5.0,5.0,0.0. If
this matrix is applied to the preceding list of vectors, they will be offset by 5.0,5.0,0.0.
( (1.0 0.0 0.0 5.0)
(0.0 1.0 0.0 5.0)
(0.0 0.0 1.0 0.0)
(0.0 0.0 0.0 1.0)
)

See also the nentselp function for more information on transformation matrixes

handent
Returns an object (entity) name based on its handle

(handent handle)
Given an entity handle string as the handle argument, the handent function returns the
entity name associated with that handle in the current editing session. The handent function returns the entity name of both graphic and nongraphic entities.

handent

374

If handent is passed an invalid handle or a handle not used by any entity in the current
drawing, nil is returned. The handent function returns entities that have been deleted
during the current editing session. You can undelete them with the entdel function.
An entitys name can change from one editing session to the next, but an entitys handle
remains constant. In a particular editing session, the code
(handent "5A2") might return <Entity name: 60004722>

Used with the same drawing but in another editing session, the same call might return a
different entity name. Once the entity name is obtained, it can be used to manipulate the
entity with any of the entity-related functions.

help
Invokes the help facility

(help [helpfile [topic [command]]])


The helpfile argument is a string that specifies a help file. If you specify an AutoCAD
Help file (.ahp), the help function uses the AutoCAD Help viewer to display the contents
of that file. If you specify a Windows Help file (.hlp) the help function uses the WinHelp
program to display the file. If the helpfile argument is an empty string ("") or is omitted, AutoCAD uses the default AutoCAD Help file. The topic argument is a key word
that specifies the topic initially displayed by the help facility. If the topic argument is an
empty string (""), the help facility displays the introductory part of the help file. The
command argument is a string that specifies the initial state of the Help window, as
described in the following table.
Values for the command argument
String

Description

HELP_CONTENTS

Displays the first topic in the Help file

HELP_HELPONHELP

Displays help on using help

HELP_PARTIALKEY

Displays the Search dialog using the string passed as the topic as
the initial search text

If you are specifying a Windows Help file, the command argument can also be a string
used by the fuCommand argument of the WinHelp() function as defined by the WinHelp
API in the Microsoft Windows SDK.

Appendix A AutoLISP Function Reference

375

The file extension is not required with the helpfile argument. If a file extension is provided, AutoCAD looks only for that file. If no file extension is provided, the following
search rules apply: append .hlp, else append .ahp.
The only error condition that the help function returns to the application is the existence
of the file specified by helpfile. All other error conditions are reported to the user
through a dialog box. The help function returns the helpfile string if it succeeds and
nil if it fails. If you use help without any arguments, it returns an empty string ("") if
successful, and nil if it fails.
The following code calls help to display the information on MYCOMMAND in the help file
achelp.ahp:
(help "achelp.ahp" "mycommand")

See also The setfunhelp function associates context-sensitive help (when the user
presses F1 ) with a user-defined command.

help

376

if
Conditionally evaluates expressions

(if testexpr thenexpr [elseexpr])


If testexpr is not nil, it evaluates thenexpr; otherwise it evaluates elseexpr. The
if function returns the value of the selected expression. If elseexpr is missing and
testexpr is nil, then the if function returns nil.
(if (= 1 3) "YES!!" "no.") returns "no."
(if (= 2 (+ 1 1)) "YES!!") returns "YES!!"
(if (= 2 (+ 3 4)) "YES!!") returns nil

See also the progn function

Appendix A AutoLISP Function Reference

377

initdia
Forces the display of the next commands dialog box

(initdia [dialogflag])
The dialogflag argument is an integer. If this argument is not present or is present and
nonzero, the next use (and next use only) of a command will display that commands dialog box rather than its command line prompts. Currently, the only commands to make use
of the initdia function are BHATCH, LAYER, IMAGE, IMAGEADJUST, LINETYPE,
MTEXT, PLOT, STYLE, and TOOLBAR.
If the dialogflag argument is zero, then any previous call to this function is cleared, which
restores the default behavior of presenting the command line interface.
This function returns no value.
Externally defined function acadapp ARX application

initget
Establishes key words for use by the next user-input function call

(initget [bits] [string])


The functions that honor key words are getint, getreal, getdist, getangle, getorient, getpoint, getcorner, getkword, entsel, nentsel, and nentselp. The
getstring function is the only user-input function that does not honor key words.
The bits argument is a bit-coded integer that allows or disallows certain types of user
input. The string argument defines a list of key words. The key words are checked by
the next user-input function call when the user does not enter the expected type of input
(for example, a point to getpoint). If the user input matches a key word from the list,
the function returns that key word as a string result. The application can test for the key
words and perform the action associated with each one. If the user input is not of the
expected type and does not match a key word, AutoCAD asks the user to try again. The
initget bit values and key words apply only to the next user-input function call.
The initget function always returns nil.

initdia

378

If initget sets a control bit and the application calls a user-input function for which the
bit has no meaning, the bit is ignored. The bits can be added together in any combination
to form a value between 0 and 255. If no bits argument is supplied, zero (no conditions)
is assumed. If the user input fails one or more of the specified conditions (as in a zero
value when zero values are not allowed), AutoCAD displays a message and asks the user
to try again.
Input options set by initget
Bit value

Description

1 (bit 0)

Prevents the user from responding to the request by entering only ENTER .

2 (bit 1)

Prevents the user from responding to the request by entering zero.

4 (bit 2)

Prevents the user from responding to the request by entering a negative value.

8 (bit 3)

Allows the user to enter a point outside the current drawing limits. This condition applies to the next user-input function even if the AutoCAD system variable
LIMCHECK is currently set.

16 (bit 4)

(Not currently used.)

32 (bit 5)

Uses dashed lines when drawing rubber-band line or box. For those functions
with which the user can specify a point by selecting a location on the graphics
screen, this bit value causes the rubber-band line or box to be dashed instead of
solid. (Some display drivers use a distinctive color instead of dashed lines.) If the
system variable POPUPS is 0, AutoCAD ignores this bit.

64 (bit 6)

Prohibits input of a Z coordinate to the getdist function; lets an application


ensure that this function returns a 2D distance.

128 (bit 7)

Allows arbitrary input as if it is a key word, first honoring any other control bits
and listed key words. This bit takes precedence over bit 0; if bits 7 and 0 are set
and the user presses ENTER , a null string is returned.

Future versions of AutoLISP might use additional initget control bits, so avoid setting
bits that arent shown in the table.

Appendix A AutoLISP Function Reference

379

The special control values are honored only by those getxxx functions for which they
make sense.
User-input functions and applicable control bits
Honors
Control bits values
key words
No
No
No
No
negative limits
zero
null
(8)
(4)
(2)
(1)

Function

Uses
dashes
(32)

2D
distance
(64)

Arbitrary
Input
(128)

getint

getreal

getdist

getangle

getorient

getpoint

getcorner

getkword

entsel

nentsel

nentselp

Key Word Specifications


The string argument is interpreted according to these rules:
Each key word is separated from the following key word by one or more spaces. For
example, "Width Height Depth" defines three key words.
Each key word can contain only letters, numbers, and hyphens (-).
There are two methods for abbreviating key words:

The required portion of the key word is specified in uppercase characters, and the
remainder of the key word is specified in lowercase characters. The uppercase abbreviation can be anywhere in the key word (for example, "LType", "eXit", or "toP").
The entire key word is specified in uppercase characters, and it is followed immediately by a comma, which is followed by the required characters (for example,

initget

380

"LTYPE,LT"). The key word characters in this case must include the first letter of the
key word, which means that "EXIT,X" is not valid.

The two brief examples, "LType" and "LTYPE,LT", are equivalent: if the user types LT
(in either upper case or lower case letters), this is sufficient to identify the key word. The
user can enter characters that follow the required portion of the key word, provided they
dont conflict with the specification. In the example, the user could also enter LTY or
LTYP, but L would not be sufficient.
If string shows the key word entirely in uppercase or lowercase characters with no
comma followed by a required part, AutoCAD recognizes the key word only if the user
enters all of it.
The initget function provides support for localized keywords. The following syntax for
the keyword string allows input of the localized keyword while it returns the language
independent keyword:
"local1 local2 localn _indep1 indep2 indepn"

where local1 through localn are the localized keywords, and indep1 through indepn
are the language-independent keywords.
There must always be the same number of localized keywords as language-independent
keywords, and the first language-independent keyword is prefixed by an underscore as
shown in the following example:
(initget "Abc Def _Ghi Jkl")
(getkword "\nEnter an option (Abc/Def): ")

Entering A returns Ghi and entering _J returns Jkl.

Appendix A AutoLISP Function Reference

381

inters
Finds the intersection of two lines

(inters pt1 pt2 pt3 pt4 [onseg])


The pt1 and pt2 arguments are the endpoints of the first line, and pt3 and pt4 are the
endpoints of the second line. If the onseg argument is present and is nil, the lines
defined by the four pt arguments are considered infinite in length, and inters returns
the point where they intersect even if that point is off the end of one or both of the lines.
If the onseg argument is omitted or is not nil, the intersection point must lie on both
lines or inters returns nil. The inters function returns nil if the two lines do not
intersect.
All points are expressed in terms of the current UCS. If all four point arguments are 3D,
inters checks for 3D intersection. If any of the points are 2D, inters projects the lines
onto the current construction plane and checks only for 2D intersection.
(setq a (1.0 1.0) b (9.0 9.0))
(setq c (4.0 1.0) d (4.0 2.0))
(inters a b c d)
returns nil
(inters a b c d T)
returns nil
(inters a b c d nil)
returns (4.0 4.0)

itoa
Returns the conversion of an integer into a string

(itoa int)
The int argument specifies an integer.
(itoa 33)
(itoa -17)

returns "33"
returns "-17"

inters

382

lambda
Defines an anonymous function

(lambda arguments expr...)


Use the lambda function when the overhead of defining a new function is not justified.
It also makes the programmers intention more apparent by laying out the function at the
spot where it is to be used. This function returns the value of its last expr, and is often
used in conjunction with apply and/or mapcar to perform a function on a list.
(apply (lambda (x y z)
(* x (- y z))
)
(5 20 14)
)
returns 30

and
(setq counter 0)
(mapcar (lambda (x)
(setq counter (1+ counter))
(* x 5)
)
(2 4 -6 10.2)
)
returns (10 20 -30 51.0)

last
Returns the last element in a list

(last lst)
(last (a b c d e))
(last (a b c (d e)))

returns E
returns (D E)

As shown, last can return an atom or a list.


At first glance, last seems a perfect way to obtain the Y coordinate of a point. While this
is true for 2D points (lists of two reals), last will return the Z coordinate of a 3D point.
To let functions work properly with 2D or 3D points, use cadr to obtain Y coordinates,
and caddr to obtain Z coordinates.

Appendix A AutoLISP Function Reference

383

length
Returns an integer indicating the number of elements in a list

(length lst)
(length (a b c d))
returns 4
(length (a b (c d)))
returns 3
(length ())
returns 0

list
Takes any number of expressions, and combines them into one list

(list expr...)
(list a b c)
(list a (b c) d)
(list 3.9 6.7)

returns (A B C)
returns (A (B C) D)
returns (3.9 6.7)

In AutoLISP, this function is frequently used to define a 2D or 3D point variable (a list of


two or three reals).
As an alternative to using the list function, you can explicitly quote a list with the
quote function if there are no variables or undefined items in the list. The single quote
character ( ) is defined as the quote function.
(3.9 6.7)

means the same as (list 3.9 6.7)

This can be useful for creating association lists and defining points.

See also the quote function

length

384

listp
Verifies that an item is a list

(listp item)
Returns T if item is a list, and returns nil otherwise.
(listp (a b c))
(listp a)
(listp 4.343)

returns T
returns nil
returns nil

Because nil is both an atom and a list, the listp function returns T when passed nil.
(listp nil)

returns T

load_dialog
Loads a DCL file

(load_dialog dclfile)
The dclfile argument is a string that specifies the DCL file to load. If the dclfile
argument does not specify a file extension, .dcl is assumed. Returns a positive integer
value (dcl_id) if successful, and returns a negative integer if it cant open the file. The
dcl_id is used as a handle in subsequent new_dialog and unload_dialog calls.
The load_dialog function searches for files according to the AutoCAD library search
path.
This function is the complement of unload_dialog. An application can load multiple
DCL files with multiple load_dialog calls.

Appendix A AutoLISP Function Reference

385

load
Evaluates the AutoLISP expressions in a file

(load filename [onfailure])


The filename argument is a string that represents the file name. If the filename argument does not specify a file extension, .lsp is assumed. If the load function fails, it returns
the value of the onfailure argument. However, if onfailure is not provided, a load
failure causes an AutoLISP error. If the operation is successful, load returns the value of
the last expression in the file.
The filename can include a directory prefix, as in /function/test1. On DOS systems, a
drive letter is also permitted. A forward slash (/) or two backslashes (\\) are valid directory delimiters. If you dont include a directory prefix in the filename string, load
searches the AutoCAD library path for the specified file. If the file is found anywhere on
this path, load then loads the file.
If the onfailure argument is a valid AutoLISP function, it is evaluated. In most cases,
the onfailure argument should be a string or an atom. This allows an AutoLISP application calling load to take alternative action upon failure.
For example, assuming that file /fred/test1.lsp contains
(defun MY-FUNC1 (x)

...function body...
)
(defun MY-FUNC2 (x)

...function body...
and that file test2.lsp does not exist, then
(load "/fred/test1")
returns MY-FUNC2
(load "\\fred\\test1")
returns MY-FUNC2
(load "/fred/test1" "bad") returns MY-FUNC2
(load "test2" "bad")
returns "bad"
(load "test2")
causes an AutoLISP error

The load function can be used from within another AutoLISP function, or even recursively (in the file being loaded).

See also the defun function and Symbol and Function Handling.

load

386

log
Returns the natural log of a number as a real number

(log num)
(log 4.5)
(log 1.22)

returns 1.50408
returns 0.198851

logand
Returns the result of the logical bitwise AND of a list of integers

(logand int int...)


(logand 7 15 3)
(logand 2 3 15)
(logand 8 3 4)

returns 3
returns 2
returns 0

logior
Returns the result of the logical bitwise inclusive OR of a list of integers

(logior int int...)


(logior 1 2 4)
(logior 9 3)

returns 7
returns 11

Appendix A AutoLISP Function Reference

387

lsh
Returns the logical bitwise shift of an integer by a specified number of bits

(lsh int numbits)


If numbits is positive, int is shifted to the left; if negative, to the right. In either case,
zero bits are shifted in, and the bits shifted out are discarded. The returned value is positive if the significant bit (bit number 31) contains a 0 after the shift operator, otherwise it
is negative.
(lsh 2 1)
(lsh 2 -1)
(lsh 40 2)

returns 4
returns 1
returns 160

mapcar
Returns a list of the result of executing a function with the individual elements of
a list or lists supplied as arguments to the function

(mapcar function list1... listn)


The number of lists must match the number of arguments required by function.
(setq a 10 b 20 c 30)
(mapcar 1+ (list a b c)) returns (11 21 31)

is equivalent to
(1+ a)
(1+ b)
(1+ c)

except that mapcar returns a list of the results.

lsh

388

The lambda function can specify an anonymous function to be performed by mapcar.


This is useful when some of the function arguments are constant or are supplied by some
other means.
(mapcar

(lambda (x)
(+ x 3)
)
(10 20 30)

returns (13 23 33)

max
Returns the largest of the numbers given

(max number number...)


(max 4.07 -144)
(max -88 19 5 2)
(max 2.1 4 8)

returns 4.07
returns 19
returns 8.0

mem
Displays the current state of AutoLISPs memory

(mem)
Displays the current state of AutoLISPs memory, and returns nil. It displays the following information:
Nodes is the total number of nodes allocated so far, which should equal the node segment
size multiplied by the number of segments.
Free nodes is the number of nodes currently on the free list as a result of a garbage collection.
Segments is the number of node segments allocated.
Allocate is the current segment size.
Collections is a count of garbage collections, whether automatic or forced.

Appendix A AutoLISP Function Reference

389

member
Searches a list for an occurrence of an expression and returns the remainder of
the list, starting with the first occurrence of the expression

(member expr lst)


If there is no occurrence of expr in lst, member returns nil.
(member c (a b c d e)) returns (C D E)
(member q (a b c d e)) returns nil

menucmd
Issues menu commands, or sets and retrieves menu item status

(menucmd string)
The string argument is a string that specifies a menu area and the value to assign to that
menu area. The string argument has the following parameters.
"menu_area=value"

The allowed values of menu_area, shown in the following table, are the same as they are
in menu file submenu references.
Menu_area string values
Menu_area
string

Menu section

B1B4

For BUTTONS menus 1 through 4

A1A4

For AUX menus 1 through 4

P0P16

For pull-down (POP) menus 0 through 16

For image tile menus

member

390

Menu_area string values (continued)


Menu_area
string

Menu section

For the SCREEN menu

T1T4

For TABLET menus 1 through 4

For DIESEL string expressions

Gmenugroup.nametag

Specifies a menugroup and name tag

The value parameter specifies the value that is assigned to menu_area.


The menucmd function can switch between subpages in an AutoCAD menu. This function
can also force the display of menus. This allows AutoLISP programs to use image tile
menus and to display other menus from which the user can make selections. AutoLISP
programs can also enable, disable, and place marks in menu items.
The following code displays the image tile menu MOREICONS.
(menucmd "I=moreicons")
Loads the MOREICONS image tile menu
(menucmd "I=*")
Displays the menu

The following code checks the status of the third menu item in the pull-down menu
POP11. If the menu item is currently enabled, the menucmd function disables it.
(setq s (menucmd "P11.3=?")) Gets the status of the menu item
(if (= s "")
If the status is an empty string,
(menucmd "P11.3=~")
disable the menu item
)

The previous code is not foolproof. In addition to being enabled or disabled, menu items
can also receive marks. The code (menucmd "P11.3=?") could return "!.", indicating
that the menu item is currently checked. This code would make the assumption that the
menu item is disabled and would continue without disabling it. If the code included a call
to the wcmatch function, it could check the status for an occurrence of the tilde (~) character and then take appropriate action.

Appendix A AutoLISP Function Reference

391

The menucmd function also allows AutoLISP programs to take advantage of the DIESEL
string expression language. Some things can be done much easier with DIESEL than with
the equivalent AutoLISP code. The following code returns a string containing the current
day and date:
(menucmd "M=$(edtime,$(getvar,date),DDDD\",\" D MONTH YYYY)")
returns "Sunday, 16 July 1995"

menugroup
Verifies that a menugroup is loaded

(menugroup groupname)
The groupname argument is a string that specifies the menugroup name. If groupname
matches a loaded menugroup the function returns the groupname string; otherwise, it
returns nil.

min
Returns the smallest of the numbers given

(min number number...)


(min 683 -10.0)
(min 73 2 48 5)
(min 2 4 6.7)

returns -10.0
returns 2
returns 2.0

menugroup

392

minusp
Verifies that a number is negative

(minusp num)
Returns T if number is negative, and returns nil otherwise.
(minusp -1)
(minusp -4.293)
(minusp 830.2)

returns T
returns T
returns nil

mode_tile
Sets the mode of a dialog box tile

(mode_tile key mode)


The key argument is a string that specifies the tile and is case-sensitive. The mode argument is an integer value. The mode argument values are described in the following table.
Mode argument values
Value

Description

Enable tile

Disable tile

Set focus to tile

Select edit box contents

Flip image highlighting on or off

Appendix A AutoLISP Function Reference

393

namedobjdict
Returns the entity name of the current drawings named object dictionary, which
is the root of all nongraphical objects in the drawing

(namedobjdict)
Using the name returned by this function and the dictionary access functions, an application can access the nongraphical objects in the drawing.

nentsel
Prompts the user to select an object (entity) by specifying a point, and provides
access to the definition data contained within a complex object

(nentsel [msg])
The msg argument is a string to be displayed as a prompt. If omitted, the Select objects
prompt is issued.
The nentsel function prompts the user to select an object. The current Object Snap
mode is ignored unless the user specifically requests it. To provide additional support at
the Command prompt, nentsel honors key words defined by a previous call to initget.
When the selected object is not complex (i.e., not a polyline or block), nentsel returns
the same information as entsel. However, if the selected object is a polyline, nentsel
returns a list containing the name of the subentity (vertex) and the pick point. This is similar to the list returned by entsel, except that the name of the selected vertex is returned
instead of the polyline header. The nentsel function always returns the starting vertex
of the selected polyline segment. Picking the third segment of a polyline, for example,
returns the third vertex. The Seqend subentity is never returned by nentsel for a
polyline.
An optimized polyline (lwpolyline entity) is defined in the drawing database as a single
entity; it does not contain subentities.
Selecting an attribute within a block reference returns the name of the attribute and the
pick point. When the selected object is a component of a block reference other than an
attribute, nentsel returns a list containing four elements.

namedobjdict

394

The first element of the list returned from picking an object within a block is the selected
entitys name. The second element is a list containing the coordinates of the point used to
pick the object.
The third element is called the Model to World Transformation Matrix. It is a list consisting of four sublists, each of which contains a set of coordinates. This matrix can be used
to transform the entity definition data points from an internal coordinate system called the
Model Coordinate System (MCS), to the World Coordinate System (WCS). The insertion
point of the block that contains the selected entity defines the origin of the MCS. The orientation of the UCS when the block is created determines the direction of the MCS axes.
The fourth element is a list containing the entity name of the block that contains the
selected object. If the selected object is in a nested block (a block within a block), the list
additionally contains the entity names of all blocks in which the selected object is nested,
starting with the innermost block and continuing outward until the name of the block that
was inserted in the drawing is reported.
(<Entity Name: ename1>

Name of entity

(Px Py Pz)
Pick point
( (X0 Y0 Z0)
Model to World Transformation Matrix
(X1 Y1 Z1)
(X2 Y2 Z2)
(X3 Y3 Z3)
)
(<Entity name:ename2> Name of most deeply nested block
.
containing selected entity
.
.
<Entity name:enamen>) Name of outermost block
)

containing selected entity

Once the entity name and the Model to World Transformation Matrix are obtained, you
can transform the entity definition data points from the MCS to the WCS. Use entget
and assoc on the entity name to obtain the definition points expressed in MCS coordinates. The Model to World Transformation Matrix returned by nentsel has the same
purpose as that returned by nentselp, but it is a 4 3 matrixpassed as an array of four
pointsthat uses the convention that a point is a row rather than a column. The transformation is described by the following matrix multiplication:

M 00 M 01 M 02
X Y Z 1.0 = X Y Z 1.0

M 10 M 11 M 12
M 20 M 21 M 22
M 30 M 31 M 32

So the equations for deriving the new coordinates are as follows:

Appendix A AutoLISP Function Reference

395

X = XM 00 + YM 10 + ZM 20 + M 30
Y = XM 01 + YM 11 + ZM 21 + M 31
Z = XM 02 + YM 12 + ZM 22 + M 32
The Mij, where 0 i, j 2, are the Model to World Transformation Matrix coordinates;
X, Y, Z is the entity definition data point expressed in MCS coordinates, and X, Y, Z is
the resulting entity definition data point expressed in WCS coordinates.
This is the only AutoLISP function that uses a matrix of this type; the nentselp function
returns a matrix similar to those used by other AutoLISP and ADSRX functions.

See also Entity Name Functions and the entsel and if functions

nentselp
Provides similar functionality to that of the nentsel function without the need
for user input

(nentselp [msg] [pt])


In addition to the optional msg argument, nentselp accepts a selection point as an
optional argument. This allows object selection without user input. The nentselp function returns a 4 4 transformation matrix, defined as follows:

M 00 M 01 M 02 M 03
M 10 M 11 M 12 M 13
M 20 M 21 M 22 M 23
M 30 M 31 M 32 M 33
The first three columns of the matrix specify scaling and rotation. The fourth column is a
translation vector.
The functions that use a matrix of this type treat a point as a column vector of dimension
4. The point is expressed in homogeneous coordinates, where the fourth element of the
point vector is a scale factor that is normally set to 1.0. The final row of the matrix, the
vector [M30 M31 M32 M33], has the nominal value of [0 0 0 1]; it is currently ignored by

nentselp

396

the functions that use this matrix format. In this convention, applying a transformation to
a point is a matrix multiplication that appears as follows:

M 00
X
M 10
Y
=
Z
M 20
1.0
0.0

M 01 M 02 M 03

X
M 11 M 12 M 13
Y

Z
M 21 M 22 M 23
1.0
0.0 0.0 1.0

This multiplication gives us the individual coordinates of the point as follows:

X = XM 00 + YM 01 + ZM 02 + M 03 ( 1.0 )
Y = XM 10 + YM 11 + ZM 12 + M 13 ( 1.0 )
Z = XM 20 + YM 21 + ZM 22 + M 23 ( 1.0 )
As these equations show, the scale factor and the last row of the matrix have no effect and
are ignored.

new_dialog
Begins a new dialog box and displays it, and can also specify a default action

(new_dialog dlgname dcl_id [action [screen-pt]])


The dlgname argument is a string that specifies the dialog box, and dcl_id identifies the
DCL file (you must have obtained its value from the load_dialog call).
The action argument, which must be specified if you specify screen-pt, is a string that
contains an AutoLISP expression to use as the default action. If you dont want to define
a default action, pass action as the empty string (""). The screen-pt argument is a 2D
point list that specifies the X,Y location of the dialog box on the screen. The point usually
specifies the upper-left corner of the dialog box, but this is platform dependent, as is the
system of units in which the location is specified. If you pass the point as(-1 -1), the
dialog box is opened in the default position (the center of the AutoCAD graphics screen).
If new_dialog succeeds, it returns T; otherwise it returns nil.
Your application must call new_dialog before it calls start_dialog. All dialog box
initializationsuch as setting tile values, creating images or lists for list boxes, and associating actions with specific tiles (with the use of action_tile)must take place after

Appendix A AutoLISP Function Reference

397

the new_dialog call and before the start_dialog call.


The default action is evaluated when the user picks an active tile that doesnt have an
action or callback explicitly assigned to it by action_tile or in DCL.
Always check the status new_dialog returns. Calling start_dialog when the
new_dialog call failed can have unpredictable results.

new_dialog

398

not
Verifies that an item evaluates to nil

(not item)
Returns T if item evaluates to nil, and returns nil otherwise.
(setq a 123 b "string" c nil)
(not a)
returns
(not b)
returns
(not c)
returns
(not ())
returns

nil
nil
T
T

Typically, the null function is used for lists, and not is used for other data types along
with some type of control function.

nth
Returns the nth element of a list

(nth n lst)
The n argument is the number of the element to return (zero is the first element). If n is
greater than lsts highest element number, nth returns nil.
(nth 3 (a b c d e))
(nth 0 (a b c d e))
(nth 5 (a b c d e))

returns D
returns A
returns nil

Appendix A AutoLISP Function Reference

399

null
Verifies that an item is bound to nil

(null item)
Returns T if item is bound to nil, and returns nil otherwise.
(setq a 123 b "string" c nil)
(null a)
returns
(null b)
returns
(null c)
returns
(null ())
returns

nil
nil
T
T

numberp
Verifies that an item is a real number or an integer

(numberp item)
Returns T if item is a real or an integer, and returns nil otherwise.
(setq a 123 b a)
(numberp 4)
(numberp 3.8348)
(numberp "Howdy")
(numberp a)
(numberp b)
(numberp (eval b))

returns T
returns T
returns nil
returns T
returns nil
returns T

open
Opens a file for access by the AutoLISP I/O functions

(open filename mode)


The filename argument is a string that specifies the name and extension of the file to be
opened. The mode argument is the read/write flag. It must be a string containing a single

null

400

lowercase letter. The following table describes the valid mode letters.
Mode options for the open function
Open
mode

Description

"r"

Open for reading. If filename does not exist, open returns nil.

"w"

Open for writing. If filename does not exist, a new file is created and opened. If
filename already exists, its existing data is overwritten.

"a"

Open for appending. If filename does not exist, a new file is created and opened.
If filename already exists, it is opened and the pointer is positioned at the end of
the existing data, so new data you write to the file is appended to the existing data.

Data passed to an open file is not actually written until th e file is closed with the close
function.
On DOS systems, some programs and text editors write text files with an end-of-file
marker (CTRL Z, decimal ASCII code 26) at the end of the text. When reading a text file,
DOS returns an end-of-file status if a CTRL Z marker is encountered, even if that marker
is followed by more data. If you intend to use OPENs "a" mode to append data to files
produced by another program, be sure that the other program does not insert CTRL Z
markers at the end of its text files.
The open function returns a file descriptor to be used by the other I/O functions. The file
descriptor must be assigned to a symbol that uses the setq function.
(setq a (open "file.ext" "r"))

Assuming that the files named in the following examples do not exist,
(setq f (open "new.tst" "w")) returns <File #nnn>
(setq f (open "nosuch.fil" "r")) returns nil
(setq f (open "logfile" "a")) returns <File #nnn>

The filename argument can include a directory prefix, as in /test/func3. On DOS systems, a drive letter is also permitted, and you can use the backslash (\) instead of the forward slash (/), but remember that you must use two backslashes (\\) to obtain one backslash in a string.
(setq f (open "/x/new.tst" "w")) returns <File #nnn>
(setq f (open "nosuch.fil" "r")) returns nil

Appendix A AutoLISP Function Reference

401

or
Returns the logical OR of a list of expressions

(or expr...)
The or function evaluates the expressions from left to right, looking for a non-nil
expression. If one is found, or ceases further evaluation and returns T. If all of the expressions are nil, or returns nil.
(or nil 45 ())
(or nil ())

returns T
returns nil

osnap
Returns a 3D point that is the result of applying an Object Snap mode to a
specified point

(osnap pt mode)
The mode argument is a string that consists of one or more valid Object Snap identifiers
such as mid, cen, and so on, separated by commas.
(setq pt1 (getpoint))
(setq pt2 (osnap pt1 "cen"))
(setq pt3 (osnap pt1 "end,int"))

The point returned by osnap depends on the current 3D view and the setting of the APERTURE system variable.

polar
Returns the UCS 3D point at a specified angle and distance from a point

(polar pt ang dist)


The ang argument is expressed in radians relative to the X axis with angles increasing in
the counterclockwise direction. Although pt can be a 3D point, ang is always with
respect to the current construction plane.

or

402

(polar (1 1 3.5) 0.785398 1.414214) returns (2.0 2.0 3.5)

prin1
Prints an expression to the command line or writes an expression to an open file

(prin1 [expr [file-desc]])


The expr argument does not need to be a string. If file-desc is present and is a file
descriptor for a file opened for writing, expr is written to the file exactly as it appears on
the screen. Only the specified expr is printed; no newline or space is included.
(setq a 123 b (a))
(prin1 a)
prints A
and returns A
(prin1 a)
prints 123 and returns 123
(prin1 b)
prints (A) and returns (A)
(prin1 "Hello")
prints "Hello" and returns "Hello"

Each of the preceding examples is displayed on the screen because no file-desc was
specified. Assuming that f is a valid file-descriptor for a file opened for writing,
(prin1 "Hello" f)

will write "Hello" to the specified file and will return "Hello".
If expr is a string containing control characters, prin1 expands these characters with a
leading \, as shown in the following table.
Control codes
Code

Description

\\

\ character

\"

" character

\e

Escape character

\n

Newline character

\r

Return character

\t

Tab character

\nnn

Character whose octal code is nnn

Appendix A AutoLISP Function Reference

403

Control codes (continued)


Code

Description

\U+XXXX

Unicode sequence; Note: not valid when running


in a Visual LISP environment

\M+NXXXX

Unicode sequence; Note: not valid when running


in a Visual LISP environment

The following examples show how to use control characters:


(prin1 (chr 2)) prints "\002" and returns "\002"
(prin1 (chr 10)) prints "\n" and returns "\n"

The prin1 function can be called with no arguments, in which case it returns (and prints)
the null string. If you use prin1 (with no arguments) as the last expression in a userdefined function, only a blank line is printed when the function is complete, allowing the
application to exit quietly.

princ
Prints an expression to the command line, or writes an expression to an open file

(princ [expr [file-desc]])


This function is the same as prin1, except that control characters in expr are printed
without expansion.
In general, prin1 is designed to print expressions in a way that is compatible with load,
while princ prints them in a way that is readable by functions such as read-line.

print
Prints an expression to the command line, or writes an expression to an open file

(print [expr [file-desc]])


This function is the same as prin1, except that it prints a newline character before expr,
and prints a space following expr.

princ

404

progn
Evaluates each expression sequentially, and returns the value of the last
expression

(progn [expr]...)
You can use progn to evaluate several expressions where only one expression is
expected.
(if (= a b)
(progn
(princ "\nA = B ")
(setq a (+ a 10) b (- b 10))
)
)

The if function normally evaluates one then expression if the test expression evaluates
to anything but nil. In this example, we have used progn to cause two expressions to be
evaluated instead.

Appendix A AutoLISP Function Reference

405

prompt
Displays a string on your screens prompt area

(prompt msg)
On dual-screen AutoCAD configurations, prompt displays msg on both screens and is,
therefore, preferable to princ.
(prompt "New value: ")

displays

New value:

on the screen(s)

The prompt function returns nil.

quit
Forces the current application to quit

(quit)
If quit is called, it returns the error message quit/exit abort and returns to the AutoCAD
Command prompt.

See also the exit function

quote
Returns an expression without evaluating it

(quote expr)
This can also be written
expr
(quote a)
(quote cat)
(quote (a b))
a
cat
(a b)

returns A
returns CAT
returns (A B)
returns A
returns CAT
returns (A B)

prompt

406

The last three examples dont work if entered directly from the keyboard in response to
an AutoCAD prompt. Remember that such input must begin with the character ( or ! to
be recognized as an AutoLISP expression.

read
Returns the first list or atom obtained from a string

(read [string])
The string argument cannot contain blanks except within a list or string. The read function returns its argument converted into the corresponding data type:
(read "hello")
returns the atom
(read "hello there")
returns the atom
(read "\"Hi Yall\"") returns the string
(read "(a b c)")
returns the list
(read "(a b c) (d)")
returns the list
(read "1.2300")
returns the real number
(read "87")
returns the integer
(read "87 3.2")
returns the integer

HELLO
HELLO
"Hi Yall"
(A B C)
(A B C)
1.23
87
87

read-char
Returns the decimal ASCII code representing the character read from the
keyboard input buffer or from an open file

(read-char [file-desc])
If no file-desc is specified and there are no characters in the keyboard input buffer,
read-char waits for keyboard entry (followed by ENTER ). For instance, assuming the
keyboard input buffer is empty,
(read-char)

waits for something to be entered. If you enter ABC followed by ENTER , read-char
returns 65 (the decimal ASCII code for the letter A). The next three calls to read-char
return 66, 67, and 10 (newline), respectively. If another read-char call is made, it again
waits for input.
The various operating systems under which AutoCAD runs use various conventions to
signal the end of a line in an ASCII text file. UNIX systems, for example, use a single
newline character (linefeed [LF], ASCII code 10), whereas DOS systems use a pair of

Appendix A AutoLISP Function Reference

407

characters (carriage-return [CR]/LF, ASCII codes 13 and 10) for the same purpose. To
facilitate development of AutoLISP programs, read-char accepts all these conventions,
returning a single newline character (ASCII code 10) whenever it detects an end-of-line
character (or character sequence).

read-line
Reads a string from the keyboard or from an open file

(read-line [file-desc])
If read-line encounters the end of the file, it returns nil; otherwise it returns the string
that it read.
For example, assuming that f is a valid open file pointer,
(read-line f)

returns the next input line from the file, or returns nil if the end-of-file has been reached.

redraw
Redraws the current viewport or a specified object (entity) in the current
viewport

(redraw [ename [mode]])


The effect of the redraw function depends on the arguments supplied. If called with no
arguments, it redraws the current viewport. If called with the ename (entity name) argument, it redraws the specified entity.
The mode argument is an integer value that controls the visibility and highlighting of the
entity.
Modes for redraw
Redraw mode

Action

Show entity

Hide entity (blank it out)

read-line

408

Modes for redraw (continued)


Redraw mode

Action

Highlight entity

Unhighlight entity

If ename is the header of a complex entity (a polyline or a block reference with attributes),
it processes the main entity and all its subentities if the mode argument is positive. If the
mode argument is negative, redraw operates on only the header entity.
The redraw function always returns nil.
The use of entity highlighting (mode 3) must be balanced with entity unhighlighting
(mode 4).
The REDRAW command has no effect on highlighted or hidden entities; however, a
REGEN forces the entities to redisplay in their normal manner.

regapp
Registers an application name with the current AutoCAD drawing in
preparation for using extended object data

(regapp application)
The application argument is a string up to 31 characters long that adheres to the symbol-naming conventions. An application name can contain letters, digits, and the special
characters dollar sign ($), hyphen (-), and underscore (_). It cannot contain spaces. Letters in the name are converted to upper case.
If an application of the same name has already been registered, this function returns nil;
otherwise it returns the name of the application.
If registered successfully, the application name is entered into the APPID symbol table.
This table maintains a list of the applications that are using extended data in the drawing.
(regapp "ADESK_4153322344")
(regapp "DESIGNER-v2.1-124753")

It is recommended that you pick a unique application name. One way of ensuring this is
to adopt a naming scheme that uses the company or product name and a unique number
(like your telephone number or the current date/time). The product version number can

Appendix A AutoLISP Function Reference

409

be included in the application name or stored by the application in a separate integer or


real-number field; for example, (1040 2.1).

rem
Divides the first number by the second, and returns the remainder

(rem number number...)


If more than two numbers are provided, rem divides the result of dividing the first number
by the second with the third, and so on.
(rem 42 12)
returns 6
(rem 12.0 16)
returns 12.0
(rem 26 7)
returns 5
(rem 5 2)
returns 1
(rem 26 7 2)
returns 1

repeat
Evaluates each expression a specified number of times, and returns the value of
the last expression

(repeat int expr...)

rem

410

The int argument must be positive.


(setq a 10 b 100)
(repeat 4
(setq a (+ a 10))
(setq b (+ b 100))
)
Sets a to 50, sets b to 500, and returns 500

reverse
Returns a list with its elements reversed

(reverse lst)
(reverse ((a) b c))

returns (C B (A))

rtos
Converts a number into a string

(rtos number [mode [precision]])


The rtos function returns a string that is the representation of number according to the
settings of mode, precision, and the system variables UNITMODE and DIMZIN. The
mode and precision arguments are integers that select the linear units mode and precision, as shown in the following table.
Linear units values
Mode value

String format

Scientific

Decimal

Engineering (feet and decimal inches)

Architectural (feet and fractional inches)

Fractional

Appendix A AutoLISP Function Reference

411

The mode and precision arguments correspond to the system variables LUNITS and
LUPREC. If you omit the arguments, rtos uses the current settings of LUNITS and
LUPREC. The UNITMODE variable affects the returned string when engineering, architectural, or fractional units are selected (a mode value of 3, 4, or 5).

set
Sets the value of a quoted symbol name to an expression

(set sym expr)


Returns the value of the expression.
(set a 5.0)
(set (quote b) a)

returns 5.0 and sets symbol A


returns A and sets symbol B

If set is used with an unquoted symbol name, it can assign a new value to another symbol
indirectly. For instance, given the previous examples
(set b 640)

returns 640

and assigns the value 640 to symbol a, because that is what symbol b contains.

See also the setq function

set_tile
Sets the value of a dialog box tile

(set_tile key value)


The key argument is a string that specifies the tile, and value is a string that names the
new value to assign (initially set by the value attribute).

set

412

setcfg
Writes application data to the AppData section of the acad.cfg file

(setcfg cfgname cfgval)


The cfgname argument is a string (132 characters maximum length) that specifies the
section and parameter to set the value of cfgval (347 characters max. length). If cfgname is not valid, setcfg returns nil. The cfgname argument must be a string of the
following form:
"AppData/application_name/section_name/.../param_name"

The following code sets the WallThk parameter in the AppData/ArchStuff section to 8
and returns the string "8":
(setcfg "AppData/ArchStuff/WallThk" "8") returns "8"

See also the getcfg function

setenv
Sets a system environment variable to a specified value

(setenv varname value)


The varname argument is a string specifying the name of the environment variable to be
set. You must enclose the varname and value in quotation marks. Environment variable
names must be spelled and cased exactly as they are stored in the system registry. Changes
to settings might not take effect until the next time AutoCAD is started.
For example, to set the value of the MaxArray environment variable to 10000,
(setenv "MaxArray" "10000")

See also the getenv function

Appendix A AutoLISP Function Reference

413

setfunhelp
Registers a user-defined command with the Help facility so that the appropriate
help file and topic are called when the user requests help on that command

(setfunhelp c:fname [helpfile [topic [command]]])


The c:fname argument is a string that specifies the user-defined command (the C:XXX
function) and must include the C: prefix. Unlike the function name passed to the defun
function, the function argument for setfunhelp must be a quoted string. The remaining three optional arguments describe the help call to be made. They are also strings and
are the same as the arguments passed to the help function. The setfunhelp function
returns the string passes as c:fname if successful otherwise, it returns nil.
The file extension is not required with the helpfile argument. If a file extension is provided, AutoCAD looks only for that file. If no file extension is provided, the following
search rules apply: If this is AutoCAD for Windows/NT, append .hlp, else append .ahp.
If no <filename>.ahp file is found, search for <filename> with no extension. Note that the
file with no extension is searched last, so on UNIX, acad.ahp is searched before acad.
It should be noted that this function verifies only that the c:fname argument has the c:
prefix. It does not verify that the c:fname function exists or the correctness of the other
arguments.
When you use the defun function to define a C:XXX function, it removes that functions
name from those registered by setfunhelp (if one exists). Therefore, setfunhelp
should only be called after the defun call, which defines the user-defined command.
The following example uses defun to define the user-defined command MYFUN. The
setfunhelp function registers the function name C:MYFUN and associates that name
with the topic myfun in the file myhelp.ahp.
(defun c:myfun ()
...
(getint "gimme: ")
...
)
(setfunhelp "c:myfun" "myhelp.ahp" "myfun")

Command: myfun
gimme: help
Assuming that the AutoCAD Help file myhelp.ahp exists in the support path, AutoCAD
displays the Help dialog with the topic myfun from the file myapp.ahp.

setfunhelp

414

See also the defun and help functions

setq
Sets the value of a symbol or symbols to associated expressions

(setq sym1 expr1 [sym2 expr2]...)


This is the basic assignment function in AutoLISP. The setq function can assign multiple
symbols in one call to the function, but returns only the last expr.
(setq a 5.0)

returns 5.0

Appendix A AutoLISP Function Reference

415

and sets the symbol a to 5.0. Whenever a is evaluated, it evaluates the real number 5.0.
(setq b 123 c 4.7)
(setq s "it")
(setq x (a b))

returns 4.7
returns "it"
returns (A B)

See also AutoLISP Variables.

setvar
Sets an AutoCAD system variable to a specified value

(setvar varname value)


If successful, setvar returns the value of the system variable. You must enclose the variable name in quotation marks.
(setvar "FILLETRAD" 0.50) returns 0.5

and sets the AutoCAD fillet radius to 0.5 units. For system variables with integer values,
the supplied value must be between 32,768 and +32,767.
Some AutoCAD commands obtain the values of system variables before issuing any
prompts. If you use setvar to set a new value while a command is in progress, the new
value might not take effect until the next AutoCAD command.
When using the setvar function to change the AutoCAD system variable ANGBASE,
the value argument is interpreted as radians. This differs from the AutoCAD SETVAR
command, which interprets this argument as degrees. When using the setvar function to
change the AutoCAD system variable SNAPANG, the value argument is interpreted as
radians relative to the AutoCAD default direction for angle 0, which is east or 3 oclock.
This also differs from the SETVAR command, which interprets this argument as degrees
relative to the ANGBASE setting.
The UNDO command does not undo changes made to the CVPORT system variable by
the setvar function.

setvar

416

You can find a list of the current AutoCAD system variables in System Variables, in the
Command Reference.

See also the getvar function

sin
Returns the sine of an angle as a real number expressed in radians

(sin ang)
The ang argument must be an angle expressed in radians.
(sin 1.0)
(sin 0.0)

returns 0.841471
returns 0.0

setview
Establishes a view for a specified viewport

(setview view_descriptor [vport_id])


The view_descriptor argument is an entity definition list similar to that returned by
tblsearch when applied to the VIEW symbol table. The optional argument vport_id
identifies which viewport is to receive the new view. The vport_id number can be
retrieved by the CVPORT system variable. If vport_id is 0, the current viewport
receives the new view. If successful, the setview function returns the
view_descriptor.

Appendix A AutoLISP Function Reference

417

slide_image
Displays an AutoCAD slide in the currently active dialog box image tile

(slide_image x1 y1 wid hgt sldname)


The slide can be a slide file (.sld) or a slide in a slide library file (.slb): the sldname argument specifies it as you would specify it for the VSLIDE command or for a menu file :
sldname or libname(sldname)

The first (upper-left) corner of the slideits insertion pointis located at (x1,y1), and
the second (lower-right) corner is located at the relative distance (wid,hgt) from the first
(wid and hgt must be positive values). The origin (0,0) is the upper-left corner of the
image. You obtain the coordinates of the lower-right corner by calling the dimension
functions (dimx_tile and dimy_tile).

snvalid
Checks the symbol table name for valid characters

(snvalid sym_name [flag])


The sym_name argument is a string that specifies a symbol table name. The optional flag
argument specifies whether the vertical bar character is allowed in sym_name. The flag
argument can be 1 or 0 (default is 0). The snvalid function returns T if sym_name is a
valid symbol table name, otherwise it returns nil.
Symbol table names must consist of only alphanumeric characters and the special characters dollar sign ($), underscore (_), and hyphen (). A null string is not a valid name.

slide_image

418

sqrt
Returns the square root of a number as a real number

(sqrt num)
(sqrt 4)
(sqrt 2.0)

returns 2.0
returns 1.41421

ssadd
Adds an object (entity) to a selection set, or creates a new selection set

(ssadd [ename [ss]])


If called with no arguments, ssadd constructs a new selection set with no members. If
called with the single entity name argument ename, ssadd constructs a new selection set
containing that single entity. If called with an entity name and the selection set ss, ssadd
adds the named entity to the selection set. The ssadd function always returns the new or
modified selection set.
When adding an entity to a set, the new entity is added to the existing set, and the set
passed as ss is returned as the result. Thus, if the set is assigned to other variables, they
also reflect the addition. If the named entity is already in the set, the ssadd operation is
ignored and no error is reported.
(setq e1 (entnext))
Sets e1 to name of first entity in drawing
(setq ss (ssadd))
Sets ss to a null selection set
(ssadd e1 ss)
Returns ss with entity name e1 added
(setq e2 (entnext e1))
Gets entity following e1
(ssadd e2 ss)
Returns ss with entity name e2 added

Appendix A AutoLISP Function Reference

419

ssdel
Deletes an object (entity) from a selection set

(ssdel ename ss)


The ssdel function deletes the entity ename from selection set ss and returns the name
of selection set ss. Note that the entity is actually deleted from the selection set as
opposed to a new set being returned with the element deleted. If the entity is not in the set,
nil is returned.
For example, given that entity name e1 is a member of selection set ss1 and entity name
e2 is not, then
(ssdel e1 ss1) Returns selection set ss with entity e1 removed
(ssdel e2 ss1) Returns nil (does not change ss1)

ssget
Prompts the user to select objects (entities), and returns a selection set

(ssget [mode] [pt1 [pt2]] [pt-list] [filter-list])


The mode argument is a string that specifies the object selection method. Valid modes are
"W", "WP", "C", "CP", "L", "P", "I", and "F", corresponding to the Window, WPolygon, Crossing, CPolygon, Last, Previous, Implied, and Fence selection methods. Another
optional mode value is "X", which selects the entire database. The pt1 and pt2 arguments specify points relevant to the selection. Supplying a point with no mode argument
is equivalent to object selection by picking a single point. The current setting of Object
Snap mode is ignored by this function unless you specifically request it while you are in
the function. The filter-list argument is an association list that specifies object properties. Objects that match the filter-list are added to the selection set. If all arguments are omitted, ssget prompts the user with the Select objects prompt, allowing interactive construction of the selection set.

ssdel

420

Selection sets can contain objects from both paper and model space, but when the selection set is used in an operation, objects from the space not currently in effect are filtered
out. Selection sets returned by ssget contain main entities only (no attributes or polyline
vertices).
Asks the user for a general object selection
and places those objects in a selection set
(ssget "P")
Creates a selection set of the most recently
selected objects
(ssget "L")
Creates a selection set of the last visible
object added to the database
(ssget "I")
Creates a selection set of the objects in the
implied selection set (those selected while
PICKFIRST is in effect)
(ssget (2 2))
Creates a selection set of the object passing
through (2,2)
(ssget "W" (0 0) (5 5)) Creates a selection set of the objects inside
the window from (0,0) to (5,5)
(ssget "C" (0 0) (1 1)) Creates a selection set of the objects crossing
the box from (0,0) to (1,1)
(ssget "X")
Creates a selection set of all objects in the
database
(ssget "X" filter-list)
Scans the database and creates a selection
set of objects matching the filter-list
(ssget filter-list)
Asks the user for a general object selection
and places only those objects matching the
filter-list in a selection set
(ssget "P" filter-list)
Creates a selection set of the most recently
selected objects that match the filter-list
(ssget)

The following examples of ssget require that a list of points be passed to the function.
The pt_list variable cannot contain points that define zero-length segments.
(setq pt_list ((1 1)(3 1)(5 2)(2 4)) )
(ssget "WP" pt_list)
(ssget "CP" pt_list)
(ssget "F" pt_list)
(ssget "WP" pt_list filter-list)

Creates a selection set of all objects inside


the polygon defined by pt_list
Creates a selection set of all objects crossing
and inside the polygon defined by pt_list
Creates a selection set of all objects
intersecting the fence defined by pt_list
Creates a selection set of all objects inside
the polygon defined by pt_list that match

the filter-list
The selected objects are highlighted only when ssget is used with no arguments. Selection sets consume AutoCAD temporary file slots, so AutoLISP is not permitted to have
more than 128 open at once. If this limit is reached, AutoCAD refuses to create any more
selection sets and returns nil to all ssget calls. To close an unneeded selection set variable, set it to nil.
A selection set variable can be passed to AutoCAD in response to any Select objects
prompt at which selection by Last is valid. It selects all the objects in the selection set variable.

Appendix A AutoLISP Function Reference

421

Selection Set Filters


Selection set filter lists can be used with any of the selection modes. You can obtain a
selection set that includes all objects of a given type, on a given layer, or of a given color.
The following example returns a selection set that consists only of blue lines that are part
of the Implied selection set (those objects selected while PICKFIRST is in effect):
(ssget "I" ((0 . "LINE") (62 . 5)))

Using the ssget filter list, you can select all objects containing extended data for a particular application. You do this by using the 3 group code, as in
(ssget "P" ((0 . "CIRCLE") (-3 ("APPNAME"))))

This selects all circles containing data for the "APPNAME" application.
For more information, see Selection Set Filter Lists and Filtering for Extended Data.

Relational Tests
Unless otherwise specified, an equals test is implied for each item in the filter-list.
For numeric groups (integers, reals, points, and vectors) you can specify other relations
by including a special 4 group code that specifies a relational operator. The value of a 4
group is a string that indicates the test operator to be applied to the next group in the filter
list.
(ssget "X" ((0 . "CIRCLE") (-4 . ">=") (40 . 2.0)))

selects all circles whose radius (group code 40) is greater than or equal to 2.0.
The following table shows the possible operators.
Relational operators for selection set filter lists
Operator

Description

"*"

Anything goes (always true)

"="

Equals

"!="

Not equal to

"/="

Not equal to

"<>"

Not equal to

"<"

Less than

"<="

Less than or equal to

">"

Greater than

ssget

422

Relational operators for selection set filter lists (continued)


Operator

Description

">="

Greater than or equal to

"&"

Bitwise AND (integer groups only)

"&="

Bitwise masked equals (integer groups only)

The use of relational operators depends on the kind of group you are testing:

All relational operators except for the bitwise operators ("&" and "&=") are valid for
both real- and integer-valued groups.
The bitwise operators "&" and "&=" are valid only for integer-valued groups. The bitwise AND, "&", is true if ((integer_group & filter)
/= 0)that is, if any of the bits set in the mask are also set in the integer group. The
bitwise masked equals, "&=", is true if ((integer_group & filter) = filter)that is, if all bits set in the mask are also set in the integer_group (other bits
might be set in the integer_group but are not checked).
For point groups, the X, Y, and Z tests can be combined into a single string, with each
operator separated by commas (for example, ">,>,*"). If an operator is omitted from
the string (for example, "=,<>" leaves out the Z test), the anything goes operator,
"*", is assumed.
Direction vectors (group type 210) can be compared only with the operators "*", "=",
and "!=" (or one of the equivalent not equal strings).
You cannot use the relational operators with string groups; use wild-card tests instead.

Appendix A AutoLISP Function Reference

423

Logical Grouping of Filter Tests


The relational operators described in the previous subsection are binary operators. You
can also test groups by creating nested Boolean expressions that use the grouping operators shown in the following table. The grouping operators are specified by 4 groups, like
the relational operators. They are paired, and must be balanced correctly in the filter list
or the ssget call fails. The number of operands these operators can enclose depends on
the operation.
Grouping operators for selection set filter lists
Starting
operator

Encloses

Ending
operator

"<AND"

One or more operands

"AND>"

"<OR"

One or more operands

"OR>"

"<XOR"

Two operands

"XOR>"

"<NOT"

One operand

"NOT>"

With the grouping operators, an operand is an entity-field group, a relational operator followed by an entity-field group, or a nested expression created by these operators. The following is an example of grouping operators in a filter list:
(ssget "X" ((-4 . "<OR")
(-4 . "<AND")
(0 . "CIRCLE")
(40 . 1.0)
(-4 . "AND>")
(-4 . "<AND")
(0 . "LINE")
(8 . "ABC")
(-4 . "AND>")
(-4 . "OR>"))
)

This selects all circles with radius 1.0, plus all lines on layer "ABC".
Because the grouping operators are not case-sensitive, you can also use their lowercase
equivalents: "<and", "and>", "<or", "or>", "<xor", "xor>", "<not", and "not>".

ssget

424

ssgetfirst
Determines which objects are selected and gripped

(ssgetfirst)
Returns a list of two selection sets similar to those passed to sssetfirst. The first element in the list is a selection set of entities that are gripped but not selected. The second
element is a selection set of entities that are both gripped and selected. Either (or both)
elements of the list can be nil.
Only entities from the current drawings model space and paper space, not nongraphical
objects or entities in other block definitions, can be analyzed by this function.

sslength
Returns an integer containing the number of objects (entities) in a selection set

(sslength ss)
The number is returned as a real if it is greater than 32,767. Selection sets never contain
duplicate selections of the same entity.
(setq sset (ssget "L")) Places the last object in selection set sset
(sslength sset)
returns 1

ssmemb
Tests whether an object (entity) is a member of a selection set

(ssmemb ename ss)


If it is, ssmemb returns the entity name (ename). If not, it returns nil. For example, given
that entity name e1 is a member of selection set ss1 and entity name e2 is not, then
(ssmemb e1 ss1)
(ssmemb e2 ss1)

returns entity name e1


returns nil

Appendix A AutoLISP Function Reference

425

ssname
Returns the object (entity) name of the indexed element of a selection set

(ssname ss index)
The index argument must be an integer. If index is negative or greater than the highest
numbered entity in the selection set, nil is returned. The first element in the set has an
index of zero. Entity names in selection sets obtained with ssget always are names of
main entities. Subentities (attributes and polyline vertices) are not returned. (The entnext function allows access to them. See entnext.)
(setq sset (ssget))
Creates a selection set named sset
(setq ent1 (ssname sset 0))
Gets name of first entity in sset
(setq ent4 (ssname sset 3))
Gets name of fourth entity in sset

To access entities beyond the 32767th one in a selection set, you must supply the index
argument as a real. For example:
(setq entx (ssname sset 50843.0)) Gets name of 50844th entity in sset

ssnamex
Retrieves information about how a selection set was created

(ssnamex ss [index])
This function returns the entity name of the element specified by index from the selection set ss along with data that describes how the entity was selected. If the index argument is not supplied, this function returns a list containing the entity names of all of the
elements in the selection set along with data that describes how each of the entities was
selected.

ssname

426

The data returned by ssnamex takes the form of a list of lists that contains information
that either describes an entity and its selection method or a polygon that was used to select
one or more entities. Each sub-list that describes the selection of a particular entity comprises three parts: the selection method ID (an integer >= 0), the entity name of the
selected entity, and selection method specific data that describes how the entity was
selected.
((sel_id1 ename1 (data))(sel_id2 ename2 (data)) ... )

The following table lists the selection method IDs.


Selection method IDs
ID

Description

non specific (i.e. Last All etc.)

Pick

Window or WPolygon

Crossing or CPolygon

Fence

Each sub-list that describes a polygon thats used during entity selection takes the form of
a polygon ID (an integer < 0), followed by point descriptions.
(polygon_id point_description_1 point_description_n... )

Polygon ID numbering starts at 1 and each additional polygon ID is incremented by 1.


Depending on the viewing location, a point is represented as one of the following: an infinite line, a ray, or a line segment. A point descriptor comprises three parts: a point descriptor ID (the type of item being described), the start point of the item, and an optional unit
vector that describes either the direction in which the infinite line travels or a vector that
describes the offset to the other side of the line segment.
(point_descriptor_id base_point [unit_or_offset_vector])

Appendix A AutoLISP Function Reference

427

The following table lists the valid point descriptor IDs.


Point descriptor IDs
ID

Description

Infinite line

Ray

Line segment

The unit_or_offset_vector is returned when the view point is something other than
0,0,1.
The data associated with Pick (type 1) entity selections is a single point description. For
example, the following record is returned for the selection of an entity picked at 1,1 in
plan view of the WCS:
(1 <Entity name: 60000064> (0 (1.0 1.0 0.0) ) )
The data associated with an entity selected with the Window, WPolygon, Crossing, or
CPolygon method is the integer ID of the polygon that selected the entity. It is up to the
application to associate the polygon identifiers and make the connection between the
polygon and the entities it selected. For example, the following record is returned for an
entity selected by Crossing (note that the polygon ID is 1).
((3 <Entity name: 60000024> 1) (1 (0 (5.14828 7.05067 0.0) )
(0 (7.13676 7.05067 0.0) ) (0 (7.13676 4.62785 0.0) )
(0 (5.14828 4.62785 0.0) ) ) )
The data associated with Fence selections is a list of points descriptions for the points
where the fence and entity visually intersect. For example, the following record is
returned for a nearly vertical line intersected three times by a Z-shaped fence.
((4 <Entity name: 60000024> (0 (5.28135 6.25219 0.0) )
(0 (5.61868 2.81961 0.0) ) (0 (5.52688 3.75381 0.0) ) ) )
Only selection sets with entities from the current drawings model space and paper
spacenot nongraphical objects or entities in other block definitionscan be retrieved
by this function.

ssnamex

428

sssetfirst
Sets which objects are selected and gripped

(sssetfirst gripset [pickset])


The selection set of objects specified by the gripset argument are gripped, and the selection set of objects specified by pickset are both gripped and selected. If any objects are
common to both selection sets, sssetfirst grips and selects the selection set specified
by pickset only (it does not grip the gripset set). If gripset is nil sssetfirst
grips and selects the pickset set. The sssetfirst function returns a list of the two
variables passed as the selection sets.
Do not call ads_ssetfirst() when AutoCAD is in the middle of executing a command.

startapp
Starts a Windows application

(startapp appcmd [file])


The appcmd argument is a string that specifies the application to execute. If appcmd does
not include a full path name, it searches the PATH environment variable for the application. The file argument is a string that specifies the file name to be opened. Returns an
integer greater than 0 if successful; otherwise it returns 0.
The following code starts the Windows Notepad and opens the acad.lsp file.
(startapp "notepad" "acad.lsp")

If an argument has embedded spaces, it must be surrounded by literal double quotes. For
example, to edit the file my stuff.txt with Notepad use the following syntax:
(startapp "notepad.exe" "\"my stuff.txt\"")

Externally defined function acadapp ARX application

Appendix A AutoLISP Function Reference

429

start_dialog
Displays a dialog box and begins accepting user input

(start_dialog)
You must first initialize the dialog box by a previous new_dialog call. The dialog box
remains active until an action expression or callback function calls done_dialog. Usually done_dialog is associated with the tile whose key is "accept" (typically the OK
button) and the tile whose key is "cancel" (typically the Cancel button).
The start_dialog function has no arguments. It returns the optional status passed to
done_dialog. The default value is 1 if the user pressed OK, 0 if the user pressed Cancel,
or -1 if all dialog boxes were terminated with term_dialog. But if done_dialog is
passed an integer status greater than 1, start_dialog returns this value, whose meaning depends on the application.

start_image
Starts the creation of an image in the dialog box tile

(start_image key)
Subsequent calls to fill_image, slide_image, and vector_image affect this image
until the application calls end_image. The key argument is a string that specifies the dialog box tile. The key argument is case-sensitive.
Do not use the set_tile function between start_image and end_image function
calls.

start_dialog

430

start_list
Starts the processing of a list in the list box or in the pop-up list dialog box tile

(start_list key [operation [index]])


The key argument is a string that specifies the dialog box tile. The key argument is casesensitive. The operation argument is an integer value whose meaning is summarized in
the following table.
List box codes for start_list
Value

Description

Change selected list contents

Append new list entry

Delete old list and create new list (the default)

The index argument is ignored unless the start_list call begins a change operation
(1), in which case index indicates the list item to change by the subsequent add_list
call. The index is zero based. If you dont specify operation, it defaults to 3 (create
new list), and if you specify operation but not index, the index defaults to 0.
Subsequent calls to add_list affect the list started by start_list until the application
calls end_list.
Do not use the set_tile function between start_list and end_list function calls.

Appendix A AutoLISP Function Reference

431

strcase
Returns a string where all alphabetic characters have been converted to upper
case or lower case

(strcase string [which])


If which is omitted or evaluates to nil, all alphabetic characters in string are converted
to upper case. If which is supplied and is not nil, all alphabetic characters in string are
converted to lower case.
(strcase "Sample")
(strcase "Sample" T)

returns "SAMPLE"
returns "sample"

The strcase function will correctly handle case mapping of the currently configured
character set.

strcat
Returns a string that is the concatenation of multiple strings

(strcat string1 [string2]...)


(strcat "a" "bout")
(strcat "a" "b" "c")
(strcat "a" "" "c")

returns "about"
returns "abc"
returns "ac"

strlen
Returns an integer that is the number of characters in a string

(strlen [string]...)
If multiple string arguments are provided, it returns the sum of the lengths of all arguments. Omitting the arguments or entering an empty string returns 0 (zero).
(strlen "abcd")
returns 4
(strlen "ab")
returns 2
(strlen "one" "two" "four" returns 10
(strlen)
returns 0

strcase

432

(strlen "")

returns 0

subst
Searches a list for an old item and returns a copy of the list with a new item
substituted in place of every occurrence of the old item

(subst newitem olditem lst)


If olditem is not found in lst, subst returns lst unchanged.
(setq sample (a b (c d) b))
(subst qq b sample)
returns (A QQ (C D) QQ)
(subst qq z sample)
returns (A B (C D) B)
(subst qq (c d) sample)
returns (A B QQ B)
(subst (qq rr) (c d) sample)
returns (A B (QQ RR) B)
(subst (qq rr) z sample)
returns (A B (C D) B)

When used in conjunction with assoc, subst provides a convenient means of replacing
the value associated with one key in an association list.
(setq who ((first john) (mid q) (last public)))
(setq old (assoc first who) sets old to (FIRST JOHN)
new (first j)
sets new to (FIRST J)
)
(subst new old who) returns ((FIRST J)(MID Q)(LAST PUBLIC))

substr
Returns a substring of a string

(substr string start [length])


The substr function starts at the start character position of string and continues for
length characters. If length is not specified, the substring continues to the end of
string. The start and length arguments must be positive integers.

Appendix A AutoLISP Function Reference

433

The first character of string is character number 1. This differs from other functions that
process elements of a list (like nth and ssname) that count the first element as 0.
(substr "abcde" 2)
(substr "abcde" 2 1)
(substr "abcde" 3 2)

returns "bcde"
returns "b"
returns "cd"

tablet
Retrieves and sets digitizer (tablet) calibrations

(tablet code [row1 row2 row3 direction])


Depending on the integer specified by code, tablet either retrieves the current digitizer
calibration or sets the calibration. If code is 0, tablet returns the current calibration. If
code is 1, it must be followed by the new calibration settings: row1, row2, row3, and
direction.
code

An integer. If the code you pass equals 0, tablet returns the current calibration; in this case, the remaining arguments must be omitted. If the code you pass equals 1, tablet sets the calibration
according to the arguments that follow; in this case, you must provide the other arguments.

row1, row2,
row3

Three 3D points. These three arguments specify the three rows of


the tablets transformation matrix.

direction

One 3D point. This is the vector (expressed in the World Coordinate


System, or WCS) that is normal to the plane that represents the surface of the tablet.

If the direction specified isnt normalized, tablet corrects it, so the direction it
returns when you set the calibration may differ from the value you passed. In a similar
way, the third element in row3 (Z) should always equal 1: tablet returns it as 1 even if
the row3 in the list specified a different value.
If tablet fails, it returns nil and sets the ERRNO system variable to a value that indicates the reason for the failure. This can happen if the digitizer is not a tablet.
A very simple transformation that can be established with tablet is the identity transformation:
(tablet 1 (1 0 0) (0 1 0) (0 0 1) (0 0 1))

With this transformation in effect, AutoCAD will receive, effectively, raw digitizer coordinates from the tablet. For example, if you pick the point with digitizer coordinates

tablet

434

(5000,15000), AutoCAD will see it as the point in your drawing with those same coordinates.
The TABMODE system variable allows AutoLISP routines to toggle the tablet on and
off.

tblnext
Finds the next item in a symbol table

(tblnext table-name [rewind])


The table-name argument is a string the identifies the symbol table. Valid table-name
values are "LAYER", "LTYPE", "VIEW", "STYLE", "BLOCK", "UCS", "APPID", "DIMSTYLE", and "VPORT". The string does not need to be upper case.
Since the vports function returns current VPORT table information, it may be easier to
use vports as opposed to tblnext to retrieve this information.
When tblnext is used repeatedly, it normally returns the next entry in the specified table
each time. The tblsearch function can set the next entry to be retrieved. However, if the
rewind argument is present and evaluates to a non-nil value, the symbol table is
rewound and the first entry in it is retrieved. If there are no more entries in the table, nil
is returned. Deleted table entries are never returned.
If an entry is found, it is returned as a list of dotted pairs of DXF-type codes and values.
(tblnext "layer" T)

Retrieves first layer

might return
((0 . "LAYER")
Symbol type
(2 . "0")
Symbol name
(70 . 0)
Flags
(62 . 7)
Color number, negative if off
(6 . "CONTINUOUS")
Linetype name
)

Note that there is no 1 group. AutoCAD remembers the last entry returned from each
table and returns the next one each time tblnext is called for that table. When you begin
scanning a table, be sure to supply a non-nil second argument to rewind the table and to
return the first entry.
Entries retrieved from the block table include a 2 group with the entity name of the first
entity in the block definition (if any). Thus, given a block called BOX,
(tblnext "block")

Appendix A AutoLISP Function Reference

435

Retrieves block definition

might return
((0 . "BLOCK")
(2 . "BOX")
(70 . 0)
(10 9.0 2.0 0.0)
(-2 . <Entity name: 40000126>)
)

Symbol type
Symbol name
Flags
Origin X,Y,Z
First entity

The entity name in the 2 group is accepted by entget and entnext, but not by other
entity access functions. For example, you cannot use ssadd to put it in a selection set. By
providing the 2 group entity name to entnext, you can scan the entities comprising a
block definition; entnext returns nil after the last entity in the block definition.
If a block contains no entities, the 2 group returned by tblnext is the entity name of its
endblk entity.

tblobjname
Returns the entity name of a specified symbol table entry

(tblobjname table-name symbol)


The tblobjname function searches the symbol table, table-name, for the symbol
name symbol and returns the entity name of that symbol table entry.
The entity name returned by tblobjname can be used in entget and entmod operations.

tblsearch
Searches a symbol table for a symbol name

(tblsearch table-name symbol [setnext])


The tblsearch function searches the symbol table, table-name, for the symbol name
symbol. Both names are converted to upper case automatically. If tblsearch finds an
entry for the given symbol name, it returns that entry in the format described for tblnext. If no such entry is found, it returns nil.
(tblsearch "style" "standard") Retrieves text style

might return
((0 . "STYLE")

Symbol name

tblobjname

436

(70 . 0)
(40 . 0.0)
(41 . 1.0)
(50 . 0.0)
(71 . 0)
(3 . "txt")
(4 . "")

Flags
Fixed height
Width factor
Obliquing angle
Generation flags
Primary font file
Bigfont file

Normally, tblsearch has no effect on the order of entries retrieved by tblnext. However, if tblsearch is successful and the setnext argument is present and non-nil, the
tblnext entry counter is adjusted so that the following tblnext call returns the entry
after the one returned by this tblsearch call.

term_dialog
Terminates all current dialog boxes as if the user had canceled each of them

(term_dialog)
If an application is terminated while any DCL files are open, AutoCAD automatically
calls term_dialog. This function is used mainly for aborting nested dialog boxes. The
term_dialog function always returns nil.

terpri
Prints a newline to the command line

(terpri)
The terpri function is not used for file I/O. To write a newline to a file, use prin1,
princ, or print.

Appendix A AutoLISP Function Reference

437

textbox
Measures a specified text object, and returns the diagonal coordinates of a box
that encloses the text

(textbox elist)
The elist argument is an entity definition list in the form returned by entget. It must
define a text object. If fields that define text parameters other than the text itself are omitted from elist, the current (or default) settings are used. If textbox is successful, it
returns a list of two points; otherwise it returns nil.
The minimum list accepted by textbox is that of the text itself.
(textbox ((1 . "Hello world.")))

might return ((0.0 0.0 0.0) (0.8 0.2 0.0))

In this case, textbox would use the current defaults for text to supply the remaining
parameters.
The points returned by textbox describe the bounding box of the text object as if its
insertion point is located at (0,0,0) and its rotation angle is 0. The first list returned is generally the point (0.0 0.0 0.0) unless the text object is oblique or vertical, or it contains letters with descenders (such as g and p). The value of the first point list specifies the offset
from the text insertion point to the lower-left corner of the smallest rectangle enclosing
the text. The second point list specifies the upper-right corner of that box. Regardless of
the orientation of the text being measured, the point list returned always describes the bottom-left and upper-right corners of this bounding box.

textpage
Switches from the graphics screen to the text screen

(textpage)
The textpage function is equivalent to textscr. This function always returns nil.

textbox

438

textscr
Switches from the graphics screen to the text screen (like the AutoCAD Flip
Screen function key)

(textscr)
The textscr function always returns nil.

trace
Aids in AutoLISP debugging

(trace function...)
The trace function sets the trace flag for the specified functions. Each time a specified
function is evaluated, a trace display appears showing the entry of the function
(indented to the level of calling depth) and prints the result of the function.
(trace my-func)

returns MY-FUNC

and sets the trace flag for function MY-FUNC. The trace function returns the last function
name passed to it.

See also the untrace function

trans
Translates a point (or a displacement) from one coordinate system to another

(trans pt from to [disp])


The pt argument is a list of three reals that can be interpreted as either a 3D point or a 3D
displacement (vector). The from argument indicates the coordinate system in which pt
is expressed, and to specifies the coordinate system of the returned point. The optional
disp argument, if present and non-nil, specifies that pt is to be treated as a 3D displace-

Appendix A AutoLISP Function Reference

439

ment rather than as a point. The from and to arguments can be an integer code (as specified in the following table), an entity name, or a 3D extrusion vector.
Coordinate system codes
Code

Coordinate system

World (WCS)

User (current UCS)

Display:
DCS of current viewport when used with code 0 or 1
DCS of current model space viewport when used with code 3

Paper space DCS (used only with code 2)

If you use an entity name for the from or to arguments it must be passed as returned by
the entnext, entlast, entsel, nentsel, and ssname functions. This lets you translate a point to and from the Object Coordinate System (OCS) of a particular object. (For
some objects, the OCS is equivalent to the WCS; for these objects, conversion between
OCS and WCS is a null operation.) A 3D extrusion vector (a list of three reals) is another
method of converting to and from an objects OCS. However, this does not work for those
objects whose OCS is equivalent to the WCS.
The trans function returns a 3D point (or displacement) in the requested to coordinate
system. For example, given a UCS that is rotated 90 degrees counterclockwise around the
World Z axis,
(trans (1.0 2.0 3.0) 0 1)
(trans (1.0 2.0 3.0) 1 0)

returns (2.0 -1.0 3.0)


returns (-2.0 1.0 3.0)

For example, to draw a line from the insertion point of a piece of text (without using
Osnap), you convert the text objects insertion point from the text objects OCS to the
UCS.
(trans text-insert-point text-ename 1)

You can then pass the result to the From point prompt.
Conversely, you must convert point (or displacement) values to their destination OCS
before feeding them to entmod. For example, if you want to move a circle (without using
the MOVE command) by the UCS-relative offset (1,2,3), you need to convert the displacement from the UCS to the circles OCS:
(trans (1 2 3) 1 circle-ename)

Then you add the resulting displacement to the circles center point.

trans

440

For example, if you have a point entered by the user and want to find out which end of a
line it looks closer to, you convert the users point from the UCS to the DCS.
(trans user-point 1 2)

Then you convert each of the lines endpoints from the OCS to the DCS.
(trans endpoint line-ename 2)

From there you can compute the distance between the users point and each endpoint of
the line (ignoring the Z coordinates) to determine which end looks closer.
The trans function can also transform 2D points. It does this by filling in the Z coordinate with an appropriate value. The Z component used depends on the from coordinate
system that was specified and on whether the value is to be converted as a point or as a
displacement. If the value is to be converted as a displacement, the Z value is always 0.0;
if the value is to be converted as a point, the filled-in Z value is determined as shown in
the following table.
Converted 2D point Z values
From

Filled-in Z value

WCS

0.0

UCS

Current elevation

OCS

0.0

Appendix A AutoLISP Function Reference

441

Converted 2D point Z values (continued)


From

Filled-in Z value

DCS

Projected to the current construction plane


(UCS XY plane + current elevation)

PSDCS

Projected to the current construction plane


(UCS XY plane + current elevation)

type
Returns the type of a specified item

(type item)
The types are returned as one of the atoms shown in the following table:
Symbol types
Type

Description

Type

Description

REAL

Floating-point numbers

SUBR

Internal functions

FILE

File descriptors

EXSUBR

External functions (ARX)

STR

Strings

PICKSET

Selection sets

INT

Integers

ENAME

Entity names

SYM

Symbols

PAGETB

Function paging table

LIST

Lists (and user functions)

Items that evaluate to nil (such as an unassigned symbol) return nil.

type

442

For example, given the assignments


(setq a 123 r 3.45 s "Hello!" x (a b c))
(setq f (open "name" "r"))

then
(type a)
(type a)
(type f)
(type r)
(type s)
(type x)
(type +)
(type nil)

returns SYM
returns INT
returns FILE
returns REAL
returns STR
returns LIST
returns SUBR
returns nil

The following example uses the type function:


(defun isint (a)
(if (= (type a) INT) is TYPE integer?
T
yes, return T
nil
no, return nil
)
)

unload_dialog
Unloads a DCL file

(unload_dialog dcl_id)
Unloads the DCL file associated with dcl_id (which was obtained from a previous
new_dialog call).
Always returns nil.

untrace
Clears the trace flag for the specified functions

(untrace function...)
Returns the last function name.

Appendix A AutoLISP Function Reference

443

The following code clears the trace flag for function MY-FUNC:
(untrace my-func)

returns MY-FUNC

See also the trace function

vector_image
Draws a vector in the currently active dialog box image

(vector_image x1 y1 x2 y2 color)
This function draws a vector in the currently active dialog box image (opened by
start_image) from the point (x1,y1) to (x2,y2). The color parameter is an AutoCAD
color number or one of the logical color numbers shown in the following table.
Symbolic names for the color attribute
Color
number

ADI
mnemonic

Description

BGLCOLOR

Current background of the AutoCAD graphics screen

15

DBGLCOLOR

Current dialog box background color

16

DFGLCOLOR

Current dialog box foreground color (for text)

18

LINELCOLOR

Current dialog box line color

The origin (0,0) is the upper-left corner of the image. You can obtain the coordinates of
the lower-right corner by calling the dimension functions (dimx_tile and dimy_tile).

vector_image

444

ver
Returns a string that contains the current AutoLISP version number

(ver)
The ver function should be used (with equal) to check the compatibility of programs.
The string takes the form
"AutoLISP Release X.X (nn)"

where X.X is the current version number and nn is a two letter language description.
(ver) might return "AutoLISP Release 14.0 (en)"

Examples of the two letter language descriptions are as follows:


(en) US/UK

(es) Spanish

(de) German

(it) Italian

(fr) French

WARNING! Before using ver in a Visual LISP program, you must initialize the variable *al-ver* in native AutoLISP. Use (setq *al-ver* (ver)) to initialize the variable. An error will result if you try to use ver without initializing *al-ver*.

vl-acad-defun
Defines a Visual LISP function symbol as a function in native AutoLISP (VLISP
Function)

(vl-acad-defun symbol)
symbol - function name.
Returns:
Indeterminate

Appendix A AutoLISP Function Reference

445

vl-acad-undefun
Undefines a Visual LISP function symbol so that it is no longer recognized as a
function in native AutoLISP (VLISP Function)

(vl-acad-undefun symbol)
symbol - function name.
Returns:
T, if successful
nil, if unsuccessful (for example, the function was not defined in AutoLISP)

vl-consp
Determines whether or not a list is nil (VLISP Function)

(vl-consp list-variable)
The vl-consp function determines whether a variable contains a valid list definition. It
returns T if list-variable is a non-nil list, and nil if it is not.
(vl-consp nil)
returns
(vl-consp t)
returns
(vl-consp (cons 0 "LINE"))returns

nil
nil
T

vl-directory-files
Lists all files in a given directory (VLISP Function)

(vl-directory-files [directory pattern directories])


Lists all files in a given directory

directory - (string) directory to collect files for; if nil or absent, use current directory
pattern - (string) DOS pattern for file name; if nil or absent, use "*.*"
directories - (fixnum) specifies if returned list should include directory names:
-1 - directories only
0 - files and directories (default)
1 - files only;

vl-acad-undefun

446

Returns a list of the files/sub-directories from the given directory which matches the pattern.
Examples:
_$ (vl-directory-files "c:/acadwin" "acad*.exe")
("ACAD.EXE" "ACADAPP.EXE" "ACADL.EXE" "ACADPS.EXE")
_$ (vl-directory-files "e:/acadwin" nil -1)
("." ".." "SUPPORT" "SAMPLE" "ADS" "FONTS" "IGESFONT" "SOURCE" "ASE")
_$ (vl-directory-files "E:/acad13c4" nil -1)
("." ".." "WIN" "COM" "DOS")

vl-every
Checks whether the predicate is true for every element combination (VLISP
Function)

(vl-every predicate-function list [more-lists]...)


The vl-every function passes the first element of each supplied list as an argument to
the test function, followed by the next element from each list, and so on. Evaluation stops
as soon as one of the lists runs out.
predicate-function - test function. May be any function that accepts as many arguments
as there are lists provided with vl-every, and returns T on any user-specified condition.
The predicate-function value should be:
symbol (function name) or
(LAMBDA (A1 A2) ...) form or
(FUNCTION (LAMBDA (A1 A2) ...)) form.
Returns:
T, if predicate function returned non-nil for every element combination
nil, otherwise.

Examples:
Check whether there are any empty files in the current directory:
_$ (vl-every
(lambda (fnm) (> (vl-file-size fnm) 0))
(vl-directory-files nil nil 1) )
T

Check whether number list in NLST is ordered by <=:


_$ (setq nlst (list 0 2 pi pi 4))

Appendix A AutoLISP Function Reference

447

(0 2 3.14159 3.14159 4)
_$ (vl-every <= nlst (cdr nlst))
T

vl-exe-filename
Returns full filename of the current Visual LISP executable (VLISP Function)

(vl-exe-filename)
Returns:
A string containing the file name
Example:
_$ (vl-exe-filename)
"C:/PROGRA~1/AUTOCA~1/VLISP/VLIDE.ARX"

vl-file-copy
Copies or appends the contents of one file to another file (VLISP Function)

(vl-file-copy "source-filename" "destination-filename" [append?])


Copy or append the contents of one file to another file. The vl-file-copy function will
not overwrite an existing file, only append to it.
source-filename - string
destination-filename - string
append? - If present and not nil, source is appended to destination file.
Returns:
non-nil: file successfully copied
nil: an error occurred. May be:

<source-filename> is not readable


<source-filename> is a directory
<append?> is absent or nil and destination-filename exists
destination-filename cannot be opened for output (e.g., illegal file name or write protected file system)
<source-filename> is the same as <destination-filename>

vl-exe-filename

448

Example:
_$ (vl-file-copy "c:/autoexec.bat" "c:/newauto.bat")
1417

vl-file-delete
Deletes a file (VLISP Function)

(vl-file-delete "filename")
filename - string containing name of file to be deleted
Returns:
T, if successful
nil, if delete failed

vl-file-directory-p
Determines if a file name refers to a directory (VLISP Function)

(vl-file-directory-p "filename")
filename - file to be tested
Returns:
T, if filename is the name of a directory, nil if it is not
Examples:
_$ (vl-file-directory-p "sample")
T
_$ (vl-file-directory-p "yinyang")
nil
_$ (vl-file-directory-p "c:/program files/autocad r14")
T
_$ (vl-file-directory-p "c:/program files/autocad r14/vlisp/yinyang.lsp")
nil

Appendix A AutoLISP Function Reference

449

vl-file-rename
Renames a file (VLISP Function)

(vl-file-rename "old-filename" "new-filename")


old-filename - name of the file you want to rename
new-filename - new name to be assigned to the file
Returns:
T, if rename completed successful
nil, if rename failed (for example, if new-filename already exists)

Example:
(vl-file-rename "c:/newauto.bat" "c:/myauto.bat")
T

vl-file-size
Determines the size of a file, in bytes (VLISP Function)

(vl-file-size "filename")
filename - name of file to be sized
Returns:
nil - filename is not readable

0 - filename is a directory or an empty file


integer - size of filename, in bytes
Example:
_$ (vl-file-size "c:/autoexec.bat")
1417

vl-file-rename

450

vl-file-systime
Returns last modification time of the specified file (VLISP Function)

(vl-file-systime "filename")
filename - name of file to be checked
Returns:
A list containing the modification date and time, or nil, if the file is not found.
The list returned contains the following elements:
year month day-of-week, day-of-month, hours, minutes, seconds
Note that Monday is day 1 of day-of-week, Tuesday is day 2, etc.
Example:
_$ (vl-file-systime "c:/program files/autocad r14/vlisp/sample/yinyang.lsp")
(1998 4 3 8 10 6 52 0)

The file was last modified in1998, in the 4th month of the year (April), the 3rd day of the
week (Wednesday), at 10:06:52.

vl-filename-base
Returns the name of a file, after stripping out the directory path and extension
(VLISP Function)

(vl-filename-base filename)
filename - file name
The vl-filename-base function does not check to see if the file exists.
Returns:
Uppercase filename, with directory and extension stripped
Examples:
_$ (vl-filename-base "c:\\acadwin\\acad.exe")
"ACAD"
_$ (vl-filename-base "c:\\acadwin")
"ACADWIN"

Appendix A AutoLISP Function Reference

451

vl-filename-directory
Returns the directory path of a file, after stripping out the name and extension
(VLISP Function)

(vl-filename-directory filename)
filename - compete file name, including path
The vl-filename-directory function does not check to see if a file of this name
exists. Slashes (/) and backslashes (\) are accepted as directory delimiters.
Returns:
Directory portion of filename, in upper case
Examples:
_$ (vl-filename-directory "c:\\acadwin\\acad.exe")
"C:\\ACADWIN"
_$ (vl-filename-directory "acad.exe")
""

vl-filename-extension
Returns the extension from a file name, after stripping out the rest of the name
(VLISP Function)

(vl-filename-extension filename)
filename - file name, including extension
The vl-filename-extension function does not check to see if a file of this name
exists
Returns:
Extension portion of filename, starting with a period (.) and converted to uppercase
Examples:
(vl-filename-extension "c:\\acadwin\\acad.exe")
".EXE"
(vl-filename-extension "c:\\acadwin\\acad")
nil

vl-filename-directory

452

vl-filename-mktemp
Calculates a unique file name to be used for a temporary file (VLISP Function)

(vl-filename-mktemp [pattern directory extension])


pattern - string containing a file name pattern; if nil or absent, use "$VL~~"
directory - string naming the directory for temporary files; if nil or absent, Visual
LISP uses the following order to select a directory:
- Directory specified in pattern, if any
- TMP environment variable
- TEMP environment variable
- current directory
extension - a string naming the extension to be assigned to the file; if nil or absent,
Visual LISP uses the extension part of pattern (which may be an empty string)
Returns:
A file name in the following format:
directory\base<XXX><.extension>
where:
base is up to 5 characters, taken from pattern
XXX is a 3 character unique combination
All file names generated by vl-filename-mktemp during a Visual LISP session are
deleted when you exit Visual LISP.
Examples:
_$ (vl-filename-mktemp)
"H:\\TMP\\$VL~~004"
_$ (vl-filename-mktemp "myapp.del")
"H:\\TMP\\MYAPP005.DEL"
_$ (vl-filename-mktemp "c:\\acadwin\\myapp.del")
"C:\\ACADWIN\\MYAPP006.DEL"
_$ (vl-filename-mktemp "c:\\acadwin\\myapp.del")
"C:\\ACADWIN\\MYAPP007.DEL"
_$ (vl-filename-mktemp "myapp" "c:\\acadwin")
"C:\\ACADWIN\\MYAPP008"
_$ (vl-filename-mktemp "myapp" "c:\\acadwin" ".del")
"C:\\ACADWIN\\MYAPP00A.DEL"

Appendix A AutoLISP Function Reference

453

vl-init
Mimics AutoLISP initialization on an Open or New drawing command (VLISP
Function)

(vl-init)
Returns:
T, if initialization is successful

vl-list*
Constructs and returns a list (VLISP Function)

(vl-list* object [more-objects]...)


object - any LISP object
more-objects - any LISP objects
vl-list* is similar to list, but it will place the last of the more-objects in the final cdr
of the result list. If the last argument to vl-list* is an atom, the result is a dotted list. If
the last argument is a list, it is appended to all previous arguments added to the.

Returns:
An atom, if object is an atom and no more objects are specified
A dotted pair, if object and all more-objects specified are atoms
A dotted list, if the last argument is an atom and neither of the previous conditions are
true
A list, if none of the previous statements are true
Examples:
(vl-list* 1)
1
(vl-list* 0 "text")
(0 . "TEXT")
(vl-list* 1 2 3)
(1 2 . 3)
(vl-list* 1 2 (3 4))
(1 2 3 4)

vl-init

454

vl-list->string
Combines the characters associated with a list of integers into a string (VLISP
Function)

(vl-list->string char-codes-list)
char-codes-list - list of non-negative integers; integer must be less than 256
Returns:
A string of characters, with each character based on one of the integers supplied in
char-codes-list
Examples:
(vl-list->string nil)
""
(vl-list->string (49 50))
"12"

vl-list-length
Calculates list length of a true list (VLISP Function)

(vl-list-length list-or-cons-object)
list-or-cons-object - a true or dotted list.
Returns:
An integer containing the list length, if the argument is a true list
nil, if list-or-cons-object is a circular or dotted list

Compatibility note: The vl-list-length function returns nil for a dotted list, while
the corresponding Common Lisp function issues an error message if the argument is a dotted list.
Examples:
(vl-list-length nil)
0
(vl-list-length (1 2))

2
(vl-list-length (1 2 . 3))

nil

Appendix A AutoLISP Function Reference

455

vl-member-if
Determines if the predicate is true for one of the list members (VLISP Function)

(vl-member-if predicate-function list)


predicate-function - test function. May be any function that accepts a single argument
and returns T for any user-specified condition. The predicate-function value should be
one of the following:
symbol (function name)
(LAMBDA (A1) ...) form
(FUNCTION (LAMBDA (A1) ...)) form
The vl-member-if function passes each element in list to the function specified in
predicate-function. If the function returns a non-nil value, vl-member-if returns the
rest of the list in the same manner as the member function.
Returns:
A list, starting with the first element that passes the test and containing all elements
following this in the original argument
nil, if none of the elements passes the test condition

Examples:
(COMMAND "_.LINE" (0 50) (50 50) nil)
nil
(vl-member-if
(lambda (x) (= (cdr x) "AcDbLine"))
(entget (entlast)))
((100 . "AcDbLine") (10 0.0 50.0 0.0) (11 50.0 50.0 0.0) (210 0.0 0.0 1.0))

vl-member-if-not
Determines if the predicate is nil for one of the list members (VLISP Function)

(vl-member-if-not predicate-function list)


predicate-function - test function. May be any function that accepts a single argument
and returns T for any user-specified condition. The predicate-function value should be
one of the following:
symbol (function name)
(LAMBDA (A1) ...) form

vl-member-if

456

(FUNCTION (LAMBDA (A1) ...))form


The vl-member-if-not function passes each element in list to the function specified in
predicate-function. If the function returns nil, vl-member-if-not returns the rest of
the list in the same manner as the member function.
Returns:
A list, starting with the first element that fails the test and containing all elements following this in the original argument
nil, if none of the elements fails the test condition

Examples:
_$ (vl-member-if-not atom (1 "Str" (0 . "line") nil t))
((0 . "line") nil T)

vl-position
Returns the index of the specified list item (VLISP Function)

(vl-position symbol list)


symbol - any AutoLISP symbol
list - a true list
Returns:
An integer containing the index position of the specified item in the list, or nil if the
item does not exist in the list
Note that the first list element is index 0, the second element is index 1, and so on.
Example:
_$ (setq stuff (list "a" "b" "c" "d" "e"))
("a" "b" "c" "d" "e")
_$ (vl-position "c" stuff)
2

Appendix A AutoLISP Function Reference

457

vl-prin1-to-string
Returns the string representation of any LISP object as if it were output by the
prin1 function (VLISP Function)

(vl-prin1-to-string object)
object - any LISP object
Returns:
String-printed representation of object, as output by prin1
Examples:
_$ (vl-prin1-to-string "abc")
"\"abc\""
_$ (vl-prin1-to-string "c:\\acadwin")
"\"C:\\\\ACADWIN\""
_$ (vl-prin1-to-string my-var)
"MY-VAR"

vl-princ-to-string
Returns the string representation of any LISP object as if it were output by the
princ function (VLISP Function)

(vl-princ-to-string object)
object - any LISP object
Returns:
String-printed representation of object, as output by princ
Examples:
_$ (vl-princ-to-string "abc")
"abc"
_$ (vl-princ-to-string "c:\\acadwin")
"C:\\ACADWIN"
_$ (vl-princ-to-string my-var)
"MY-VAR"

vl-prin1-to-string

458

vl-registry-delete
Deletes the specified key or value from the Windows Registry (VLISP Function)

(vl-registry-delete reg-key [val-name])


reg-key - Registry key (string)
val-name - Registry value (string)
If val-name is supplied and is not nil, the specified value will be purged from the Registry. If val-name is absent or nil, the function deletes the specified key and all of its
values.
This function cannot delete a key that has subkeys. To delete a subtree you must use
vl-registry-descendents to enumerate all subkeys and delete all of them.

Returns:
T if successful, nil otherwise

Example:
_$ (vl-registry-write "HKEY_CURRENT_USER\\Test" "" "test data")
"test data"
_$ (vl-registry-read "HKEY_CURRENT_USER\\Test")
"test data"
_$ (vl-registry-delete "HKEY_CURRENT_USER\\Test")
T

vl-registry-descendents
Returns a list of subkeys or value names for the specified Registry key (VLISP
Function)

(vl-registry-descendents reg-key [val-names])


reg-key - Registry key (string)
val-names - Registry values (string)
If val-names is supplied and is not nil, the specified value names will be listed from the
Registry. If val-name is absent or nil, the function displays all subkeys of reg-key.
Returns:
A list of strings, if successful, nil otherwise

Appendix A AutoLISP Function Reference

459

Example:
$ (vl-registry-descendents "HKEY_LOCAL_MACHINE\\SOFTWARE")
("Description" "Program Groups" "ORACLE" "ODBC" "Netscape" "Microsoft")

vl-registry-read
Returns data stored in the Windows Registry for the specified key/value pair
(VLISP Function)

(vl-registry-read reg-key [val-name])


reg-key - Registry key (string)
val-name - Registry value (string)
If val-name is supplied and is not nil, the specified value will be read from the Registry.
If val-name is absent or nil, the function reads the specified key and all of its values.
Returns:
Registry data (a string) if successful, nil otherwise
Example:
$ (vl-registry-read "HKEY_CURRENT_USER\\Test")
nil
_$ (vl-registry-write "HKEY_CURRENT_USER\\Test" "" "test data")
"test data"
_$ (vl-registry-read "HKEY_CURRENT_USER\\Test")
"test data"

vl-registry-write
Creates a key in the Windows Registry (VLISP Function)

(vl-registry-write reg-key [val-name val-data])


reg-key - Registry key (string)
val-name - Registry value (string)
val-data - Registry data (string)
If val-name is not supplied or is nil, a default value for the key is written. If val-name is
supplied and val-data is not specified, an empty string is stored.

vl-registry-read

460

Returns:
val-data, if successful, nil otherwise
Example:
_$ (vl-registry-write "HKEY_CURRENT_USER\\Test" "" "test data")
"test data"
_$ (vl-registry-read "HKEY_CURRENT_USER\\Test")
"test data"

vl-remove
Removes elements from a list (VLISP Function)

(vl-remove element-to-remove list)


element-to-remove - value of element to be removed; may be any LISP data type
list - any list
Returns:
The list with all elements except those equal to element-to-remove
Example:
(vl-remove pi (list pi t 0 "abc"))

(T 0 "abc")

vl-remove-if
Returns all elements of the supplied list which fail the test function (VLISP
Function)

(vl-remove-if predicate-function list)


predicate-function - test function. May be any function that accepts one argument and
returns T on a user-specified condition. The predicate-function value should be one of
the following:
symbol (function name)
(LAMBDA (A1 A2) ...) form
(FUNCTION (LAMBDA (A1 A2) ...)) form

Returns:
A list containing all elements of list for which predicate-function returns nil

Appendix A AutoLISP Function Reference

461

Examples:
_$ (vl-remove-if vl-symbolp (list pi t 0 "abc"))

(3.14159 0 "abc")

vl-remove-if-not
Returns all elements of the supplied list which pass the test function (VLISP
Function)

(vl-remove-if-not predicate-function list)


predicate-function - test function. May be any function that accepts one argument and
returns a non-nil value for any user-specified condition. The predicate-function value
should be one of the following:
symbol (function name)
(LAMBDA (A1) ...) form
(FUNCTION (LAMBDA (A1) ...)) form

Returns:
A list containing all elements of list for which predicate-function returns a non-nil
value
Examples:
_$ (vl-remove-if-not vl-symbolp (list pi t 0 "abc"))
(T)

vl-some
Checks whether the predicate is not nil for one element combination (VLISP
Function)

(vl-some predicate-function list [more-lists]...)


predicate-function - test function. Can be any function that accepts as many arguments
as there are lists provided with vl-some, and returns T on a user-specified condition.
The predicate-function value should be one of the following:
symbol (function name)
(LAMBDA (A1 A2 ...) ...) form
(FUNCTION (LAMBDA (A1 A2 ...) ...)) form

vl-remove-if-not

462

The vl-some function passes the first element of each supplied list as an argument to the
test function, then the next element from each list, and so on. Evaluation stops as soon as
the predicate function returns non-nil for an argument combination or one of the lists
runs out.
Returns:
predicate value, if predicate function returned non-nil
nil, otherwise

Examples:
Check whether number list NLST has equal elements in sequence:
(setq nlst (list 0 2 pi pi 4))
(0 2 3.14159 3.14159 4)
(vl-some = nlst (cdr nlst))
T

vl-sort
Sorts the elements in a list according to a given compare function (VLISP
Function)

(vl-sort list less?-function)


list - any list
less?-function - compare function. Can be any function that accepts two arguments
and returns T (or any non-nil value) if the first argument precedes the second in the
sort order. The value of less?-function should be one of the following:
symbol (function name)
(LAMBDA (A1 A2) ...) form
(FUNCTION (LAMBDA (A1 A2) ...)) form

Returns:
A list containing the elements of list in the order specified by less?-function. Duplicate
elements may be eliminated from the list.
Examples:
Sort a list of numbers:
_$ (vl-sort (3 2 1 3) <)
(1 2 3) ; Note that only one 3 remains in the result list

Appendix A AutoLISP Function Reference

463

Sort a list of 2D points by Y coordinate:


_$ (vl-sort ((1 3) (2 2) (3 1))
(function (lambda (e1 e2)
(< (cadr e1) (cadr e2)) ) ) )
((3 1) (2 2) (1 3))

Sort a list of symbols:


_$ (vl-sort
(a d c b a)
(lambda (s1 s2)
(< (vl-symbol-name s1) (vl-symbol-name s2)) ) )
(A B C D)
; Note that only one A remains in the result list

vl-sort-i
Sorts the elements in a list according to a given compare function, and returns
the element index numbers (VLISP Function)

(vl-sort-i list less?-function)


list - any list
less?-function - compare function. Can be any function that accepts two arguments
and returns T (or any non-nil value) if the first argument precedes the second in the
sort order. The value of less?-function should be one of the following:
symbol (function name)
(LAMBDA (A1 A2) ...) form
(FUNCTION (LAMBDA (A1 A2) ...)) form

Returns:
A list containing the index values of the elements of list, sorted in the order specified
by less?-function. Duplicate elements will be retained in the result.
Examples:
Sort a list of characters in descending order:
_$ (vl-sort-i ("a" "d" "f" "c") >)
(2 1 3 0)

The sorted list order is "f" "d" "c" "a"; "f" is the 3rd element (index 2) in the original list,
"d" is the 2nd element (index 1) in the list, and so on.
Sort a list of numbers in ascending order:
_$ (vl-sort-i (3 2 1 3) <)
(2 1 3 0) ; Note that both occurrences of 3 are accounted for in the result list

vl-sort-i

464

Sort a list of 2D points by Y coordinate:


_$ (vl-sort-i ((1 3) (2 2) (3 1))
(function (lambda (e1 e2)
(< (cadr e1) (cadr e2)) ) ) )
(2 1 0)

Sort a list of symbols:


_$ (vl-sort-i
(a d c b a)
(lambda (s1 s2)
(< (vl-symbol-name s1) (vl-symbol-name s2)) ) )
(4 0 3 2 1)
; Note that both as are accounted for in the result list

vl-string->list
Converts a string into a list of character codes (VLISP Function)

(vl-string->list string)
Returns:
A list, each element of which is an integer representing the character code of the corresponding character in string
Examples:
_$ (vl-string->list "")
nil
_$ (vl-string->list "12")
(49 50)

vl-string-elt
Returns the ASCII representation of the character at a specified position in a
string (VLISP Function)

(vl-string-elt string position)


string - string to be inspected
position - displacement in the string; first character is displacement 0
Note that an error occurs if position is outside of the range of the string
Returns:
An integer denoting the ascii representation of the character at the specified position

Appendix A AutoLISP Function Reference

465

Example:
_$ (vl-string-elt "May the Force be with you" 8)
70

vl-string-left-trim
Removes the specified characters from the beginning of a string (VLISP
Function)

(vl-string-left-trim character-set string)


character-set - a string listing the characters to be removed
string - string to be stripped
Returns:
A string containing a substring of string with all leading characters in character-set
removed
Examples:
_$ (vl-string-left-trim " \t\n" "\n\t STR ")
"STR "
_$ (vl-string-left-trim "12456789" "12463CPO is not R2D2")
"3CPO is not R2D2"
_$ (vl-string-left-trim " " " There are too many spaces here")
"There are too many spaces here"

vl-string-mismatch
Returns the length of the longest common prefix for two strings, starting at
specified positions (VLISP Function)

(vl-string-mismatch str1 str2 [pos1 pos2 ignore-case-p])


str1 - first string
str2 - second string
pos1 - position to search from in the first string; 0 if omitted
pos2 - position to search from in the second string; 0 if omitted
ignore-case-p - if T is specified for this argument, case is ignored, otherwise case is
considered

vl-string-left-trim

466

Returns:
An integer
Examples:
_$ (vl-string-mismatch "VL-FUN" "VL-VAR")
3
_$ (vl-string-mismatch "vl-fun" "avl-var")
0
_$ (vl-string-mismatch "vl-fun" "avl-var" 0 1)
3
_$ (vl-string-mismatch "VL-FUN" "Vl-vAR")
1
_$ (vl-string-mismatch "VL-FUN" "Vl-vAR" 0 0 T)
3

vl-string-position
Looks for a character with the specified ascii code in a string (VLISP Function)

(vl-string-position char-code str [start-pos1 from-end-p])


char-code - integer representation of the character to be searched for
str - string to be searched
pos - position to begin searching from in the string (first character is 0); 0 if omitted
from-end-p - if T is specified for this argument, the search begins at the end of the
string and continues backward to pos
Returns:
An integer representing the displacement in the string at which char-code was found;
nil if the character is not found

Examples:
_$ (vl-string-position (ascii "z") "azbzc")
1
_$ (vl-string-position 122 "azbzc")
1
_$ (vl-string-position (ascii "z") "azbzc" nil t)
3

Note in the previous example that vl-string-position returned the first occurrence
of the letter "z," but indicated its displacement counting back from the end of the string

Appendix A AutoLISP Function Reference

467

_$ (vl-string-position (ascii "x") "azbzc")


nil

vl-string-right-trim
Removes the specified characters from the end of a string (VLISP Function)

(vl-string-right-trim character-set string)


character-set - a string listing the characters to be removed
string - string to be stripped
Returns:
A string containing a substring of string with all trailing characters in character-set
removed
Examples:
_$ (vl-string-right-trim " \t\n" " STR \n\t ")
" STR"
_$ (vl-string-right-trim "1356789" "3CPO is not R2D267891")
"3CPO is not R2D2"
_$ (vl-string-right-trim " " "There are too many spaces at the end
"There are too many spaces at the end"

")

vl-string-search
Searches for the specified pattern in a string (VLISP Function)

(vl-string-search pattern string [start-pos])


pattern - string to be searched for within
string - string to be searched for
start-pos - starting position of search; 0, if omitted
Returns:
An integer representing the position in the string where the specified pattern was
found, or nil if the pattern is not found; the first character of the string is position 0
Examples:
_$ (vl-string-search "foo" "pfooyey on you")
1

vl-string-right-trim

468

_$ (vl-string-search "who" "pfooyey on you")


nil
_$ (vl-string-search "foo" "fooey-more-fooey" 1)
11

vl-string-subst
Substitutes one string for another, within a string (VLISP Function)

(vl-string-subst new-str pattern string [start-pos])


new-str - string to be substituted for pattern
pattern - string to be searched for within string
string - string to be searched
start-pos - starting position of search; 0, if omitted
Note that the search is case sensitive.
Returns:
The value of string after any substitutions have been made
Example:
_$ (vl-string-subst "Obi-wan" "Ben" "Ben Kenobi")
"Obi-wan Kenobi"
_$ (vl-string-subst "Obi-wan" "Ben" "ben Kenobi")
"ben Kenobi"
_$ (vl-string-subst "Obi-wan" "Ben" "Ben \"Ben\" Kenobi" 3)
"Ben \"Obi-wan\" Kenobi"

vl-string-translate
Replaces characters in a string with a specified set of characters (VLISP
Function)

(vl-string-translate source-set dest-set str)


source-set - string of characters to be matched
dest-set - string of characters to be substituted for those in source-set
str - string to be searched and translated

Appendix A AutoLISP Function Reference

469

Returns:
The value of str after any substitutions have been made
Examples:
_$ (vl-string-translate "abcABC" "123123" "A is a, B is b, C is C")
"1 is 1, 2 is 2, 3 is 3"
_$ (vl-string-translate "abc" "123" "A is a, B is b, C is C")
"A is 1, B is 2, C is C"

vl-string-trim
Removes the specified characters from the beginning and end of a string (VLISP
Function)

(vl-string-trim char-set str)


char-set - a string containing the list of characters to be removed from str
str - string to be trimmed
Returns:
str, after any trimming has occurred
Examples:
_$ (vl-string-trim " \t\n" " \t\n STR \n\t ")
"STR"
_$ (vl-string-trim "this is junk" "this is junk Dont call this junk! this is junk")
"Dont call this junk!"
_$ (vl-string-trim " " "
"Leave me alone"

Leave me alone

")

vl-symbol-name
Returns a string containing the name of a symbol (VLISP Function)

(vl-symbol-name symbol)
symbol - any LISP symbol
Returns:
A string containing the name of the supplied symbol argument
Examples:

vl-string-trim

470

_$ (vl-symbol-name S::STARTUP)
"S::STARTUP"
_$ (progn (setq sym my-var) (vl-symbol-name sym))
"MY-VAR"
_$ (vl-symbol-name 1)
; *** ERROR: bad argument type: symbolp 1

vl-symbol-value
Returns the current value bound to a symbol (VLISP Function)

(vl-symbol-value symbol)
symbol - any LISP symbol
This function is equivalent to the AutoLISP EVAL function, but does not call the LISP
evaluator.
Examples:
_$ (vl-symbol-value t)
T
_$ (vl-symbol-value PI)
3.14159
_$ (progn (setq sym PAUSE) (vl-symbol-value sym))
"\\"

vl-symbolp
Identifies whether or not a specified object is a symbol (VLISP Function)

(vl-symbolp object)
object - any LISP object
Returns:
T if object is a symbol
nil if object is not a symbol

Examples:
_$ (vl-symbolp t)
T
_$ (vl-symbolp nil)

Appendix A AutoLISP Function Reference

471

nil
_$ (vl-symbolp 1)
nil
_$ (vl-symbolp (list 1))
nil

vlax-3D-point
Creates ActiveX-compatible 3D point structure (VLISP Function)

(vlax-3D-point list)
(vlax-3D-point x y [z])
list - a list of 2 or 3 numbers, representing points
x, y - numbers representing X and Y coordinates of a point
z - number (optional) representing Z coordinate of a point
Returns:
The structure created
Examples:
$ (vlax-3D-point 5 20)
(5.0 20.0 0.0)
_$ (vlax-3D-point (33.6 44.0 90.0))
(33.6 44.0 90.0)

vlax-add-cmd
Adds commands to a group (VLISP Function)

(vlax-add-cmd global-name func-sym [local-name cmd-flags])


global-name - string
func-sym - a symbol naming an AutoLISP function with zero arguments
local-name - string (defaults to global-name)
cmd-flags - integer (defaults to ACRX_CMD_MODAL | ACRX_CMD_REDRAW)
Primary flags:
ACRX_CMD_MODAL0x00
Command cannot be invoked while another command is active

vlax-3D-point

472

ACRX_CMD_TRANSPARENT0x01
Command can be invoked while another command is active
Secondary flags:
ACRX_CMD_USEPICKSET0x02
When the pickfirst set is retrieved it is cleared within AutoCAD. Command will be
able to retrieve the pickfirst set. Command cannot retrieve nor set grips.
ACRX_CMD_REDRAW0x04
When the pickfirst set or grip set is retrieved, neither will be cleared within AutoCAD.
Command can retrieve the pickfirst set and the grip set.
If both ACRX_CMD_USEPICKSET and ACRX_CMD_REDRAW are set, the effect is
the same as if just ACRX_CMD_REDRAW is set. For more information on the flags,
refer to ObjectARX documentation.
Commands are added to VLC-<AppName> group (this group is also used in the regapp
function). No more than 50 commands can be added to a group.
Example:
The next function hello-autocad has no C: prefix, but we use vlax-add-cmd to make it visible as an ARX-style command at the Command: prompt
>(defun hello-autocad () (hello "Visual LISP"))
>(vlax-add-cmd "hello-autocad" hello-autocad)

vlax-curve-getArea
Returns the area inside the curve (VLISP Function)

(vlax-curve-getArea curve-obj)
curve-obj - VLA object to be measured
Returns:
Real number if successful, otherwise nil

Appendix A AutoLISP Function Reference

473

vlax-curve-getDistAtParam
Returns the length of the curves segment from the curves beginning to the
specified point (VLISP Function)

( vlax-curve-getDistAtParam curve-obj param)


curve-obj - VLA object to be measured
param - parameter specifying a point on the curve
Returns:
Real number if successful, otherwise nil

vlax-curve-getDistAtPoint
Returns the length of the curves segment between the curves start point and the
specified point (VLISP Function)

( vlax-curve-getDistAtPoint curve-obj point)


curve-obj - VLA object to be measured
point - 3-d point list (in WCS coordinates) on the curve
Returns:
Real number if successful, otherwise nil

vlax-curve-getEndParam
Returns the parameter of the endpoint of the curve (VLISP Function)

(vlax-curve-getEndParam curve-obj)
curve-obj - VLA object to be measured
Returns:
Real number if successful, otherwise nil

vlax-curve-getDistAtParam

474

vlax-curve-getEndPoint
Returns the end point (in WCS coordinates) of the curve (VLISP Function)

(vlax-curve-getEndPoint curve-obj)
curve-obj - VLA object to be measured
Returns:
3-d point list if successful, otherwise nil

vlax-curve-getParamAtDist
Distance along the curve from the beginning of the curve to the location of the
specified parameter (VLISP Function)

(vlax-curve-getParamAtDist curve-obj param)


curve-obj - VLA object to be measured
param - parameter specifying a point on the curve
Returns:
Real number if successful, otherwise nil

vlax-curve-getParamAtPoint
Returns the parameter of the curve at the point (VLISP Function)

(vlax-curve-getParamAtPoint curve-obj point)


curve-obj - VLA object to be measured
point - 3-d point list (in WCS coordinates) on the curve
Returns:
Real number if successful, otherwise nil

Appendix A AutoLISP Function Reference

475

vlax-curve-getPointAtDist
Returns the point (in WCS coordinates) along a curve at the distance specified by
the user (VLISP Function)

(vlax-curve-getPointAtDist curve-obj dist)


curve-obj - VLA object to be measured
dist - distance along the curve from the beginning of the curve to the location of the
specified point
Returns:
3-d point list if successful, nil otherwise

vlax-curve-getPointAtParam
Determines the point on the curve that corresponds to the param parameter and
returns the point (VLISP Function)

(vlax-curve-getPointAtParam curve-obj param)


curve-obj - VLA object to be measured
param - parameter on the curve at which the point is desired
Returns:
3-d point list if successful, nil otherwise

vlax-curve-getStartParam
Returns the start parameter on the curve (VLISP Function)

(vlax-curve-getStartParam curve-obj)
curve-obj - VLA object to be measured
Returns:
Real number if successful, otherwise nil

vlax-curve-getPointAtDist

476

vlax-curve-getStartPoint
Returns the start point (in WCS coordinates) of the curve (VLISP Function)

(vlax-curve-getStartPoint curve-obj)
curve-obj - VLA object to be measured
Returns:
3-d point list if successful, nil otherwise

vlax-curve-isClosed
Determines if the specified curve is closed (i.e., start point is same as end point)
(VLISP Function)

(vlax-curve-isClosed curve-obj)
curve-obj - VLA object to be tested
Returns:
T if the curve is closed, nil otherwise

vlax-curve-isPeriodic
Determines if the specified curve has an infinite range in both directions and
there is a period value dT, such that there is a point on curve at (u + dT) = point
on curve (u), for any parameter u. (VLISP Function)

(vlax-curve-isPeriodic curve-obj)
curve-obj - VLA object to be tested
Returns:
T if the curve is periodic, nil otherwise

Appendix A AutoLISP Function Reference

477

vlax-curve-isPlanar
Determines if there is a plane that contains the curve (VLISP Function)

(vlax-curve-isPlanar curve-obj)
curve-obj - VLA object to be tested
Returns:
T if the there is a plane that contains the curve, nil otherwise

vlax-curve-getClosestPointTo
Returns the point (in WCS coordinates) on a curve that is nearest to the specified
point (VLISP Function)

(vlax-curve-getClosestPointTo curve-obj givenPnt [extend])


curve-obj - VLA object to be measured
givenPnt - point (in WCS coordinates) for which to find the nearest point on the curve
extend (optional) - boolean; if non-nil value is specified,
vlax-curve-getClosestPointTo extends the curve when searching for the
nearest point
Returns:
3-d point list if successful, nil otherwise

vlax-curve-getClosestPointToProjection
Returns the point (in WCS coordinates) on a curve that is nearest to the specified
point (VLISP Function)

(vlax-curve-getClosestPointToProjection curve-obj givenPnt normal [extend])


curve-obj - VLA object to be measured
givenPnt - point (in WCS coordinates) for which to find the nearest point on the curve
normal - normal vector (in WCS coordinates) for the plane to project onto

vlax-curve-isPlanar

478

extend (optional) - boolean; if non-nil value is specified,


vlax-curve-getClosestPointToProjection extends the curve when searching
for the nearest point
Returns:
3-d point list if successful, nil otherwise

vlax-curve-getFirstDeriv
Returns the first derivative (in WCS coordinates) of a curve at the specified
location (VLISP Function)

(vlax-curve-getFirstDeriv curve-obj param)


curve-obj - VLA object to be measured
param - parameter of the location on the curve at which to find the first derivative
Returns:
3-d vector list if successful, nil otherwise

vlax-curve-getSecondDeriv
Returns the second derivative (in WCS coordinates) of a curve at the specified
location (VLISP Function)

(vlax-curve-getSecondDeriv curve-obj param)


curve-obj - VLA object to be measured
param - parameter of the location on the curve at which to find the second derivative
Returns:
3-d vector list if successful, nil otherwise

Appendix A AutoLISP Function Reference

479

vlax-dump-object
Lists an objects methods and properties (VLISP Function)

(vlax-dump-object obj)
obj - VLA object
Returns:
T, if successful, or an error message, if an invalid object name is supplied
Example
_$ (setq aa (vlax-get-acad-object))
#<VLA-OBJECT IAcadApplication 00b3b91c>
_$ (vlax-dump-object aa)
; IAcadApplication: AutoCAD Application Interface
; Property values:
; ActiveDocument (RO) = #<VLA-OBJECT IAcadDocument 01b52fac>
; Application (RO) = #<VLA-OBJECT IAcadApplication 00b3b91c>
; Caption (RO) = "AutoCAD - [Drawing.dwg]"
; FullName (RO) = "C:\\Program Files\\AutoCAD R14\\acad.exe"
; Height = 638
; Left = 264
; LocaleId (RO) = 1033
; Name (RO) = "AutoCAD"
; Path (RO) = "C:\\Program Files\\AutoCAD R14"
; Preferences (RO) = #<VLA-OBJECT IAcadPreferences 03a937cc>
; Top = 312
; Version (RO) = "14.01"
; Visible = -1
; Width = 987
T

vlax-dump-object

480

vlax-ename->vla-object
Transform entity to VLA object (VLISP Function)

(vlax-ename->vla-object entname)
entname - entity name
Returns:
VLA object
Example
_$ (setq e (car (entsel)))
<Entity name: 27e0540>
_$ (vlax-ename->vla-object e)
#<VLA-OBJECT IAcadLWPolyline 03f713a0>

vlax-erased-p
Determines whether an object was erased (VLISP Function)

(vlax-erased-p obj)
obj - VLA object
Returns:
T if the object was erased, nil otherwise

vlax-for
Iterates through a collection of objects evaluating each expression (VLISP Function)

(vlax-for symbol collection [expression1 [expression2 ...]])


symbol - a symbol that will be assigned to each VLA object in a collection
collection - VLA object representing a collection object
expression1, expression2... expressions to be evaluated
Returns:
The value of the last expression evaluated for the last object in the collection

Appendix A AutoLISP Function Reference

481

vlax-get
Low-level property get function. May be used for custom ActiveX object (VLISP
Function)

(vlax-get obj property)


obj - VLA object
property - string indicating the name of the property to be retrieved
Returns:
The value of the property
Example:
(setq vlaobj (vlax-ename->vla-object e))
#<VLA-OBJECT IAcadLWPolyline 0467114c>
$ (vlax-get vlaobj "Color")
256

vlax-get-acad-object
Retrieves the top level AutoCAD application object for the current AutoCAD
session (VLISP Function)

(vlax-get-acad-object)
Example:
_$ (setq aa (vlax-get-acad-object))
#<VLA-OBJECT IAcadApplication 00b3b91c>

vlax-get

482

vlax-invoke
Calls the specified method of an object (VLISP Function)

The vlax-invoke function can be used for a custom ActiveX object.

(vlax-invoke obj method list)


obj - VLA object
method - a string specifying the name of the method to be called
list - list of arguments to be passed to the method called. No argument type checking
is performed. All sub-lists are converted to Variant Arrays.
Returns:
The method (first argument)
Examples:
(vlax-invoke vla-object update nil)

This is equivalent to the standard VLA call:


(vla-update vla-object)

vlax-ldata-delete
Erases LISP data from a drawing dictionary (VLISP Function)

(vlax-ldata-delete dict key)


dict - VLA object, AutoCAD drawing entity object, or string naming a global dictionary
key - string specifying the dictionary key
Returns:
T, if successful
nil, if unsuccessful (for example, the data did not exist)

Appendix A AutoLISP Function Reference

483

Examples:
_$ (vlax-ldata-put "dict" "key" (1))
(1)
_$ (vlax-ldata-delete "dict" "key")
T
_$ (vlax-ldata-delete "dict" "key")
nil

vlax-ldata-get
Retrieves LISP data from a drawing dictionary (VLISP Function)

(vlax-ldata-get dict key [default-data])


dict - VLA object or AutoCAD drawing entity object, or a string naming a global dictionary
key - string specifying the dictionary key
default-data (optional) - LISP data to be returned if no matching key exists in the dictionary
Returns:
Value of key item
Example:
_$ (vlax-ldata-get "dict" "key")
(1)

vlax-ldata-list
Lists LISP data in a drawing dictionary (VLISP Function)

(vlax-ldata-list dict)
dict - VLA object or AutoCAD drawing entity object, or a string naming a global dictionary
Returns:

An associative list consisting of pairs (key . value)

vlax-ldata-get

484

vlax-ldata-put
Stores LISP data in a drawing dictionary (VLISP Function)

(vlax-ldata-put dict key data)


dict - VLA object or AutoCAD drawing entity object, or a string naming a global dictionary
key - string specifying the dictionary key
data - LISP data to be stored in the dictionary
Returns:
The value of data
Example:
_$ (vlax-ldata-put "dict" "key" (1))
(1)

vlax-ldata-test
Determines if data can be saved over a session boundary (VLISP Function)

(vlax-ldata-test data)
data - any LISP data to be tested
Returns:
T, if the data can be saved and restored over the session boundary
nil, if data cannot be saved and restored

Appendix A AutoLISP Function Reference

485

vlax-map-collection
Applies a function to all objects in a collection (VLISP Function)

(vlax-map-collection obj function)


obj - VLA object representing a collection
function - symbol or lambda expression to be applied
Returns:
obj (the first argument)
Example:
(vlax-map-collection (vla-get-ModelSpace acadDocument) vlax-dump-object)
; IAcadLWPolyline: AutoCAD Lightweight Polyline Interface
; Property values:
; Application (RO) = #<VLA-OBJECT IAcadApplication 00b3b91c>
; Area (RO) = 3.67152
; Closed = -1
; Color = 256
; Coordinates = (9.59247 4.44872 9.25814 5.34715 4.19911 5.67949 ... )
; EntityName (RO) = "AcDbPolyline"
; EntityType (RO) = 24
; Handle (RO) = "4C"
; Layer = "0"
; Linetype = "BYLAYER"
; LinetypeScale = 1.0
; Normal = (0.0 0.0 1.0)
; ObjectID (RO) = 42009888
; Thickness = 0.0
; Visible = -1
; IAcadCircle: AutoCAD Circle Interface
; Property values:
; Application (RO) = #<VLA-OBJECT IAcadApplication 00b3b91c>
; Area (RO) = 0.661383
; Center = (8.53948 4.91026 0.0)
; Color = 256
; EntityName (RO) = "AcDbCircle"
; EntityType (RO) = 8
; Handle (RO) = "4D"
; Layer = "0"
; Linetype = "BYLAYER"
; LinetypeScale = 1.0
; Normal = (0.0 0.0 1.0)
; ObjectID (RO) = 42009896
; Radius = 0.45883
; Thickness = 0.0
; Visible = -1

vlax-map-collection

486

vlax-method-applicable-p
Determines if an object supports a particular method (VLISP Function)

(vlax-method-applicable-p obj method)


obj - VLA object
method - a string containing the name of the method to check
Returns:
T, if the object supports the method
nil, if the object does not support the method

Examples (applied to a LightweightPolyline object):


_$ (vlax-method-applicable-p WhatsMyLine "copy")
T
_$ (vlax-method-applicable-p WhatsMyLine "AddBox")
nil

vlax-object-released-p
Determines if an object has been released (VLISP Function)

(vlax-object-released-p obj)
obj - VLA object.
Returns:
T, if object is released (no AutoCAD drawing object is attached to obj)
nil, if the object has not been released

vlax-product-key
Returns AutoCADs registry path (VLISP Function)

This path can be used to register an application for demand loading.


Returns:
A string containing the registry path

Appendix A AutoLISP Function Reference

487

Example:
(vlax-product-key)
"Software\\Autodesk\\AutoCAD\\R14.0\\ACAD-2450999:99924631"

vlax-property-available-p
Determines if an object has a specified property (VLISP Function)

(vlax-property-available-p obj prop [T])


obj - VLA object.
property - a string naming the property to be checked
T - if specified, tells vlax-property-available-p to also check that the property can be
modified
Returns:
T, if the object has the specified property
nil, if the object does not have the specified property. If the optional "T" argument is
specified on the function call, nil will be returned either if the property is not avail-

able or if the property cannot be modified.


Examples (applied to a LightweightPolyline object):
_$ (vlax-property-available-p WhatsMyLine "Color")
T
_$ (vlax-property-available-p WhatsMyLine "center")
nil

For a circle object:


_$ (vlax-property-available-p myCircle "area")
T

Note how supplying the optional third argument changes the result:
_$ (vlax-property-available-p myCircle "area" T)
nil

The funtion returns nil because, although the circle has an "area" property, that property
cannot be modified.

vlax-property-available-p

488

vlax-put
Low-level property set function (VLISP Function)

Can be used for custom ActiveX objects

(vlax-put obj property arg)


obj - VLA object
property - a string specifying the name of the property to be set
arg - value to be set
Returns:
nil, if successful

Example:
$ (vlax-put vlaobj "Color" 1)
nil

which is equivalent to the standard VLA call:


(vla-put-color vlaobj acRed)

vlax-read-enabled-p
Determines if an object can be read (VLISP Function)

(vlax-read-enabled-p obj)
obj - VLA object
Returns:
T, if the object is readable
nil, if the object is not readable

Appendix A AutoLISP Function Reference

489

vlax-reg-app
Registers an application (VLISP Function)

(vlax-reg-app app-reg-path cmds-alist loadctrls [appname [no-err-p]])


app-reg-path a string in the form of "SOFTWARE\\<company name>\\<product
name>\\<product version>".
cmds-alist - a list of command descriptions, each of which must be one of: (<globalcmd-name> . <local-cmd-name>) or <cmd-name>. Every <cmd-name> - string or
symbol.
loadctrls - INT, see ARX docs
appname (optional) - a string that will be appended to AutoCADs Application subpath; default value is the base name of the application
no-err-p (optional) - boolean flag that prevents fail on registry operations if not nil
and returns nil; default value is nil
Returns:
a string containing the registry key path that was registered

vlax-release-object
Releases a drawing object (VLISP Function)

(vlax-release-object obj)
obj - VLA object
After release, the drawing object is no longer accessible through obj.
Returns:
Indeterminate

vlax-reg-app

490

vlax-remove-cmd
Removes a single command or a command group (VLISP Function)

Removes a single command or the whole command group for the current AutoCAD session.

(vlax-remove-cmd global-name)
global-name - either a string or T. If global-name is T, the whole command group
VLC-AppName (for example, VLC-VLIDE) is deleted.

vlax-tmatrix
Returns a suitable representation for a 4x4 transformation matrix to be used in
VLA methods (VLISP Function)

(vlax-tmatrix list)
Returns a suitable representation (acceptable to ActiveX methods) for a 4x4 transformation matrix (namely: vla-TransformBy).
list - a list of four lists, each containing four numbers, representing transformation
matrix elements

vlax-typeinfo-available-p
Deterines whether TypeLib information is present for the specified type of object
(VLISP Function)

Visual LISP requires TypeLib information to determine whether a method or property is


available for an object. Some objects may not have TypeLib information (for example,
AcadDocument).

(vlax-typeinfo-available-p obj)
obj - VLA object
Returns:
T, if TypeLib information is available
nil, if TypeLib information is not available

Appendix A AutoLISP Function Reference

491

vlax-vla-object->ename
Transforms a VLA object to an AutoLISP entity (VLISP Function)

(vlax-vla-object->ename obj)
obj - VLA object
Returns:
An AutoLISP entity name
Example:
_$ (vlax-vla-object->ename vlaobj)
<Entity name: 27e0540>

vlax-write-enabled-p
Determines if an AutoCAD drawing object can be modified (VLISP Function)

(vlax-write-enabled-p obj)
obj - VLA object or AutoLISP entity object
Returns:
T, if an AutoCAD drawing object can be modified
nil, if the object cannot be modified

vlisp-export-symbol
Assigns a native AutoLISP variable to the value it has in Visual LISP (VLISP
Function)

(vlisp-export-symbol symbol-name)
symbol-name - Visual LISP symbol or list of symbols
Returns:
The value of the exported symbol, or the last exported symbol, if a list was supplied

vlax-vla-object->ename

492

Examples:
_$ (setq dd 1)
1
_$ (VLISP-EXPORT-SYMBOL dd)
1
_$ (setq zz "str")
"str"
$ (VLISP-EXPORT-SYMBOL (dd zz))
"str"

vlisp-import-exsubrs
Registers the entry point of an ADS or ARX application within the Visual LISP
environment (VLISP Function)

(vlisp-import-exsubrs ("app-name" "entry-name" ["entry-name"...]))


app-name - base name of the application load module
entry-name - names of application functions to be defined in Visual LISP
Returns:
Indeterminate
Examples:
_$ (VLISP-IMPORT-EXSUBRS ("acadapp.exe" "appload"))
("ACADAPP" "appload" "C:PSDRAG" "MTPROP" "MTEDIT" "C:PSFILL" "BHATCH"
"BPOLY" "C:PSIN" "ACAD_COLORDLG" "STARTAPP" "ISMNUGRPLOADED" "INITDIA")

vlisp-import-symbol
Assigns a Visual LISP symbol to the same value it has in native AutoLISP
(VLISP Function)

(vlisp-import-symbol symbol-name)
symbol-name - AutoLISP symbol or list of symbols
Returns:
The value of the imported symbol, or the last imported symbol in a list of symbols
Examples:
_$ (vlisp-import-symbol dd)
1

Appendix A AutoLISP Function Reference

493

_$ (vlisp-import-symbol xx)
nil
_$ (vlisp-import-symbol (xx dd))
1

vlr-acdb-reactor
Constructs a database (global) reactor object (VLISP Function)

The vlr-acdb-reactor function constructs a database (global) reactor object. The


reactor object is added to the drawing database, but does not become persistent.

(vlr-acdb-reactor data callbacks)


data - any AutoLISP data to be associated with a reactor object
callbacks - a list of pairs (<event-name> . <callback_function>) where event-name is
one of the symbols listed in a Table AcDb I below, and callback_function is a symbol
representing a function to be called when the event fires. Each callback function
accepts two arguments:
reactor_object - the VLR object that called the callback function
obj - the database object (passed as an AutoLISP entity) associated
with the event
Table AcDb I
Name

Event

:vlr-objectAppended

An object has been appended to the drawing


database.

:vlr-objectUnAppended

An object has been detached from the drawing


database, e.g. by using UNDO.

:vlr-objectReAppended

A detached object has been restored in the


drawing database, e.g. by using REDO.

:vlr-objectOpenedForModify

An object is about to be changed.

:vlr-objectModified

An object has been changed.

:vlr-objectErased

An object has been flagged as being erased.

:vlr-objectUnErased

An objects erased-flag has been removed.

vlr-acdb-reactor

494

vlr-add
Enables a disabled reactor object (VLISP Function)

(vlr-add obj)
obj -a VLR object, the reactor to be enabled
Returns:
obj (the argument)

vlr-added-p
Tests to determine if a reactor object is enabled (VLISP Function)

(vlr-added-p obj)
obj - a VLR object, the reactor to be tested
Returns:
T, if the specified reactor is enabled
nil, if the reactor is disabled

vlr-beep-reaction
Produces a beep sound (VLISP Function)

(vlr-beep-reaction [args])
This is a predefined callback function that accepts a variable number of arguments,
depending on the reactor type. Can be assigned to an event handler for debugging. This
function works in the Visual LISP IDE only.

Appendix A AutoLISP Function Reference

495

vlr-current-reaction-name
Returns the name (symbol) of the current event, if called from within a reactors
callback (VLISP Function)

(vlr-current-reaction-name)
Returns:
A symbol indicating the event that triggered the reactor

vlr-data
Returns application-specific data associated with a reactor (VLISP Function)

(vlr-data obj)
obj - a VLR object, the reactor object from which to extract data

vlr-data-set
Overwrites application-specific data associated with a reactor (VLISP Function)

(vlr-data-set obj data)


obj - a VLR object, the reactor object for setting the data
data - any AutoLISP data
The vlr-data-set function should be used with care to avoid creation of circular structures.
Returns:
data

vlr-current-reaction-name

496

vlr-editor-reactor
Constructs an Editor (global) reactor object (VLISP Function)

The reactor object is added to the drawing database, but does not become persistent.

(vlr-editor-reactor data callbacks)


data - any AutoLISP data to be associated with the reactor object
callbacks - a list of pairs (<event-name> . <callback_function>) where event-name is
one of the symbols listed in Table Editor Events, and callback_function is a symbol
representing a function to be called when the event fires. Each callback function
accepts two arguments:
reactor_object - the VLR object that called the callback function
list - a list of extra data elements associated with the particular event.
The contents of this list for particular events is shown in
Table Editor Callback Data.
Returns:
The reactor_object argument
Table Editor Events
Table Editor Events
Name

Event

:vlr-unknownCommand

The user has called a command unknown to AutoCAD.

:vlr-commandWillStart

The user has called a command known to AutoCAD.

:vlr-commandEnded

A command has completed.

:vlr-commandCancelled

A command has been cancelled by the user or another application.

:vlr-commandFailed

A command failed to complete.

:vlr-lispWillStart

An AutoLISP expression is to be evaluated inside the drawing editor.

:vlr-lispEnded

The evaluation of an AutoLISP expression has completed.

Appendix A AutoLISP Function Reference

497

Table Editor Events


Name

Event

:vlr-lispCancelled

The evaluation of an AutoLISP expression has been cancelled. Next


the :vlr-lispEnded event will be fired.

:vlr-beginClose

The drawing database is to be closed.

:vlr-beginDxfIn

The contents of a DXF file is to be appended to the drawing database.

:vlr-abortDxfIn

The drawing database has been changed, but the DXF import was not
successful.

:vlr-dxfInComplete

The DXF import was successful.

:vlr-beginDxfOut

AutoCAD is about to export the drawing database into a DXF file.

:vlr-abortDxfOut

The DXF export operation failed.

:vlr-dxfOutComplete

The DXF export operation was successful.

:vlr-beginDwgOpen

AutoCAD is about to open a drawing.

:vlr-endDwgOpen

AutoCAD ended the open operation.

:vlr-dwgFileOpened

A new drawing has been loaded into the AutoCAD drawing editor.

:vlr-databaseToBeDestroyed

The contents of the drawing database is about to be deleted from


memory.

:vlr-beginSave

AutoCAD is about to save the drawing file.

:vlr-SaveComplete

AutoCAD has saved the current drawing to disk.

:vlr-sysVarWillChange

AutoCAD is about to change a system variable.

:vlr-sysVarChanged

AutoCAD finished changing the system variable.

vlr-editor-reactor

498

Table Editor Callback Data


Table Editor Callback Data
Name

List
length

:vlr-lispEnded,
:vlr-lispCancelled,
:vlr-beginClose,
:vlr-beginDxfIn,
:vlr-abortDxfIn,
:vlr-dxfInComplete,
:vlr-beginDxfOut,
:vlr-abortDxfOut,
:vlr-dxfOutComplete,
:vlr-databaseToBeDestroyed

:vlr-unknownCommand
:vlr-commandWillStart
:vlr-commandEnded
:vlr-commandCancelled
:vlr-commandFailed

command name (string)

:vlr-lispWillStart

first line of AutoLISP expression to evaluate


(string)

:vlr-beginDwgOpen,
:vlr-endDwgOpen,
:vlr-dwgFileOpened

filename to open (string)

:vlr-beginSave

default filename for save (string), may be changed


by the user

:vlr-saveComplete

actual filename used for save (string)

:vlr-sysVarWillChange

system variable name (string)

:vlr-sysVarChanged

first parameter is the system variable name (string),


second parameter is a change-successful flag (integer: 1 = success, 0 = failed)

Appendix A AutoLISP Function Reference

499

Parameters

vlr-linker-reactor
Constructs a Linker (global) reactor object (VLISP Function)

The reactor object is added to the drawing database, but does not become persistent.

(vlr-linker-reactor data callbacks)


data - any AutoLISP data to be associated with the reactor object
callbacks - a list of pairs (<event-name> . <callback_function>) where event-name is
one of the symbols listed in Table Linker Events on page 500, and
callback_function is a symbol representing a function to be called when the event
fires. Each callback function accepts two arguments:
reactor_object - the VLR object that called the callback function
list - a list containing the name string of the ARX program
loaded/unloaded.
Returns:
The reactor_object argument
Table Linker Events
Table Linker Events
Name

Event

:vlr-rxAppLoaded

The dynamic linker has loaded a new ARX program. The program
has finished its initialization.

:vlr-rxAppUnLoaded

The dynamic linker has unloaded an ARX program. The program


already has done its clean-up.

vlr-object-reactor
Constructs an object reactor object (VLISP Function)

The reactor object is added to the drawing database, but does not become persistent.

(vlr-object-reactor owners data callbacks)


owners - AutoLISP list of VLA objects for valid drawing objects to be watched

vlr-linker-reactor

500

data - any AutoLISP data to be associated with the reactor object


callbacks - a list of pairs (<event-name> . <callback_function>) where event-name is
one of the symbols listed in Table: Object Events on page 502, and
callback_function is a symbol representing a function to be called when the event
fires. Each callback function accepts three arguments:
owner - owner of the VLA object the event applies to
reactor_object - the VLR object that called the callback function
list - a list of extra data elements associated with the particular

event. The contents of this list for particular events is shown


in Table: Object Callback Data on page 503.
Returns:
The reactor_object argument

Appendix A AutoLISP Function Reference

501

Table: Object Events


Table: Object Events
Name

Event

:vlr-cancelled

The modification of the object has been cancelled.

:vlr-copied

The object has been copied.

:vlr-erased

Erase-flag of the object has been set.

:vlr-unerased

Erase-flag of the object has been reset.

:vlr-goodbye

The object is about to be deleted from memory.

:vlr-openedForModify

The object is about to be modified.

:vlr-modified

The object has been modified. If the modification was cancelled,


also :vlr-cancelled and :vlr-modifyUndone will be fired.

:vlr-subObjModified

A sub-entity of the object has been modified.

:vlr-modifyUndone

The objects modification was undone.

:vlr-modifiedXData

The objects extended entity data have been modified.

:vlr-unappended

The object has been detached from the drawing database.

:vlr-reappended

The object has been re-attached to the drawing database.

:vlr-objectClosed

The objects modification has been finished.

vlr-object-reactor

502

Table: Object Callback Data


Table: Object Callback Data
Name

List
length

Parameters

:vlr-cancelled
:vlr-erased,
:vlr-unerased
:vlr-goodbye
:vlr-openedForModify
:vlr-modified
:vlr-modifyUndone
:vlr-modifiedXData
:vlr-unappended
:vlr-reappended
:vlr-objectClosed

:vlr-copied

The object created by the copy operation


(ename).

:vlr-subObjModified

The sub-object (ename) that has been modified

vlr-owner-add
Adds an object to the list of owners of an object reactor (VLISP Function)

(vlr-owner-add reactor owner)


reactor - a VLR object
owner - a VLA object to be added to the list of notifiers for this reactor
Adds a new source of reactor events; reactor will receive events from the specified object.
Returns:
Indeterminate

Appendix A AutoLISP Function Reference

503

vlr-owner-remove
Removes an object from the list of owners of an object reactor (VLISP Function)

(vlr-owner-remove reactor owner)


reactor - a VLR object
owner - a VLA object to be removed from the list of notifiers for this reactor
Returns:
Indeterminate

vlr-owners
Returns the list of owners of an object reactor (VLISP Function)

Returns a list of objects that notify the specified reactor.

(vlr-owners reactor)
reactor - a VLR object

vlr-pers
Makes a reactor persistent (VLISP Function)

(vlr-pers reactor)
reactor - a VLR object
Returns:
Indeterminate

vlr-pers-p
Determines whether or not a reactor is persistent (VLISP Function)

(vlr-pers-p reactor)
reactor - a VLR object

vlr-owner-remove

504

Returns:
T, if the specified reactor is persistent
nil, if the reactor is transient

vlr-pers-release
Makes a reactor transient (VLISP Function)

(vlr-pers-release reactor)
reactor - a VLR object
Returns:
Indeterminate

vlr-reaction-names
Returns a list of all callback conditions for this reactor type (VLISP Function)

(vlr-reaction-names reactor-type)
reactor-type - one of the following symbols:
:VLR-AcDb-reactor
:VLR-Editor-reactor
:VLR-Linker-reactor
:VLR-Object-reactor
Returns:
A list of symbols indicating the possible events for the specified reactor type

vlr-reaction-set
Adds or replaces a callback function in a reactor (VLISP Function)

(vlr-reaction-set reactor event function)


reactor - a VLR object
event - a symbol denoting one of the event types available for this reactor type

Appendix A AutoLISP Function Reference

505

function - a symbol representing the AutoLISP function to be added or replaced


Returns
Indeterminate

vlr-reactions
Returns a list of pairs (event-name . callback_function) for the reactor (VLISP
Function)

(vlr-reactions reactor)
reactor - a VLR object

vlr-reactors
Returns a list of all reactors of a given type (VLISP Function)

(vlr-reactors reactor-type)
reactor-type - one of the following symbols:
:VLR-AcDb-reactor
:VLR-Editor-reactor
:VLR-Linker-reactor
:VLR-Object-reactor

vlr-remove
Disables a reactor (VLISP Function)

(vlr-remove reactor)
reactor - a VLR object
Returns
Indeterminate

vlr-reactions

506

vlr-remove-all
Disables all reactors of the specified type (VLISP Function)

(vlr-remove-all reactor-type)
reactor-type - one of the following symbols:
:VLR-AcDb-reactor
:VLR-Editor-reactor
:VLR-Linker-reactor
:VLR-Object-reactor
Returns
Indeterminate

vlr-trace-reaction
A pre-defined callback function that prints one or more callback arguments in
the Trace window (VLISP Function)

(vlr-trace-reaction any number of arguments)


This function can be used as a debugging tool to verify that your reactor has fired.

vlr-type
Returns a symbol representing the reactor type (VLISP Function)

(vlr-type reactor)
reactor - a VLR object

vlr-types
Returns a list of all reactor types (VLISP Function)

(vlr-types)
Returns:

Appendix A AutoLISP Function Reference

507

(:VLR-Linker-Reactor :VLR-Editor-Reactor :VLR-AcDb-Reactor :VLR-ObjectReactor)

vports
Returns a list of viewport descriptors for the current viewport configuration

(vports)
Each viewport descriptor is a list consisting of the viewport identification number and the
coordinates of the viewports lower-left and upper-right corners.
If the AutoCAD system variable TILEMODE is set to 1 (on), the returned list describes
the viewport configuration created with the AutoCAD VPORTS command. The corners
of the viewports are expressed in values between 0.0 and 1.0, with (0.0, 0.0) representing
the lower-left corner of the display screens graphics area, and (1.0, 1.0) the upper-right
corner. If TILEMODE is 0 (off), the returned list describes the viewport objects created
with the MVIEW command. The viewport object corners are expressed in paper space
coordinates. Viewport number 1 is always paper space when TILEMODE is off.
For example, given a single-viewport configuration with TILEMODE on, the vports
function might return this:
((1 (0.0 0.0) (1.0 1.0)))

Similarly, given four equal-sized viewports located in the four corners of the screen when
TILEMODE is on, the vports function might return this:
(

(5 (0.5 0.0) (1.0 0.5))


(2 (0.5 0.5) (1.0 1.0))
(3 (0.0 0.5) (0.5 1.0))
(4 (0.0 0.0) (0.5 0.5)) )

The current viewports descriptor is always first in the list. In the previous example, viewport number 5 is the current viewport.

wcmatch
Performs a wild-card pattern match on a string

(wcmatch string pattern)


The wcmatch function compares the string to the pattern to see if they match. If so,
T is returned; otherwise, nil is returned. Both string and pattern can be either a

vports

508

quoted string or a variable. The pattern can contain the wild-card pattern-matching
characters shown in the following table. Only the first 500 characters (approximately) of
the string and pattern are compared; anything beyond that is ignored.
Wild-card characters
Character

Definition

(pound)

Matches any single numeric digit

(at)

Matches any single alphabetic character

(period)

Matches any single nonalphanumeric character

(asterisk)

Matches any character sequence, including an empty one, and it can


be used anywhere in the search pattern: at the beginning, middle, or
end

(question mark)

Matches any single character

(tilde)

If it is the first character in the pattern, it matches anything except the


pattern

[...]

Matches any one of the characters enclosed

[~...]

Matches any single character not enclosed

(hyphen)

Used inside brackets to specify a range for a single character

(comma)

Separates two patterns

(reverse quote)

Escapes special characters (reads next character literally)

(wcmatch "Name" "N*")

returns T

This tests the string Name to see if it begins with the character N. You can use commas in
a pattern to enter more than one pattern condition. This example performs three comparisons:
(wcmatch "Name" "???,~*m*,N*") returns T

If any of the three pattern conditions is met, wcmatch returns T. In this case the tests are
these: Name has three characters (false); Name does not contain an m (false); and Name
begins with N (true). At least one condition was met, so this expression returns T.
The comparison is case-sensitive, so upper- and lowercase characters must match. It is
valid to use variables and values returned from AutoLISP functions for string and pattern values.

Appendix A AutoLISP Function Reference

509

To test for a wild-card character in a string, you can use the single reverse-quote character
() to escape the character. Escape means that the character following the single reverse
quote is not read as a wild-card character; it is compared at its face value. For example,
to search for a comma anywhere in the string Name, enter this:
(wcmatch "Name" "*,*")

returns nil

Because other wild-card characters might be added in future releases of AutoLISP, it is a


good idea to escape all nonalphanumeric characters in the pattern to ensure upward compatibility.

wcmatch

510

Both the C and AutoLISP programming languages use the backslash (\) as an escape character, so you need two backslashes (\\) to produce one backslash in a string. To test for a
backslash character anywhere in Name, you enter this:
(wcmatch "Name" "*\\*")

returns nil

All characters enclosed in brackets ([ . . . ]) are read literally, so there is no need to escape
them, with the following exceptions: the tilde character (~) is read literally only when it
is not the first bracketed character (as in "[A~BC]"); otherwise it is read as the negation
character, meaning that wcmatch should match all characters except those following the
tilde (as in "[~ABC]"). The dash character () is read literally only when it is the first or
last bracketed character (as in "[ABC]" or "[ABC]") or when it follows a leading tilde
(as in "[~-ABC]"). Otherwise, the dash character () is used within brackets to specify a
range of values for a specific character. The range works only for single characters, so
"STR[138]" matches STR1, STR2, STR3, and STR8, and "[AZ]" matches any single
uppercase letter.
The closing bracket character ("]") is also read literally if it is the first bracketed character or if it follows a leading tilde (as in "[ ]ABC]" or "[~]ABC]").

while
Evaluates a test expression, and if it is not nil, evaluates other expressions;
repeats this process until the test expression evaluates to nil

(while testexpr expr...)


The while function continues until testexpr is nil. It then returns the most recent
value of the last expr.
The following code calls user function SOME-FUNC ten times, with test set to 1 through
10. It then returns 11, which is the value of the last expression evaluated.
(setq test 1)
(while (<= test 10)
(some-func test)
(setq test (1+ test))
)

Appendix A AutoLISP Function Reference

511

write-char
Writes one character to the screen or to an open file

(write-char num [file-desc])


The num argument is the decimal ASCII code for the character to be written and is also
the value returned by write-char.
(write-char 67)

returns 67

and writes the letter C on the screen. Assuming that f is the descriptor for an open file:
(write-char 67 f)

returns 67

and writes the letter C to that file.


The various operating systems on which AutoCAD runs separate conventions to signal
the end of a line in an ASCII text file. UNIX systems, for example, use a single newline
character (LF, ASCII code 10), whereas DOS systems use a pair of characters (CR/LF,
ASCII codes 13 and 10) for the same purpose. To facilitate development of AutoLISP
programs, write-char translates a newline character (ASCII code 10) into the end-ofline character (or character sequence) used by the operating system that youre currently
using. Thus, on a DOS system,
(write-char 10 f)

returns 10

but writes the character sequence CR/LF (ASCII codes 13 and 10) to the file. writechar cannot write a NUL character (ASCII code 0) to a file.

write-line
Writes a string to the screen or to an open file

(write-line string [file-desc])


It returns string quoted in the normal manner but omits the quotes when writing to the
file. For example, assuming that f is a valid open file descriptor,
(write-line "Test" f) writes

Test and returns

"Test"

write-char

512

xdroom
Returns the amount of extended data (Xdata) space that is available for an object
(entity)

(xdroom ename)
If unsuccessful, xdroom returns nil. Because there is a limit (currently, 16 kilobytes) on
the amount of extended data that can be assigned to an entity definition, and because multiple applications can append extended data to the same entity, this function is provided
so that an application can verify that there is room for the extended data that it will
append. It can be called in conjunction with xdsize, which returns the size of an
extended data list.
Here is an example that looks up the available space for extended data of a viewport
object. Assuming that the variable vpname contains the name of a viewport object,
(xdroom vpname)

returns 16162

In this example, 16,162 bytes of the original 16,383 bytes of extended data space are
available, meaning that 221 bytes are used. You can determine the amount of available
data space by using the xdsize function.

xdsize
Returns the size (in bytes) that a list occupies when it is linked to an object
(entity) as extended data

(xdsize lst)
If unsuccessful, xdsize returns nil. The lst argument must be a valid list of extended
data that contain an application name previously registered with the use of the regapp
function. Brace fields (group code 1002) must be balanced. An invalid lst generates an
error and places the appropriate error code in the ERRNO variable. If the extended data
contains an unregistered application name, you see this error message (assuming that
CMDECHO is on):
Invalid application name in 1001 group
The lst can start with a 3 group code (the extended data sentinel), but it is not required.
Because extended data can contain information from multiple applications, the list must
have a set of enclosing parentheses.

Appendix A AutoLISP Function Reference

513

(-3 ("MYAPP" (1000 . "SUITOFARMOR")


(1002 . "{")
(1040 . 0.0)
(1040 . 1.0)
(1002 . "}")
)
)

Here is the same example without the 3 group code. This list is just the cdr of the first
example, but it is important that the enclosing parentheses are included:
( ("MYAPP" (1000 . "SUITOFARMOR")
(1002 . "{")
(1040 . 0.0)
(1040 . 1.0)
(1002 . "}")
)
)

xload
Loads an ADS application

(xload application [onfailure])


The application argument is entered as a quoted string or as a variable that contains
the name of an executable file. At the time the file is loaded, it is verified to be a valid
ADS application. Also, the version of the ADS program, ADS itself, and the version of
AutoLISP that is running are checked for compatibility.
If the xload operation fails, it normally causes an AutoLISP error. However, if the
onfailure argument is supplied, xload returns the value of this argument upon failure
instead of an error message.
If the application is successfully loaded, the application name is returned.
(xload "/myapps/xapp") if successful, returns "/myapps/xapp"

xload

514

If you attempt to load an application that is already loaded, xload issues the message
Application "application" already loaded.
and returns the application name. You may want to check the currently loaded ADS applications with the ads function before using xload.

xunload
Unloads an ADS application

(xunload application [onfailure])


If the application is successfully unloaded, the application name is returned; otherwise,
an error message is issued.
Enter application as a quoted string or as a variable containing the name of an application that was loaded with the xload function. The application name must be entered
exactly as it was entered for the xload function. If a path (directory name) was entered
for the application in xload, it can be omitted in the xunload function.
For example, the following function will unload the previous application loaded by the
xload function:
(xunload "ame") if successful, returns "ame"

If the xunload operation fails, it normally causes an AutoLISP error. However, if the
onfailure argument is supplied, xunload returns the value of this argument upon failure instead of issuing an error message. This feature of xunload is similar to that in the
xload function.

Appendix A AutoLISP Function Reference

515

zerop
Verifies that a number evaluates to zero

(zerop number)
Returns T if number evaluates to zero, returns nil otherwise.
(zerop 0)
(zerop 0.0)
(zerop 0.0001)

returns T
returns T
returns nil

zerop

516

Appendix A AutoLISP Function Reference

517

S-ar putea să vă placă și