&& (sym->usage & uDEFINE) == 0)
&& (sym->usage & uDEFINE) == 0))
command(void){   int                 tok, ret;   cell                val;   char               *str;   int                 index;   cell                code_index;   while (*lptr <= ' ' && *lptr != '\0')      lptr += 1;   if (*lptr == '\0')      return CMD_EMPTYLINE;	/* empty line */   if (*lptr != '#')      return skiplevel > 0 ? CMD_CONDFALSE : CMD_NONE;	/* it is not a compiler directive */   /* compiler directive found */   indent_nowarn = TRUE;	/* allow loose indentation" */   lexclr(FALSE);		/* clear any "pushed" tokens */   /* on a pending expression, force to return a silent ';' token and force to    * re-read the line    */   if (!sc_needsemicolon && stgget(&index, &code_index))     {	lptr = term_expr;	return CMD_TERM;     }				/* if */   tok = lex(&val, &str);   ret = skiplevel > 0 ? CMD_CONDFALSE : CMD_DIRECTIVE;	/* preset 'ret' to CMD_DIRECTIVE (most common case) */   switch (tok)     {     case tpIF:		/* conditional compilation */	ret = CMD_IF;	iflevel += 1;	if (skiplevel)	   break;		/* break out of switch */	preproc_expr(&val, NULL);	/* get value (or 0 on error) */	if (!val)	   skiplevel = iflevel;	check_empty(lptr);	break;     case tpELSE:	ret = CMD_IF;	if (iflevel == 0 && skiplevel == 0)	  {	     error(26);		/* no matching #if */	     errorset(sRESET);	  }	else	  {	     if (elsedone == iflevel)		error(60);	/* multiple #else directives between #if ... #endif */	     elsedone = iflevel;	     if (skiplevel == iflevel)		skiplevel = 0;	     else if (skiplevel == 0)		skiplevel = iflevel;	  }			/* if */	check_empty(lptr);	break;#if 0				/* ??? *really* need to use a stack here */     case tpELSEIF:	ret = CMD_IF;	if (iflevel == 0 && skiplevel == 0)	  {	     error(26);		/* no matching #if */	     errorset(sRESET);	  }	else if (elsedone == iflevel)	  {	     error(61);		/* #elseif directive may not follow an #else */	     errorset(sRESET);	  }	else	  {	     preproc_expr(&val, NULL);	/* get value (or 0 on error) */	     if (skiplevel == 0)		skiplevel = iflevel;	/* we weren't skipping, start skipping now */	     else if (val)		skiplevel = 0;	/* we were skipping, condition is valid -> stop skipping */	     /* else: we were skipping and condition is invalid -> keep skipping */	     check_empty(lptr);	  }			/* if */	break;#endif     case tpENDIF:	ret = CMD_IF;	if (iflevel == 0 && skiplevel == 0)	  {	     error(26);	     errorset(sRESET);	  }	else	  {	     if (skiplevel == iflevel)		skiplevel = 0;	     if (elsedone == iflevel)		elsedone = 0;	/* ??? actually, should build a stack of #if/#endif and keep				 * the state whether an #else was seen per nesting level */	     iflevel -= 1;	  }			/* if */	check_empty(lptr);	break;     case tINCLUDE:		/* #include directive */	ret = CMD_INCLUDE;	if (skiplevel == 0)	   doinclude();	break;     case tpFILE:	if (skiplevel == 0)	  {	     char                pathname[_MAX_PATH];	     lptr = getstring(pathname, sizeof pathname, lptr);	     if (strlen(pathname) > 0)	       {		  free(inpfname);		  inpfname = duplicatestring(pathname);		  if (inpfname == NULL)		     error(103);	/* insufficient memory */	       }		/* if */	  }			/* if */	check_empty(lptr);	break;     case tpLINE:	if (skiplevel == 0)	  {	     if (lex(&val, &str) != tNUMBER)		error(8);	/* invalid/non-constant expression */	     fline = (int)val;	  }			/* if */	check_empty(lptr);	break;     case tpASSERT:	if (skiplevel == 0 && (sc_debug & sCHKBOUNDS) != 0)	  {	     preproc_expr(&val, NULL);	/* get constant expression (or 0 on error) */	     if (!val)		error(7);	/* assertion failed */	     check_empty(lptr);	  }			/* if */	break;     case tpPRAGMA:	if (skiplevel == 0)	  {	     if (lex(&val, &str) == tSYMBOL)	       {		  if (strcmp(str, "ctrlchar") == 0)		    {		       if (lex(&val, &str) != tNUMBER)			  error(27);	/* invalid character constant */		       sc_ctrlchar = (char)val;		    }		  else if (strcmp(str, "compress") == 0)		    {		       cell                val;		       preproc_expr(&val, NULL);		       sc_compress = (int)val;	/* switch code packing on/off */		    }		  else if (strcmp(str, "dynamic") == 0)		    {		       preproc_expr(&sc_stksize, NULL);		    }		  else if (strcmp(str, "library") == 0)		    {		       char                name[sNAMEMAX + 1];		       while (*lptr <= ' ' && *lptr != '\0')			  lptr++;		       if (*lptr == '"')			 {			    lptr = getstring(name, sizeof name, lptr);			 }		       else			 {			    int                 i;			    for (i = 0; i < sizeof name && alphanum(*lptr);				 i++, lptr++)			       name[i] = *lptr;			    name[i] = '\0';			 }	/* if */		       if (strlen(name) == 0)			 {			    curlibrary = NULL;			 }		       else			 {			    if (strlen(name) > sEXPMAX)			       error(220, name, sEXPMAX);	/* exported symbol is truncated */			    /* add the name if it does not yet exist in the table */			    if (find_constval(&libname_tab, name, 0) == NULL)			       curlibrary =				  append_constval(&libname_tab, name, 0, 0);			 }	/* if */		    }		  else if (strcmp(str, "pack") == 0)		    {		       cell                val;		       preproc_expr(&val, NULL);	/* default = packed/unpacked */		       sc_packstr = (int)val;		    }		  else if (strcmp(str, "rational") == 0)		    {		       char                name[sNAMEMAX + 1];		       cell                digits = 0;		       int                 i;		       /* first gather all information, start with the tag name */		       while (*lptr <= ' ' && *lptr != '\0')			  lptr++;		       for (i = 0; i < sizeof name && alphanum(*lptr);			    i++, lptr++)			  name[i] = *lptr;		       name[i] = '\0';		       /* then the precision (for fixed point arithmetic) */		       while (*lptr <= ' ' && *lptr != '\0')			  lptr++;		       if (*lptr == '(')			 {			    preproc_expr(&digits, NULL);			    if (digits <= 0 || digits > 9)			      {				 error(68);	/* invalid rational number precision */				 digits = 0;			      }	/* if */			    if (*lptr == ')')			       lptr++;			 }	/* if */		       /* add the tag (make it public) and check the values */		       i = sc_addtag(name);		       exporttag(i);		       if (sc_rationaltag == 0			   || (sc_rationaltag == i			       && rational_digits == (int)digits))			 {			    sc_rationaltag = i;			    rational_digits = (int)digits;			 }		       else			 {			    error(69);	/* rational number format already set, can only be set once */			 }	/* if */		    }		  else if (strcmp(str, "semicolon") == 0)		    {		       cell                val;		       preproc_expr(&val, NULL);		       sc_needsemicolon = (int)val;		    }		  else if (strcmp(str, "tabsize") == 0)		    {		       cell                val;		       preproc_expr(&val, NULL);		       sc_tabsize = (int)val;		    }		  else if (strcmp(str, "align") == 0)		    {		       sc_alignnext = TRUE;		    }		  else if (strcmp(str, "unused") == 0)		    {		       char                name[sNAMEMAX + 1];		       int                 i, comma;		       symbol             *sym;		       do			 {			    /* get the name */			    while (*lptr <= ' ' && *lptr != '\0')			       lptr++;			    for (i = 0; i < sizeof name && isalpha(*lptr);				 i++, lptr++)			       name[i] = *lptr;			    name[i] = '\0';			    /* get the symbol */			    sym = findloc(name);			    if (sym == NULL)			       sym = findglb(name);			    if (sym != NULL)			      {				 sym->usage |= uREAD;				 if (sym->ident == iVARIABLE				     || sym->ident == iREFERENCE				     || sym->ident == iARRAY				     || sym->ident == iREFARRAY)				    sym->usage |= uWRITTEN;			      }			    else			      {				 error(17, name);	/* undefined symbol */			      }	/* if */			    /* see if a comma follows the name */			    while (*lptr <= ' ' && *lptr != '\0')			       lptr++;			    comma = (*lptr == ',');			    if (comma)			       lptr++;			 }		       while (comma);		    }		  else		    {		       error(207);	/* unknown #pragma */		    }		/* if */	       }	     else	       {		  error(207);	/* unknown #pragma */	       }		/* if */	     check_empty(lptr);	  }			/* if */	break;     case tpENDINPUT:     case tpENDSCRPT:	if (skiplevel == 0)	  {	     check_empty(lptr);	     assert(inpf != NULL);	     if (inpf != inpf_org)		sc_closesrc(inpf);	     inpf = NULL;	  }			/* if */	break;#if !defined NOEMIT     case tpEMIT:	{	   /* write opcode to output file */	   char                name[40];	   int                 i;	   while (*lptr <= ' ' && *lptr != '\0')	      lptr++;	   for (i = 0; i < 40 && (isalpha(*lptr) || *lptr == '.'); i++, lptr++)	      name[i] = (char)tolower(*lptr);	   name[i] = '\0';	   stgwrite("\t");	   stgwrite(name);	   stgwrite(" ");	   code_idx += opcodes(1);	   /* write parameter (if any) */	   while (*lptr <= ' ' && *lptr != '\0')	      lptr++;	   if (*lptr != '\0')	     {		symbol             *sym;		tok = lex(&val, &str);		switch (tok)		  {		  case tNUMBER:		  case tRATIONAL:		     outval(val, FALSE);		     code_idx += opargs(1);		     break;		  case tSYMBOL:		     sym = findloc(str);		     if (sym == NULL)			sym = findglb(str);		     if (sym == NULL || sym->ident != iFUNCTN			 && sym->ident != iREFFUNC			 && (sym->usage & uDEFINE) == 0)		       {			  error(17, str);	/* undefined symbol */		       }		     else		       {			  outval(sym->addr, FALSE);			  /* mark symbol as "used", unknown whether for read or write */			  markusage(sym, uREAD | uWRITTEN);			  code_idx += opargs(1);		       }	/* if */		     break;		  default:		     {			char                s2[20];			extern char        *sc_tokens[];	/* forward declaration */			if (tok < 256)			   sprintf(s2, "%c", (char)tok);			else			   strcpy(s2, sc_tokens[tok - tFIRST]);			error(1, sc_tokens[tSYMBOL - tFIRST], s2);			break;		     }		/* case */		  }		/* switch */	     }			/* if */	   stgwrite("\n");	   check_empty(lptr);	   break;	}			/* case */#endif#if !defined NO_DEFINE     case tpDEFINE:	{	   ret = CMD_DEFINE;	   if (skiplevel == 0)	     {		char               *pattern, *substitution;		char               *start, *end;		int                 count, prefixlen;		stringpair         *def;		/* find the pattern to match */		while (*lptr <= ' ' && *lptr != '\0')		   lptr++;		start = lptr;	/* save starting point of the match pattern */		count = 0;		while (*lptr > ' ' && *lptr != '\0')		  {		     litchar(&lptr, FALSE);	/* litchar() advances "lptr" and handles escape characters */		     count++;		  }		/* while */		end = lptr;		/* check pattern to match */		if (!isalpha(*start) && *start != '_')		  {		     error(74);	/* pattern must start with an alphabetic character */		     break;		  }		/* if */		/* store matched pattern */		pattern = malloc(count + 1);		if (pattern == NULL)		   error(103);	/* insufficient memory */		lptr = start;		count = 0;		while (lptr != end)		  {		     assert(lptr < end);		     assert(*lptr != '\0');		     pattern[count++] = (char)litchar(&lptr, FALSE);		  }		/* while */		pattern[count] = '\0';		/* special case, erase trailing variable, because it could match anything */		if (count >= 2 && isdigit(pattern[count - 1])		    && pattern[count - 2] == '%')		   pattern[count - 2] = '\0';		/* find substitution string */		while (*lptr <= ' ' && *lptr != '\0')		   lptr++;		start = lptr;	/* save starting point of the match pattern */		count = 0;		end = NULL;		while (*lptr != '\0')		  {		     /* keep position of the start of trailing whitespace */		     if (*lptr <= ' ')		       {			  if (end == NULL)			     end = lptr;		       }		     else		       {			  end = NULL;		       }	/* if */		     count++;		     lptr++;		  }		/* while */		if (end == NULL)		   end = lptr;		/* store matched substitution */		substitution = malloc(count + 1);	/* +1 for '\0' */		if (substitution == NULL)		   error(103);	/* insufficient memory */		lptr = start;		count = 0;		while (lptr != end)		  {		     assert(lptr < end);		     assert(*lptr != '\0');		     substitution[count++] = *lptr++;		  }		/* while */		substitution[count] = '\0';		/* check whether the definition already exists */		for (prefixlen = 0, start = pattern;		     isalpha(*start) || isdigit(*start) || *start == '_';		     prefixlen++, start++)		   /* nothing */ ;		assert(prefixlen > 0);		if ((def = find_subst(pattern, prefixlen)) != NULL)		  {		     if (strcmp(def->first, pattern) != 0			 || strcmp(def->second, substitution) != 0)			error(201, pattern);	/* redefinition of macro (non-identical) */		     delete_subst(pattern, prefixlen);		  }		/* if */		/* add the pattern/substitution pair to the list */		assert(strlen(pattern) > 0);		insert_subst(pattern, substitution, prefixlen);		free(pattern);		free(substitution);	     }			/* if */	   break;	}			/* case */     case tpUNDEF:	if (skiplevel == 0)	  {	     if (lex(&val, &str) == tSYMBOL)	       {		  if (!delete_subst(str, strlen(str)))		     error(17, str);	/* undefined symbol */	       }	     else	       {		  error(20, str);	/* invalid symbol name */	       }		/* if */	     check_empty(lptr);	  }			/* if */	break;#endif     default:	error(31);		/* unknown compiler directive */	ret = skiplevel > 0 ? CMD_DIRECTIVE : CMD_NONE;	/* line must be processed (if skiplevel==0) */     }				/* switch */   return ret;}