Example #1
0
// ----------------------------------------------------------------
static lrec_t* lrec_reader_mmap_csv_process(void* pvstate, void* pvhandle, context_t* pctx) {
	lrec_reader_mmap_csv_state_t* pstate = pvstate;
	file_reader_mmap_state_t* phandle = pvhandle;

	if (pstate->expect_header_line_next) {
		if (!lrec_reader_mmap_csv_get_fields(pstate, pstate->pfields, phandle))
			return NULL;
		pstate->ilno++;

		slls_t* pheader_fields = slls_alloc();
		int i = 0;
		for (rsllse_t* pe = pstate->pfields->phead; i < pstate->pfields->length && pe != NULL; pe = pe->pnext, i++) {
			if (*pe->value == 0) {
				fprintf(stderr, "%s: unacceptable empty CSV key at file \"%s\" line %lld.\n",
					MLR_GLOBALS.argv0, pctx->filename, pstate->ilno);
				exit(1);
			}
			// Transfer pointer-free responsibility from the rslls to the
			// header fields in the header keeper
			slls_append(pheader_fields, pe->value, pe->free_flag);
			pe->free_flag = 0;
		}
		rslls_reset(pstate->pfields);

		pstate->pheader_keeper = lhmslv_get(pstate->pheader_keepers, pheader_fields);
		if (pstate->pheader_keeper == NULL) {
			pstate->pheader_keeper = header_keeper_alloc(NULL, pheader_fields);
			lhmslv_put(pstate->pheader_keepers, pheader_fields, pstate->pheader_keeper,
				NO_FREE); // freed by header-keeper
		} else { // Re-use the header-keeper in the header cache
			slls_free(pheader_fields);
		}

		pstate->expect_header_line_next = FALSE;
	}
	int rc = lrec_reader_mmap_csv_get_fields(pstate, pstate->pfields, phandle);
	pstate->ilno++;
	if (rc == FALSE) // EOF
		return NULL;
	else {
		lrec_t* prec = pstate->use_implicit_header
			? paste_indices_and_data(pstate, pstate->pfields, pctx)
			: paste_header_and_data(pstate, pstate->pfields, pctx);
		rslls_reset(pstate->pfields);
		return prec;
	}
}
Example #2
0
// ----------------------------------------------------------------
static lrec_t* lrec_reader_stdio_csv_process(void* pvstate, void* pvhandle, context_t* pctx) {
	lrec_reader_stdio_csv_state_t* pstate = pvstate;

	// Ingest the next header line, if expected
	if (pstate->expect_header_line_next) {
		while (TRUE) {
			if (!lrec_reader_stdio_csv_get_fields(pstate, pstate->pfields, pctx, TRUE))
				return NULL;
			pstate->ilno++;

			// We check for comments here rather than within the parser since it's important
			// for users to be able to comment out lines containing double-quoted newlines.
			if (pstate->comment_string != NULL && pstate->pfields->phead != NULL) {
				if (streqn(pstate->pfields->phead->value, pstate->comment_string, pstate->comment_string_length)) {
					if (pstate->comment_handling == PASS_COMMENTS) {
						int i = 0;
						for (
							rsllse_t* pe = pstate->pfields->phead;
							i < pstate->pfields->length && pe != NULL;
							pe = pe->pnext, i++)
						{
							if (i > 0)
								fputs(pstate->ifs, stdout);
							fputs(pe->value, stdout);
						}
						if (pstate->do_auto_line_term) {
							fputs(pctx->auto_line_term, stdout);
						} else {
							fputs(pstate->irs, stdout);
						}
					}
					rslls_reset(pstate->pfields);
					continue;
				}
			}

			slls_t* pheader_fields = slls_alloc();
			int i = 0;
			for (rsllse_t* pe = pstate->pfields->phead; i < pstate->pfields->length && pe != NULL; pe = pe->pnext) {
				if (*pe->value == 0) {
					fprintf(stderr, "%s: unacceptable empty CSV key at file \"%s\" line %lld.\n",
						MLR_GLOBALS.bargv0, pctx->filename, pstate->ilno);
					exit(1);
				}
				// Transfer pointer-free responsibility from the rslls to the
				// header fields in the header keeper
				slls_append(pheader_fields, pe->value, pe->free_flag);
				pe->free_flag = 0;
			}
			rslls_reset(pstate->pfields);

			pstate->pheader_keeper = lhmslv_get(pstate->pheader_keepers, pheader_fields);
			if (pstate->pheader_keeper == NULL) {
				pstate->pheader_keeper = header_keeper_alloc(NULL, pheader_fields);
				lhmslv_put(pstate->pheader_keepers, pheader_fields, pstate->pheader_keeper,
					NO_FREE); // freed by header-keeper
			} else { // Re-use the header-keeper in the header cache
				slls_free(pheader_fields);
			}

			pstate->expect_header_line_next = FALSE;
			break;
		}
	}

	// Ingest the next data line, if expected
	while (TRUE) {
		int rc = lrec_reader_stdio_csv_get_fields(pstate, pstate->pfields, pctx, FALSE);
		pstate->ilno++;
		if (rc == FALSE) // EOF
			return NULL;

		// We check for comments here rather than within the parser since it's important
		// for users to be able to comment out lines containing double-quoted newlines.
		if (pstate->comment_string != NULL && pstate->pfields->phead != NULL) {
			if (streqn(pstate->pfields->phead->value, pstate->comment_string, pstate->comment_string_length)) {
				if (pstate->comment_handling == PASS_COMMENTS) {
					int i = 0;
					for (
						rsllse_t* pe = pstate->pfields->phead;
						i < pstate->pfields->length && pe != NULL;
						pe = pe->pnext, i++)
					{
						if (i > 0)
							fputs(pstate->ifs, stdout);
						fputs(pe->value, stdout);
					}
					if (pstate->do_auto_line_term) {
						fputs(pctx->auto_line_term, stdout);
					} else {
						fputs(pstate->irs, stdout);
					}
				}
				rslls_reset(pstate->pfields);
				continue;
			}
		}

		lrec_t* prec =  pstate->use_implicit_header
			? paste_indices_and_data(pstate, pstate->pfields, pctx)
			: paste_header_and_data(pstate, pstate->pfields, pctx);
		rslls_reset(pstate->pfields);
		return prec;
	}
}