Ejemplo n.º 1
0
/*
 * The idea here is to take directives like this emitted
 * by cpp:
 *
 *	# num
 *
 * and convert them to directives like this that are
 * understood by the GNU assembler:
 *
 *	.line num
 *
 * and similarly:
 *
 *	# num "string" optional stuff
 *
 * is converted to
 *
 *	.line num
 *	.file "string"
 *
 * While this could be done with a sequence of sed
 * commands, this is simpler and faster..
 */
static pid_t
filter(int pipein, int pipeout)
{
	pid_t pid;
	FILE *in, *out;
	char *wspace;
	size_t wspace_len;

	if (verbose)
		(void) fprintf(stderr, "{#line filter} ");

	switch (pid = fork()) {
	case 0:
		if (dup2(pipein, 0) == -1 ||
		    dup2(pipeout, 1) == -1) {
			perror("dup2");
			exit(1);
		}
		closefrom(3);
		break;
	case -1:
		perror("fork");
		exit(1);
	default:
		return (pid);
	}

	in = fdopen(0, "r");
	out = fdopen(1, "w");

	/*
	 * Key off the CODEMGR_WS environment variable to detect
	 * if we're in an activated workspace, and to get the
	 * path to the workspace.
	 */
	wspace = getenv("CODEMGR_WS");
	if (wspace != NULL)
		wspace_len = strlen(wspace);

	while (!feof(in)) {
		int c, num;

		switch (c = fgetc(in)) {
		case '#':
			switch (fscanf(in, " %d", &num)) {
			case 0:
				/*
				 * discard comment lines completely
				 * discard ident strings completely too.
				 * (GNU as politely ignores them..)
				 */
				copyuntil(in, NULL, '\n');
				break;
			default:
				(void) fprintf(stderr, "fscanf botch?");
				/*FALLTHROUGH*/
			case EOF:
				exit(1);
				/*NOTREACHED*/
			case 1:
				/*
				 * This line has a number at the beginning;
				 * if it has a string after the number, then
				 * it's a filename.
				 *
				 * If this is an activated workspace, use
				 * copyuntil_path() to do path rewriting
				 * that will prevent workspace paths from
				 * being burned into the resulting object.
				 * If not in an activated workspace, then
				 * copy the existing path straight through
				 * without interpretation.
				 */
				if (fgetc(in) == ' ' && fgetc(in) == '"') {
					(void) fprintf(out, "\t.file \"");
					if (wspace != NULL)
						copyuntil_path(in, out, '"',
						    wspace, wspace_len);
					else
						copyuntil(in, out, '"');
					(void) fputc('\n', out);
				}
				(void) fprintf(out, "\t.line %d\n", num - 1);
				/*
				 * discard the rest of the line
				 */
				copyuntil(in, NULL, '\n');
				break;
			}
			break;
		case '\n':
			/*
			 * preserve newlines
			 */
			(void) fputc(c, out);
			break;
		case EOF:
			/*
			 * don't write EOF!
			 */
			break;
		default:
			/*
			 * lines that don't begin with '#' are copied
			 */
			(void) fputc(c, out);
			copyuntil(in, out, '\n');
			break;
		}

		if (ferror(out))
			exit(1);
	}

	exit(0);
	/*NOTREACHED*/
}
Ejemplo n.º 2
0
static int linescan(String *lp, String tokstring){

	int retval = TOK_ERR;
	
	switch(**lp){
		case '\n':
			/* New line */
			debug(DEBUG_INCOMPLETE, "TOK_NL");

			retval = TOK_NL;
			break;

		case ';': 
		case '#':
			debug(DEBUG_INCOMPLETE, "TOK_COMMENT");

			/* Comment */

			retval = TOK_COMMENT;
			break;

		case '=':
			/* Value */
			(*lp)++;
			copyuntil(tokstring, lp, MAX_VALUE, "#;\n");
			debug(DEBUG_INCOMPLETE, "TOK_VALUE");
			retval = TOK_VALUE;
			break;


 		case '[':
			/* Section start */

			(*lp)++;
			if(copyuntil(tokstring, lp, MAX_SECTION, "]\n") == ']'){
				(*lp)++;
				debug(DEBUG_INCOMPLETE, "TOK_SECTION");
				retval = TOK_SECTION;
			}
			else{
				debug(DEBUG_UNEXPECTED, "Section not closed off");
				retval = TOK_ERR; /* Section broken */
			}
			break;

		default:
			/* Look for a key */

			if(isalnum(**lp)){
				debug(DEBUG_INCOMPLETE, "lp: %s", *lp);
				copyuntil(tokstring, lp, MAX_KEY, "=\n");
				debug(DEBUG_INCOMPLETE, "stop char: %s", *lp);

				if(**lp == '='){
					debug(DEBUG_INCOMPLETE, "TOK_KEY");
					retval = TOK_KEY;
				}
				else{
					debug(DEBUG_INCOMPLETE, "TOK_ERR, key broken");
					retval = TOK_ERR; // Key broken
				}
			}
			else{
				debug(DEBUG_INCOMPLETE, "TOK_ERR, invalid char %c", **lp);
				retval = TOK_ERR; // Not something valid
			}
			break;
	}				
	return retval;
}