Mercurial > ~darius > hgwebdir.cgi > paradise_client
view macros.c @ 3:5a977ccbc7a9 default tip
Empty changelog
author | darius |
---|---|
date | Sat, 06 Dec 1997 05:41:29 +0000 |
parents | |
children |
line wrap: on
line source
/* $Id: macros.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ /* here's pretty much all the macro code. */ /* This bears little resemblance to the */ /* BRM code, i.e. it's somewhat organized :)*/ /* Bill Dyess 10/05/93 [BDyess]*/ #ifdef MACROS #include"copyright.h" #include<stdio.h> #if !defined(SVR4) && !defined(sparc) #include<strings.h> #else #include<string.h> #endif /* !SVR4 && !sparc */ #include<ctype.h> #include<fcntl.h> #include<sys/types.h> #include"Wlib.h" #include"data.h" #include"defs.h" #include"struct.h" #include"gameconf.h" #include"proto.h" #define MAXMACRO 4096 #if defined(__STDC__) || defined(RS6K) || defined(sgi) typedef signed char s_char; #else typedef char s_char; #endif /* prototypes */ void doMacro2 P((struct macro * m, W_Event * data)); void handle_dollar P((char **locpntr, char **destpntr, W_Event * data)); void handle_special P((char **locpntr, char **destpntr, W_Event * data)); char *strtoupper P((char *buf)); char *strtolower P((char *buf)); void handle_test P((char **locpntr, char **destpntr, W_Event * data)); void handle_conditional P((char **locpntr, char **destpntr, W_Event * data)); void getTestString P((char *buf, char **locpntr, char **destpntr, W_Event * data)); void getConditionalString P((char **locpntr, char **destpntr, W_Event * data)); void ignoreConditionalString P((char **locpntr)); int abortflag = 0; void initMacros() { struct stringlist *s; char *loc; unsigned char ch; struct macro *m; int i; struct dmacro_list *dm; struct dmacro_list *dm_def; int notdone; unsigned char c; char *str; /* initialize macro lookup tables */ bzero(macrotable, sizeof(struct macro *) * 256); #ifdef RC_DISTRESS /* sizeof doesn't work if it isn't in the same source file, shoot me */ MCOPY(dist_defaults, dist_prefered, sizedist); #endif for (s = defaults; s; s = s->next) { #ifdef RC_DISTRESS if (strncmpi(s->string, "dist.", 5) == 0) { str = (s->string) + 5; if (*str == '^') { str++; if (*str == '^') c = '^'; else c = *str + 128; } else c = *str; str++; if (*str != '.') { str = (s->string) + 4; c = '\0'; } str++; notdone = 1; for (dm = &dist_prefered[take], dm_def = &dist_defaults[take], i = take; dm->name && notdone; dm++, dm_def++, i++) { if (strcmpi(str, dm->name) == 0) { dm->macro = strdup(s->value); if (c) { if (!macrotable[c]) { macrotable[c] = (struct macro *) malloc(sizeof(struct macro)); bzero(macrotable[c], sizeof(struct macro)); } macrotable[c]->flags |= MACRCD; macrotable[c]->to = i; /* printf("dist.%c.%s: %s\n",c,dm->name,dm->macro);*/ dm->c = c; dm_def->c = c; } notdone = 0; } } } #endif /* RC_DISTRESS */ #ifdef BEEPLITE else if (strncmpi(s->string, "lite.", 5) == 0) { int offset = 5; char **lt; if (s->string[6] == '.') offset = 7; notdone = 1; for (lt = &distlite[take], dm = &dist_prefered[take]; dm->name && notdone; dm++, lt++) { if (strcmpi(s->string + offset, dm->name) == 0) { *lt = strdup(s->value); /* printf("lite.%s: %s\n",dm->name,*lt);*/ notdone = 0; } } if (notdone) fprintf(stderr, "Unknown lite %s\n", s->string + offset); } #endif /* BEEPLITE */ if (!strncmpi("mac", s->string, 3)) { if (s->string[3] == '.') loc = s->string + 4; else if (strncmpi("ro.", s->string + 3, 3)) continue; else loc = s->string + 6; if (*loc == '^') { /* possible control char */ loc++; if (*loc == '^' && *loc) ch = '^'; else ch = *loc + 128; } else ch = *loc; loc++; if (!macrotable[ch]) { /* make sure it doesn't already exist. I've allowed people to have singlemacro: before the macro.*.* statements, so it is possible */ /* modified to allow multline macros by creating a linked list of macro structures. -JR */ if (ch == '?') { printf("Can't use '?' as a macro. It is reserved for the macro window. Ignoring.\n"); continue; } macrotable[ch] = m = (struct macro *) malloc(sizeof(struct macro)); bzero(m, sizeof(struct macro)); } else { #ifdef RC_DISTRESS if (macrotable[ch]->flags & MACRCD) { m = macrotable[ch]; m->flags &= ~(MACRCD); /* in case singleMacro was set */ m->next = 0; } else #endif { m = (struct macro *) malloc(sizeof(struct macro)); m->next = macrotable[ch]; macrotable[ch] = m; m->next->flags |= MACMULTI; m->flags = m->next->flags; } } if (*(loc++) != '.') m->to = -2; /* no destination given */ else { ch = *loc; if (ch == '%') { m->specialto = toupper(*(loc + 1)); m->to = -1; } else { m->to = ch; } } m->string = strdup(s->value); } else if (!strncmpi("singlemacro", s->string, 11)) { loc = s->value; while (*loc) { ch = *(loc++); if (ch == '^') {/* for control chars */ if (*loc != '^' && *loc) ch = *loc + 128; loc++; } if (!macrotable[ch]) { m = macrotable[ch] = (struct macro *) malloc(sizeof(struct macro)); bzero(m, sizeof(struct macro)); m->flags = MACSINGLE; } else { for (m = macrotable[ch]; m; m = m->next) m->flags |= MACSINGLE; } } } } for (i = 0; i < 256; i++) { /* eliminate any macros that have (null) macro strings */ if (macrotable[i] && !(macrotable[i]->flags & MACRCD)) { struct macro *tmp, **scan; scan=¯otable[i]; while (*scan) { if ( (*scan)->string ) { scan = &(*scan)->next; } else { tmp = (*scan); *scan = tmp->next; free(tmp); } } } } #ifdef RC_DISTRESS /* make macro entries for the default RCD keys, if those keys don't have macros defined */ for (dm = &dist_prefered[take], i = take; dm->name; dm++, i++) { if (!macrotable[dm->c]) { macrotable[dm->c] = (struct macro *) malloc(sizeof(struct macro)); bzero(macrotable[dm->c], sizeof(struct macro)); macrotable[dm->c]->flags = MACRCD; macrotable[dm->c]->to = i; } } #endif } void doMacro(data) W_Event *data; /* takes a key as input and creates a string that is then sent to smessage*/ { static struct macro *m; int key = data->key; if (key == '?') { showMacroWin(); macroState = 0; return; } if (macroState != 2) m = macrotable[key]; if (!m) { W_Beep(); warning("No such macro"); macroState = 0; return; /* no macro */ } #ifdef RC_DISTRESS if (m->flags & MACRCD) { rcd(m->to, data); macroState = 0; return; } #endif while (m) { if (macroState == 2) { m->to = key; doMacro2(m, data); m->to = -2; } else { doMacro2(m, data); if (macroState == 2) return; } m = m->next; } macroState = 0; warning(" "); } void doMacro2(m, data) struct macro *m; W_Event *data; { int group = -1, recip = 0; char buf[MAXMACRO], sourcebuf[MAXMACRO]; char *loc, *dest; struct obtype *target; /* first figure out who I'm going to send it to */ if ((s_char)m->to == -1) { /* special recipient */ switch (m->specialto) { case 'I': /* send a message to myself */ case 'C': group = MINDIV; recip = me->p_no; break; case 'U': /* send message to player nearest mouse */ case 'P': group = MINDIV; target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); recip = target->o_num; break; case 'T': /* send message to team of the player nearest mouse */ case 'Z': group = MTEAM; target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); recip = idx_to_mask(players[target->o_num].p_teami); break; case 'G': /* send message to nearest friendly player to my ship */ group = MINDIV; target = gettarget((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER | TARG_FRIENDLY); recip = target->o_num; break; case 'H': /* send message to nearest enemy player to my ship */ group = MINDIV; target = gettarget((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER | TARG_ENEMY); recip = target->o_num; break; default: warning("Bad macro - incorrect 'to' field"); break; } } else if ((s_char)m->to == -2) { /* get recipient not provided, so change state to get one */ macroState = 2; warning("Send macro to who?"); return; } else recip = m->to; /* now parse the macro itself. */ strcpy(sourcebuf, m->string); loc = sourcebuf; dest = buf; while (*loc) { if (*loc == '$') { loc++; handle_dollar(&loc, &dest, data); /* handle the special escape */ } else if (*loc == '%') { loc++; if (*loc == '*') return; /* %* means exit macro NOW */ handle_special(&loc, &dest, data); /* handle the special escape */ } else { *(dest++) = *(loc++); } } *dest = 0; if (buf[0] == 0 || abortflag) { /* abortflag means somewhere there was a %* */ abortflag = 0; macroState = 0; return; /* null message. If you *really* want to print a null message, use <space> */ } if (group == -1) group = getgroup(recip, &recip); if (group <= 0) return; if ((m->flags & MACMULTI) && (F_multiline_enabled || paradise)) group |= MMACRO; pmessage(buf, recip, group); } void handle_special(locpntr, destpntr, data) char **locpntr, **destpntr; W_Event *data; { char ch = **locpntr; char *buf = *destpntr; struct obtype *target; struct macro *m; int targettype = 0; struct id *id; /* for pingstats */ #if 0 extern int ping_iloss_sc; /* inc % loss 0--100, server to client */ extern int ping_iloss_cs; /* inc % loss 0--100, client to server */ #endif /* 0 */ extern int ping_tloss_sc; /* total % loss 0--100, server to client */ extern int ping_tloss_cs; /* total % loss 0--100, client to server */ #if 0 extern int ping_lag; /* delay in ms of last ping */ #endif /* 0 */ extern int ping_av; /* average rt */ extern int ping_sd; /* standard deviation */ switch (ch) { case 'a': /* armies carried by sender */ sprintf(buf, "%d", me->p_armies); break; case 'd': /* sender damage percentage */ sprintf(buf, "%d", 100 * me->p_damage / me->p_ship->s_maxdamage); break; case 's': /* sender shield percentage */ sprintf(buf, "%d", 100 * me->p_shield / me->p_ship->s_maxshield); break; case 'f': /* sender fuel percentage */ sprintf(buf, "%d", 100 * me->p_fuel / me->p_ship->s_maxfuel); break; case 'w': /* sender wtemp percentage */ sprintf(buf, "%d", 100 * me->p_wtemp / me->p_ship->s_maxwpntemp); break; case 'e': /* sender etemp percentage */ sprintf(buf, "%d", 100 * me->p_etemp / me->p_ship->s_maxegntemp); break; case 'r': /* team id character of target player */ target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); buf[0] = teaminfo[players[target->o_num].p_teami].letter; buf[1] = 0; break; case 't': /* team id character of target planet */ target = gettarget(data->Window, data->x, data->y, TARG_PLANET); buf[0] = teaminfo[mask_to_idx(planets[target->o_num].pl_owner)].letter; buf[1] = 0; break; case 'p': /* id character of target player */ targettype = TARG_PLAYER; case 'g': /* id character of target friendly player */ if (!targettype) targettype = TARG_PLAYER | TARG_FRIENDLY; case 'h': /* id char of target enemy player */ if (!targettype) targettype = TARG_PLAYER | TARG_ENEMY; id = getTargetID(data->Window, data->x, data->y, targettype); buf[0] = id->mapstring[1]; buf[1] = 0; break; case 'P': /* id character of player nearest sender */ id = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER); buf[0] = id->mapstring[1]; buf[1] = 0; break; case 'T': /* team id character of sender team */ buf[0] = me->p_mapchars[0]; buf[1] = 0; break; case 'c': /* sender id character */ buf[0] = me->p_mapchars[1]; buf[1] = 0; break; case 'C': /* 1 if cloaked, 0 if not [BDyess] */ if (me->p_flags & PFCLOAK) buf[0] = '1'; else buf[0] = '0'; buf[1] = 0; break; case 'n': /* armies on target planet */ target = gettarget(data->Window, data->x, data->y, TARG_PLANET); sprintf(buf, "%d", planets[target->o_num].pl_info ? planets[target->o_num].pl_armies : -1); break; case 'E': /* 1 if etemped, 0 if not */ if (me->p_flags & PFENG) buf[0] = '1'; else buf[0] = '0'; buf[1] = 0; break; case 'W': /* 1 if wtemped, 0 if not */ if (me->p_flags & PFWEP) buf[0] = '1'; else buf[0] = '0'; buf[1] = 0; break; case 'S': /* sender two character ship type */ strncpy(buf, me->p_ship->s_desig, 2); buf[2] = 0; break; case 'G': /* id char of friendly player nearest sender */ targettype = TARG_FRIENDLY; case 'H': /* id char of enemy player nearest sender */ if (!targettype) targettype = TARG_ENEMY; id = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER | targettype); buf[0] = id->mapstring[1]; buf[1] = 0; break; case 'l': /* three character name of target planet */ case 'L': id = getTargetID(data->Window, data->x, data->y, TARG_PLANET); strcpy(buf, id->mapstring); buf[0] = tolower(buf[0]); break; case 'i': /* sender full player name (16 character max) */ case 'I': strncpy(buf, me->p_name, 16); buf[16] = 0; break; case 'u': /* full name of target player (16 character max) */ case 'U': id = getTargetID(data->Window, data->x, data->y, TARG_PLAYER); strncpy(buf, id->name, 16); buf[16] = 0; break; case 'z': /* 3 letter team id of target planet */ case 'Z': id = getTargetID(data->Window, data->x, data->y, TARG_PLANET); strcpy(buf, teaminfo[id->team].shortname); strtolower(buf); break; case 'b': /* nearest planet to sender */ case 'B': id = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLANET); strcpy(buf, id->mapstring); buf[0] = tolower(buf[0]); break; case 'v': /* average ping round trip time */ sprintf(buf, "%d", ping_av); break; case 'V': /* ping stdev */ sprintf(buf, "%d", ping_sd); break; case 'y': /* packet loss */ sprintf(buf, "%d", (2 * ping_tloss_sc + ping_tloss_cs) / 3); break; case 'm': /* last message */ case 'M': strcpy(buf, lastMessage); break; case 'o': /* insert three letter team name */ case 'O': strcpy(buf, teaminfo[me->p_teami].shortname); break; case ' ': /* nothing. This is so you can start a macro with spaces */ buf[0] = ' '; buf[1] = 0; break; case '%': /* insert % */ buf[0] = '%'; buf[1] = 0; break; case '?': /* start test */ (*locpntr)++; handle_test(locpntr, destpntr, data); return; case '{': /* conditional */ handle_conditional(locpntr, destpntr, data); return; case '*': /* abort! */ abortflag = 1; return; case '2': /* is paradise? sorry, ran out of good letters. '2' means, 'is Netrek II?'. */ buf[0] = paradise + '0'; buf[1] = 0; break; case '_': /* call another macro. Added 1/24/94 [BDyess] */ (*locpntr)++; if (**locpntr == '^') { /* control char */ (*locpntr)++; m = macrotable[**locpntr + (**locpntr == '^') ? 0 : 128]; } else { m = macrotable[(int) **locpntr]; } if (m) { /* does the macro exist? */ char temp[MAXMACRO]; strcpy(temp, m->string); strcat(temp, *locpntr + 1); strcpy(*locpntr + 1, temp); } else { /* somebody screwed up */ printf("Error: called macro "); if (&m - macrotable >= 128) putchar('^'); printf("%c doesn't exist.\n", **locpntr); } buf[0] = 0; break; default: sprintf(buf, "Unknown %% escape: %%%c", ch); warning(buf); buf[0] = 0; break; } if (isupper(ch)) strtoupper(buf); (*locpntr)++; while (**destpntr) (*destpntr)++; return; } void handle_test(locpntr, destpntr, data) char **locpntr, **destpntr; W_Event *data; { char l[MAXMACRO], r[MAXMACRO], condition = 0; short trueflag = 0; getTestString(l, locpntr, destpntr, data); if (**locpntr != '%') { condition = *((*locpntr)++); getTestString(r, locpntr, destpntr, data); } switch (condition) { case '=': if (!strcmp(l, r)) trueflag = 1; break; case '>': if (atoi(l) > atoi(r)) trueflag = 1; break; case '<': if (atoi(l) < atoi(r)) trueflag = 1; break; default: if (atoi(l)) trueflag = 1; } **destpntr = '0' + trueflag; *(*destpntr + 1) = 0; (*destpntr)++; return; } void handle_conditional(locpntr, destpntr, data) char **locpntr, **destpntr; W_Event *data; { (*locpntr)++; **destpntr = 0; (*destpntr)--; if (**destpntr == '0') { ignoreConditionalString(locpntr); getConditionalString(locpntr, destpntr, data); } else { getConditionalString(locpntr, destpntr, data); ignoreConditionalString(locpntr); } (*locpntr) += 2; while (**destpntr) (*destpntr)++; return; } void ignoreConditionalString(locpntr) char **locpntr; { int depth = 0, breakflag = 0; while (**locpntr) { if (**locpntr == '%') { switch (*(*locpntr + 1)) { case '!': if (!depth) breakflag = 1; (*locpntr) += 2; break; case '}': if (depth) { depth--; (*locpntr) += 2; } else breakflag = 1; break; case '{': depth++; (*locpntr) += 2; break; case '*': abortflag = 1; return; default: (*locpntr)++; } if (breakflag) break; } else (*locpntr)++; } } void getConditionalString(locpntr, destpntr, data) char **locpntr, **destpntr; W_Event *data; { char *dest = *destpntr; while (**locpntr) { if (**locpntr != '%' && **locpntr != '$' && **locpntr) *(dest++) = *((*locpntr)++); else if (*(*locpntr + 1) == '!') { (*locpntr) += 2; break; } else if (*(*locpntr + 1) == '}') break; else if (**locpntr == '%') { (*locpntr)++; handle_special(locpntr, &dest, data); while (*(dest++)); dest--; } else { /* **locpntr must equal '$' */ (*locpntr)++; handle_dollar(locpntr, &dest, data); while (*(dest++)); dest--; } } *dest = 0; return; } void getTestString(buf, locpntr, destpntr, data) char *buf, **locpntr, **destpntr; W_Event *data; { char *dest = buf; if (**locpntr == '%') { (*locpntr)++; handle_special(locpntr, &buf, data); } else if (**locpntr == '$') { (*locpntr)++; handle_dollar(locpntr, &buf, data); } else { while (**locpntr != '%' && **locpntr != '$' && **locpntr != '<' && **locpntr != '>' && **locpntr != '=' && **locpntr) *(dest++) = *((*locpntr)++); *dest = 0; } return; } char * strtoupper(buf) char *buf; { char *s; for (s = buf; *s; s++) *s = toupper(*s); return buf; } char * strtolower(buf) char *buf; { char *s; for (s = buf; *s; s++) *s = tolower(*s); return buf; } /**********************************************************************/ /* start with a $ field 1: (n)earest (t)arget (s)elf (doesn't have fields 2 and 3) (_) ego (has no other fields) field 2: (a)ny (t)eammate (f)riendly (h)ostile field 3: (a)ny (u)ser (p)lanet (includes asteroids) (s)tar (n)ebula (b)lack hole (^) non-planet (*) any stellar object field 4: (optional) NYI (U)ppercase (C)apitalize (L)owercase field 5: full (n)ame (Hammor, Thought) (i)dentifier (e.g. R5, Ka, Can, Sco) (#) number (0-9a-z for players, %d for planets) (t)eam name (Romulan) (s)hort team id (ROM) (l)etter of team (R) (a)rmies (@) sector (A)rable, 0=not arable, 1=arable but not AGRI, 2=AGRI (M)etal, 0, 1, 2(repair), or 3(sy) (D)ilithium, 0, 1 or 2(fuel) Any implementation of the paradise $ codes (subset or superset) must implement and document the $_ code. -- Robert Forsman */ void handle_dollar(locpntr, destpntr, data) char **locpntr, **destpntr; W_Event *data; { char *buf = *destpntr; struct id *target; char ch = *((*locpntr)++); W_Window w; int x, y; int flags; int capitalize = 0; buf[0] = 0; if (ch == '_') { strcpy(buf, "Paradise netrek $ codes are orthogonal and make sense."); while (**destpntr) (*destpntr)++; return; } if (ch == 's') { target = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER | TARG_SELF); } else { switch (tolower(ch)) { case 'n': w = 0; x = me->p_x; y = me->p_y; break; case 't': w = data->Window; x = data->x; y = data->y; break; default: printf("Invalid $ code field 1 : `%c'\n", ch); return; } ch = *((*locpntr)++); switch (tolower(ch)) { case 'a': flags = 0; break; case 't': flags = TARG_TEAM; break; case 'f': flags = TARG_FRIENDLY; break; case 'h': flags = TARG_ENEMY; break; default: printf("Invalid $ code field 2 : `%c'\n", ch); return; } ch = *((*locpntr)++); switch (tolower(ch)) { case 'a': flags |= TARG_PLAYER | TARG_ASTRAL; break; case 'u': flags |= TARG_PLAYER; break; case 'p': flags |= TARG_PLANET; break; case 's': flags |= TARG_STAR; break; case 'n': flags |= TARG_NEBULA; break; case 'b': flags |= TARG_BLACKHOLE; break; case '^': flags |= (TARG_ASTRAL & ~TARG_PLANET); /* fall through */ case '*': flags |= TARG_PLANET; break; default: printf("Invalid $ code field 3 : `%c'\n", ch); return; } target = getTargetID(w, x, y, flags); } ch = tolower(*((*locpntr)++)); if (ch == 'l') capitalize = -1; else if (ch == 'c') capitalize = 1; else if (ch == 'u') capitalize = 2; else (*locpntr)--; /* oops, back up and try again */ ch = *((*locpntr)++); switch (ch) { case 'n': strcpy(buf, target->name); break; case 'i': /* if (target->type == PLANETTYPE) {*/ strcpy(buf, target->mapstring); /* } else { buf[0] = target->mapstring[1]; buf[1] = 0; }*/ break; case '#': if (target->type == PLANETTYPE) { sprintf(buf, "%d", target->number); } else { buf[0] = target->mapstring[1]; buf[1] = 0; } break; case 't': strcpy(buf, teaminfo[target->team].name); break; case 's': strcpy(buf, teaminfo[target->team].shortname); break; case 'l': buf[0] = teaminfo[target->team].letter; buf[1] = 0; break; case 'a': sprintf(buf, "%d", (target->type == PLANETTYPE) ? planets[target->number].pl_armies : players[target->number].p_armies); break; case '@': if (!paradise) break; if (target->type == PLANETTYPE) { x = planets[target->number].pl_x; y = planets[target->number].pl_y; } else { x = players[target->number].p_x; y = players[target->number].p_y; } sprintf(buf, "%d-%d", x / GRIDSIZE + 1, y / GRIDSIZE + 1); break; case 'A': /* Arable or AGRI */ buf[0] = '0'; if (target->type == PLANETTYPE) { if (planets[target->number].pl_flags & PLARABLE) buf[0] = '1'; if (planets[target->number].pl_flags & PLAGRI) buf[0] = '2'; } buf[1] = 0; break; case 'M': /* Metal, Repair, or SY */ buf[0] = '0'; if (target->type == PLANETTYPE) { if (planets[target->number].pl_flags & PLMETAL) buf[0] = '1'; if (planets[target->number].pl_flags & PLREPAIR) buf[0] = '2'; if (planets[target->number].pl_flags & PLSHIPYARD) buf[0] = '3'; } buf[1] = 0; break; case 'D': /* Dilythium or Fuel */ buf[0] = '0'; if (target->type == PLANETTYPE) { if (planets[target->number].pl_flags & PLDILYTH) buf[0] = '1'; if (planets[target->number].pl_flags & PLFUEL) buf[0] = '2'; } buf[1] = 0; break; default: printf("Invalid $ code field 4 : `%c'\n", ch); return; } if (capitalize < 0) { char *s; for (s = buf; *s; s++) *s = tolower(*s); } else if (capitalize > 1) { char *s; for (s = buf; *s; s++) *s = toupper(*s); } else if (capitalize) { char *s; s = buf; *s = toupper(*s); for (s++; *s; s++) *s = tolower(*s); } while (**destpntr) (*destpntr)++; return; } #endif /* MACROS */