home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
lxprpas.zip
/
LXPROTO.C
< prev
next >
Wrap
Text File
|
1998-04-20
|
11KB
|
230 lines
/********************************************************************
* *
* LXPROTO - A simple prototype statement inserter for LPEX. *
* *
* (C) Copyright IBM Corporation 1989-1995 *
* *
*********************************************************************
* *
* The PROTO command (which invokes LXPROTO.DLL) is best tied to *
* a key (such as Ctrl-X). When invoked, it checks the content of *
* the current line. If there is a word under the cursor, or *
* immediately before it, PROTO checks whether this word, prefixed *
* with 'xxx' (where 'xxx' is the parameter supplied to PROTO) is a *
* current global variable. If so, the value of the variable is *
* treated as a set of elements to be inserted at the current *
* position. If no parameter is supplied, '#' is used. *
* *
* Thus, given the global variable definition: *
* *
* GLOBAL.#if /if (?) {//} else {//} *
* *
* and the actionkey definition: *
* *
* ACTION.c-x proto *
* *
* pressing Ctrl-x when the cursor is on a line under the word "if" *
* will cause LPEX to replace the text with: *
* *
* if (?) { *
* *
* } else { *
* *
* } *
* *
* Note that: *
* *
* 1. BLOCK SET WORD is used to locate word to use as a base for *
* the global variable. This allows the use of accented chars *
* and numerics, but not of delimiters and specials. *
* *
* 2. The new text is aligned with the word on the original line. *
* *
* 3. The cursor is positioned at the first ? in the replacement *
* text (or at the start of the first line if none). *
* *
* 4. The line separator ("/" in the example above) is taken as *
* the first non-blank character in the variable definition. *
* *
* 5. Any text after the original word will be placed at the end *
* of the last line of the replacement text. *
* *
*********************************************************************
* *
* Operation: *
* 1. obtain content of current line *
* 2. identify the word under the cursor (if none, return) *
* 3. prefix word with 'xxx' and check if this is a global variable *
* 4. if no, return *
* 5. delete current line *
* 6. scan variable definition, inserting lines *
* 7. append remainder of original line to last line *
* 8. set position at first "?" (or first line). *
* *
********************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "lpexapi.h"
#define BLANK ' '
/* A large work area for LPEX calls */
char result[MAXQUERY]; /* result used for queries */
char quer[100] = "GLOBAL."; /* used to test if global exists */
char posi[100]; /* used to set position */
char newl[300]; /* used to hold inserted lines */
char *lxxquer(char *item, char *buff) /* return pointer to query value */
{
char *p;
lxquery(item, buff); /* returns "ITEM value" string */
p = buff;
while (*p != BLANK && *p != '\0') ++p; /* step over item name */
if (*p == BLANK) ++p; /* and following blank */
return p;
}
int lxxqnum(char *item) /* returns as an int the result of a query */
{
char work[100];
return atoi(lxxquer(item, work));
}
lxmain(uchr *arg)
{
char *p, *q, *r, *s, buff[300];
int i;
int k; /* position of first "?" in pattern */
char delim; /* line delimiter in pattern */
int join1; /* true if text before word */
int join2; /* true if text after word */
int offset; /* start of word offset from start of line */
int cnt; /* counts inserted lines */
char autoparse[20]; /* used to remember autoparse state */
int noword = 0;
char blockdefaulttype[50];
lxquery("BLOCKDEFAULTTYPE", blockdefaulttype);
lxcmd("SET BLOCKDEFAULTTYPE CHARACTER");
while (arg[0] == BLANK) /* skip leading blanks */
arg++;
p = quer + 7;
if (*arg == '\0') /* set default prefix */
strcpy(p, "#");
else {
while (*arg != '\0' && *arg != BLANK)
*p++ = *arg++; /* set prefix as requested */
*p = '\0';
}
lxquery("AUTOPARSE", buff);
strcpy(autoparse, buff);
/* Get hold of the current element */
p = lxxquer("CONTENT", result);
i = lxxqnum("POSITION");
if (i > strlen(p) + 1)
noword = 1;
else if (lxcmd("BLOCK SET CHARACTER WORD") != 0) /* mark the current word */
noword = 1; /* can't find a word */
else {
lxcmd("BLOCK FIND");
offset = lxxqnum("POSITION") - 1;
q = p + offset; /* q points to start of word */
lxcmd("BLOCK FIND END");
i = lxxqnum("POSITION");
r = p + i; /* r points to char after end of word */
lxcmd("BLOCK CLEAR");
lxcall("SET", blockdefaulttype);
if ((i = r - q) > 30) /* variable max length */
return 0;
s = quer + strlen(quer);
memcpy(s, q, i); /* set up variable query */
memset(s+i, '\0', 1);
s = lxxquer(quer, buff); /* and get value */
noword = (*s == '\0'); /* there isn't one, so exit */
}
if (noword) {
/* lxcmd("MSG PROTO - cursor is not positioned on a prototype word."); */
lxcmd("ALARM");
return 0;
}
lxcmd("SET AUTOPARSE OFF");
lxcmd("MARK SET PROTO.001"); /* remember start of changes */
join1 = join2 = 0;
if (q != p) { /* if preceding text: */
*q = '\0';
lxcall("INSERT", p); /* insert before */
join1 = 1;
}
if (*r != '\0') { /* if following text: */
lxcall("INSERT", r); /* insert after */
join2 = 1;
lxcmd("PREV");
}
cnt = 0;
q = s; while (*q == BLANK) ++q; /* skip over blank(s) */
delim = *q++; /* get and skip over delimiter */
k = 0;
p = newl; /* first line doesn't have padding */
while (*q != '\0') { /* while pattern not ended */
if (cnt == 1) { /* later lines do get padded */
memset(newl, BLANK, offset); /* pad start of line */
p = newl + offset;
}
r = p;
while (*q != delim && *q != '\0') { /* for each line in pattern */
if (k == 0 && *q == '?') { /* if it is first "?" */
k = r - p + 1; /* remember it */
}
*r++ = *q++;
}
*r = '\0';
lxcall("INSERT", newl); /* insert line */
if (cnt == 0 && join1 == 1) { /* join to preceding text */
lxcmd("PREV");
lxcmd("SPLITJOIN JOIN");
}
if (k > 0) { /* if a "?" was found */
sprintf(posi, "SET POSITION %u", offset + k);
lxcmd(posi); /* put cursor there */
lxcmd("MARK SET PROTO.002"); /* note position */
k = -1; /* indicate mark 2 has been set */
}
if (*q == delim) ++q; /* skip delimiter */
++cnt;
}
if (join2 == 1) { /* join last line to succeeding text */
lxcmd("SPLITJOIN JOIN");
}
/* go back to original line and delete it */
lxcmd("MARK FIND PROTO.001");
lxcmd("MARK CLEAR PROTO.001");
lxcmd("DELETE");
if (k < 0) { /* "?" was found */
lxcmd("MARK FIND PROTO.002"); /* so put cursor there */
lxcmd("MARK CLEAR PROTO.002");
}
lxcall("SET", autoparse); /* reset autoparse state */
return 0;
}