//============================================================================
// Name        : pci-parser.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <fstream>

#include <cstring>
#include <map>
#include <vector>

using namespace std;

struct Device
{
	string vendorId;
	string vendorName;
	string deviceId;
	string deviceName;
};

void escapeString(string& str)
{
	string::iterator pos = str.begin();
	while (pos !=  str.end())
	{
		if (*pos == '"' || *pos == '?' || *pos == '\\')
		{
			pos = str.insert(pos, '\\');
			pos ++;
		}
		pos ++;
	}
}

int main()
{
	ifstream in("./pci.ids");

	char buffer[1024];
	vector<Device> vectDevice;
	string strVendorName;
	string strVendorId;

	while (in.good())
	{
		in.getline(buffer, sizeof(buffer));


		if (!in.eof())
		{
			string str(buffer);
			if (str.empty())
			{
				continue;
			}
			if (buffer[0] == '#') // comment
			{
				continue;
			}
			if (buffer[0] == '\t')
			{
				// a sub entry
				Device device;

				device.vendorId = strVendorId;
				device.vendorName = strVendorName;
				int start = 1;
				while (buffer[start] == '\t') start++;
				device.deviceId.assign(buffer+start, buffer+start+4);
				device.deviceName.assign(buffer+start+4+2, buffer+strlen(buffer));

				if (device.deviceId.find(' ') != string::npos ||
					device.vendorId.find(' ') != string::npos)
				{
					continue;
				}
				escapeString(device.vendorName);
				escapeString(device.deviceName);
				vectDevice.push_back(device);
			}
			else
			{
				// new vendor
				strVendorId.assign(buffer, buffer+4);
				strVendorName.assign(buffer+6, buffer+ strlen(buffer));
			}
		}
	}
	cout << "struct PCIDeviceTable\n\
{\n\
	\tconst char*pszVendorId;\n\
	\tconst char*pszVendorName;\n\
	\tconst char*pszDeviceId;\n\
	\tconst char*pszDeviceName;\n\
};\n\
static PCIDeviceTable pciDeviceTable[] =\n";
	cout << "{\n";
	for (size_t i = 0; i < vectDevice.size(); i ++)
	{
		const Device& device=vectDevice[i];
		cout << "\t{\n\t\t\"0x" << device.vendorId << "\",\"" << device.vendorName
				<< "\",\"0x" << device.deviceId << "\",\"" << device.deviceName << "\"\n\t},\n";
	}
	cout << "};\n";
	return 0;
}
