1 ///////////////////////////////////////////////////////////////////////////////
2 /*
3  * Copyright (c) 2022, Intel Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24 ///////////////////////////////////////////////////////////////////////////////
25 
26 #include <iostream>
27 #include <fstream>
28 #include <sstream>
29 #include <iomanip>
30 #include <string>
31 #include <map>
32 #include <algorithm>
33 #include <sys/stat.h>
34 #include <ctime>
35 #ifdef __linux__
36 #include <bits/stdc++.h>
37 #endif
38 
39 static const int32_t  MAJ_VERSION   = 1;
40 static const int32_t  MIN_VERSION   = 1;
41 static const char *HEADER_EXT       = ".h";
42 static const char *SOURCE_EXT       = ".c";
43 static const char *PARAM_I          = "-i";
44 static const char *PARAM_O          = "-o";
45 static const char *PARAM_V          = "-v";
46 static const char *PARAM_INDEX      = "-index";
47 static const char *PARAM_TOTAL      = "-t";
48 
49 #ifdef LINUX_
50 static const char *FILE_SEP         = "/";
51 #else
52 static const char *FILE_SEP         = "\\";
53 #endif
54 
55 static std::string COPYRIGHT = "";
56 static const std::string copyright_front =
57     "/*\n"
58     " * Copyright (c) "
59     ;
60 static const std::string copyright_end =
61     ", Intel Corporation\n"
62     " *\n"
63     " * Permission is hereby granted, free of charge, to any person obtaining a\n"
64     " * copy of this software and associated documentation files (the\n"
65     " * 'Software'), to deal in the Software without restriction, including\n"
66     " * without limitation the rights to use, copy, modify, merge, publish,\n"
67     " * distribute, sublicense, and/or sell copies of the Software, and to\n"
68     " * permit persons to whom the Software is furnished to do so, subject to\n"
69     " * the following conditions:\n"
70     " *\n"
71     " * The above copyright notice and this permission notice shall be included\n"
72     " * in all copies or substantial portions of the Software.\n"
73     " *\n"
74     " * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS\n"
75     " * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n"
76     " * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n"
77     " * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n"
78     " * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n"
79     " * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n"
80     " * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
81     "*/\n"
82     "\n"
83     "////////////////////////////////////////////////////////////////////////////////\n"
84     "// !!! WARNING - AUTO GENERATED FILE. DO NOT EDIT DIRECTLY. !!!\n"
85     "// Generated by KernelBinToSource.exe tool\n"
86     "////////////////////////////////////////////////////////////////////////////////\n"
87     ;
88 
89 
90 //-----------------------------------------------------------------------------
91 // String EndsWith
92 //-----------------------------------------------------------------------------
strEndsWith(const std::string & str,const std::string & substr)93 bool strEndsWith(
94     const std::string &str,
95     const std::string &substr)
96 {
97     size_t i = str.rfind(substr);
98     return (i != std::string::npos) && (i == (str.length() - substr.length()));
99 }
100 
101 //-----------------------------------------------------------------------------
102 // Append Path
103 //-----------------------------------------------------------------------------
appendPath(const std::string & sPath,const std::string & sSubPath)104 std::string appendPath(
105     const std::string &sPath,
106     const std::string &sSubPath)
107 {
108     std::string strAppendPath = sPath;
109     if (!strEndsWith(sPath, FILE_SEP))
110     {
111         strAppendPath += FILE_SEP;
112     }
113     strAppendPath += sSubPath;
114 
115     return strAppendPath;
116 }
117 
118 //-----------------------------------------------------------------------------
119 // Get the filename from file path
120 //-----------------------------------------------------------------------------
getFileName(const std::string & sFilePath)121 std::string getFileName(const std::string &sFilePath)
122 {
123 #ifdef LINUX_
124     std::string::size_type uiLoc = sFilePath.rfind("/");
125 #else
126     std::string::size_type uiLoc = sFilePath.rfind("\\");
127 #endif
128 
129     if (uiLoc != std::string::npos)
130     {
131         return sFilePath.substr(uiLoc+1, sFilePath.length());
132     }
133 
134     return sFilePath;
135 }
136 
137 //-----------------------------------------------------------------------------
138 // Writes the Header file
139 //-----------------------------------------------------------------------------
writeHeaderFile(const uint32_t * pBuffer,uint32_t uiSize,const std::string & sFileName,const std::string & sVarName)140 int32_t writeHeaderFile(
141     const uint32_t      *pBuffer,
142     uint32_t             uiSize,
143     const std::string   &sFileName,
144     const std::string   &sVarName)
145 {
146     int32_t             iStatus = -1;
147     std::ofstream       oOutStream;
148     std::stringstream   oSs;
149     std::string         sHeaderSentry;
150     std::string         sSizeName;
151 
152     oOutStream.open(sFileName.c_str(), std::ios::out | std::ios::trunc );
153     if (!oOutStream.is_open())
154     {
155         printf("Error: Unable to open file '%s' for writing\n", sFileName.c_str());
156         goto finish;
157     }
158 
159     sHeaderSentry = "__" + sVarName + "_H__";
160     sSizeName = "extern const unsigned int " + sVarName + "_SIZE";
161 
162     oSs << COPYRIGHT
163         << "#ifndef " << sHeaderSentry << std::endl
164         << "#define " << sHeaderSentry << std::endl << std::endl
165         << sSizeName.c_str() << ";" << std::endl
166         << "extern const unsigned int " << sVarName.c_str() << "[]" << ";"
167         << std::endl << std::endl;
168 
169     oSs << "#endif // " << sHeaderSentry << std::endl;
170 
171     oOutStream << oSs.rdbuf();
172 
173     printf("Header file '%s' generated successfully!\n", sFileName.c_str());
174 
175     iStatus = 0;
176 
177 finish:
178     if (oOutStream.is_open())
179     {
180         oOutStream.close();
181     }
182 
183     return iStatus;
184 }
185 
186 //-----------------------------------------------------------------------------
187 // Writes Partial Source file
188 //-----------------------------------------------------------------------------
writePartialSourceFile(const uint32_t * pBuffer,uint32_t uiSize,const std::string & sFileName,const std::string & sVarName,const uint32_t & index,const uint32_t & total)189 int32_t writePartialSourceFile(
190     const uint32_t      *pBuffer,
191     uint32_t            uiSize,
192     const std::string   &sFileName,
193     const std::string   &sVarName,
194     const uint32_t      &index,
195     const uint32_t      &total)
196 {
197     int32_t             iStatus = -1;
198     std::ofstream       oOutStream;
199     std::stringstream   oSs;
200     std::string         sSizeName;
201     std::string         sPlatformName;
202     const uint32_t uiHexLen = 11;
203     char sHex[uiHexLen];
204     uint32_t offset_size = 0;
205     uint32_t final_size = (uiSize + total) * sizeof(uint32_t);
206     uint32_t stub = 0;
207 
208     int gPos     = 0;
209     int underPos = 0;
210 
211     oOutStream.open(sFileName.c_str(), std::ios::out | std::ios::trunc );
212     if (!oOutStream.is_open())
213     {
214         printf("Error: Unable to open file '%s' for writing\n", sFileName.c_str());
215         goto finish;
216     }
217 
218     sSizeName = "extern const unsigned int " + sVarName + "_SIZE";
219 
220     sPlatformName = sVarName;
221 
222     // support platform/ip names of both G series and Xe series
223     gPos = sPlatformName.find_first_of('G', 3);
224     underPos = sPlatformName.find_first_of('_');
225     if (gPos > 3 && gPos - 1 == underPos)
226     {
227         sPlatformName.erase(0, gPos + 1);
228         sPlatformName = "GEN" + sPlatformName;
229     }
230     else
231     {
232         sPlatformName.erase(0, underPos + 1);
233         std::map<std::string, std::string> nameMap = {
234             {"XE_HPG", "XE_HPG"}, {"XE_HPG_CMFCPATCH", "XE_HPG_CMFCPATCH"}
235         };
236 
237         if (nameMap.find(sPlatformName) == nameMap.end())
238         {
239             printf("Error: Unable to recognize platform name '%s', KernelBinToSource tool should add support for newer platform\n", sPlatformName.c_str());
240             goto finish;
241         }
242         sPlatformName = nameMap[sPlatformName];
243     }
244 
245     oSs << COPYRIGHT << std::endl;
246     oSs << "#ifdef IGFX_" << sPlatformName.c_str() << "_SUPPORTED" << std::endl;
247     oSs << sSizeName.c_str() << " = " << final_size << ";" << std::endl
248         << "extern const unsigned int " << sVarName.c_str() << "[] ="
249         << std::endl << "{";
250 
251     for(stub = 0; stub < total; stub++)
252     {
253         if (stub % 8 == 0)
254         {
255             oSs << std::endl << "    ";
256         }
257 
258         if( stub == index + 1)
259         {
260             offset_size = uiSize * sizeof(uint32_t);
261         }
262 
263         snprintf(sHex, uiHexLen, "0x%08x", offset_size);
264 
265         sHex[uiHexLen - 1] = '\0';
266 
267         if (stub % 8 == 7)
268         {
269             oSs << sHex << ",";
270         }else
271         {
272             oSs << sHex << ", ";
273         }
274     }
275 
276     for (uint32_t i = 0; i < uiSize; i++)
277     {
278         if ((i + stub) % 8 == 0)
279         {
280             oSs << std::endl << "    ";
281         }
282 
283         snprintf(sHex, uiHexLen, "0x%08x", pBuffer[i]);
284         sHex[uiHexLen - 1] = '\0';
285         oSs << sHex;
286 
287         if (i < (uiSize - 1))
288         {
289             if ((i + stub) % 8 == 7)
290             {
291                 oSs << ",";
292             }
293             else
294             {
295                 oSs << ", ";
296             }
297         }
298     }
299 
300     oSs << std::endl << "};" << std::endl;
301 
302     //Dummy kernel filled with 216 bytes
303     oSs << "#else" << std::endl
304         << sSizeName.c_str() << " = 216;" << std::endl
305         << "extern const unsigned int " << sVarName.c_str() << "[] = {" << std::endl
306         << "    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000," << std::endl
307         << "};" << std::endl
308         << "#endif" << std::endl;
309 
310     oOutStream << oSs.rdbuf();
311 
312     printf("Source file '%s' generated successfully!\n", sFileName.c_str());
313 
314     iStatus = 0;
315 
316 finish:
317     if (oOutStream.is_open())
318     {
319         oOutStream.close();
320     }
321 
322     return iStatus;
323 }
324 
325 //-----------------------------------------------------------------------------
326 // Writes the Source file
327 //-----------------------------------------------------------------------------
writeSourceFile(const uint32_t * pBuffer,uint32_t uiSize,const std::string & sFileName,const std::string & sVarName)328 int32_t writeSourceFile(
329     const uint32_t      *pBuffer,
330     uint32_t            uiSize,
331     const std::string   &sFileName,
332     const std::string   &sVarName)
333 {
334     int32_t             iStatus = -1;
335     std::ofstream       oOutStream;
336     std::stringstream   oSs;
337     std::string         sSizeName;
338     std::string         sPlatformName;
339     const uint32_t uiHexLen = 11;
340     char sHex[uiHexLen];
341 
342     int gPos     = 0;
343     int underPos = 0;
344 
345     oOutStream.open(sFileName.c_str(), std::ios::out | std::ios::trunc );
346     if (!oOutStream.is_open())
347     {
348         printf("Error: Unable to open file '%s' for writing\n", sFileName.c_str());
349         goto finish;
350     }
351 
352     sSizeName = "extern const unsigned int " + sVarName + "_SIZE";
353 
354     sPlatformName = sVarName;
355 
356     // support platform/ip names of both G series and Xe series
357     gPos = sPlatformName.find_first_of('G', 3);
358     underPos = sPlatformName.find_first_of('_');
359     if (gPos > 3 && gPos - 1 == underPos)
360     {
361         sPlatformName.erase(0, gPos + 1);
362         sPlatformName = "GEN" + sPlatformName;
363     }
364     else
365     {
366         sPlatformName.erase(0, underPos + 1);
367         std::map<std::string, std::string> nameMap = {
368             {"XE_HPG", "XE_HPG"}, {"XE_HPG_CMFCPATCH", "XE_HPG_CMFCPATCH"}
369         };
370 
371         if (nameMap.find(sPlatformName) == nameMap.end())
372         {
373             printf("Error: Unable to recognize platform name '%s', KernelBinToSource tool should add support for newer platform\n", sPlatformName.c_str());
374             goto finish;
375         }
376         sPlatformName = nameMap[sPlatformName];
377     }
378 
379     oSs << COPYRIGHT << std::endl;
380     oSs << "#ifdef IGFX_" << sPlatformName.c_str() << "_SUPPORTED" << std::endl;
381 
382     oSs << sSizeName.c_str() << " = " << uiSize * sizeof(uint32_t) << ";" << std::endl
383         << "extern const unsigned int " << sVarName.c_str() << "[] ="
384         << std::endl << "{";
385 
386     for (uint32_t i = 0; i < uiSize; i++)
387     {
388         if (i % 8 == 0)
389         {
390             oSs << std::endl << "    ";
391         }
392 
393         snprintf(sHex, uiHexLen, "0x%08x", pBuffer[i]);
394         sHex[uiHexLen - 1] = '\0';
395         oSs << sHex;
396 
397         if (i < (uiSize - 1))
398         {
399             oSs << ", ";
400         }
401     }
402     oSs << std::endl << "};" << std::endl;
403 
404     //Dummy kernel filled with 216 bytes
405     oSs << "#else" << std::endl
406         << sSizeName.c_str() << " = 216;" << std::endl
407         << "extern const unsigned int " << sVarName.c_str() << "[] = {" << std::endl
408         << "    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000," << std::endl
409         << "};" << std::endl
410         << "#endif" << std::endl;
411 
412     oOutStream << oSs.rdbuf();
413 
414     printf("Source file '%s' generated successfully!\n", sFileName.c_str());
415 
416     iStatus = 0;
417 
418 finish:
419     if (oOutStream.is_open())
420     {
421         oOutStream.close();
422     }
423 
424     return iStatus;
425 }
426 
427 //-----------------------------------------------------------------------------
428 // Creates the Source file
429 //-----------------------------------------------------------------------------
createSourceFile(const std::string & sInputFile,const std::string & sOutputDir,const std::string & sVar,const uint32_t & index,const uint32_t & total)430 int32_t createSourceFile(
431     const std::string &sInputFile,
432     const std::string &sOutputDir,
433     const std::string &sVar,
434     const uint32_t &index,
435     const uint32_t &total)
436 {
437     struct stat     StatResult;
438     int32_t         iStatus = -1;
439     std::ifstream   oInStream;
440     std::string     sInputFileName;
441     std::string     sOutputFile;
442     std::string     sVarName;
443     uint32_t        *pBuffer    = nullptr;
444     uint32_t        uiSize      = 0;
445     float fSize     = (ceil)(0.0f);
446     uint32_t uiIntSize  = 0;
447 
448     // Check if input file exists
449     if (0 != stat(sInputFile.c_str(), &StatResult))
450     {
451         printf("Error: Unable to read file '%s'\n", sInputFile.c_str());
452         goto finish;
453     }
454     uiSize = StatResult.st_size;
455 
456     if (sOutputDir.length() > 0)
457     {
458         // Check if out direction exists and validate it is a directory
459         if (0 != stat(sOutputDir.c_str(), &StatResult))
460         {
461             printf("Error: Unable to find directory '%s'\n", sOutputDir.c_str());
462             goto finish;
463         }
464         if (0 == (StatResult.st_mode & S_IFDIR))
465         {
466             printf("Error: Path '%s' is a valid directory\n", sOutputDir.c_str());
467             goto finish;
468         }
469     }
470 
471     sInputFileName = getFileName(sInputFile);
472     if (sOutputDir.find("media_softlet") != std::string::npos)
473     {
474         // For media softlet, move vp kernel from media ip to render ip
475         std::string::size_type replaceIndex = sInputFileName.find("_hpm");
476 
477         if(replaceIndex != std::string::npos)
478         {
479             sInputFileName.replace(replaceIndex, 4, "_hpg");
480         }
481     }
482 
483     {
484         // Set the Output path
485         std::string::size_type uiLoc = sInputFileName.find(".", 0 );
486         sOutputFile = (uiLoc != std::string::npos) ? sInputFileName.substr(0, uiLoc) : sInputFileName;
487         sVarName = (sVar.length() == 0) ? sOutputFile : sVar;
488     }
489 
490     // Read the File
491     oInStream.open(sInputFile.c_str(), std::ios::in | std::ios::binary);
492     if (! oInStream.is_open())
493     {
494         printf("Error: Unable to open file '%s' for reading\n", sInputFile.c_str());
495         goto finish;
496     }
497 
498     // Read from the file
499     fSize     = (ceil)(uiSize / 4.0f);
500     uiIntSize  = static_cast<uint32_t>(fSize);
501 
502     pBuffer = new uint32_t[uiIntSize];
503     pBuffer[uiIntSize - 1] = 0; // set the last entry as 0 for handling non uint32_t file sizes.
504     oInStream.read(reinterpret_cast<char*>(pBuffer), uiSize);
505 
506     if (oInStream.bad())
507     {
508         printf("Error: Unable to read from file '%s'\n", sInputFile.c_str());
509         goto finish;
510     }
511     else
512     {
513         sOutputFile += SOURCE_EXT;
514         sOutputFile = appendPath(sOutputDir, sOutputFile);
515 
516         std::transform(sVarName.begin(), sVarName.end(), sVarName.begin(), ::toupper);
517         if (index == -1)
518         {
519             iStatus = writeSourceFile(pBuffer, uiIntSize, sOutputFile, sVarName);
520         }
521         else
522         {
523             iStatus = writePartialSourceFile(pBuffer, uiIntSize, sOutputFile, sVarName, index, total);
524         }
525     }
526 
527 finish:
528     if (oInStream.is_open())
529     {
530         oInStream.close();
531     }
532 
533     if (pBuffer)
534     {
535         delete [] pBuffer;
536         pBuffer = nullptr;
537     }
538     return iStatus;
539 }
540 
541 //-----------------------------------------------------------------------------
542 // Creates the Header file
543 //-----------------------------------------------------------------------------
createHeaderFile(const std::string & sInputFile,const std::string & sOutputDir,const std::string & sVar)544 int32_t createHeaderFile(
545     const std::string &sInputFile,
546     const std::string &sOutputDir,
547     const std::string &sVar)
548 {
549     struct stat     StatResult;
550     int32_t         iStatus = -1;
551     std::ifstream   oInStream;
552     std::string     sInputFileName;
553     std::string     sOutputFile;
554     std::string     sVarName;
555     uint32_t        *pBuffer    = nullptr;
556     uint32_t        uiSize      = 0;
557     float fSize     = (ceil)(0.0f);
558     uint32_t uiIntSize  = 0;
559 
560     // Check if input file exists
561     if (0 != stat(sInputFile.c_str(), &StatResult))
562     {
563         printf("Error: Unable to read file '%s'\n", sInputFile.c_str());
564         goto finish;
565     }
566     if (StatResult.st_size > 0)
567     {
568         uiSize = StatResult.st_size;
569     }
570     else
571     {
572         printf("Error: The read file '%s' is null!\n", sInputFile.c_str());
573         goto finish;
574     }
575 
576     if (sOutputDir.length() > 0)
577     {
578         // Check if out direction exists and validate it is a directory
579         if (0 != stat(sOutputDir.c_str(), &StatResult))
580         {
581             printf("Error: Unable to find directory '%s'\n", sOutputDir.c_str());
582             goto finish;
583         }
584         if (0 == (StatResult.st_mode & S_IFDIR))
585         {
586             printf("Error: Path '%s' is a valid directory\n", sOutputDir.c_str());
587             goto finish;
588         }
589     }
590 
591     sInputFileName = getFileName(sInputFile);
592     if (sOutputDir.find("media_softlet") != std::string::npos)
593     {
594         // For media softlet, move vp kernel from media ip to render ip
595         std::string::size_type replaceIndex = sInputFileName.find("_hpm");
596 
597         if(replaceIndex != std::string::npos)
598         {
599             sInputFileName.replace(replaceIndex, 4, "_hpg");
600         }
601     }
602 
603     {
604         // Set the Output path
605         std::string::size_type uiLoc = sInputFileName.find(".", 0 );
606         sOutputFile = (uiLoc != std::string::npos) ? sInputFileName.substr(0, uiLoc) : sInputFileName;
607         sVarName = (sVar.length() == 0) ? sOutputFile : sVar;
608     }
609 
610     // Read the File
611     oInStream.open(sInputFile.c_str(), std::ios::in | std::ios::binary);
612     if (! oInStream.is_open())
613     {
614         printf("Error: Unable to open file '%s' for reading\n", sInputFile.c_str());
615         goto finish;
616     }
617 
618     // Read from the file
619     fSize     = (ceil)(uiSize / 4.0f);
620     uiIntSize  = static_cast<uint32_t>(fSize);
621 
622     pBuffer = new uint32_t[uiIntSize];
623     pBuffer[uiIntSize - 1] = 0; // set the last entry as 0 for handling non uint32_t file sizes.
624     oInStream.read(reinterpret_cast<char*>(pBuffer), uiSize);
625 
626     if (oInStream.bad())
627     {
628         printf("Error: Unable to read from file '%s'\n", sInputFile.c_str());
629         goto finish;
630     }
631     else
632     {
633         sOutputFile += HEADER_EXT;
634         sOutputFile = appendPath(sOutputDir, sOutputFile);
635     }
636     std::transform(sVarName.begin(), sVarName.end(), sVarName.begin(), ::toupper);
637     iStatus = writeHeaderFile(pBuffer, uiIntSize, sOutputFile, sVarName);
638 
639 finish:
640     if (oInStream.is_open())
641     {
642         oInStream.close();
643     }
644 
645     if (pBuffer)
646     {
647         delete [] pBuffer;
648         pBuffer = nullptr;
649     }
650     return iStatus;
651 }
652 
653 //-----------------------------------------------------------------------------
654 // Prints Usage
655 //-----------------------------------------------------------------------------
printUsage(const std::string & sProgram)656 void printUsage(const std::string &sProgram)
657 {
658     std::cout << "Usage: "
659               << sProgram.c_str()
660               << " (" << PARAM_I << " InPath)"
661               << " [" << PARAM_O << " OutPath]"
662               << " [" << PARAM_V << " VarName]"
663               << " [" << PARAM_INDEX << " Kernel Index]"
664               << " [" << PARAM_TOTAL << " Kernel Total]"
665               << std::endl
666               << "    " << PARAM_I << " Path to Kernel binary input file (required)"             << std::endl
667               << "    " << PARAM_O << " Path to Kernel binary output directory (optional)"       << std::endl
668               << "    " << PARAM_V << " Variable Name on the generated source file (optional)"   << std::endl
669               << "    " << PARAM_INDEX << " Variable kernel Index  (optional)"                   << std::endl
670               << "    " << PARAM_TOTAL << " Variable kernel total count (optional)"              << std::endl;
671 
672 }
673 
674 //-----------------------------------------------------------------------------
675 // Parses input
676 //-----------------------------------------------------------------------------
parseInput(int32_t argc,char * argv[],const std::string & sProgram,std::string & sInput,std::string & sOutput,std::string & sVarName,uint32_t & index,uint32_t & total)677 int32_t parseInput(
678     int32_t             argc,
679     char                *argv[],
680     const std::string   &sProgram,
681     std::string         &sInput,
682     std::string         &sOutput,
683     std::string         &sVarName,
684     uint32_t            &index,
685     uint32_t            &total)
686 {
687     int32_t iStatus = -1;
688 
689     // Must have even number of arguments (excluding argv[0])
690     if (argc % 2 == 0)
691     {
692         goto finish;
693     }
694 
695     for (int i = 1; i < argc; i += 2)
696     {
697         if (0 == strcmp(PARAM_I, argv[i]))
698         {
699             sInput = argv[i+1];
700         }
701         else if (0 == strcmp(PARAM_O, argv[i]))
702         {
703             sOutput = argv[i+1];
704         }
705         else if (0 == strcmp(PARAM_V, argv[i]))
706         {
707             sVarName = argv[i+1];
708         }
709         else if (0 == strcmp(PARAM_INDEX, argv[i]))
710         {
711             index = atoi(argv[i+1]);
712         }
713         else if (0 == strcmp(PARAM_TOTAL, argv[i]))
714         {
715             total = atoi(argv[i+1]) + 1;
716         }
717         else
718         {
719             std::cout << "Error: Invalid option " << argv[i] << std::endl;
720             goto finish;
721         }
722     }
723 
724     if (sInput.length() == 0)
725     {
726         goto finish;
727     }
728 
729     iStatus = 0;
730 
731 finish:
732     if (iStatus != 0)
733     {
734         printUsage(sProgram);
735     }
736 
737     return iStatus;
738 }
739 
740 //-----------------------------------------------------------------------------
741 // Prints time
742 //-----------------------------------------------------------------------------
printTime(int64_t lFreq,int64_t lTime)743 void printTime(int64_t lFreq, int64_t lTime)
744 {
745     double dsec = ((double)lTime) / ((double)lFreq);
746     double dms  = dsec * 1000;
747     std::cout << "Time Took " << std::setw(2) << dsec << "s "
748               << "(" << dms << "ms)"
749               << std::endl;
750 }
751 
752 //-----------------------------------------------------------------------------
753 // Main Function
754 //-----------------------------------------------------------------------------
main(int argc,char * argv[])755 int32_t main(int argc, char *argv[])
756 {
757     std::string sProgram    = getFileName(argv[0]);
758     //get current time
759     time_t t = time(0);
760     tm* now = localtime(&t);
761     uint64_t year = 1900 + now->tm_year;
762 
763     std::cout << std::endl
764               << sProgram.c_str() << " v" << MAJ_VERSION << "." << MIN_VERSION << std::endl
765               << "(c) Intel Corporation " << year << ". All rights reserved." << std::endl << std::endl;
766 
767     COPYRIGHT = copyright_front + std::to_string(year) + copyright_end;
768 
769     int32_t iStatus = -1;
770     std::string sInputPath;
771     std::string sOutputDir;
772     std::string sVarName;
773     uint32_t index=-1;
774     uint32_t total=-1;
775 
776     iStatus = parseInput(argc, argv, sProgram, sInputPath, sOutputDir, sVarName, index, total);
777     if (iStatus != 0)
778     {
779         goto finish;
780     }
781 
782     iStatus = createHeaderFile(sInputPath, sOutputDir, sVarName);
783 
784     iStatus = createSourceFile(sInputPath, sOutputDir, sVarName, index, total);
785 
786 finish:
787     return iStatus;
788 }
789